jamulus-3.9.1+dfsg/0000755000175000017500000000000014341067632013157 5ustar vimervimerjamulus-3.9.1+dfsg/ios/0000755000175000017500000000000014340334543013746 5ustar vimervimerjamulus-3.9.1+dfsg/ios/deploy_ios.sh0000755000175000017500000000126214340334543016454 0ustar vimervimer#!/bin/bash set -eu -o pipefail ## Builds an ipa file for iOS. Should be run from the repo-root # Create Xcode file and build qmake -spec macx-xcode Jamulus.pro /usr/bin/xcodebuild -project Jamulus.xcodeproj -scheme Jamulus -configuration Release clean archive -archivePath "build/Jamulus.xcarchive" CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO CODE_SIGN_ENTITLEMENTS="" # Generate ipa by copying the .app file from the xcarchive directory mkdir build/Payload cp -r build/Jamulus.xcarchive/Products/Applications/Jamulus.app build/Payload/ cd build zip -0 -y -r Jamulus.ipa Payload/ # Make a deploy folder and copy file mkdir ../deploy mv Jamulus.ipa ../deploy jamulus-3.9.1+dfsg/ios/Info.plist0000644000175000017500000000345614340334543015726 0ustar vimervimer CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString 1.0 CFBundleVersion 1 LSRequiresIPhoneOS NSMicrophoneUsageDescription We need access to your microphone to let others hear you. UIApplicationSceneManifest UIApplicationSupportsMultipleScenes UIApplicationSupportsIndirectInputEvents UIBackgroundModes audio UILaunchScreen UILaunchStoryboardName LaunchScreen UIRequiredDeviceCapabilities armv7 UISupportedInterfaceOrientations UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UISupportedInterfaceOrientations~ipad UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight jamulus-3.9.1+dfsg/CONTRIBUTING.md0000644000175000017500000001527214340334543015414 0ustar vimervimer# Contributing to Jamulus We’d really appreciate your support! Please ensure that you understand the following in order to keep things organized: - If a [Github issue](https://github.com/jamulussoftware/jamulus/issues) for your feature/bug fix already exists, write a message in that issue indicating that you want to work on it. - Otherwise, please [post on the GitHub Discussions](https://github.com/jamulussoftware/jamulus/discussions) and say that you are planning to do some coding and explain why. Then we can discuss the specification. - Please begin coding only after we have agreed on a specification to avoid putting a lot of effort into something that may not be accepted later. ## Jamulus project/source code general principles ### 1. Stability Instabilities during live performances such as WorldJam are not acceptable. As a result, stability has been, and must continue to be the most important requirement. The following principles are designed to support this. ### 2. [Keep it Simple and Stupid](https://en.wikipedia.org/wiki/KISS_principle) and 3. [Do One Thing and Do It Well](https://en.wikipedia.org/wiki/Unix_philosophy#Do_One_Thing_and_Do_It_Well) If a feature or function can be accomplished in another way by another system or method, it is preferable not to build that feature into Jamulus. Rather than implementing each and every feature as part of Jamulus, we concentrate on a stable core and implement interfaces for interaction with third-party components as needed. The [JSON-RPC](https://github.com/jamulussoftware/jamulus/blob/master/docs/JSON-RPC.md) API for example, allows you to communicate with the client and server from outside the application. ### Source code consistency Please install and run `clang-format` on your PC **before committing** to maintain a consistent coding style. You should use the version we use to validate the style in our CI [(see our coding-style-check file and look for the `clangFormatVersion`)](https://github.com/jamulussoftware/jamulus/blob/master/.github/workflows/coding-style-check.yml#L20). Our CI will fail and tell you about styling violations. There are several ways to run clang-format: - Use your editor's or IDE's clang-format support. - Via make: after running `qmake Jamulus.pro`, run `make clang_format` - By hand: run `clang-format -i ` #### Style definition Please see the [.clang_format file](https://github.com/jamulussoftware/jamulus/blob/master/.clang-format) in the root folder. In summary: - Respect the existing code style: Tab size=4, insert spaces. - Insert a space before and after `(` and `)`. There should be no space between `)` and `;` or before an empty `()`. - Enclose all bodies of `if`, `else`, `while`, `for`, etc. in braces `{` and `}` on separate lines. - Do not use concatinations in strings with parameters. Instead use substitutions. **Do:** `QString ( tr ( "Hello, %1. Have a nice day!" ) ).arg( getName() )` **Don't:** `tr ( "Hello " ) + getName() + tr ( ". Have a nice day!" )` ...to make translation easier. ### Supported platforms We support the following platforms and versions: - **Windows 7** or later - **macOS 10.10** or later - **Ubuntu 18.04** or later, **Debian 10** or later, most Linux flavors with recent enough Qt versions _While Android and iOS aren't officially supported, please don't break their builds._ Please try to avoid breaking any build by introducing platform-specific code. Check to see if any newly introduced Qt calls, parameters, properties or constants are available in the minimum supported Qt version, which is currently **5.9**. Note that code _style_ in a file may be Qt 4.x. While you should normally stick to existing style, if you make large-scale modifications, updating to Qt 5.9 style is recommended. Maintain C++11 compatibility throughout the code. ### Dependencies If your code requires new dependencies, ensure that they are available on all supported platforms and that their inclusion has been discussed and approved. ### User experience Jamulus is used by people from all over the world with different backgrounds and levels of knowledge. Features should be usable in the sense that they behave as expected by someone without a technical background. To maintain consistency in language, follow the [style and tone guide](https://jamulus.io/contribute/Style-and-Tone). In terms of the UI, prefer standard approaches to exotic ones. ### Submitting code and getting started We're using git to develop Jamulus. To contribute, you should get familiar to git and GitHub. Have a look at our [guide for translators](docs/TRANSLATING.md) - especially read the git related part. If you need more in depth information, the [git-scm book](https://git-scm.com/book/en/v2) might also help you getting started. If you have any questions, don't hesitate to ask, as git can be very confusing. ### Testing To check that there are no errors, please run a local (build/feature) test. Keep an eye on the CI checks for quality or compile issues after opening a pull request and fix them as needed. You can also test the build on your repository by naming your branch `autobuild/` which will start the building process on your repo. ### Ownership The submitter of an Issue or a PR is responsible for its care and feeding, answering all questions directed at them, and making agreed changes if necessary. Authors are strongly encouraged to update their initial posts/PR descriptions or title to reflect the current state of play, amends, enhancements, outstanding issues, etc., to reduce effort for others in understanding a PR or an Issue. Admins reserve the right to do this as they see fit. ### Documentation/Acknowledgements The ChangeLog must be updated for each new feature or bug fix. Please include a single-sentence suggestion for that as part of your pull request description after the `CHANGELOG: ` keyword. Do not modify the ChangeLog file as part of your PR as it will lead to conflicts. If you are a first-time contributor/translator, please add your name to the contributors/translators list in the About dialog of Jamulus (see in `src/util.cpp` in the constructor function `CAboutDlg::CAboutDlg()`). ### Merging Pull Requests The git master branch is protected and requires at least two reviews by the main developers before the pull request can be merged. Any of the main developers can initiate the merge if a pull request receives at least two positive reviews. --- ## Want to get involved in other ways? We always need help with documentation, [translation](docs/TRANSLATING.md) and anything else. Feel free to look at the [Website repository](https://github.com/jamulussoftware/jamuluswebsite) or get involved in fixing issues from the [issue tracker](https://github.com/jamulussoftware/jamulus/issues). jamulus-3.9.1+dfsg/.gitmodules0000644000175000017500000000010714340334543015327 0ustar vimervimer[submodule "libs/oboe"] path = libs/oboe url = ../../google/oboe.git jamulus-3.9.1+dfsg/SECURITY.md0000644000175000017500000000330314340334543014744 0ustar vimervimer# Reporting Security Issues **⚠️ Please do not open GitHub issues for security vulnerabilities. ⚠️** We encourage responsible disclosure practices for security vulnerabilities. If you think you have found a security-relevant issue, please send the details to **team@jamulus.io**. We will then - open a placeholder issue without details, - assess the severity, - work on a fix, - schedule a release which includes the fix and - publish all relevant details as part of the issue, - publish a Github security advisory as necessary. # Security model ## Guarantees The Jamulus project aims to provide robust software. It tries hard to avoid all kinds of implementation issues such as Code Execution, unwanted File system access, or similar issues. ## Limitations The following is a list of areas where there may be expectations which Jamulus currently does not fulfill: - There is no registration, authentication or user database. Usernames can freely be chosen. - There is no encryption or message authentication. Both protocol messages and audio are transmitted in the clear. Anyone with access to the network traffic is able to listen to the audio or even modify it. - There is little protection against certain patterns of Denial of Service: - Servers have a limited number of slots for clients which can easily be exhausted. - There is no protection against spam in the chat function. - Jamulus is UDP-based and UDP does not provide protection against source address spoofing. This enables all kinds of Denial of Service or Impersonation attacks. For some of these areas there are long-term ideas about extending Jamulus (e.g. usage of TCP, authentication), but they have not been decided upon yet. jamulus-3.9.1+dfsg/docs/0000755000175000017500000000000014340334543014104 5ustar vimervimerjamulus-3.9.1+dfsg/docs/JAMULUS_PROTOCOL.md0000644000175000017500000001676314340334543017104 0ustar vimervimer# The Jamulus Audio Protocol Jamulus uses connectionless UDP packets to communicate between the client and server, and additionally for directory server registration. The `src/protocol.cpp` file contains much of the details of the packets themselves, whereas this document is intended to form a higher-level view of the protocol interactions. Some of the messages need to be acknowledged, some do not. If a message ID is less than 1000, the message must be acknowledged in under `SEND_MESS_TIMEOUT_MS` ms. All of this information can be discovered from reading the code, but hopefully is quicker to digest when available in one location. There is a wireshark dissector available too, [here](https://github.com/softins/jamulus-wireshark), if you would like to inspect the packet flow. --- ## Overview The message packet structure is: ``` +-------------+------------+------------+------------------+--------------+-------------+ | 2 bytes TAG | 2 bytes ID | 1 byte SEQ | 2 bytes data LEN | n bytes DATA | 2 bytes CRC | +-------------+------------+------------+------------------+--------------+-------------+ ``` The TAG bytes are zero bytes. The ID provides the message type. The SEQ is a wrapping sequence number for the message LENgth of the data preceeds the data and is followed by a CRC for the packet. Data is sent little-endian, i.e. not network byte-order. Where a message will not fit into the maximum packet size before fragmentation, a split message container is used. ``` +------------+--------------+----------------+--------------+ | 2 bytes ID | 1 byte FRAGS | 1 byte FRAG_ID | n bytes DATA | +------------+--------------+----------------+--------------+ ``` The ID is the message type sent in fragments FRAGS is the total number of fragments FRAG_ID is the sequence number of the data in this fragment DATA is the fragment data to be re-assembled This forms the data component of the packet above. ## Client Session with a Server As the protocol is connectionless, the message flow at session start up can happen out of order. When a client starts a session with a server, it sends valid audio packets to the server port, to which the server will respond with the audio mix for that client. The server on a new client connection will: - Tell the client connection its ID, with a `CLIENT_ID (32, 0x2000)` message. - Reset the connected client list with a `CONN_CLIENTS_LIST (24, 0x1800)` message. - Determine if the client supports split messages, with a `REQ_SPLIT_MESSAGE_SUPPORT (34, 0x2200)` message. - Request the details of the audio packets from the client with a `REQ_NETW_TRANSPORT_PROPS (21, 0x1500)` message, - Request the number of jitter buffer value to use, with a `REQ_JITT_BUF_SIZE (11, 0x0B00)` message. - Request the details of the channel info, with a `REQ_CHANNELS_INFOS (23, 0x1700)` message. - Send the version and OS of the server, with a `VERSION_AND_OS (29, 0x1d00)` message. This is defined in `CServer::OnNewConnection()` The client on a new connection will: - Send its channel info with a `CHANNELS_INFO (25, 0x1900)` message - Request the list of connected clients with a `REQ_CONN_CLIENT_LIST (16, 0x1000)` message - Set the server-side jitter buffer value with a `JITT_BUF_SIZE (10, 0x0a00)` message This is defined in `CClient::OnNewConnection()` At the end of the session, the client calls the `CLM_DISCONNECTION (1010, 0xf203)` message, until the server stops streaming audio to it. A typical flow would be: ``` Client Server AUDIO ---------------------------------> <------------------------------------ CLIENT_ID (32, 0x2000) ACK(CLIENT_ID) ------------------------> <------------------------------------ CONN_CLIENTS_LIST (24, 0x1800) (Reset to zero) ACK(CONN_CLIENTS_LIST) ----------------> <------------------------------------ REQ_SPLIT_MESSAGE_SUPPORT (34, 0x2200) SPLIT_MESS_SUPPORTED (35, 0x2300) ---------> ACK(REQ_SPLIT_MESSAGE_SUPPORT) --------> <------------------------------------ ACK(SPLIT_MESS_SUPPORTED) <------------------------------------ REQ_NETW_TRANSPORT_PROPS (21, 0x1500) NETW_TRANSPORT_PROPS (20, 0x1400) ---------> ACK(REQ_NETW_TRANSPORT_PROPS) ---------> <------------------------------------ ACK(NETW_TRANSPORT_PROPS) <------------------------------------ REQ_JITT_BUF_SIZE (11, 0x0B00) JITT_BUF_SIZE (10, 0x0a00) ----------------> ACK(REQ_JITT_BUF_SIZE) ----------------> <------------------------------------ ACK(JITT_BUF_SIZE) <------------------------------------ REQ_CHANNELS_INFOS (23, 0x1700) CHANNEL_INFOS (25, 0x1900) ----------------> ACK(REQ_CHANNELS_INFOS) ---------------> <------------------------------------ ACK(CHANNEL_INFOS) (Optional welcome message) <------------------------------------ CHAT_TEXT (18, 0x1200) ACK(CHAT_TEXT) ------------------------> <------------------------------------ VERSION_AND_OS (29, 0x1d00) ACK(VERSION_AND_OS) -------------------> CHANNEL_INFOS (25, 0x1900) ----------------> <------------------------------------ ACK(CHANNEL_INFOS) <------------------------------------ RECORDER_STATE (33, 0x2100) ACK(RECORDER_STATE) -------------------> REQ_CONNECTED_CLIENTS_LIST (16, 0x1000) ----> <------------------------------------ ACK(REQ_CONNECTED_CLIENTS_LIST) REQ_CHANNEL_LEVEL_LIST (28, 0x1c00) --------> JITT_BUF_SIZE (10, 0x0a00) ----------------> <------------------------------------ JITT_BUF_SIZE (10, 0x0a00) <------------------------------------ ACK(JITT_BUF_SIZE) ACK(JITT_BUF_SIZE) --------------------> <------------------------------------ CONN_CLIENTS_LIST (24, 0x1800) ACK(CONN_CLIENTS_LIST) ----------------> NETW_TRANSPORT_PROPS (20, 0x1400) ---------> <------------------------------------ CONN_CLIENTS_LIST (24, 0x1800) <------------------------------------ ACK(NETW_TRANSPORT_PROPS) ACK(CONN_CLIENTS_LIST) ----------------> ``` ## General Streaming Messages During streaming, some control messages are used. Some typical messages could be: ``` Client Server <------------------------------------ CLM_CHANNEL_LEVEL_LIST (1015, 0xf703) CHANNEL_GAIN (13, 0x0d00) -----------------> CLM_PING_MS (1001, 0xe903) ------------------> <------------------------------------ ACK(CHANNEL_GAIN) <------------------------------------ CLM_PING_MS (1001, 0xe903) MUTE_STATE_CHANGED (31, 0x1f00) -----------> <------------------------------------ ACK(MUTE_STATE_CHANGED) NETW_TRANSPORT_PROPS (20, 0x1400) ---------> <------------------------------------ ACK(NETW_TRANSPORT_PROPS) - Reset audio packet sequencing on change CHANNEL_PAN (30, 0x1e00) ------------------> <------------------------------------ ACK(CHANNEL_PAN) ``` --- ## Audio Packet Structure The OPUS codec is used to compress the audio over the network and the packets are documented [here](https://datatracker.ietf.org/doc/html/rfc6716). Jamulus uses a custom OPUS encoder / decoder, giving some different frame sizes, but always uses a 48kHz sample rate. OPUS and OPUS64 codecs are the only supported options currently. The packet size will vary based on: - Stereo vs mono - Buffer size (64/128/256 samples) - Use of frame sequence number (from v3.6.0 onwards) These values are wrapped up into the `NETW_TRANSPORT_PROPS` messages, which the client sends to the server to tell it which values to use. Both client and server use a jitter buffer for received audio data to prevent audio drop-out. This is configurable. jamulus-3.9.1+dfsg/docs/JSON-RPC.md0000644000175000017500000002604114340334543015624 0ustar vimervimer # Jamulus JSON-RPC Documentation A JSON-RPC interface is available for both Jamulus client and server to allow programmatic access. To use the JSON-RPC interface, run Jamulus with the `--jsonrpcport --jsonrpcsecretfile /file/with/a/secret.txt` options. This will start a JSON-RPC server on the specified port on the localhost. The file referenced by `--jsonrpcsecretfile` must contain a single line with a freely chosen string with at least 16 characters. It can be generated like this: ``` $ openssl rand -base64 10 > /file/with/a/secret.txt ``` ## Wire protocol The JSON-RPC server is based on the [JSON-RPC 2.0](https://www.jsonrpc.org/specification) protocol, using [streaming newline-delimited JSON over TCP](https://clue.engineering/2018/introducing-reactphp-ndjson) as the transport. There are three main types of messages being exchanged: - A **request** from the consumer to Jamulus. - A **response** from Jamulus to the consumer. - A **notification** from Jamulus to the consumer. ## Example After opening a TCP connection to the JSON-RPC server, the connection must be authenticated: ```json {"id":1,"jsonrpc":"2.0","method":"jamulus/apiAuth","params":{"secret": "...the secret from the file in --jsonrpcsecretfile..."}} ``` Request must be sent as a single line of JSON-encoded data, followed by a newline character. Jamulus will send back a **response** in the same manner: ```json {"id":1,"jsonrpc":"2.0","result":"ok"} ``` After successful authentication, the following **request** can be sent: ```json {"id":2,"jsonrpc":"2.0","method":"jamulus/getMode","params":{}} ``` The request must be sent as a single line of JSON-encoded data, followed by a newline character. Jamulus will send back a **response** in the same manner: ```json {"id":2,"jsonrpc":"2.0","result":{"mode":"client"}} ``` Jamulus will also send **notifications** to the consumer: ```json {"jsonrpc":"2.0","method":"jamulusclient/chatTextReceived","params":{"text":"(01:23:45 AM) user test"}} ``` ## Method reference ### jamulus/apiAuth Authenticates the connection which is a requirement for calling further methods. Parameters: | Name | Type | Description | | --- | --- | --- | | params.secret | string | The preshared secret key. | Results: | Name | Type | Description | | --- | --- | --- | | result | string | "ok" on success | ### jamulus/getMode Returns the current mode, i.e. whether Jamulus is running as a server or client. Parameters: | Name | Type | Description | | --- | --- | --- | | params | object | No parameters (empty object). | Results: | Name | Type | Description | | --- | --- | --- | | result.mode | string | The current mode (server or client). | ### jamulus/getVersion Returns Jamulus version. Parameters: | Name | Type | Description | | --- | --- | --- | | params | object | No parameters (empty object). | Results: | Name | Type | Description | | --- | --- | --- | | result.version | string | The Jamulus version. | ### jamulusclient/getChannelInfo Returns the client's profile information. Parameters: | Name | Type | Description | | --- | --- | --- | | params | object | No parameters (empty object). | Results: | Name | Type | Description | | --- | --- | --- | | result.id | number | The channel ID. | | result.name | string | The musician’s name. | | result.skillLevel | string | The musician’s skill level (beginner, intermediate, expert, or null). | | result.countryId | number | The musician’s country ID (see QLocale::Country). | | result.city | string | The musician’s city. | | result.instrumentId | number | The musician’s instrument ID (see CInstPictures::GetTable). | | result.skillLevel | string | Your skill level (beginner, intermediate, expert, or null). | ### jamulusclient/getClientInfo Returns the client information. Parameters: | Name | Type | Description | | --- | --- | --- | | params | object | No parameters (empty object). | Results: | Name | Type | Description | | --- | --- | --- | | result.connected | boolean | Whether the client is connected to the server. | ### jamulusclient/getClientList Returns the client list. Parameters: | Name | Type | Description | | --- | --- | --- | | params | object | No parameters (empty object). | Results: | Name | Type | Description | | --- | --- | --- | | result.clients | array | The client list. See jamulusclient/clientListReceived for the format. | ### jamulusclient/sendChatText Sends a chat text message. Parameters: | Name | Type | Description | | --- | --- | --- | | params.chatText | string | The chat text message. | Results: | Name | Type | Description | | --- | --- | --- | | result | string | Always "ok". | ### jamulusclient/setName Sets your name. Parameters: | Name | Type | Description | | --- | --- | --- | | params.name | string | The new name. | Results: | Name | Type | Description | | --- | --- | --- | | result | string | Always "ok". | ### jamulusclient/setSkillLevel Sets your skill level. Parameters: | Name | Type | Description | | --- | --- | --- | | params.skillLevel | string | The new skill level (beginner, intermediate, expert, or null). | Results: | Name | Type | Description | | --- | --- | --- | | result | string | Always "ok". | ### jamulusserver/getClients Returns the list of connected clients along with details about them. Parameters: | Name | Type | Description | | --- | --- | --- | | params | object | No parameters (empty object). | Results: | Name | Type | Description | | --- | --- | --- | | result.clients | array | The list of connected clients. | | result.clients[*].id | number | The client’s channel id. | | result.clients[*].address | string | The client’s address (ip:port). | | result.clients[*].name | string | The client’s name. | | result.clients[*].jitterBufferSize | number | The client’s jitter buffer size. | | result.clients[*].channels | number | The number of audio channels of the client. | ### jamulusserver/getRecorderStatus Returns the recorder state. Parameters: | Name | Type | Description | | --- | --- | --- | | params | object | No parameters (empty object). | Results: | Name | Type | Description | | --- | --- | --- | | result.initialised | boolean | True if the recorder is initialised. | | result.errorMessage | string | The recorder error message, if any. | | result.enabled | boolean | True if the recorder is enabled. | | result.recordingDirectory | string | The recorder recording directory. | ### jamulusserver/getServerProfile Returns the server registration profile and status. Parameters: | Name | Type | Description | | --- | --- | --- | | params | object | No parameters (empty object). | Results: | Name | Type | Description | | --- | --- | --- | | result.name | string | The server name. | | result.city | string | The server city. | | result.countryId | number | The server country ID (see QLocale::Country). | | result.welcomeMessage | string | The server welcome message. | | result.directoryServer | string | The directory server to which this server requested registration, or blank if none. | | result.registrationStatus | string | The server registration status as string (see ESvrRegStatus and SerializeRegistrationStatus). | ### jamulusserver/restartRecording Restarts the recording into a new directory. Parameters: | Name | Type | Description | | --- | --- | --- | | params | object | No parameters (empty object). | Results: | Name | Type | Description | | --- | --- | --- | | result | string | Always "acknowledged". To check if the recording was restarted or if there is any error, call `jamulusserver/getRecorderStatus` again. | ### jamulusserver/setRecordingDirectory Sets the server recording directory. Parameters: | Name | Type | Description | | --- | --- | --- | | params.recordingDirectory | string | The new recording directory. | Results: | Name | Type | Description | | --- | --- | --- | | result | string | Always "acknowledged". To check if the directory was changed, call `jamulusserver/getRecorderStatus` again. | ### jamulusserver/setServerName Sets the server name. Parameters: | Name | Type | Description | | --- | --- | --- | | params.serverName | string | The new server name. | Results: | Name | Type | Description | | --- | --- | --- | | result | string | Always "ok". | ### jamulusserver/setWelcomeMessage Sets the server welcome message. Parameters: | Name | Type | Description | | --- | --- | --- | | params.welcomeMessage | string | The new welcome message. | Results: | Name | Type | Description | | --- | --- | --- | | result | string | Always "ok". | ### jamulusserver/startRecording Starts the server recording. Parameters: | Name | Type | Description | | --- | --- | --- | | params | object | No parameters (empty object). | Results: | Name | Type | Description | | --- | --- | --- | | result | string | Always "acknowledged". To check if the recording was enabled, call `jamulusserver/getRecorderStatus` again. | ### jamulusserver/stopRecording Stops the server recording. Parameters: | Name | Type | Description | | --- | --- | --- | | params | object | No parameters (empty object). | Results: | Name | Type | Description | | --- | --- | --- | | result | string | Always "acknowledged". To check if the recording was disabled, call `jamulusserver/getRecorderStatus` again. | ## Notification reference ### jamulusclient/channelLevelListReceived Emitted when the channel level list is received. Parameters: | Name | Type | Description | | --- | --- | --- | | params.channelLevelList | array | The channel level list. Each item corresponds to the respective client retrieved from the jamulusclient/clientListReceived notification. | | params.channelLevelList[*] | number | The channel level, an integer between 0 and 9. | ### jamulusclient/chatTextReceived Emitted when a chat text is received. Parameters: | Name | Type | Description | | --- | --- | --- | | params.chatText | string | The chat text. | ### jamulusclient/clientListReceived Emitted when the client list is received. Parameters: | Name | Type | Description | | --- | --- | --- | | params.clients | array | The client list. | | params.clients[*].id | number | The channel ID. | | params.clients[*].name | string | The musician’s name. | | params.clients[*].skillLevel | string | The musician’s skill level (beginner, intermediate, expert, or null). | | params.clients[*].countryId | number | The musician’s country ID (see QLocale::Country). | | params.clients[*].city | string | The musician’s city. | | params.clients[*].instrumentId | number | The musician’s instrument ID (see CInstPictures::GetTable). | ### jamulusclient/connected Emitted when the client is connected to the server. Parameters: | Name | Type | Description | | --- | --- | --- | | params.id | number | The channel ID assigned to the client. | ### jamulusclient/disconnected Emitted when the client is disconnected from the server. Parameters: | Name | Type | Description | | --- | --- | --- | | params | object | No parameters (empty object). | jamulus-3.9.1+dfsg/docs/TRANSLATING.md0000644000175000017500000003030414340334543016214 0ustar vimervimer# Guide for Translators This guide is written to provide instructions from scratch for contributing to the translation of the Jamulus application to other languages. The code for Jamulus is open source, and is managed and made available via the Github site. For completeness, this document describes the use both of GitHub (using `git`) and of _Qt Linguist_. --- ## Introduction The translator must be able to do the following steps, which will each be explained further down: - Create their own linked copy ("repository" or "repo") of Jamulus in GitHub. This is called Forking. - Copy ("clone") their own repository to their computer, using either: - Command line `git`, or - [Github Desktop](https://docs.github.com/en/desktop) - Update their own local repo from the upstream master branch. - Create a local branch to contain the update. - Use the Qt Linguist tool to edit the appropriate translation (`.ts`) file. - Commit the updated `.ts` file to the branch their own local git repo. - Push the branch from their local repo to their own repo on Github. - Raise a Pull Request (PR) for the merging of the updated file into the upstream repo by the developers. This guide contains two main parts: 1. Instructions for getting set up, which only needs to be done once. 2. The workflow for updating and contributing translations as a part of the preparation for a release of Jamulus. --- ## 1. Setting up ### Visit github.com First of all, visit the [Github website](https://github.com) If you don't yet have a Github account, click on **Sign up** to go to the Create Your Account page. Enter: - Your chosen username. This is a simple word containing letters and, optionally, numbers, and will identify you in the Github world. It is not an email address. This name is represented in the examples below as `yourusername`. - Your email address. This will be used by Github to send you notifications by email, and to identify commits made by you. - Your chosen password. Do not use the same password as for any other website. - Solve the puzzle to prove you are human and click **Create account**. If you do have a Github account, and are not yet logged in, click on **Sign in**, and enter your username and password, then **Sign in**. Go to the [Jamulus repository](https://github.com/jamulussoftware/jamulus). Create your own copy ("fork") of the Jamulus repository by clicking the **Fork** button at the top right of the page. If your Github account is also part of an organisation, Github will ask you where to create the fork. Choose your personal Github account. It will then display the message "Forking jamulussoftware/jamulus", and when finished will display the home page of your own Jamulus repo (**yourusername/jamulus**). ### Command line git tools Linux and Mac machines come with command-line Git tools ready-installed or easily available. - On Mac, the `git` command is available in `/usr/bin/git`, as part of the Xcode package, or can be installed separately (see below). - On Linux, it may be necessary to install the `git` package using one of these commands: - On RedHat or CentOS, `yum install git` or `dnf install git` - On Debian or Ubuntu: `apt install git` - On Windows, Git can be obtained from [Git for Windows](https://git-for-windows.github.io/) More information about installing Git on various systems can be found [here](https://www.atlassian.com/git/tutorials/install-git) Make a local copy of your Jamulus repo by using `git clone`: - At the shell command-line, navigate to the directory that will be the parent of your `jamulus` development directory. - Give one of the following commands: - For ssh access: `git clone git@github.com:yourusername/jamulus.git` - For https access: `git clone https://github.com/yourusername/jamulus.git` This will create a `jamulus` directory. Change to that directory. - Add the upstream repository: `git remote add upstream https://github.com/jamulussoftware/jamulus.git` - Check the remotes using `git remote -v`. The output should look like this: ``` origin git@github.com:yourusername/jamulus.git (fetch) origin git@github.com:yourusername/jamulus.git (push) upstream https://github.com/jamulussoftware/jamulus.git (fetch) upstream https://github.com/jamulussoftware/jamulus.git (push) ``` or this: ``` origin https://github.com/yourusername/jamulus.git (fetch) origin https://github.com/yourusername/jamulus.git (push) upstream https://github.com/jamulussoftware/jamulus.git (fetch) upstream https://github.com/jamulussoftware/jamulus.git (push) ``` ### Github Desktop [Github Desktop](https://docs.github.com/en/desktop) is available for macOS 10.10 or later, and Windows 7 64-bit or later. It is not available for 32-bit Windows. To install Github Desktop, visit the [download page](https://desktop.github.com) and follow the link for the appropriate Operating System. When downloading for Mac, the instructions suggest opening `GitHubDesktop.zip`, but in fact, what was downloaded was `GitHubDesktop.app`. This should just be moved from `Downloads` to `Applications`. Run Github Desktop, and do the following steps: - On the Welcome Screen, click on **Sign in to GitHub.com** - Sign in by following the instructions. These may vary depending on whether you have logged into Github via a web browser already. If necessary, click on **Authorize Desktop**. - Confirm access by entering your Github password. - for Mac, if the browser requests to open "Github Desktop.app", click **Allow**. - In Configure Git, enter your name and email address. These will be used to identify commits you make to Git. Click **Continue**. - Agree or decline to submit periodic usage stats, and click **Finish**. - Either: - Select **Clone a Repository from the Internet** and enter `yourusername/jamulus`, or - Select your own fork of Jamulus from the list (`yourusername/jamulus`) and click the **Clone** button. - Select the Local Path where the project should be stored, and click **Clone**. - It will display the page **Cloning jamulus** with progress indication. - On completion of cloning, it will ask "How are you planning to use this fork?". Answer "To contribute to the parent project". ### Qt Linguist Qt Linguist is a part of the Qt development suite, and may either be installed via your Operating System's packaging manager, or by downloading from the [Qt Open Source download page](https://www.qt.io/download-open-source). In the latter case you will need to create an account on the Qt website. Under Linux - On RedHat or CentOS: `yum install qt5-linguist` or `dnf install qt5-linguist` - On Debian or Ubuntu: `apt install qttools5-dev-tools` Instructions for use are in the [Qt Linguist Manual](https://doc.qt.io/qt-5/qtlinguist-index.html) --- ## 2. Doing a translation ### Get the most up-to-date files and set up a new branch #### With git command line tools The first step is to get the local repo up to date with the upstream master: ``` cd projectdir/jamulus git fetch upstream ``` This fetches information about the current state of the upstream repo. It is now necessary to apply any upstream changes to the local repo. As the user will not be updating the `master` branch themselves, `git rebase` can be used to fast-forward to the current state: ``` git checkout master git rebase upstream/master git push ``` Finally, create a new branch for the changes that will be done (do not just do them on `master`). The actual name of the branch is not critical, since the branch will be deleted after being merged, but it's worth choosing a meaningful name: ``` git checkout -b translate-r3_7_0-german ``` (The branch name is chosen by the user; the above name translate-r3_7_0-german is an example for the German translation of V3.7.0) The branch will be used later as the source of a Pull Request. #### With Github Desktop Select the current repository as `jamulus`, and the current branch as `master`. Click on "Fetch origin" to get fully up to date with upstream. Drop down the "Current Branch" menu and click on the **New Branch** button. Give the branch a meaningful name such as `translate-r3_7_0-german` and click **Create Branch**. Do not click on **Publish branch** just yet. ### Work on the translation file Open Qt Linguist, and navigate to the directory `src/translation` within your project directory. In this directory are translation source files for each language, each with a `.ts` suffix. Don't worry about the `.qm` files, as they are compiled when building the release code. Open the `.ts` file for the language being worked on. Each context in the left-hand column represents a source file or graphical form containing translatable words and phrases ("strings"). The icon beside each shows a green tick if there is nothing further to be done, a yellow tick if a translation needs attention, and a question mark if there are untranslated strings. After clicking on a Context, the list of strings needing translation is shown, with a green tick beside the ones that have been done. The right-hand pane will show either the source code or the form, so that the usage can be checked, in case this aids the translation. Strings with a grey tick can be ignored. They are old strings that used to be used but are no longer. They are retained for reference in case they should be used again in the future. Again, strings with a question mark require translation. After some or all of the required strings have been translated, the file can be saved. ### Submit the updated translation as a Pull Request (PR) Once all translations have been done, the branch containing the changes must be commited to your own repo, pushed to Github (`origin`) and then a Pull Request raised to the upstream repo. #### With git command line tools First, check the current branch with `git status`, to make sure it is correct, and then do a commit, with a commit message describing the change, for example: ``` git commit -am 'Update German translations for v3.7.0' ``` Then do a `git push`. It will probably tell you to set the upstream repository for tracking, and conveniently gives the command for copying and pasting: ``` git push --set-upstream origin translate-r3_7_0-german ``` Finally, go to the Github website where it will most likely offer a banner saying there is a recent commit and offering to raise a Pull Request. Do so. #### With Github Desktop Select the current repository as `jamulus`, and the branch that was created above, such as `translate-r3_7_0-german`. The changed file(s) should be listed in the left-hand column as `src/translation/translation_xx_YY.ts`. When the file is selected, the differences will be displayed in the main panel. Add a simple commit message in the first box below the file list, (e.g. change "Update filename" to something like "Update German translations for v3.7.0"), and add any extra description in the Description box (optional, probably not required). Commit the changes to the local git repo by clicking on **Commit to **. Click on **Publish branch** or **Push origin**. This will push the branch to your own repo on Github. (It will say **Publish branch** for a new branch, or **Push origin** if the branch has already been published). There will now be a section offering **Create Pull Request**. Click on that to create the PR to the upstream repository. #### Updating a PR/fixing conflicts Other contributors may have edited your files after you began your work, which can cause conflicts. If GitHub or git tells you about conflicts, or if you are requested to [rebase](https://teamairship.com/update-outdated-branch-without-creating-merge-commit/) your work, do so as follows: ```shell git remote add upstream git@github.com:jamulussoftware/jamulus ;# add the main repo as upstream remote if you didn’t already as mentioned above git fetch upstream ; # Get the latest changes from the main upstream repo you added before (if needed) git checkout ;# switch to (= checkout) the branch you want to rebase git rebase upstream/master ;# replay (=rebase) your changes onto the latest code (and fix conflicts if needed) git rebase --continue # to continue the rebasing progress after having fixed the conflicts git push --force # Push the changes to your repo. Be aware that this will overwrite your remote branch! ``` --- ## That's all Thank you for contributing! jamulus-3.9.1+dfsg/docs/RELATED-PROJECTS.md0000644000175000017500000000437214340334543016743 0ustar vimervimer# Other projects related to Jamulus This document lists a number of third-party projects related to Jamulus, which users may find interesting. ## jamulus-php [jamulus-php](https://github.com/softins/jamulus-php) implements a simplified Jamulus client in a PHP web server, which knows enough Jamulus protocol to fetch the list of registered servers from a directory, and a list of active clients from each registered server. It returns the results in JSON for display by a front end, such as [Jamulus Explorer](https://explorer.jamulus.io) or [Jamulus Live](https://jamulus.live/). ## jamulus-web [jamulus-web](https://github.com/softins/jamulus-web) implments the front end used by the [Jamulus Explorer](https://explorer.jamulus.io) web site, which allows a web browser to be used to view the public server directories and the servers that are registered to them. ## jamulus-wireshark [jamulus-wireshark](https://github.com/softins/jamulus-wireshark) is a protocol dissector plugin for Wireshark, to enable Wireshark to understand the structure of the Jamulus protocol and display it in a user-friendly way. It is implemented in LUA. ## jamulus-historytool [jamulus-historytool](https://github.com/pljones/jamulus-historytool) comprises two scripts: - A PHP script to parse the Jamulus log file and emit it as a JSON response - A JS script to parse the JSON response and emit an SVG DOM node This replaces the History Graph that used to be part of the Jamulus server itself. ## jamulus-jamexporter [jamulus-jamexporter](https://github.com/pljones/jamulus-jamexporter) comprises two scripts: - A bash script to monitor the Jamulus recording base directory for new recordings - A bash script to apply some judicious rules and compression before uploading the recordings offsite ## jamulus-docker [jamulus-docker](https://github.com/grundic/jamulus-docker) is an implementation of Jamulus within a Docker container. It provides a `Dockerfile` and some documentation. ## jamulus-server-remote [jamulus-server-remote](https://github.com/vdellamea/jamulus-server-remote) provides a lightweight web front-end for a headless Jamulus server running on Linux. It allows a user to start and stop recordings, and to zip them up and download them via a web browser. It is implemented in PHP. jamulus-3.9.1+dfsg/docs/README.md0000644000175000017500000000056314340334543015367 0ustar vimervimer# Documentation Mostly documentation can be found on the Jamulus Website: https://jamulus.io ## Project related documentation 1. Release process: https://jamulus.io/contribute/Release-Process 2. Style and tone guide: https://jamulus.io/contribute/Style-and-Tone 3. Administration (i.e. how we work) of the Jamulus project: https://jamulus.io/contribute/Administration jamulus-3.9.1+dfsg/.clang-format0000644000175000017500000000336314340334543015534 0ustar vimervimer--- # Style for Clang-Format version 10 # https://releases.llvm.org/10.0.0/tools/clang/docs/ClangFormatStyleOptions.html BasedOnStyle: LLVM AccessModifierOffset: -4 AlignConsecutiveAssignments: true AlignConsecutiveDeclarations: true AlignConsecutiveMacros: true # Alignment of Consecutive Assignments/Declarations/Macros can be changed to `AcrossEmptyLinesAndComments` with Clang-Format version 12 #AlignConsecutiveAssignments: AcrossEmptyLinesAndComments #AlignConsecutiveDeclarations: AcrossEmptyLinesAndComments #AlignConsecutiveMacros: AcrossEmptyLinesAndComments AlignEscapedNewlines: DontAlign AllowAllArgumentsOnNextLine: false AllowAllConstructorInitializersOnNextLine: false AllowAllParametersOfDeclarationOnNextLine: false AllowShortBlocksOnASingleLine: Empty AlwaysBreakTemplateDeclarations: Yes BinPackArguments: false BinPackParameters: false BraceWrapping: AfterCaseLabel: true AfterClass: true AfterControlStatement: Always AfterEnum: true AfterFunction: true AfterNamespace: true AfterObjCDeclaration: true AfterStruct: true AfterUnion: true AfterExternBlock: true BeforeCatch: true BeforeElse: true IndentBraces: false SplitEmptyFunction: false SplitEmptyRecord: false SplitEmptyNamespace: false BreakBeforeBraces: Custom BreakConstructorInitializers: AfterColon ColumnLimit: 150 ConstructorInitializerAllOnOneLineOrOnePerLine: true IndentPPDirectives: AfterHash IndentWidth: 4 PenaltyBreakString: 1000 PenaltyReturnTypeOnItsOwnLine: 1060 PointerAlignment: Left SortIncludes: false SpaceAfterCStyleCast: true SpaceAfterTemplateKeyword: false SpaceBeforeParens: NonEmptyParentheses SpacesInConditionalStatement: true SpacesInParentheses: true ObjCBlockIndentWidth: 4 ObjCSpaceAfterProperty: true ObjCSpaceBeforeProtocolList: true jamulus-3.9.1+dfsg/linux/0000755000175000017500000000000014340334543014313 5ustar vimervimerjamulus-3.9.1+dfsg/linux/debian/0000755000175000017500000000000014340334543015535 5ustar vimervimerjamulus-3.9.1+dfsg/linux/debian/compat0000644000175000017500000000000214340334543016733 0ustar vimervimer9 jamulus-3.9.1+dfsg/linux/debian/rules0000755000175000017500000000273314340334543016622 0ustar vimervimer#!/usr/bin/make -f export QT_SELECT=qt5 DEB_TARGET_GNU_TYPE := $(shell dpkg-architecture -qDEB_TARGET_GNU_TYPE) DEB_HOST_GNU_TYPE := $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) DEB_BUILD_GNU_TYPE := $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) ifeq ($(DEB_BUILD_GNU_TYPE),$(DEB_HOST_GNU_TYPE)) QMAKE := qmake else QMAKE := "/usr/lib/$(DEB_BUILD_GNU_TYPE)/qt5/bin/qmake" -qtconf "/usr/lib/$(DEB_TARGET_GNU_TYPE)/qt5/qt.conf" -spec "/usr/lib/$(DEB_TARGET_GNU_TYPE)/qt5/mkspecs/$(DEB_TARGET_GNU_TYPE)-g++" LIBS+="-lstdc++ -lm" endif %: dh $@ override_dh_update_autotools_config: # dh_update_autotools_config replaces libs/opus/config.{sub,guess}. # This is unnecessary as we don't build opus via autotools at all # (we use qmake). In addition, this would cause our -dev version generation # logic to mark Debian builds as -dirty by default. # Therefore, disable this behavior: : override_dh_auto_configure: mkdir -p build-gui && cd build-gui && $(QMAKE) "CONFIG+=noupcasename" PREFIX=/usr ../Jamulus.pro mkdir -p build-nox && cd build-nox && $(QMAKE) "CONFIG+=headless serveronly" TARGET=jamulus-headless PREFIX=/usr ../Jamulus.pro override_dh_auto_build: cd src/translation && lrelease *.ts cd build-gui && make -j "$$(nproc)" cd build-nox && make -j "$$(nproc)" override_dh_auto_install: cd build-nox && make install INSTALL_ROOT=../debian/tmp cd build-gui && make install INSTALL_ROOT=../debian/tmp override_dh_auto_clean: rm -rf build-gui rm -rf build-nox dh_clean jamulus-3.9.1+dfsg/linux/debian/copyright0000644000175000017500000000242614340334543017474 0ustar vimervimerFormat: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: Jamulus Upstream-Contact: The Jamulus Development Team Source: https://github.com/jamulussoftware/jamulus/ Files: * Copyright: 2021-2022 The Jamulus Development Team and contributors 2004-2021 Volker Fischer and contributors License: GPL-2+ Files: debian/* Copyright: 2020 Tormod Volden 2020 Olivier Humbert 2019 Marc Landolt jr License: GPL-2+ License: GPL-2+ This package is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. . This package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. Comment: You should have received a copy of the GNU General Public License along with this program. If not, see . On Debian systems, the complete text of the GNU General Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". jamulus-3.9.1+dfsg/linux/debian/jamulus-headless.service0000644000175000017500000000113114340334543022361 0ustar vimervimer[Unit] Description=Jamulus headless server After=network.target StartLimitIntervalSec=0 [Service] Type=simple User=jamulus Group=nogroup NoNewPrivileges=true ProtectSystem=true ProtectHome=true Nice=-20 IOSchedulingClass=realtime IOSchedulingPriority=0 #### Change this to publish this server, set genre, location and other parameters. #### See https://jamulus.io/wiki/Command-Line-Options #### ExecStart=/bin/sh -c 'exec /usr/bin/jamulus-headless -s -n' Restart=on-failure RestartSec=30 StandardOutput=journal StandardError=inherit SyslogIdentifier=jamulus [Install] WantedBy=multi-user.target jamulus-3.9.1+dfsg/linux/debian/jamulus-headless.postinst0000755000175000017500000000023114340334543022607 0ustar vimervimer#!/bin/sh set -e # dh_sysuser can be used in newer distro releases adduser --system --quiet --home /nonexistent --no-create-home jamulus #DEBHELPER# jamulus-3.9.1+dfsg/linux/debian/control0000644000175000017500000000444714340334543017151 0ustar vimervimerSource: jamulus Section: sound Priority: optional Maintainer: "The Jamulus Development Team" Build-Depends: debhelper (>= 9), libjack-jackd2-dev, qtbase5-dev, qttools5-dev-tools, Standards-Version: 3.9.7 Homepage: https://jamulus.io Vcs-Git: git://github.com/jamulussoftware/jamulus.git Vcs-Browser: https://github.com/jamulussoftware/jamulus Package: jamulus Architecture: any # Define dependencies explicitly for the best compatibility across all supported Ubuntu/Debian versions. # The automatism would otherwise select package names or versions which are not available on some systems, # especially when run in the Github Ubuntu 18.04 build environment. Depends: libc6 (>= 2.17), libstdc++6 (>= 5.2), libgcc1 (>= 1:3.0), libjack-jackd2-0 (>= 1.9.5~dfsg-14) | libjack-0.116, libqt5core5a (>= 5.9.5), libqt5network5 (>= 5.9.5), libqt5xml5 (>= 5.9.5), libqt5gui5 (>= 5.9.5) | libqt5gui5-gles (>= 5.9.5), libqt5widgets5 (>= 5.9.5), libqt5multimedia5 (>= 5.9.5) Recommends: qjackctl Description: Low latency Audio Server/Client Jamulus is for playing, rehearsing, or just jamming with your friends, your band or just anyone you find online. With high quality, low-latency sound on a normal broadband connection, it's easy to play together remotely and in time. There is one server running the Jamulus server software which collects the audio data from each Jamulus client, mixes the audio data and sends the mix back to each client. . It runs on all major operating systems. Package: jamulus-headless Architecture: any Depends: libc6 (>= 2.17), libstdc++6 (>= 5.2), libgcc1 (>= 1:3.0), libqt5core5a (>= 5.9.5), libqt5network5 (>= 5.9.5), libqt5xml5 (>= 5.9.5) Description: Low latency Audio Server (headless) This package contains a Jamulus binary built for headless operation (without GUI library dependencies) and a jamulus-headless systemd service. Jamulus is for playing, rehearsing, or just jamming with your friends, your band or just anyone you find online. With high quality, low-latency sound on a normal broadband connection, it's easy to play together remotely and in time. There is one server running the Jamulus server software which collects the audio data from each Jamulus client, mixes the audio data and sends the mix back to each client. . It runs on all major operating systems. . jamulus-3.9.1+dfsg/linux/debian/changelog0000644000175000017500000000021314340334543017403 0ustar vimervimerjamulus (3.5.10~git-0) UNRELEASED; urgency=medium * Initial release. -- marc Sun, 26 May 2019 13:11:40 +0200 jamulus-3.9.1+dfsg/linux/debian/jamulus-headless.install0000644000175000017500000000011414340334543022367 0ustar vimervimerusr/bin/jamulus-headless debian/jamulus-headless.service lib/systemd/system jamulus-3.9.1+dfsg/linux/debian/jamulus.install0000644000175000017500000000044114340334543020604 0ustar vimervimerusr/bin/jamulus usr/share/applications/jamulus.desktop usr/share/applications/jamulus-server.desktop usr/share/icons/hicolor/512x512/apps/io.jamulus.jamulus.png usr/share/icons/hicolor/scalable/apps/io.jamulus.jamulus.svg usr/share/icons/hicolor/scalable/apps/io.jamulus.jamulusserver.svg jamulus-3.9.1+dfsg/linux/debian/source/0000755000175000017500000000000014340334543017035 5ustar vimervimerjamulus-3.9.1+dfsg/linux/debian/source/format0000644000175000017500000000001414340334543020243 0ustar vimervimer3.0 (quilt) jamulus-3.9.1+dfsg/linux/debian/watch0000644000175000017500000000035114340334543016565 0ustar vimervimerversion=4 # GitHub hosted projects opts=uversionmangle=s%_%.%g,filenamemangle=s%(?:.*?)?(r\d[\d_]*)\.tar\.gz%@PACKAGE@-$1.tar.gz% \ https://github.com/jamulussoftware/jamulus/tags \ (?:.*?/)?r(\d[\d_]*)\.tar\.gz debian uupdate jamulus-3.9.1+dfsg/linux/deploy_deb.sh0000755000175000017500000000167514340334543016771 0ustar vimervimer#!/bin/bash set -eu -o pipefail # Create deb files TARGET_ARCH="${TARGET_ARCH:-amd64}" cp -r linux/debian . # get the jamulus version from pro file VERSION=$(grep -oP 'VERSION = \K\w[^\s\\]*' Jamulus.pro) export DEBFULLNAME="Jamulus Development Team" DEBEMAIL=team@jamulus.io # Generate Changelog echo -n generating changelog rm -f debian/changelog dch --create --package jamulus --empty --newversion "${VERSION}" '' perl .github/autobuild/extractVersionChangelog.pl ChangeLog "${VERSION}" --line-per-entry | while read -r entry; do echo -n . dch "$entry" done echo echo "${VERSION} building..." CC=$(dpkg-architecture -A"${TARGET_ARCH}" -qDEB_TARGET_GNU_TYPE)-gcc # Note: debuild only handles -a, not the long form --host-arch # There must be no space after -a either, otherwise debuild cannot recognize it and fails during Changelog checks. CC="${CC}" debuild --preserve-env -b -us -uc -j -a"${TARGET_ARCH}" --target-arch "${TARGET_ARCH}" jamulus-3.9.1+dfsg/linux/raspijamulus.sh0000755000175000017500000001216014340334543017371 0ustar vimervimer#!/bin/bash # This script is intended to setup a clean Raspberry Pi system for running Jamulus # This needs to be run from the linux/ folder readonly OPUS="opus-1.3.1" NCORES=$(nproc) readonly NCORES # install required packages readonly pkgs=(alsamixergui build-essential qtbase5-dev qttools5-dev-tools libasound2-dev cmake libglib2.0-dev) if ! dpkg -s "${pkgs[@]}" > /dev/null 2>&1; then read -p "Do you want to install missing packages? " -n 1 -r echo if [[ ${REPLY} =~ ^[Yy]$ ]]; then sudo apt-get install "${pkgs[@]}" -y # Raspbian 10 needs qt5-default; Raspbian 11 doesn't need or provide it if ! qtchooser -list-versions | grep -q default; then sudo apt-get install qt5-default -y fi fi fi # Opus audio codec, custom compilation with custom modes and fixed point support if [ -d "${OPUS}" ]; then echo "The Opus directory is present, we assume it is compiled and ready to use. If not, delete the opus directory and call this script again." else wget https://archive.mozilla.org/pub/opus/"${OPUS}.tar.gz" tar -xzf "${OPUS}.tar.gz" rm "${OPUS}.tar.gz" cd "${OPUS}" || exit 1 if [ "${OPUS}" == "opus-1.3.1" ]; then echo "@@ -117,13 +117,19 @@ void validate_celt_decoder(CELTDecoder *st) #ifndef CUSTOM_MODES celt_assert(st->mode == opus_custom_mode_create(48000, 960, NULL)); celt_assert(st->overlap == 120); + celt_assert(st->end <= 21); +#else +/* From Section 4.3 in the spec: The normal CELT layer uses 21 of those bands, + though Opus Custom (see Section 6.2) may use a different number of bands + + Check if it's within the maximum number of Bark frequency bands instead */ + celt_assert(st->end <= 25); #endif celt_assert(st->channels == 1 || st->channels == 2); celt_assert(st->stream_channels == 1 || st->stream_channels == 2); celt_assert(st->downsample > 0); celt_assert(st->start == 0 || st->start == 17); celt_assert(st->start < st->end); - celt_assert(st->end <= 21); #ifdef OPUS_ARCHMASK celt_assert(st->arch >= 0); celt_assert(st->arch <= OPUS_ARCHMASK);" >> opus_patch_file.diff patch celt/celt_decoder.c opus_patch_file.diff fi ./configure --enable-custom-modes --enable-fixed-point make "-j${NCORES}" mkdir include/opus cp include/*.h include/opus cd .. fi # Jack audio without DBUS support if [ -d "jack2" ]; then echo "The Jack2 directory is present, we assume it is compiled and ready to use. If not, delete the jack2 directory and call this script again." else git clone https://github.com/jackaudio/jack2.git cd jack2 || exit 1 git checkout v1.9.20 ./waf configure --alsa --prefix=/usr/local "--libdir=$(pwd)/build" ./waf "-j${NCORES}" mkdir build/jack cp build/*.so build/jack cp build/common/*.so build/jack cp build/example-clients/*.so build/jack cd .. # give audio group rights to do realtime if grep -Fq "@audio" /etc/security/limits.conf; then echo "audio group already has realtime rights" else sudo sh -c 'echo "@audio - rtprio 95" >> /etc/security/limits.conf' sudo sh -c 'echo "@audio - memlock unlimited" >> /etc/security/limits.conf' fi fi # compile Jamulus with external Opus library cd .. qmake "CONFIG+=opus_shared_lib raspijamulus headless" "INCLUDEPATH+=linux/${OPUS}/include" "QMAKE_LIBDIR+=linux/${OPUS}/.libs" "INCLUDEPATH+=linux/jack2/common" "QMAKE_LIBDIR+=linux/jack2/build/common" Jamulus.pro make "-j${NCORES}" # get first USB audio sound card device ADEVICE=$(aplay -l | grep "USB Audio" | tail -1 | cut -d' ' -f3) echo "Using USB audio device: ${ADEVICE}" # write Jamulus ini file for setting the client name and buffer settings, if there is # just one CPU core, we assume that we are running on a Raspberry Pi Zero JAMULUSINIFILE="Jamulus.ini" NAME64=$(echo "Raspi $(hostname)" | cut -c -16 | tr -d $'\n' | base64) if [ "$NCORES" -gt "1" ]; then echo -e "\n ${NAME64}" > ${JAMULUSINIFILE} echo -e " 1\n 3\n 3" >> ${JAMULUSINIFILE} echo -e " 2\n 1\n" >> ${JAMULUSINIFILE} else echo -e "\n ${NAME64}" > ${JAMULUSINIFILE} echo -e " 1\n 3\n 3" >> ${JAMULUSINIFILE} echo -e " 0\n 1\n" >> ${JAMULUSINIFILE} fi # taken from "Raspberry Pi and realtime, low-latency audio" homepage at wiki.linuxaudio.org #sudo service triggerhappy stop #sudo service dbus stop #sudo mount -o remount,size=128M /dev/shm # start Jack2 and Jamulus in headless mode export LD_LIBRARY_PATH="linux/${OPUS}/.libs:linux/jack2/build:linux/jack2/build/common" linux/jack2/build/jackd -R -T --silent -P70 -p16 -t2000 -d alsa "-dhw:${ADEVICE}" -p 128 -n 3 -r 48000 -s & ./Jamulus -n -i ${JAMULUSINIFILE} -c anygenre3.jamulus.io & echo "###---------- PRESS ANY KEY TO TERMINATE THE JAMULUS SESSION ---------###" read -n 1 -s -r -p "" killall Jamulus jamulus-3.9.1+dfsg/linux/Jamulus.10000644000175000017500000002265614340334543016030 0ustar vimervimer.\" Manual page for Jamulus .\" Copyright (c) 2021 .\" mirabilos .\" Published under the same terms as Jamulus itself. .\"- .Dd December 23, 2021 .Dt JAMULUS 1 .Os .Sh NAME .Nm Jamulus .Nd real-time collaborative music session .Sh SYNOPSIS .Nm .Op Fl 6 | Fl \-enableipv6 .Op Fl c | Fl \-connect Ar address .Op Fl d | Fl \-discononquit .Op Fl e | Fl \-directoryserver Ar hostname .Op Fl F | Fl \-fastupdate .Op Fl f | Fl \-listfilter Ar filter .Op Fl h | Fl \&? | Fl \-help .Op Fl i | Fl \-inifile Ar file .Op Fl j | Fl \-nojackconnect .Op Fl L | Fl \-licence .Op Fl l | Fl \-log Ar file .Op Fl M | Fl \-mutestream .Op Fl m | Fl \-htmlstatus Ar file .Op Fl n | Fl \-nogui .Op Fl o | Fl \-serverinfo Ar info .Op Fl P | Fl \-delaypan .Op Fl p | Fl \-port Ar number .Op Fl Q | Fl \-qos Ar value .Op Fl R | Fl \-recording Ar directory .Op Fl s | Fl \-server .Op Fl T | Fl \-multithreading .Op Fl t | Fl \-notranslation .Op Fl u | Fl \-numchannels .Op Fl v | Fl \-version .Op Fl w | Fl \-welcomemessage Ar message .Op Fl z | Fl \-startminimized .Op Fl \-centralserver Ar hostname .Op Fl \-clientname Ar name .Op Fl \-ctrlmidich Ar MIDISetup .Op Fl \-directoryfile Ar file .Op Fl \-mutemyown .Op Fl \-norecord .Op Fl \-serverbindip Ar ip .Op Fl \-serverpublicip Ar ip .Op Fl \-showallservers .Op Fl \-showanalyzerconsole .Sh DESCRIPTION .Nm Jamulus , a low-latency audio client and server, enables musicians to perform real-time .Dq jam sessions over the internet. It is available across multiple platforms, so participants of any field can communicate without specialist setup requirements. This is not restricted to music, of course; other use .Pq perhaps conferencing? is also possible. .Pp One participant starts .Nm in Server mode, ideally on a dedicated server (virtual) machine; all participants start the (graphical) Client which transmits audio to the Server, receiving back a mixed stream. Use of a metronome is recommended. Clients should be connected using ethernet, not wireless, and use proper headphone and microphone connections, not Bluetooth. The Server should run on a low-latency system, ideally not a VM. .Pp Running .Nm without any extra options launches the full graphical Client. .Pp The options are as follows: .Bl -tag -width Ds .It Fl 6 | Fl \-enableipv6 enable IPv6 support .It Fl c | Fl \-connect Ar address .Pq Client mode only connect to the given Server .Ar address .Pq Ar hostname Ns Op Ar :port at startup .It Fl d | Fl \-discononquit .Pq Server mode only disconnect all Clients on quit .It Fl e | Fl \-directoryserver Ar hostname .Pq Server mode only Register the Server with the given Directory by setting the Directory Server Address to use to .Ar hostname ; see also .Fl o ; to be a Directory Server, use .Dq Li localhost .It Fl F | Fl \-fastupdate .Pq Server mode only use 64 samples frame size mode, which reduces latency if Clients connect with .Dq enable small network buffers turned on; requires a faster CPU to avoid dropouts and uses more bandwidth to connected Clients .It Fl \-jsonrpcsecretfile Ar file (Server mode only) Set the path to a text .Ar file containing an authentication string for obtaining access to the JSON-RPC API. This option is required when .Fl \-jsonrpcport is used. .It Fl \-jsonrpcport Ar port (Server mode only) Enables JSON-RPC API server to control the application, set the TCP .Ar port number. This API is .Em experimental and may change. It is only accessible from localhost. Please refer to the JSON-RPC API Documentation. .It Fl f | Fl \-listfilter Ar filter .Pq Directory mode only whitelist which Servers are allowed to register on the server list; .Ar filter must consist of semicolon-separated IP addresses .It Fl h | Fl \&? | Fl \-help display a short help text and exit immediately .It Fl i | Fl \-inifile Ar file .Pq Client and non-headless Server mode only override default initialisation file with .Ar file .It Fl j | Fl \-nojackconnect .Pq Client mode only do not automatically connect to JACK .It Fl L | Fl \-licence .Pq Server mode only require Clients to accept the agreement shown in the welcome message .Pq use Fl w No to set the text before they are allowed joining .It Fl l | Fl \-log Ar file .Pq Server mode only enable logging to .Ar file .It Fl M | Fl \-mutestream .Pq Client mode only start in muted state .It Fl m | Fl \-htmlstatus Ar file .Pq Server mode only write Server status and list of connected Clients, in HTML format, to .Ar file periodically .It Fl n | Fl \-nogui disable the GUI .It Fl o | Fl \-serverinfo Ar info .Pq Registered Servers only set Server location details, formatted as .Sm off .Xo .Ar name Li \&; .Ar city Li \&; .Ar locale .Xc .Sm on where .Ar locale is the numeric value of a .Li QLocale ; see .Pa https://doc.qt.io/qt\-5/qlocale.html#Country\-enum for a list .It Fl P | Fl \-delaypan .Pq Server mode only start with delay panning enabled .It Fl p | Fl \-port Ar number set the local UDP port to use to .Ar number .Pq default: 22124 .It Fl Q | Fl \-qos Ar value set QoS .Ar value .Pq iptos byte to use .Pq default: 128 .It Fl R | Fl \-recording Ar Directory .Pq Server mode only enable recording .Pq but see Fl \-norecord storing tracks in .Ar Directory .It Fl s | Fl \-server start in Server mode .It Fl T | Fl \-multithreading .Pq Server mode only use multithreading to make better use of multi-core CPUs and support more Clients .It Fl t | Fl \-notranslation disable translations, use built-in English strings .It Fl u | Fl \-numchannels .Pq Server mode only set maximum number of channels .Pq and , therefore , users ; default is 10, maximum is 150 .It Fl v | Fl \-version display version information and exit immediately .It Fl w | Fl \-welcomemessage Ar message .Pq Server mode only show .Ar message .Pq may contain HTML and inline CSS to users on connect .It Fl z | Fl \-startminimized .Pq Server mode only start with minimised window .It Fl \-centralserver Ar hostname .Pq Server mode only deprecated alias for .Fl \-directoryserver .It Fl \-clientname Ar name .Pq Client mode only set window title and JACK client name .It Fl \-ctrlmidich Ar MIDISetup .Pq Client mode only set MIDI controller channel to listen on, control number offset and consecutive CC numbers (channels); format: .Sm off .Xo .Ar channel .Op Li \&;f Ar off Li \&* Ar nchans .Op Li \&;p Ar off Li \&* Ar nchans .Op Li \&;s Ar off Li \&* Ar nchans .Op Li \&;m Ar off Li \&* Ar nchans .Xc .Sm on .Pp The first semicolon-separated element sets the MIDI channel .Nm listens on for control messages. The other elements specify the items to control by their first literal letter (f\ =\ volume fader, p\ =\ pan, m\ =\ mute, s\ =\ solo) directly followed by the offset (CC number) to start from, a literal asterisk, and the amount of consecutive CC numbers to assign. Fader strips in the mixer window are controlled in ascending order from left to right. .Nm does not provide feedback as to the current state of the Solo and Mute buttons so the controller must track and signal their state locally. .It Fl \-directoryfile Ar file .Pq Directory mode only remember registered Servers even if the Directory is restarted .It Fl \-mutemyown .Pq headless Client only mute my channel in my personal mix .It Fl \-norecord .Pq Server mode only do not automatically start recording even if configured with .Fl R .It Fl \-serverbindip Ar ip .Pq Server mode only configure Legacy IP address to bind to .It Fl \-serverpublicip Ar ip .Pq Server mode only configure public legacy IP address when both the Directory Server and the actual Server are situated behind the same NAT, so that Clients can connect .It Fl \-showallservers .Pq Client mode only show all registered Servers in the serverlist regardless whether a ping to the Server is possible or not .Pq debugging command .It Fl \-showanalyzerconsole .Pq Client mode only show analyser console to debug network buffer properties .Pq debugging command .El .Pp Note that the debugging commands are not intended for general use. .Pp .Nm Jamulus knows four modes of operation: Client mode and three kinds of Server .Pq Unregistered, Registered, Directory. A Unregistered Server is unlisted, Clients can only connect if given the address (IP address and port). A Registered Server will contact a Directory (whose address must be given at Server startup) and show up in that Server's list; Clients can retrieve a list of Registered Servers from the Directory Server. Several Registered Directories are operated by the Jamulus project; there is a Directory for each genre, which is how Registered Jamulus Servers are categorised into genres. .Sh SEE ALSO .Xr qjackctl 1 .Bl -tag -width Ds .It Pa https://jamulus.io/wiki/Software\-Manual online handbook .It Pa https://jamulus.io/wiki/FAQ frequently asked questions .It Pa https://jamulus.io/wiki/Running\-a\-Server documentation on Server configuration and types .It Pa https://jamulus.io/wiki/Server\-Linux#running\-in\-registered\-mode current list of Directory Servers operated by the Jamulus project, controlling the .Dq genre .It Pa https://jamulus.io/wiki/Tips\-Tricks\-More verbose .Fl \-ctrlmidich documentation and other more or less useful information .It Pa https://github.com/jamulussoftware/jamulus/blob/master/docs/JSON\-RPC.md JSON-RPC API Documentation (see .Fl \-jsonrpcport above) .El .Sh AUTHORS .An -nosplit .An mirabilos Aq tg@debian.org wrote this manual page for the Debian project, but it may be used elsewhere as well. .Sh BUGS This manual page was derived from the source code and summarises some of the information from the website, but it could be more helpful. .Pp Some of the networking code assumes Legacy IP .Pq IPv4 . jamulus-3.9.1+dfsg/linux/jamulus-server.desktop.in0000644000175000017500000000130214340334543021273 0ustar vimervimer[Desktop Entry] Name=Jamulus (server) Name[fr]=Jamulus (serveur) Comment=Jam Session Comment[fr]=Séance de bœuf Comment[sv]=Musikaliska jamsessioner över Internet GenericName=Internet Jam Session Software GenericName[fr]=Logiciel de séance de bœuf sur Internet GenericName[es]=Software para Jam Sessions por Internet GenericName[pt]=Software para Jam Sessions pela Internet GenericName[nl]=Software voor jamsessies over internet GenericName[sk]=Softvér na džemovanie cez internet GenericName[sv]=Mjukvara för Jam Sessioner över Internet Exec=$$TARGET -s Icon=io.jamulus.jamulusserver Terminal=false Type=Application Categories=AudioVideo;Audio;Mixer;Qt; Keywords=jam;live;online;music;conference; jamulus-3.9.1+dfsg/linux/jamulus.desktop.in0000644000175000017500000000122514340334543017773 0ustar vimervimer[Desktop Entry] Name=Jamulus Comment=Jam Session Comment[fr]=Séance de bœuf Comment[sv]=Musikaliska jamsessioner över Internet GenericName=Internet Jam Session Software GenericName[fr]=Logiciel de séance de bœuf sur Internet GenericName[es]=Software para Jam Sessions por Internet GenericName[pt]=Software para Jam Sessions pela Internet GenericName[nl]=Software voor jamsessies over internet GenericName[sk]=Softvér na džemovanie cez internet GenericName[sv]=Mjukvara för Jam Sessioner över Internet Exec=$$TARGET Icon=io.jamulus.jamulus Terminal=false Type=Application Categories=AudioVideo;Audio;Mixer;Qt; Keywords=jam;live;online;music;conference; jamulus-3.9.1+dfsg/COPYING0000644000175000017500000004563014340334543014217 0ustar vimervimerGeneral software license: GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS -------------------------------------------------------------------------------- Component "OPUS" license: Copyright 2001-2011 Xiph.Org, Skype Limited, Octasic, Jean-Marc Valin, Timothy B. Terriberry, CSIRO, Gregory Maxwell, Mark Borgerding, Erik de Castro Lopo Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Opus is subject to the royalty-free patent licenses which are specified at: Xiph.Org Foundation: https://datatracker.ietf.org/ipr/1524/ Microsoft Corporation: https://datatracker.ietf.org/ipr/1914/ Broadcom Corporation: https://datatracker.ietf.org/ipr/1526/ -------------------------------------------------------------------------------- Component "Synthesis ToolKit" license: The Synthesis ToolKit in C++ (STK) is a set of open source audio signal processing and algorithmic synthesis classes written in the C++ programming language. STK was designed to facilitate rapid development of music synthesis and audio processing software, with an emphasis on cross-platform functionality, realtime control, ease of use, and educational example code. STK currently runs with realtime support (audio and MIDI) on Linux, Macintosh OS X, and Windows computer platforms. Generic, non-realtime support has been tested under NeXTStep, Sun, and other platforms and should work with any standard C++ compiler. STK WWW site: http://ccrma.stanford.edu/software/stk/ The Synthesis ToolKit in C++ (STK) Copyright (c) 1995-2011 Perry R. Cook and Gary P. Scavone Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. Any person wishing to distribute modifications to the Software is asked to send the modifications to the original developer so that they can be incorporated into the canonical version. This is, however, not a binding provision of this license. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. jamulus-3.9.1+dfsg/.clang-format-ignore0000644000175000017500000000032214340334543017005 0ustar vimervimer# Exclude third party code from clang-format checks. # # This file is used by the clang-format-lint-action on Github. # When updating this list, remember to update Jamulus.pro's CLANG_SOURCES # as well. ./libs jamulus-3.9.1+dfsg/.gitignore0000644000175000017500000000124514340334543015146 0ustar vimervimer.qmake.stash Jamulus Jamulus.ini Makefile *.pro.user* **.cppe **.he .cproject .project .settings .idea .vscode .cache *.user *.user.* *.o moc_*.cpp ui_*.h moc_predefs.h src/res/qrc_resources.cpp libs/ASIOSDK2 windows/VC_redist.x64.exe windows/vc_redist.x86.exe libs/NSIS/nsProcess.dll windows/NSIS libs/NSIS/nsProcess/Release/ debug/ release/ build/ deploy/ build-gui/ build-nox/ jamulus.sln jamulus.vcxproj jamulus.vcxproj.filters Jamulus.app/ .DS_Store linux/opus* linux/jack2 linux/claudio_piano.sf2 linux/fluidsynth* linux/jamulus.desktop linux/jamulus-server.desktop .xcode Debug-iphoneos/ Jamulus.xcodeproj jamulus_plugin_import.cpp .github_release_changelog.md /debian/ jamulus-3.9.1+dfsg/src/0000755000175000017500000000000014340334543013743 5ustar vimervimerjamulus-3.9.1+dfsg/src/analyzerconsole.cpp0000644000175000017500000001662414340334543017670 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include "analyzerconsole.h" // Analyzer console implementation ********************************************* CAnalyzerConsole::CAnalyzerConsole ( CClient* pNCliP, QWidget* parent ) : CBaseDlg ( parent, Qt::Window ), // use Qt::Window to get min/max window buttons pClient ( pNCliP ), GraphImage ( 1, 1, QImage::Format_RGB32 ), GraphErrRateCanvasRect ( 0, 0, 600, 450 ), // defines total size of graph iGridFrameOffset ( 10 ), iLineWidth ( 2 ), iMarkerSize ( 10 ), iXAxisTextHeight ( 22 ), GraphBackgroundColor ( Qt::white ), // background GraphFrameColor ( Qt::black ), // frame GraphGridColor ( Qt::gray ), // grid LineColor ( Qt::blue ), LineLimitColor ( Qt::green ), LineMaxUpLimitColor ( Qt::red ) { // set the window icon and title text const QIcon icon = QIcon ( QString::fromUtf8 ( ":/png/main/res/fronticon.png" ) ); setWindowIcon ( icon ); setWindowTitle ( tr ( "Analyzer Console" ) ); // create main layout QVBoxLayout* pMainLayout = new QVBoxLayout; // create and add main tab widget pMainTabWidget = new QTabWidget ( this ); pMainLayout->addWidget ( pMainTabWidget ); setLayout ( pMainLayout ); // error rate gaph tab pTabWidgetBufErrRate = new QWidget(); QVBoxLayout* pTabErrRateLayout = new QVBoxLayout ( pTabWidgetBufErrRate ); pGraphErrRate = new QLabel ( this ); pTabErrRateLayout->addWidget ( pGraphErrRate ); pMainTabWidget->addTab ( pTabWidgetBufErrRate, tr ( "Error Rate of Each Buffer Size" ) ); // Connections ------------------------------------------------------------- // timers QObject::connect ( &TimerErrRateUpdate, &QTimer::timeout, this, &CAnalyzerConsole::OnTimerErrRateUpdate ); } void CAnalyzerConsole::showEvent ( QShowEvent* ) { // start timer for error rate graph TimerErrRateUpdate.start ( ERR_RATE_GRAPH_UPDATE_TIME_MS ); } void CAnalyzerConsole::hideEvent ( QHideEvent* ) { // if window is closed, stop timer TimerErrRateUpdate.stop(); } void CAnalyzerConsole::OnTimerErrRateUpdate() { // generate current graph image DrawFrame(); DrawErrorRateTrace(); // set new image to the label pGraphErrRate->setPixmap ( QPixmap().fromImage ( GraphImage ) ); } void CAnalyzerConsole::DrawFrame() { // scale image to correct size GraphImage = GraphImage.scaled ( GraphErrRateCanvasRect.width(), GraphErrRateCanvasRect.height() ); // generate plot grid frame rectangle GraphGridFrame.setRect ( GraphErrRateCanvasRect.x() + iGridFrameOffset, GraphErrRateCanvasRect.y() + iGridFrameOffset, GraphErrRateCanvasRect.width() - 2 * iGridFrameOffset, GraphErrRateCanvasRect.height() - 2 * iGridFrameOffset - iXAxisTextHeight ); GraphImage.fill ( GraphBackgroundColor.rgb() ); // fill background // create painter QPainter GraphPainter ( &GraphImage ); // create actual plot region (grid frame) GraphPainter.setPen ( GraphFrameColor ); GraphPainter.drawRect ( GraphGridFrame ); } void CAnalyzerConsole::DrawErrorRateTrace() { // create painter QPainter GraphPainter ( &GraphImage ); // get the network buffer error rates to be displayed CVector vecButErrorRates; double dLimit; double dMaxUpLimit; pClient->GetBufErrorRates ( vecButErrorRates, dLimit, dMaxUpLimit ); // get the number of data elements const int iNumBuffers = vecButErrorRates.Size(); // convert the limits in the log domain const double dLogLimit = log10 ( dLimit ); const double dLogMaxUpLimit = log10 ( dMaxUpLimit ); // use fixed y-axis scale where the limit line is in the middle of the graph const double dMax = 0; const double dMin = dLogLimit * 2; // calculate space between points on the x-axis const double dXSpace = static_cast ( GraphGridFrame.width() ) / ( iNumBuffers - 1 ); // plot the limit line as dashed line const double dYValLimitInGraph = CalcYPosInGraph ( dMin, dMax, dLogLimit ); GraphPainter.setPen ( QPen ( QBrush ( LineLimitColor ), iLineWidth, Qt::DashLine ) ); GraphPainter.drawLine ( QPoint ( GraphGridFrame.x(), dYValLimitInGraph ), QPoint ( GraphGridFrame.x() + GraphGridFrame.width(), dYValLimitInGraph ) ); // plot the maximum upper limit line as a dashed line const double dYValMaxUpLimitInGraph = CalcYPosInGraph ( dMin, dMax, dLogMaxUpLimit ); GraphPainter.setPen ( QPen ( QBrush ( LineMaxUpLimitColor ), iLineWidth, Qt::DashLine ) ); GraphPainter.drawLine ( QPoint ( GraphGridFrame.x(), dYValMaxUpLimitInGraph ), QPoint ( GraphGridFrame.x() + GraphGridFrame.width(), dYValMaxUpLimitInGraph ) ); // plot the data for ( int i = 0; i < iNumBuffers; i++ ) { // data convert in log domain // check for special case if error rate is 0 (which would lead to -Inf // after the log operation) if ( vecButErrorRates[i] > 0 ) { vecButErrorRates[i] = log10 ( vecButErrorRates[i] ); } else { // definition: set it to lowest possible axis value vecButErrorRates[i] = dMin; } // calculate the actual point in the graph (in pixels) const QPoint curPoint ( GraphGridFrame.x() + static_cast ( dXSpace * i ), CalcYPosInGraph ( dMin, dMax, vecButErrorRates[i] ) ); // draw a marker and a solid line which goes from the bottom to the // marker (similar to Matlab stem() function) GraphPainter.setPen ( QPen ( QBrush ( LineColor ), iMarkerSize, Qt::SolidLine, Qt::RoundCap ) ); GraphPainter.drawPoint ( curPoint ); GraphPainter.setPen ( QPen ( QBrush ( LineColor ), iLineWidth ) ); GraphPainter.drawLine ( QPoint ( curPoint.x(), GraphGridFrame.y() + GraphGridFrame.height() ), curPoint ); } } int CAnalyzerConsole::CalcYPosInGraph ( const double dAxisMin, const double dAxisMax, const double dValue ) const { // calculate value range const double dValRange = dAxisMax - dAxisMin; // calculate current normalized y-axis value const double dYValNorm = ( dValue - dAxisMin ) / dValRange; // consider the graph grid size to calculate the final y-axis value return GraphGridFrame.y() + static_cast ( static_cast ( GraphGridFrame.height() ) * ( 1 - dYValNorm ) ); } jamulus-3.9.1+dfsg/src/serverlogging.h0000644000175000017500000000331214340334543016770 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #include #include #include #include #include #include "global.h" #include "util.h" /* Classes ********************************************************************/ class CServerLogging { public: CServerLogging() : bDoLogging ( false ), File ( DEFAULT_LOG_FILE_NAME ) {} virtual ~CServerLogging(); void Start ( const QString& strLoggingFileName ); void AddServerStopped(); void AddNewConnection ( const QHostAddress& ClientInetAddr, const int iNumberOfConnectedClients ); protected: void operator<< ( const QString& sNewStr ); QString CurTimeDatetoLogString(); bool bDoLogging; QFile File; }; jamulus-3.9.1+dfsg/src/rpcserver.h0000644000175000017500000000546614340334543016142 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2021-2022 * * Author(s): * dtinth * Christian Hoffmann * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #include #include #include #include #include #include #include #include #include #include typedef std::function CRpcHandler; /* Classes ********************************************************************/ class CRpcServer : public QObject { Q_OBJECT public: CRpcServer ( QObject* parent, int iPort, QString secret ); virtual ~CRpcServer(); bool Start(); void HandleMethod ( const QString& strMethod, CRpcHandler pHandler ); void BroadcastNotification ( const QString& strMethod, const QJsonObject& aParams ); static QJsonObject CreateJsonRpcError ( int code, QString message ); // JSON-RPC standard error codes static const int iErrInvalidRequest = -32600; static const int iErrMethodNotFound = -32601; static const int iErrInvalidParams = -32602; static const int iErrParseError = -32700; // Our errors static const int iErrAuthenticationFailed = 400; static const int iErrUnauthenticated = 401; private: int iPort; QString strSecret; QTcpServer* pTransportServer; // A map from method name to handler functions QMap mapMethodHandlers; QMap isAuthenticated; QVector vecClients; void HandleApiAuth ( QTcpSocket* pSocket, const QJsonObject& params, QJsonObject& response ); void ProcessMessage ( QTcpSocket* pSocket, QJsonObject message, QJsonObject& response ); void Send ( QTcpSocket* pSocket, const QJsonDocument& aMessage ); static QJsonObject CreateJsonRpcErrorReply ( int code, QString message ); protected slots: void OnNewConnection(); }; jamulus-3.9.1+dfsg/src/serverdlg.cpp0000644000175000017500000011357614340334543016461 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include "serverdlg.h" /* Implementation *************************************************************/ CServerDlg::CServerDlg ( CServer* pNServP, CServerSettings* pNSetP, const bool bStartMinimized, QWidget* parent ) : CBaseDlg ( parent, Qt::Window ), // use Qt::Window to get min/max window buttons pServer ( pNServP ), pSettings ( pNSetP ), BitmapSystemTrayInactive ( QString::fromUtf8 ( ":/png/main/res/servertrayiconinactive.png" ) ), BitmapSystemTrayActive ( QString::fromUtf8 ( ":/png/main/res/servertrayiconactive.png" ) ) { // check if system tray icon can be used bSystemTrayIconAvailable = SystemTrayIcon.isSystemTrayAvailable(); setupUi ( this ); // set window title setWindowTitle ( tr ( "%1 Server", "%1 is the name of the main application" ).arg ( APP_NAME ) ); // Add help text to controls ----------------------------------------------- // Tab: Server setup // client list lvwClients->setWhatsThis ( "" + tr ( "Client List" ) + ": " + tr ( "The client list shows all clients which are currently connected to this " "server. Some information about the clients like the IP address and name " "are given for each connected client." ) ); lvwClients->setAccessibleName ( tr ( "Connected clients list view" ) ); // Server list selection combo box QString strDirectoryTypeAN = tr ( "Directory Type combo box" ); lblDirectoryType->setAccessibleName ( strDirectoryTypeAN ); cbxDirectoryType->setAccessibleName ( strDirectoryTypeAN ); QString strDirectoryTypeWT = "" + tr ( "Directory" ) + ": " + tr ( "Select '%1' not to register your server with a directory." ).arg ( DirectoryTypeToString ( AT_NONE ) ) + "
" + tr ( "Select one of the genres to register with that directory." ) + "
" + tr ( "Or select '%1' and specify a Custom Directory address on the " "Options tab to register with a custom directory." ) .arg ( DirectoryTypeToString ( AT_CUSTOM ) ) + "

" + tr ( "For any value except '%1', this server registers " "with a directory so that a %2 user can select this server " "in the client connect dialog server list when they choose that directory." ) .arg ( DirectoryTypeToString ( AT_NONE ) ) .arg ( APP_NAME ) + "

" + tr ( "The registration of the server is renewed periodically " "to make sure that all servers in the connect dialog server list are " "actually available." ); lblDirectoryType->setWhatsThis ( strDirectoryTypeWT ); cbxDirectoryType->setWhatsThis ( strDirectoryTypeWT ); // server registration status label lblRegSvrStatus->setWhatsThis ( "" + tr ( "Register Server Status" ) + ": " + tr ( "When a value other than \"%1\" is chosen for Directory, this will show " "whether registration is successful. If the registration failed, " "please choose a different directory." ) .arg ( DirectoryTypeToString ( AT_NONE ) ) ); // server name QString strServName = "" + tr ( "Server Name" ) + ": " + tr ( "The server name identifies " "your server in the connect dialog server list at the clients." ); lblServerName->setWhatsThis ( strServName ); edtServerName->setWhatsThis ( strServName ); edtServerName->setAccessibleName ( tr ( "Server name line edit" ) ); // location city QString strLocCity = "" + tr ( "Location City" ) + ": " + tr ( "The city in which this " "server is located can be set here. If a city name is entered, it " "will be shown in the connect dialog server list at the clients." ); lblLocationCity->setWhatsThis ( strLocCity ); edtLocationCity->setWhatsThis ( strLocCity ); edtLocationCity->setAccessibleName ( tr ( "City where the server is located line edit" ) ); // location country QString strLocCountry = "" + tr ( "Country/Region" ) + ": " + tr ( "Set the country or region where the server is running. " "Clients will show this location in their connect dialog's server " "list." ); lblLocationCountry->setWhatsThis ( strLocCountry ); cbxLocationCountry->setWhatsThis ( strLocCountry ); cbxLocationCountry->setAccessibleName ( tr ( "Combo box for location of this server" ) ); // enable recorder chbEnableRecorder->setAccessibleName ( tr ( "Checkbox to turn on or off server recording" ) ); chbEnableRecorder->setWhatsThis ( "" + tr ( "Enable Recorder" ) + ": " + tr ( "Checked when the recorder is enabled, otherwise unchecked. " "The recorder will run when a session is in progress, if (set up correctly and) enabled." ) ); // new recording pbtNewRecording->setAccessibleName ( tr ( "Request new recording button" ) ); pbtNewRecording->setWhatsThis ( "" + tr ( "New Recording" ) + ": " + tr ( "During a recording session, the button can be used to start a new recording." ) ); // recorder status lblRecorderStatus->setAccessibleName ( tr ( "Recorder status label" ) ); lblRecorderStatus->setWhatsThis ( "" + tr ( "Recorder Status" ) + ": " + tr ( "Displays the current status of the recorder. The following values are possible:" ) + "
" + "
" + SREC_NOT_INITIALISED + "
" + "
" + tr ( "No recording directory has been set or the value is not useable. " "Check the value in the Options tab." ) + "
" + "
" + SREC_NOT_ENABLED + "
" + "
" #ifdef _WIN32 + tr ( "Recording has been switched off by the UI checkbox." ) #else + tr ( "Recording has been switched off, either by the UI checkbox or SIGUSR2 being received." ) #endif + "
" + "
" + SREC_NOT_RECORDING + "
" + "
" + tr ( "There is no one connected to the server to record." ) + "
" + "
" + SREC_RECORDING + "
" + "
" + tr ( "The performers are being recorded to the specified session directory." ) + "
" + "
" + "
" + tr ( "NOTE" ) + ": " + tr ( "If the recording directory is not useable, the problem will be displayed in place of the session directory." ) ); // current session directory QString strCurrentSessionDirAN = tr ( "Current session directory text box (read-only)" ); lblCurrentSessionDir->setAccessibleName ( strCurrentSessionDirAN ); edtCurrentSessionDir->setAccessibleName ( strCurrentSessionDirAN ); QString strCurrentSessionDirWT = "" + tr ( "Current Session Directory" ) + ": " + tr ( "Enabled during recording and holds the current recording session directory. " "Disabled after recording or when the recorder is not enabled." ); lblCurrentSessionDir->setWhatsThis ( strCurrentSessionDirWT ); edtCurrentSessionDir->setWhatsThis ( strCurrentSessionDirWT ); // welcome message tedWelcomeMessage->setAccessibleName ( tr ( "Server welcome message edit box" ) ); tedWelcomeMessage->setWhatsThis ( "" + tr ( "Server Welcome Message" ) + ": " + tr ( "A server welcome message text is displayed in the chat window if a " "musician enters the server. If no message is set, the server welcome is disabled." ) ); // Tab: options // Interface Language QString strWTLanguage = "" + tr ( "Language" ) + ": " + tr ( "Select the language to be used for the user interface." ); lblLanguage->setWhatsThis ( strWTLanguage ); cbxLanguage->setWhatsThis ( strWTLanguage ); cbxLanguage->setAccessibleName ( tr ( "Language combo box" ) ); // recording directory pbtRecordingDir->setAccessibleName ( tr ( "Display dialog to select recording directory button" ) ); pbtRecordingDir->setWhatsThis ( "" + tr ( "Main Recording Directory" ) + ": " + tr ( "Click the button to open the dialog that allows the main recording directory to be selected. " "The chosen value must exist and be writeable (allow creation of sub-directories " "by the user %1 is running as)." ) .arg ( APP_NAME ) ); edtRecordingDir->setAccessibleName ( tr ( "Main recording directory text box (read-only)" ) ); edtRecordingDir->setWhatsThis ( "" + tr ( "Main Recording Directory" ) + ": " + tr ( "The current value of the main recording directory. " "The chosen value must exist and be writeable (allow creation of sub-directories " "by the user %1 is running as). " "Click the button to open the dialog that allows the main recording directory to be selected." ) .arg ( APP_NAME ) ); tbtClearRecordingDir->setAccessibleName ( tr ( "Clear the recording directory button" ) ); tbtClearRecordingDir->setWhatsThis ( "" + tr ( "Clear Recording Directory" ) + ": " + tr ( "Click the button to clear the currently selected recording directory. " "This will prevent recording until a new value is selected." ) ); // custom directory QString strCustomDirectory = "" + tr ( "Custom Directory address" ) + ": " + tr ( "The Custom Directory address is the address of the directory " "holding the server list to which this server should be added." ); lblCustomDirectory->setWhatsThis ( strCustomDirectory ); edtCustomDirectory->setWhatsThis ( strCustomDirectory ); edtCustomDirectory->setAccessibleName ( tr ( "Custom Directory line edit" ) ); // server list persistence file name (directory server only) pbtServerListPersistence->setAccessibleName ( tr ( "Server List Filename dialog push button" ) ); pbtServerListPersistence->setWhatsThis ( "" + tr ( "Server List Filename" ) + ": " + tr ( "Click the button to open the dialog that allows the " "server list persistence file name to be set. The user %1 is running as " "needs to be able to create the file name specified " "although it may already exist (it will get overwritten on save)." ) .arg ( APP_NAME ) ); edtServerListPersistence->setAccessibleName ( tr ( "Server List Filename text box (read-only)" ) ); edtServerListPersistence->setWhatsThis ( "" + tr ( "Server List Filename" ) + ": " + tr ( "The current value of server list persistence file name. The user %1 is running as " "needs to be able to create the file name specified " "although it may already exist (it will get overwritten on save). " "Click the button to open the dialog that allows the " "server list persistence file name to be set." ) .arg ( APP_NAME ) ); tbtClearServerListPersistence->setAccessibleName ( tr ( "Clear the server list file name button" ) ); tbtClearServerListPersistence->setWhatsThis ( "" + tr ( "Clear Server List Filename" ) + ": " + tr ( "Click the button to clear the currently selected server list persistence file name. " "This will prevent persisting the server list until a new value is selected." ) ); // start minimized on operating system start chbStartOnOSStart->setWhatsThis ( "" + tr ( "Start Minimized on Operating System Start" ) + ": " + tr ( "If the start minimized on operating system start " "check box is checked, the server will be " "started when the operating system starts up and is automatically " "minimized to a system task bar icon." ) ); // Application initialisation // init system tray icon if ( bSystemTrayIconAvailable ) { // prepare context menu to be added to the system tray icon pSystemTrayIconMenu = new QMenu ( this ); pSystemTrayIconMenu->addAction ( tr ( "E&xit" ), this, SLOT ( OnSysTrayMenuExit() ) ); pSystemTrayIconMenu->addSeparator(); pSystemTrayIconMenu->addAction ( tr ( "&Hide %1 server" ).arg ( APP_NAME ), this, SLOT ( OnSysTrayMenuHide() ) ); pSystemTrayIconMenu->setDefaultAction ( pSystemTrayIconMenu->addAction ( tr ( "&Show %1 server" ).arg ( APP_NAME ), this, SLOT ( OnSysTrayMenuOpen() ) ) ); SystemTrayIcon.setContextMenu ( pSystemTrayIconMenu ); // set tool text SystemTrayIcon.setToolTip ( tr ( "%1 server", "%1 is the name of the main application" ).arg ( APP_NAME ) ); // show icon of state "inactive" SystemTrayIcon.setIcon ( QIcon ( BitmapSystemTrayInactive ) ); SystemTrayIcon.show(); } // act on "start minimized" flag (note, this has to be done after setting // and acting on the correct value for the system tray icon availablility) if ( bStartMinimized ) { showMinimized(); } // UI initialisation // set up list view for connected clients lvwClients->setColumnWidth ( 0, 170 ); // 170 // IP:port lvwClients->setColumnWidth ( 1, 200 ); // 200 // Name lvwClients->setColumnWidth ( 2, 120 ); // 60 // Buf-Frames lvwClients->setColumnWidth ( 3, 50 ); // Channels lvwClients->clear(); //### TODO: BEGIN ###// // workaround for resize problem of window after iconize in task bar lvwClients->setMinimumWidth ( 170 + 130 + 60 + 205 ); lvwClients->setMinimumHeight ( 140 ); //### TODO: END ###// // insert items in reverse order because in Windows all of them are // always visible -> put first item on the top vecpListViewItems.Init ( MAX_NUM_CHANNELS ); for ( int i = MAX_NUM_CHANNELS - 1; i >= 0; i-- ) { vecpListViewItems[i] = new QTreeWidgetItem ( lvwClients ); vecpListViewItems[i]->setHidden ( true ); } // directory type combo box cbxDirectoryType->clear(); cbxDirectoryType->addItem ( DirectoryTypeToString ( AT_NONE ) ); cbxDirectoryType->addItem ( DirectoryTypeToString ( AT_DEFAULT ) ); cbxDirectoryType->addItem ( DirectoryTypeToString ( AT_ANY_GENRE2 ) ); cbxDirectoryType->addItem ( DirectoryTypeToString ( AT_ANY_GENRE3 ) ); cbxDirectoryType->addItem ( DirectoryTypeToString ( AT_GENRE_ROCK ) ); cbxDirectoryType->addItem ( DirectoryTypeToString ( AT_GENRE_JAZZ ) ); cbxDirectoryType->addItem ( DirectoryTypeToString ( AT_GENRE_CLASSICAL_FOLK ) ); cbxDirectoryType->addItem ( DirectoryTypeToString ( AT_GENRE_CHORAL ) ); cbxDirectoryType->addItem ( DirectoryTypeToString ( AT_CUSTOM ) ); // server info max lengths edtServerName->setMaxLength ( MAX_LEN_SERVER_NAME ); edtLocationCity->setMaxLength ( MAX_LEN_SERVER_CITY ); // load country combo box with all available countries cbxLocationCountry->setInsertPolicy ( QComboBox::NoInsert ); cbxLocationCountry->clear(); for ( int iCurCntry = static_cast ( QLocale::AnyCountry ); iCurCntry < static_cast ( QLocale::LastCountry ); iCurCntry++ ) { // add all countries except of the "Default" country if ( static_cast ( iCurCntry ) == QLocale::AnyCountry ) { continue; } if ( !CLocale::IsCountryCodeSupported ( iCurCntry ) ) { // The current Qt version which is the base for the loop may support // more country codes than our protocol does. Therefore, skip // the unsupported options to avoid surprises. continue; } // store the country enum index together with the string (this is // important since we sort the combo box items later on) cbxLocationCountry->addItem ( QLocale::countryToString ( static_cast ( iCurCntry ) ), iCurCntry ); } // sort country combo box items in alphabetical order cbxLocationCountry->model()->sort ( 0, Qt::AscendingOrder ); // setup welcome message GUI control tedWelcomeMessage->setPlaceholderText ( tr ( "Type a message here. If no message is set, the server welcome is disabled." ) ); // language combo box (corrects the setting if language not found) cbxLanguage->Init ( pSettings->strLanguage ); // recorder options pbtRecordingDir->setAutoDefault ( false ); tbtClearRecordingDir->setText ( u8"\u232B" ); // server list persistence file pbtServerListPersistence->setAutoDefault ( false ); tbtClearServerListPersistence->setText ( u8"\u232B" ); // update start minimized check box (only available for Windows) #ifndef _WIN32 chbStartOnOSStart->setVisible ( false ); #else const bool bCurAutoStartMinState = pServer->GetAutoRunMinimized(); if ( bCurAutoStartMinState ) { chbStartOnOSStart->setCheckState ( Qt::Checked ); } else { chbStartOnOSStart->setCheckState ( Qt::Unchecked ); } // modify registry according to setting (this is just required in case a // user has changed the registry by hand) ModifyAutoStartEntry ( bCurAutoStartMinState ); #endif // update delay panning check box if ( pServer->IsDelayPanningEnabled() ) { chbEnableDelayPanning->setCheckState ( Qt::Checked ); } else { chbEnableDelayPanning->setCheckState ( Qt::Unchecked ); } // prepare update check info label (invisible by default) lblUpdateCheck->setOpenExternalLinks ( true ); // enables opening a web browser if one clicks on a html link lblUpdateCheck->setText ( "" + APP_UPGRADE_AVAILABLE_MSG_TEXT.arg ( APP_NAME ).arg ( VERSION ) + "" ); lblUpdateCheck->hide(); // update GUI dependencies UpdateGUIDependencies(); UpdateRecorderStatus ( QString() ); // View menu -------------------------------------------------------------- QMenu* pViewMenu = new QMenu ( tr ( "&Window" ), this ); pViewMenu->addAction ( tr ( "E&xit" ), this, SLOT ( close() ), QKeySequence ( Qt::CTRL + Qt::Key_Q ) ); // Main menu bar ----------------------------------------------------------- pMenu = new QMenuBar ( this ); pMenu->addMenu ( pViewMenu ); pMenu->addMenu ( new CHelpMenu ( false, this ) ); // Now tell the layout about the menu layout()->setMenuBar ( pMenu ); // Window positions -------------------------------------------------------- // main window if ( !pSettings->vecWindowPosMain.isEmpty() && !pSettings->vecWindowPosMain.isNull() ) { restoreGeometry ( pSettings->vecWindowPosMain ); } // Connections ------------------------------------------------------------- // check boxes QObject::connect ( chbEnableRecorder, &QCheckBox::stateChanged, this, &CServerDlg::OnEnableRecorderStateChanged ); QObject::connect ( chbStartOnOSStart, &QCheckBox::stateChanged, this, &CServerDlg::OnStartOnOSStartStateChanged ); QObject::connect ( chbEnableDelayPanning, &QCheckBox::stateChanged, this, &CServerDlg::OnEnableDelayPanningStateChanged ); // line edits QObject::connect ( edtServerName, &QLineEdit::editingFinished, this, &CServerDlg::OnServerNameEditingFinished ); QObject::connect ( edtLocationCity, &QLineEdit::editingFinished, this, &CServerDlg::OnLocationCityEditingFinished ); QObject::connect ( edtCustomDirectory, &QLineEdit::editingFinished, this, &CServerDlg::OnCustomDirectoryEditingFinished ); // combo boxes QObject::connect ( cbxDirectoryType, static_cast ( &QComboBox::currentIndexChanged ), this, &CServerDlg::OnDirectoryTypeCurrentIndexChanged ); QObject::connect ( cbxLocationCountry, static_cast ( &QComboBox::currentIndexChanged ), this, &CServerDlg::OnLocationCountryCurrentIndexChanged ); QObject::connect ( cbxLanguage, &CLanguageComboBox::LanguageChanged, this, &CServerDlg::OnLanguageChanged ); // push buttons QObject::connect ( pbtNewRecording, &QPushButton::released, this, &CServerDlg::OnNewRecordingClicked ); QObject::connect ( pbtRecordingDir, &QPushButton::released, this, &CServerDlg::OnRecordingDirClicked ); QObject::connect ( pbtServerListPersistence, &QPushButton::released, this, &CServerDlg::OnServerListPersistenceClicked ); // tool buttons QObject::connect ( tbtClearRecordingDir, &QToolButton::released, this, &CServerDlg::OnClearRecordingDirClicked ); QObject::connect ( tbtClearServerListPersistence, &QToolButton::released, this, &CServerDlg::OnClearServerListPersistenceClicked ); // timers QObject::connect ( &Timer, &QTimer::timeout, this, &CServerDlg::OnTimer ); // other QObject::connect ( tedWelcomeMessage, &QTextEdit::textChanged, this, &CServerDlg::OnWelcomeMessageChanged ); QObject::connect ( pServer, &CServer::Started, this, &CServerDlg::OnServerStarted ); QObject::connect ( pServer, &CServer::Stopped, this, &CServerDlg::OnServerStopped ); QObject::connect ( pServer, &CServer::SvrRegStatusChanged, this, &CServerDlg::OnSvrRegStatusChanged ); QObject::connect ( pServer, &CServer::RecordingSessionStarted, this, &CServerDlg::OnRecordingSessionStarted ); QObject::connect ( pServer, &CServer::StopRecorder, this, &CServerDlg::OnStopRecorder ); QObject::connect ( pServer, &CServer::CLVersionAndOSReceived, this, &CServerDlg::OnCLVersionAndOSReceived ); QObject::connect ( &SystemTrayIcon, &QSystemTrayIcon::activated, this, &CServerDlg::OnSysTrayActivated ); // Initializations which have to be done after the signals are connected --- // start timer for GUI controls Timer.start ( GUI_CONTRL_UPDATE_TIME ); // query the update server version number needed for update check (note // that the connection less message respond may not make it back but that // is not critical since the next time Jamulus is started we have another // chance and the update check is not time-critical at all) CHostAddress UpdateServerHostAddress; // Send the request to two servers for redundancy if either or both of them // has a higher release version number, the reply will trigger the notification. if ( NetworkUtil().ParseNetworkAddress ( UPDATECHECK1_ADDRESS, UpdateServerHostAddress, pServer->IsIPv6Enabled() ) ) { pServer->CreateCLServerListReqVerAndOSMes ( UpdateServerHostAddress ); } if ( NetworkUtil().ParseNetworkAddress ( UPDATECHECK2_ADDRESS, UpdateServerHostAddress, pServer->IsIPv6Enabled() ) ) { pServer->CreateCLServerListReqVerAndOSMes ( UpdateServerHostAddress ); } } void CServerDlg::closeEvent ( QCloseEvent* Event ) { // store window positions pSettings->vecWindowPosMain = saveGeometry(); // default implementation of this event handler routine Event->accept(); } void CServerDlg::OnStartOnOSStartStateChanged ( int value ) { const bool bCurAutoStartMinState = ( value == Qt::Checked ); // update registry and server setting (for ini file) pServer->SetAutoRunMinimized ( bCurAutoStartMinState ); ModifyAutoStartEntry ( bCurAutoStartMinState ); } void CServerDlg::OnServerNameEditingFinished() { QString strNewName = edtServerName->text(); // check length if ( strNewName.length() <= MAX_LEN_SERVER_NAME ) { // apply new setting to the server and update it pServer->SetServerName ( strNewName ); } else { // text is too long, update control with shortened text edtServerName->setText ( strNewName.left ( MAX_LEN_SERVER_NAME ) ); } } void CServerDlg::OnLocationCityEditingFinished() { QString strNewCity = edtLocationCity->text(); // check length if ( strNewCity.length() <= MAX_LEN_SERVER_CITY ) { // apply new setting to the server and update it pServer->SetServerCity ( strNewCity ); } else { // text is too long, update control with shortened text edtLocationCity->setText ( strNewCity.left ( MAX_LEN_SERVER_CITY ) ); } } void CServerDlg::OnCustomDirectoryEditingFinished() { // apply new setting to the server and update it pServer->SetDirectoryAddress ( edtCustomDirectory->text() ); // update GUI dependencies UpdateGUIDependencies(); } void CServerDlg::OnLocationCountryCurrentIndexChanged ( int iCntryListItem ) { // apply new setting to the server and update it pServer->SetServerCountry ( static_cast ( cbxLocationCountry->itemData ( iCntryListItem ).toInt() ) ); } void CServerDlg::OnDirectoryTypeCurrentIndexChanged ( int iTypeIdx ) { // apply new setting to the server and update it pServer->SetDirectoryType ( static_cast ( iTypeIdx - 1 ) ); // update GUI dependencies UpdateGUIDependencies(); } void CServerDlg::OnServerStarted() { UpdateSystemTrayIcon ( true ); UpdateRecorderStatus ( QString() ); } void CServerDlg::OnServerStopped() { UpdateSystemTrayIcon ( false ); UpdateRecorderStatus ( QString() ); } void CServerDlg::OnStopRecorder() { UpdateRecorderStatus ( QString() ); if ( pServer->GetRecorderErrMsg() != QString() ) { QMessageBox::warning ( this, APP_NAME, tr ( "Recorder failed to start. " "Please check available disk space and permissions and try again. " "Error: " ) + pServer->GetRecorderErrMsg() ); } } void CServerDlg::OnRecordingDirClicked() { // get the current value from pServer QString currentValue = pServer->GetRecordingDir(); QString newRecordingDir = QFileDialog::getExistingDirectory ( this, tr ( "Select Main Recording Directory" ), currentValue, QFileDialog::ShowDirsOnly | QFileDialog::DontUseNativeDialog ); if ( newRecordingDir != currentValue ) { pServer->SetRecordingDir ( newRecordingDir ); UpdateRecorderStatus ( QString() ); } } void CServerDlg::OnClearRecordingDirClicked() { if ( pServer->GetRecorderErrMsg() != QString() || pServer->GetRecordingDir() != "" ) { pServer->SetRecordingDir ( "" ); UpdateRecorderStatus ( QString() ); } } void CServerDlg::OnServerListPersistenceClicked() { // get the current value from pServer QString currentValue = pServer->GetServerListFileName(); QFileDialog fileDialog; fileDialog.setAcceptMode ( QFileDialog::AcceptSave ); fileDialog.setOptions ( QFileDialog::DontUseNativeDialog | QFileDialog::HideNameFilterDetails ); fileDialog.selectFile ( currentValue ); if ( fileDialog.exec() && fileDialog.selectedFiles().size() == 1 ) { QString newFileName = fileDialog.selectedFiles().takeFirst(); if ( newFileName != currentValue ) { pServer->SetServerListFileName ( newFileName ); UpdateGUIDependencies(); } } } void CServerDlg::OnClearServerListPersistenceClicked() { if ( pServer->GetServerListFileName() != "" ) { pServer->SetServerListFileName ( "" ); UpdateGUIDependencies(); } } void CServerDlg::OnSysTrayActivated ( QSystemTrayIcon::ActivationReason ActReason ) { #ifdef _WIN32 // on single or double click on the icon, show window in foreground for windows only if ( ActReason == QSystemTrayIcon::Trigger || ActReason == QSystemTrayIcon::DoubleClick ) #else // on double click on the icon, show window in foreground for all if ( ActReason == QSystemTrayIcon::DoubleClick ) #endif { ShowWindowInForeground(); } } void CServerDlg::OnCLVersionAndOSReceived ( CHostAddress, COSUtil::EOpSystemType, QString strVersion ) { // update check #if QT_VERSION >= QT_VERSION_CHECK( 5, 6, 0 ) int mySuffixIndex; QVersionNumber myVersion = QVersionNumber::fromString ( VERSION, &mySuffixIndex ); int serverSuffixIndex; QVersionNumber serverVersion = QVersionNumber::fromString ( strVersion, &serverSuffixIndex ); // only compare if the server version has no suffix (such as dev or beta) if ( strVersion.size() == serverSuffixIndex && QVersionNumber::compare ( serverVersion, myVersion ) > 0 ) { lblUpdateCheck->show(); } #endif } void CServerDlg::OnTimer() { CVector vecHostAddresses; CVector vecsName; CVector veciJitBufNumFrames; CVector veciNetwFrameSizeFact; ListViewMutex.lock(); { pServer->GetConCliParam ( vecHostAddresses, vecsName, veciJitBufNumFrames, veciNetwFrameSizeFact ); // we assume that all vectors have the same length const int iNumChannels = vecHostAddresses.Size(); // fill list with connected clients for ( int i = 0; i < iNumChannels; i++ ) { if ( !( vecHostAddresses[i].InetAddr == QHostAddress ( static_cast ( 0 ) ) ) ) { // IP, port number vecpListViewItems[i]->setText ( 0, vecHostAddresses[i].toString ( CHostAddress::SM_IP_PORT ) ); // name vecpListViewItems[i]->setText ( 1, vecsName[i] ); // jitter buffer size (polling for updates) vecpListViewItems[i]->setText ( 2, QString().setNum ( veciJitBufNumFrames[i] ) ); // show num of audio channels int iNumAudioChs = pServer->GetClientNumAudioChannels ( i ); vecpListViewItems[i]->setText ( 3, QString().setNum ( iNumAudioChs ) ); vecpListViewItems[i]->setHidden ( false ); } else { vecpListViewItems[i]->setHidden ( true ); } } } ListViewMutex.unlock(); } void CServerDlg::UpdateGUIDependencies() { const EDirectoryType directoryType = pServer->GetDirectoryType(); cbxDirectoryType->setCurrentIndex ( static_cast ( directoryType ) + 1 ); const ESvrRegStatus eSvrRegStatus = pServer->GetSvrRegStatus(); QString strStatus = svrRegStatusToString ( eSvrRegStatus ); QString strFontColour = "darkGreen"; if ( pServer->IsDirectoryServer() ) { strStatus = tr ( "Now a directory" ); } else { switch ( eSvrRegStatus ) { case SRS_BAD_ADDRESS: case SRS_TIME_OUT: case SRS_SERVER_LIST_FULL: case SRS_VERSION_TOO_OLD: case SRS_NOT_FULFILL_REQUIREMENTS: strFontColour = "red"; break; default: break; } } if ( eSvrRegStatus == SRS_NOT_REGISTERED ) { lblRegSvrStatus->setText ( strStatus ); } else { lblRegSvrStatus->setText ( "" + strStatus + "" ); } edtServerName->setText ( pServer->GetServerName() ); edtLocationCity->setText ( pServer->GetServerCity() ); cbxLocationCountry->setCurrentIndex ( cbxLocationCountry->findData ( static_cast ( pServer->GetServerCountry() ) ) ); tedWelcomeMessage->setText ( pServer->GetWelcomeMessage() ); edtCustomDirectory->setText ( pServer->GetDirectoryAddress() ); edtServerListPersistence->setText ( pServer->GetServerListFileName() ); } void CServerDlg::UpdateSystemTrayIcon ( const bool bIsActive ) { if ( bSystemTrayIconAvailable ) { if ( bIsActive ) { SystemTrayIcon.setIcon ( QIcon ( BitmapSystemTrayActive ) ); } else { SystemTrayIcon.setIcon ( QIcon ( BitmapSystemTrayInactive ) ); } } } void CServerDlg::ModifyAutoStartEntry ( const bool bDoAutoStart ) { // auto start is currently only supported for Windows #ifdef _WIN32 // init settings object so that it points to the correct place in the // Windows registry for the auto run entry QSettings RegSettings ( "HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::NativeFormat ); // create start string of auto run entry QString strRegValue = QCoreApplication::applicationFilePath().replace ( "/", "\\" ) + " -s --startminimized"; #endif if ( bDoAutoStart ) { #ifdef _WIN32 // ckeck if registry entry is correctly present, if not, correct const bool bWriteRegValue = strRegValue.compare ( RegSettings.value ( AUTORUN_SERVER_REG_NAME ).toString() ); if ( bWriteRegValue ) { // write reg key in the registry RegSettings.setValue ( AUTORUN_SERVER_REG_NAME, strRegValue ); } #endif } else { #ifdef _WIN32 // delete reg key if present if ( RegSettings.contains ( AUTORUN_SERVER_REG_NAME ) ) { RegSettings.remove ( AUTORUN_SERVER_REG_NAME ); } #endif } } void CServerDlg::UpdateRecorderStatus ( QString sessionDir ) { QString currentSessionDir = edtCurrentSessionDir->text(); QString errMsg = pServer->GetRecorderErrMsg(); bool bIsRecording = false; QString strRecorderStatus; QString strRecordingDir; if ( pServer->GetRecorderInitialised() ) { strRecordingDir = pServer->GetRecordingDir(); chbEnableRecorder->setEnabled ( true ); if ( pServer->GetRecordingEnabled() ) { if ( pServer->IsRunning() ) { edtCurrentSessionDir->setText ( sessionDir != QString() ? sessionDir : "" ); strRecorderStatus = SREC_RECORDING; bIsRecording = true; } else { strRecorderStatus = SREC_NOT_RECORDING; } } else { strRecorderStatus = SREC_NOT_ENABLED; } } else { strRecordingDir = pServer->GetRecorderErrMsg(); if ( strRecordingDir == QString() ) { strRecordingDir = pServer->GetRecordingDir(); } else { strRecordingDir = tr ( "ERROR" ) + ": " + strRecordingDir; } chbEnableRecorder->setEnabled ( false ); strRecorderStatus = SREC_NOT_INITIALISED; } chbEnableRecorder->blockSignals ( true ); chbEnableRecorder->setChecked ( strRecorderStatus != SREC_NOT_ENABLED ); chbEnableRecorder->blockSignals ( false ); edtRecordingDir->setText ( strRecordingDir ); edtRecordingDir->setEnabled ( !bIsRecording ); pbtRecordingDir->setEnabled ( !bIsRecording ); tbtClearRecordingDir->setEnabled ( !bIsRecording ); edtCurrentSessionDir->setEnabled ( bIsRecording ); lblRecorderStatus->setText ( strRecorderStatus ); pbtNewRecording->setEnabled ( bIsRecording ); } void CServerDlg::changeEvent ( QEvent* pEvent ) { // if we have a system tray icon, we make the window invisible if it is // minimized if ( bSystemTrayIconAvailable && ( pEvent->type() == QEvent::WindowStateChange ) ) { if ( isMinimized() ) { // we have to call the hide function from another thread -> use // the timer for this purpose QTimer::singleShot ( 0, this, SLOT ( hide() ) ); } else { // we have to call the show function from another thread -> use // the timer for this purpose QTimer::singleShot ( 0, this, SLOT ( show() ) ); } } } jamulus-3.9.1+dfsg/src/mac/0000755000175000017500000000000014340334543014503 5ustar vimervimerjamulus-3.9.1+dfsg/src/mac/activity.mm0000644000175000017500000000344314340334543016676 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * AronVietti * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include "activity.h" #include class CActivityId { public: id activityId; }; CActivity::CActivity() : pActivity ( new CActivityId() ) {} CActivity::~CActivity() { delete pActivity; } void CActivity::BeginActivity() { NSActivityOptions options = NSActivityBackground | NSActivityIdleDisplaySleepDisabled | NSActivityIdleSystemSleepDisabled | NSActivityLatencyCritical; pActivity->activityId = [[NSProcessInfo processInfo] beginActivityWithOptions:options reason:@"Jamulus provides low latency audio processing and should not be inturrupted by system throttling."]; } void CActivity::EndActivity() { [[NSProcessInfo processInfo] endActivity:pActivity->activityId]; pActivity->activityId = nil; } jamulus-3.9.1+dfsg/src/mac/badgelabel.h0000644000175000017500000000213514340334543016717 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2022-2022 * * Author(s): * The Jamulus Development Team * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include void SetMacBadgeLabelText ( const QString& text ); jamulus-3.9.1+dfsg/src/mac/activity.h0000644000175000017500000000305414340334543016512 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * AronVietti * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once // Forward Delcaration to pointer that holds the activity id class CActivityId; // Represents an OSX specific activity. See Managing Activities // https://developer.apple.com/documentation/foundation/nsprocessinfo?language=objc // This essentially lets us start and stop an Activity frame where we tell the OS // that we are Latency Critical and are not performing background tasks. class CActivity { private: CActivityId* pActivity; public: CActivity(); ~CActivity(); void BeginActivity(); void EndActivity(); }; jamulus-3.9.1+dfsg/src/mac/badgelabel.mm0000644000175000017500000000236414340334543017105 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2022-2022 * * Author(s): * The Jamulus Development Team * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include "badgelabel.h" #import #import void SetMacBadgeLabelText ( const QString& text ) { [[[NSApplication sharedApplication] dockTile] setBadgeLabel:text.toNSString()]; } jamulus-3.9.1+dfsg/src/ios/0000755000175000017500000000000014340334543014535 5ustar vimervimerjamulus-3.9.1+dfsg/src/ios/ios_app_delegate.h0000644000175000017500000000034014340334543020167 0ustar vimervimer#import #include @interface QIOSApplicationDelegate : UIResponder @property ( strong, nonatomic ) UIWindow* window; @end jamulus-3.9.1+dfsg/src/ios/ios_app_delegate.mm0000644000175000017500000000037014340334543020354 0ustar vimervimer#import "ios_app_delegate.h" @interface QIOSApplicationDelegate () @end @implementation QIOSApplicationDelegate - (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions { return YES; } @end jamulus-3.9.1+dfsg/src/clientsettingsdlgbase.ui0000644000175000017500000013301514340334543020666 0ustar vimervimer CClientSettingsDlgBase 0 0 436 524 Settings :/png/main/res/fronticon.png:/png/main/res/fronticon.png true 0 0 1 true My Profile Qt::Horizontal 0 20 Qt::Vertical QSizePolicy::Preferred 20 13 Musician's Profile Alias/Name Instrument Country/Region City Skill 0 0 150 0 150 0 150 0 0 0 150 0 150 0 Qt::Vertical 20 40 User Interface Skin Meter Style Language Mixer Rows Audio Alerts 150 0 0 0 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 1 8 Enable Qt::Vertical 20 14 Qt::Horizontal 0 20 Audio/Network Setup Audio Device 0 0 0 0 Qt::Vertical QSizePolicy::Expanding 20 10 0 0 Driver Setup false Qt::Vertical 20 10 0 0 QFrame::NoFrame QFrame::Plain 0 0 0 0 Input Channel Mapping 3 0 0 L 0 0 R 3 Output Channel Mapping 3 0 0 L 0 0 R 3 Qt::Vertical QSizePolicy::Expanding 20 10 Audio Channels Audio Quality Qt::Vertical 20 10 Buffer Delay 0 0 (preferred) 0 0 (default) 0 0 (safe) Qt::Horizontal QSizePolicy::MinimumExpanding 0 20 Jitter Buffer 0 0 Auto Local Qt::AlignCenter false Server Qt::AlignCenter false Size Qt::AlignCenter false Size Qt::AlignCenter false Qt::Horizontal QSizePolicy::Minimum 0 0 1 20 1 Qt::Vertical QSlider::TicksBothSides Qt::Horizontal QSizePolicy::Minimum 0 0 1 20 1 Qt::Vertical QSlider::TicksBothSides 0 0 Enable Small Network Buffers Audio Stream Rate 2 Qt::Horizontal 1 5 kbps Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter val Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 2 Qt::Horizontal 1 5 Qt::Horizontal QSizePolicy::Minimum 0 20 Advanced Setup Qt::Horizontal 10 20 Qt::Vertical QSizePolicy::MinimumExpanding 17 20 Custom Directories: true Qt::Vertical 20 13 New Client Level % Qt::Vertical 20 40 Input Boost Qt::Vertical 20 40 Feedback Protection 0 0 Enable Qt::Vertical 20 40 Qt::Horizontal 10 20 Qt::Horizontal QSizePolicy::Preferred 20 20 Input Balance 3 Pan Qt::AlignCenter Qt::Horizontal QSizePolicy::Minimum 0 20 0 0 0 0 1 Qt::Horizontal QSlider::TicksBothSides Qt::Horizontal QSizePolicy::Minimum 0 20 50 0 Center Qt::AlignCenter false Qt::Horizontal QSizePolicy::Preferred 20 20 Qt::Vertical 367 13 CLanguageComboBox QComboBox
util.h
pedtAlias pcbxInstrument pcbxCountry pedtCity pcbxSkill cbxSkin cbxMeterStyle cbxLanguage spnMixerRows chbAudioAlerts cbxSoundcard butDriverSetup cbxLInChan cbxRInChan cbxLOutChan cbxROutChan cbxAudioChannels cbxAudioQuality rbtBufferDelayPreferred rbtBufferDelayDefault rbtBufferDelaySafe chbAutoJitBuf sldNetBuf sldNetBufServer chbEnableOPUS64 cbxCustomDirectories edtNewClientLevel cbxInputBoost chbDetectFeedback sldAudioPan
jamulus-3.9.1+dfsg/src/serverrpc.h0000644000175000017500000000261214340334543016130 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2021-2022 * * Author(s): * dtinth * Christian Hoffmann * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #include "server.h" #include "rpcserver.h" /* Classes ********************************************************************/ class CServerRpc : public QObject { Q_OBJECT public: CServerRpc ( CServer* pServer, CRpcServer* pRpcServer, QObject* parent = nullptr ); static QJsonValue SerializeRegistrationStatus ( ESvrRegStatus eSvrRegStatus ); }; jamulus-3.9.1+dfsg/src/signalhandler.cpp0000644000175000017500000001445214340334543017270 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2020-2022 * * Author(s): * Peter L Jones * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * ****************************************************************************** * * This code contains some ideas derived from QCtrlSignals * https://github.com/Skycoder42/QCtrlSignals.git * - mostly the singleton and emitSignal code, plus some of the structure * - virtually everything else is common knowledge across SourceForge answers * * BSD 3-Clause License * * Copyright (c) 2016, Felix Barz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * * Neither the name of the copyright holder nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * \******************************************************************************/ #include "signalhandler.h" class CSignalHandlerSingleton : public CSignalHandler { public: inline CSignalHandlerSingleton() : CSignalHandler() {} }; Q_GLOBAL_STATIC ( CSignalHandlerSingleton, singleton ) CSignalHandler::CSignalHandler() : pSignalBase ( CSignalBase::withSignalHandler ( this ) ) {} CSignalHandler::~CSignalHandler() = default; CSignalHandler* CSignalHandler::getSingletonP() { return singleton; } bool CSignalHandler::emitSignal ( int sigNum ) { return QMetaObject::invokeMethod ( singleton, "HandledSignal", Qt::QueuedConnection, Q_ARG ( int, sigNum ) ); } #ifndef _WIN32 void CSignalHandler::OnSocketNotify ( int socket ) { int sigNum; // The following read() triggers a Codacy/flawfinder finding: // "Check buffer boundaries if used in a loop including recursive loops (CWE-120, CWE-20)" // Investigation has shown that this is a false positive as the proper buffer size is enforced. if ( ::read ( socket, &sigNum, sizeof ( int ) ) == sizeof ( int ) ) // Flawfinder: ignore { emitSignal ( sigNum ); } } #endif // ---------------------------------------------------------- CSignalBase::CSignalBase ( CSignalHandler* pSignalHandler ) : pSignalHandler ( pSignalHandler ) {} CSignalBase::~CSignalBase() = default; CSignalBase* CSignalBase::withSignalHandler ( CSignalHandler* pSignalHandler ) { #ifdef _WIN32 return new CSignalWin ( pSignalHandler ); #else return new CSignalUnix ( pSignalHandler ); #endif } #ifdef _WIN32 CSignalWin::CSignalWin ( CSignalHandler* nPSignalHandler ) : CSignalBase ( nPSignalHandler ), lock ( QReadWriteLock::Recursive ) { SetConsoleCtrlHandler ( signalHandler, true ); } CSignalWin::~CSignalWin() { SetConsoleCtrlHandler ( signalHandler, false ); } QReadWriteLock* CSignalWin::getLock() const { return &lock; } BOOL WINAPI CSignalWin::signalHandler ( _In_ DWORD ) { auto self = getSelf(); QReadLocker lock ( self->getLock() ); return self->pSignalHandler->emitSignal ( -1 ); } #else int CSignalUnix::socketPair[2]; CSignalUnix::CSignalUnix ( CSignalHandler* nPSignalHandler ) : CSignalBase ( nPSignalHandler ) { if ( ::socketpair ( AF_UNIX, SOCK_STREAM, 0, socketPair ) == 0 ) { socketNotifier = new QSocketNotifier ( socketPair[1], QSocketNotifier::Read ); QObject::connect ( socketNotifier, &QSocketNotifier::activated, nPSignalHandler, &CSignalHandler::OnSocketNotify ); socketNotifier->setEnabled ( true ); setSignalHandled ( SIGUSR1, true ); setSignalHandled ( SIGUSR2, true ); setSignalHandled ( SIGINT, true ); setSignalHandled ( SIGTERM, true ); } } CSignalUnix::~CSignalUnix() { setSignalHandled ( SIGUSR1, false ); setSignalHandled ( SIGUSR2, false ); setSignalHandled ( SIGINT, false ); setSignalHandled ( SIGTERM, false ); } QReadWriteLock* CSignalUnix::getLock() const { return nullptr; } bool CSignalUnix::setSignalHandled ( int sigNum, bool state ) { struct sigaction sa; sigemptyset ( &sa.sa_mask ); if ( state ) { sa.sa_handler = CSignalUnix::signalHandler; sa.sa_flags = SA_RESTART; } else { sa.sa_handler = SIG_DFL; sa.sa_flags = 0; } return ::sigaction ( sigNum, &sa, nullptr ) == 0; } void CSignalUnix::signalHandler ( int sigNum ) { const auto res = ::write ( socketPair[0], &sigNum, sizeof ( int ) ); Q_UNUSED ( res ); } #endif jamulus-3.9.1+dfsg/src/clientdlg.h0000644000175000017500000002354614340334543016073 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if QT_VERSION >= QT_VERSION_CHECK( 5, 6, 0 ) # include #endif #include "global.h" #include "util.h" #include "client.h" #include "settings.h" #include "multicolorled.h" #include "audiomixerboard.h" #include "clientsettingsdlg.h" #include "chatdlg.h" #include "connectdlg.h" #include "analyzerconsole.h" #include "ui_clientdlgbase.h" #if defined( Q_OS_MACX ) # include "mac/badgelabel.h" #endif /* Definitions ****************************************************************/ // update time for GUI controls #define LEVELMETER_UPDATE_TIME_MS 100 // ms #define BUFFER_LED_UPDATE_TIME_MS 300 // ms #define LED_BAR_UPDATE_TIME_MS 1000 // ms #define CHECK_AUDIO_DEV_OK_TIME_MS 5000 // ms #define DETECT_FEEDBACK_TIME_MS 3000 // ms // number of ping times > upper bound until error message is shown #define NUM_HIGH_PINGS_UNTIL_ERROR 5 /* Classes ********************************************************************/ class CClientDlg : public CBaseDlg, private Ui_CClientDlgBase { Q_OBJECT public: CClientDlg ( CClient* pNCliP, CClientSettings* pNSetP, const QString& strConnOnStartupAddress, const QString& strMIDISetup, const bool bNewShowComplRegConnList, const bool bShowAnalyzerConsole, const bool bMuteStream, const bool bNEnableIPv6, QWidget* parent = nullptr ); protected: void SetGUIDesign ( const EGUIDesign eNewDesign ); void SetMeterStyle ( const EMeterStyle eNewMeterStyle ); void SetMyWindowTitle ( const int iNumClients ); void ShowConnectionSetupDialog(); void ShowGeneralSettings ( int iTab ); void ShowChatWindow ( const bool bForceRaise = true ); void ShowAnalyzerConsole(); void UpdateAudioFaderSlider(); void UpdateRevSelection(); void Connect ( const QString& strSelectedAddress, const QString& strMixerBoardLabel ); void Disconnect(); void ManageDragNDrop ( QDropEvent* Event, const bool bCheckAccept ); void SetPingTime ( const int iPingTime, const int iOverallDelayMs, const CMultiColorLED::ELightColor eOverallDelayLEDColor ); CClient* pClient; CClientSettings* pSettings; int iClients; bool bConnected; bool bConnectDlgWasShown; bool bDetectFeedback; bool bEnableIPv6; ERecorderState eLastRecorderState; EGUIDesign eLastDesign; QTimer TimerSigMet; QTimer TimerBuffersLED; QTimer TimerStatus; QTimer TimerPing; QTimer TimerCheckAudioDeviceOk; QTimer TimerDetectFeedback; virtual void closeEvent ( QCloseEvent* Event ); virtual void dragEnterEvent ( QDragEnterEvent* Event ) { ManageDragNDrop ( Event, true ); } virtual void dropEvent ( QDropEvent* Event ) { ManageDragNDrop ( Event, false ); } void UpdateDisplay(); CClientSettingsDlg ClientSettingsDlg; CChatDlg ChatDlg; CConnectDlg ConnectDlg; CAnalyzerConsole AnalyzerConsole; public slots: void OnConnectDisconBut(); void OnTimerSigMet(); void OnTimerBuffersLED(); void OnTimerCheckAudioDeviceOk(); void OnTimerDetectFeedback(); void OnTimerStatus() { UpdateDisplay(); } void OnTimerPing(); void OnPingTimeResult ( int iPingTime ); void OnCLPingTimeWithNumClientsReceived ( CHostAddress InetAddr, int iPingTime, int iNumClients ); void OnControllerInFaderLevel ( const int iChannelIdx, const int iValue ) { MainMixerBoard->SetFaderLevel ( iChannelIdx, iValue ); } void OnControllerInPanValue ( const int iChannelIdx, const int iValue ) { MainMixerBoard->SetPanValue ( iChannelIdx, iValue ); } void OnControllerInFaderIsSolo ( const int iChannelIdx, const bool bIsSolo ) { MainMixerBoard->SetFaderIsSolo ( iChannelIdx, bIsSolo ); } void OnControllerInFaderIsMute ( const int iChannelIdx, const bool bIsMute ) { MainMixerBoard->SetFaderIsMute ( iChannelIdx, bIsMute ); } void OnControllerInMuteMyself ( const bool bMute ) { chbLocalMute->setChecked ( bMute ); } void OnVersionAndOSReceived ( COSUtil::EOpSystemType, QString strVersion ); void OnCLVersionAndOSReceived ( CHostAddress, COSUtil::EOpSystemType, QString strVersion ); void OnLoadChannelSetup(); void OnSaveChannelSetup(); void OnOpenConnectionSetupDialog() { ShowConnectionSetupDialog(); } void OnOpenUserProfileSettings(); void OnOpenAudioNetSettings(); void OnOpenAdvancedSettings(); void OnOpenChatDialog() { ShowChatWindow(); } void OnOpenAnalyzerConsole() { ShowAnalyzerConsole(); } void OnOwnFaderFirst() { pSettings->bOwnFaderFirst = !pSettings->bOwnFaderFirst; MainMixerBoard->SetFaderSorting ( pSettings->eChannelSortType ); } void OnNoSortChannels() { MainMixerBoard->SetFaderSorting ( ST_NO_SORT ); } void OnSortChannelsByName() { MainMixerBoard->SetFaderSorting ( ST_BY_NAME ); } void OnSortChannelsByInstrument() { MainMixerBoard->SetFaderSorting ( ST_BY_INSTRUMENT ); } void OnSortChannelsByGroupID() { MainMixerBoard->SetFaderSorting ( ST_BY_GROUPID ); } void OnSortChannelsByCity() { MainMixerBoard->SetFaderSorting ( ST_BY_CITY ); } void OnClearAllStoredSoloMuteSettings(); void OnSetAllFadersToNewClientLevel() { MainMixerBoard->SetAllFaderLevelsToNewClientLevel(); } void OnAutoAdjustAllFaderLevels() { MainMixerBoard->AutoAdjustAllFaderLevels(); } void OnNumMixerPanelRowsChanged ( int value ) { MainMixerBoard->SetNumMixerPanelRows ( value ); } void OnSettingsStateChanged ( int value ); void OnChatStateChanged ( int value ); void OnLocalMuteStateChanged ( int value ); void OnAudioReverbValueChanged ( int value ) { pClient->SetReverbLevel ( value ); } void OnReverbSelLClicked() { pClient->SetReverbOnLeftChan ( true ); } void OnReverbSelRClicked() { pClient->SetReverbOnLeftChan ( false ); } void OnFeedbackDetectionChanged ( int state ) { ClientSettingsDlg.SetEnableFeedbackDetection ( state == Qt::Checked ); } void OnConClientListMesReceived ( CVector vecChanInfo ); void OnChatTextReceived ( QString strChatText ); void OnLicenceRequired ( ELicenceType eLicenceType ); void OnSoundDeviceChanged ( QString strError ); void OnChangeChanGain ( int iId, float fGain, bool bIsMyOwnFader ) { pClient->SetRemoteChanGain ( iId, fGain, bIsMyOwnFader ); } void OnChangeChanPan ( int iId, float fPan ) { pClient->SetRemoteChanPan ( iId, fPan ); } void OnNewLocalInputText ( QString strChatText ) { pClient->CreateChatTextMes ( strChatText ); } void OnReqServerListQuery ( CHostAddress InetAddr ) { pClient->CreateCLReqServerListMes ( InetAddr ); } void OnCreateCLServerListPingMes ( CHostAddress InetAddr ) { pClient->CreateCLServerListPingMes ( InetAddr ); } void OnCreateCLServerListReqVerAndOSMes ( CHostAddress InetAddr ) { pClient->CreateCLServerListReqVerAndOSMes ( InetAddr ); } void OnCreateCLServerListReqConnClientsListMes ( CHostAddress InetAddr ) { pClient->CreateCLServerListReqConnClientsListMes ( InetAddr ); } void OnCLServerListReceived ( CHostAddress InetAddr, CVector vecServerInfo ) { ConnectDlg.SetServerList ( InetAddr, vecServerInfo ); } void OnCLRedServerListReceived ( CHostAddress InetAddr, CVector vecServerInfo ) { ConnectDlg.SetServerList ( InetAddr, vecServerInfo, true ); } void OnCLConnClientsListMesReceived ( CHostAddress InetAddr, CVector vecChanInfo ) { ConnectDlg.SetConnClientsList ( InetAddr, vecChanInfo ); } void OnClientIDReceived ( int iChanID ) { MainMixerBoard->SetMyChannelID ( iChanID ); } void OnMuteStateHasChangedReceived ( int iChanID, bool bIsMuted ) { MainMixerBoard->SetRemoteFaderIsMute ( iChanID, bIsMuted ); } void OnCLChannelLevelListReceived ( CHostAddress /* unused */, CVector vecLevelList ) { MainMixerBoard->SetChannelLevels ( vecLevelList ); } void OnConnectDlgAccepted(); void OnDisconnected() { Disconnect(); } void OnGUIDesignChanged(); void OnMeterStyleChanged(); void OnRecorderStateReceived ( ERecorderState eRecorderState ); void SetMixerBoardDeco ( const ERecorderState newRecorderState, const EGUIDesign eNewDesign ); void OnAudioChannelsChanged() { UpdateRevSelection(); } void OnNumClientsChanged ( int iNewNumClients ); void accept() { close(); } // introduced by pljones signals: void SendTabChange ( int iTabIdx ); }; jamulus-3.9.1+dfsg/src/audiomixerboard.h0000644000175000017500000002527714340334543017307 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "util.h" #include "levelmeter.h" #include "settings.h" /* Classes ********************************************************************/ class CChannelFader : public QObject { Q_OBJECT public: CChannelFader ( QWidget* pNW ); QString GetReceivedName() { return cReceivedChanInfo.strName; } int GetReceivedInstrument() { return cReceivedChanInfo.iInstrument; } QString GetReceivedCity() { return cReceivedChanInfo.strCity; } void SetChannelInfos ( const CChannelInfo& cChanInfo ); void Show() { pFrame->show(); } void Hide() { pFrame->hide(); } bool IsVisible() { return !pFrame->isHidden(); } bool IsSolo() { return pcbSolo->isChecked(); } bool IsMute() { return pcbMute->isChecked(); } int GetGroupID() { return iGroupID; } void SetGUIDesign ( const EGUIDesign eNewDesign ); void SetMeterStyle ( const EMeterStyle eNewMeterStyle ); void SetDisplayChannelLevel ( const bool eNDCL ); bool GetDisplayChannelLevel(); void SetDisplayPans ( const bool eNDP ); QFrame* GetMainWidget() { return pFrame; } void SetPanValue ( const int iPan ); void SetFaderIsSolo ( const bool bIsSolo ); void SetFaderIsMute ( const bool bIsMute ); void SetGroupID ( const int iNGroupID ); void SetRemoteFaderIsMute ( const bool bIsMute ); void SetFaderLevel ( const double dLevel, const bool bIsGroupUpdate = false ); int GetFaderLevel() { return pFader->value(); } double GetPreviousFaderLevel() { return dPreviousFaderLevel; } int GetPanValue() { return pPan->value(); } void Reset(); void SetRunningNewClientCnt ( const int iNRunningNewClientCnt ) { iRunningNewClientCnt = iNRunningNewClientCnt; } int GetRunningNewClientCnt() { return iRunningNewClientCnt; } void SetChannelLevel ( const uint16_t iLevel ); void SetIsMyOwnFader() { bIsMyOwnFader = true; } bool GetIsMyOwnFader() { return bIsMyOwnFader; } void UpdateSoloState ( const bool bNewOtherSoloState ); void SetMIDICtrlUsed ( const bool isMIDICtrlUsed ) { bMIDICtrlUsed = isMIDICtrlUsed; } protected: void UpdateGroupIDDependencies(); void SetMute ( const bool bState ); void SetupFaderTag ( const ESkillLevel eSkillLevel ); void SendPanValueToServer ( const int iPan ); void SendFaderLevelToServer ( const double dLevel, const bool bIsGroupUpdate ); QFrame* pFrame; QWidget* pLevelsBox; QWidget* pMuteSoloBox; CLevelMeter* plbrChannelLevel; QSlider* pFader; QDial* pPan; QLabel* pPanLabel; QLabel* pInfoLabel; QHBoxLayout* pLabelGrid; QVBoxLayout* pLabelPictGrid; QCheckBox* pcbMute; QCheckBox* pcbSolo; QCheckBox* pcbGroup; QMenu* pGroupPopupMenu; QGroupBox* pLabelInstBox; QLabel* plblLabel; QLabel* plblInstrument; QLabel* plblCountryFlag; CChannelInfo cReceivedChanInfo; bool bOtherChannelIsSolo; bool bIsMyOwnFader; bool bIsMutedAtServer; double dPreviousFaderLevel; int iGroupID; QString strGroupBaseText; int iRunningNewClientCnt; int iInstrPicMaxWidth; EGUIDesign eDesign; EMeterStyle eMeterStyle; QPixmap BitmapMutedIcon; bool bMIDICtrlUsed; public slots: void OnLevelValueChanged ( int value ) { SendFaderLevelToServer ( value, QGuiApplication::keyboardModifiers() == Qt::ShiftModifier ); /* isolate a channel from the group temporarily with shift-click-drag (#695) */ } void OnPanValueChanged ( int value ); void OnMuteStateChanged ( int value ); void OnGroupStateChanged ( int ); void OnGroupMenuGrp ( int iGrp ) { SetGroupID ( iGrp ); } signals: void gainValueChanged ( float value, bool bIsMyOwnFader, bool bIsGroupUpdate, bool bSuppressServerUpdate, double dLevelRatio ); void panValueChanged ( float value ); void soloStateChanged ( int value ); }; template class CAudioMixerBoardSlots : public CAudioMixerBoardSlots { public: void OnChGainValueChanged ( float fValue, bool bIsMyOwnFader, bool bIsGroupUpdate, bool bSuppressServerUpdate, double dLevelRatio ) { UpdateGainValue ( slotId - 1, fValue, bIsMyOwnFader, bIsGroupUpdate, bSuppressServerUpdate, dLevelRatio ); } void OnChPanValueChanged ( float fValue ) { UpdatePanValue ( slotId - 1, fValue ); } protected: virtual void UpdateGainValue ( const int iChannelIdx, const float fValue, const bool bIsMyOwnFader, const bool bIsGroupUpdate, const bool bSuppressServerUpdate, const double dLevelRatio ) = 0; virtual void UpdatePanValue ( const int iChannelIdx, const float fValue ) = 0; }; template<> class CAudioMixerBoardSlots<0> {}; class CAudioMixerBoard : public QGroupBox, public CAudioMixerBoardSlots { Q_OBJECT public: CAudioMixerBoard ( QWidget* parent = nullptr ); virtual ~CAudioMixerBoard(); void SetSettingsPointer ( CClientSettings* pNSet ) { pSettings = pNSet; } void HideAll(); void ApplyNewConClientList ( CVector& vecChanInfo ); void SetServerName ( const QString& strNewServerName ); QString GetServerName() { return strServerName; } void SetGUIDesign ( const EGUIDesign eNewDesign ); void SetMeterStyle ( const EMeterStyle eNewMeterStyle ); void SetDisplayPans ( const bool eNDP ); void SetPanIsSupported(); void SetRemoteFaderIsMute ( const int iChannelIdx, const bool bIsMute ); void SetMyChannelID ( const int iChannelIdx ) { iMyChannelID = iChannelIdx; } int GetMyChannelID() const { return iMyChannelID; } void SetFaderLevel ( const int iChannelIdx, const int iValue ); void SetPanValue ( const int iChannelIdx, const int iValue ); void SetFaderIsSolo ( const int iChannelIdx, const bool bIsSolo ); void SetFaderIsMute ( const int iChannelIdx, const bool bIsMute ); void SetNumMixerPanelRows ( const int iNNumMixerPanelRows ); int GetNumMixerPanelRows() { return iNumMixerPanelRows; } void SetFaderSorting ( const EChSortType eNChSortType ); EChSortType GetFaderSorting() { return eChSortType; } void SetChannelLevels ( const CVector& vecChannelLevel ); void SetRecorderState ( const ERecorderState newRecorderState ); ERecorderState GetRecorderState() { return eRecorderState; }; void SetAllFaderLevelsToNewClientLevel(); void StoreAllFaderSettings(); void LoadAllFaderSettings(); void AutoAdjustAllFaderLevels(); void MuteMyChannel(); void SetMIDICtrlUsed ( const bool bMIDICtrlUsed ); protected: class CMixerBoardScrollArea : public QScrollArea { public: CMixerBoardScrollArea ( QWidget* parent = nullptr ) : QScrollArea ( parent ) {} protected: virtual void resizeEvent ( QResizeEvent* event ) { // if after a resize of the main window a vertical scroll bar is required, make // sure that the fader label is visible (scroll down completely) ensureVisible ( 0, 2000 ); // use a large value here QScrollArea::resizeEvent ( event ); } }; void ChangeFaderOrder ( const EChSortType eChSortType ); bool GetStoredFaderSettings ( const QString& strName, int& iStoredFaderLevel, int& iStoredPanValue, bool& bStoredFaderIsSolo, bool& bStoredFaderIsMute, int& iGroupID ); void StoreFaderSettings ( CChannelFader* pChanFader ); void UpdateSoloStates(); void UpdateTitle(); CClientSettings* pSettings; CVector vecpChanFader; CMixerBoardScrollArea* pScrollArea; QGridLayout* pMainLayout; bool bDisplayPans; bool bIsPanSupported; bool bNoFaderVisible; int iMyChannelID; int iRunningNewClientCnt; // integer type is sufficient, will never overrun for its purpose int iNumMixerPanelRows; QString strServerName; ERecorderState eRecorderState; QMutex Mutex; EChSortType eChSortType; CVector vecAvgLevels; virtual void UpdateGainValue ( const int iChannelIdx, const float fValue, const bool bIsMyOwnFader, const bool bIsGroupUpdate, const bool bSuppressServerUpdate, const double dLevelRatio ); virtual void UpdatePanValue ( const int iChannelIdx, const float fValue ); template inline void connectFaderSignalsToMixerBoardSlots(); signals: void ChangeChanGain ( int iId, float fGain, bool bIsMyOwnFader ); void ChangeChanPan ( int iId, float fPan ); void NumClientsChanged ( int iNewNumClients ); }; jamulus-3.9.1+dfsg/src/clientrpc.h0000644000175000017500000000270214340334543016100 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2021-2022 * * Author(s): * dtinth * Christian Hoffmann * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #include "client.h" #include "util.h" #include "rpcserver.h" /* Classes ********************************************************************/ class CClientRpc : public QObject { Q_OBJECT public: CClientRpc ( CClient* pClient, CRpcServer* pRpcServer, QObject* parent = nullptr ); private: QJsonArray arrStoredChanInfo; static QJsonValue SerializeSkillLevel ( ESkillLevel skillLevel ); }; jamulus-3.9.1+dfsg/src/protocol.h0000644000175000017500000004435014340334543015763 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #include #include #include #include #include #include "global.h" #include "util.h" /* Definitions ****************************************************************/ // protocol message IDs #define PROTMESSID_ILLEGAL 0 // illegal ID #define PROTMESSID_ACKN 1 // acknowledge #define PROTMESSID_JITT_BUF_SIZE 10 // jitter buffer size #define PROTMESSID_REQ_JITT_BUF_SIZE 11 // request jitter buffer size #define PROTMESSID_NET_BLSI_FACTOR 12 // OLD (not used anymore) #define PROTMESSID_CHANNEL_GAIN 13 // set channel gain for mix #define PROTMESSID_CONN_CLIENTS_LIST_NAME 14 // OLD (not used anymore) #define PROTMESSID_SERVER_FULL 15 // OLD (not used anymore) #define PROTMESSID_REQ_CONN_CLIENTS_LIST 16 // request connected client list #define PROTMESSID_CHANNEL_NAME 17 // OLD (not used anymore) #define PROTMESSID_CHAT_TEXT 18 // contains a chat text #define PROTMESSID_PING_MS 19 // OLD (not used anymore) #define PROTMESSID_NETW_TRANSPORT_PROPS 20 // properties for network transport #define PROTMESSID_REQ_NETW_TRANSPORT_PROPS 21 // request properties for network transport #define PROTMESSID_DISCONNECTION 22 // OLD (not used anymore) #define PROTMESSID_REQ_CHANNEL_INFOS 23 // request channel infos for fader tag #define PROTMESSID_CONN_CLIENTS_LIST 24 // channel infos for connected clients #define PROTMESSID_CHANNEL_INFOS 25 // set channel infos #define PROTMESSID_OPUS_SUPPORTED 26 // tells that OPUS codec is supported #define PROTMESSID_LICENCE_REQUIRED 27 // licence required #define PROTMESSID_REQ_CHANNEL_LEVEL_LIST 28 // OLD (not used anymore) // TODO needed for compatibility to old servers >= 3.4.6 and <= 3.5.12 #define PROTMESSID_VERSION_AND_OS 29 // version number and operating system #define PROTMESSID_CHANNEL_PAN 30 // set channel pan for mix #define PROTMESSID_MUTE_STATE_CHANGED 31 // mute state of your signal at another client has changed #define PROTMESSID_CLIENT_ID 32 // current user ID and server status #define PROTMESSID_RECORDER_STATE 33 // contains the state of the jam recorder (ERecorderState) #define PROTMESSID_REQ_SPLIT_MESS_SUPPORT 34 // request support for split messages #define PROTMESSID_SPLIT_MESS_SUPPORTED 35 // split messages are supported // message IDs of connection less messages (CLM) // DEFINITION -> start at 1000, end at 1999, see IsConnectionLessMessageID #define PROTMESSID_CLM_PING_MS 1001 // for measuring ping time #define PROTMESSID_CLM_PING_MS_WITHNUMCLIENTS 1002 // for ping time and num. of clients info #define PROTMESSID_CLM_SERVER_FULL 1003 // server full message #define PROTMESSID_CLM_REGISTER_SERVER 1004 // register server #define PROTMESSID_CLM_UNREGISTER_SERVER 1005 // unregister server #define PROTMESSID_CLM_SERVER_LIST 1006 // server list #define PROTMESSID_CLM_REQ_SERVER_LIST 1007 // request server list #define PROTMESSID_CLM_SEND_EMPTY_MESSAGE 1008 // an empty message shall be send #define PROTMESSID_CLM_EMPTY_MESSAGE 1009 // empty message #define PROTMESSID_CLM_DISCONNECTION 1010 // disconnection #define PROTMESSID_CLM_VERSION_AND_OS 1011 // version number and operating system #define PROTMESSID_CLM_REQ_VERSION_AND_OS 1012 // request version number and operating system #define PROTMESSID_CLM_CONN_CLIENTS_LIST 1013 // channel infos for connected clients #define PROTMESSID_CLM_REQ_CONN_CLIENTS_LIST 1014 // request the connected clients list #define PROTMESSID_CLM_CHANNEL_LEVEL_LIST 1015 // channel level list #define PROTMESSID_CLM_REGISTER_SERVER_RESP 1016 // status of server registration request #define PROTMESSID_CLM_REGISTER_SERVER_EX 1017 // register server with extended information #define PROTMESSID_CLM_RED_SERVER_LIST 1018 // reduced server list // special IDs #define PROTMESSID_SPECIAL_SPLIT_MESSAGE 2001 // a container for split messages // lengths of message as defined in protocol.cpp file #define MESS_HEADER_LENGTH_BYTE 7 // TAG (2), ID (2), cnt (1), length (2) #define MESS_LEN_WITHOUT_DATA_BYTE ( MESS_HEADER_LENGTH_BYTE + 2 /* CRC (2) */ ) // time out for message re-send if no acknowledgement was received #define SEND_MESS_TIMEOUT_MS 400 // ms // message split parameters #define MESS_SPLIT_PART_SIZE_BYTES 550 #define MAX_NUM_MESS_SPLIT_PARTS ( MAX_SIZE_BYTES_NETW_BUF / MESS_SPLIT_PART_SIZE_BYTES ) /* Classes ********************************************************************/ class CProtocol : public QObject { Q_OBJECT public: CProtocol(); void Reset(); void SetSplitMessageSupported ( const bool bIn ) { bSplitMessageSupported = bIn; } void CreateJitBufMes ( const int iJitBufSize ); void CreateReqJitBufMes(); void CreateClientIDMes ( const int iChanID ); void CreateChanGainMes ( const int iChanID, const float fGain ); void CreateChanPanMes ( const int iChanID, const float fPan ); void CreateMuteStateHasChangedMes ( const int iChanID, const bool bIsMuted ); void CreateConClientListMes ( const CVector& vecChanInfo ); void CreateReqConnClientsList(); void CreateChanInfoMes ( const CChannelCoreInfo ChanInfo ); void CreateReqChanInfoMes(); void CreateChatTextMes ( const QString strChatText ); void CreateNetwTranspPropsMes ( const CNetworkTransportProps& NetTrProps ); void CreateReqNetwTranspPropsMes(); void CreateReqSplitMessSupportMes(); void CreateSplitMessSupportedMes(); void CreateLicenceRequiredMes ( const ELicenceType eLicenceType ); void CreateOpusSupportedMes(); //### TODO: BEGIN ###// // needed for compatibility to old servers >= 3.4.6 and <= 3.5.12 void CreateReqChannelLevelListMes(); //### TODO: END ###// void CreateVersionAndOSMes(); void CreateRecorderStateMes ( const ERecorderState eRecorderState ); void CreateCLPingMes ( const CHostAddress& InetAddr, const int iMs ); void CreateCLPingWithNumClientsMes ( const CHostAddress& InetAddr, const int iMs, const int iNumClients ); void CreateCLServerFullMes ( const CHostAddress& InetAddr ); void CreateCLRegisterServerMes ( const CHostAddress& InetAddr, const CHostAddress& LInetAddr, const CServerCoreInfo& ServerInfo ); void CreateCLRegisterServerExMes ( const CHostAddress& InetAddr, const CHostAddress& LInetAddr, const CServerCoreInfo& ServerInfo ); void CreateCLUnregisterServerMes ( const CHostAddress& InetAddr ); void CreateCLServerListMes ( const CHostAddress& InetAddr, const CVector vecServerInfo ); void CreateCLRedServerListMes ( const CHostAddress& InetAddr, const CVector vecServerInfo ); void CreateCLReqServerListMes ( const CHostAddress& InetAddr ); void CreateCLSendEmptyMesMes ( const CHostAddress& InetAddr, const CHostAddress& TargetInetAddr ); void CreateCLEmptyMes ( const CHostAddress& InetAddr ); void CreateCLDisconnection ( const CHostAddress& InetAddr ); void CreateCLVersionAndOSMes ( const CHostAddress& InetAddr ); void CreateCLReqVersionAndOSMes ( const CHostAddress& InetAddr ); void CreateCLConnClientsListMes ( const CHostAddress& InetAddr, const CVector& vecChanInfo ); void CreateCLReqConnClientsListMes ( const CHostAddress& InetAddr ); void CreateCLChannelLevelListMes ( const CHostAddress& InetAddr, const CVector& vecLevelList, const int iNumClients ); void CreateCLRegisterServerResp ( const CHostAddress& InetAddr, const ESvrRegResult eResult ); static bool ParseMessageFrame ( const CVector& vecbyData, const int iNumBytesIn, CVector& vecbyMesBodyData, int& iRecCounter, int& iRecID ); void ParseMessageBody ( const CVector& vecbyMesBodyData, const int iRecCounter, const int iRecID ); void ParseConnectionLessMessageBody ( const CVector& vecbyMesBodyData, const int iRecID, const CHostAddress& InetAddr ); static bool IsConnectionLessMessageID ( const int iID ) { return ( iID >= 1000 ) && ( iID < 2000 ); } // this function is public because we need it in the test bench void CreateAndImmSendAcknMess ( const int& iID, const int& iCnt ); protected: class CSendMessage { public: CSendMessage() : vecMessage ( 0 ), iID ( PROTMESSID_ILLEGAL ), iCnt ( 0 ) {} CSendMessage ( const CVector& nMess, const int iNCnt, const int iNID ) : vecMessage ( nMess ), iID ( iNID ), iCnt ( iNCnt ) {} CSendMessage& operator= ( const CSendMessage& NewSendMess ) { vecMessage.Init ( NewSendMess.vecMessage.Size() ); vecMessage = NewSendMess.vecMessage; iID = NewSendMess.iID; iCnt = NewSendMess.iCnt; return *this; } CVector vecMessage; int iID, iCnt; }; void EnqueueMessage ( CVector& vecMessage, const int iCnt, const int iID ); void GenMessageFrame ( CVector& vecOut, const int iCnt, const int iID, const CVector& vecData ); void GenSplitMessageContainer ( CVector& vecOut, const int iID, const int iNumParts, const int iSplitCnt, const CVector& vecData, const int iStartIndexInData, const int iLengthOfDataPart ); bool ParseSplitMessageContainer ( const CVector& vecbyData, CVector& vecbyMesBodyData, const int iSplitMessageDataIndex, int& iID, int& iNumParts, int& iSplitCnt, int& iCurPartSize ); void PutValOnStream ( CVector& vecIn, int& iPos, const uint32_t iVal, const int iNumOfBytes ); void PutStringUTF8OnStream ( CVector& vecIn, int& iPos, const QByteArray& sStringUTF8, const int iNumberOfBytsLen = 2 ); // default is 2 bytes length indicator void PutCountryOnStream ( CVector& vecIn, int& iPos, QLocale::Country eCountry ); static uint32_t GetValFromStream ( const CVector& vecIn, int& iPos, const int iNumOfBytes ); bool GetStringFromStream ( const CVector& vecIn, int& iPos, const int iMaxStringLen, QString& strOut, const int iNumberOfBytsLen = 2 ); // default is 2 bytes length indicator static QLocale::Country GetCountryFromStream ( const CVector& vecIn, int& iPos ); void SendMessage(); void CreateAndSendMessage ( const int iID, const CVector& vecData ); void CreateAndImmSendConLessMessage ( const int iID, const CVector& vecData, const CHostAddress& InetAddr ); bool EvaluateJitBufMes ( const CVector& vecData ); bool EvaluateReqJitBufMes(); bool EvaluateClientIDMes ( const CVector& vecData ); bool EvaluateChanGainMes ( const CVector& vecData ); bool EvaluateChanPanMes ( const CVector& vecData ); bool EvaluateMuteStateHasChangedMes ( const CVector& vecData ); bool EvaluateConClientListMes ( const CVector& vecData ); bool EvaluateReqConnClientsList(); bool EvaluateChanInfoMes ( const CVector& vecData ); bool EvaluateReqChanInfoMes(); bool EvaluateChatTextMes ( const CVector& vecData ); bool EvaluateNetwTranspPropsMes ( const CVector& vecData ); bool EvaluateReqNetwTranspPropsMes(); bool EvaluateReqSplitMessSupportMes(); bool EvaluateSplitMessSupportedMes(); bool EvaluateLicenceRequiredMes ( const CVector& vecData ); bool EvaluateVersionAndOSMes ( const CVector& vecData ); bool EvaluateRecorderStateMes ( const CVector& vecData ); bool EvaluateCLPingMes ( const CHostAddress& InetAddr, const CVector& vecData ); bool EvaluateCLPingWithNumClientsMes ( const CHostAddress& InetAddr, const CVector& vecData ); bool EvaluateCLServerFullMes(); bool EvaluateCLRegisterServerMes ( const CHostAddress& InetAddr, const CVector& vecData ); bool EvaluateCLRegisterServerExMes ( const CHostAddress& InetAddr, const CVector& vecData ); bool EvaluateCLUnregisterServerMes ( const CHostAddress& InetAddr ); bool EvaluateCLServerListMes ( const CHostAddress& InetAddr, const CVector& vecData ); bool EvaluateCLRedServerListMes ( const CHostAddress& InetAddr, const CVector& vecData ); bool EvaluateCLReqServerListMes ( const CHostAddress& InetAddr ); bool EvaluateCLSendEmptyMesMes ( const CVector& vecData ); bool EvaluateCLDisconnectionMes ( const CHostAddress& InetAddr ); bool EvaluateCLVersionAndOSMes ( const CHostAddress& InetAddr, const CVector& vecData ); bool EvaluateCLReqVersionAndOSMes ( const CHostAddress& InetAddr ); bool EvaluateCLConnClientsListMes ( const CHostAddress& InetAddr, const CVector& vecData ); bool EvaluateCLReqConnClientsListMes ( const CHostAddress& InetAddr ); bool EvaluateCLChannelLevelListMes ( const CHostAddress& InetAddr, const CVector& vecData ); bool EvaluateCLRegisterServerResp ( const CHostAddress& InetAddr, const CVector& vecData ); int iOldRecID; int iOldRecCnt; // these two objects must be sequred by a mutex uint8_t iCounter; std::list SendMessQueue; QTimer TimerSendMess; QMutex Mutex; CVector vecbySplitMessageStorage; int iSplitMessageCnt; int iSplitMessageDataIndex; bool bSplitMessageSupported; public slots: void OnTimerSendMess() { SendMessage(); } signals: // transmitting void MessReadyForSending ( CVector vecMessage ); void CLMessReadyForSending ( CHostAddress InetAddr, CVector vecMessage ); // receiving void ChangeJittBufSize ( int iNewJitBufSize ); void ReqJittBufSize(); void ChangeNetwBlSiFact ( int iNewNetwBlSiFact ); void ClientIDReceived ( int iChanID ); void ChangeChanGain ( int iChanID, float fNewGain ); void ChangeChanPan ( int iChanID, float fNewPan ); void MuteStateHasChangedReceived ( int iCurID, bool bIsMuted ); void ConClientListMesReceived ( CVector vecChanInfo ); void ServerFullMesReceived(); void ReqConnClientsList(); void ChangeChanInfo ( CChannelCoreInfo ChanInfo ); void ReqChanInfo(); void ChatTextReceived ( QString strChatText ); void NetTranspPropsReceived ( CNetworkTransportProps NetworkTransportProps ); void ReqNetTranspProps(); void ReqSplitMessSupport(); void SplitMessSupported(); void LicenceRequired ( ELicenceType eLicenceType ); void VersionAndOSReceived ( COSUtil::EOpSystemType eOSType, QString strVersion ); void RecorderStateReceived ( ERecorderState eRecorderState ); void CLPingReceived ( CHostAddress InetAddr, int iMs ); void CLPingWithNumClientsReceived ( CHostAddress InetAddr, int iMs, int iNumClients ); void CLRegisterServerReceived ( CHostAddress InetAddr, CHostAddress LInetAddr, CServerCoreInfo ServerInfo ); void CLRegisterServerExReceived ( CHostAddress InetAddr, CHostAddress LInetAddr, CServerCoreInfo ServerInfo, COSUtil::EOpSystemType eOSType, QString strVersion ); void CLUnregisterServerReceived ( CHostAddress InetAddr ); void CLServerListReceived ( CHostAddress InetAddr, CVector vecServerInfo ); void CLRedServerListReceived ( CHostAddress InetAddr, CVector vecServerInfo ); void CLReqServerList ( CHostAddress InetAddr ); void CLSendEmptyMes ( CHostAddress TargetInetAddr ); void CLDisconnection ( CHostAddress InetAddr ); void CLVersionAndOSReceived ( CHostAddress InetAddr, COSUtil::EOpSystemType eOSType, QString strVersion ); void CLReqVersionAndOS ( CHostAddress InetAddr ); void CLConnClientsListMesReceived ( CHostAddress InetAddr, CVector vecChanInfo ); void CLReqConnClientsList ( CHostAddress InetAddr ); void CLChannelLevelListReceived ( CHostAddress InetAddr, CVector vecLevelList ); void CLRegisterServerResp ( CHostAddress InetAddr, ESvrRegResult eStatus ); }; jamulus-3.9.1+dfsg/src/channel.h0000644000175000017500000002554114340334543015533 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #include #include #include #if QT_VERSION >= QT_VERSION_CHECK( 5, 6, 0 ) # include #endif #include "global.h" #include "buffer.h" #include "util.h" #include "protocol.h" #include "socket.h" /* Definitions ****************************************************************/ // set the time-out for the input buffer until the state changes from // connected to not connected (the actual time depends on the way the error // correction is implemented) #define CON_TIME_OUT_SEC_MAX 30 // seconds // number of frames for audio fade-in, 48 kHz, x samples: 3 sec / (x samples / 48 kHz) #define FADE_IN_NUM_FRAMES 2250 #define FADE_IN_NUM_FRAMES_DBLE_FRAMESIZE 1125 enum EPutDataStat { PS_GEN_ERROR, PS_AUDIO_OK, PS_AUDIO_ERR, PS_AUDIO_INVALID, PS_PROT_OK, PS_PROT_OK_MESS_NOT_EVALUATED, PS_PROT_ERR, PS_NEW_CONNECTION }; /* Classes ********************************************************************/ class CChannel : public QObject { Q_OBJECT public: // we have to make "server" the default since I do not see a chance to // use constructor initialization in the server for a vector of channels CChannel ( const bool bNIsServer = true ); void PutProtocolData ( const int iRecCounter, const int iRecID, const CVector& vecbyMesBodyData, const CHostAddress& RecHostAddr ); EPutDataStat PutAudioData ( const CVector& vecbyData, const int iNumBytes, CHostAddress RecHostAddr ); EGetDataStat GetData ( CVector& vecbyData, const int iNumBytes ); void PrepAndSendPacket ( CHighPrioSocket* pSocket, const CVector& vecbyNPacket, const int iNPacketLen ); void ResetTimeOutCounter() { iConTimeOut = iConTimeOutStartVal; } bool IsConnected() const { return iConTimeOut > 0; } void Disconnect(); void SetEnable ( const bool bNEnStat ); bool IsEnabled() { return bIsEnabled; } void SetAddress ( const CHostAddress NAddr ) { InetAddr = NAddr; } const CHostAddress& GetAddress() const { return InetAddr; } void ResetInfo() { bIsIdentified = false; ChannelInfo = CChannelCoreInfo(); } // reset does not emit a message QString GetName(); void SetChanInfo ( const CChannelCoreInfo& NChanInf ); CChannelCoreInfo& GetChanInfo() { return ChannelInfo; } void SetRemoteInfo ( const CChannelCoreInfo ChInfo ) { Protocol.CreateChanInfoMes ( ChInfo ); } void CreateReqChanInfoMes() { Protocol.CreateReqChanInfoMes(); } void CreateVersionAndOSMes() { Protocol.CreateVersionAndOSMes(); } void CreateMuteStateHasChangedMes ( const int iChanID, const bool bIsMuted ) { Protocol.CreateMuteStateHasChangedMes ( iChanID, bIsMuted ); } void SetGain ( const int iChanID, const float fNewGain ); float GetGain ( const int iChanID ); float GetFadeInGain() { return static_cast ( iFadeInCnt ) / iFadeInCntMax; } void SetPan ( const int iChanID, const float fNewPan ); float GetPan ( const int iChanID ); void SetRemoteChanGain ( const int iId, const float fGain ) { Protocol.CreateChanGainMes ( iId, fGain ); } void SetRemoteChanPan ( const int iId, const float fPan ) { Protocol.CreateChanPanMes ( iId, fPan ); } bool SetSockBufNumFrames ( const int iNewNumFrames, const bool bPreserve = false ); int GetSockBufNumFrames() const { return iCurSockBufNumFrames; } void UpdateSocketBufferSize(); int GetUploadRateKbps(); // set/get network out buffer size and size factor void SetAudioStreamProperties ( const EAudComprType eNewAudComprType, const int iNewNetwFrameSize, const int iNewNetwFrameSizeFact, const int iNewNumAudioChannels ); void SetDoAutoSockBufSize ( const bool bValue ) { bDoAutoSockBufSize = bValue; } bool GetDoAutoSockBufSize() const { return bDoAutoSockBufSize; } int GetNetwFrameSizeFact() const { return iNetwFrameSizeFact; } int GetCeltNumCodedBytes() const { return iCeltNumCodedBytes; } void GetBufErrorRates ( CVector& vecErrRates, double& dLimit, double& dMaxUpLimit ) { SockBuf.GetErrorRates ( vecErrRates, dLimit, dMaxUpLimit ); } EAudComprType GetAudioCompressionType() { return eAudioCompressionType; } int GetNumAudioChannels() const { return iNumAudioChannels; } // network protocol interface void CreateJitBufMes ( const int iJitBufSize ) { if ( ProtocolIsEnabled() ) { Protocol.CreateJitBufMes ( iJitBufSize ); } } void CreateClientIDMes ( const int iChanID ) { Protocol.CreateClientIDMes ( iChanID ); } void CreateReqNetwTranspPropsMes() { Protocol.CreateReqNetwTranspPropsMes(); } void CreateReqSplitMessSupportMes() { Protocol.CreateReqSplitMessSupportMes(); } void CreateReqJitBufMes() { Protocol.CreateReqJitBufMes(); } void CreateReqConnClientsList() { Protocol.CreateReqConnClientsList(); } void CreateChatTextMes ( const QString& strChatText ) { Protocol.CreateChatTextMes ( strChatText ); } void CreateLicReqMes ( const ELicenceType eLicenceType ) { Protocol.CreateLicenceRequiredMes ( eLicenceType ); } //### TODO: BEGIN ###// // needed for compatibility to old servers >= 3.4.6 and <= 3.5.12 void CreateReqChannelLevelListMes() { Protocol.CreateReqChannelLevelListMes(); } //### TODO: END ###// void CreateConClientListMes ( const CVector& vecChanInfo ) { Protocol.CreateConClientListMes ( vecChanInfo ); } void CreateRecorderStateMes ( const ERecorderState eRecorderState ) { Protocol.CreateRecorderStateMes ( eRecorderState ); } CNetworkTransportProps GetNetworkTransportPropsFromCurrentSettings(); double UpdateAndGetLevelForMeterdB ( const CVector& vecsAudio, const int iInSize, const bool bIsStereoIn ); protected: bool ProtocolIsEnabled(); void ResetNetworkTransportProperties() { // set it to a state were no decoding is ever possible (since we want // only to decode data when a network transport property message is // received with the correct values) eAudioCompressionType = CT_NONE; iNetwFrameSizeFact = FRAME_SIZE_FACTOR_PREFERRED; iNetwFrameSize = CELT_MINIMUM_NUM_BYTES; iCeltNumCodedBytes = CELT_MINIMUM_NUM_BYTES; iNumAudioChannels = 1; // mono bUseSequenceNumber = false; } // connection parameters CHostAddress InetAddr; // channel info CChannelCoreInfo ChannelInfo; // mixer and effect settings CVector vecfGains; CVector vecfPannings; // network jitter-buffer CNetBufWithStats SockBuf; int iCurSockBufNumFrames; bool bDoAutoSockBufSize; bool bUseSequenceNumber; uint8_t iSendSequenceNumber; // network output conversion buffer CConvBuf ConvBuf; // network protocol CProtocol Protocol; int iConTimeOut; int iConTimeOutStartVal; int iFadeInCnt; int iFadeInCntMax; bool bIsEnabled; bool bIsServer; bool bIsIdentified; int iNetwFrameSizeFact; int iNetwFrameSize; int iCeltNumCodedBytes; int iAudioFrameSizeSamples; EAudComprType eAudioCompressionType; int iNumAudioChannels; QMutex Mutex; QMutex MutexSocketBuf; QMutex MutexConvBuf; CStereoSignalLevelMeter SignalLevelMeter; public slots: void OnSendProtMessage ( CVector vecMessage ); void OnJittBufSizeChange ( int iNewJitBufSize ); void OnChangeChanGain ( int iChanID, float fNewGain ); void OnChangeChanPan ( int iChanID, float fNewPan ); void OnChangeChanInfo ( CChannelCoreInfo ChanInfo ); void OnNetTranspPropsReceived ( CNetworkTransportProps NetworkTransportProps ); void OnReqNetTranspProps(); void OnReqSplitMessSupport(); void OnSplitMessSupported() { Protocol.SetSplitMessageSupported ( true ); } void OnVersionAndOSReceived ( COSUtil::EOpSystemType eOSType, QString strVersion ); void OnParseMessageBody ( CVector vecbyMesBodyData, int iRecCounter, int iRecID ) { // note that the return value is ignored here Protocol.ParseMessageBody ( vecbyMesBodyData, iRecCounter, iRecID ); } void OnProtocolMessageReceived ( int iRecCounter, int iRecID, CVector vecbyMesBodyData, CHostAddress RecHostAddr ) { PutProtocolData ( iRecCounter, iRecID, vecbyMesBodyData, RecHostAddr ); } void OnProtocolCLMessageReceived ( int iRecID, CVector vecbyMesBodyData, CHostAddress RecHostAddr ) { emit DetectedCLMessage ( vecbyMesBodyData, iRecID, RecHostAddr ); } void OnNewConnection() { emit NewConnection(); } signals: void MessReadyForSending ( CVector vecMessage ); void NewConnection(); void ReqJittBufSize(); void JittBufSizeChanged ( int iNewJitBufSize ); void ServerAutoSockBufSizeChange ( int iNNumFra ); void ReqConnClientsList(); void ConClientListMesReceived ( CVector vecChanInfo ); void ChanInfoHasChanged(); void ClientIDReceived ( int iChanID ); void MuteStateHasChanged ( int iChanID, bool bIsMuted ); void MuteStateHasChangedReceived ( int iChanID, bool bIsMuted ); void ReqChanInfo(); void ChatTextReceived ( QString strChatText ); void ReqNetTranspProps(); void LicenceRequired ( ELicenceType eLicenceType ); void VersionAndOSReceived ( COSUtil::EOpSystemType eOSType, QString strVersion ); void RecorderStateReceived ( ERecorderState eRecorderState ); void Disconnected(); void DetectedCLMessage ( CVector vecbyMesBodyData, int iRecID, CHostAddress RecHostAddr ); void ParseMessageBody ( CVector vecbyMesBodyData, int iRecCounter, int iRecID ); }; jamulus-3.9.1+dfsg/src/buffer.h0000644000175000017500000003321014340334543015364 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #include "util.h" #include "global.h" /* Definitions ****************************************************************/ // number of simulation network jitter buffers for evaluating the statistic // NOTE If you want to change this number, the code has to modified, too! #define NUM_STAT_SIMULATION_BUFFERS 10 // hysteresis for buffer size decision to avoid fast changes if close to the bound #define FILTER_DECISION_HYSTERESIS 0.1 // definition of the upper error bound of the jitter buffers #define ERROR_RATE_BOUND_DOUBLE_FRAME_SIZE 0.0005 #define ERROR_RATE_BOUND ( ERROR_RATE_BOUND_DOUBLE_FRAME_SIZE / 2 ) // definition of the upper jitter buffer error bound, if that one is reached we // have to speed up the filtering to quickly get out of a incorrect buffer // size state #define UP_MAX_ERROR_BOUND_DOUBLE_FRAME_SIZE 0.01 #define UP_MAX_ERROR_BOUND ( UP_MAX_ERROR_BOUND_DOUBLE_FRAME_SIZE / 2 ) // each regular buffer access lead to a count for put and get, assuming 2.66 ms // blocks we have 15 s / 2.66 ms * 2 = approx. 11000 #define MAX_STATISTIC_COUNT_DOUBLE_FRAME_SIZE 11000 // each regular buffer access lead to a count for put and get, assuming 1.33 ms // blocks we have 15 s / 1.33 ms * 2 = approx. 22500 #define MAX_STATISTIC_COUNT 22500 // Note that the following definitions of the weigh constants assume a block // size of 128 samples at a sampling rate of 48 kHz. #define IIR_WEIGTH_UP_NORMAL_DOUBLE_FRAME_SIZE 0.999995 #define IIR_WEIGTH_DOWN_NORMAL_DOUBLE_FRAME_SIZE 0.9999 #define IIR_WEIGTH_UP_FAST_DOUBLE_FRAME_SIZE 0.9995 #define IIR_WEIGTH_DOWN_FAST_DOUBLE_FRAME_SIZE 0.999 // convert numbers from 128 samples case using http://www.tsdconseil.fr/tutos/tuto-iir1-en.pdf // and https://octave-online.net: // gamma = exp(-Ts/tau), after some calculations we get: x=0.999995;exp(64/128*log(x)) #define IIR_WEIGTH_UP_NORMAL 0.9999975 #define IIR_WEIGTH_DOWN_NORMAL 0.99994999875 #define IIR_WEIGTH_UP_FAST 0.9997499687422 #define IIR_WEIGTH_DOWN_FAST 0.999499875 /* Classes ********************************************************************/ // Buffer base class ----------------------------------------------------------- template class CBuffer { public: CBuffer() {} void Init ( const int iNewMemSize ) { // allocate memory for actual data buffer vecMemory.Init ( iNewMemSize ); // init buffer pointers and buffer state (empty buffer) iGetPos = 0; iPutPos = 0; eBufState = BS_EMPTY; // store total memory size value iMemSize = iNewMemSize; } virtual bool Put ( const CVector& vecData, const int iInSize ) { // copy new data in internal buffer int iCurPos = 0; if ( iPutPos + iInSize > iMemSize ) { // remaining space size for second block const int iRemSpace = iPutPos + iInSize - iMemSize; // data must be written in two steps because of wrap around while ( iPutPos < iMemSize ) { vecMemory[iPutPos++] = vecData[iCurPos++]; } for ( iPutPos = 0; iPutPos < iRemSpace; iPutPos++ ) { vecMemory[iPutPos] = vecData[iCurPos++]; } } else { // data can be written in one step std::copy ( vecData.begin(), vecData.begin() + iInSize, vecMemory.begin() + iPutPos ); // set the put position one block further (no wrap around needs // to be considered here) iPutPos += iInSize; } // take care about wrap around of put pointer if ( iPutPos == iMemSize ) { iPutPos = 0; } // set buffer state flag if ( iPutPos == iGetPos ) { eBufState = BS_FULL; } else { eBufState = BS_OK; } return true; // no error check in base class, always return ok } virtual bool Get ( CVector& vecData, const int iOutSize ) { // copy data from internal buffer in output buffer int iCurPos = 0; if ( iGetPos + iOutSize > iMemSize ) { // remaining data size for second block const int iRemData = iGetPos + iOutSize - iMemSize; // data must be read in two steps because of wrap around while ( iGetPos < iMemSize ) { vecData[iCurPos++] = vecMemory[iGetPos++]; } for ( iGetPos = 0; iGetPos < iRemData; iGetPos++ ) { vecData[iCurPos++] = vecMemory[iGetPos]; } } else { // data can be read in one step std::copy ( vecMemory.begin() + iGetPos, vecMemory.begin() + iGetPos + iOutSize, vecData.begin() ); // set the get position one block further (no wrap around needs // to be considered here) iGetPos += iOutSize; } // take care about wrap around of get pointer if ( iGetPos == iMemSize ) { iGetPos = 0; } // set buffer state flag if ( iPutPos == iGetPos ) { eBufState = BS_EMPTY; } else { eBufState = BS_OK; } return true; // no error check in base class, always return ok } virtual int GetAvailData() const { // calculate available data in buffer int iAvData = iPutPos - iGetPos; // check for special case and wrap around if ( iAvData < 0 ) { iAvData += iMemSize; // wrap around } else { if ( ( iAvData == 0 ) && ( eBufState == BS_FULL ) ) { iAvData = iMemSize; } } return iAvData; } bool isFull() const { return eBufState == BS_FULL; } bool isEmpty() const { return eBufState == BS_EMPTY; } protected: enum EBufState { BS_OK, BS_FULL, BS_EMPTY }; CVector vecMemory; int iMemSize; int iGetPos; int iPutPos; EBufState eBufState; }; // Network buffer (jitter buffer) ---------------------------------------------- class CNetBuf { public: CNetBuf ( const bool bNIsSim = false ) : iSequenceNumberAtGetPos ( 0 ), bIsSimulation ( bNIsSim ), bIsInitialized ( false ) {} void Init ( const int iNewBlockSize, const int iNewNumBlocks, const bool bNUseSequenceNumber, const bool bPreserve = false ); void SetIsSimulation ( const bool bNIsSim ) { bIsSimulation = bNIsSim; } virtual bool Put ( const CVector& vecbyData, int iInSize ); virtual bool Get ( CVector& vecbyData, const int iOutSize ); protected: enum EBufState { BS_OK, BS_FULL, BS_EMPTY }; int GetAvailSpace() const; int GetAvailData() const; void Resize ( const int iNewNumBlocks, const int iNewBlockSize ); CVector> vecvecMemory; CVector veciBlockValid; int iNumBlocksMemory; int iBlockGetPos; int iBlockPutPos; int iBlockSize; uint8_t iSequenceNumberAtGetPos; // uint8_t so that it wraps automatically EBufState eBufState; bool bUseSequenceNumber; bool bIsSimulation; bool bIsInitialized; static constexpr int iNumBytesSeqNum = 1; // per definition 1 byte sequence counter }; // Network buffer (jitter buffer) with statistic calculations ------------------ class CNetBufWithStats : public CNetBuf { public: CNetBufWithStats(); void Init ( const int iNewBlockSize, const int iNewNumBlocks, const bool bNUseSequenceNumber, const bool bPreserve = false ); void SetUseDoubleSystemFrameSize ( const bool bNDSFSize ) { bUseDoubleSystemFrameSize = bNDSFSize; } virtual bool Put ( const CVector& vecbyData, const int iInSize ); virtual bool Get ( CVector& vecbyData, const int iOutSize ); int GetAutoSetting() { return iCurAutoBufferSizeSetting; } void GetErrorRates ( CVector& vecErrRates, double& dLimit, double& dMaxUpLimit ); protected: void UpdateAutoSetting(); void ResetInitCounter(); // statistic (do not use the vector class since the classes do not have // appropriate copy constructor/operator) CErrorRate ErrorRateStatistic[NUM_STAT_SIMULATION_BUFFERS]; CNetBuf SimulationBuffer[NUM_STAT_SIMULATION_BUFFERS]; int viBufSizesForSim[NUM_STAT_SIMULATION_BUFFERS]; double dCurIIRFilterResult; int iCurDecidedResult; int iInitCounter; int iCurAutoBufferSizeSetting; int iMaxStatisticCount; bool bUseDoubleSystemFrameSize; double dAutoFilt_WightUpNormal; double dAutoFilt_WightDownNormal; double dAutoFilt_WightUpFast; double dAutoFilt_WightDownFast; double dErrorRateBound; double dUpMaxErrorBound; }; // Conversion buffer (very simple buffer) -------------------------------------- // For this very simple buffer no wrap around mechanism is implemented. We // assume here, that the applied buffers are an integer fraction of the total // buffer size. template class CConvBuf { public: CConvBuf() { Init ( 0 ); } void Init ( const int iNewMemSize, const bool bNUseSequenceNumber = false ) { // allocate internal memory and reset read/write positions vecMemory.Init ( iNewMemSize ); iMemSize = iNewMemSize; iBufferSize = iNewMemSize; bUseSequenceNumber = bNUseSequenceNumber; Reset(); } void Reset() { iPutPos = 0; iGetPos = 0; } void SetBufferSize ( const int iNBSize ) { // if buffer size has changed, apply new value and reset the buffer pointers if ( ( iNBSize != iBufferSize ) && ( iNBSize <= iMemSize ) ) { iBufferSize = iNBSize; Reset(); } } void PutAll ( const CVector& vecsData ) { iGetPos = 0; std::copy ( vecsData.begin(), vecsData.begin() + iBufferSize, // note that input vector might be larger then memory size vecMemory.begin() ); } bool Put ( const CVector& vecData, const int iVecSize, const TData SequenceNumber = 0 ) { // calculate the end position after copying int iEnd = iPutPos + iVecSize; // consider optional sequence number if ( bUseSequenceNumber ) { iEnd++; } // first check for buffer overrun if ( iEnd <= iBufferSize ) { // copy new data in internal buffer std::copy ( vecData.begin(), vecData.begin() + iVecSize, vecMemory.begin() + iPutPos ); // add optional sequence number (NOTE that we currently // only support a single sequence number per packet) if ( bUseSequenceNumber ) { // append the sequence number at the end vecMemory[iPutPos + iVecSize] = SequenceNumber; } // set buffer pointer one block further iPutPos = iEnd; // return "buffer is ready for readout" flag return ( iEnd == iBufferSize ); } // buffer overrun or not initialized, return "not ready" return false; } const CVector& GetAll() { iPutPos = 0; return vecMemory; } void GetAll ( CVector& vecsData, const int iVecSize ) { iPutPos = 0; // copy data from internal buffer in given buffer std::copy ( vecMemory.begin(), vecMemory.begin() + iVecSize, vecsData.begin() ); } bool Get ( CVector& vecsData, const int iVecSize ) { // calculate the input size and the end position after copying const int iEnd = iGetPos + iVecSize; // first check for buffer underrun if ( iEnd <= iBufferSize ) { // copy new data from internal buffer std::copy ( vecMemory.begin() + iGetPos, vecMemory.begin() + iGetPos + iVecSize, vecsData.begin() ); // set buffer pointer one block further iGetPos = iEnd; // return the memory could be read return true; } // return that no memory could be read return false; } protected: CVector vecMemory; int iMemSize; int iBufferSize; bool bUseSequenceNumber; int iPutPos, iGetPos; }; jamulus-3.9.1+dfsg/src/clientsettingsdlg.h0000644000175000017500000001053414340334543017645 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "util.h" #include "client.h" #include "settings.h" #include "multicolorled.h" #include "ui_clientsettingsdlgbase.h" /* Definitions ****************************************************************/ // update time for GUI controls #define DISPLAY_UPDATE_TIME 1000 // ms /* Classes ********************************************************************/ class CClientSettingsDlg : public CBaseDlg, private Ui_CClientSettingsDlgBase { Q_OBJECT public: CClientSettingsDlg ( CClient* pNCliP, CClientSettings* pNSetP, QWidget* parent = nullptr ); void UpdateUploadRate(); void UpdateDisplay(); void UpdateSoundDeviceChannelSelectionFrame(); void SetEnableFeedbackDetection ( bool enable ); protected: void UpdateJitterBufferFrame(); void UpdateSoundCardFrame(); void UpdateDirectoryServerComboBox(); void UpdateAudioFaderSlider(); QString GenSndCrdBufferDelayString ( const int iFrameSize, const QString strAddText = "" ); virtual void showEvent ( QShowEvent* ); CClient* pClient; CClientSettings* pSettings; QTimer TimerStatus; QButtonGroup SndCrdBufferDelayButtonGroup; public slots: void OnTimerStatus() { UpdateDisplay(); } void OnNetBufValueChanged ( int value ); void OnNetBufServerValueChanged ( int value ); void OnAutoJitBufStateChanged ( int value ); void OnEnableOPUS64StateChanged ( int value ); void OnFeedbackDetectionChanged ( int value ); void OnCustomDirectoriesEditingFinished(); void OnNewClientLevelEditingFinished() { pSettings->iNewClientFaderLevel = edtNewClientLevel->text().toInt(); } void OnInputBoostChanged(); void OnSndCrdBufferDelayButtonGroupClicked ( QAbstractButton* button ); void OnSoundcardActivated ( int iSndDevIdx ); void OnLInChanActivated ( int iChanIdx ); void OnRInChanActivated ( int iChanIdx ); void OnLOutChanActivated ( int iChanIdx ); void OnROutChanActivated ( int iChanIdx ); void OnAudioChannelsActivated ( int iChanIdx ); void OnAudioQualityActivated ( int iQualityIdx ); void OnGUIDesignActivated ( int iDesignIdx ); void OnMeterStyleActivated ( int iMeterStyleIdx ); void OnAudioAlertsChanged ( int value ); void OnLanguageChanged ( QString strLanguage ) { pSettings->strLanguage = strLanguage; } void OnAliasTextChanged ( const QString& strNewName ); void OnInstrumentActivated ( int iCntryListItem ); void OnCountryActivated ( int iCntryListItem ); void OnCityTextChanged ( const QString& strNewName ); void OnSkillActivated ( int iCntryListItem ); void OnTabChanged(); void OnMakeTabChange ( int iTabIdx ); void OnAudioPanValueChanged ( int value ); #if defined( _WIN32 ) && !defined( WITH_JACK ) // Only include this slot for Windows when JACK is NOT used void OnDriverSetupClicked(); #endif signals: void GUIDesignChanged(); void MeterStyleChanged(); void AudioAlertsChanged(); void AudioChannelsChanged(); void CustomDirectoriesChanged(); void NumMixerPanelRowsChanged ( int value ); }; jamulus-3.9.1+dfsg/src/settings.h0000644000175000017500000002022014340334543015750 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #include #include #include #include #ifndef HEADLESS # include #endif #include "global.h" #ifndef SERVER_ONLY # include "client.h" #endif #include "server.h" #include "util.h" /* Classes ********************************************************************/ class CSettings : public QObject { Q_OBJECT public: CSettings() : vecWindowPosMain(), // empty array strLanguage ( "" ), strFileName ( "" ) { QObject::connect ( QCoreApplication::instance(), &QCoreApplication::aboutToQuit, this, &CSettings::OnAboutToQuit ); } void Load ( const QList CommandLineOptions ); void Save(); // common settings QByteArray vecWindowPosMain; QString strLanguage; protected: virtual void WriteSettingsToXML ( QDomDocument& IniXMLDocument ) = 0; virtual void ReadSettingsFromXML ( const QDomDocument& IniXMLDocument, const QList& CommandLineOptions ) = 0; void ReadFromFile ( const QString& strCurFileName, QDomDocument& XMLDocument ); void WriteToFile ( const QString& strCurFileName, const QDomDocument& XMLDocument ); void SetFileName ( const QString& sNFiName, const QString& sDefaultFileName ); // The following functions implement the conversion from the general string // to base64 (which should be used for binary data in XML files). This // enables arbitrary utf8 characters to be used as the names in the GUI. // // ATTENTION: The "FromBase64[...]" functions must be used with caution! // The reason is that if the FromBase64ToByteArray() is used to // assign the stored value to a QString, this is incorrect but // will not generate a compile error since there is a default // conversion available for QByteArray to QString. QString ToBase64 ( const QByteArray strIn ) const { return QString::fromLatin1 ( strIn.toBase64() ); } QString ToBase64 ( const QString strIn ) const { return ToBase64 ( strIn.toUtf8() ); } QByteArray FromBase64ToByteArray ( const QString strIn ) const { return QByteArray::fromBase64 ( strIn.toLatin1() ); } QString FromBase64ToString ( const QString strIn ) const { return QString::fromUtf8 ( FromBase64ToByteArray ( strIn ) ); } // init file access function for read/write void SetNumericIniSet ( QDomDocument& xmlFile, const QString& strSection, const QString& strKey, const int iValue = 0 ); bool GetNumericIniSet ( const QDomDocument& xmlFile, const QString& strSection, const QString& strKey, const int iRangeStart, const int iRangeStop, int& iValue ); void SetFlagIniSet ( QDomDocument& xmlFile, const QString& strSection, const QString& strKey, const bool bValue = false ); bool GetFlagIniSet ( const QDomDocument& xmlFile, const QString& strSection, const QString& strKey, bool& bValue ); // actual working function for init-file access QString GetIniSetting ( const QDomDocument& xmlFile, const QString& sSection, const QString& sKey, const QString& sDefaultVal = "" ); void PutIniSetting ( QDomDocument& xmlFile, const QString& sSection, const QString& sKey, const QString& sValue = "" ); QString strFileName; public slots: void OnAboutToQuit() { Save(); } }; #ifndef SERVER_ONLY class CClientSettings : public CSettings { public: CClientSettings ( CClient* pNCliP, const QString& sNFiName ) : CSettings(), vecStoredFaderTags ( MAX_NUM_STORED_FADER_SETTINGS, "" ), vecStoredFaderLevels ( MAX_NUM_STORED_FADER_SETTINGS, AUD_MIX_FADER_MAX ), vecStoredPanValues ( MAX_NUM_STORED_FADER_SETTINGS, AUD_MIX_PAN_MAX / 2 ), vecStoredFaderIsSolo ( MAX_NUM_STORED_FADER_SETTINGS, false ), vecStoredFaderIsMute ( MAX_NUM_STORED_FADER_SETTINGS, false ), vecStoredFaderGroupID ( MAX_NUM_STORED_FADER_SETTINGS, INVALID_INDEX ), vstrIPAddress ( MAX_NUM_SERVER_ADDR_ITEMS, "" ), iNewClientFaderLevel ( 100 ), iInputBoost ( 1 ), iSettingsTab ( SETTING_TAB_AUDIONET ), bConnectDlgShowAllMusicians ( true ), eChannelSortType ( ST_NO_SORT ), iNumMixerPanelRows ( 1 ), vstrDirectoryAddress ( MAX_NUM_SERVER_ADDR_ITEMS, "" ), eDirectoryType ( AT_DEFAULT ), bEnableFeedbackDetection ( true ), bEnableAudioAlerts ( false ), vecWindowPosSettings(), // empty array vecWindowPosChat(), // empty array vecWindowPosConnect(), // empty array bWindowWasShownSettings ( false ), bWindowWasShownChat ( false ), bWindowWasShownConnect ( false ), bOwnFaderFirst ( false ), pClient ( pNCliP ) { SetFileName ( sNFiName, DEFAULT_INI_FILE_NAME ); } void LoadFaderSettings ( const QString& strCurFileName ); void SaveFaderSettings ( const QString& strCurFileName ); // general settings CVector vecStoredFaderTags; CVector vecStoredFaderLevels; CVector vecStoredPanValues; CVector vecStoredFaderIsSolo; CVector vecStoredFaderIsMute; CVector vecStoredFaderGroupID; CVector vstrIPAddress; int iNewClientFaderLevel; int iInputBoost; int iSettingsTab; bool bConnectDlgShowAllMusicians; EChSortType eChannelSortType; int iNumMixerPanelRows; CVector vstrDirectoryAddress; EDirectoryType eDirectoryType; int iCustomDirectoryIndex; // index of selected custom directory server bool bEnableFeedbackDetection; bool bEnableAudioAlerts; bool bCleanUpLegacyFaderSettings; // window position/state settings QByteArray vecWindowPosSettings; QByteArray vecWindowPosChat; QByteArray vecWindowPosConnect; bool bWindowWasShownSettings; bool bWindowWasShownChat; bool bWindowWasShownConnect; bool bOwnFaderFirst; protected: virtual void WriteSettingsToXML ( QDomDocument& IniXMLDocument ) override; virtual void ReadSettingsFromXML ( const QDomDocument& IniXMLDocument, const QList& CommandLineOptions ) override; // Code for #2680 clean up QString CleanUpLegacyFaderSetting ( QString strFaderTag, int iIdx ); void ReadFaderSettingsFromXML ( const QDomDocument& IniXMLDocument ); void WriteFaderSettingsToXML ( QDomDocument& IniXMLDocument ); CClient* pClient; }; #endif class CServerSettings : public CSettings { public: CServerSettings ( CServer* pNSerP, const QString& sNFiName ) : CSettings(), pServer ( pNSerP ) { SetFileName ( sNFiName, DEFAULT_INI_FILE_NAME_SERVER ); } protected: virtual void WriteSettingsToXML ( QDomDocument& IniXMLDocument ) override; virtual void ReadSettingsFromXML ( const QDomDocument& IniXMLDocument, const QList& CommandLineOptions ) override; CServer* pServer; }; jamulus-3.9.1+dfsg/src/global.h0000644000175000017500000003326314340334543015363 0ustar vimervimer/******************************************************************************\ * \Copyright (c) 2004-2022 * \author Volker Fischer * \mainpage Jamulus source code documentation \section intro_sec Introduction The Jamulus software enables musicians to perform real-time jam sessions over the internet. There is one server running the Jamulus server software which collects the audio data from each Jamulus client, mixes the audio data and sends the mix back to each client. Prefix definitions for the GUI: label: lbl combo box: cbx line edit: edt list view: lvw check box: chb radio button: rbt button: but text view: txv slider: sld LED: led group box: grb pixmap label: pxl LED bar: lbr ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #if _WIN32 # define _CRT_SECURE_NO_WARNINGS #endif #include #include #include #include #include #include #ifndef _WIN32 # include // solves a compile problem on recent Ubuntu #endif #ifdef HAVE_CONFIG_H # include "config.h" #endif /* Definitions ****************************************************************/ // define this macro to get debug output //#define _DEBUG_ #undef _DEBUG_ // version and application name (use version from qt prject file) #undef VERSION #define VERSION APP_VERSION #define APP_NAME "Jamulus" // Windows registry key name of auto run entry for the server #define AUTORUN_SERVER_REG_NAME "Jamulus server" // default names of the ini-file for client and server #define DEFAULT_INI_FILE_NAME "Jamulus.ini" #define DEFAULT_INI_FILE_NAME_SERVER "Jamulusserver.ini" // file name for logging file #define DEFAULT_LOG_FILE_NAME "Jamulussrvlog.txt" // System block size, this is the block size on which the audio coder works. // All other block sizes must be a multiple of this size. // Note that the UpdateAutoSetting() function assumes a value of 128. #define SYSTEM_FRAME_SIZE_SAMPLES 64 #define DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES ( 2 * SYSTEM_FRAME_SIZE_SAMPLES ) // additional buffer for delay panning #define MAX_DELAY_PANNING_SAMPLES 64 // default server address and port numbers #define DEFAULT_QOS_NUMBER 128 // CS4 (Quality of Service) #define DEFAULT_SERVER_ADDRESS "anygenre1.jamulus.io" #define DEFAULT_PORT_NUMBER 22124 #define CENTSERV_ANY_GENRE2 "anygenre2.jamulus.io:22224" #define CENTSERV_ANY_GENRE3 "anygenre3.jamulus.io:22624" #define CENTSERV_GENRE_ROCK "rock.jamulus.io:22424" #define CENTSERV_GENRE_JAZZ "jazz.jamulus.io:22324" #define CENTSERV_GENRE_CLASSICAL_FOLK "classical.jamulus.io:22524" #define CENTSERV_GENRE_CHORAL "choral.jamulus.io:22724" // specify an invalid port to disable the server #define INVALID_PORT -1 // servers to check for new versions #define UPDATECHECK1_ADDRESS "updatecheck1.jamulus.io" #define UPDATECHECK2_ADDRESS "updatecheck2.jamulus.io" // getting started and software manual URL #define CLIENT_GETTING_STARTED_URL "https://jamulus.io/wiki/Getting-Started" #define SERVER_GETTING_STARTED_URL "https://jamulus.io/wiki/Running-a-Server" #define SOFTWARE_MANUAL_URL "https://jamulus.io/wiki/Software-Manual" // app update message #define APP_UPGRADE_AVAILABLE_MSG_TEXT \ QCoreApplication::translate ( \ "global", \ "A %1 upgrade is available: go to details and downloads" ) // determining server internal address uses well-known host and port // We just need a valid, public Internet IP here. We will not send any // traffic there as we will only set up an UDP socket without sending any // data. #define WELL_KNOWN_HOST "1.1.1.1" // CloudFlare #define WELL_KNOWN_HOST6 "2606:4700:4700::1111" // CloudFlare #define WELL_KNOWN_PORT DEFAULT_PORT_NUMBER #define IP_LOOKUP_TIMEOUT 500 // ms // system sample rate (the sound card and audio coder works on this sample rate) #define SYSTEM_SAMPLE_RATE_HZ 48000 // Hz // define the allowed audio frame size factors (since the // "SYSTEM_FRAME_SIZE_SAMPLES" is quite small, it may be that on some // computers a larger value is required) #define FRAME_SIZE_FACTOR_PREFERRED 1 // 64 samples accumulated frame size #define FRAME_SIZE_FACTOR_DEFAULT 2 // 128 samples accumulated frame size #define FRAME_SIZE_FACTOR_SAFE 4 // 256 samples accumulated frame size // define the minimum allowed number of coded bytes for CELT (the encoder // gets in trouble if the value is too low) #define CELT_MINIMUM_NUM_BYTES 10 // Maximum block size for network input buffer. It is defined by the longest // protocol message which is PROTMESSID_CLM_SERVER_LIST: Worst case: // (2+2+1+2+2)+200*(4+2+2+1+1+2+20+2+32+2+20)=17609 // We add some headroom to that value. #define MAX_SIZE_BYTES_NETW_BUF 20000 // minimum/maximum network buffer size (which can be chosen by slider) #define MIN_NET_BUF_SIZE_NUM_BL 1 // number of blocks #define MAX_NET_BUF_SIZE_NUM_BL 20 // number of blocks #define AUTO_NET_BUF_SIZE_FOR_PROTOCOL ( MAX_NET_BUF_SIZE_NUM_BL + 1 ) // auto set parameter (only used for protocol) // default network buffer size #define DEF_NET_BUF_SIZE_NUM_BL 10 // number of blocks // audio mixer fader and panning maximum value #define AUD_MIX_FADER_MAX 100 #define AUD_MIX_PAN_MAX 100 // range of audio mixer fader #define AUD_MIX_FADER_RANGE_DB 35.0f // coefficient for averaging channel levels for automatic fader adjustment #define AUTO_FADER_ADJUST_ALPHA 0.2f // target level for auto fader adjustment in decibels #define AUTO_FADER_TARGET_LEVEL_DB -30.0f // threshold in decibels below which the channel is considered as noise // and not adjusted #define AUTO_FADER_NOISE_THRESHOLD_DB -40.0f // maximum number of fader groups (must be consistent to audiomixerboard implementation) #define MAX_NUM_FADER_GROUPS 8 // maximum number of recognized sound cards installed in the system #define MAX_NUMBER_SOUND_CARDS 129 // e.g. 16 inputs, 8 outputs + default entry (MacOS) // define the maximum number of audio channel for input/output we can store // channel infos for (and therefore this is the maximum number of entries in // the channel selection combo box regardless of the actual available number // of channels by the audio device) #define MAX_NUM_IN_OUT_CHANNELS 64 // maximum number of elemts in the server address combo box #define MAX_NUM_SERVER_ADDR_ITEMS 12 // maximum number of fader settings to be stored (together with the fader tags) #define MAX_NUM_STORED_FADER_SETTINGS 250 // range for signal level meter #define LOW_BOUND_SIG_METER ( -50.0 ) // dB #define UPPER_BOUND_SIG_METER ( 0.0 ) // dB // defines for LED level meter CLevelMeter #define NUM_STEPS_LED_BAR 8 #define RED_BOUND_LED_BAR 7 #define YELLOW_BOUND_LED_BAR 5 // maximum number of connected clients at the server (must not be larger than 256) #define MAX_NUM_CHANNELS 150 // max number channels for server // actual number of used channels in the server // this parameter can safely be changed from 1 to MAX_NUM_CHANNELS // without any other changes in the code #define DEFAULT_USED_NUM_CHANNELS 10 // default used number channels for server // Maximum number of servers registered in the server list. If you want to // change this parameter, you most probably have to adjust MAX_SIZE_BYTES_NETW_BUF. #define MAX_NUM_SERVERS_IN_SERVER_LIST 150 // reduced to 150 because we now have genre-based server lists // defines the time interval at which the ping time is updated in the GUI #define PING_UPDATE_TIME_MS 500 // ms // defines the time interval at which the ping time is updated for the server list #define PING_UPDATE_TIME_SERVER_LIST_MS 2500 // ms // defines the interval between Channel Level updates from the server #define CHANNEL_LEVEL_UPDATE_INTERVAL 200 // number of frames at 64 samples frame size // time-out until a registered server is deleted from the server list if no // new registering was made in minutes #define SERVLIST_TIME_OUT_MINUTES 33 // minutes (should include 3 UDP registration messages) // poll time for server list (to check if entries are time-out) #define SERVLIST_POLL_TIME_MINUTES 1 // minute // time interval for sending ping messages to servers in the server list #define SERVLIST_UPDATE_PING_SERVERS_MS 59000 // ms // time between server registration refreshes #define SERVLIST_REGIST_INTERV_MINUTES 15 // minutes // defines the minimum time a server must run to be a permanent server #define SERVLIST_TIME_PERMSERV_MINUTES 2880 // minutes, 2880 = 60 min * 24 h * 2 d // registration response timeout #define REGISTER_SERVER_TIME_OUT_MS 500 // ms // defines the maximum number of times to retry server registration // when no response is received within the timeout (before reverting // to SERVLIST_REGIST_INTERV_MINUTES) #define REGISTER_SERVER_RETRY_LIMIT 5 // count // Maximum length of fader tag and text message strings (Since for chat messages // some HTML code is added, we also have to define a second length which includes // this additionl HTML code. Right now the length of the HTML code is approx. 66 // characters. Here, we add some headroom to this number) #define MAX_LEN_FADER_TAG 16 #define MAX_LEN_CHAT_TEXT 1600 #define MAX_LEN_CHAT_TEXT_PLUS_HTML 1800 #define MAX_LEN_SERVER_NAME 20 #define MAX_LEN_IP_ADDRESS 15 #define MAX_LEN_SERVER_CITY 20 #define MAX_LEN_VERSION_TEXT 30 // define Settings tab indexes #define SETTING_TAB_USER 0 #define SETTING_TAB_AUDIONET 1 #define SETTING_TAB_ADVANCED 2 // common tool tip bottom line text #define TOOLTIP_COM_END_TEXT \ "
" + \ QCoreApplication::translate ( "global", \ "For more information use the \"What's " \ "This\" help (help menu, right mouse button or Shift+F1)" ) + \ "
" // server welcome message title (do not change for compatibility!) #define WELCOME_MESSAGE_PREFIX "Server Welcome Message: " // mixer settings file name suffix #define MIX_SETTINGS_FILE_SUFFIX "jch" // minimum length of JSON-RPC secret string (main.cpp) #define JSON_RPC_MINIMUM_SECRET_LENGTH 16 // JSON-RPC listen address #define JSON_RPC_LISTEN_ADDRESS "127.0.0.1" #define _MAXSHORT 32767 #define _MINSHORT ( -32768 ) #define INVALID_INDEX -1 // define invalid index as a negative value (a valid index must always be >= 0) #if HAVE_STDINT_H # include #elif HAVE_INTTYPES_H # include #elif defined( _WIN32 ) typedef __int64 int64_t; typedef __int32 int32_t; typedef __int16 int16_t; typedef unsigned __int64 uint64_t; typedef unsigned __int32 uint32_t; typedef unsigned __int16 uint16_t; typedef unsigned __int8 uint8_t; #elif defined( ANDROID ) // don't redfine types for android as these ones below don't work #else typedef long long int64_t; typedef int int32_t; typedef short int16_t; typedef unsigned long long uint64_t; typedef unsigned int uint32_t; typedef unsigned short uint16_t; typedef unsigned char uint8_t; #endif /* Pseudo enum definitions -------------------------------------------------- */ // definition for custom event #define MS_PACKET_RECEIVED 0 /* Classes ********************************************************************/ class CGenErr { public: CGenErr ( QString strNewErrorMsg, QString strNewErrorType = "" ) : strErrorMsg ( strNewErrorMsg ), strErrorType ( strNewErrorType ) {} QString GetErrorText() const { // return formatted error text if ( strErrorType.isEmpty() ) { return strErrorMsg; } else { return strErrorType + ": " + strErrorMsg; } } protected: QString strErrorMsg; QString strErrorType; }; class CCustomEvent : public QEvent { public: CCustomEvent ( int iNewMeTy, int iNewSt, int iNewChN = 0 ) : QEvent ( QEvent::Type ( QEvent::User + 11 ) ), iMessType ( iNewMeTy ), iStatus ( iNewSt ), iChanNum ( iNewChN ) {} int iMessType; int iStatus; int iChanNum; }; /* Prototypes for global functions ********************************************/ // command line parsing, TODO do not declare functions globally but in a class QString UsageArguments ( char** argv ); bool GetFlagArgument ( char** argv, int& i, QString strShortOpt, QString strLongOpt ); bool GetStringArgument ( int argc, char** argv, int& i, QString strShortOpt, QString strLongOpt, QString& strArg ); bool GetNumericArgument ( int argc, char** argv, int& i, QString strShortOpt, QString strLongOpt, double rRangeStart, double rRangeStop, double& rValue ); jamulus-3.9.1+dfsg/src/clientrpc.cpp0000644000175000017500000002736014340334543016442 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2021-2022 * * Author(s): * dtinth * Christian Hoffmann * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include "clientrpc.h" CClientRpc::CClientRpc ( CClient* pClient, CRpcServer* pRpcServer, QObject* parent ) : QObject ( parent ) { /// @rpc_notification jamulusclient/chatTextReceived /// @brief Emitted when a chat text is received. /// @param {string} params.chatText - The chat text. connect ( pClient, &CClient::ChatTextReceived, [=] ( QString strChatText ) { pRpcServer->BroadcastNotification ( "jamulusclient/chatTextReceived", QJsonObject{ { "chatText", strChatText }, } ); } ); /// @rpc_notification jamulusclient/connected /// @brief Emitted when the client is connected to the server. /// @param {number} params.id - The channel ID assigned to the client. connect ( pClient, &CClient::ClientIDReceived, [=] ( int iChanID ) { pRpcServer->BroadcastNotification ( "jamulusclient/connected", QJsonObject{ { "id", iChanID }, } ); } ); /// @rpc_notification jamulusclient/clientListReceived /// @brief Emitted when the client list is received. /// @param {array} params.clients - The client list. /// @param {number} params.clients[*].id - The channel ID. /// @param {string} params.clients[*].name - The musician’s name. /// @param {string} params.clients[*].skillLevel - The musician’s skill level (beginner, intermediate, expert, or null). /// @param {number} params.clients[*].countryId - The musician’s country ID (see QLocale::Country). /// @param {string} params.clients[*].city - The musician’s city. /// @param {number} params.clients[*].instrumentId - The musician’s instrument ID (see CInstPictures::GetTable). connect ( pClient, &CClient::ConClientListMesReceived, [=] ( CVector vecChanInfo ) { QJsonArray arrChanInfo; for ( const auto& chanInfo : vecChanInfo ) { QJsonObject objChanInfo{ { "id", chanInfo.iChanID }, { "name", chanInfo.strName }, { "skillLevel", SerializeSkillLevel ( chanInfo.eSkillLevel ) }, { "countryId", chanInfo.eCountry }, { "city", chanInfo.strCity }, { "instrumentId", chanInfo.iInstrument }, }; arrChanInfo.append ( objChanInfo ); } pRpcServer->BroadcastNotification ( "jamulusclient/clientListReceived", QJsonObject{ { "clients", arrChanInfo }, } ); arrStoredChanInfo = arrChanInfo; } ); /// @rpc_notification jamulusclient/channelLevelListReceived /// @brief Emitted when the channel level list is received. /// @param {array} params.channelLevelList - The channel level list. /// Each item corresponds to the respective client retrieved from the jamulusclient/clientListReceived notification. /// @param {number} params.channelLevelList[*] - The channel level, an integer between 0 and 9. connect ( pClient, &CClient::CLChannelLevelListReceived, [=] ( CHostAddress /* unused */, CVector vecLevelList ) { QJsonArray arrLevelList; for ( const auto& level : vecLevelList ) { arrLevelList.append ( level ); } pRpcServer->BroadcastNotification ( "jamulusclient/channelLevelListReceived", QJsonObject{ { "channelLevelList", arrLevelList }, } ); } ); /// @rpc_notification jamulusclient/disconnected /// @brief Emitted when the client is disconnected from the server. /// @param {object} params - No parameters (empty object). connect ( pClient, &CClient::Disconnected, [=]() { pRpcServer->BroadcastNotification ( "jamulusclient/disconnected", QJsonObject{} ); } ); /// @rpc_method jamulus/getMode /// @brief Returns the current mode, i.e. whether Jamulus is running as a server or client. /// @param {object} params - No parameters (empty object). /// @result {string} result.mode - The current mode (server or client). pRpcServer->HandleMethod ( "jamulus/getMode", [=] ( const QJsonObject& params, QJsonObject& response ) { QJsonObject result{ { "mode", "client" } }; response["result"] = result; Q_UNUSED ( params ); } ); /// @rpc_method jamulusclient/getClientInfo /// @brief Returns the client information. /// @param {object} params - No parameters (empty object). /// @result {boolean} result.connected - Whether the client is connected to the server. pRpcServer->HandleMethod ( "jamulusclient/getClientInfo", [=] ( const QJsonObject& params, QJsonObject& response ) { QJsonObject result{ { "connected", pClient->IsConnected() } }; response["result"] = result; Q_UNUSED ( params ); } ); /// @rpc_method jamulusclient/getChannelInfo /// @brief Returns the client's profile information. /// @param {object} params - No parameters (empty object). /// @result {number} result.id - The channel ID. /// @result {string} result.name - The musician’s name. /// @result {string} result.skillLevel - The musician’s skill level (beginner, intermediate, expert, or null). /// @result {number} result.countryId - The musician’s country ID (see QLocale::Country). /// @result {string} result.city - The musician’s city. /// @result {number} result.instrumentId - The musician’s instrument ID (see CInstPictures::GetTable). /// @result {string} result.skillLevel - Your skill level (beginner, intermediate, expert, or null). pRpcServer->HandleMethod ( "jamulusclient/getChannelInfo", [=] ( const QJsonObject& params, QJsonObject& response ) { QJsonObject result{ // TODO: We cannot include "id" here is pClient->ChannelInfo is a CChannelCoreInfo which lacks that field. { "name", pClient->ChannelInfo.strName }, { "countryId", pClient->ChannelInfo.eCountry }, { "city", pClient->ChannelInfo.strCity }, { "instrumentId", pClient->ChannelInfo.iInstrument }, { "skillLevel", SerializeSkillLevel ( pClient->ChannelInfo.eSkillLevel ) }, }; response["result"] = result; Q_UNUSED ( params ); } ); /// @rpc_method jamulusclient/getClientList /// @brief Returns the client list. /// @param {object} params - No parameters (empty object). /// @result {array} result.clients - The client list. See jamulusclient/clientListReceived for the format. pRpcServer->HandleMethod ( "jamulusclient/getClientList", [=] ( const QJsonObject& params, QJsonObject& response ) { if ( !pClient->IsConnected() ) { response["error"] = CRpcServer::CreateJsonRpcError ( 1, "Client is not connected" ); return; } QJsonObject result{ { "clients", arrStoredChanInfo }, }; response["result"] = result; Q_UNUSED ( params ); } ); /// @rpc_method jamulusclient/setName /// @brief Sets your name. /// @param {string} params.name - The new name. /// @result {string} result - Always "ok". pRpcServer->HandleMethod ( "jamulusclient/setName", [=] ( const QJsonObject& params, QJsonObject& response ) { auto jsonName = params["name"]; if ( !jsonName.isString() ) { response["error"] = CRpcServer::CreateJsonRpcError ( CRpcServer::iErrInvalidParams, "Invalid params: name is not a string" ); return; } pClient->ChannelInfo.strName = TruncateString ( jsonName.toString(), MAX_LEN_FADER_TAG ); pClient->SetRemoteInfo(); response["result"] = "ok"; } ); /// @rpc_method jamulusclient/setSkillLevel /// @brief Sets your skill level. /// @param {string} params.skillLevel - The new skill level (beginner, intermediate, expert, or null). /// @result {string} result - Always "ok". pRpcServer->HandleMethod ( "jamulusclient/setSkillLevel", [=] ( const QJsonObject& params, QJsonObject& response ) { auto jsonSkillLevel = params["skillLevel"]; if ( jsonSkillLevel.isNull() ) { pClient->ChannelInfo.eSkillLevel = SL_NOT_SET; pClient->SetRemoteInfo(); return; } if ( !jsonSkillLevel.isString() ) { response["error"] = CRpcServer::CreateJsonRpcError ( CRpcServer::iErrInvalidParams, "Invalid params: skillLevel is not a string" ); return; } auto strSkillLevel = jsonSkillLevel.toString(); if ( strSkillLevel == "beginner" ) { pClient->ChannelInfo.eSkillLevel = SL_BEGINNER; } else if ( strSkillLevel == "intermediate" ) { pClient->ChannelInfo.eSkillLevel = SL_INTERMEDIATE; } else if ( strSkillLevel == "expert" ) { pClient->ChannelInfo.eSkillLevel = SL_PROFESSIONAL; } else { response["error"] = CRpcServer::CreateJsonRpcError ( CRpcServer::iErrInvalidParams, "Invalid params: skillLevel is not beginner, intermediate or expert" ); return; } pClient->SetRemoteInfo(); response["result"] = "ok"; } ); /// @rpc_method jamulusclient/sendChatText /// @brief Sends a chat text message. /// @param {string} params.chatText - The chat text message. /// @result {string} result - Always "ok". pRpcServer->HandleMethod ( "jamulusclient/sendChatText", [=] ( const QJsonObject& params, QJsonObject& response ) { auto jsonMessage = params["chatText"]; if ( !jsonMessage.isString() ) { response["error"] = CRpcServer::CreateJsonRpcError ( CRpcServer::iErrInvalidParams, "Invalid params: chatText is not a string" ); return; } if ( !pClient->IsConnected() ) { response["error"] = CRpcServer::CreateJsonRpcError ( 1, "Client is not connected" ); return; } pClient->CreateChatTextMes ( jsonMessage.toString() ); response["result"] = "ok"; } ); } QJsonValue CClientRpc::SerializeSkillLevel ( ESkillLevel eSkillLevel ) { switch ( eSkillLevel ) { case SL_BEGINNER: return QJsonValue ( "beginner" ); case SL_INTERMEDIATE: return QJsonValue ( "intermediate" ); case SL_PROFESSIONAL: return QJsonValue ( "expert" ); default: return QJsonValue ( QJsonValue::Null ); } } jamulus-3.9.1+dfsg/src/multicolorled.cpp0000644000175000017500000001106514340334543017330 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * * Description: * Implements a multi color LED * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include "multicolorled.h" /* Implementation *************************************************************/ CMultiColorLED::CMultiColorLED ( QWidget* parent ) : QLabel ( parent ), BitmCubeDisabled ( QString::fromUtf8 ( ":/png/LEDs/res/CLEDDisabled.png" ) ), BitmCubeGrey ( QString::fromUtf8 ( ":/png/LEDs/res/CLEDGrey.png" ) ), BitmCubeGreen ( QString::fromUtf8 ( ":/png/LEDs/res/CLEDGreenBig.png" ) ), BitmCubeYellow ( QString::fromUtf8 ( ":/png/LEDs/res/IndicatorYellowFancy.png" ) ), BitmCubeRed ( QString::fromUtf8 ( ":/png/LEDs/res/IndicatorRedFancy.png" ) ), BitmIndicatorGreen ( QString::fromUtf8 ( ":/png/LEDs/res/IndicatorGreen.png" ) ), BitmIndicatorYellow ( QString::fromUtf8 ( ":/png/LEDs/res/IndicatorYellow.png" ) ), BitmIndicatorRed ( QString::fromUtf8 ( ":/png/LEDs/res/IndicatorRed.png" ) ) { // set init bitmap setPixmap ( BitmCubeGrey ); eColorFlag = RL_GREY; // set default type and reset eType = MT_LED; Reset(); } void CMultiColorLED::SetType ( const EType eNType ) { eType = eNType; Reset(); } void CMultiColorLED::changeEvent ( QEvent* curEvent ) { // act on enabled changed state if ( curEvent->type() == QEvent::EnabledChange ) { if ( isEnabled() ) { setPixmap ( BitmCubeGrey ); eColorFlag = RL_GREY; } else { setPixmap ( BitmCubeDisabled ); eColorFlag = RL_DISABLED; } } } void CMultiColorLED::SetColor ( const ELightColor eNewColorFlag ) { switch ( eNewColorFlag ) { case RL_RED: // red if ( eColorFlag != RL_RED ) { if ( eType == MT_LED ) { setPixmap ( BitmCubeRed ); } else { setPixmap ( BitmIndicatorRed ); } setAccessibleDescription ( tr ( "Red" ) ); eColorFlag = RL_RED; } break; case RL_YELLOW: // yellow if ( eColorFlag != RL_YELLOW ) { if ( eType == MT_LED ) { setPixmap ( BitmCubeYellow ); } else { setPixmap ( BitmIndicatorYellow ); } setAccessibleDescription ( tr ( "Yellow" ) ); eColorFlag = RL_YELLOW; } break; case RL_GREEN: // green if ( eColorFlag != RL_GREEN ) { if ( eType == MT_LED ) { setPixmap ( BitmCubeGreen ); } else { setPixmap ( BitmIndicatorGreen ); } setAccessibleDescription ( tr ( "Green" ) ); eColorFlag = RL_GREEN; } break; default: // if no color is active, set control to grey light if ( eColorFlag != RL_GREY ) { if ( eType == MT_LED ) { setPixmap ( BitmCubeGrey ); } else { // make it invisible if in indicator mode setPixmap ( QPixmap() ); } eColorFlag = RL_GREY; } break; } } void CMultiColorLED::Reset() { if ( isEnabled() ) { // set color flag to disable to make sure the pixmap gets updated eColorFlag = RL_DISABLED; SetColor ( RL_GREY ); } } void CMultiColorLED::SetLight ( const ELightColor eNewStatus ) { if ( isEnabled() ) { SetColor ( eNewStatus ); } } jamulus-3.9.1+dfsg/src/clientdlgbase.ui0000644000175000017500000005504214340334543017110 0ustar vimervimer CClientDlgBase 0 0 511 490 true :/png/main/res/fronticon.png:/png/main/res/fronticon.png true 0 0 3 3 0 0 QFrame::NoFrame QFrame::Plain 6 3 0 0 :/png/main/res/fronticon.png Qt::AlignCenter false Qt::Vertical QSizePolicy::Expanding 13 10 3 Reverb Qt::AlignCenter Qt::Horizontal QSizePolicy::Minimum 0 20 0 0 0 125 16777215 300 1 Qt::Vertical QSlider::TicksBothSides Qt::Horizontal QSizePolicy::Minimum 0 20 3 Left Right Qt::Vertical QSizePolicy::Expanding 13 10 Qt::Vertical Input Qt::AlignCenter 0 0 19 88 0 0 19 88 L Qt::AlignCenter R Qt::AlignCenter Qt::Horizontal Jitter Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false Delay Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false Ping Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 34 0 Qt::LeftToRight Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 22 0 22 16777215 ms 34 0 Qt::LeftToRight Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 22 0 22 16777215 ms 0 0 14 14 14 14 0 0 14 14 14 14 Qt::Horizontal &Mute Myself &Settings &Chat 0 0 120 45 C&onnect false false Qt::Vertical MUTED (Other people won't hear you) Qt::AlignCenter 6 QLayout::SetMinimumSize 0 9 0 0 Set up your audio, connect to a server and start jamming! Qt::AlignCenter 0 0 Update check CMultiColorLED QWidget
multicolorled.h
CAudioMixerBoard QWidget
audiomixerboard.h
CLevelMeter QWidget
levelmeter.h
1
butConnect chbLocalMute chbSettings chbChat sldAudioReverb rbtReverbSelL rbtReverbSelR
jamulus-3.9.1+dfsg/src/sound/0000755000175000017500000000000014340334543015073 5ustar vimervimerjamulus-3.9.1+dfsg/src/sound/oboe/0000755000175000017500000000000014340334543016017 5ustar vimervimerjamulus-3.9.1+dfsg/src/sound/oboe/sound.cpp0000644000175000017500000003003614340334543017655 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Simon Tomlinson, Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include "sound.h" #include "../../android/androiddebug.cpp" /* Implementation *************************************************************/ const uint8_t CSound::RING_FACTOR = 20; CSound::CSound ( void ( *fpNewProcessCallback ) ( CVector& psData, void* arg ), void* arg, const QString& strMIDISetup, const bool, const QString& ) : CSoundBase ( "Oboe", fpNewProcessCallback, arg, strMIDISetup ) { #ifdef ANDROIDDEBUG qInstallMessageHandler ( myMessageHandler ); #endif } void CSound::setupCommonStreamParams ( oboe::AudioStreamBuilder* builder ) { // We request EXCLUSIVE mode since this will give us the lowest possible // latency. If EXCLUSIVE mode isn't available the builder will fall back to SHARED mode // Setting format to be PCM 16 bits (int16_t) builder->setFormat ( oboe::AudioFormat::I16 ) ->setSharingMode ( oboe::SharingMode::Exclusive ) ->setChannelCount ( oboe::ChannelCount::Stereo ) ->setSampleRate ( SYSTEM_SAMPLE_RATE_HZ ) ->setFramesPerCallback ( iOboeBufferSizeMono ) ->setSampleRateConversionQuality ( oboe::SampleRateConversionQuality::Medium ) ->setPerformanceMode ( oboe::PerformanceMode::LowLatency ); return; } void CSound::closeStream ( oboe::ManagedStream& stream ) { if ( stream ) { oboe::Result result; result = stream->requestStop(); if ( oboe::Result::OK != result ) { throw CGenErr ( tr ( "Error requesting stream stop: $s", oboe::convertToText ( result ) ) ); } result = stream->close(); if ( oboe::Result::OK != result ) { throw CGenErr ( tr ( "Error closing stream: $s", oboe::convertToText ( result ) ) ); } stream.reset(); } } void CSound::openStreams() { // Setup output stream oboe::AudioStreamBuilder inBuilder, outBuilder; outBuilder.setDirection ( oboe::Direction::Output ); outBuilder.setCallback ( this ); setupCommonStreamParams ( &outBuilder ); oboe::Result result = outBuilder.openManagedStream ( mPlayStream ); if ( result != oboe::Result::OK ) { return; } mPlayStream->setBufferSizeInFrames ( iOboeBufferSizeStereo ); warnIfNotLowLatency ( mPlayStream, "PlayStream" ); printStreamDetails ( mPlayStream ); // Setup input stream inBuilder.setDirection ( oboe::Direction::Input ); // Only set callback for the input direction // the output will be handled writing directly on the stream inBuilder.setCallback ( this ); setupCommonStreamParams ( &inBuilder ); result = inBuilder.openManagedStream ( mRecordingStream ); if ( result != oboe::Result::OK ) { closeStream ( mPlayStream ); return; } mRecordingStream->setBufferSizeInFrames ( iOboeBufferSizeStereo ); warnIfNotLowLatency ( mRecordingStream, "RecordStream" ); printStreamDetails ( mRecordingStream ); printStreamDetails ( mPlayStream ); } void CSound::printStreamDetails ( oboe::ManagedStream& stream ) { QString sDirection = ( stream->getDirection() == oboe::Direction::Input ? "Input" : "Output" ); QString sFramesPerBurst = QString::number ( stream->getFramesPerBurst() ); QString sBufferSizeInFrames = QString::number ( stream->getBufferSizeInFrames() ); QString sBytesPerFrame = QString::number ( stream->getBytesPerFrame() ); QString sBytesPerSample = QString::number ( stream->getBytesPerSample() ); QString sBufferCapacityInFrames = QString::number ( stream->getBufferCapacityInFrames() ); QString sPerformanceMode = ( stream->getPerformanceMode() == oboe::PerformanceMode::LowLatency ? "LowLatency" : "NotLowLatency" ); QString sSharingMode = ( stream->getSharingMode() == oboe::SharingMode::Exclusive ? "Exclusive" : "Shared" ); QString sDeviceID = QString::number ( stream->getDeviceId() ); QString sSampleRate = QString::number ( stream->getSampleRate() ); QString sAudioFormat = ( stream->getFormat() == oboe::AudioFormat::I16 ? "I16" : "Float" ); QString sFramesPerCallback = QString::number ( stream->getFramesPerCallback() ); qInfo() << "Stream details: [sDirection: " << sDirection << ", FramesPerBurst: " << sFramesPerBurst << ", BufferSizeInFrames: " << sBufferSizeInFrames << ", BytesPerFrame: " << sBytesPerFrame << ", BytesPerSample: " << sBytesPerSample << ", BufferCapacityInFrames: " << sBufferCapacityInFrames << ", PerformanceMode: " << sPerformanceMode << ", SharingMode: " << sSharingMode << ", DeviceID: " << sDeviceID << ", SampleRate: " << sSampleRate << ", AudioFormat: " << sAudioFormat << ", FramesPerCallback: " << sFramesPerCallback << "]"; } void CSound::warnIfNotLowLatency ( oboe::ManagedStream& stream, QString streamName ) { if ( stream->getPerformanceMode() != oboe::PerformanceMode::LowLatency ) { QString latencyMode = ( stream->getPerformanceMode() == oboe::PerformanceMode::None ? "None" : "Power Saving" ); } Q_UNUSED ( streamName ); } void CSound::closeStreams() { // clean up closeStream ( mRecordingStream ); closeStream ( mPlayStream ); } void CSound::Start() { openStreams(); // call base class CSoundBase::Start(); // finally start the streams so the callback begins, start with inputstream first. mRecordingStream->requestStart(); mPlayStream->requestStart(); } void CSound::Stop() { closeStreams(); // call base class CSoundBase::Stop(); } int CSound::Init ( const int iNewPrefMonoBufferSize ) { // store buffer size iOboeBufferSizeMono = iNewPrefMonoBufferSize; // 512 // init base class CSoundBase::Init ( iOboeBufferSizeMono ); // set internal buffer size value and calculate stereo buffer size iOboeBufferSizeStereo = 2 * iOboeBufferSizeMono; // create memory for intermediate audio buffer vecsTmpInputAudioSndCrdStereo.Init ( iOboeBufferSizeStereo ); mOutBuffer.Init ( iOboeBufferSizeStereo * RING_FACTOR ); return iOboeBufferSizeMono; } // This is the main callback method for when an audio stream is ready to publish data to an output stream // or has received data on an input stream. As per manual much be very careful not to do anything in this back that // can cause delays such as sleeping, file processing, allocate memory, etc. oboe::DataCallbackResult CSound::onAudioReady ( oboe::AudioStream* oboeStream, void* audioData, int32_t numFrames ) { // only process if we are running if ( !bRun ) { return oboe::DataCallbackResult::Continue; } if ( mStats.in_callback_calls % 1000 == 0 ) { mStats.log(); } if ( oboeStream == mRecordingStream.get() && audioData ) { return onAudioInput ( oboeStream, audioData, numFrames ); } if ( oboeStream == mPlayStream.get() && audioData ) { return onAudioOutput ( oboeStream, audioData, numFrames ); } return oboe::DataCallbackResult::Continue; } oboe::DataCallbackResult CSound::onAudioInput ( oboe::AudioStream* oboeStream, void* audioData, int32_t numFrames ) { mStats.in_callback_calls++; // First things first, we need to discard the input queue a little for 500ms or so if ( mCountCallbacksToDrain > 0 ) { // discard the input buffer const int32_t numBytes = numFrames * oboeStream->getBytesPerFrame(); memset ( audioData, 0 /* value */, numBytes ); mCountCallbacksToDrain--; } // We're good to start recording now // Take the data from the recording device output buffer and move // it to the vector ready to send up to the server // // According to the format that we've set on initialization, audioData // is an array of int16_t // int16_t* intData = static_cast ( audioData ); // Copy recording data to internal vector memcpy ( vecsTmpInputAudioSndCrdStereo.data(), intData, sizeof ( int16_t ) * numFrames * oboeStream->getChannelCount() ); if ( numFrames != iOboeBufferSizeMono ) { qDebug() << "Received " << numFrames << " expecting " << iOboeBufferSizeMono; } mStats.frames_in += numFrames; // Tell parent class that we've put some data ready to send to the server ProcessCallback ( vecsTmpInputAudioSndCrdStereo ); // The callback has placed in the vector the samples to play addOutputData ( oboeStream->getChannelCount() ); return oboe::DataCallbackResult::Continue; } void CSound::addOutputData ( int channel_count ) { QMutexLocker locker ( &MutexAudioProcessCallback ); const std::size_t bufsize = (std::size_t) iOboeBufferSizeMono * channel_count; // Only copy data if we have data to copy, otherwise fill with silence if ( vecsTmpInputAudioSndCrdStereo.empty() ) { // prime output stream buffer with silence vecsTmpInputAudioSndCrdStereo.resize ( bufsize, 0 ); } mOutBuffer.Put ( vecsTmpInputAudioSndCrdStereo, bufsize ); if ( mOutBuffer.isFull() ) { mStats.ring_overrun++; } } oboe::DataCallbackResult CSound::onAudioOutput ( oboe::AudioStream* oboeStream, void* audioData, int32_t numFrames ) { mStats.frames_out += numFrames; mStats.out_callback_calls++; QMutexLocker locker ( &MutexAudioProcessCallback ); const int32_t to_write = numFrames * oboeStream->getChannelCount(); const int32_t count = std::min ( mOutBuffer.GetAvailData(), to_write ); CVector outBuffer ( count ); mOutBuffer.Get ( outBuffer, count ); // // According to the format that we've set on initialization, audioData // is an array of int16_t // int16_t* intData = static_cast ( audioData ); memcpy ( intData, outBuffer.data(), sizeof ( int16_t ) * count ); if ( to_write > count ) { mStats.frames_filled_out += ( to_write - count ); memset ( intData + count, 0, sizeof ( int16_t ) * ( to_write - count ) ); } return oboe::DataCallbackResult::Continue; } // TODO better handling of stream closing errors void CSound::onErrorAfterClose ( oboe::AudioStream* oboeStream, oboe::Result result ) { qDebug() << "CSound::onErrorAfterClose"; Q_UNUSED ( oboeStream ); Q_UNUSED ( result ); } // TODO better handling of stream closing errors void CSound::onErrorBeforeClose ( oboe::AudioStream* oboeStream, oboe::Result result ) { qDebug() << "CSound::onErrorBeforeClose"; Q_UNUSED ( oboeStream ); Q_UNUSED ( result ); } void CSound::Stats::reset() { frames_in = 0; frames_out = 0; frames_filled_out = 0; in_callback_calls = 0; out_callback_calls = 0; ring_overrun = 0; } void CSound::Stats::log() const { qDebug() << "Stats: " << "frames_in: " << frames_in << ",frames_out: " << frames_out << ",frames_filled_out: " << frames_filled_out << ",in_callback_calls: " << in_callback_calls << ",out_callback_calls: " << out_callback_calls << ",ring_overrun: " << ring_overrun; } jamulus-3.9.1+dfsg/src/sound/oboe/sound.h0000644000175000017500000000710414340334543017322 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Simon Tomlinson, Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #include #include "../soundbase.h" #include "../../global.h" #include #include #include "buffer.h" #include /* Classes ********************************************************************/ class CSound : public CSoundBase, public oboe::AudioStreamCallback { Q_OBJECT public: static const uint8_t RING_FACTOR; CSound ( void ( *fpNewProcessCallback ) ( CVector& psData, void* arg ), void* arg, const QString& strMIDISetup, const bool, const QString& ); virtual ~CSound() {} virtual int Init ( const int iNewPrefMonoBufferSize ); virtual void Start(); virtual void Stop(); // Call backs for Oboe virtual oboe::DataCallbackResult onAudioReady ( oboe::AudioStream* oboeStream, void* audioData, int32_t numFrames ); virtual void onErrorAfterClose ( oboe::AudioStream* oboeStream, oboe::Result result ); virtual void onErrorBeforeClose ( oboe::AudioStream* oboeStream, oboe::Result result ); struct Stats { Stats() { reset(); } void reset(); void log() const; std::size_t frames_in; std::size_t frames_out; std::size_t frames_filled_out; std::size_t in_callback_calls; std::size_t out_callback_calls; std::size_t ring_overrun; }; protected: CVector vecsTmpInputAudioSndCrdStereo; CBuffer mOutBuffer; int iOboeBufferSizeMono; int iOboeBufferSizeStereo; private: void setupCommonStreamParams ( oboe::AudioStreamBuilder* builder ); void printStreamDetails ( oboe::ManagedStream& stream ); void openStreams(); void closeStreams(); void warnIfNotLowLatency ( oboe::ManagedStream& stream, QString streamName ); void closeStream ( oboe::ManagedStream& stream ); oboe::DataCallbackResult onAudioInput ( oboe::AudioStream* oboeStream, void* audioData, int32_t numFrames ); oboe::DataCallbackResult onAudioOutput ( oboe::AudioStream* oboeStream, void* audioData, int32_t numFrames ); void addOutputData ( int channel_count ); oboe::ManagedStream mRecordingStream; oboe::ManagedStream mPlayStream; // used to reach a state where the input buffer is // empty and the garbage in the first 500ms or so is discarded static constexpr int32_t kNumCallbacksToDrain = 10; int32_t mCountCallbacksToDrain = kNumCallbacksToDrain; Stats mStats; }; jamulus-3.9.1+dfsg/src/sound/jack/0000755000175000017500000000000014340334543016003 5ustar vimervimerjamulus-3.9.1+dfsg/src/sound/jack/sound.cpp0000644000175000017500000003147414340334543017650 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * * This code is based on the simple_client example of the Jack audio interface. * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include "sound.h" #ifdef WITH_JACK void CSound::OpenJack ( const bool bNoAutoJackConnect, const char* jackClientName ) { jack_status_t JackStatus; const char* serverName; if ( ( serverName = getenv ( "JACK_DEFAULT_SERVER" ) ) == NULL ) { serverName = "default"; } qInfo() << qUtf8Printable ( QString ( "Connecting to JACK \"%1\" instance (use the JACK_DEFAULT_SERVER environment variable to change this)." ).arg ( serverName ) ); // try to become a client of the JACK server pJackClient = jack_client_open ( jackClientName, JackNullOption, &JackStatus ); if ( pJackClient == nullptr ) { throw CGenErr ( tr ( "JACK couldn't be started automatically. " "Please start JACK manually and check for error messages." ) ); } // tell the JACK server to call "process()" whenever // there is work to be done jack_set_process_callback ( pJackClient, process, this ); // register a "buffer size changed" callback function jack_set_buffer_size_callback ( pJackClient, bufferSizeCallback, this ); // register shutdown callback function jack_on_shutdown ( pJackClient, shutdownCallback, this ); // check sample rate, if not correct, just fire error if ( jack_get_sample_rate ( pJackClient ) != SYSTEM_SAMPLE_RATE_HZ ) { throw CGenErr ( QString ( tr ( "JACK isn't running at a sample rate of %1 Hz. Please use " "a tool like QjackCtl to set the " "the JACK sample rate to %1 Hz." ) ) .arg ( SYSTEM_SAMPLE_RATE_HZ ) ); } // create four ports (two for input, two for output -> stereo) input_port_left = jack_port_register ( pJackClient, "input left", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0 ); input_port_right = jack_port_register ( pJackClient, "input right", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0 ); output_port_left = jack_port_register ( pJackClient, "output left", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 ); output_port_right = jack_port_register ( pJackClient, "output right", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 ); if ( ( input_port_left == nullptr ) || ( input_port_right == nullptr ) || ( output_port_left == nullptr ) || ( output_port_right == nullptr ) ) { throw CGenErr ( QString ( tr ( "The JACK port registration failed. This is probably an error with JACK. Please stop %1 and JACK. " "Afterwards check if another program at a sample rate of %2 Hz can connect to JACK." ) ) .arg ( APP_NAME ) .arg ( SYSTEM_SAMPLE_RATE_HZ ) ); } // optional MIDI initialization if ( iCtrlMIDIChannel != INVALID_MIDI_CH ) { input_port_midi = jack_port_register ( pJackClient, "input midi", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0 ); if ( input_port_midi == nullptr ) { throw CGenErr ( QString ( tr ( "The JACK port registration failed. This is probably an error with JACK. Please stop %1 and JACK. " "Afterwards, check if another MIDI program can connect to JACK." ) ) .arg ( APP_NAME ) ); } } else { input_port_midi = nullptr; } // tell the JACK server that we are ready to roll if ( jack_activate ( pJackClient ) ) { throw CGenErr ( QString ( tr ( "Can't activate the JACK client. This is probably an error with JACK. Please check the JACK output." ) ) .arg ( APP_NAME ) ); } if ( !bNoAutoJackConnect ) { // connect the ports, note: you cannot do this before // the client is activated, because we cannot allow // connections to be made to clients that are not // running const char** ports; // try to connect physical input ports if ( ( ports = jack_get_ports ( pJackClient, nullptr, nullptr, JackPortIsPhysical | JackPortIsOutput ) ) != nullptr ) { jack_connect ( pJackClient, ports[0], jack_port_name ( input_port_left ) ); // before connecting the second stereo channel, check if the input is not mono if ( ports[1] ) { jack_connect ( pJackClient, ports[1], jack_port_name ( input_port_right ) ); } jack_free ( ports ); } // try to connect physical output ports if ( ( ports = jack_get_ports ( pJackClient, nullptr, nullptr, JackPortIsPhysical | JackPortIsInput ) ) != nullptr ) { jack_connect ( pJackClient, jack_port_name ( output_port_left ), ports[0] ); // before connecting the second stereo channel, check if the output is not mono if ( ports[1] ) { jack_connect ( pJackClient, jack_port_name ( output_port_right ), ports[1] ); } jack_free ( ports ); } // input latency jack_latency_range_t latrange; latrange.min = 0; latrange.max = 0; jack_port_get_latency_range ( input_port_left, JackCaptureLatency, &latrange ); int inLatency = latrange.min; // be optimistic // output latency latrange.min = 0; latrange.max = 0; jack_port_get_latency_range ( output_port_left, JackPlaybackLatency, &latrange ); int outLatency = latrange.min; // be optimistic // compute latency by using the first input and first output // ports and using the most optimistic values fInOutLatencyMs = static_cast ( inLatency + outLatency ) * 1000 / SYSTEM_SAMPLE_RATE_HZ; } } void CSound::CloseJack() { // deactivate client jack_deactivate ( pJackClient ); // unregister ports jack_port_unregister ( pJackClient, input_port_left ); jack_port_unregister ( pJackClient, input_port_right ); jack_port_unregister ( pJackClient, output_port_left ); jack_port_unregister ( pJackClient, output_port_right ); // close client connection to jack server jack_client_close ( pJackClient ); } void CSound::Start() { // call base class CSoundBase::Start(); } void CSound::Stop() { // call base class CSoundBase::Stop(); } int CSound::Init ( const int /* iNewPrefMonoBufferSize */ ) { //### TODO: BEGIN ###// // try setting buffer size seems not to work! -> no audio after this operation! // Doesn't this give an infinite loop? The set buffer size function will call our // registered callback which calls "EmitReinitRequestSignal()". In that function // this CSound::Init() function is called... // jack_set_buffer_size ( pJackClient, iNewPrefMonoBufferSize ); //### TODO: END ###// // without a Jack server, Jamulus makes no sense to run, throw an error message if ( bJackWasShutDown ) { throw CGenErr ( QString ( tr ( "JACK was shut down. %1 " "requires JACK to run. Please restart %1 to " "start JACK again. " ) ) .arg ( APP_NAME ) ); } // get actual buffer size iJACKBufferSizeMono = jack_get_buffer_size ( pJackClient ); // init base class CSoundBase::Init ( iJACKBufferSizeMono ); // set internal buffer size value and calculate stereo buffer size iJACKBufferSizeStero = 2 * iJACKBufferSizeMono; // create memory for intermediate audio buffer vecsTmpAudioSndCrdStereo.Init ( iJACKBufferSizeStero ); return iJACKBufferSizeMono; } // JACK callbacks -------------------------------------------------------------- int CSound::process ( jack_nframes_t nframes, void* arg ) { CSound* pSound = static_cast ( arg ); int i; // make sure we are locked during execution QMutexLocker locker ( &pSound->MutexAudioProcessCallback ); if ( pSound->IsRunning() && ( nframes == static_cast ( pSound->iJACKBufferSizeMono ) ) ) { // get input data pointer jack_default_audio_sample_t* in_left = (jack_default_audio_sample_t*) jack_port_get_buffer ( pSound->input_port_left, nframes ); jack_default_audio_sample_t* in_right = (jack_default_audio_sample_t*) jack_port_get_buffer ( pSound->input_port_right, nframes ); // copy input audio data if ( ( in_left != nullptr ) && ( in_right != nullptr ) ) { for ( i = 0; i < pSound->iJACKBufferSizeMono; i++ ) { pSound->vecsTmpAudioSndCrdStereo[2 * i] = Float2Short ( in_left[i] * _MAXSHORT ); pSound->vecsTmpAudioSndCrdStereo[2 * i + 1] = Float2Short ( in_right[i] * _MAXSHORT ); } } // call processing callback function pSound->ProcessCallback ( pSound->vecsTmpAudioSndCrdStereo ); // get output data pointer jack_default_audio_sample_t* out_left = (jack_default_audio_sample_t*) jack_port_get_buffer ( pSound->output_port_left, nframes ); jack_default_audio_sample_t* out_right = (jack_default_audio_sample_t*) jack_port_get_buffer ( pSound->output_port_right, nframes ); // copy output data if ( ( out_left != nullptr ) && ( out_right != nullptr ) ) { for ( i = 0; i < pSound->iJACKBufferSizeMono; i++ ) { out_left[i] = (jack_default_audio_sample_t) pSound->vecsTmpAudioSndCrdStereo[2 * i] / _MAXSHORT; out_right[i] = (jack_default_audio_sample_t) pSound->vecsTmpAudioSndCrdStereo[2 * i + 1] / _MAXSHORT; } } } else { // get output data pointer jack_default_audio_sample_t* out_left = (jack_default_audio_sample_t*) jack_port_get_buffer ( pSound->output_port_left, nframes ); jack_default_audio_sample_t* out_right = (jack_default_audio_sample_t*) jack_port_get_buffer ( pSound->output_port_right, nframes ); // clear output data if ( ( out_left != nullptr ) && ( out_right != nullptr ) ) { memset ( out_left, 0, sizeof ( jack_default_audio_sample_t ) * nframes ); memset ( out_right, 0, sizeof ( jack_default_audio_sample_t ) * nframes ); } } // akt on MIDI data if MIDI is enabled if ( pSound->input_port_midi != nullptr ) { void* in_midi = jack_port_get_buffer ( pSound->input_port_midi, nframes ); if ( in_midi != 0 ) { jack_nframes_t event_count = jack_midi_get_event_count ( in_midi ); for ( jack_nframes_t j = 0; j < event_count; j++ ) { jack_midi_event_t in_event; jack_midi_event_get ( &in_event, in_midi, j ); // copy packet and send it to the MIDI parser //### TODO: BEGIN ###// // do not call malloc in real-time callback CVector vMIDIPaketBytes ( in_event.size ); //### TODO: END ###// for ( i = 0; i < static_cast ( in_event.size ); i++ ) { vMIDIPaketBytes[i] = static_cast ( in_event.buffer[i] ); } pSound->ParseMIDIMessage ( vMIDIPaketBytes ); } } } return 0; // zero on success, non-zero on error } int CSound::bufferSizeCallback ( jack_nframes_t, void* arg ) { CSound* pSound = static_cast ( arg ); pSound->EmitReinitRequestSignal ( RS_ONLY_RESTART_AND_INIT ); return 0; // zero on success, non-zero on error } void CSound::shutdownCallback ( void* arg ) { CSound* pSound = static_cast ( arg ); pSound->bJackWasShutDown = true; pSound->EmitReinitRequestSignal ( RS_ONLY_RESTART_AND_INIT ); } #endif // WITH_JACK jamulus-3.9.1+dfsg/src/sound/jack/sound.h0000644000175000017500000001120614340334543017304 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #ifndef JACK_ON_WINDOWS // these headers are not available in Windows OS # include # include #endif #include #include #include #include #include #include #include "../../util.h" #include "../soundbase.h" #include "../../global.h" #if WITH_JACK # include # include #endif /* Definitions ****************************************************************/ #define NUM_IN_OUT_CHANNELS 2 // always stereo // the number of periods is critical for latency #define NUM_PERIOD_BLOCKS_IN 2 #define NUM_PERIOD_BLOCKS_OUT 1 #define MAX_SND_BUF_IN 200 #define MAX_SND_BUF_OUT 200 /* Classes ********************************************************************/ #if WITH_JACK class CSound : public CSoundBase { Q_OBJECT public: CSound ( void ( *fpNewProcessCallback ) ( CVector& psData, void* arg ), void* arg, const QString& strMIDISetup, const bool bNoAutoJackConnect, const QString& strJackClientName ) : CSoundBase ( "Jack", fpNewProcessCallback, arg, strMIDISetup ), iJACKBufferSizeMono ( 0 ), bJackWasShutDown ( false ), fInOutLatencyMs ( 0.0f ) { QString strJackName = QString ( APP_NAME ); if ( !strJackClientName.isEmpty() ) { strJackName += " " + strJackClientName; } OpenJack ( bNoAutoJackConnect, strJackName.toLocal8Bit().data() ); } virtual ~CSound() { CloseJack(); } virtual int Init ( const int iNewPrefMonoBufferSize ); virtual void Start(); virtual void Stop(); virtual float GetInOutLatencyMs() { return fInOutLatencyMs; } // these variables should be protected but cannot since we want // to access them from the callback function CVector vecsTmpAudioSndCrdStereo; int iJACKBufferSizeMono; int iJACKBufferSizeStero; bool bJackWasShutDown; jack_port_t* input_port_left; jack_port_t* input_port_right; jack_port_t* output_port_left; jack_port_t* output_port_right; jack_port_t* input_port_midi; protected: void OpenJack ( const bool bNoAutoJackConnect, const char* jackClientName ); void CloseJack(); // callbacks static int process ( jack_nframes_t nframes, void* arg ); static int bufferSizeCallback ( jack_nframes_t, void* arg ); static void shutdownCallback ( void* ); jack_client_t* pJackClient; float fInOutLatencyMs; }; #else // no sound -> dummy class definition class CSound : public CSoundBase { Q_OBJECT public: CSound ( void ( *fpNewProcessCallback ) ( CVector& psData, void* pParg ), void* pParg, const QString& strMIDISetup, const bool, const QString& ) : CSoundBase ( "nosound", fpNewProcessCallback, pParg, strMIDISetup ), HighPrecisionTimer ( true ) { HighPrecisionTimer.Start(); QObject::connect ( &HighPrecisionTimer, &CHighPrecisionTimer::timeout, this, &CSound::OnTimer ); } virtual ~CSound() {} virtual int Init ( const int iNewPrefMonoBufferSize ) { CSoundBase::Init ( iNewPrefMonoBufferSize ); vecsTemp.Init ( 2 * iNewPrefMonoBufferSize ); return iNewPrefMonoBufferSize; } CHighPrecisionTimer HighPrecisionTimer; CVector vecsTemp; public slots: void OnTimer() { vecsTemp.Reset ( 0 ); if ( IsRunning() ) { ProcessCallback ( vecsTemp ); } } }; #endif // WITH_JACK jamulus-3.9.1+dfsg/src/sound/soundbase.cpp0000644000175000017500000003721714340334543017574 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include "soundbase.h" // This is used as a lookup table for parsing option letters, mapping // a single character to an EMidiCtlType char const sMidiCtlChar[] = { // Has to follow order of EMidiCtlType /* [EMidiCtlType::Fader] = */ 'f', /* [EMidiCtlType::Pan] = */ 'p', /* [EMidiCtlType::Solo] = */ 's', /* [EMidiCtlType::Mute] = */ 'm', /* [EMidiCtlType::MuteMyself] = */ 'o', /* [EMidiCtlType::None] = */ '\0' }; /* Implementation *************************************************************/ CSoundBase::CSoundBase ( const QString& strNewSystemDriverTechniqueName, void ( *fpNewProcessCallback ) ( CVector& psData, void* pParg ), void* pParg, const QString& strMIDISetup ) : fpProcessCallback ( fpNewProcessCallback ), pProcessCallbackArg ( pParg ), bRun ( false ), bCallbackEntered ( false ), strSystemDriverTechniqueName ( strNewSystemDriverTechniqueName ), iCtrlMIDIChannel ( INVALID_MIDI_CH ), aMidiCtls ( 128 ) { // parse the MIDI setup command line argument string ParseCommandLineArgument ( strMIDISetup ); // initializations for the sound card names (default) lNumDevs = 1; strDriverNames[0] = strSystemDriverTechniqueName; // set current device strCurDevName = ""; // default device } void CSoundBase::Stop() { // set flag so that thread can leave the main loop bRun = false; // wait for draining the audio process callback QMutexLocker locker ( &MutexAudioProcessCallback ); } /******************************************************************************\ * Device handling * \******************************************************************************/ QStringList CSoundBase::GetDevNames() { QMutexLocker locker ( &MutexDevProperties ); QStringList slDevNames; // put all device names in the string list for ( int iDev = 0; iDev < lNumDevs; iDev++ ) { slDevNames << strDriverNames[iDev]; } return slDevNames; } QString CSoundBase::SetDev ( const QString strDevName ) { QMutexLocker locker ( &MutexDevProperties ); // init return parameter with "no error" QString strReturn = ""; // init flag for "load any driver" bool bTryLoadAnyDriver = false; // check if an ASIO driver was already initialized if ( !strCurDevName.isEmpty() ) { // a device was already been initialized and is used, first clean up // driver UnloadCurrentDriver(); const QString strErrorMessage = LoadAndInitializeDriver ( strDevName, false ); if ( !strErrorMessage.isEmpty() ) { if ( strDevName != strCurDevName ) { // loading and initializing the new driver failed, go back to // original driver and create error message LoadAndInitializeDriver ( strCurDevName, false ); // store error return message strReturn = QString ( tr ( "Can't use the selected audio device " "because of the following error: %1 " "The previous driver will be selected." ) .arg ( strErrorMessage ) ); } else { // loading and initializing the current driver failed, try to find // at least one usable driver bTryLoadAnyDriver = true; } } } else { if ( !strDevName.isEmpty() ) { // This is the first time a driver is to be initialized, we first // try to load the selected driver, if this fails, we try to load // the first available driver in the system. If this fails, too, we // throw an error that no driver is available -> it does not make // sense to start the software if no audio hardware is available. if ( !LoadAndInitializeDriver ( strDevName, false ).isEmpty() ) { // loading and initializing the new driver failed, try to find // at least one usable driver bTryLoadAnyDriver = true; } } else { // try to find one usable driver (select the first valid driver) bTryLoadAnyDriver = true; } } if ( bTryLoadAnyDriver ) { // if a driver was previously selected, show a warning message if ( !strDevName.isEmpty() ) { strReturn = tr ( "The previously selected audio device " "is no longer available or the driver has changed to an incompatible state. " "We'll attempt to find a valid audio device, but this new audio device may cause feedback. " "Before connecting to a server, please check your audio device settings." ); } // try to load and initialize any valid driver QVector vsErrorList = LoadAndInitializeFirstValidDriver(); if ( !vsErrorList.isEmpty() ) { // create error message with all details QString sErrorMessage = tr ( "%1 couldn't find a usable %2 audio device.

" ).arg ( APP_NAME ).arg ( strSystemDriverTechniqueName ); for ( int i = 0; i < lNumDevs; i++ ) { sErrorMessage += "" + GetDeviceName ( i ) + ": " + vsErrorList[i] + "

"; } #if defined( _WIN32 ) && !defined( WITH_JACK ) // to be able to access the ASIO driver setup for changing, e.g., the sample rate, we // offer the user under Windows that we open the driver setups of all registered // ASIO drivers sErrorMessage += "
" + tr ( "You may be able to fix errors in the driver settings. Do you want to open these settings now?" ); if ( QMessageBox::Yes == QMessageBox::information ( nullptr, APP_NAME, sErrorMessage, QMessageBox::Yes | QMessageBox::No ) ) { LoadAndInitializeFirstValidDriver ( true ); } sErrorMessage = QString ( tr ( "Can't start %1. Please restart %1 and check/reconfigure your audio settings." ) ).arg ( APP_NAME ); #endif throw CGenErr ( sErrorMessage ); } } return strReturn; } QVector CSoundBase::LoadAndInitializeFirstValidDriver ( const bool bOpenDriverSetup ) { QVector vsErrorList; // load and initialize first valid ASIO driver bool bValidDriverDetected = false; int iDriverCnt = 0; // try all available drivers in the system ("lNumDevs" devices) while ( !bValidDriverDetected && ( iDriverCnt < lNumDevs ) ) { // try to load and initialize current driver, store error message const QString strCurError = LoadAndInitializeDriver ( GetDeviceName ( iDriverCnt ), bOpenDriverSetup ); vsErrorList.append ( strCurError ); if ( strCurError.isEmpty() ) { // initialization was successful bValidDriverDetected = true; // store ID of selected driver strCurDevName = GetDeviceName ( iDriverCnt ); // empty error list shows that init was successful vsErrorList.clear(); } // try next driver iDriverCnt++; } return vsErrorList; } /******************************************************************************\ * MIDI handling * \******************************************************************************/ void CSoundBase::ParseCommandLineArgument ( const QString& strMIDISetup ) { int iMIDIOffsetFader = 70; // Behringer X-TOUCH: offset of 0x46 // parse the server info string according to definition: there is // the legacy definition with just one or two numbers that only // provides a definition for the controller offset of the level // controllers (default 70 for the sake of Behringer X-Touch) // [MIDI channel];[offset for level] // // The more verbose new form is a sequence of offsets for various // controllers: at the current point, 'f', 'p', 's', and 'm' are // parsed for fader, pan, solo, mute controllers respectively. // However, at the current point of time only 'f' and 'p' // controllers are actually implemented. The syntax for a Korg // nanoKONTROL2 with 8 fader controllers starting at offset 0 and // 8 pan controllers starting at offset 16 would be // // [MIDI channel];f0*8;p16*8 // // Namely a sequence of letters indicating the kind of controller, // followed by the offset of the first such controller, followed // by * and a count for number of controllers (if more than 1) if ( !strMIDISetup.isEmpty() ) { // split the different parameter strings const QStringList slMIDIParams = strMIDISetup.split ( ";" ); // [MIDI channel] if ( slMIDIParams.count() >= 1 ) { iCtrlMIDIChannel = slMIDIParams[0].toUInt(); } bool bSimple = true; // Indicates the legacy kind of specifying // the fader controller offset without an // indication of the count of controllers // [offset for level] if ( slMIDIParams.count() >= 2 ) { int i = slMIDIParams[1].toUInt ( &bSimple ); // if the second parameter can be parsed as a number, we // have the legacy specification of controllers. if ( bSimple ) iMIDIOffsetFader = i; } if ( bSimple ) { // For the legacy specification, we consider every controller // up to the maximum number of channels (or the maximum // controller number) a fader. for ( int i = 0; i < MAX_NUM_CHANNELS; i++ ) { if ( i + iMIDIOffsetFader > 127 ) break; aMidiCtls[i + iMIDIOffsetFader] = { EMidiCtlType::Fader, i }; } return; } // We have named controllers for ( int i = 1; i < slMIDIParams.count(); i++ ) { QString sParm = slMIDIParams[i].trimmed(); if ( sParm.isEmpty() ) continue; int iCtrl = QString ( sMidiCtlChar ).indexOf ( sParm[0] ); if ( iCtrl < 0 ) continue; EMidiCtlType eTyp = static_cast ( iCtrl ); const QStringList slP = sParm.mid ( 1 ).split ( '*' ); int iFirst = slP[0].toUInt(); int iNum = ( slP.count() > 1 ) ? slP[1].toUInt() : 1; for ( int iOff = 0; iOff < iNum; iOff++ ) { if ( iOff >= MAX_NUM_CHANNELS ) break; if ( iFirst + iOff >= 128 ) break; aMidiCtls[iFirst + iOff] = { eTyp, iOff }; } } } } void CSoundBase::ParseMIDIMessage ( const CVector& vMIDIPaketBytes ) { if ( vMIDIPaketBytes.Size() > 0 ) { const uint8_t iStatusByte = vMIDIPaketBytes[0]; // check if status byte is correct if ( ( iStatusByte >= 0x80 ) && ( iStatusByte < 0xF0 ) ) { // zero-based MIDI channel number (i.e. range 0-15) const int iMIDIChannelZB = iStatusByte & 0x0F; /* // debugging printf ( "%02X: ", iMIDIChannelZB ); for ( int i = 0; i < vMIDIPaketBytes.Size(); i++ ) { printf ( "%02X ", vMIDIPaketBytes[i] ); } printf ( "\n" ); */ // per definition if MIDI channel is 0, we listen to all channels // note that iCtrlMIDIChannel is one-based channel number if ( ( iCtrlMIDIChannel == 0 ) || ( iCtrlMIDIChannel - 1 == iMIDIChannelZB ) ) { // we only want to parse controller messages if ( ( iStatusByte >= 0xB0 ) && ( iStatusByte < 0xC0 ) ) { // make sure packet is long enough if ( vMIDIPaketBytes.Size() > 2 && vMIDIPaketBytes[1] <= uint8_t ( 127 ) && vMIDIPaketBytes[2] <= uint8_t ( 127 ) ) { const CMidiCtlEntry& cCtrl = aMidiCtls[vMIDIPaketBytes[1]]; const int iValue = vMIDIPaketBytes[2]; ; switch ( cCtrl.eType ) { case Fader: { // we are assuming that the controller number is the same // as the audio fader index and the range is 0-127 const int iFaderLevel = static_cast ( static_cast ( iValue ) / 127 * AUD_MIX_FADER_MAX ); // consider offset for the faders emit ControllerInFaderLevel ( cCtrl.iChannel, iFaderLevel ); } break; case Pan: { // Pan levels need to be symmetric between 1 and 127 const int iPanValue = static_cast ( static_cast ( qMax ( iValue, 1 ) - 1 ) / 126 * AUD_MIX_PAN_MAX ); emit ControllerInPanValue ( cCtrl.iChannel, iPanValue ); } break; case Solo: { // We depend on toggles reflecting the desired state emit ControllerInFaderIsSolo ( cCtrl.iChannel, iValue >= 0x40 ); } break; case Mute: { // We depend on toggles reflecting the desired state emit ControllerInFaderIsMute ( cCtrl.iChannel, iValue >= 0x40 ); } break; case MuteMyself: { // We depend on toggles reflecting the desired state to Mute Myself emit ControllerInMuteMyself ( iValue >= 0x40 ); } break; default: break; } } } } } } } jamulus-3.9.1+dfsg/src/sound/coreaudio-mac/0000755000175000017500000000000014340334543017603 5ustar vimervimerjamulus-3.9.1+dfsg/src/sound/coreaudio-mac/sound.cpp0000644000175000017500000012104114340334543021436 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include "sound.h" /* Implementation *************************************************************/ CSound::CSound ( void ( *fpNewProcessCallback ) ( CVector& psData, void* arg ), void* arg, const QString& strMIDISetup, const bool, const QString& ) : CSoundBase ( "CoreAudio", fpNewProcessCallback, arg, strMIDISetup ), midiInPortRef ( static_cast ( NULL ) ) { // Apple Mailing Lists: Subject: GUI Apps should set kAudioHardwarePropertyRunLoop // in the HAL, From: Jeff Moore, Date: Fri, 6 Dec 2002 // Most GUI applciations have several threads on which they receive // notifications already, so the having the HAL's thread around is wasteful. // Here is what you should do: On the thread you want the HAL to use for // notifications (for most apps, this will be the main thread), add the // following lines of code: // tell the HAL to use the current thread as it's run loop CFRunLoopRef theRunLoop = CFRunLoopGetCurrent(); AudioObjectPropertyAddress property = { kAudioHardwarePropertyRunLoop, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; AudioObjectSetPropertyData ( kAudioObjectSystemObject, &property, 0, NULL, sizeof ( CFRunLoopRef ), &theRunLoop ); // initial query for available input/output sound devices in the system GetAvailableInOutDevices(); // init device index as not initialized (invalid) lCurDev = INVALID_INDEX; CurrentAudioInputDeviceID = 0; CurrentAudioOutputDeviceID = 0; iNumInChan = 0; iNumInChanPlusAddChan = 0; iNumOutChan = 0; iSelInputLeftChannel = 0; iSelInputRightChannel = 0; iSelOutputLeftChannel = 0; iSelOutputRightChannel = 0; // Optional MIDI initialization -------------------------------------------- if ( iCtrlMIDIChannel != INVALID_MIDI_CH ) { // create client and ports MIDIClientRef midiClient = static_cast ( NULL ); MIDIClientCreate ( CFSTR ( APP_NAME ), NULL, NULL, &midiClient ); MIDIInputPortCreate ( midiClient, CFSTR ( "Input port" ), callbackMIDI, this, &midiInPortRef ); // open connections from all sources const int iNMIDISources = MIDIGetNumberOfSources(); for ( int i = 0; i < iNMIDISources; i++ ) { MIDIEndpointRef src = MIDIGetSource ( i ); MIDIPortConnectSource ( midiInPortRef, src, NULL ); } } } void CSound::GetAvailableInOutDevices() { UInt32 iPropertySize = 0; AudioObjectPropertyAddress stPropertyAddress; stPropertyAddress.mScope = kAudioObjectPropertyScopeGlobal; stPropertyAddress.mElement = kAudioObjectPropertyElementMaster; // first get property size of devices array and allocate memory stPropertyAddress.mSelector = kAudioHardwarePropertyDevices; AudioObjectGetPropertyDataSize ( kAudioObjectSystemObject, &stPropertyAddress, 0, NULL, &iPropertySize ); CVector vAudioDevices ( iPropertySize ); // now actually query all devices present in the system AudioObjectGetPropertyData ( kAudioObjectSystemObject, &stPropertyAddress, 0, NULL, &iPropertySize, &vAudioDevices[0] ); // calculate device count based on size of returned data array const UInt32 iDeviceCount = iPropertySize / sizeof ( AudioDeviceID ); // always add system default devices for input and output as first entry lNumDevs = 0; strDriverNames[lNumDevs] = "System Default In/Out Devices"; iPropertySize = sizeof ( AudioDeviceID ); stPropertyAddress.mSelector = kAudioHardwarePropertyDefaultInputDevice; if ( AudioObjectGetPropertyData ( kAudioObjectSystemObject, &stPropertyAddress, 0, NULL, &iPropertySize, &audioInputDevice[lNumDevs] ) ) { throw CGenErr ( tr ( "No sound card is available in your system. " "CoreAudio input AudioHardwareGetProperty call failed." ) ); } iPropertySize = sizeof ( AudioDeviceID ); stPropertyAddress.mSelector = kAudioHardwarePropertyDefaultOutputDevice; if ( AudioObjectGetPropertyData ( kAudioObjectSystemObject, &stPropertyAddress, 0, NULL, &iPropertySize, &audioOutputDevice[lNumDevs] ) ) { throw CGenErr ( tr ( "No sound card is available in the system. " "CoreAudio output AudioHardwareGetProperty call failed." ) ); } lNumDevs++; // next device // add detected devices // // we add combined entries for input and output for each device so that we // do not need two combo boxes in the GUI for input and output (therefore // all possible combinations are required which can be a large number) for ( UInt32 i = 0; i < iDeviceCount; i++ ) { for ( UInt32 j = 0; j < iDeviceCount; j++ ) { // get device infos for both current devices QString strDeviceName_i; QString strDeviceName_j; bool bIsInput_i; bool bIsInput_j; bool bIsOutput_i; bool bIsOutput_j; GetAudioDeviceInfos ( vAudioDevices[i], strDeviceName_i, bIsInput_i, bIsOutput_i ); GetAudioDeviceInfos ( vAudioDevices[j], strDeviceName_j, bIsInput_j, bIsOutput_j ); // check if i device is input and j device is output and that we are // in range if ( bIsInput_i && bIsOutput_j && ( lNumDevs < MAX_NUMBER_SOUND_CARDS ) ) { strDriverNames[lNumDevs] = "in: " + strDeviceName_i + "/out: " + strDeviceName_j; // store audio device IDs audioInputDevice[lNumDevs] = vAudioDevices[i]; audioOutputDevice[lNumDevs] = vAudioDevices[j]; lNumDevs++; // next device } } } } void CSound::GetAudioDeviceInfos ( const AudioDeviceID DeviceID, QString& strDeviceName, bool& bIsInput, bool& bIsOutput ) { UInt32 iPropertySize; AudioObjectPropertyAddress stPropertyAddress; // init return values bIsInput = false; bIsOutput = false; // check if device is input or output or both (is that possible?) stPropertyAddress.mSelector = kAudioDevicePropertyStreams; stPropertyAddress.mElement = kAudioObjectPropertyElementMaster; // input check iPropertySize = 0; stPropertyAddress.mScope = kAudioDevicePropertyScopeInput; AudioObjectGetPropertyDataSize ( DeviceID, &stPropertyAddress, 0, NULL, &iPropertySize ); bIsInput = ( iPropertySize > 0 ); // check if any input streams are available // output check iPropertySize = 0; stPropertyAddress.mScope = kAudioDevicePropertyScopeOutput; AudioObjectGetPropertyDataSize ( DeviceID, &stPropertyAddress, 0, NULL, &iPropertySize ); bIsOutput = ( iPropertySize > 0 ); // check if any output streams are available // get property name CFStringRef sPropertyStringValue = NULL; stPropertyAddress.mSelector = kAudioObjectPropertyName; stPropertyAddress.mScope = kAudioObjectPropertyScopeGlobal; iPropertySize = sizeof ( CFStringRef ); AudioObjectGetPropertyData ( DeviceID, &stPropertyAddress, 0, NULL, &iPropertySize, &sPropertyStringValue ); // convert string if ( !ConvertCFStringToQString ( sPropertyStringValue, strDeviceName ) ) { // use a default name in case the conversion did not succeed strDeviceName = "UNKNOWN"; } } int CSound::CountChannels ( AudioDeviceID devID, bool isInput ) { OSStatus err; UInt32 propSize; int result = 0; if ( isInput ) { vecNumInBufChan.Init ( 0 ); } else { vecNumOutBufChan.Init ( 0 ); } // it seems we have multiple buffers where each buffer has only one channel, // in that case we assume that each input channel has its own buffer AudioObjectPropertyScope theScope = isInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput; AudioObjectPropertyAddress theAddress = { kAudioDevicePropertyStreamConfiguration, theScope, 0 }; AudioObjectGetPropertyDataSize ( devID, &theAddress, 0, NULL, &propSize ); AudioBufferList* buflist = (AudioBufferList*) malloc ( propSize ); err = AudioObjectGetPropertyData ( devID, &theAddress, 0, NULL, &propSize, buflist ); if ( !err ) { for ( UInt32 i = 0; i < buflist->mNumberBuffers; ++i ) { // The correct value mNumberChannels for an AudioBuffer can be derived from the mChannelsPerFrame // and the interleaved flag. For non interleaved formats, mNumberChannels is always 1. // For interleaved formats, mNumberChannels is equal to mChannelsPerFrame. result += buflist->mBuffers[i].mNumberChannels; if ( isInput ) { vecNumInBufChan.Add ( buflist->mBuffers[i].mNumberChannels ); } else { vecNumOutBufChan.Add ( buflist->mBuffers[i].mNumberChannels ); } } } free ( buflist ); return result; } QString CSound::LoadAndInitializeDriver ( QString strDriverName, bool ) { // secure lNumDevs/strDriverNames access QMutexLocker locker ( &Mutex ); // reload the driver list of available sound devices GetAvailableInOutDevices(); // find driver index from given driver name int iDriverIdx = INVALID_INDEX; // initialize with an invalid index for ( int i = 0; i < MAX_NUMBER_SOUND_CARDS; i++ ) { if ( strDriverName.compare ( strDriverNames[i] ) == 0 ) { iDriverIdx = i; } } // if the selected driver was not found, return an error message if ( iDriverIdx == INVALID_INDEX ) { return tr ( "The currently selected audio device is no longer present. Please check your audio device." ); } // check device capabilities if it fulfills our requirements const QString strStat = CheckDeviceCapabilities ( iDriverIdx ); // check if device is capable and if not the same device is used if ( strStat.isEmpty() && ( strCurDevName.compare ( strDriverNames[iDriverIdx] ) != 0 ) ) { AudioObjectPropertyAddress stPropertyAddress; // unregister callbacks if previous device was valid if ( lCurDev != INVALID_INDEX ) { stPropertyAddress.mElement = kAudioObjectPropertyElementMaster; stPropertyAddress.mScope = kAudioObjectPropertyScopeGlobal; // unregister callback functions for device property changes stPropertyAddress.mSelector = kAudioHardwarePropertyDefaultOutputDevice; AudioObjectRemovePropertyListener ( kAudioObjectSystemObject, &stPropertyAddress, deviceNotification, this ); stPropertyAddress.mSelector = kAudioHardwarePropertyDefaultInputDevice; AudioObjectRemovePropertyListener ( kAudioObjectSystemObject, &stPropertyAddress, deviceNotification, this ); stPropertyAddress.mSelector = kAudioDevicePropertyDeviceHasChanged; AudioObjectRemovePropertyListener ( audioOutputDevice[lCurDev], &stPropertyAddress, deviceNotification, this ); AudioObjectRemovePropertyListener ( audioInputDevice[lCurDev], &stPropertyAddress, deviceNotification, this ); stPropertyAddress.mSelector = kAudioDevicePropertyDeviceIsAlive; AudioObjectRemovePropertyListener ( audioOutputDevice[lCurDev], &stPropertyAddress, deviceNotification, this ); AudioObjectRemovePropertyListener ( audioInputDevice[lCurDev], &stPropertyAddress, deviceNotification, this ); } // store ID of selected driver if initialization was successful lCurDev = iDriverIdx; CurrentAudioInputDeviceID = audioInputDevice[iDriverIdx]; CurrentAudioOutputDeviceID = audioOutputDevice[iDriverIdx]; // register callbacks stPropertyAddress.mElement = kAudioObjectPropertyElementMaster; stPropertyAddress.mScope = kAudioObjectPropertyScopeGlobal; // setup callbacks for device property changes stPropertyAddress.mSelector = kAudioDevicePropertyDeviceHasChanged; AudioObjectAddPropertyListener ( audioInputDevice[lCurDev], &stPropertyAddress, deviceNotification, this ); AudioObjectAddPropertyListener ( audioOutputDevice[lCurDev], &stPropertyAddress, deviceNotification, this ); stPropertyAddress.mSelector = kAudioDevicePropertyDeviceIsAlive; AudioObjectAddPropertyListener ( audioInputDevice[lCurDev], &stPropertyAddress, deviceNotification, this ); AudioObjectAddPropertyListener ( audioOutputDevice[lCurDev], &stPropertyAddress, deviceNotification, this ); stPropertyAddress.mSelector = kAudioHardwarePropertyDefaultOutputDevice; AudioObjectAddPropertyListener ( kAudioObjectSystemObject, &stPropertyAddress, deviceNotification, this ); stPropertyAddress.mSelector = kAudioHardwarePropertyDefaultInputDevice; AudioObjectAddPropertyListener ( kAudioObjectSystemObject, &stPropertyAddress, deviceNotification, this ); // the device has changed, per definition we reset the channel // mapping to the defaults (first two available channels) SetLeftInputChannel ( 0 ); SetRightInputChannel ( 1 ); SetLeftOutputChannel ( 0 ); SetRightOutputChannel ( 1 ); // store the current name of the driver strCurDevName = strDriverNames[iDriverIdx]; } return strStat; } QString CSound::CheckDeviceCapabilities ( const int iDriverIdx ) { UInt32 iPropertySize; AudioStreamBasicDescription CurDevStreamFormat; Float64 inputSampleRate = 0; Float64 outputSampleRate = 0; const Float64 fSystemSampleRate = static_cast ( SYSTEM_SAMPLE_RATE_HZ ); AudioObjectPropertyAddress stPropertyAddress; stPropertyAddress.mScope = kAudioObjectPropertyScopeGlobal; stPropertyAddress.mElement = kAudioObjectPropertyElementMaster; // check input device sample rate stPropertyAddress.mSelector = kAudioDevicePropertyNominalSampleRate; iPropertySize = sizeof ( Float64 ); if ( AudioObjectGetPropertyData ( audioInputDevice[iDriverIdx], &stPropertyAddress, 0, NULL, &iPropertySize, &inputSampleRate ) ) { return QString ( tr ( "The audio input device is no longer available. Please check if your input device is connected correctly." ) ); } if ( inputSampleRate != fSystemSampleRate ) { // try to change the sample rate if ( AudioObjectSetPropertyData ( audioInputDevice[iDriverIdx], &stPropertyAddress, 0, NULL, sizeof ( Float64 ), &fSystemSampleRate ) != noErr ) { return QString ( tr ( "The sample rate on the current input device isn't %1 Hz and is therefore incompatible. " "Please select another device or try setting the sample rate to %1 Hz " "manually via Audio-MIDI-Setup (in Applications->Utilities)." ) ) .arg ( SYSTEM_SAMPLE_RATE_HZ ); } } // check output device sample rate iPropertySize = sizeof ( Float64 ); if ( AudioObjectGetPropertyData ( audioOutputDevice[iDriverIdx], &stPropertyAddress, 0, NULL, &iPropertySize, &outputSampleRate ) ) { return QString ( tr ( "The audio output device is no longer available. Please check if your output device is connected correctly." ) ); } if ( outputSampleRate != fSystemSampleRate ) { // try to change the sample rate if ( AudioObjectSetPropertyData ( audioOutputDevice[iDriverIdx], &stPropertyAddress, 0, NULL, sizeof ( Float64 ), &fSystemSampleRate ) != noErr ) { return QString ( tr ( "The sample rate on the current output device isn't %1 Hz and is therefore incompatible. " "Please select another device or try setting the sample rate to %1 Hz " "manually via Audio-MIDI-Setup (in Applications->Utilities)." ) ) .arg ( SYSTEM_SAMPLE_RATE_HZ ); } } // get the stream ID of the input device (at least one stream must always exist) iPropertySize = 0; stPropertyAddress.mSelector = kAudioDevicePropertyStreams; stPropertyAddress.mScope = kAudioObjectPropertyScopeInput; AudioObjectGetPropertyDataSize ( audioInputDevice[iDriverIdx], &stPropertyAddress, 0, NULL, &iPropertySize ); CVector vInputStreamIDList ( iPropertySize ); AudioObjectGetPropertyData ( audioInputDevice[iDriverIdx], &stPropertyAddress, 0, NULL, &iPropertySize, &vInputStreamIDList[0] ); const AudioStreamID inputStreamID = vInputStreamIDList[0]; // get the stream ID of the output device (at least one stream must always exist) iPropertySize = 0; stPropertyAddress.mSelector = kAudioDevicePropertyStreams; stPropertyAddress.mScope = kAudioObjectPropertyScopeOutput; AudioObjectGetPropertyDataSize ( audioOutputDevice[iDriverIdx], &stPropertyAddress, 0, NULL, &iPropertySize ); CVector vOutputStreamIDList ( iPropertySize ); AudioObjectGetPropertyData ( audioOutputDevice[iDriverIdx], &stPropertyAddress, 0, NULL, &iPropertySize, &vOutputStreamIDList[0] ); const AudioStreamID outputStreamID = vOutputStreamIDList[0]; // According to the AudioHardware documentation: "If the format is a linear PCM // format, the data will always be presented as 32 bit, native endian floating // point. All conversions to and from the true physical format of the hardware // is handled by the devices driver.". // check the input iPropertySize = sizeof ( AudioStreamBasicDescription ); stPropertyAddress.mSelector = kAudioStreamPropertyVirtualFormat; stPropertyAddress.mScope = kAudioObjectPropertyScopeGlobal; AudioObjectGetPropertyData ( inputStreamID, &stPropertyAddress, 0, NULL, &iPropertySize, &CurDevStreamFormat ); if ( ( CurDevStreamFormat.mFormatID != kAudioFormatLinearPCM ) || ( CurDevStreamFormat.mFramesPerPacket != 1 ) || ( CurDevStreamFormat.mBitsPerChannel != 32 ) || ( !( CurDevStreamFormat.mFormatFlags & kAudioFormatFlagIsFloat ) ) || ( !( CurDevStreamFormat.mFormatFlags & kAudioFormatFlagIsPacked ) ) ) { return QString ( tr ( "The stream format on the current input device isn't " "compatible with this software. Please select another device." ) ); } // check the output AudioObjectGetPropertyData ( outputStreamID, &stPropertyAddress, 0, NULL, &iPropertySize, &CurDevStreamFormat ); if ( ( CurDevStreamFormat.mFormatID != kAudioFormatLinearPCM ) || ( CurDevStreamFormat.mFramesPerPacket != 1 ) || ( CurDevStreamFormat.mBitsPerChannel != 32 ) || ( !( CurDevStreamFormat.mFormatFlags & kAudioFormatFlagIsFloat ) ) || ( !( CurDevStreamFormat.mFormatFlags & kAudioFormatFlagIsPacked ) ) ) { return QString ( tr ( "The stream format on the current output device isn't " "compatible with %1. Please select another device." ) ) .arg ( APP_NAME ); } // store the input and out number of channels for this device iNumInChan = CountChannels ( audioInputDevice[iDriverIdx], true ); iNumOutChan = CountChannels ( audioOutputDevice[iDriverIdx], false ); // clip the number of input/output channels to our allowed maximum if ( iNumInChan > MAX_NUM_IN_OUT_CHANNELS ) { iNumInChan = MAX_NUM_IN_OUT_CHANNELS; } if ( iNumOutChan > MAX_NUM_IN_OUT_CHANNELS ) { iNumOutChan = MAX_NUM_IN_OUT_CHANNELS; } // get the channel names of the input device for ( int iCurInCH = 0; iCurInCH < iNumInChan; iCurInCH++ ) { CFStringRef sPropertyStringValue = NULL; stPropertyAddress.mSelector = kAudioObjectPropertyElementName; stPropertyAddress.mElement = iCurInCH + 1; stPropertyAddress.mScope = kAudioObjectPropertyScopeInput; iPropertySize = sizeof ( CFStringRef ); AudioObjectGetPropertyData ( audioInputDevice[iDriverIdx], &stPropertyAddress, 0, NULL, &iPropertySize, &sPropertyStringValue ); // convert string const bool bConvOK = ConvertCFStringToQString ( sPropertyStringValue, sChannelNamesInput[iCurInCH] ); // add the "[n]:" at the beginning as is in the Audio-Midi-Setup if ( !bConvOK || ( iPropertySize == 0 ) ) { // use a default name in case there was an error or the name is empty sChannelNamesInput[iCurInCH] = QString ( "%1: Channel %1" ).arg ( iCurInCH + 1 ); } else { sChannelNamesInput[iCurInCH].prepend ( QString ( "%1: " ).arg ( iCurInCH + 1 ) ); } } // get the channel names of the output device for ( int iCurOutCH = 0; iCurOutCH < iNumOutChan; iCurOutCH++ ) { CFStringRef sPropertyStringValue = NULL; stPropertyAddress.mSelector = kAudioObjectPropertyElementName; stPropertyAddress.mElement = iCurOutCH + 1; stPropertyAddress.mScope = kAudioObjectPropertyScopeOutput; iPropertySize = sizeof ( CFStringRef ); AudioObjectGetPropertyData ( audioOutputDevice[iDriverIdx], &stPropertyAddress, 0, NULL, &iPropertySize, &sPropertyStringValue ); // convert string const bool bConvOK = ConvertCFStringToQString ( sPropertyStringValue, sChannelNamesOutput[iCurOutCH] ); // add the "[n]:" at the beginning as is in the Audio-Midi-Setup if ( !bConvOK || ( iPropertySize == 0 ) ) { // use a default name in case there was an error or the name is empty sChannelNamesOutput[iCurOutCH] = QString ( "%1: Channel %1" ).arg ( iCurOutCH + 1 ); } else { sChannelNamesOutput[iCurOutCH].prepend ( QString ( "%1: " ).arg ( iCurOutCH + 1 ) ); } } // special case with 4 input channels: support adding channels if ( iNumInChan == 4 ) { // add four mixed channels (i.e. 4 normal, 4 mixed channels) iNumInChanPlusAddChan = 8; for ( int iCh = 0; iCh < iNumInChanPlusAddChan; iCh++ ) { int iSelCH, iSelAddCH; GetSelCHAndAddCH ( iCh, iNumInChan, iSelCH, iSelAddCH ); if ( iSelAddCH >= 0 ) { // for mixed channels, show both audio channel names to be mixed sChannelNamesInput[iCh] = sChannelNamesInput[iSelCH] + " + " + sChannelNamesInput[iSelAddCH]; } } } else { // regular case: no mixing input channels used iNumInChanPlusAddChan = iNumInChan; } // everything is ok, return empty string for "no error" case return ""; } void CSound::UpdateChSelection() { // calculate the selected input/output buffer and the selected interleaved // channel index in the buffer, note that each buffer can have a different // number of interleaved channels int iChCnt; int iSelCHLeft, iSelAddCHLeft; int iSelCHRight, iSelAddCHRight; // initialize all buffer indexes with an invalid value iSelInBufferLeft = INVALID_INDEX; iSelInBufferRight = INVALID_INDEX; iSelAddInBufferLeft = INVALID_INDEX; // if no additional channel used, this will stay on the invalid value iSelAddInBufferRight = INVALID_INDEX; // if no additional channel used, this will stay on the invalid value iSelOutBufferLeft = INVALID_INDEX; iSelOutBufferRight = INVALID_INDEX; // input GetSelCHAndAddCH ( iSelInputLeftChannel, iNumInChan, iSelCHLeft, iSelAddCHLeft ); GetSelCHAndAddCH ( iSelInputRightChannel, iNumInChan, iSelCHRight, iSelAddCHRight ); iChCnt = 0; for ( int iBuf = 0; iBuf < vecNumInBufChan.Size(); iBuf++ ) { iChCnt += vecNumInBufChan[iBuf]; if ( ( iSelInBufferLeft < 0 ) && ( iChCnt > iSelCHLeft ) ) { iSelInBufferLeft = iBuf; iSelInInterlChLeft = iSelCHLeft - iChCnt + vecNumInBufChan[iBuf]; } if ( ( iSelInBufferRight < 0 ) && ( iChCnt > iSelCHRight ) ) { iSelInBufferRight = iBuf; iSelInInterlChRight = iSelCHRight - iChCnt + vecNumInBufChan[iBuf]; } if ( ( iSelAddCHLeft >= 0 ) && ( iSelAddInBufferLeft < 0 ) && ( iChCnt > iSelAddCHLeft ) ) { iSelAddInBufferLeft = iBuf; iSelAddInInterlChLeft = iSelAddCHLeft - iChCnt + vecNumInBufChan[iBuf]; } if ( ( iSelAddCHRight >= 0 ) && ( iSelAddInBufferRight < 0 ) && ( iChCnt > iSelAddCHRight ) ) { iSelAddInBufferRight = iBuf; iSelAddInInterlChRight = iSelAddCHRight - iChCnt + vecNumInBufChan[iBuf]; } } // output GetSelCHAndAddCH ( iSelOutputLeftChannel, iNumOutChan, iSelCHLeft, iSelAddCHLeft ); GetSelCHAndAddCH ( iSelOutputRightChannel, iNumOutChan, iSelCHRight, iSelAddCHRight ); iChCnt = 0; for ( int iBuf = 0; iBuf < vecNumOutBufChan.Size(); iBuf++ ) { iChCnt += vecNumOutBufChan[iBuf]; if ( ( iSelOutBufferLeft < 0 ) && ( iChCnt > iSelCHLeft ) ) { iSelOutBufferLeft = iBuf; iSelOutInterlChLeft = iSelCHLeft - iChCnt + vecNumOutBufChan[iBuf]; } if ( ( iSelOutBufferRight < 0 ) && ( iChCnt > iSelCHRight ) ) { iSelOutBufferRight = iBuf; iSelOutInterlChRight = iSelCHRight - iChCnt + vecNumOutBufChan[iBuf]; } } } void CSound::SetLeftInputChannel ( const int iNewChan ) { // apply parameter after input parameter check if ( ( iNewChan >= 0 ) && ( iNewChan < iNumInChanPlusAddChan ) ) { iSelInputLeftChannel = iNewChan; UpdateChSelection(); } } void CSound::SetRightInputChannel ( const int iNewChan ) { // apply parameter after input parameter check if ( ( iNewChan >= 0 ) && ( iNewChan < iNumInChanPlusAddChan ) ) { iSelInputRightChannel = iNewChan; UpdateChSelection(); } } void CSound::SetLeftOutputChannel ( const int iNewChan ) { // apply parameter after input parameter check if ( ( iNewChan >= 0 ) && ( iNewChan < iNumOutChan ) ) { iSelOutputLeftChannel = iNewChan; UpdateChSelection(); } } void CSound::SetRightOutputChannel ( const int iNewChan ) { // apply parameter after input parameter check if ( ( iNewChan >= 0 ) && ( iNewChan < iNumOutChan ) ) { iSelOutputRightChannel = iNewChan; UpdateChSelection(); } } void CSound::Start() { // register the callback function for input and output AudioDeviceCreateIOProcID ( audioInputDevice[lCurDev], callbackIO, this, &audioInputProcID ); AudioDeviceCreateIOProcID ( audioOutputDevice[lCurDev], callbackIO, this, &audioOutputProcID ); // start the audio stream AudioDeviceStart ( audioInputDevice[lCurDev], audioInputProcID ); AudioDeviceStart ( audioOutputDevice[lCurDev], audioOutputProcID ); // call base class CSoundBase::Start(); } void CSound::Stop() { // stop the audio stream AudioDeviceStop ( audioInputDevice[lCurDev], audioInputProcID ); AudioDeviceStop ( audioOutputDevice[lCurDev], audioOutputProcID ); // unregister the callback function for input and output AudioDeviceDestroyIOProcID ( audioInputDevice[lCurDev], audioInputProcID ); AudioDeviceDestroyIOProcID ( audioOutputDevice[lCurDev], audioOutputProcID ); // call base class CSoundBase::Stop(); } int CSound::Init ( const int iNewPrefMonoBufferSize ) { UInt32 iActualMonoBufferSize; // Error message string: in case buffer sizes on input and output cannot be // set to the same value const QString strErrBufSize = tr ( "The buffer sizes of the current " "input and output audio device can't be set to a common value. Please " "select different input/output devices in your system settings." ); // try to set input buffer size iActualMonoBufferSize = SetBufferSize ( audioInputDevice[lCurDev], true, iNewPrefMonoBufferSize ); if ( iActualMonoBufferSize != static_cast ( iNewPrefMonoBufferSize ) ) { // try to set the input buffer size to the output so that we // have a matching pair if ( SetBufferSize ( audioOutputDevice[lCurDev], false, iActualMonoBufferSize ) != iActualMonoBufferSize ) { throw CGenErr ( strErrBufSize ); } } else { // try to set output buffer size if ( SetBufferSize ( audioOutputDevice[lCurDev], false, iNewPrefMonoBufferSize ) != static_cast ( iNewPrefMonoBufferSize ) ) { throw CGenErr ( strErrBufSize ); } } // store buffer size iCoreAudioBufferSizeMono = iActualMonoBufferSize; // init base class CSoundBase::Init ( iCoreAudioBufferSizeMono ); // set internal buffer size value and calculate stereo buffer size iCoreAudioBufferSizeStereo = 2 * iCoreAudioBufferSizeMono; // create memory for intermediate audio buffer vecsTmpAudioSndCrdStereo.Init ( iCoreAudioBufferSizeStereo ); return iCoreAudioBufferSizeMono; } UInt32 CSound::SetBufferSize ( AudioDeviceID& audioDeviceID, const bool bIsInput, UInt32 iPrefBufferSize ) { AudioObjectPropertyAddress stPropertyAddress; stPropertyAddress.mSelector = kAudioDevicePropertyBufferFrameSize; if ( bIsInput ) { stPropertyAddress.mScope = kAudioDevicePropertyScopeInput; } else { stPropertyAddress.mScope = kAudioDevicePropertyScopeOutput; } stPropertyAddress.mElement = kAudioObjectPropertyElementMaster; // first set the value UInt32 iSizeBufValue = sizeof ( UInt32 ); AudioObjectSetPropertyData ( audioDeviceID, &stPropertyAddress, 0, NULL, iSizeBufValue, &iPrefBufferSize ); // read back which value is actually used UInt32 iActualMonoBufferSize = 0; AudioObjectGetPropertyData ( audioDeviceID, &stPropertyAddress, 0, NULL, &iSizeBufValue, &iActualMonoBufferSize ); return iActualMonoBufferSize; } OSStatus CSound::deviceNotification ( AudioDeviceID, UInt32, const AudioObjectPropertyAddress* inAddresses, void* inRefCon ) { CSound* pSound = static_cast ( inRefCon ); if ( ( inAddresses->mSelector == kAudioDevicePropertyDeviceHasChanged ) || ( inAddresses->mSelector == kAudioDevicePropertyDeviceIsAlive ) || ( inAddresses->mSelector == kAudioHardwarePropertyDefaultOutputDevice ) || ( inAddresses->mSelector == kAudioHardwarePropertyDefaultInputDevice ) ) { if ( ( inAddresses->mSelector == kAudioDevicePropertyDeviceHasChanged ) || ( inAddresses->mSelector == kAudioDevicePropertyDeviceIsAlive ) ) { // if any property of the device has changed, do a full reload pSound->EmitReinitRequestSignal ( RS_RELOAD_RESTART_AND_INIT ); } else { // for any other change in audio devices, just initiate a restart which // triggers an update of the sound device selection combo box pSound->EmitReinitRequestSignal ( RS_ONLY_RESTART ); } } return noErr; } OSStatus CSound::callbackIO ( AudioDeviceID inDevice, const AudioTimeStamp*, const AudioBufferList* inInputData, const AudioTimeStamp*, AudioBufferList* outOutputData, const AudioTimeStamp*, void* inRefCon ) { CSound* pSound = static_cast ( inRefCon ); // both, the input and output device use the same callback function QMutexLocker locker ( &pSound->MutexAudioProcessCallback ); const int iCoreAudioBufferSizeMono = pSound->iCoreAudioBufferSizeMono; const int iSelInBufferLeft = pSound->iSelInBufferLeft; const int iSelInBufferRight = pSound->iSelInBufferRight; const int iSelInInterlChLeft = pSound->iSelInInterlChLeft; const int iSelInInterlChRight = pSound->iSelInInterlChRight; const int iSelAddInBufferLeft = pSound->iSelAddInBufferLeft; const int iSelAddInBufferRight = pSound->iSelAddInBufferRight; const int iSelAddInInterlChLeft = pSound->iSelAddInInterlChLeft; const int iSelAddInInterlChRight = pSound->iSelAddInInterlChRight; const int iSelOutBufferLeft = pSound->iSelOutBufferLeft; const int iSelOutBufferRight = pSound->iSelOutBufferRight; const int iSelOutInterlChLeft = pSound->iSelOutInterlChLeft; const int iSelOutInterlChRight = pSound->iSelOutInterlChRight; const CVector& vecNumInBufChan = pSound->vecNumInBufChan; const CVector& vecNumOutBufChan = pSound->vecNumOutBufChan; if ( ( inDevice == pSound->CurrentAudioInputDeviceID ) && inInputData && pSound->bRun ) { // check sizes (note that float32 has four bytes) if ( ( iSelInBufferLeft >= 0 ) && ( iSelInBufferLeft < static_cast ( inInputData->mNumberBuffers ) ) && ( iSelInBufferRight >= 0 ) && ( iSelInBufferRight < static_cast ( inInputData->mNumberBuffers ) ) && ( iSelAddInBufferLeft < static_cast ( inInputData->mNumberBuffers ) ) && ( iSelAddInBufferRight < static_cast ( inInputData->mNumberBuffers ) ) && ( inInputData->mBuffers[iSelInBufferLeft].mDataByteSize == static_cast ( vecNumInBufChan[iSelInBufferLeft] * iCoreAudioBufferSizeMono * 4 ) ) && ( inInputData->mBuffers[iSelInBufferRight].mDataByteSize == static_cast ( vecNumInBufChan[iSelInBufferRight] * iCoreAudioBufferSizeMono * 4 ) ) ) { Float32* pLeftData = static_cast ( inInputData->mBuffers[iSelInBufferLeft].mData ); Float32* pRightData = static_cast ( inInputData->mBuffers[iSelInBufferRight].mData ); int iNumChanPerFrameLeft = vecNumInBufChan[iSelInBufferLeft]; int iNumChanPerFrameRight = vecNumInBufChan[iSelInBufferRight]; // copy input data for ( int i = 0; i < iCoreAudioBufferSizeMono; i++ ) { // copy left and right channels separately pSound->vecsTmpAudioSndCrdStereo[2 * i] = (short) ( pLeftData[iNumChanPerFrameLeft * i + iSelInInterlChLeft] * _MAXSHORT ); pSound->vecsTmpAudioSndCrdStereo[2 * i + 1] = (short) ( pRightData[iNumChanPerFrameRight * i + iSelInInterlChRight] * _MAXSHORT ); } // add an additional optional channel if ( iSelAddInBufferLeft >= 0 ) { pLeftData = static_cast ( inInputData->mBuffers[iSelAddInBufferLeft].mData ); iNumChanPerFrameLeft = vecNumInBufChan[iSelAddInBufferLeft]; for ( int i = 0; i < iCoreAudioBufferSizeMono; i++ ) { pSound->vecsTmpAudioSndCrdStereo[2 * i] = Float2Short ( pSound->vecsTmpAudioSndCrdStereo[2 * i] + pLeftData[iNumChanPerFrameLeft * i + iSelAddInInterlChLeft] * _MAXSHORT ); } } if ( iSelAddInBufferRight >= 0 ) { pRightData = static_cast ( inInputData->mBuffers[iSelAddInBufferRight].mData ); iNumChanPerFrameRight = vecNumInBufChan[iSelAddInBufferRight]; for ( int i = 0; i < iCoreAudioBufferSizeMono; i++ ) { pSound->vecsTmpAudioSndCrdStereo[2 * i + 1] = Float2Short ( pSound->vecsTmpAudioSndCrdStereo[2 * i + 1] + pRightData[iNumChanPerFrameRight * i + iSelAddInInterlChRight] * _MAXSHORT ); } } } else { // incompatible sizes, clear work buffer pSound->vecsTmpAudioSndCrdStereo.Reset ( 0 ); } // call processing callback function pSound->ProcessCallback ( pSound->vecsTmpAudioSndCrdStereo ); } if ( ( inDevice == pSound->CurrentAudioOutputDeviceID ) && outOutputData && pSound->bRun ) { // check sizes (note that float32 has four bytes) if ( ( iSelOutBufferLeft >= 0 ) && ( iSelOutBufferLeft < static_cast ( outOutputData->mNumberBuffers ) ) && ( iSelOutBufferRight >= 0 ) && ( iSelOutBufferRight < static_cast ( outOutputData->mNumberBuffers ) ) && ( outOutputData->mBuffers[iSelOutBufferLeft].mDataByteSize == static_cast ( vecNumOutBufChan[iSelOutBufferLeft] * iCoreAudioBufferSizeMono * 4 ) ) && ( outOutputData->mBuffers[iSelOutBufferRight].mDataByteSize == static_cast ( vecNumOutBufChan[iSelOutBufferRight] * iCoreAudioBufferSizeMono * 4 ) ) ) { Float32* pLeftData = static_cast ( outOutputData->mBuffers[iSelOutBufferLeft].mData ); Float32* pRightData = static_cast ( outOutputData->mBuffers[iSelOutBufferRight].mData ); int iNumChanPerFrameLeft = vecNumOutBufChan[iSelOutBufferLeft]; int iNumChanPerFrameRight = vecNumOutBufChan[iSelOutBufferRight]; // copy output data for ( int i = 0; i < iCoreAudioBufferSizeMono; i++ ) { // copy left and right channels separately pLeftData[iNumChanPerFrameLeft * i + iSelOutInterlChLeft] = (Float32) pSound->vecsTmpAudioSndCrdStereo[2 * i] / _MAXSHORT; pRightData[iNumChanPerFrameRight * i + iSelOutInterlChRight] = (Float32) pSound->vecsTmpAudioSndCrdStereo[2 * i + 1] / _MAXSHORT; } } } return kAudioHardwareNoError; } void CSound::callbackMIDI ( const MIDIPacketList* pktlist, void* refCon, void* ) { CSound* pSound = static_cast ( refCon ); if ( pSound->midiInPortRef != static_cast ( NULL ) ) { MIDIPacket* midiPacket = const_cast ( pktlist->packet ); for ( unsigned int j = 0; j < pktlist->numPackets; j++ ) { // copy packet and send it to the MIDI parser CVector vMIDIPaketBytes ( midiPacket->length ); for ( int i = 0; i < midiPacket->length; i++ ) { vMIDIPaketBytes[i] = static_cast ( midiPacket->data[i] ); } pSound->ParseMIDIMessage ( vMIDIPaketBytes ); midiPacket = MIDIPacketNext ( midiPacket ); } } } bool CSound::ConvertCFStringToQString ( const CFStringRef stringRef, QString& sOut ) { // check if the string reference is a valid pointer if ( stringRef != NULL ) { // first check if the string is not empty if ( CFStringGetLength ( stringRef ) > 0 ) { // convert CFString in c-string (quick hack!) and then in QString char* sC_strPropValue = (char*) malloc ( CFStringGetLength ( stringRef ) * 3 + 1 ); if ( CFStringGetCString ( stringRef, sC_strPropValue, CFStringGetLength ( stringRef ) * 3 + 1, kCFStringEncodingUTF8 ) ) { sOut = sC_strPropValue; free ( sC_strPropValue ); return true; // OK } } // release the string reference because it is not needed anymore CFRelease ( stringRef ); } return false; // not OK } jamulus-3.9.1+dfsg/src/sound/coreaudio-mac/sound.h0000644000175000017500000001261614340334543021112 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #include #include #include #include #include #include "../soundbase.h" #include "../../global.h" /* Classes ********************************************************************/ class CSound : public CSoundBase { Q_OBJECT public: CSound ( void ( *fpNewProcessCallback ) ( CVector& psData, void* arg ), void* arg, const QString& strMIDISetup, const bool, const QString& ); virtual int Init ( const int iNewPrefMonoBufferSize ); virtual void Start(); virtual void Stop(); // channel selection virtual int GetNumInputChannels() { return iNumInChanPlusAddChan; } virtual QString GetInputChannelName ( const int iDiD ) { return sChannelNamesInput[iDiD]; } virtual void SetLeftInputChannel ( const int iNewChan ); virtual void SetRightInputChannel ( const int iNewChan ); virtual int GetLeftInputChannel() { return iSelInputLeftChannel; } virtual int GetRightInputChannel() { return iSelInputRightChannel; } virtual int GetNumOutputChannels() { return iNumOutChan; } virtual QString GetOutputChannelName ( const int iDiD ) { return sChannelNamesOutput[iDiD]; } virtual void SetLeftOutputChannel ( const int iNewChan ); virtual void SetRightOutputChannel ( const int iNewChan ); virtual int GetLeftOutputChannel() { return iSelOutputLeftChannel; } virtual int GetRightOutputChannel() { return iSelOutputRightChannel; } // these variables/functions should be protected but cannot since we want // to access them from the callback function CVector vecsTmpAudioSndCrdStereo; int iCoreAudioBufferSizeMono; int iCoreAudioBufferSizeStereo; AudioDeviceID CurrentAudioInputDeviceID; AudioDeviceID CurrentAudioOutputDeviceID; long lCurDev; int iNumInChan; int iNumInChanPlusAddChan; // includes additional "added" channels int iNumOutChan; int iSelInputLeftChannel; int iSelInputRightChannel; int iSelOutputLeftChannel; int iSelOutputRightChannel; int iSelInBufferLeft; int iSelInBufferRight; int iSelInInterlChLeft; int iSelInInterlChRight; int iSelAddInBufferLeft; int iSelAddInBufferRight; int iSelAddInInterlChLeft; int iSelAddInInterlChRight; int iSelOutBufferLeft; int iSelOutBufferRight; int iSelOutInterlChLeft; int iSelOutInterlChRight; CVector vecNumInBufChan; CVector vecNumOutBufChan; protected: virtual QString LoadAndInitializeDriver ( QString strDriverName, bool ); QString CheckDeviceCapabilities ( const int iDriverIdx ); void UpdateChSelection(); void GetAvailableInOutDevices(); int CountChannels ( AudioDeviceID devID, bool isInput ); UInt32 SetBufferSize ( AudioDeviceID& audioDeviceID, const bool bIsInput, UInt32 iPrefBufferSize ); void GetAudioDeviceInfos ( const AudioDeviceID DeviceID, QString& strDeviceName, bool& bIsInput, bool& bIsOutput ); bool ConvertCFStringToQString ( const CFStringRef stringRef, QString& sOut ); // callbacks static OSStatus deviceNotification ( AudioDeviceID, UInt32, const AudioObjectPropertyAddress* inAddresses, void* inRefCon ); static OSStatus callbackIO ( AudioDeviceID inDevice, const AudioTimeStamp*, const AudioBufferList* inInputData, const AudioTimeStamp*, AudioBufferList* outOutputData, const AudioTimeStamp*, void* inRefCon ); static void callbackMIDI ( const MIDIPacketList* pktlist, void* refCon, void* ); AudioDeviceID audioInputDevice[MAX_NUMBER_SOUND_CARDS]; AudioDeviceID audioOutputDevice[MAX_NUMBER_SOUND_CARDS]; AudioDeviceIOProcID audioInputProcID; AudioDeviceIOProcID audioOutputProcID; MIDIPortRef midiInPortRef; QString sChannelNamesInput[MAX_NUM_IN_OUT_CHANNELS]; QString sChannelNamesOutput[MAX_NUM_IN_OUT_CHANNELS]; QMutex Mutex; }; jamulus-3.9.1+dfsg/src/sound/coreaudio-ios/0000755000175000017500000000000014340334543017635 5ustar vimervimerjamulus-3.9.1+dfsg/src/sound/coreaudio-ios/sound.mm0000644000175000017500000003256714340334543021335 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * ann0see and ngocdh based on code from Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include "sound.h" #include #define kOutputBus 0 #define kInputBus 1 /* Implementation *************************************************************/ CSound::CSound ( void ( *fpNewProcessCallback ) ( CVector& psData, void* arg ), void* arg, const QString& strMIDISetup, const bool, const QString& ) : CSoundBase ( "CoreAudio iOS", fpNewProcessCallback, arg, strMIDISetup ), isInitialized ( false ) { try { NSError* audioSessionError = nil; [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:&audioSessionError]; [[AVAudioSession sharedInstance] requestRecordPermission:^( BOOL granted ) { if ( granted ) { // ok } else { // TODO - alert user } }]; [[AVAudioSession sharedInstance] setMode:AVAudioSessionModeMeasurement error:&audioSessionError]; } catch ( const CGenErr& generr ) { QMessageBox::warning ( nullptr, "Sound exception", generr.GetErrorText() ); } buffer.mNumberChannels = 2; buffer.mData = malloc ( 256 * sizeof ( Float32 ) * buffer.mNumberChannels ); // max size bufferList.mNumberBuffers = 1; bufferList.mBuffers[0] = buffer; } CSound::~CSound() { free ( buffer.mData ); } /** This callback is called when sound card needs output data to play. And because Jamulus uses the same buffer to store input and output data (input is sent to server, then output is fetched from server), we actually use the output callback to read inputdata first, process it, and then copy the output fetched from server to ioData, which will then be played. */ OSStatus CSound::recordingCallback ( void* inRefCon, AudioUnitRenderActionFlags* ioActionFlags, const AudioTimeStamp* inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList* ioData ) { CSound* pSound = static_cast ( inRefCon ); // setting up temp buffer pSound->buffer.mDataByteSize = pSound->iCoreAudioBufferSizeMono * sizeof ( Float32 ) * pSound->buffer.mNumberChannels; pSound->bufferList.mBuffers[0] = pSound->buffer; // Obtain recorded samples // Calling Unit Render to store input data to bufferList AudioUnitRender ( pSound->audioUnit, ioActionFlags, inTimeStamp, 1, inNumberFrames, &pSound->bufferList ); // Now, we have the samples we just read sitting in buffers in bufferList // Process the new data pSound->processBufferList ( &pSound->bufferList, pSound ); // THIS IS WHERE vecsStereo is filled with data from bufferList Float32* pData = (Float32*) ( ioData->mBuffers[0].mData ); // copy output data for ( int i = 0; i < pSound->iCoreAudioBufferSizeMono; i++ ) { pData[2 * i] = (Float32) pSound->vecsTmpAudioSndCrdStereo[2 * i] / _MAXSHORT; // left pData[2 * i + 1] = (Float32) pSound->vecsTmpAudioSndCrdStereo[2 * i + 1] / _MAXSHORT; // right } return noErr; } void CSound::processBufferList ( AudioBufferList* inInputData, CSound* pSound ) // got stereo input data { QMutexLocker locker ( &pSound->MutexAudioProcessCallback ); Float32* pData = static_cast ( inInputData->mBuffers[0].mData ); // copy input data for ( int i = 0; i < pSound->iCoreAudioBufferSizeMono; i++ ) { // copy left and right channels separately pSound->vecsTmpAudioSndCrdStereo[2 * i] = (short) ( pData[2 * i] * _MAXSHORT ); // left pSound->vecsTmpAudioSndCrdStereo[2 * i + 1] = (short) ( pData[2 * i + 1] * _MAXSHORT ); // right } pSound->ProcessCallback ( pSound->vecsTmpAudioSndCrdStereo ); } // TODO - CSound::Init is called multiple times at launch to verify device capabilities. // For iOS though, Init takes long, so should better reduce those inits for iOS (Now: 9 times/launch). int CSound::Init ( const int iCoreAudioBufferSizeMono ) { try { this->iCoreAudioBufferSizeMono = iCoreAudioBufferSizeMono; // set internal buffer size value and calculate stereo buffer size iCoreAudioBufferSizeStereo = 2 * iCoreAudioBufferSizeMono; // create memory for intermediate audio buffer vecsTmpAudioSndCrdStereo.Init ( iCoreAudioBufferSizeStereo ); AVAudioSession* sessionInstance = [AVAudioSession sharedInstance]; // we are going to play and record so we pick that category NSError* error = nil; [sessionInstance setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionMixWithOthers | AVAudioSessionCategoryOptionDefaultToSpeaker | AVAudioSessionCategoryOptionAllowBluetooth | AVAudioSessionCategoryOptionAllowBluetoothA2DP | AVAudioSessionCategoryOptionAllowAirPlay error:&error]; // using values from jamulus settings 64 = 2.67ms/2 NSTimeInterval bufferDuration = iCoreAudioBufferSizeMono / Float32 ( SYSTEM_SAMPLE_RATE_HZ ); // yeah it's math [sessionInstance setPreferredIOBufferDuration:bufferDuration error:&error]; // set the session's sample rate 48000 - the only supported by Jamulus [sessionInstance setPreferredSampleRate:SYSTEM_SAMPLE_RATE_HZ error:&error]; [[AVAudioSession sharedInstance] setActive:YES error:&error]; OSStatus status; // Describe audio component AudioComponentDescription desc; desc.componentType = kAudioUnitType_Output; desc.componentSubType = kAudioUnitSubType_RemoteIO; desc.componentFlags = 0; desc.componentFlagsMask = 0; desc.componentManufacturer = kAudioUnitManufacturer_Apple; // Get component AudioComponent inputComponent = AudioComponentFindNext ( NULL, &desc ); // Get audio units status = AudioComponentInstanceNew ( inputComponent, &audioUnit ); checkStatus ( status ); // Enable IO for recording UInt32 flag = 1; status = AudioUnitSetProperty ( audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, kInputBus, &flag, sizeof ( flag ) ); checkStatus ( status ); // Enable IO for playback status = AudioUnitSetProperty ( audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, kOutputBus, &flag, sizeof ( flag ) ); checkStatus ( status ); // Describe format AudioStreamBasicDescription audioFormat; audioFormat.mSampleRate = SYSTEM_SAMPLE_RATE_HZ; audioFormat.mFormatID = kAudioFormatLinearPCM; audioFormat.mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked; audioFormat.mFramesPerPacket = 1; audioFormat.mChannelsPerFrame = 2; // stereo, so 2 interleaved channels audioFormat.mBitsPerChannel = 32; // sizeof float32 audioFormat.mBytesPerPacket = 8; // (sizeof float32) * 2 channels audioFormat.mBytesPerFrame = 8; //(sizeof float32) * 2 channels // Apply format status = AudioUnitSetProperty ( audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, kInputBus, &audioFormat, sizeof ( audioFormat ) ); checkStatus ( status ); status = AudioUnitSetProperty ( audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus, &audioFormat, sizeof ( audioFormat ) ); checkStatus ( status ); // Set callback AURenderCallbackStruct callbackStruct; callbackStruct.inputProc = recordingCallback; // this is actually the playback callback callbackStruct.inputProcRefCon = this; status = AudioUnitSetProperty ( audioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Global, kOutputBus, &callbackStruct, sizeof ( callbackStruct ) ); checkStatus ( status ); // Initialise status = AudioUnitInitialize ( audioUnit ); checkStatus ( status ); SwitchDevice ( strCurDevName ); if ( !isInitialized ) { [[NSNotificationCenter defaultCenter] addObserverForName:AVAudioSessionRouteChangeNotification object:nil queue:nil usingBlock:^( NSNotification* notification ) { UInt8 reason = [[notification.userInfo valueForKey:AVAudioSessionRouteChangeReasonKey] intValue]; if ( reason == AVAudioSessionRouteChangeReasonNewDeviceAvailable or reason == AVAudioSessionRouteChangeReasonOldDeviceUnavailable ) { emit ReinitRequest ( RS_RELOAD_RESTART_AND_INIT ); // reload the available devices frame } }]; } isInitialized = true; } catch ( const CGenErr& generr ) { QMessageBox::warning ( nullptr, "Sound init exception", generr.GetErrorText() ); } return iCoreAudioBufferSizeMono; } void CSound::Start() { // call base class CSoundBase::Start(); try { OSStatus err = AudioOutputUnitStart ( audioUnit ); checkStatus ( err ); } catch ( const CGenErr& generr ) { QMessageBox::warning ( nullptr, "Sound start exception", generr.GetErrorText() ); } } void CSound::Stop() { try { OSStatus err = AudioOutputUnitStop ( audioUnit ); checkStatus ( err ); } catch ( const CGenErr& generr ) { QMessageBox::warning ( nullptr, "Sound stop exception", generr.GetErrorText() ); } // call base class CSoundBase::Stop(); } void CSound::checkStatus ( int status ) { if ( status ) { printf ( "Status not 0! %d\n", status ); } } QString CSound::LoadAndInitializeDriver ( QString strDriverName, bool ) { // secure lNumDevs/strDriverNames access QMutexLocker locker ( &Mutex ); // reload the driver list of available sound devices GetAvailableInOutDevices(); // store the current name of the driver strCurDevName = strDriverName; return ""; } void CSound::GetAvailableInOutDevices() { // always add system default devices for input and output as first entry lNumDevs = 1; strDriverNames[0] = "System Default In/Out Devices"; AVAudioSession* sessionInstance = [AVAudioSession sharedInstance]; if ( sessionInstance.availableInputs.count > 1 ) { lNumDevs = 2; strDriverNames[1] = "in: Built-in Mic/out: System Default"; } } void CSound::SwitchDevice ( QString strDriverName ) { // find driver index from given driver name int iDriverIdx = INVALID_INDEX; // initialize with an invalid index for ( int i = 0; i < MAX_NUMBER_SOUND_CARDS; i++ ) { if ( strDriverName.compare ( strDriverNames[i] ) == 0 ) { iDriverIdx = i; break; } } NSError* error = nil; AVAudioSession* sessionInstance = [AVAudioSession sharedInstance]; if ( iDriverIdx == 0 ) // system default device { unsigned long lastInput = sessionInstance.availableInputs.count - 1; [sessionInstance setPreferredInput:sessionInstance.availableInputs[lastInput] error:&error]; } else // built-in mic { [sessionInstance setPreferredInput:sessionInstance.availableInputs[0] error:&error]; } } jamulus-3.9.1+dfsg/src/sound/coreaudio-ios/sound.h0000644000175000017500000000533114340334543021140 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * ann0see and ngocdh based on code from Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #include "../soundbase.h" #include "../../global.h" #import class CSound : public CSoundBase { Q_OBJECT public: CSound ( void ( *fpNewProcessCallback ) ( CVector& psData, void* arg ), void* arg, const QString& strMIDISetup, const bool, const QString& ); ~CSound(); virtual int Init ( const int iNewPrefMonoBufferSize ); virtual void Start(); virtual void Stop(); virtual void processBufferList ( AudioBufferList*, CSound* ); AudioUnit audioUnit; // these variables/functions should be protected but cannot since we want // to access them from the callback function CVector vecsTmpAudioSndCrdStereo; int iCoreAudioBufferSizeMono; int iCoreAudioBufferSizeStereo; bool isInitialized; protected: virtual QString LoadAndInitializeDriver ( QString strDriverName, bool ); void GetAvailableInOutDevices(); void SwitchDevice ( QString strDriverName ); AudioBuffer buffer; AudioBufferList bufferList; void checkStatus ( int status ); static OSStatus recordingCallback ( void* inRefCon, AudioUnitRenderActionFlags* ioActionFlags, const AudioTimeStamp* inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList* ioData ); QMutex Mutex; }; jamulus-3.9.1+dfsg/src/sound/soundbase.h0000644000175000017500000001364114340334543017234 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #include #include #include #ifndef HEADLESS # include #endif #include "../global.h" #include "../util.h" // TODO better solution with enum definition // problem: in signals it seems not to work to use CSoundBase::ESndCrdResetType enum ESndCrdResetType { RS_ONLY_RESTART = 1, RS_ONLY_RESTART_AND_INIT, RS_RELOAD_RESTART_AND_INIT }; enum EMidiCtlType { Fader = 0, Pan, Solo, Mute, MuteMyself, None }; class CMidiCtlEntry { public: CMidiCtlEntry ( EMidiCtlType eT = EMidiCtlType::None, int iC = 0 ) : eType ( eT ), iChannel ( iC ) {} EMidiCtlType eType; int iChannel; }; /* Classes ********************************************************************/ class CSoundBase : public QThread { Q_OBJECT public: CSoundBase ( const QString& strNewSystemDriverTechniqueName, void ( *fpNewProcessCallback ) ( CVector& psData, void* pParg ), void* pParg, const QString& strMIDISetup ); virtual int Init ( const int iNewPrefMonoBufferSize ) { return iNewPrefMonoBufferSize; } virtual void Start() { bRun = true; bCallbackEntered = false; } virtual void Stop(); // device selection QStringList GetDevNames(); QString SetDev ( const QString strDevName ); QString GetDev() { QMutexLocker locker ( &MutexDevProperties ); return strCurDevName; } virtual int GetNumInputChannels() { return 2; } virtual QString GetInputChannelName ( const int ) { return "Default"; } virtual void SetLeftInputChannel ( const int ) {} virtual void SetRightInputChannel ( const int ) {} virtual int GetLeftInputChannel() { return 0; } virtual int GetRightInputChannel() { return 1; } virtual int GetNumOutputChannels() { return 2; } virtual QString GetOutputChannelName ( const int ) { return "Default"; } virtual void SetLeftOutputChannel ( const int ) {} virtual void SetRightOutputChannel ( const int ) {} virtual int GetLeftOutputChannel() { return 0; } virtual int GetRightOutputChannel() { return 1; } virtual float GetInOutLatencyMs() { return 0.0f; } // "0.0" means no latency is available virtual void OpenDriverSetup() {} bool IsRunning() const { return bRun; } bool IsCallbackEntered() const { return bCallbackEntered; } // TODO this should be protected but since it is used // in a callback function it has to be public -> better solution void EmitReinitRequestSignal ( const ESndCrdResetType eSndCrdResetType ) { emit ReinitRequest ( eSndCrdResetType ); } protected: virtual QString LoadAndInitializeDriver ( QString, bool ) { return ""; } virtual void UnloadCurrentDriver() {} QVector LoadAndInitializeFirstValidDriver ( const bool bOpenDriverSetup = false ); void ParseCommandLineArgument ( const QString& strMIDISetup ); QString GetDeviceName ( const int iDiD ) { return strDriverNames[iDiD]; } static void GetSelCHAndAddCH ( const int iSelCH, const int iNumInChan, int& iSelCHOut, int& iSelAddCHOut ) { // we have a mixed channel setup, definitions: // - mixed channel setup only for 4 physical inputs: // SelCH == 4: Ch 0 + Ch 2 // SelCh == 5: Ch 0 + Ch 3 // SelCh == 6: Ch 1 + Ch 2 // SelCh == 7: Ch 1 + Ch 3 if ( iSelCH >= iNumInChan ) { iSelAddCHOut = ( ( iSelCH - iNumInChan ) % 2 ) + 2; iSelCHOut = ( iSelCH - iNumInChan ) / 2; } else { iSelAddCHOut = INVALID_INDEX; // set it to an invalid number iSelCHOut = iSelCH; } } // function pointer to callback function void ( *fpProcessCallback ) ( CVector& psData, void* arg ); void* pProcessCallbackArg; // callback function call for derived classes void ProcessCallback ( CVector& psData ) { bCallbackEntered = true; ( *fpProcessCallback ) ( psData, pProcessCallbackArg ); } void ParseMIDIMessage ( const CVector& vMIDIPaketBytes ); bool bRun; bool bCallbackEntered; QMutex MutexAudioProcessCallback; QMutex MutexDevProperties; QString strSystemDriverTechniqueName; int iCtrlMIDIChannel; QVector aMidiCtls; long lNumDevs; QString strCurDevName; QString strDriverNames[MAX_NUMBER_SOUND_CARDS]; signals: void ReinitRequest ( int iSndCrdResetType ); void ControllerInFaderLevel ( int iChannelIdx, int iValue ); void ControllerInPanValue ( int iChannelIdx, int iValue ); void ControllerInFaderIsSolo ( int iChannelIdx, bool bIsSolo ); void ControllerInFaderIsMute ( int iChannelIdx, bool bIsMute ); void ControllerInMuteMyself ( bool bMute ); }; jamulus-3.9.1+dfsg/src/sound/asio/0000755000175000017500000000000014340334543016026 5ustar vimervimerjamulus-3.9.1+dfsg/src/sound/asio/sound.cpp0000644000175000017500000014042114340334543017664 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * * Description: * Sound card interface for Windows operating systems * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include "sound.h" /* Implementation *************************************************************/ // external references extern AsioDrivers* asioDrivers; bool loadAsioDriver ( char* name ); // pointer to our sound object CSound* pSound; /******************************************************************************\ * Common * \******************************************************************************/ QString CSound::LoadAndInitializeDriver ( QString strDriverName, bool bOpenDriverSetup ) { // find and load driver int iDriverIdx = INVALID_INDEX; // initialize with an invalid index for ( int i = 0; i < MAX_NUMBER_SOUND_CARDS; i++ ) { if ( strDriverName.compare ( cDriverNames[i] ) == 0 ) { iDriverIdx = i; } } // if the selected driver was not found, return an error message if ( iDriverIdx == INVALID_INDEX ) { return tr ( "The selected audio device is no longer present in the system. Please check your audio device." ); } // Save number of channels from last driver // Need to save these (but not the driver name) as CheckDeviceCapabilities() overwrites them long lNumInChanPrev = lNumInChan; long lNumOutChanPrev = lNumOutChan; loadAsioDriver ( cDriverNames[iDriverIdx] ); // According to the docs, driverInfo.asioVersion and driverInfo.sysRef // should be set, but we haven't being doing that and it seems to work // okay... memset ( &driverInfo, 0, sizeof driverInfo ); if ( ASIOInit ( &driverInfo ) != ASE_OK ) { // clean up and return error string asioDrivers->removeCurrentDriver(); return tr ( "Couldn't initialise the audio driver. Check if your audio hardware is plugged in and verify your driver settings." ); } // check device capabilities if it fulfills our requirements const QString strStat = CheckDeviceCapabilities(); // also sets lNumInChan and lNumOutChan // check if device is capable if ( strStat.isEmpty() ) { // Reset channel mapping if the sound card name has changed or the number of channels has changed if ( ( strCurDevName.compare ( strDriverNames[iDriverIdx] ) != 0 ) || ( lNumInChanPrev != lNumInChan ) || ( lNumOutChanPrev != lNumOutChan ) ) { // In order to fix https://github.com/jamulussoftware/jamulus/issues/796 // this code runs after a change in the ASIO driver (not when changing the ASIO input selection.) // mapping to the defaults (first two available channels) ResetChannelMapping(); // store ID of selected driver if initialization was successful strCurDevName = cDriverNames[iDriverIdx]; } } else { // if requested, open ASIO driver setup in case of an error if ( bOpenDriverSetup ) { OpenDriverSetup(); QMessageBox::question ( nullptr, APP_NAME, "Are you done with your ASIO driver settings of " + GetDeviceName ( iDriverIdx ) + "?", QMessageBox::Yes ); } // driver cannot be used, clean up asioDrivers->removeCurrentDriver(); } return strStat; } void CSound::UnloadCurrentDriver() { // clean up ASIO stuff if ( bRun ) { Stop(); } if ( bufferInfos[0].buffers[0] ) { ASIODisposeBuffers(); bufferInfos[0].buffers[0] = NULL; } ASIOExit(); asioDrivers->removeCurrentDriver(); } QString CSound::CheckDeviceCapabilities() { // This function checks if our required input/output channel // properties are supported by the selected device. If the return // string is empty, the device can be used, otherwise the error // message is returned. // check the sample rate const ASIOError CanSaRateReturn = ASIOCanSampleRate ( SYSTEM_SAMPLE_RATE_HZ ); if ( ( CanSaRateReturn == ASE_NoClock ) || ( CanSaRateReturn == ASE_NotPresent ) ) { // return error string return QString ( tr ( "The selected audio device is incompatible " "since it doesn't support a sample rate of %1 Hz. Please select another " "device." ) ) .arg ( SYSTEM_SAMPLE_RATE_HZ ); } // check if sample rate can be set const ASIOError SetSaRateReturn = ASIOSetSampleRate ( SYSTEM_SAMPLE_RATE_HZ ); if ( ( SetSaRateReturn == ASE_NoClock ) || ( SetSaRateReturn == ASE_InvalidMode ) || ( SetSaRateReturn == ASE_NotPresent ) ) { // return error string return QString ( tr ( "The current audio device configuration is incompatible " "because the sample rate couldn't be set to %2 Hz. Please check for a hardware switch or " "driver setting to set the sample rate manually and restart %1." ) ) .arg ( APP_NAME ) .arg ( SYSTEM_SAMPLE_RATE_HZ ); } // check the number of available channels ASIOGetChannels ( &lNumInChan, &lNumOutChan ); if ( ( lNumInChan < NUM_IN_OUT_CHANNELS ) || ( lNumOutChan < NUM_IN_OUT_CHANNELS ) ) { // return error string return QString ( tr ( "The selected audio device is incompatible since it doesn't support " "%1 in/out channels. Please select another device or configuration." ) ) .arg ( NUM_IN_OUT_CHANNELS ); } // clip number of input/output channels to our maximum if ( lNumInChan > MAX_NUM_IN_OUT_CHANNELS ) { lNumInChan = MAX_NUM_IN_OUT_CHANNELS; } if ( lNumOutChan > MAX_NUM_IN_OUT_CHANNELS ) { lNumOutChan = MAX_NUM_IN_OUT_CHANNELS; } // query channel infos for all available input channels bool bInputChMixingSupported = true; for ( int i = 0; i < lNumInChan; i++ ) { // setup for input channels channelInfosInput[i].isInput = ASIOTrue; channelInfosInput[i].channel = i; ASIOGetChannelInfo ( &channelInfosInput[i] ); // Check supported sample formats. // Actually, it would be enough to have at least two channels which // support the required sample format. But since we have support for // all known sample types, the following check should always pass and // therefore we throw the error message on any channel which does not // fulfill the sample format requirement (quick hack solution). if ( !CheckSampleTypeSupported ( channelInfosInput[i].type ) ) { // return error string return tr ( "The selected audio device is incompatible since " "the required audio sample format isn't available. Please use another device." ); } // store the name of the channel and check if channel mixing is supported channelInputName[i] = channelInfosInput[i].name; if ( !CheckSampleTypeSupportedForCHMixing ( channelInfosInput[i].type ) ) { bInputChMixingSupported = false; } } // query channel infos for all available output channels for ( int i = 0; i < lNumOutChan; i++ ) { // setup for output channels channelInfosOutput[i].isInput = ASIOFalse; channelInfosOutput[i].channel = i; ASIOGetChannelInfo ( &channelInfosOutput[i] ); // Check supported sample formats. // Actually, it would be enough to have at least two channels which // support the required sample format. But since we have support for // all known sample types, the following check should always pass and // therefore we throw the error message on any channel which does not // fulfill the sample format requirement (quick hack solution). if ( !CheckSampleTypeSupported ( channelInfosOutput[i].type ) ) { // return error string return tr ( "The selected audio device is incompatible since " "the required audio sample format isn't available. Please use another device." ); } } // special case with 4 input channels: support adding channels if ( ( lNumInChan == 4 ) && bInputChMixingSupported ) { // add four mixed channels (i.e. 4 normal, 4 mixed channels) lNumInChanPlusAddChan = 8; for ( int iCh = 0; iCh < lNumInChanPlusAddChan; iCh++ ) { int iSelCH, iSelAddCH; GetSelCHAndAddCH ( iCh, lNumInChan, iSelCH, iSelAddCH ); if ( iSelAddCH >= 0 ) { // for mixed channels, show both audio channel names to be mixed channelInputName[iCh] = channelInputName[iSelCH] + " + " + channelInputName[iSelAddCH]; } } } else { // regular case: no mixing input channels used lNumInChanPlusAddChan = lNumInChan; } // everything is ok, return empty string for "no error" case return ""; } void CSound::SetLeftInputChannel ( const int iNewChan ) { // apply parameter after input parameter check if ( ( iNewChan >= 0 ) && ( iNewChan < lNumInChanPlusAddChan ) ) { vSelectedInputChannels[0] = iNewChan; } } void CSound::SetRightInputChannel ( const int iNewChan ) { // apply parameter after input parameter check if ( ( iNewChan >= 0 ) && ( iNewChan < lNumInChanPlusAddChan ) ) { vSelectedInputChannels[1] = iNewChan; } } void CSound::SetLeftOutputChannel ( const int iNewChan ) { // apply parameter after input parameter check if ( ( iNewChan >= 0 ) && ( iNewChan < lNumOutChan ) ) { vSelectedOutputChannels[0] = iNewChan; } } void CSound::SetRightOutputChannel ( const int iNewChan ) { // apply parameter after input parameter check if ( ( iNewChan >= 0 ) && ( iNewChan < lNumOutChan ) ) { vSelectedOutputChannels[1] = iNewChan; } } int CSound::GetActualBufferSize ( const int iDesiredBufferSizeMono ) { int iActualBufferSizeMono; // query the usable buffer sizes ASIOGetBufferSize ( &HWBufferInfo.lMinSize, &HWBufferInfo.lMaxSize, &HWBufferInfo.lPreferredSize, &HWBufferInfo.lGranularity ); //### TEST: BEGIN ###// /* #include QMessageBox::information ( 0, "APP_NAME", QString("lMinSize: %1, lMaxSize: %2, lPreferredSize: %3, lGranularity: %4"). arg(HWBufferInfo.lMinSize).arg(HWBufferInfo.lMaxSize).arg(HWBufferInfo.lPreferredSize).arg(HWBufferInfo.lGranularity) ); _exit(1); */ //### TEST: END ###// //### TODO: BEGIN ###// // see https://github.com/EddieRingle/portaudio/blob/master/src/hostapi/asio/pa_asio.cpp#L1654 // (SelectHostBufferSizeForUnspecifiedUserFramesPerBuffer) //### TODO: END ###// // calculate "nearest" buffer size and set internal parameter accordingly // first check minimum and maximum values if ( iDesiredBufferSizeMono <= HWBufferInfo.lMinSize ) { iActualBufferSizeMono = HWBufferInfo.lMinSize; } else { if ( iDesiredBufferSizeMono >= HWBufferInfo.lMaxSize ) { iActualBufferSizeMono = HWBufferInfo.lMaxSize; } else { // ASIO SDK 2.2: "Notes: When minimum and maximum buffer size are // equal, the preferred buffer size has to be the same value as // well; granularity should be 0 in this case." if ( HWBufferInfo.lMinSize == HWBufferInfo.lMaxSize ) { iActualBufferSizeMono = HWBufferInfo.lMinSize; } else { if ( ( HWBufferInfo.lGranularity < -1 ) || ( HWBufferInfo.lGranularity == 0 ) ) { // Special case (seen for EMU audio cards): granularity is // zero or less than zero (make sure to exclude the special // case of -1). // There is no definition of this case in the ASIO SDK // document. We assume here that all buffer sizes in between // minimum and maximum buffer sizes are allowed. iActualBufferSizeMono = iDesiredBufferSizeMono; } else { // General case -------------------------------------------- // initialization int iTrialBufSize = HWBufferInfo.lMinSize; int iLastTrialBufSize = HWBufferInfo.lMinSize; bool bSizeFound = false; // test loop while ( ( iTrialBufSize <= HWBufferInfo.lMaxSize ) && ( !bSizeFound ) ) { if ( iTrialBufSize >= iDesiredBufferSizeMono ) { // test which buffer size fits better: the old one or the // current one if ( ( iTrialBufSize - iDesiredBufferSizeMono ) > ( iDesiredBufferSizeMono - iLastTrialBufSize ) ) { iTrialBufSize = iLastTrialBufSize; } // exit while loop bSizeFound = true; } if ( !bSizeFound ) { // store old trial buffer size iLastTrialBufSize = iTrialBufSize; // increment trial buffer size (check for special // case first) if ( HWBufferInfo.lGranularity == -1 ) { // special case: buffer sizes are a power of 2 iTrialBufSize *= 2; } else { iTrialBufSize += HWBufferInfo.lGranularity; } } } // clip trial buffer size (it may happen in the while // routine that "iTrialBufSize" is larger than "lMaxSize" in // case "lMaxSize - lMinSize" is not divisible by the // granularity) if ( iTrialBufSize > HWBufferInfo.lMaxSize ) { iTrialBufSize = HWBufferInfo.lMaxSize; } // set ASIO buffer size iActualBufferSizeMono = iTrialBufSize; } } } } return iActualBufferSizeMono; } int CSound::Init ( const int iNewPrefMonoBufferSize ) { ASIOMutex.lock(); // get mutex lock { // get the actual sound card buffer size which is supported // by the audio hardware iASIOBufferSizeMono = GetActualBufferSize ( iNewPrefMonoBufferSize ); // init base class CSoundBase::Init ( iASIOBufferSizeMono ); // set internal buffer size value and calculate stereo buffer size iASIOBufferSizeStereo = 2 * iASIOBufferSizeMono; // set the sample rate ASIOSetSampleRate ( SYSTEM_SAMPLE_RATE_HZ ); // create memory for intermediate audio buffer vecsMultChanAudioSndCrd.Init ( iASIOBufferSizeStereo ); // create and activate ASIO buffers (buffer size in samples), // dispose old buffers (if any) ASIODisposeBuffers(); // prepare input channels for ( int i = 0; i < lNumInChan; i++ ) { bufferInfos[i].isInput = ASIOTrue; bufferInfos[i].channelNum = i; bufferInfos[i].buffers[0] = 0; bufferInfos[i].buffers[1] = 0; } // prepare output channels for ( int i = 0; i < lNumOutChan; i++ ) { bufferInfos[lNumInChan + i].isInput = ASIOFalse; bufferInfos[lNumInChan + i].channelNum = i; bufferInfos[lNumInChan + i].buffers[0] = 0; bufferInfos[lNumInChan + i].buffers[1] = 0; } ASIOCreateBuffers ( bufferInfos, lNumInChan + lNumOutChan, iASIOBufferSizeMono, &asioCallbacks ); // query the latency of the driver long lInputLatency = 0; long lOutputLatency = 0; if ( ASIOGetLatencies ( &lInputLatency, &lOutputLatency ) != ASE_NotPresent ) { // add the input and output latencies (returned in number of // samples) and calculate the time in ms fInOutLatencyMs = ( static_cast ( lInputLatency ) + lOutputLatency ) * 1000 / SYSTEM_SAMPLE_RATE_HZ; } else { // no latency available fInOutLatencyMs = 0.0f; } // check whether the driver requires the ASIOOutputReady() optimization // (can be used by the driver to reduce output latency by one block) bASIOPostOutput = ( ASIOOutputReady() == ASE_OK ); } ASIOMutex.unlock(); return iASIOBufferSizeMono; } void CSound::Start() { // start audio ASIOStart(); // call base class CSoundBase::Start(); } void CSound::Stop() { // stop audio ASIOStop(); // call base class CSoundBase::Stop(); // make sure the working thread is actually done // (by checking the locked state) if ( ASIOMutex.tryLock ( 5000 ) ) { ASIOMutex.unlock(); } } CSound::CSound ( void ( *fpNewCallback ) ( CVector& psData, void* arg ), void* arg, const QString& strMIDISetup, const bool, const QString& ) : CSoundBase ( "ASIO", fpNewCallback, arg, strMIDISetup ), lNumInChan ( 0 ), lNumInChanPlusAddChan ( 0 ), lNumOutChan ( 0 ), fInOutLatencyMs ( 0.0f ), // "0.0" means that no latency value is available vSelectedInputChannels ( NUM_IN_OUT_CHANNELS ), vSelectedOutputChannels ( NUM_IN_OUT_CHANNELS ) { int i; // init pointer to our sound object pSound = this; // We assume NULL'd pointers in this structure indicate that buffers are not // allocated yet (see UnloadCurrentDriver). memset ( bufferInfos, 0, sizeof bufferInfos ); // get available ASIO driver names in system for ( i = 0; i < MAX_NUMBER_SOUND_CARDS; i++ ) { // allocate memory for driver names cDriverNames[i] = new char[32]; } char cDummyName[] = "dummy"; loadAsioDriver ( cDummyName ); // to initialize external object lNumDevs = asioDrivers->getDriverNames ( cDriverNames, MAX_NUMBER_SOUND_CARDS ); // in case we do not have a driver available, throw error if ( lNumDevs == 0 ) { throw CGenErr ( "" + tr ( "No ASIO audio device driver found." ) + "

" + QString ( tr ( "Please install an ASIO driver before running %1. " "If you own a device with ASIO support, install its official ASIO driver. " "If not, you'll need to install a universal driver like ASIO4ALL." ) ) .arg ( APP_NAME ) ); } asioDrivers->removeCurrentDriver(); // copy driver names to base class but internally we still have to use // the char* variable because of the ASIO API :-( for ( i = 0; i < lNumDevs; i++ ) { strDriverNames[i] = cDriverNames[i]; } // init device index as not initialized (invalid) strCurDevName = ""; // init channel mapping ResetChannelMapping(); // set up the asioCallback structure asioCallbacks.bufferSwitch = &bufferSwitch; asioCallbacks.sampleRateDidChange = &sampleRateChanged; asioCallbacks.asioMessage = &asioMessages; asioCallbacks.bufferSwitchTimeInfo = &bufferSwitchTimeInfo; } void CSound::ResetChannelMapping() { // init selected channel numbers with defaults: use first available // channels for input and output vSelectedInputChannels[0] = 0; vSelectedInputChannels[1] = 1; vSelectedOutputChannels[0] = 0; vSelectedOutputChannels[1] = 1; } // ASIO callbacks ------------------------------------------------------------- ASIOTime* CSound::bufferSwitchTimeInfo ( ASIOTime*, long index, ASIOBool processNow ) { bufferSwitch ( index, processNow ); return 0L; } bool CSound::CheckSampleTypeSupported ( const ASIOSampleType SamType ) { // check for supported sample types return ( ( SamType == ASIOSTInt16LSB ) || ( SamType == ASIOSTInt24LSB ) || ( SamType == ASIOSTInt32LSB ) || ( SamType == ASIOSTFloat32LSB ) || ( SamType == ASIOSTFloat64LSB ) || ( SamType == ASIOSTInt32LSB16 ) || ( SamType == ASIOSTInt32LSB18 ) || ( SamType == ASIOSTInt32LSB20 ) || ( SamType == ASIOSTInt32LSB24 ) || ( SamType == ASIOSTInt16MSB ) || ( SamType == ASIOSTInt24MSB ) || ( SamType == ASIOSTInt32MSB ) || ( SamType == ASIOSTFloat32MSB ) || ( SamType == ASIOSTFloat64MSB ) || ( SamType == ASIOSTInt32MSB16 ) || ( SamType == ASIOSTInt32MSB18 ) || ( SamType == ASIOSTInt32MSB20 ) || ( SamType == ASIOSTInt32MSB24 ) ); } bool CSound::CheckSampleTypeSupportedForCHMixing ( const ASIOSampleType SamType ) { // check for supported sample types for audio channel mixing (see bufferSwitch) return ( ( SamType == ASIOSTInt16LSB ) || ( SamType == ASIOSTInt24LSB ) || ( SamType == ASIOSTInt32LSB ) ); } void CSound::bufferSwitch ( long index, ASIOBool ) { int iCurSample; // get references to class members int& iASIOBufferSizeMono = pSound->iASIOBufferSizeMono; CVector& vecsMultChanAudioSndCrd = pSound->vecsMultChanAudioSndCrd; // perform the processing for input and output pSound->ASIOMutex.lock(); // get mutex lock { // CAPTURE ------------------------------------------------------------- for ( int i = 0; i < NUM_IN_OUT_CHANNELS; i++ ) { int iSelCH, iSelAddCH; GetSelCHAndAddCH ( pSound->vSelectedInputChannels[i], pSound->lNumInChan, iSelCH, iSelAddCH ); // copy new captured block in thread transfer buffer (copy // mono data interleaved in stereo buffer) switch ( pSound->channelInfosInput[iSelCH].type ) { case ASIOSTInt16LSB: { // no type conversion required, just copy operation int16_t* pASIOBuf = static_cast ( pSound->bufferInfos[iSelCH].buffers[index] ); for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { vecsMultChanAudioSndCrd[2 * iCurSample + i] = pASIOBuf[iCurSample]; } if ( iSelAddCH >= 0 ) { // mix input channels case: int16_t* pASIOBufAdd = static_cast ( pSound->bufferInfos[iSelAddCH].buffers[index] ); for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { vecsMultChanAudioSndCrd[2 * iCurSample + i] = Float2Short ( (float) vecsMultChanAudioSndCrd[2 * iCurSample + i] + (float) pASIOBufAdd[iCurSample] ); } } break; } case ASIOSTInt24LSB: for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { int iCurSam = 0; memcpy ( &iCurSam, ( (char*) pSound->bufferInfos[iSelCH].buffers[index] ) + iCurSample * 3, 3 ); iCurSam >>= 8; vecsMultChanAudioSndCrd[2 * iCurSample + i] = static_cast ( iCurSam ); } if ( iSelAddCH >= 0 ) { // mix input channels case: for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { int iCurSam = 0; memcpy ( &iCurSam, ( (char*) pSound->bufferInfos[iSelAddCH].buffers[index] ) + iCurSample * 3, 3 ); iCurSam >>= 8; vecsMultChanAudioSndCrd[2 * iCurSample + i] = Float2Short ( (float) vecsMultChanAudioSndCrd[2 * iCurSample + i] + (float) static_cast ( iCurSam ) ); } } break; case ASIOSTInt32LSB: { int32_t* pASIOBuf = static_cast ( pSound->bufferInfos[iSelCH].buffers[index] ); for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { vecsMultChanAudioSndCrd[2 * iCurSample + i] = static_cast ( pASIOBuf[iCurSample] >> 16 ); } if ( iSelAddCH >= 0 ) { // mix input channels case: int32_t* pASIOBufAdd = static_cast ( pSound->bufferInfos[iSelAddCH].buffers[index] ); for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { vecsMultChanAudioSndCrd[2 * iCurSample + i] = Float2Short ( (float) vecsMultChanAudioSndCrd[2 * iCurSample + i] + (float) static_cast ( pASIOBufAdd[iCurSample] >> 16 ) ); } } break; } case ASIOSTFloat32LSB: // IEEE 754 32 bit float, as found on Intel x86 architecture // clang-format off // NOT YET TESTED // clang-format on for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { vecsMultChanAudioSndCrd[2 * iCurSample + i] = static_cast ( static_cast ( pSound->bufferInfos[iSelCH].buffers[index] )[iCurSample] * _MAXSHORT ); } break; case ASIOSTFloat64LSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture // clang-format off // NOT YET TESTED // clang-format on for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { vecsMultChanAudioSndCrd[2 * iCurSample + i] = static_cast ( static_cast ( pSound->bufferInfos[iSelCH].buffers[index] )[iCurSample] * _MAXSHORT ); } break; case ASIOSTInt32LSB16: // 32 bit data with 16 bit alignment // clang-format off // NOT YET TESTED // clang-format on for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { vecsMultChanAudioSndCrd[2 * iCurSample + i] = static_cast ( static_cast ( pSound->bufferInfos[iSelCH].buffers[index] )[iCurSample] & 0xFFFF ); } break; case ASIOSTInt32LSB18: // 32 bit data with 18 bit alignment // clang-format off // NOT YET TESTED // clang-format on for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { vecsMultChanAudioSndCrd[2 * iCurSample + i] = static_cast ( ( static_cast ( pSound->bufferInfos[iSelCH].buffers[index] )[iCurSample] & 0x3FFFF ) >> 2 ); } break; case ASIOSTInt32LSB20: // 32 bit data with 20 bit alignment // clang-format off // NOT YET TESTED // clang-format on for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { vecsMultChanAudioSndCrd[2 * iCurSample + i] = static_cast ( ( static_cast ( pSound->bufferInfos[iSelCH].buffers[index] )[iCurSample] & 0xFFFFF ) >> 4 ); } break; case ASIOSTInt32LSB24: // 32 bit data with 24 bit alignment // clang-format off // NOT YET TESTED // clang-format on for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { vecsMultChanAudioSndCrd[2 * iCurSample + i] = static_cast ( ( static_cast ( pSound->bufferInfos[iSelCH].buffers[index] )[iCurSample] & 0xFFFFFF ) >> 8 ); } break; case ASIOSTInt16MSB: // clang-format off // NOT YET TESTED // clang-format on // flip bits for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { vecsMultChanAudioSndCrd[2 * iCurSample + i] = Flip16Bits ( ( static_cast ( pSound->bufferInfos[iSelCH].buffers[index] ) )[iCurSample] ); } break; case ASIOSTInt24MSB: // clang-format off // NOT YET TESTED // clang-format on for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { // because the bits are flipped, we do not have to perform the // shift by 8 bits int iCurSam = 0; memcpy ( &iCurSam, ( (char*) pSound->bufferInfos[iSelCH].buffers[index] ) + iCurSample * 3, 3 ); vecsMultChanAudioSndCrd[2 * iCurSample + i] = Flip16Bits ( static_cast ( iCurSam ) ); } break; case ASIOSTInt32MSB: // clang-format off // NOT YET TESTED // clang-format on for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { // flip bits and convert to 16 bit vecsMultChanAudioSndCrd[2 * iCurSample + i] = static_cast ( Flip32Bits ( static_cast ( pSound->bufferInfos[iSelCH].buffers[index] )[iCurSample] ) >> 16 ); } break; case ASIOSTFloat32MSB: // IEEE 754 32 bit float, as found on Intel x86 architecture // clang-format off // NOT YET TESTED // clang-format on for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { vecsMultChanAudioSndCrd[2 * iCurSample + i] = static_cast ( static_cast ( Flip32Bits ( static_cast ( pSound->bufferInfos[iSelCH].buffers[index] )[iCurSample] ) ) * _MAXSHORT ); } break; case ASIOSTFloat64MSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture // clang-format off // NOT YET TESTED // clang-format on for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { vecsMultChanAudioSndCrd[2 * iCurSample + i] = static_cast ( static_cast ( Flip64Bits ( static_cast ( pSound->bufferInfos[iSelCH].buffers[index] )[iCurSample] ) ) * _MAXSHORT ); } break; case ASIOSTInt32MSB16: // 32 bit data with 16 bit alignment // clang-format off // NOT YET TESTED // clang-format on for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { vecsMultChanAudioSndCrd[2 * iCurSample + i] = static_cast ( Flip32Bits ( static_cast ( pSound->bufferInfos[iSelCH].buffers[index] )[iCurSample] ) & 0xFFFF ); } break; case ASIOSTInt32MSB18: // 32 bit data with 18 bit alignment // clang-format off // NOT YET TESTED // clang-format on for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { vecsMultChanAudioSndCrd[2 * iCurSample + i] = static_cast ( ( Flip32Bits ( static_cast ( pSound->bufferInfos[iSelCH].buffers[index] )[iCurSample] ) & 0x3FFFF ) >> 2 ); } break; case ASIOSTInt32MSB20: // 32 bit data with 20 bit alignment // clang-format off // NOT YET TESTED // clang-format on for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { vecsMultChanAudioSndCrd[2 * iCurSample + i] = static_cast ( ( Flip32Bits ( static_cast ( pSound->bufferInfos[iSelCH].buffers[index] )[iCurSample] ) & 0xFFFFF ) >> 4 ); } break; case ASIOSTInt32MSB24: // 32 bit data with 24 bit alignment // clang-format off // NOT YET TESTED // clang-format on for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { vecsMultChanAudioSndCrd[2 * iCurSample + i] = static_cast ( ( Flip32Bits ( static_cast ( pSound->bufferInfos[iSelCH].buffers[index] )[iCurSample] ) & 0xFFFFFF ) >> 8 ); } break; } } // call processing callback function pSound->ProcessCallback ( vecsMultChanAudioSndCrd ); // PLAYBACK ------------------------------------------------------------ for ( int i = 0; i < NUM_IN_OUT_CHANNELS; i++ ) { const int iSelCH = pSound->lNumInChan + pSound->vSelectedOutputChannels[i]; // copy data from sound card in output buffer (copy // interleaved stereo data in mono sound card buffer) switch ( pSound->channelInfosOutput[pSound->vSelectedOutputChannels[i]].type ) { case ASIOSTInt16LSB: { // no type conversion required, just copy operation int16_t* pASIOBuf = static_cast ( pSound->bufferInfos[iSelCH].buffers[index] ); for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { pASIOBuf[iCurSample] = vecsMultChanAudioSndCrd[2 * iCurSample + i]; } break; } case ASIOSTInt24LSB: // clang-format off // NOT YET TESTED // clang-format on for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { // convert current sample in 24 bit format int32_t iCurSam = static_cast ( vecsMultChanAudioSndCrd[2 * iCurSample + i] ); iCurSam <<= 8; memcpy ( ( (char*) pSound->bufferInfos[iSelCH].buffers[index] ) + iCurSample * 3, &iCurSam, 3 ); } break; case ASIOSTInt32LSB: { int32_t* pASIOBuf = static_cast ( pSound->bufferInfos[iSelCH].buffers[index] ); for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { // convert to 32 bit const int32_t iCurSam = static_cast ( vecsMultChanAudioSndCrd[2 * iCurSample + i] ); pASIOBuf[iCurSample] = ( iCurSam << 16 ); } break; } case ASIOSTFloat32LSB: // IEEE 754 32 bit float, as found on Intel x86 architecture // clang-format off // NOT YET TESTED // clang-format on for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { const float fCurSam = static_cast ( vecsMultChanAudioSndCrd[2 * iCurSample + i] ); static_cast ( pSound->bufferInfos[iSelCH].buffers[index] )[iCurSample] = fCurSam / _MAXSHORT; } break; case ASIOSTFloat64LSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture // clang-format off // NOT YET TESTED // clang-format on for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { const double fCurSam = static_cast ( vecsMultChanAudioSndCrd[2 * iCurSample + i] ); static_cast ( pSound->bufferInfos[iSelCH].buffers[index] )[iCurSample] = fCurSam / _MAXSHORT; } break; case ASIOSTInt32LSB16: // 32 bit data with 16 bit alignment // clang-format off // NOT YET TESTED // clang-format on for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { // convert to 32 bit const int32_t iCurSam = static_cast ( vecsMultChanAudioSndCrd[2 * iCurSample + i] ); static_cast ( pSound->bufferInfos[iSelCH].buffers[index] )[iCurSample] = iCurSam; } break; case ASIOSTInt32LSB18: // 32 bit data with 18 bit alignment // clang-format off // NOT YET TESTED // clang-format on for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { // convert to 32 bit const int32_t iCurSam = static_cast ( vecsMultChanAudioSndCrd[2 * iCurSample + i] ); static_cast ( pSound->bufferInfos[iSelCH].buffers[index] )[iCurSample] = ( iCurSam << 2 ); } break; case ASIOSTInt32LSB20: // 32 bit data with 20 bit alignment // clang-format off // NOT YET TESTED // clang-format on for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { // convert to 32 bit const int32_t iCurSam = static_cast ( vecsMultChanAudioSndCrd[2 * iCurSample + i] ); static_cast ( pSound->bufferInfos[iSelCH].buffers[index] )[iCurSample] = ( iCurSam << 4 ); } break; case ASIOSTInt32LSB24: // 32 bit data with 24 bit alignment // clang-format off // NOT YET TESTED // clang-format on for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { // convert to 32 bit const int32_t iCurSam = static_cast ( vecsMultChanAudioSndCrd[2 * iCurSample + i] ); static_cast ( pSound->bufferInfos[iSelCH].buffers[index] )[iCurSample] = ( iCurSam << 8 ); } break; case ASIOSTInt16MSB: // clang-format off // NOT YET TESTED // clang-format on // flip bits for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { ( (int16_t*) pSound->bufferInfos[iSelCH].buffers[index] )[iCurSample] = Flip16Bits ( vecsMultChanAudioSndCrd[2 * iCurSample + i] ); } break; case ASIOSTInt24MSB: // clang-format off // NOT YET TESTED // clang-format on for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { // because the bits are flipped, we do not have to perform the // shift by 8 bits int32_t iCurSam = static_cast ( Flip16Bits ( vecsMultChanAudioSndCrd[2 * iCurSample + i] ) ); memcpy ( ( (char*) pSound->bufferInfos[iSelCH].buffers[index] ) + iCurSample * 3, &iCurSam, 3 ); } break; case ASIOSTInt32MSB: // clang-format off // NOT YET TESTED // clang-format on for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { // convert to 32 bit and flip bits int iCurSam = static_cast ( vecsMultChanAudioSndCrd[2 * iCurSample + i] ); static_cast ( pSound->bufferInfos[iSelCH].buffers[index] )[iCurSample] = Flip32Bits ( iCurSam << 16 ); } break; case ASIOSTFloat32MSB: // IEEE 754 32 bit float, as found on Intel x86 architecture // clang-format off // NOT YET TESTED // clang-format on for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { const float fCurSam = static_cast ( vecsMultChanAudioSndCrd[2 * iCurSample + i] ); static_cast ( pSound->bufferInfos[iSelCH].buffers[index] )[iCurSample] = static_cast ( Flip32Bits ( static_cast ( fCurSam / _MAXSHORT ) ) ); } break; case ASIOSTFloat64MSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture // clang-format off // NOT YET TESTED // clang-format on for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { const double fCurSam = static_cast ( vecsMultChanAudioSndCrd[2 * iCurSample + i] ); static_cast ( pSound->bufferInfos[iSelCH].buffers[index] )[iCurSample] = static_cast ( Flip64Bits ( static_cast ( fCurSam / _MAXSHORT ) ) ); } break; case ASIOSTInt32MSB16: // 32 bit data with 16 bit alignment // clang-format off // NOT YET TESTED // clang-format on for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { // convert to 32 bit const int32_t iCurSam = static_cast ( vecsMultChanAudioSndCrd[2 * iCurSample + i] ); static_cast ( pSound->bufferInfos[iSelCH].buffers[index] )[iCurSample] = Flip32Bits ( iCurSam ); } break; case ASIOSTInt32MSB18: // 32 bit data with 18 bit alignment // clang-format off // NOT YET TESTED // clang-format on for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { // convert to 32 bit const int32_t iCurSam = static_cast ( vecsMultChanAudioSndCrd[2 * iCurSample + i] ); static_cast ( pSound->bufferInfos[iSelCH].buffers[index] )[iCurSample] = Flip32Bits ( iCurSam << 2 ); } break; case ASIOSTInt32MSB20: // 32 bit data with 20 bit alignment // clang-format off // NOT YET TESTED // clang-format on for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { // convert to 32 bit const int32_t iCurSam = static_cast ( vecsMultChanAudioSndCrd[2 * iCurSample + i] ); static_cast ( pSound->bufferInfos[iSelCH].buffers[index] )[iCurSample] = Flip32Bits ( iCurSam << 4 ); } break; case ASIOSTInt32MSB24: // 32 bit data with 24 bit alignment // clang-format off // NOT YET TESTED // clang-format on for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ ) { // convert to 32 bit const int32_t iCurSam = static_cast ( vecsMultChanAudioSndCrd[2 * iCurSample + i] ); static_cast ( pSound->bufferInfos[iSelCH].buffers[index] )[iCurSample] = Flip32Bits ( iCurSam << 8 ); } break; } } // Finally if the driver supports the ASIOOutputReady() optimization, // do it here, all data are in place ----------------------------------- if ( pSound->bASIOPostOutput ) { ASIOOutputReady(); } } pSound->ASIOMutex.unlock(); } long CSound::asioMessages ( long selector, long, void*, double* ) { long ret = 0; switch ( selector ) { case kAsioEngineVersion: // return the supported ASIO version of the host application ret = 2L; // Host ASIO implementation version, 2 or higher break; // both messages might be send if the buffer size changes case kAsioBufferSizeChange: pSound->EmitReinitRequestSignal ( RS_ONLY_RESTART_AND_INIT ); ret = 1L; // 1L if request is accepted or 0 otherwise break; case kAsioResetRequest: pSound->EmitReinitRequestSignal ( RS_RELOAD_RESTART_AND_INIT ); ret = 1L; // 1L if request is accepted or 0 otherwise break; } return ret; } int16_t CSound::Flip16Bits ( const int16_t iIn ) { uint16_t iMask = ( 1 << 15 ); int16_t iOut = 0; for ( unsigned int i = 0; i < 16; i++ ) { // copy current bit to correct position iOut |= ( iIn & iMask ) ? 1 : 0; // shift out value and mask by one bit iOut <<= 1; iMask >>= 1; } return iOut; } int32_t CSound::Flip32Bits ( const int32_t iIn ) { uint32_t iMask = ( static_cast ( 1 ) << 31 ); int32_t iOut = 0; for ( unsigned int i = 0; i < 32; i++ ) { // copy current bit to correct position iOut |= ( iIn & iMask ) ? 1 : 0; // shift out value and mask by one bit iOut <<= 1; iMask >>= 1; } return iOut; } int64_t CSound::Flip64Bits ( const int64_t iIn ) { uint64_t iMask = ( static_cast ( 1 ) << 63 ); int64_t iOut = 0; for ( unsigned int i = 0; i < 64; i++ ) { // copy current bit to correct position iOut |= ( iIn & iMask ) ? 1 : 0; // shift out value and mask by one bit iOut <<= 1; iMask >>= 1; } return iOut; } jamulus-3.9.1+dfsg/src/sound/asio/sound.h0000644000175000017500000001262414340334543017334 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #include #include #include "../../util.h" #include "../../global.h" #include "../soundbase.h" // The following includes require the ASIO SDK to be placed in // libs/ASIOSDK2 during build. // Important: // - Do not copy parts of ASIO SDK into the Jamulus source tree without // further consideration as it would make the license situation more // complicated. // - When building yourself, read and understand the // Steinberg ASIO SDK Licensing Agreement and verify whether you might be // obliged to sign it as well, especially when considering distribution // of Jamulus Windows binaries with ASIO support. #include "asiosys.h" #include "asio.h" #include "asiodrivers.h" /* Definitions ****************************************************************/ // stereo for input and output #define NUM_IN_OUT_CHANNELS 2 /* Classes ********************************************************************/ class CSound : public CSoundBase { Q_OBJECT public: CSound ( void ( *fpNewCallback ) ( CVector& psData, void* arg ), void* arg, const QString& strMIDISetup, const bool, const QString& ); virtual ~CSound() { UnloadCurrentDriver(); } virtual int Init ( const int iNewPrefMonoBufferSize ); virtual void Start(); virtual void Stop(); virtual void OpenDriverSetup() { ASIOControlPanel(); } // channel selection virtual int GetNumInputChannels() { return static_cast ( lNumInChanPlusAddChan ); } virtual QString GetInputChannelName ( const int iDiD ) { return channelInputName[iDiD]; } virtual void SetLeftInputChannel ( const int iNewChan ); virtual void SetRightInputChannel ( const int iNewChan ); virtual int GetLeftInputChannel() { return vSelectedInputChannels[0]; } virtual int GetRightInputChannel() { return vSelectedInputChannels[1]; } virtual int GetNumOutputChannels() { return static_cast ( lNumOutChan ); } virtual QString GetOutputChannelName ( const int iDiD ) { return channelInfosOutput[iDiD].name; } virtual void SetLeftOutputChannel ( const int iNewChan ); virtual void SetRightOutputChannel ( const int iNewChan ); virtual int GetLeftOutputChannel() { return vSelectedOutputChannels[0]; } virtual int GetRightOutputChannel() { return vSelectedOutputChannels[1]; } virtual float GetInOutLatencyMs() { return fInOutLatencyMs; } protected: virtual QString LoadAndInitializeDriver ( QString strDriverName, bool bOpenDriverSetup ); virtual void UnloadCurrentDriver(); int GetActualBufferSize ( const int iDesiredBufferSizeMono ); QString CheckDeviceCapabilities(); bool CheckSampleTypeSupported ( const ASIOSampleType SamType ); bool CheckSampleTypeSupportedForCHMixing ( const ASIOSampleType SamType ); void ResetChannelMapping(); int iASIOBufferSizeMono; int iASIOBufferSizeStereo; long lNumInChan; long lNumInChanPlusAddChan; // includes additional "added" channels long lNumOutChan; float fInOutLatencyMs; CVector vSelectedInputChannels; CVector vSelectedOutputChannels; CVector vecsMultChanAudioSndCrd; QMutex ASIOMutex; // utility functions static int16_t Flip16Bits ( const int16_t iIn ); static int32_t Flip32Bits ( const int32_t iIn ); static int64_t Flip64Bits ( const int64_t iIn ); // audio hardware buffer info struct sHWBufferInfo { long lMinSize; long lMaxSize; long lPreferredSize; long lGranularity; } HWBufferInfo; // ASIO stuff ASIODriverInfo driverInfo; ASIOBufferInfo bufferInfos[2 * MAX_NUM_IN_OUT_CHANNELS]; // for input and output buffers -> "2 *" ASIOChannelInfo channelInfosInput[MAX_NUM_IN_OUT_CHANNELS]; QString channelInputName[MAX_NUM_IN_OUT_CHANNELS]; ASIOChannelInfo channelInfosOutput[MAX_NUM_IN_OUT_CHANNELS]; bool bASIOPostOutput; ASIOCallbacks asioCallbacks; // callbacks static void bufferSwitch ( long index, ASIOBool processNow ); static ASIOTime* bufferSwitchTimeInfo ( ASIOTime* timeInfo, long index, ASIOBool processNow ); static void sampleRateChanged ( ASIOSampleRate ) {} static long asioMessages ( long selector, long value, void* message, double* opt ); char* cDriverNames[MAX_NUMBER_SOUND_CARDS]; }; jamulus-3.9.1+dfsg/src/sound/README.md0000644000175000017500000000027414340334543016355 0ustar vimervimer# Sound APIs and Sound API related files This folder contains the related files for all sound APIs. ## Documentation of sound design **Fixme:** The sound design is not yet documented. jamulus-3.9.1+dfsg/src/settings.cpp0000644000175000017500000011051614340334543016313 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include "settings.h" /* Implementation *************************************************************/ void CSettings::Load ( const QList CommandLineOptions ) { // prepare file name for loading initialization data from XML file and read // data from file if possible QDomDocument IniXMLDocument; ReadFromFile ( strFileName, IniXMLDocument ); // read the settings from the given XML file ReadSettingsFromXML ( IniXMLDocument, CommandLineOptions ); } void CSettings::Save() { // create XML document for storing initialization parameters QDomDocument IniXMLDocument; // write the settings in the XML file WriteSettingsToXML ( IniXMLDocument ); // prepare file name for storing initialization data in XML file and store // XML data in file WriteToFile ( strFileName, IniXMLDocument ); } void CSettings::ReadFromFile ( const QString& strCurFileName, QDomDocument& XMLDocument ) { QFile file ( strCurFileName ); if ( file.open ( QIODevice::ReadOnly ) ) { XMLDocument.setContent ( QTextStream ( &file ).readAll(), false ); file.close(); } } void CSettings::WriteToFile ( const QString& strCurFileName, const QDomDocument& XMLDocument ) { QFile file ( strCurFileName ); if ( file.open ( QIODevice::WriteOnly ) ) { QTextStream ( &file ) << XMLDocument.toString(); file.close(); } } void CSettings::SetFileName ( const QString& sNFiName, const QString& sDefaultFileName ) { // return the file name with complete path, take care if given file name is empty strFileName = sNFiName; if ( strFileName.isEmpty() ) { // we use the Qt default setting file paths for the different OSs by // utilizing the QSettings class const QString sConfigDir = QFileInfo ( QSettings ( QSettings::IniFormat, QSettings::UserScope, APP_NAME, APP_NAME ).fileName() ).absolutePath(); // make sure the directory exists if ( !QFile::exists ( sConfigDir ) ) { QDir().mkpath ( sConfigDir ); } // append the actual file name strFileName = sConfigDir + "/" + sDefaultFileName; } } void CSettings::SetNumericIniSet ( QDomDocument& xmlFile, const QString& strSection, const QString& strKey, const int iValue ) { // convert input parameter which is an integer to string and store PutIniSetting ( xmlFile, strSection, strKey, QString::number ( iValue ) ); } bool CSettings::GetNumericIniSet ( const QDomDocument& xmlFile, const QString& strSection, const QString& strKey, const int iRangeStart, const int iRangeStop, int& iValue ) { // init return value bool bReturn = false; const QString strGetIni = GetIniSetting ( xmlFile, strSection, strKey ); // check if it is a valid parameter if ( !strGetIni.isEmpty() ) { // convert string from init file to integer iValue = strGetIni.toInt(); // check range if ( ( iValue >= iRangeStart ) && ( iValue <= iRangeStop ) ) { bReturn = true; } } return bReturn; } void CSettings::SetFlagIniSet ( QDomDocument& xmlFile, const QString& strSection, const QString& strKey, const bool bValue ) { // we encode true -> "1" and false -> "0" PutIniSetting ( xmlFile, strSection, strKey, bValue ? "1" : "0" ); } bool CSettings::GetFlagIniSet ( const QDomDocument& xmlFile, const QString& strSection, const QString& strKey, bool& bValue ) { // init return value bool bReturn = false; const QString strGetIni = GetIniSetting ( xmlFile, strSection, strKey ); if ( !strGetIni.isEmpty() ) { bValue = ( strGetIni.toInt() != 0 ); bReturn = true; } return bReturn; } // Init-file routines using XML *********************************************** QString CSettings::GetIniSetting ( const QDomDocument& xmlFile, const QString& sSection, const QString& sKey, const QString& sDefaultVal ) { // init return parameter with default value QString sResult ( sDefaultVal ); // get section QDomElement xmlSection = xmlFile.firstChildElement ( sSection ); if ( !xmlSection.isNull() ) { // get key QDomElement xmlKey = xmlSection.firstChildElement ( sKey ); if ( !xmlKey.isNull() ) { // get value sResult = xmlKey.text(); } } return sResult; } void CSettings::PutIniSetting ( QDomDocument& xmlFile, const QString& sSection, const QString& sKey, const QString& sValue ) { // check if section is already there, if not then create it QDomElement xmlSection = xmlFile.firstChildElement ( sSection ); if ( xmlSection.isNull() ) { // create new root element and add to document xmlSection = xmlFile.createElement ( sSection ); xmlFile.appendChild ( xmlSection ); } // check if key is already there, if not then create it QDomElement xmlKey = xmlSection.firstChildElement ( sKey ); if ( xmlKey.isNull() ) { xmlKey = xmlFile.createElement ( sKey ); xmlSection.appendChild ( xmlKey ); } // add actual data to the key QDomText currentValue = xmlFile.createTextNode ( sValue ); xmlKey.appendChild ( currentValue ); } #ifndef SERVER_ONLY // Client settings ------------------------------------------------------------- void CClientSettings::LoadFaderSettings ( const QString& strCurFileName ) { // prepare file name for loading initialization data from XML file and read // data from file if possible QDomDocument IniXMLDocument; ReadFromFile ( strCurFileName, IniXMLDocument ); // read the settings from the given XML file ReadFaderSettingsFromXML ( IniXMLDocument ); } void CClientSettings::SaveFaderSettings ( const QString& strCurFileName ) { // create XML document for storing initialization parameters QDomDocument IniXMLDocument; // write the settings in the XML file WriteFaderSettingsToXML ( IniXMLDocument ); // prepare file name for storing initialization data in XML file and store // XML data in file WriteToFile ( strCurFileName, IniXMLDocument ); } void CClientSettings::ReadSettingsFromXML ( const QDomDocument& IniXMLDocument, const QList& CommandLineOptions ) { int iIdx; int iValue; bool bValue; bCleanUpLegacyFaderSettings = CommandLineOptions.contains ( "--cleanuplegacyfadersettings" ); // IP addresses for ( iIdx = 0; iIdx < MAX_NUM_SERVER_ADDR_ITEMS; iIdx++ ) { vstrIPAddress[iIdx] = GetIniSetting ( IniXMLDocument, "client", QString ( "ipaddress%1" ).arg ( iIdx ), "" ); } // new client level if ( GetNumericIniSet ( IniXMLDocument, "client", "newclientlevel", 0, 100, iValue ) ) { iNewClientFaderLevel = iValue; } // input boost if ( GetNumericIniSet ( IniXMLDocument, "client", "inputboost", 1, 10, iValue ) ) { iInputBoost = iValue; } if ( GetFlagIniSet ( IniXMLDocument, "client", "enablefeedbackdetection", bValue ) ) { bEnableFeedbackDetection = bValue; } // connect dialog show all musicians if ( GetFlagIniSet ( IniXMLDocument, "client", "connectdlgshowallmusicians", bValue ) ) { bConnectDlgShowAllMusicians = bValue; } // language strLanguage = GetIniSetting ( IniXMLDocument, "client", "language", CLocale::FindSysLangTransFileName ( CLocale::GetAvailableTranslations() ).first ); // fader channel sorting if ( GetNumericIniSet ( IniXMLDocument, "client", "channelsort", 0, 4 /* ST_BY_CITY */, iValue ) ) { eChannelSortType = static_cast ( iValue ); } // own fader first sorting if ( GetFlagIniSet ( IniXMLDocument, "client", "ownfaderfirst", bValue ) ) { bOwnFaderFirst = bValue; } // number of mixer panel rows if ( GetNumericIniSet ( IniXMLDocument, "client", "numrowsmixpan", 1, 8, iValue ) ) { iNumMixerPanelRows = iValue; } // audio alerts if ( GetFlagIniSet ( IniXMLDocument, "client", "enableaudioalerts", bValue ) ) { bEnableAudioAlerts = bValue; } // name pClient->ChannelInfo.strName = FromBase64ToString ( GetIniSetting ( IniXMLDocument, "client", "name_base64", ToBase64 ( QCoreApplication::translate ( "CMusProfDlg", "No Name" ) ) ) ); // instrument if ( GetNumericIniSet ( IniXMLDocument, "client", "instrument", 0, CInstPictures::GetNumAvailableInst() - 1, iValue ) ) { pClient->ChannelInfo.iInstrument = iValue; } // country if ( GetNumericIniSet ( IniXMLDocument, "client", "country", 0, static_cast ( QLocale::LastCountry ), iValue ) ) { pClient->ChannelInfo.eCountry = CLocale::WireFormatCountryCodeToQtCountry ( iValue ); } else { // if no country is given, use the one from the operating system pClient->ChannelInfo.eCountry = QLocale::system().country(); } // city pClient->ChannelInfo.strCity = FromBase64ToString ( GetIniSetting ( IniXMLDocument, "client", "city_base64" ) ); // skill level if ( GetNumericIniSet ( IniXMLDocument, "client", "skill", 0, 3 /* SL_PROFESSIONAL */, iValue ) ) { pClient->ChannelInfo.eSkillLevel = static_cast ( iValue ); } // audio fader if ( GetNumericIniSet ( IniXMLDocument, "client", "audfad", AUD_FADER_IN_MIN, AUD_FADER_IN_MAX, iValue ) ) { pClient->SetAudioInFader ( iValue ); } // reverberation level if ( GetNumericIniSet ( IniXMLDocument, "client", "revlev", 0, AUD_REVERB_MAX, iValue ) ) { pClient->SetReverbLevel ( iValue ); } // reverberation channel assignment if ( GetFlagIniSet ( IniXMLDocument, "client", "reverblchan", bValue ) ) { pClient->SetReverbOnLeftChan ( bValue ); } // sound card selection const QString strError = pClient->SetSndCrdDev ( FromBase64ToString ( GetIniSetting ( IniXMLDocument, "client", "auddev_base64", "" ) ) ); if ( !strError.isEmpty() ) { # ifndef HEADLESS // special case: when settings are loaded no GUI is yet created, therefore // we have to create a warning message box here directly QMessageBox::warning ( nullptr, APP_NAME, strError ); # endif } // sound card channel mapping settings: make sure these settings are // set AFTER the sound card device is set, otherwise the settings are // overwritten by the defaults // // sound card left input channel mapping if ( GetNumericIniSet ( IniXMLDocument, "client", "sndcrdinlch", 0, MAX_NUM_IN_OUT_CHANNELS - 1, iValue ) ) { pClient->SetSndCrdLeftInputChannel ( iValue ); } // sound card right input channel mapping if ( GetNumericIniSet ( IniXMLDocument, "client", "sndcrdinrch", 0, MAX_NUM_IN_OUT_CHANNELS - 1, iValue ) ) { pClient->SetSndCrdRightInputChannel ( iValue ); } // sound card left output channel mapping if ( GetNumericIniSet ( IniXMLDocument, "client", "sndcrdoutlch", 0, MAX_NUM_IN_OUT_CHANNELS - 1, iValue ) ) { pClient->SetSndCrdLeftOutputChannel ( iValue ); } // sound card right output channel mapping if ( GetNumericIniSet ( IniXMLDocument, "client", "sndcrdoutrch", 0, MAX_NUM_IN_OUT_CHANNELS - 1, iValue ) ) { pClient->SetSndCrdRightOutputChannel ( iValue ); } // sound card preferred buffer size index if ( GetNumericIniSet ( IniXMLDocument, "client", "prefsndcrdbufidx", FRAME_SIZE_FACTOR_PREFERRED, FRAME_SIZE_FACTOR_SAFE, iValue ) ) { // additional check required since only a subset of factors are // defined if ( ( iValue == FRAME_SIZE_FACTOR_PREFERRED ) || ( iValue == FRAME_SIZE_FACTOR_DEFAULT ) || ( iValue == FRAME_SIZE_FACTOR_SAFE ) ) { pClient->SetSndCrdPrefFrameSizeFactor ( iValue ); } } // automatic network jitter buffer size setting if ( GetFlagIniSet ( IniXMLDocument, "client", "autojitbuf", bValue ) ) { pClient->SetDoAutoSockBufSize ( bValue ); } // network jitter buffer size if ( GetNumericIniSet ( IniXMLDocument, "client", "jitbuf", MIN_NET_BUF_SIZE_NUM_BL, MAX_NET_BUF_SIZE_NUM_BL, iValue ) ) { pClient->SetSockBufNumFrames ( iValue ); } // network jitter buffer size for server if ( GetNumericIniSet ( IniXMLDocument, "client", "jitbufserver", MIN_NET_BUF_SIZE_NUM_BL, MAX_NET_BUF_SIZE_NUM_BL, iValue ) ) { pClient->SetServerSockBufNumFrames ( iValue ); } // enable OPUS64 setting if ( GetFlagIniSet ( IniXMLDocument, "client", "enableopussmall", bValue ) ) { pClient->SetEnableOPUS64 ( bValue ); } // GUI design if ( GetNumericIniSet ( IniXMLDocument, "client", "guidesign", 0, 2 /* GD_SLIMFADER */, iValue ) ) { pClient->SetGUIDesign ( static_cast ( iValue ) ); } // MeterStyle if ( GetNumericIniSet ( IniXMLDocument, "client", "meterstyle", 0, 4 /* MT_LED_ROUND_BIG */, iValue ) ) { pClient->SetMeterStyle ( static_cast ( iValue ) ); } else { // if MeterStyle is not found in the ini, set it based on the GUI design if ( GetNumericIniSet ( IniXMLDocument, "client", "guidesign", 0, 2 /* GD_SLIMFADER */, iValue ) ) { switch ( iValue ) { case GD_STANDARD: pClient->SetMeterStyle ( MT_BAR_WIDE ); break; case GD_ORIGINAL: pClient->SetMeterStyle ( MT_LED_STRIPE ); break; case GD_SLIMFADER: pClient->SetMeterStyle ( MT_BAR_NARROW ); break; default: pClient->SetMeterStyle ( MT_LED_STRIPE ); break; } } } // audio channels if ( GetNumericIniSet ( IniXMLDocument, "client", "audiochannels", 0, 2 /* CC_STEREO */, iValue ) ) { pClient->SetAudioChannels ( static_cast ( iValue ) ); } // audio quality if ( GetNumericIniSet ( IniXMLDocument, "client", "audioquality", 0, 2 /* AQ_HIGH */, iValue ) ) { pClient->SetAudioQuality ( static_cast ( iValue ) ); } // custom directories //### TODO: BEGIN ###// // compatibility to old version (< 3.6.1) QString strDirectoryAddress = GetIniSetting ( IniXMLDocument, "client", "centralservaddr", "" ); //### TODO: END ###// for ( iIdx = 0; iIdx < MAX_NUM_SERVER_ADDR_ITEMS; iIdx++ ) { //### TODO: BEGIN ###// // compatibility to old version (< 3.8.2) strDirectoryAddress = GetIniSetting ( IniXMLDocument, "client", QString ( "centralservaddr%1" ).arg ( iIdx ), strDirectoryAddress ); //### TODO: END ###// vstrDirectoryAddress[iIdx] = GetIniSetting ( IniXMLDocument, "client", QString ( "directoryaddress%1" ).arg ( iIdx ), strDirectoryAddress ); strDirectoryAddress = ""; } // directory type //### TODO: BEGIN ###// // compatibility to old version (<3.4.7) // only the case that "centralservaddr" was set in old ini must be considered if ( !vstrDirectoryAddress[0].isEmpty() && GetFlagIniSet ( IniXMLDocument, "client", "defcentservaddr", bValue ) && !bValue ) { eDirectoryType = AT_CUSTOM; } // compatibility to old version (< 3.8.2) else if ( GetNumericIniSet ( IniXMLDocument, "client", "centservaddrtype", 0, static_cast ( AT_CUSTOM ), iValue ) ) { eDirectoryType = static_cast ( iValue ); } //### TODO: END ###// else if ( GetNumericIniSet ( IniXMLDocument, "client", "directorytype", 0, static_cast ( AT_CUSTOM ), iValue ) ) { eDirectoryType = static_cast ( iValue ); } else { // if no address type is given, choose one from the operating system locale eDirectoryType = AT_DEFAULT; } // custom directory index if ( ( eDirectoryType == AT_CUSTOM ) && GetNumericIniSet ( IniXMLDocument, "client", "customdirectoryindex", 0, MAX_NUM_SERVER_ADDR_ITEMS, iValue ) ) { iCustomDirectoryIndex = iValue; } else { // if directory is not set to custom, or if no custom directory index is found in the settings .ini file, then initialize to zero iCustomDirectoryIndex = 0; } // window position of the main window vecWindowPosMain = FromBase64ToByteArray ( GetIniSetting ( IniXMLDocument, "client", "winposmain_base64" ) ); // window position of the settings window vecWindowPosSettings = FromBase64ToByteArray ( GetIniSetting ( IniXMLDocument, "client", "winposset_base64" ) ); // window position of the chat window vecWindowPosChat = FromBase64ToByteArray ( GetIniSetting ( IniXMLDocument, "client", "winposchat_base64" ) ); // window position of the connect window vecWindowPosConnect = FromBase64ToByteArray ( GetIniSetting ( IniXMLDocument, "client", "winposcon_base64" ) ); // visibility state of the settings window if ( GetFlagIniSet ( IniXMLDocument, "client", "winvisset", bValue ) ) { bWindowWasShownSettings = bValue; } // visibility state of the chat window if ( GetFlagIniSet ( IniXMLDocument, "client", "winvischat", bValue ) ) { bWindowWasShownChat = bValue; } // visibility state of the connect window if ( GetFlagIniSet ( IniXMLDocument, "client", "winviscon", bValue ) ) { bWindowWasShownConnect = bValue; } // selected Settings Tab if ( GetNumericIniSet ( IniXMLDocument, "client", "settingstab", 0, 2, iValue ) ) { iSettingsTab = iValue; } // fader settings ReadFaderSettingsFromXML ( IniXMLDocument ); } QString CClientSettings::CleanUpLegacyFaderSetting ( QString strFaderTag, int iIdx ) { bool ok; int iIdy; bool bDup; if ( !bCleanUpLegacyFaderSettings || strFaderTag.isEmpty() ) { return strFaderTag; } QStringList slChanFaderTag = strFaderTag.split ( ":" ); if ( slChanFaderTag.size() != 2 ) { return strFaderTag; } const int iChan = slChanFaderTag[0].toInt ( &ok ); if ( ok && iChan >= 0 && iChan <= MAX_NUM_CHANNELS ) { // *assumption*: legacy tag that needs cleaning up strFaderTag = slChanFaderTag[1]; } // duplicate detection // this assumes the first entry into the vector is the newest one and skips any later ones. // the alternative is to use iIdy for the vector entry, so overwriting the duplicate. // (in both cases, this currently leaves holes in the vector.) bDup = false; for ( iIdy = 0; iIdy < iIdx; iIdy++ ) { if ( strFaderTag == vecStoredFaderTags[iIdy] ) { // duplicate entry bDup = true; break; } } if ( bDup ) { // so skip all settings for this iIdx (use iIdx here even if using iIdy and not doing continue below) return QString(); } return strFaderTag; } void CClientSettings::ReadFaderSettingsFromXML ( const QDomDocument& IniXMLDocument ) { int iIdx; int iValue; bool bValue; for ( iIdx = 0; iIdx < MAX_NUM_STORED_FADER_SETTINGS; iIdx++ ) { // stored fader tags QString strFaderTag = CleanUpLegacyFaderSetting ( FromBase64ToString ( GetIniSetting ( IniXMLDocument, "client", QString ( "storedfadertag%1_base64" ).arg ( iIdx ), "" ) ), iIdx ); if ( strFaderTag.isEmpty() ) { // duplicate from clean up code continue; } vecStoredFaderTags[iIdx] = strFaderTag; // stored fader levels if ( GetNumericIniSet ( IniXMLDocument, "client", QString ( "storedfaderlevel%1" ).arg ( iIdx ), 0, AUD_MIX_FADER_MAX, iValue ) ) { vecStoredFaderLevels[iIdx] = iValue; } // stored pan values if ( GetNumericIniSet ( IniXMLDocument, "client", QString ( "storedpanvalue%1" ).arg ( iIdx ), 0, AUD_MIX_PAN_MAX, iValue ) ) { vecStoredPanValues[iIdx] = iValue; } // stored fader solo state if ( GetFlagIniSet ( IniXMLDocument, "client", QString ( "storedfaderissolo%1" ).arg ( iIdx ), bValue ) ) { vecStoredFaderIsSolo[iIdx] = bValue; } // stored fader muted state if ( GetFlagIniSet ( IniXMLDocument, "client", QString ( "storedfaderismute%1" ).arg ( iIdx ), bValue ) ) { vecStoredFaderIsMute[iIdx] = bValue; } // stored fader group ID if ( GetNumericIniSet ( IniXMLDocument, "client", QString ( "storedgroupid%1" ).arg ( iIdx ), INVALID_INDEX, MAX_NUM_FADER_GROUPS - 1, iValue ) ) { vecStoredFaderGroupID[iIdx] = iValue; } } } void CClientSettings::WriteSettingsToXML ( QDomDocument& IniXMLDocument ) { int iIdx; // IP addresses for ( iIdx = 0; iIdx < MAX_NUM_SERVER_ADDR_ITEMS; iIdx++ ) { PutIniSetting ( IniXMLDocument, "client", QString ( "ipaddress%1" ).arg ( iIdx ), vstrIPAddress[iIdx] ); } // new client level SetNumericIniSet ( IniXMLDocument, "client", "newclientlevel", iNewClientFaderLevel ); // input boost SetNumericIniSet ( IniXMLDocument, "client", "inputboost", iInputBoost ); // feedback detection SetFlagIniSet ( IniXMLDocument, "client", "enablefeedbackdetection", bEnableFeedbackDetection ); // connect dialog show all musicians SetFlagIniSet ( IniXMLDocument, "client", "connectdlgshowallmusicians", bConnectDlgShowAllMusicians ); // language PutIniSetting ( IniXMLDocument, "client", "language", strLanguage ); // fader channel sorting SetNumericIniSet ( IniXMLDocument, "client", "channelsort", static_cast ( eChannelSortType ) ); // own fader first sorting SetFlagIniSet ( IniXMLDocument, "client", "ownfaderfirst", bOwnFaderFirst ); // number of mixer panel rows SetNumericIniSet ( IniXMLDocument, "client", "numrowsmixpan", iNumMixerPanelRows ); // audio alerts SetFlagIniSet ( IniXMLDocument, "client", "enableaudioalerts", bEnableAudioAlerts ); // name PutIniSetting ( IniXMLDocument, "client", "name_base64", ToBase64 ( pClient->ChannelInfo.strName ) ); // instrument SetNumericIniSet ( IniXMLDocument, "client", "instrument", pClient->ChannelInfo.iInstrument ); // country SetNumericIniSet ( IniXMLDocument, "client", "country", CLocale::QtCountryToWireFormatCountryCode ( pClient->ChannelInfo.eCountry ) ); // city PutIniSetting ( IniXMLDocument, "client", "city_base64", ToBase64 ( pClient->ChannelInfo.strCity ) ); // skill level SetNumericIniSet ( IniXMLDocument, "client", "skill", static_cast ( pClient->ChannelInfo.eSkillLevel ) ); // audio fader SetNumericIniSet ( IniXMLDocument, "client", "audfad", pClient->GetAudioInFader() ); // reverberation level SetNumericIniSet ( IniXMLDocument, "client", "revlev", pClient->GetReverbLevel() ); // reverberation channel assignment SetFlagIniSet ( IniXMLDocument, "client", "reverblchan", pClient->IsReverbOnLeftChan() ); // sound card selection PutIniSetting ( IniXMLDocument, "client", "auddev_base64", ToBase64 ( pClient->GetSndCrdDev() ) ); // sound card left input channel mapping SetNumericIniSet ( IniXMLDocument, "client", "sndcrdinlch", pClient->GetSndCrdLeftInputChannel() ); // sound card right input channel mapping SetNumericIniSet ( IniXMLDocument, "client", "sndcrdinrch", pClient->GetSndCrdRightInputChannel() ); // sound card left output channel mapping SetNumericIniSet ( IniXMLDocument, "client", "sndcrdoutlch", pClient->GetSndCrdLeftOutputChannel() ); // sound card right output channel mapping SetNumericIniSet ( IniXMLDocument, "client", "sndcrdoutrch", pClient->GetSndCrdRightOutputChannel() ); // sound card preferred buffer size index SetNumericIniSet ( IniXMLDocument, "client", "prefsndcrdbufidx", pClient->GetSndCrdPrefFrameSizeFactor() ); // automatic network jitter buffer size setting SetFlagIniSet ( IniXMLDocument, "client", "autojitbuf", pClient->GetDoAutoSockBufSize() ); // network jitter buffer size SetNumericIniSet ( IniXMLDocument, "client", "jitbuf", pClient->GetSockBufNumFrames() ); // network jitter buffer size for server SetNumericIniSet ( IniXMLDocument, "client", "jitbufserver", pClient->GetServerSockBufNumFrames() ); // enable OPUS64 setting SetFlagIniSet ( IniXMLDocument, "client", "enableopussmall", pClient->GetEnableOPUS64() ); // GUI design SetNumericIniSet ( IniXMLDocument, "client", "guidesign", static_cast ( pClient->GetGUIDesign() ) ); // MeterStyle SetNumericIniSet ( IniXMLDocument, "client", "meterstyle", static_cast ( pClient->GetMeterStyle() ) ); // audio channels SetNumericIniSet ( IniXMLDocument, "client", "audiochannels", static_cast ( pClient->GetAudioChannels() ) ); // audio quality SetNumericIniSet ( IniXMLDocument, "client", "audioquality", static_cast ( pClient->GetAudioQuality() ) ); // custom directories for ( iIdx = 0; iIdx < MAX_NUM_SERVER_ADDR_ITEMS; iIdx++ ) { PutIniSetting ( IniXMLDocument, "client", QString ( "directoryaddress%1" ).arg ( iIdx ), vstrDirectoryAddress[iIdx] ); } // directory type SetNumericIniSet ( IniXMLDocument, "client", "directorytype", static_cast ( eDirectoryType ) ); // custom directory index SetNumericIniSet ( IniXMLDocument, "client", "customdirectoryindex", iCustomDirectoryIndex ); // window position of the main window PutIniSetting ( IniXMLDocument, "client", "winposmain_base64", ToBase64 ( vecWindowPosMain ) ); // window position of the settings window PutIniSetting ( IniXMLDocument, "client", "winposset_base64", ToBase64 ( vecWindowPosSettings ) ); // window position of the chat window PutIniSetting ( IniXMLDocument, "client", "winposchat_base64", ToBase64 ( vecWindowPosChat ) ); // window position of the connect window PutIniSetting ( IniXMLDocument, "client", "winposcon_base64", ToBase64 ( vecWindowPosConnect ) ); // visibility state of the settings window SetFlagIniSet ( IniXMLDocument, "client", "winvisset", bWindowWasShownSettings ); // visibility state of the chat window SetFlagIniSet ( IniXMLDocument, "client", "winvischat", bWindowWasShownChat ); // visibility state of the connect window SetFlagIniSet ( IniXMLDocument, "client", "winviscon", bWindowWasShownConnect ); // Settings Tab SetNumericIniSet ( IniXMLDocument, "client", "settingstab", iSettingsTab ); // fader settings WriteFaderSettingsToXML ( IniXMLDocument ); } void CClientSettings::WriteFaderSettingsToXML ( QDomDocument& IniXMLDocument ) { int iIdx; for ( iIdx = 0; iIdx < MAX_NUM_STORED_FADER_SETTINGS; iIdx++ ) { // stored fader tags PutIniSetting ( IniXMLDocument, "client", QString ( "storedfadertag%1_base64" ).arg ( iIdx ), ToBase64 ( vecStoredFaderTags[iIdx] ) ); // stored fader levels SetNumericIniSet ( IniXMLDocument, "client", QString ( "storedfaderlevel%1" ).arg ( iIdx ), vecStoredFaderLevels[iIdx] ); // stored pan values SetNumericIniSet ( IniXMLDocument, "client", QString ( "storedpanvalue%1" ).arg ( iIdx ), vecStoredPanValues[iIdx] ); // stored fader solo states SetFlagIniSet ( IniXMLDocument, "client", QString ( "storedfaderissolo%1" ).arg ( iIdx ), vecStoredFaderIsSolo[iIdx] != 0 ); // stored fader muted states SetFlagIniSet ( IniXMLDocument, "client", QString ( "storedfaderismute%1" ).arg ( iIdx ), vecStoredFaderIsMute[iIdx] != 0 ); // stored fader group ID SetNumericIniSet ( IniXMLDocument, "client", QString ( "storedgroupid%1" ).arg ( iIdx ), vecStoredFaderGroupID[iIdx] ); } } #endif // Server settings ------------------------------------------------------------- // that this gets called means we are not headless void CServerSettings::ReadSettingsFromXML ( const QDomDocument& IniXMLDocument, const QList& CommandLineOptions ) { int iValue; bool bValue; // window position of the main window vecWindowPosMain = FromBase64ToByteArray ( GetIniSetting ( IniXMLDocument, "server", "winposmain_base64" ) ); // name/city/country if ( !CommandLineOptions.contains ( "--serverinfo" ) ) { // name pServer->SetServerName ( GetIniSetting ( IniXMLDocument, "server", "name" ) ); // city pServer->SetServerCity ( GetIniSetting ( IniXMLDocument, "server", "city" ) ); // country if ( GetNumericIniSet ( IniXMLDocument, "server", "country", 0, static_cast ( QLocale::LastCountry ), iValue ) ) { pServer->SetServerCountry ( CLocale::WireFormatCountryCodeToQtCountry ( iValue ) ); } } // norecord flag if ( !CommandLineOptions.contains ( "--norecord" ) ) { if ( GetFlagIniSet ( IniXMLDocument, "server", "norecord", bValue ) ) { pServer->SetEnableRecording ( !bValue ); } } // welcome message if ( !CommandLineOptions.contains ( "--welcomemessage" ) ) { pServer->SetWelcomeMessage ( FromBase64ToString ( GetIniSetting ( IniXMLDocument, "server", "welcome" ) ) ); } // language strLanguage = GetIniSetting ( IniXMLDocument, "server", "language", CLocale::FindSysLangTransFileName ( CLocale::GetAvailableTranslations() ).first ); // base recording directory if ( !CommandLineOptions.contains ( "--recording" ) ) { pServer->SetRecordingDir ( FromBase64ToString ( GetIniSetting ( IniXMLDocument, "server", "recordingdir_base64" ) ) ); } // to avoid multiple registrations, must do this after collecting serverinfo if ( !CommandLineOptions.contains ( "--centralserver" ) && !CommandLineOptions.contains ( "--directoryserver" ) ) { // custom directory // CServerListManager defaults to command line argument (or "" if not passed) // Server GUI defaults to "" QString directoryAddress = ""; //### TODO: BEGIN ###// // compatibility to old version < 3.8.2 directoryAddress = GetIniSetting ( IniXMLDocument, "server", "centralservaddr", directoryAddress ); //### TODO: END ###// directoryAddress = GetIniSetting ( IniXMLDocument, "server", "directoryaddress", directoryAddress ); pServer->SetDirectoryAddress ( directoryAddress ); } // directory type // CServerListManager defaults to AT_NONE // Because type could be AT_CUSTOM, it has to be set after the address to avoid multiple registrations EDirectoryType directoryType = AT_NONE; // if a command line Directory server address is set, set the Directory Type (genre) to AT_CUSTOM so it's used if ( CommandLineOptions.contains ( "--centralserver" ) || CommandLineOptions.contains ( "--directoryserver" ) ) { directoryType = AT_CUSTOM; } else { //### TODO: BEGIN ###// // compatibility to old version < 3.4.7 if ( GetFlagIniSet ( IniXMLDocument, "server", "defcentservaddr", bValue ) ) { directoryType = bValue ? AT_DEFAULT : AT_CUSTOM; } else //### TODO: END ###// // if "directorytype" itself is set, use it (note "AT_NONE", "AT_DEFAULT" and "AT_CUSTOM" are min/max directory type here) //### TODO: BEGIN ###// // compatibility to old version < 3.8.2 if ( GetNumericIniSet ( IniXMLDocument, "server", "centservaddrtype", static_cast ( AT_DEFAULT ), static_cast ( AT_CUSTOM ), iValue ) ) { directoryType = static_cast ( iValue ); } //### TODO: END ###// else if ( GetNumericIniSet ( IniXMLDocument, "server", "directorytype", static_cast ( AT_NONE ), static_cast ( AT_CUSTOM ), iValue ) ) { directoryType = static_cast ( iValue ); } //### TODO: BEGIN ###// // compatibility to old version < 3.9.0 // override type to AT_NONE if servlistenabled exists and is false if ( GetFlagIniSet ( IniXMLDocument, "server", "servlistenabled", bValue ) && !bValue ) { directoryType = AT_NONE; } //### TODO: END ###// } pServer->SetDirectoryType ( directoryType ); // server list persistence file name if ( !CommandLineOptions.contains ( "--directoryfile" ) ) { pServer->SetServerListFileName ( FromBase64ToString ( GetIniSetting ( IniXMLDocument, "server", "directoryfile_base64" ) ) ); } // start minimized on OS start if ( !CommandLineOptions.contains ( "--startminimized" ) ) { if ( GetFlagIniSet ( IniXMLDocument, "server", "autostartmin", bValue ) ) { pServer->SetAutoRunMinimized ( bValue ); } } // delay panning if ( !CommandLineOptions.contains ( "--delaypan" ) ) { if ( GetFlagIniSet ( IniXMLDocument, "server", "delaypan", bValue ) ) { pServer->SetEnableDelayPanning ( bValue ); } } } void CServerSettings::WriteSettingsToXML ( QDomDocument& IniXMLDocument ) { // window position of the main window PutIniSetting ( IniXMLDocument, "server", "winposmain_base64", ToBase64 ( vecWindowPosMain ) ); // directory type SetNumericIniSet ( IniXMLDocument, "server", "directorytype", static_cast ( pServer->GetDirectoryType() ) ); // name PutIniSetting ( IniXMLDocument, "server", "name", pServer->GetServerName() ); // city PutIniSetting ( IniXMLDocument, "server", "city", pServer->GetServerCity() ); // country SetNumericIniSet ( IniXMLDocument, "server", "country", CLocale::QtCountryToWireFormatCountryCode ( pServer->GetServerCountry() ) ); // norecord flag SetFlagIniSet ( IniXMLDocument, "server", "norecord", pServer->GetDisableRecording() ); // welcome message PutIniSetting ( IniXMLDocument, "server", "welcome", ToBase64 ( pServer->GetWelcomeMessage() ) ); // language PutIniSetting ( IniXMLDocument, "server", "language", strLanguage ); // base recording directory PutIniSetting ( IniXMLDocument, "server", "recordingdir_base64", ToBase64 ( pServer->GetRecordingDir() ) ); // custom directory PutIniSetting ( IniXMLDocument, "server", "directoryaddress", pServer->GetDirectoryAddress() ); // server list persistence file name PutIniSetting ( IniXMLDocument, "server", "directoryfile_base64", ToBase64 ( pServer->GetServerListFileName() ) ); // start minimized on OS start SetFlagIniSet ( IniXMLDocument, "server", "autostartmin", pServer->GetAutoRunMinimized() ); // delay panning SetFlagIniSet ( IniXMLDocument, "server", "delaypan", pServer->IsDelayPanningEnabled() ); // we MUST do this after saving the value and Save() is only called OnAboutToQuit() pServer->SetDirectoryType ( AT_NONE ); } jamulus-3.9.1+dfsg/src/serverlist.h0000644000175000017500000002105514340334543016321 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * pljones * Originally, if you wanted to run a server, you had to open the firewall of your computer at the correct ports and introduce a port forwarding at your router to get it work. Whilst the above can work, using a directory server simplifies the process. The user who wants to run a server just registers his server with a directory server and a mechanism implemented in the protocol opens the firewall, similar to STUN. REQUIREMENTS: The client sets the URL of the directory server and can get a list of all currently activated and registered servers. If the user clicks on the server of his choice, he gets connected to this server. The server list must be available in both cases: if the client is connected to a server or not. The server list contains the name of the server, an optional location, the number of connected users and a ping time which is updated as long as the server list is visible (similar to the ping measurement in the general settings dialog). Additional information may be also present in the list, like reliability of the server, etc. CONNECTION PROCESS: A server contacts the directory server and registers through some protocol mechanism. If a client requests the server list from a directory server, the directory server sends the IP address of the client to each registered server so that they can immediately send a "firewall opening" UDP packet to this IP address. If the client now sends ping messages to each of the servers in the list, the server firewalls and routers are prepared for receiving UDP packets from this IP address and will tunnel it through. Note: this mechanism will not work in a private network. ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #include #include #include #include #include #if QT_VERSION >= QT_VERSION_CHECK( 5, 6, 0 ) # include #endif #include "global.h" #include "util.h" #include "protocol.h" /* Classes ********************************************************************/ class CServerListEntry : public CServerInfo { public: CServerListEntry() : CServerInfo ( CHostAddress(), CHostAddress(), "", QLocale::AnyCountry, "", 0, false ) { UpdateRegistration(); } CServerListEntry ( const CHostAddress& NHAddr, const CHostAddress& NLHAddr, const QString& NsName, const QLocale::Country& NeCountry, const QString& NsCity, const int NiMaxNumClients, const bool NbPermOnline ) : CServerInfo ( NHAddr, NLHAddr, NsName, NeCountry, NsCity, NiMaxNumClients, NbPermOnline ) { UpdateRegistration(); } CServerListEntry ( const CHostAddress& NHAddr, const CHostAddress& NLHAddr, const CServerCoreInfo& NewCoreServerInfo ) : CServerInfo ( NHAddr, NLHAddr, NewCoreServerInfo.strName, NewCoreServerInfo.eCountry, NewCoreServerInfo.strCity, NewCoreServerInfo.iMaxNumClients, NewCoreServerInfo.bPermanentOnline ) { UpdateRegistration(); } void UpdateRegistration() { RegisterTime.start(); } static CServerListEntry parse ( QString strHAddr, QString strLHAddr, QString sName, QString sCity, QString strCountry, QString strNumClients, bool isPermanent, bool bEnableIPv6 ); QString toCSV(); // time on which the entry was registered QElapsedTimer RegisterTime; protected: // Taken from src/settings.h - the same comment applies static QString ToBase64 ( const QByteArray strIn ) { return QString::fromLatin1 ( strIn.toBase64() ); } static QString ToBase64 ( const QString strIn ) { return ToBase64 ( strIn.toUtf8() ); } static QByteArray FromBase64ToByteArray ( const QString strIn ) { return QByteArray::fromBase64 ( strIn.toLatin1() ); } static QString FromBase64ToString ( const QString strIn ) { return QString::fromUtf8 ( FromBase64ToByteArray ( strIn ) ); } }; class CServerListManager : public QObject { Q_OBJECT public: CServerListManager ( const quint16 iNPortNum, const QString& sNDirectoryAddress, const QString& strServerListFileName, const QString& strServerInfo, const QString& strServerListFilter, const QString& strServerPublicIP, const int iNumChannels, const bool bNEnableIPv6, CProtocol* pNConLProt ); void SetServerName ( const QString& strNewName ); QString GetServerName() { return ServerList[0].strName; } void SetServerCity ( const QString& strNewCity ); QString GetServerCity() { return ServerList[0].strCity; } void SetServerCountry ( const QLocale::Country eNewCountry ); QLocale::Country GetServerCountry() { return ServerList[0].eCountry; } void SetDirectoryAddress ( const QString sNDirectoryAddress ); QString GetDirectoryAddress() { return strDirectoryAddress; } void SetDirectoryType ( const EDirectoryType eNCSAT ); EDirectoryType GetDirectoryType() { return DirectoryType; } bool IsDirectoryServer() const { return bIsDirectoryServer; } ESvrRegStatus GetSvrRegStatus() { return eSvrRegStatus; } // the update has to be called if any change to the server list // properties was done void Update(); void Append ( const CHostAddress& InetAddr, const CHostAddress& LInetAddr, const CServerCoreInfo& ServerInfo, const QString strVersion = "" ); void Remove ( const CHostAddress& InetAddr ); void RetrieveAll ( const CHostAddress& InetAddr ); void StoreRegistrationResult ( ESvrRegResult eStatus ); QString GetServerListFileName() { return ServerListFileName; } bool SetServerListFileName ( QString strFilename ); protected: void SetIsDirectoryServer(); void Unregister(); void Register(); void SetRegistered ( bool bIsRegister ); int IndexOf ( CHostAddress haSearchTerm ); bool Load(); void Save(); void SetSvrRegStatus ( ESvrRegStatus eNSvrRegStatus ); QMutex Mutex; CHostAddress DirectoryAddress; EDirectoryType DirectoryType; bool bEnableIPv6; CHostAddress ServerPublicIP; CHostAddress ServerPublicIP6; QString ServerListFileName; QList ServerList; QString strDirectoryAddress; bool bIsDirectoryServer; // server registration status ESvrRegStatus eSvrRegStatus; QList vWhiteList; QString strMinServerVersion; CProtocol* pConnLessProtocol; // count of registration retries int iSvrRegRetries; QTimer TimerPollList; QTimer TimerPingServerInList; QTimer TimerPingServers; QTimer TimerRefreshRegistration; QTimer TimerCLRegisterServerResp; QTimer TimerIsPermanent; public slots: void OnTimerPollList(); void OnTimerPingServerInList(); void OnTimerPingServers(); void OnTimerRefreshRegistration() { SetRegistered ( true ); } void OnTimerCLRegisterServerResp(); void OnTimerIsPermanent() { ServerList[0].bPermanentOnline = true; } void OnAboutToQuit(); signals: void SvrRegStatusChanged(); }; jamulus-3.9.1+dfsg/src/signalhandler.h0000644000175000017500000001213514340334543016731 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2020-2022 * * Author(s): * Peter L Jones * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * ****************************************************************************** * * This code contains some ideas derived from QCtrlSignals * https://github.com/Skycoder42/QCtrlSignals.git * - mostly the singleton and emitSignal code, plus some of the structure * - virtually everything else is common knowledge across SourceForge answers * * BSD 3-Clause License * * Copyright (c) 2016, Felix Barz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * * Neither the name of the copyright holder nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * \******************************************************************************/ #pragma once #include #include #include #include #include #include #ifdef _WIN32 # include # include # include # include # include #else # include # include # include # include # include # include # include #endif class CSignalBase; class CSignalHandler : public QObject { Q_OBJECT friend class CSignalBase; friend class CSignalHandlerSingleton; public: static CSignalHandler* getSingletonP(); bool emitSignal ( int ); #ifndef _WIN32 public slots: void OnSocketNotify ( int socket ); #endif signals: void HandledSignal ( int sigNum ); private: QScopedPointer pSignalBase; explicit CSignalHandler(); ~CSignalHandler() override; }; // ---------------------------------------------------------- class CSignalBase { Q_DISABLE_COPY ( CSignalBase ) public: static CSignalBase* withSignalHandler ( CSignalHandler* ); virtual ~CSignalBase(); virtual QReadWriteLock* getLock() const = 0; QSet sHandledSigNums; protected: CSignalBase ( CSignalHandler* ); CSignalHandler* pSignalHandler; template static T* getSelf() { return static_cast ( CSignalHandler::getSingletonP()->pSignalBase.data() ); } }; #ifdef _WIN32 class CSignalWin : public CSignalBase { public: CSignalWin ( CSignalHandler* ); ~CSignalWin() override; virtual QReadWriteLock* getLock() const override; private: mutable QReadWriteLock lock; static BOOL WINAPI signalHandler ( _In_ DWORD ); }; #else class CSignalUnix : public CSignalBase { public: CSignalUnix ( CSignalHandler* ); ~CSignalUnix() override; virtual QReadWriteLock* getLock() const override; private: QSocketNotifier* socketNotifier = nullptr; bool setSignalHandled ( int sigNum, bool state ); static int socketPair[2]; static void signalHandler ( int sigNum ); }; #endif jamulus-3.9.1+dfsg/src/levelmeter.cpp0000644000175000017500000003633014340334543016620 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * * Description: * Implements a multi color LED bar * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include "levelmeter.h" /* Implementation *************************************************************/ CLevelMeter::CLevelMeter ( QWidget* parent ) : QWidget ( parent ), eLevelMeterType ( MT_BAR_WIDE ) { // initialize LED meter QWidget* pLEDMeter = new QWidget(); QVBoxLayout* pLEDLayout = new QVBoxLayout ( pLEDMeter ); pLEDLayout->setAlignment ( Qt::AlignHCenter ); pLEDLayout->setContentsMargins ( 0, 0, 0, 0 ); pLEDLayout->setSpacing ( 0 ); // create LEDs plus the clip LED vecpLEDs.Init ( NUM_LEDS_INCL_CLIP_LED ); for ( int iLEDIdx = NUM_LEDS_INCL_CLIP_LED - 1; iLEDIdx >= 0; iLEDIdx-- ) { // create LED object vecpLEDs[iLEDIdx] = new cLED ( parent ); // add LED to layout with spacer (do not add spacer on the bottom of the first LED) if ( iLEDIdx < NUM_LEDS_INCL_CLIP_LED - 1 ) { pLEDLayout->addStretch(); } pLEDLayout->addWidget ( vecpLEDs[iLEDIdx]->GetLabelPointer() ); } // initialize bar meter pBarMeter = new QProgressBar(); pBarMeter->setOrientation ( Qt::Vertical ); pBarMeter->setRange ( 0, 100 * NUM_STEPS_LED_BAR ); // use factor 100 to reduce quantization (bar is continuous) pBarMeter->setFormat ( "" ); // suppress percent numbers // setup stacked layout for meter type switching mechanism pMinStackedLayout = new CMinimumStackedLayout ( this ); pMinStackedLayout->addWidget ( pLEDMeter ); pMinStackedLayout->addWidget ( pBarMeter ); // according to QScrollArea description: "When using a scroll area to display the // contents of a custom widget, it is important to ensure that the size hint of // the child widget is set to a suitable value." pBarMeter->setMinimumSize ( QSize ( 1, 1 ) ); pLEDMeter->setMinimumSize ( QSize ( 1, 1 ) ); // update the meter type (using the default value of the meter type) SetLevelMeterType ( eLevelMeterType ); // setup clip indicator timer TimerClip.setSingleShot ( true ); TimerClip.setInterval ( CLIP_IND_TIME_OUT_MS ); // Connections ------------------------------------------------------------- QObject::connect ( &TimerClip, &QTimer::timeout, this, &CLevelMeter::ClipReset ); } CLevelMeter::~CLevelMeter() { // clean up the LED objects for ( int iLEDIdx = 0; iLEDIdx < NUM_LEDS_INCL_CLIP_LED; iLEDIdx++ ) { delete vecpLEDs[iLEDIdx]; } } void CLevelMeter::SetLevelMeterType ( const ELevelMeterType eNType ) { eLevelMeterType = eNType; switch ( eNType ) { case MT_LED_STRIPE: // initialize all LEDs for ( int iLEDIdx = 0; iLEDIdx < NUM_LEDS_INCL_CLIP_LED; iLEDIdx++ ) { vecpLEDs[iLEDIdx]->SetColor ( cLED::RL_BLACK ); } pMinStackedLayout->setCurrentIndex ( 0 ); break; case MT_LED_ROUND_BIG: // initialize all LEDs for ( int iLEDIdx = 0; iLEDIdx < NUM_LEDS_INCL_CLIP_LED; iLEDIdx++ ) { vecpLEDs[iLEDIdx]->SetColor ( cLED::RL_ROUND_BIG_BLACK ); } pMinStackedLayout->setCurrentIndex ( 0 ); break; case MT_LED_ROUND_SMALL: // initialize all LEDs for ( int iLEDIdx = 0; iLEDIdx < NUM_LEDS_INCL_CLIP_LED; iLEDIdx++ ) { vecpLEDs[iLEDIdx]->SetColor ( cLED::RL_ROUND_SMALL_BLACK ); } pMinStackedLayout->setCurrentIndex ( 0 ); break; case MT_BAR_WIDE: case MT_BAR_NARROW: pMinStackedLayout->setCurrentIndex ( 1 ); break; } // update bar meter style and reset clip state SetBarMeterStyleAndClipStatus ( eNType, false ); } void CLevelMeter::SetBarMeterStyleAndClipStatus ( const ELevelMeterType eNType, const bool bIsClip ) { switch ( eNType ) { case MT_BAR_NARROW: if ( bIsClip ) { pBarMeter->setStyleSheet ( "QProgressBar { border: 0px solid red;" " margin: 0px;" " padding: 0px;" " width: 4px;" " background: red; }" "QProgressBar::chunk { background: green; }" ); } else { pBarMeter->setStyleSheet ( "QProgressBar { border: 0px;" " margin: 0px;" " padding: 0px;" " width: 4px; }" "QProgressBar::chunk { background: green; }" ); } break; default: /* MT_BAR_WIDE */ if ( bIsClip ) { pBarMeter->setStyleSheet ( "QProgressBar { border: 2px solid red;" " margin: 1px;" " padding: 1px;" " width: 15px;" " background: transparent; }" "QProgressBar::chunk { background: green; }" ); } else { pBarMeter->setStyleSheet ( "QProgressBar { margin: 1px;" " padding: 1px;" " width: 15px; }" "QProgressBar::chunk { background: green; }" ); } break; } } void CLevelMeter::SetValue ( const double dValue ) { switch ( eLevelMeterType ) { case MT_LED_STRIPE: // update state of all LEDs for current level value (except of the clip LED) for ( int iLEDIdx = 0; iLEDIdx < NUM_STEPS_LED_BAR; iLEDIdx++ ) { // set active LED color if value is above current LED index if ( iLEDIdx < dValue ) { // check which color we should use (green, yellow or red) if ( iLEDIdx < YELLOW_BOUND_LED_BAR ) { // green region vecpLEDs[iLEDIdx]->SetColor ( cLED::RL_GREEN ); } else { if ( iLEDIdx < RED_BOUND_LED_BAR ) { // yellow region vecpLEDs[iLEDIdx]->SetColor ( cLED::RL_YELLOW ); } else { // red region vecpLEDs[iLEDIdx]->SetColor ( cLED::RL_RED ); } } } else { // we use black LED for inactive state vecpLEDs[iLEDIdx]->SetColor ( cLED::RL_BLACK ); } } break; case MT_LED_ROUND_BIG: // update state of all LEDs for current level value (except of the clip LED) for ( int iLEDIdx = 0; iLEDIdx < NUM_STEPS_LED_BAR; iLEDIdx++ ) { // set active LED color if value is above current LED index if ( iLEDIdx < dValue ) { // check which color we should use (green, yellow or red) if ( iLEDIdx < YELLOW_BOUND_LED_BAR ) { // green region vecpLEDs[iLEDIdx]->SetColor ( cLED::RL_ROUND_BIG_GREEN ); } else { if ( iLEDIdx < RED_BOUND_LED_BAR ) { // yellow region vecpLEDs[iLEDIdx]->SetColor ( cLED::RL_ROUND_BIG_YELLOW ); } else { // red region vecpLEDs[iLEDIdx]->SetColor ( cLED::RL_ROUND_BIG_RED ); } } } else { // we use black LED for inactive state vecpLEDs[iLEDIdx]->SetColor ( cLED::RL_ROUND_BIG_BLACK ); } } break; case MT_LED_ROUND_SMALL: // update state of all LEDs for current level value (except of the clip LED) for ( int iLEDIdx = 0; iLEDIdx < NUM_STEPS_LED_BAR; iLEDIdx++ ) { // set active LED color if value is above current LED index if ( iLEDIdx < dValue ) { // check which color we should use (green, yellow or red) if ( iLEDIdx < YELLOW_BOUND_LED_BAR ) { // green region vecpLEDs[iLEDIdx]->SetColor ( cLED::RL_ROUND_SMALL_GREEN ); } else { if ( iLEDIdx < RED_BOUND_LED_BAR ) { // yellow region vecpLEDs[iLEDIdx]->SetColor ( cLED::RL_ROUND_SMALL_YELLOW ); } else { // red region vecpLEDs[iLEDIdx]->SetColor ( cLED::RL_ROUND_SMALL_RED ); } } } else { // we use black LED for inactive state vecpLEDs[iLEDIdx]->SetColor ( cLED::RL_ROUND_SMALL_BLACK ); } } break; case MT_BAR_WIDE: case MT_BAR_NARROW: pBarMeter->setValue ( 100 * dValue ); break; } // clip indicator management (note that in case of clipping, i.e. full // scale level, the value is above NUM_STEPS_LED_BAR since the minimum // value of int16 is -32768 but we normalize with 32767 -> therefore // we really only show the clipping indicator, if actually the largest // value of int16 is used) if ( dValue > NUM_STEPS_LED_BAR ) { switch ( eLevelMeterType ) { case MT_LED_STRIPE: vecpLEDs[NUM_STEPS_LED_BAR]->SetColor ( cLED::RL_RED ); break; case MT_LED_ROUND_BIG: vecpLEDs[NUM_STEPS_LED_BAR]->SetColor ( cLED::RL_ROUND_BIG_RED ); break; case MT_LED_ROUND_SMALL: vecpLEDs[NUM_STEPS_LED_BAR]->SetColor ( cLED::RL_ROUND_SMALL_RED ); break; case MT_BAR_WIDE: case MT_BAR_NARROW: SetBarMeterStyleAndClipStatus ( eLevelMeterType, true ); break; } TimerClip.start(); } } void CLevelMeter::ClipReset() { // we manually want to reset the clipping indicator: stop timer and reset // clipping indicator GUI element TimerClip.stop(); switch ( eLevelMeterType ) { case MT_LED_STRIPE: vecpLEDs[NUM_STEPS_LED_BAR]->SetColor ( cLED::RL_BLACK ); break; case MT_LED_ROUND_BIG: vecpLEDs[NUM_STEPS_LED_BAR]->SetColor ( cLED::RL_ROUND_BIG_BLACK ); break; case MT_LED_ROUND_SMALL: vecpLEDs[NUM_STEPS_LED_BAR]->SetColor ( cLED::RL_ROUND_SMALL_BLACK ); break; case MT_BAR_WIDE: case MT_BAR_NARROW: SetBarMeterStyleAndClipStatus ( eLevelMeterType, false ); break; } } CLevelMeter::cLED::cLED ( QWidget* parent ) : BitmCubeLedBlack ( QString::fromUtf8 ( ":/png/LEDs/res/HLEDBlack.png" ) ), BitmCubeLedGreen ( QString::fromUtf8 ( ":/png/LEDs/res/HLEDGreen.png" ) ), BitmCubeLedYellow ( QString::fromUtf8 ( ":/png/LEDs/res/HLEDYellow.png" ) ), BitmCubeLedRed ( QString::fromUtf8 ( ":/png/LEDs/res/HLEDRed.png" ) ), BitmCubeRoundSmallLedBlack ( QString::fromUtf8 ( ":/png/LEDs/res/CLEDBlackSmall.png" ) ), BitmCubeRoundSmallLedGreen ( QString::fromUtf8 ( ":/png/LEDs/res/CLEDGreenSmall.png" ) ), BitmCubeRoundSmallLedYellow ( QString::fromUtf8 ( ":/png/LEDs/res/CLEDYellowSmall.png" ) ), BitmCubeRoundSmallLedRed ( QString::fromUtf8 ( ":/png/LEDs/res/CLEDRedSmall.png" ) ), BitmCubeRoundBigLedBlack ( QString::fromUtf8 ( ":/png/LEDs/res/CLEDBlackBig.png" ) ), BitmCubeRoundBigLedGreen ( QString::fromUtf8 ( ":/png/LEDs/res/CLEDGreenBig.png" ) ), BitmCubeRoundBigLedYellow ( QString::fromUtf8 ( ":/png/LEDs/res/CLEDYellowBig.png" ) ), BitmCubeRoundBigLedRed ( QString::fromUtf8 ( ":/png/LEDs/res/CLEDRedBig.png" ) ) { // create LED label pLEDLabel = new QLabel ( "", parent ); // set initial bitmap pLEDLabel->setPixmap ( BitmCubeLedBlack ); eCurLightColor = RL_BLACK; } void CLevelMeter::cLED::SetColor ( const ELightColor eNewColor ) { // only update LED if color has changed if ( eNewColor != eCurLightColor ) { switch ( eNewColor ) { case RL_DISABLED: // note that this is required for the compact channel mode pLEDLabel->setPixmap ( QPixmap() ); break; case RL_BLACK: pLEDLabel->setPixmap ( BitmCubeLedBlack ); break; case RL_GREEN: pLEDLabel->setPixmap ( BitmCubeLedGreen ); break; case RL_YELLOW: pLEDLabel->setPixmap ( BitmCubeLedYellow ); break; case RL_RED: pLEDLabel->setPixmap ( BitmCubeLedRed ); break; case RL_ROUND_SMALL_BLACK: pLEDLabel->setPixmap ( BitmCubeRoundSmallLedBlack ); break; case RL_ROUND_SMALL_GREEN: pLEDLabel->setPixmap ( BitmCubeRoundSmallLedGreen ); break; case RL_ROUND_SMALL_YELLOW: pLEDLabel->setPixmap ( BitmCubeRoundSmallLedYellow ); break; case RL_ROUND_SMALL_RED: pLEDLabel->setPixmap ( BitmCubeRoundSmallLedRed ); break; case RL_ROUND_BIG_BLACK: pLEDLabel->setPixmap ( BitmCubeRoundBigLedBlack ); break; case RL_ROUND_BIG_GREEN: pLEDLabel->setPixmap ( BitmCubeRoundBigLedGreen ); break; case RL_ROUND_BIG_YELLOW: pLEDLabel->setPixmap ( BitmCubeRoundBigLedYellow ); break; case RL_ROUND_BIG_RED: pLEDLabel->setPixmap ( BitmCubeRoundBigLedRed ); break; } eCurLightColor = eNewColor; } } jamulus-3.9.1+dfsg/src/testbench.h0000644000175000017500000002724014340334543016100 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #include #include #include #include #include #include "global.h" #include "socket.h" #include "protocol.h" #include "util.h" /* Classes ********************************************************************/ class CTestbench : public QObject { Q_OBJECT public: CTestbench ( QString sNewAddress, quint16 iNewPort ) : sAddress ( sNewAddress ), iPort ( iNewPort ) { sLAddress = GenRandomIPv4Address().toString(); iLPort = static_cast ( GenRandomIntInRange ( -2, 10000 ) ); // bind socket (try 100 port numbers) quint16 iPortIncrement = 0; // start value: port number plus ten bool bSuccess = false; // initialization for while loop while ( !bSuccess && ( iPortIncrement <= 100 ) ) { bSuccess = UdpSocket.bind ( QHostAddress ( QHostAddress::Any ), 22222 + iPortIncrement ); iPortIncrement++; } // connect protocol signals QObject::connect ( &Protocol, &CProtocol::MessReadyForSending, this, &CTestbench::OnSendProtMessage ); QObject::connect ( &Protocol, &CProtocol::CLMessReadyForSending, this, &CTestbench::OnSendCLMessage ); // connect and start the timer (testbench heartbeat) QObject::connect ( &Timer, &QTimer::timeout, this, &CTestbench::OnTimer ); Timer.start ( 1 ); // 1 ms } protected: int GenRandomIntInRange ( const int iStart, const int iEnd ) const { return static_cast ( iStart + ( ( static_cast ( iEnd - iStart + 1 ) * rand() ) / RAND_MAX ) ); } QString GenRandomString() const { const int iLen = GenRandomIntInRange ( 0, 111 ); QString strReturn = ""; for ( int i = 0; i < iLen; i++ ) { strReturn += static_cast ( GenRandomIntInRange ( 0, 255 ) ); } return strReturn; } QHostAddress GenRandomIPv4Address() const { quint32 a = static_cast ( 192 ); quint32 b = static_cast ( 168 ); quint32 c = static_cast ( GenRandomIntInRange ( 1, 253 ) ); quint32 d = static_cast ( GenRandomIntInRange ( 1, 253 ) ); return QHostAddress ( a << 24 | b << 16 | c << 8 | d ); } QString sAddress; quint16 iPort; QString sLAddress; quint16 iLPort; QTimer Timer; CProtocol Protocol; QUdpSocket UdpSocket; public slots: void OnTimer() { CVector vecChanInfo ( 1 ); CNetworkTransportProps NetTrProps; CServerCoreInfo ServerInfo; CVector vecServerInfo ( 1 ); CVector vecLevelList ( 1 ); CHostAddress CurHostAddress ( QHostAddress ( sAddress ), iPort ); CHostAddress CurLocalAddress ( QHostAddress ( sLAddress ), iLPort ); CChannelCoreInfo ChannelCoreInfo; ELicenceType eLicenceType; ESvrRegResult eSvrRegResult; // generate random protocol message switch ( GenRandomIntInRange ( 0, 34 ) ) { case 0: // PROTMESSID_JITT_BUF_SIZE Protocol.CreateJitBufMes ( GenRandomIntInRange ( 0, 10 ) ); break; case 1: // PROTMESSID_REQ_JITT_BUF_SIZE Protocol.CreateReqJitBufMes(); break; case 2: // PROTMESSID_CHANNEL_GAIN Protocol.CreateChanGainMes ( GenRandomIntInRange ( 0, 20 ), GenRandomIntInRange ( -100, 100 ) ); break; case 4: // PROTMESSID_CONN_CLIENTS_LIST vecChanInfo[0].iChanID = GenRandomIntInRange ( -2, 20 ); vecChanInfo[0].strName = GenRandomString(); Protocol.CreateConClientListMes ( vecChanInfo ); break; case 5: // PROTMESSID_REQ_CONN_CLIENTS_LIST Protocol.CreateReqConnClientsList(); break; case 7: // PROTMESSID_CHANNEL_INFOS ChannelCoreInfo.eCountry = static_cast ( GenRandomIntInRange ( 0, 100 ) ); ChannelCoreInfo.eSkillLevel = static_cast ( GenRandomIntInRange ( 0, 3 ) ); ChannelCoreInfo.iInstrument = GenRandomIntInRange ( 0, 100 ); ChannelCoreInfo.strCity = GenRandomString(); ChannelCoreInfo.strName = GenRandomString(); Protocol.CreateChanInfoMes ( ChannelCoreInfo ); break; case 8: // PROTMESSID_REQ_CHANNEL_INFOS Protocol.CreateReqChanInfoMes(); break; case 9: // PROTMESSID_CHAT_TEXT Protocol.CreateChatTextMes ( GenRandomString() ); break; case 10: // PROTMESSID_LICENCE_REQUIRED eLicenceType = static_cast ( GenRandomIntInRange ( 0, 1 ) ); Protocol.CreateLicenceRequiredMes ( eLicenceType ); break; case 11: // PROTMESSID_NETW_TRANSPORT_PROPS NetTrProps.eAudioCodingType = static_cast ( GenRandomIntInRange ( 0, 2 ) ); NetTrProps.iAudioCodingArg = GenRandomIntInRange ( -100, 100 ); NetTrProps.iBaseNetworkPacketSize = GenRandomIntInRange ( -2, 1000 ); NetTrProps.iBlockSizeFact = GenRandomIntInRange ( -2, 100 ); NetTrProps.iNumAudioChannels = GenRandomIntInRange ( -2, 10 ); NetTrProps.iSampleRate = GenRandomIntInRange ( -2, 10000 ); NetTrProps.eFlags = static_cast ( GenRandomIntInRange ( 0, 1 ) ); Protocol.CreateNetwTranspPropsMes ( NetTrProps ); break; case 12: // PROTMESSID_REQ_NETW_TRANSPORT_PROPS Protocol.CreateReqNetwTranspPropsMes(); break; case 14: // PROTMESSID_CLM_PING_MS Protocol.CreateCLPingMes ( CurHostAddress, GenRandomIntInRange ( -2, 1000 ) ); break; case 15: // PROTMESSID_CLM_PING_MS_WITHNUMCLIENTS Protocol.CreateCLPingWithNumClientsMes ( CurHostAddress, GenRandomIntInRange ( -2, 1000 ), GenRandomIntInRange ( -2, 1000 ) ); break; case 16: // PROTMESSID_CLM_SERVER_FULL Protocol.CreateCLServerFullMes ( CurHostAddress ); break; case 17: // PROTMESSID_CLM_REGISTER_SERVER ServerInfo.bPermanentOnline = static_cast ( GenRandomIntInRange ( 0, 1 ) ); ServerInfo.eCountry = static_cast ( GenRandomIntInRange ( 0, 100 ) ); ServerInfo.iMaxNumClients = GenRandomIntInRange ( -2, 10000 ); ServerInfo.strCity = GenRandomString(); ServerInfo.strName = GenRandomString(); Protocol.CreateCLRegisterServerMes ( CurHostAddress, CurLocalAddress, ServerInfo ); break; case 18: // PROTMESSID_CLM_UNREGISTER_SERVER Protocol.CreateCLUnregisterServerMes ( CurHostAddress ); break; case 19: // PROTMESSID_CLM_SERVER_LIST vecServerInfo[0].bPermanentOnline = static_cast ( GenRandomIntInRange ( 0, 1 ) ); vecServerInfo[0].eCountry = static_cast ( GenRandomIntInRange ( 0, 100 ) ); vecServerInfo[0].HostAddr = CurHostAddress; vecServerInfo[0].LHostAddr = CurLocalAddress; vecServerInfo[0].iMaxNumClients = GenRandomIntInRange ( -2, 10000 ); vecServerInfo[0].strCity = GenRandomString(); vecServerInfo[0].strName = GenRandomString(); Protocol.CreateCLServerListMes ( CurHostAddress, vecServerInfo ); break; case 20: // PROTMESSID_CLM_REQ_SERVER_LIST Protocol.CreateCLReqServerListMes ( CurHostAddress ); break; case 21: // PROTMESSID_CLM_SEND_EMPTY_MESSAGE Protocol.CreateCLSendEmptyMesMes ( CurHostAddress, CurHostAddress ); break; case 22: // PROTMESSID_CLM_EMPTY_MESSAGE Protocol.CreateCLEmptyMes ( CurHostAddress ); break; case 23: // PROTMESSID_CLM_DISCONNECTION Protocol.CreateCLDisconnection ( CurHostAddress ); break; case 24: // PROTMESSID_CLM_VERSION_AND_OS Protocol.CreateCLVersionAndOSMes ( CurHostAddress ); break; case 25: // PROTMESSID_CLM_REQ_VERSION_AND_OS Protocol.CreateCLReqVersionAndOSMes ( CurHostAddress ); break; case 26: // PROTMESSID_ACKN Protocol.CreateAndImmSendAcknMess ( GenRandomIntInRange ( -10, 100 ), GenRandomIntInRange ( -100, 100 ) ); break; case 27: { // arbitrary "audio" packet (with random sizes) CVector vecMessage ( GenRandomIntInRange ( 1, 1000 ) ); OnSendProtMessage ( vecMessage ); break; } case 28: // PROTMESSID_CLM_CONN_CLIENTS_LIST vecChanInfo[0].iChanID = GenRandomIntInRange ( -2, 20 ); vecChanInfo[0].strName = GenRandomString(); Protocol.CreateCLConnClientsListMes ( CurHostAddress, vecChanInfo ); break; case 29: // PROTMESSID_CLM_REQ_CONN_CLIENTS_LIST Protocol.CreateCLReqConnClientsListMes ( CurHostAddress ); break; case 30: // PROTMESSID_CLM_CHANNEL_LEVEL_LIST vecLevelList[0] = GenRandomIntInRange ( 0, 0xF ); Protocol.CreateCLChannelLevelListMes ( CurHostAddress, vecLevelList, 1 ); break; case 31: // PROTMESSID_CLM_REGISTER_SERVER_RESP eSvrRegResult = static_cast ( GenRandomIntInRange ( 0, 1 ) ); Protocol.CreateCLRegisterServerResp ( CurHostAddress, eSvrRegResult ); break; case 32: // PROTMESSID_CHANNEL_PAN Protocol.CreateChanPanMes ( GenRandomIntInRange ( -2, 20 ), GenRandomIntInRange ( 0, 32767 ) ); break; case 33: // PROTMESSID_MUTE_STATE_CHANGED Protocol.CreateMuteStateHasChangedMes ( GenRandomIntInRange ( -2, 20 ), GenRandomIntInRange ( 0, 1 ) ); break; case 34: // PROTMESSID_CLIENT_ID Protocol.CreateClientIDMes ( GenRandomIntInRange ( -2, 20 ) ); break; } } void OnSendProtMessage ( CVector vecMessage ) { UdpSocket.writeDatagram ( (const char*) &( (CVector) vecMessage )[0], vecMessage.Size(), QHostAddress ( sAddress ), iPort ); // reset protocol so that we do not have to wait for an acknowledge to // send the next message Protocol.Reset(); } void OnSendCLMessage ( CHostAddress, CVector vecMessage ) { OnSendProtMessage ( vecMessage ); } }; jamulus-3.9.1+dfsg/src/clientdlg.cpp0000644000175000017500000016364714340334543016435 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include "clientdlg.h" /* Implementation *************************************************************/ CClientDlg::CClientDlg ( CClient* pNCliP, CClientSettings* pNSetP, const QString& strConnOnStartupAddress, const QString& strMIDISetup, const bool bNewShowComplRegConnList, const bool bShowAnalyzerConsole, const bool bMuteStream, const bool bNEnableIPv6, QWidget* parent ) : CBaseDlg ( parent, Qt::Window ), // use Qt::Window to get min/max window buttons pClient ( pNCliP ), pSettings ( pNSetP ), bConnectDlgWasShown ( false ), bDetectFeedback ( false ), bEnableIPv6 ( bNEnableIPv6 ), eLastRecorderState ( RS_UNDEFINED ), // for SetMixerBoardDeco eLastDesign ( GD_ORIGINAL ), // " ClientSettingsDlg ( pNCliP, pNSetP, parent ), ChatDlg ( parent ), ConnectDlg ( pNSetP, bNewShowComplRegConnList, parent ), AnalyzerConsole ( pNCliP, parent ) { setupUi ( this ); // Add help text to controls ----------------------------------------------- // input level meter QString strInpLevH = "" + tr ( "Input Level Meter" ) + ": " + tr ( "This shows " "the level of the two stereo channels " "for your audio input." ) + "
" + tr ( "Make sure not to clip the input signal to avoid distortions of the " "audio signal." ); QString strInpLevHTT = tr ( "If the application " "is connected to a server and " "you play your instrument/sing into the microphone, the VU " "meter should flicker. If this is not the case, you have " "probably selected the wrong input channel (e.g. 'line in' instead " "of the microphone input) or set the input gain too low in the " "(Windows) audio mixer." ) + "
" + tr ( "For proper usage of the " "application, you should not hear your singing/instrument through " "the loudspeaker or your headphone when the software is not connected. " "This can be achieved by muting your input audio channel in the " "Playback mixer (not the Recording mixer!)." ) + TOOLTIP_COM_END_TEXT; QString strInpLevHAccText = tr ( "Input level meter" ); QString strInpLevHAccDescr = tr ( "Simulates an analog LED level meter." ); lblInputLEDMeter->setWhatsThis ( strInpLevH ); lblLevelMeterLeft->setWhatsThis ( strInpLevH ); lblLevelMeterRight->setWhatsThis ( strInpLevH ); lbrInputLevelL->setWhatsThis ( strInpLevH ); lbrInputLevelL->setAccessibleName ( strInpLevHAccText ); lbrInputLevelL->setAccessibleDescription ( strInpLevHAccDescr ); lbrInputLevelL->setToolTip ( strInpLevHTT ); lbrInputLevelL->setEnabled ( false ); lbrInputLevelR->setWhatsThis ( strInpLevH ); lbrInputLevelR->setAccessibleName ( strInpLevHAccText ); lbrInputLevelR->setAccessibleDescription ( strInpLevHAccDescr ); lbrInputLevelR->setToolTip ( strInpLevHTT ); lbrInputLevelR->setEnabled ( false ); // connect/disconnect button butConnect->setWhatsThis ( "" + tr ( "Connect/Disconnect Button" ) + ": " + tr ( "Opens a dialog where you can select a server to connect to. " "If you are connected, pressing this button will end the session." ) ); butConnect->setAccessibleName ( tr ( "Connect and disconnect toggle button" ) ); // reverberation level QString strAudReverb = "" + tr ( "Reverb effect" ) + ": " + tr ( "Reverb can be applied to one local mono audio channel or to both " "channels in stereo mode. The mono channel selection and the " "reverb level can be modified. For example, if " "a microphone signal is fed in to the right audio channel of the " "sound card and a reverb effect needs to be applied, set the " "channel selector to right and move the fader upwards until the " "desired reverb level is reached." ); lblAudioReverb->setWhatsThis ( strAudReverb ); sldAudioReverb->setWhatsThis ( strAudReverb ); sldAudioReverb->setAccessibleName ( tr ( "Reverb effect level setting" ) ); // reverberation channel selection QString strRevChanSel = "" + tr ( "Reverb Channel Selection" ) + ": " + tr ( "With these radio buttons the audio input channel on which the " "reverb effect is applied can be chosen. Either the left " "or right input channel can be selected." ); rbtReverbSelL->setWhatsThis ( strRevChanSel ); rbtReverbSelL->setAccessibleName ( tr ( "Left channel selection for reverb" ) ); rbtReverbSelR->setWhatsThis ( strRevChanSel ); rbtReverbSelR->setAccessibleName ( tr ( "Right channel selection for reverb" ) ); // delay LED QString strLEDDelay = "" + tr ( "Delay Status LED" ) + ": " + tr ( "Shows the current audio delay status:" ) + "
    " "
  • " "" + tr ( "Green" ) + ": " + tr ( "The delay is perfect for a jam " "session." ) + "
  • " "
  • " "" + tr ( "Yellow" ) + ": " + tr ( "A session is still possible " "but it may be harder to play." ) + "
  • " "
  • " "" + tr ( "Red" ) + ": " + tr ( "The delay is too large for " "jamming." ) + "
  • " "
"; lblDelay->setWhatsThis ( strLEDDelay ); ledDelay->setWhatsThis ( strLEDDelay ); ledDelay->setToolTip ( tr ( "If this LED indicator turns red, " "you will not have much fun using %1." ) .arg ( APP_NAME ) + TOOLTIP_COM_END_TEXT ); ledDelay->setAccessibleName ( tr ( "Delay status LED indicator" ) ); // buffers LED QString strLEDBuffers = "" + tr ( "Local Jitter Buffer Status LED" ) + ": " + tr ( "The local jitter buffer status LED shows the current audio/streaming " "status. If the light is red, the audio stream is interrupted. " "This is caused by one of the following problems:" ) + "
    " "
  • " + tr ( "The network jitter buffer is not large enough for the current " "network/audio interface jitter." ) + "
  • " "
  • " + tr ( "The sound card's buffer delay (buffer size) is too small " "(see Settings window)." ) + "
  • " "
  • " + tr ( "The upload or download stream rate is too high for your " "internet bandwidth." ) + "
  • " "
  • " + tr ( "The CPU of the client or server is at 100%." ) + "
  • " "
"; lblBuffers->setWhatsThis ( strLEDBuffers ); ledBuffers->setWhatsThis ( strLEDBuffers ); ledBuffers->setToolTip ( tr ( "If this LED indicator turns red, " "the audio stream is interrupted." ) + TOOLTIP_COM_END_TEXT ); ledBuffers->setAccessibleName ( tr ( "Local Jitter Buffer status LED indicator" ) ); // current connection status details QString strConnStats = "" + tr ( "Current Connection Status" ) + ": " + tr ( "The Ping Time is the time required for the audio " "stream to travel from the client to the server and back again. This " "delay is introduced by the network and should be about " "20-30 ms. If this delay is higher than about 50 ms, your distance to " "the server is too large or your internet connection is not " "sufficient." ) + "
" + tr ( "Overall Delay is calculated from the current Ping Time and the " "delay introduced by the current buffer settings." ); lblPing->setWhatsThis ( strConnStats ); lblPingVal->setWhatsThis ( strConnStats ); lblDelay->setWhatsThis ( strConnStats ); lblDelayVal->setWhatsThis ( strConnStats ); lblPingVal->setText ( "---" ); lblPingUnit->setText ( "" ); lblDelayVal->setText ( "---" ); lblDelayUnit->setText ( "" ); // init GUI design SetGUIDesign ( pClient->GetGUIDesign() ); // MeterStyle init SetMeterStyle ( pClient->GetMeterStyle() ); // set the settings pointer to the mixer board (must be done early) MainMixerBoard->SetSettingsPointer ( pSettings ); MainMixerBoard->SetNumMixerPanelRows ( pSettings->iNumMixerPanelRows ); // Pass through flag for MIDICtrlUsed MainMixerBoard->SetMIDICtrlUsed ( !strMIDISetup.isEmpty() ); // reset mixer board MainMixerBoard->HideAll(); // init status label OnTimerStatus(); // init connection button text butConnect->setText ( tr ( "C&onnect" ) ); // init input level meter bars lbrInputLevelL->SetValue ( 0 ); lbrInputLevelR->SetValue ( 0 ); // init status LEDs ledBuffers->Reset(); ledDelay->Reset(); // init audio reverberation sldAudioReverb->setRange ( 0, AUD_REVERB_MAX ); const int iCurAudReverb = pClient->GetReverbLevel(); sldAudioReverb->setValue ( iCurAudReverb ); sldAudioReverb->setTickInterval ( AUD_REVERB_MAX / 5 ); // init input boost pClient->SetInputBoost ( pSettings->iInputBoost ); // init reverb channel UpdateRevSelection(); // init connect dialog ConnectDlg.SetShowAllMusicians ( pSettings->bConnectDlgShowAllMusicians ); // set window title (with no clients connected -> "0") SetMyWindowTitle ( 0 ); // track number of clients to detect joins/leaves for audio alerts iClients = 0; // prepare Mute Myself info label (invisible by default) lblGlobalInfoLabel->setStyleSheet ( ".QLabel { background: red; }" ); lblGlobalInfoLabel->hide(); // prepare update check info label (invisible by default) lblUpdateCheck->setOpenExternalLinks ( true ); // enables opening a web browser if one clicks on a html link lblUpdateCheck->setText ( "" + APP_UPGRADE_AVAILABLE_MSG_TEXT.arg ( APP_NAME ).arg ( VERSION ) + "" ); lblUpdateCheck->hide(); // setup timers TimerCheckAudioDeviceOk.setSingleShot ( true ); // only check once after connection TimerDetectFeedback.setSingleShot ( true ); // Connect on startup ------------------------------------------------------ if ( !strConnOnStartupAddress.isEmpty() ) { // initiate connection (always show the address in the mixer board // (no alias)) Connect ( strConnOnStartupAddress, strConnOnStartupAddress ); } // File menu -------------------------------------------------------------- QMenu* pFileMenu = new QMenu ( tr ( "&File" ), this ); pFileMenu->addAction ( tr ( "&Connection Setup..." ), this, SLOT ( OnOpenConnectionSetupDialog() ), QKeySequence ( Qt::CTRL + Qt::Key_C ) ); pFileMenu->addSeparator(); pFileMenu->addAction ( tr ( "&Load Mixer Channels Setup..." ), this, SLOT ( OnLoadChannelSetup() ) ); pFileMenu->addAction ( tr ( "&Save Mixer Channels Setup..." ), this, SLOT ( OnSaveChannelSetup() ) ); pFileMenu->addSeparator(); pFileMenu->addAction ( tr ( "E&xit" ), this, SLOT ( close() ), QKeySequence ( Qt::CTRL + Qt::Key_Q ) ); // Edit menu -------------------------------------------------------------- QMenu* pEditMenu = new QMenu ( tr ( "&Edit" ), this ); pEditMenu->addAction ( tr ( "Clear &All Stored Solo and Mute Settings" ), this, SLOT ( OnClearAllStoredSoloMuteSettings() ) ); pEditMenu->addAction ( tr ( "Set All Faders to New Client &Level" ), this, SLOT ( OnSetAllFadersToNewClientLevel() ), QKeySequence ( Qt::CTRL + Qt::Key_L ) ); pEditMenu->addAction ( tr ( "Auto-Adjust all &Faders" ), this, SLOT ( OnAutoAdjustAllFaderLevels() ), QKeySequence ( Qt::CTRL + Qt::Key_F ) ); // View menu -------------------------------------------------------------- QMenu* pViewMenu = new QMenu ( tr ( "&View" ), this ); // own fader first option: works from server version 3.5.5 which supports sending client ID back to client QAction* OwnFaderFirstAction = pViewMenu->addAction ( tr ( "O&wn Fader First" ), this, SLOT ( OnOwnFaderFirst() ), QKeySequence ( Qt::CTRL + Qt::Key_W ) ); pViewMenu->addSeparator(); QAction* NoSortAction = pViewMenu->addAction ( tr ( "N&o User Sorting" ), this, SLOT ( OnNoSortChannels() ), QKeySequence ( Qt::CTRL + Qt::Key_O ) ); QAction* ByNameAction = pViewMenu->addAction ( tr ( "Sort Users by &Name" ), this, SLOT ( OnSortChannelsByName() ), QKeySequence ( Qt::CTRL + Qt::Key_N ) ); QAction* ByInstrAction = pViewMenu->addAction ( tr ( "Sort Users by &Instrument" ), this, SLOT ( OnSortChannelsByInstrument() ), QKeySequence ( Qt::CTRL + Qt::Key_I ) ); QAction* ByGroupAction = pViewMenu->addAction ( tr ( "Sort Users by &Group" ), this, SLOT ( OnSortChannelsByGroupID() ), QKeySequence ( Qt::CTRL + Qt::Key_G ) ); QAction* ByCityAction = pViewMenu->addAction ( tr ( "Sort Users by &City" ), this, SLOT ( OnSortChannelsByCity() ), QKeySequence ( Qt::CTRL + Qt::Key_T ) ); OwnFaderFirstAction->setCheckable ( true ); OwnFaderFirstAction->setChecked ( pSettings->bOwnFaderFirst ); // the sorting menu entries shall be checkable and exclusive QActionGroup* SortActionGroup = new QActionGroup ( this ); SortActionGroup->setExclusive ( true ); NoSortAction->setCheckable ( true ); SortActionGroup->addAction ( NoSortAction ); ByNameAction->setCheckable ( true ); SortActionGroup->addAction ( ByNameAction ); ByInstrAction->setCheckable ( true ); SortActionGroup->addAction ( ByInstrAction ); ByGroupAction->setCheckable ( true ); SortActionGroup->addAction ( ByGroupAction ); ByCityAction->setCheckable ( true ); SortActionGroup->addAction ( ByCityAction ); // initialize sort type setting (i.e., recover stored setting) switch ( pSettings->eChannelSortType ) { case ST_NO_SORT: NoSortAction->setChecked ( true ); break; case ST_BY_NAME: ByNameAction->setChecked ( true ); break; case ST_BY_INSTRUMENT: ByInstrAction->setChecked ( true ); break; case ST_BY_GROUPID: ByGroupAction->setChecked ( true ); break; case ST_BY_CITY: ByCityAction->setChecked ( true ); break; } MainMixerBoard->SetFaderSorting ( pSettings->eChannelSortType ); pViewMenu->addSeparator(); pViewMenu->addAction ( tr ( "C&hat..." ), this, SLOT ( OnOpenChatDialog() ), QKeySequence ( Qt::CTRL + Qt::Key_H ) ); // optionally show analyzer console entry if ( bShowAnalyzerConsole ) { pViewMenu->addAction ( tr ( "&Analyzer Console..." ), this, SLOT ( OnOpenAnalyzerConsole() ) ); } pViewMenu->addSeparator(); // Settings menu -------------------------------------------------------------- QMenu* pSettingsMenu = new QMenu ( tr ( "Sett&ings" ), this ); pSettingsMenu->addAction ( tr ( "My &Profile..." ), this, SLOT ( OnOpenUserProfileSettings() ), QKeySequence ( Qt::CTRL + Qt::Key_P ) ); pSettingsMenu->addAction ( tr ( "Audio/Network &Settings..." ), this, SLOT ( OnOpenAudioNetSettings() ), QKeySequence ( Qt::CTRL + Qt::Key_S ) ); pSettingsMenu->addAction ( tr ( "A&dvanced Settings..." ), this, SLOT ( OnOpenAdvancedSettings() ), QKeySequence ( Qt::CTRL + Qt::Key_D ) ); // Main menu bar ----------------------------------------------------------- QMenuBar* pMenu = new QMenuBar ( this ); pMenu->addMenu ( pFileMenu ); pMenu->addMenu ( pEditMenu ); pMenu->addMenu ( pViewMenu ); pMenu->addMenu ( pSettingsMenu ); pMenu->addMenu ( new CHelpMenu ( true, this ) ); // Now tell the layout about the menu layout()->setMenuBar ( pMenu ); // Window positions -------------------------------------------------------- // main window if ( !pSettings->vecWindowPosMain.isEmpty() && !pSettings->vecWindowPosMain.isNull() ) { restoreGeometry ( pSettings->vecWindowPosMain ); } // settings window if ( !pSettings->vecWindowPosSettings.isEmpty() && !pSettings->vecWindowPosSettings.isNull() ) { ClientSettingsDlg.restoreGeometry ( pSettings->vecWindowPosSettings ); } if ( pSettings->bWindowWasShownSettings ) { ShowGeneralSettings ( pSettings->iSettingsTab ); } // chat window if ( !pSettings->vecWindowPosChat.isEmpty() && !pSettings->vecWindowPosChat.isNull() ) { ChatDlg.restoreGeometry ( pSettings->vecWindowPosChat ); } if ( pSettings->bWindowWasShownChat ) { ShowChatWindow(); } // connection setup window if ( !pSettings->vecWindowPosConnect.isEmpty() && !pSettings->vecWindowPosConnect.isNull() ) { ConnectDlg.restoreGeometry ( pSettings->vecWindowPosConnect ); } // Connections ------------------------------------------------------------- // push buttons QObject::connect ( butConnect, &QPushButton::clicked, this, &CClientDlg::OnConnectDisconBut ); // check boxes QObject::connect ( chbSettings, &QCheckBox::stateChanged, this, &CClientDlg::OnSettingsStateChanged ); QObject::connect ( chbChat, &QCheckBox::stateChanged, this, &CClientDlg::OnChatStateChanged ); QObject::connect ( chbLocalMute, &QCheckBox::stateChanged, this, &CClientDlg::OnLocalMuteStateChanged ); // timers QObject::connect ( &TimerSigMet, &QTimer::timeout, this, &CClientDlg::OnTimerSigMet ); QObject::connect ( &TimerBuffersLED, &QTimer::timeout, this, &CClientDlg::OnTimerBuffersLED ); QObject::connect ( &TimerStatus, &QTimer::timeout, this, &CClientDlg::OnTimerStatus ); QObject::connect ( &TimerPing, &QTimer::timeout, this, &CClientDlg::OnTimerPing ); QObject::connect ( &TimerCheckAudioDeviceOk, &QTimer::timeout, this, &CClientDlg::OnTimerCheckAudioDeviceOk ); QObject::connect ( &TimerDetectFeedback, &QTimer::timeout, this, &CClientDlg::OnTimerDetectFeedback ); QObject::connect ( sldAudioReverb, &QSlider::valueChanged, this, &CClientDlg::OnAudioReverbValueChanged ); // radio buttons QObject::connect ( rbtReverbSelL, &QRadioButton::clicked, this, &CClientDlg::OnReverbSelLClicked ); QObject::connect ( rbtReverbSelR, &QRadioButton::clicked, this, &CClientDlg::OnReverbSelRClicked ); // other QObject::connect ( pClient, &CClient::ConClientListMesReceived, this, &CClientDlg::OnConClientListMesReceived ); QObject::connect ( pClient, &CClient::Disconnected, this, &CClientDlg::OnDisconnected ); QObject::connect ( pClient, &CClient::ChatTextReceived, this, &CClientDlg::OnChatTextReceived ); QObject::connect ( pClient, &CClient::ClientIDReceived, this, &CClientDlg::OnClientIDReceived ); QObject::connect ( pClient, &CClient::MuteStateHasChangedReceived, this, &CClientDlg::OnMuteStateHasChangedReceived ); QObject::connect ( pClient, &CClient::RecorderStateReceived, this, &CClientDlg::OnRecorderStateReceived ); // This connection is a special case. On receiving a licence required message via the // protocol, a modal licence dialog is opened. Since this blocks the thread, we need // a queued connection to make sure the core protocol mechanism is not blocked, too. qRegisterMetaType ( "ELicenceType" ); QObject::connect ( pClient, &CClient::LicenceRequired, this, &CClientDlg::OnLicenceRequired, Qt::QueuedConnection ); QObject::connect ( pClient, &CClient::PingTimeReceived, this, &CClientDlg::OnPingTimeResult ); QObject::connect ( pClient, &CClient::CLServerListReceived, this, &CClientDlg::OnCLServerListReceived ); QObject::connect ( pClient, &CClient::CLRedServerListReceived, this, &CClientDlg::OnCLRedServerListReceived ); QObject::connect ( pClient, &CClient::CLConnClientsListMesReceived, this, &CClientDlg::OnCLConnClientsListMesReceived ); QObject::connect ( pClient, &CClient::CLPingTimeWithNumClientsReceived, this, &CClientDlg::OnCLPingTimeWithNumClientsReceived ); QObject::connect ( pClient, &CClient::ControllerInFaderLevel, this, &CClientDlg::OnControllerInFaderLevel ); QObject::connect ( pClient, &CClient::ControllerInPanValue, this, &CClientDlg::OnControllerInPanValue ); QObject::connect ( pClient, &CClient::ControllerInFaderIsSolo, this, &CClientDlg::OnControllerInFaderIsSolo ); QObject::connect ( pClient, &CClient::ControllerInFaderIsMute, this, &CClientDlg::OnControllerInFaderIsMute ); QObject::connect ( pClient, &CClient::ControllerInMuteMyself, this, &CClientDlg::OnControllerInMuteMyself ); QObject::connect ( pClient, &CClient::CLChannelLevelListReceived, this, &CClientDlg::OnCLChannelLevelListReceived ); QObject::connect ( pClient, &CClient::VersionAndOSReceived, this, &CClientDlg::OnVersionAndOSReceived ); QObject::connect ( pClient, &CClient::CLVersionAndOSReceived, this, &CClientDlg::OnCLVersionAndOSReceived ); QObject::connect ( pClient, &CClient::SoundDeviceChanged, this, &CClientDlg::OnSoundDeviceChanged ); QObject::connect ( &ClientSettingsDlg, &CClientSettingsDlg::GUIDesignChanged, this, &CClientDlg::OnGUIDesignChanged ); QObject::connect ( &ClientSettingsDlg, &CClientSettingsDlg::MeterStyleChanged, this, &CClientDlg::OnMeterStyleChanged ); QObject::connect ( &ClientSettingsDlg, &CClientSettingsDlg::AudioChannelsChanged, this, &CClientDlg::OnAudioChannelsChanged ); QObject::connect ( &ClientSettingsDlg, &CClientSettingsDlg::CustomDirectoriesChanged, &ConnectDlg, &CConnectDlg::OnCustomDirectoriesChanged ); QObject::connect ( &ClientSettingsDlg, &CClientSettingsDlg::NumMixerPanelRowsChanged, this, &CClientDlg::OnNumMixerPanelRowsChanged ); QObject::connect ( this, &CClientDlg::SendTabChange, &ClientSettingsDlg, &CClientSettingsDlg::OnMakeTabChange ); QObject::connect ( MainMixerBoard, &CAudioMixerBoard::ChangeChanGain, this, &CClientDlg::OnChangeChanGain ); QObject::connect ( MainMixerBoard, &CAudioMixerBoard::ChangeChanPan, this, &CClientDlg::OnChangeChanPan ); QObject::connect ( MainMixerBoard, &CAudioMixerBoard::NumClientsChanged, this, &CClientDlg::OnNumClientsChanged ); QObject::connect ( &ChatDlg, &CChatDlg::NewLocalInputText, this, &CClientDlg::OnNewLocalInputText ); QObject::connect ( &ConnectDlg, &CConnectDlg::ReqServerListQuery, this, &CClientDlg::OnReqServerListQuery ); // note that this connection must be a queued connection, otherwise the server list ping // times are not accurate and the client list may not be retrieved for all servers listed // (it seems the sendto() function needs to be called from different threads to fire the // packet immediately and do not collect packets before transmitting) QObject::connect ( &ConnectDlg, &CConnectDlg::CreateCLServerListPingMes, this, &CClientDlg::OnCreateCLServerListPingMes, Qt::QueuedConnection ); QObject::connect ( &ConnectDlg, &CConnectDlg::CreateCLServerListReqVerAndOSMes, this, &CClientDlg::OnCreateCLServerListReqVerAndOSMes ); QObject::connect ( &ConnectDlg, &CConnectDlg::CreateCLServerListReqConnClientsListMes, this, &CClientDlg::OnCreateCLServerListReqConnClientsListMes ); QObject::connect ( &ConnectDlg, &CConnectDlg::accepted, this, &CClientDlg::OnConnectDlgAccepted ); // Initializations which have to be done after the signals are connected --- // start timer for status bar TimerStatus.start ( LED_BAR_UPDATE_TIME_MS ); // restore connect dialog if ( pSettings->bWindowWasShownConnect ) { ShowConnectionSetupDialog(); } // mute stream on startup (must be done after the signal connections) if ( bMuteStream ) { chbLocalMute->setCheckState ( Qt::Checked ); } // query the update server version number needed for update check (note // that the connection less message respond may not make it back but that // is not critical since the next time Jamulus is started we have another // chance and the update check is not time-critical at all) CHostAddress UpdateServerHostAddress; // Send the request to two servers for redundancy if either or both of them // has a higher release version number, the reply will trigger the notification. if ( NetworkUtil().ParseNetworkAddress ( UPDATECHECK1_ADDRESS, UpdateServerHostAddress, bEnableIPv6 ) ) { pClient->CreateCLServerListReqVerAndOSMes ( UpdateServerHostAddress ); } if ( NetworkUtil().ParseNetworkAddress ( UPDATECHECK2_ADDRESS, UpdateServerHostAddress, bEnableIPv6 ) ) { pClient->CreateCLServerListReqVerAndOSMes ( UpdateServerHostAddress ); } } void CClientDlg::closeEvent ( QCloseEvent* Event ) { // store window positions pSettings->vecWindowPosMain = saveGeometry(); pSettings->vecWindowPosSettings = ClientSettingsDlg.saveGeometry(); pSettings->vecWindowPosChat = ChatDlg.saveGeometry(); pSettings->vecWindowPosConnect = ConnectDlg.saveGeometry(); pSettings->bWindowWasShownSettings = ClientSettingsDlg.isVisible(); pSettings->bWindowWasShownChat = ChatDlg.isVisible(); pSettings->bWindowWasShownConnect = ConnectDlg.isVisible(); // if settings/connect dialog or chat dialog is open, close it ClientSettingsDlg.close(); ChatDlg.close(); ConnectDlg.close(); AnalyzerConsole.close(); // if connected, terminate connection if ( pClient->IsRunning() ) { pClient->Stop(); } // make sure all current fader settings are applied to the settings struct MainMixerBoard->StoreAllFaderSettings(); pSettings->bConnectDlgShowAllMusicians = ConnectDlg.GetShowAllMusicians(); pSettings->eChannelSortType = MainMixerBoard->GetFaderSorting(); pSettings->iNumMixerPanelRows = MainMixerBoard->GetNumMixerPanelRows(); // default implementation of this event handler routine Event->accept(); } void CClientDlg::ManageDragNDrop ( QDropEvent* Event, const bool bCheckAccept ) { // we only want to use drag'n'drop with file URLs QListIterator UrlIterator ( Event->mimeData()->urls() ); while ( UrlIterator.hasNext() ) { const QString strFileNameWithPath = UrlIterator.next().toLocalFile(); // check all given URLs and if any has the correct suffix if ( !strFileNameWithPath.isEmpty() && ( QFileInfo ( strFileNameWithPath ).suffix() == MIX_SETTINGS_FILE_SUFFIX ) ) { if ( bCheckAccept ) { // only accept drops of supports file types Event->acceptProposedAction(); } else { // load the first valid settings file and leave the loop pSettings->LoadFaderSettings ( strFileNameWithPath ); MainMixerBoard->LoadAllFaderSettings(); break; } } } } void CClientDlg::UpdateRevSelection() { if ( pClient->GetAudioChannels() == CC_STEREO ) { // for stereo make channel selection invisible since // reverberation effect is always applied to both channels rbtReverbSelL->setVisible ( false ); rbtReverbSelR->setVisible ( false ); } else { // make radio buttons visible rbtReverbSelL->setVisible ( true ); rbtReverbSelR->setVisible ( true ); // update value if ( pClient->IsReverbOnLeftChan() ) { rbtReverbSelL->setChecked ( true ); } else { rbtReverbSelR->setChecked ( true ); } } // update visibility of the pan controls in the audio mixer board (pan is not supported for mono) MainMixerBoard->SetDisplayPans ( pClient->GetAudioChannels() != CC_MONO ); } void CClientDlg::OnConnectDlgAccepted() { // We had an issue that the accepted signal was emit twice if a list item was double // clicked in the connect dialog. To avoid this we introduced a flag which makes sure // we process the accepted signal only once after the dialog was initially shown. if ( bConnectDlgWasShown ) { // get the address from the connect dialog QString strSelectedAddress = ConnectDlg.GetSelectedAddress(); // only store new host address in our data base if the address is // not empty and it was not a server list item (only the addresses // typed in manually are stored by definition) if ( !strSelectedAddress.isEmpty() && !ConnectDlg.GetServerListItemWasChosen() ) { // store new address at the top of the list, if the list was already // full, the last element is thrown out pSettings->vstrIPAddress.StringFiFoWithCompare ( strSelectedAddress ); } // get name to be set in audio mixer group box title QString strMixerBoardLabel; if ( ConnectDlg.GetServerListItemWasChosen() ) { // in case a server in the server list was chosen, // display the server name of the server list strMixerBoardLabel = ConnectDlg.GetSelectedServerName(); } else { // an item of the server address combo box was chosen, // just show the address string as it was entered by the // user strMixerBoardLabel = strSelectedAddress; // special case: if the address is empty, we substitute the default // directory address so that a user who just pressed the connect // button without selecting an item in the table or manually entered an // address gets a successful connection if ( strSelectedAddress.isEmpty() ) { strSelectedAddress = DEFAULT_SERVER_ADDRESS; strMixerBoardLabel = tr ( "%1 Directory" ).arg ( DirectoryTypeToString ( AT_DEFAULT ) ); } } // first check if we are already connected, if this is the case we have to // disconnect the old server first if ( pClient->IsRunning() ) { Disconnect(); } // initiate connection Connect ( strSelectedAddress, strMixerBoardLabel ); // reset flag bConnectDlgWasShown = false; } } void CClientDlg::OnConnectDisconBut() { // the connect/disconnect button implements a toggle functionality if ( pClient->IsRunning() ) { Disconnect(); SetMixerBoardDeco ( RS_UNDEFINED, pClient->GetGUIDesign() ); } else { ShowConnectionSetupDialog(); } } void CClientDlg::OnClearAllStoredSoloMuteSettings() { // if we are in an active connection, we first have to store all fader settings in // the settings struct, clear the solo and mute states and then apply the settings again MainMixerBoard->StoreAllFaderSettings(); pSettings->vecStoredFaderIsSolo.Reset ( false ); pSettings->vecStoredFaderIsMute.Reset ( false ); MainMixerBoard->LoadAllFaderSettings(); } void CClientDlg::OnLoadChannelSetup() { QString strFileName = QFileDialog::getOpenFileName ( this, tr ( "Select Channel Setup File" ), "", QString ( "*." ) + MIX_SETTINGS_FILE_SUFFIX ); if ( !strFileName.isEmpty() ) { // first update the settings struct and then update the mixer panel pSettings->LoadFaderSettings ( strFileName ); MainMixerBoard->LoadAllFaderSettings(); } } void CClientDlg::OnSaveChannelSetup() { QString strFileName = QFileDialog::getSaveFileName ( this, tr ( "Select Channel Setup File" ), "", QString ( "*." ) + MIX_SETTINGS_FILE_SUFFIX ); if ( !strFileName.isEmpty() ) { // first store all current fader settings (in case we are in an active connection // right now) and then save the information in the settings struct in the file MainMixerBoard->StoreAllFaderSettings(); pSettings->SaveFaderSettings ( strFileName ); } } void CClientDlg::OnVersionAndOSReceived ( COSUtil::EOpSystemType, QString strVersion ) { // check if Pan is supported by the server (minimum version is 3.5.4) #if QT_VERSION >= QT_VERSION_CHECK( 5, 6, 0 ) if ( QVersionNumber::compare ( QVersionNumber::fromString ( strVersion ), QVersionNumber ( 3, 5, 4 ) ) >= 0 ) { MainMixerBoard->SetPanIsSupported(); } #endif } void CClientDlg::OnCLVersionAndOSReceived ( CHostAddress, COSUtil::EOpSystemType, QString strVersion ) { // update check #if ( QT_VERSION >= QT_VERSION_CHECK( 5, 6, 0 ) ) && !defined( DISABLE_VERSION_CHECK ) int mySuffixIndex; QVersionNumber myVersion = QVersionNumber::fromString ( VERSION, &mySuffixIndex ); int serverSuffixIndex; QVersionNumber serverVersion = QVersionNumber::fromString ( strVersion, &serverSuffixIndex ); // only compare if the server version has no suffix (such as dev or beta) if ( strVersion.size() == serverSuffixIndex && QVersionNumber::compare ( serverVersion, myVersion ) > 0 ) { // show the label and hide it after one minute again lblUpdateCheck->show(); QTimer::singleShot ( 60000, [this]() { lblUpdateCheck->hide(); } ); } #endif } void CClientDlg::OnChatTextReceived ( QString strChatText ) { if ( pSettings->bEnableAudioAlerts ) { QSoundEffect* sf = new QSoundEffect(); sf->setSource ( QUrl::fromLocalFile ( ":sounds/res/sounds/new_message.wav" ) ); sf->play(); } ChatDlg.AddChatText ( strChatText ); // Open chat dialog. If a server welcome message is received, we force // the dialog to be upfront in case a licence text is shown. For all // other new chat texts we do not want to force the dialog to be upfront // always when a new message arrives since this is annoying. ShowChatWindow ( ( strChatText.indexOf ( WELCOME_MESSAGE_PREFIX ) == 0 ) ); UpdateDisplay(); } void CClientDlg::OnLicenceRequired ( ELicenceType eLicenceType ) { // right now only the creative common licence is supported if ( eLicenceType == LT_CREATIVECOMMONS ) { CLicenceDlg LicenceDlg; // mute the client output stream pClient->SetMuteOutStream ( true ); // Open the licence dialog and check if the licence was accepted. In // case the dialog is just closed or the decline button was pressed, // disconnect from that server. if ( !LicenceDlg.exec() ) { Disconnect(); } // unmute the client output stream if local mute button is not pressed if ( chbLocalMute->checkState() == Qt::Unchecked ) { pClient->SetMuteOutStream ( false ); } } } void CClientDlg::OnConClientListMesReceived ( CVector vecChanInfo ) { // update mixer board with the additional client infos MainMixerBoard->ApplyNewConClientList ( vecChanInfo ); } void CClientDlg::OnNumClientsChanged ( int iNewNumClients ) { if ( pSettings->bEnableAudioAlerts && iNewNumClients > iClients ) { QSoundEffect* sf = new QSoundEffect(); sf->setSource ( QUrl::fromLocalFile ( ":sounds/res/sounds/new_user.wav" ) ); sf->play(); } // iNewNumClients will be zero on the first trigger of this signal handler when connecting to a new server. // Subsequent triggers will thus sound the alert (if enabled). iClients = iNewNumClients; // update window title SetMyWindowTitle ( iNewNumClients ); } void CClientDlg::OnOpenAudioNetSettings() { ShowGeneralSettings ( SETTING_TAB_AUDIONET ); } void CClientDlg::OnOpenAdvancedSettings() { ShowGeneralSettings ( SETTING_TAB_ADVANCED ); } void CClientDlg::OnOpenUserProfileSettings() { ShowGeneralSettings ( SETTING_TAB_USER ); } void CClientDlg::SetMyWindowTitle ( const int iNumClients ) { // set the window title (and therefore also the task bar icon text of the OS) // according to the following specification (#559): // - users - Jamulus QString strWinTitle; const bool bClientNameIsUsed = !pClient->strClientName.isEmpty(); if ( bClientNameIsUsed ) { // if --clientname is used, the APP_NAME must be the very first word in // the title, otherwise some user scripts do not work anymore, see #789 strWinTitle += QString ( APP_NAME ) + " - " + pClient->strClientName + " "; } if ( iNumClients == 0 ) { // only application name if ( !bClientNameIsUsed ) // if --clientname is used, the APP_NAME is the first word in title { strWinTitle += QString ( APP_NAME ); } } else { strWinTitle += MainMixerBoard->GetServerName(); if ( iNumClients == 1 ) { strWinTitle += " - 1 " + tr ( "user" ); } else if ( iNumClients > 1 ) { strWinTitle += " - " + QString::number ( iNumClients ) + " " + tr ( "users" ); } if ( !bClientNameIsUsed ) // if --clientname is used, the APP_NAME is the first word in title { strWinTitle += " - " + QString ( APP_NAME ); } } setWindowTitle ( strWinTitle ); #if defined( Q_OS_MACX ) // for MacOS only we show the number of connected clients as a // badge label text if more than one user is connected if ( iNumClients > 1 ) { // show the number of connected clients SetMacBadgeLabelText ( QString ( "%1" ).arg ( iNumClients ) ); } else { // clear the text (apply an empty string) SetMacBadgeLabelText ( "" ); } #endif } void CClientDlg::ShowConnectionSetupDialog() { // show connect dialog bConnectDlgWasShown = true; ConnectDlg.show(); ConnectDlg.setWindowTitle ( MakeClientNameTitle ( tr ( "Connect" ), pClient->strClientName ) ); // make sure dialog is upfront and has focus ConnectDlg.raise(); ConnectDlg.activateWindow(); } void CClientDlg::ShowGeneralSettings ( int iTab ) { // open general settings dialog emit SendTabChange ( iTab ); ClientSettingsDlg.show(); ClientSettingsDlg.setWindowTitle ( MakeClientNameTitle ( tr ( "Settings" ), pClient->strClientName ) ); // make sure dialog is upfront and has focus ClientSettingsDlg.raise(); ClientSettingsDlg.activateWindow(); } void CClientDlg::ShowChatWindow ( const bool bForceRaise ) { ChatDlg.show(); ChatDlg.setWindowTitle ( MakeClientNameTitle ( tr ( "Chat" ), pClient->strClientName ) ); if ( bForceRaise ) { // make sure dialog is upfront and has focus ChatDlg.showNormal(); ChatDlg.raise(); ChatDlg.activateWindow(); } UpdateDisplay(); } void CClientDlg::ShowAnalyzerConsole() { // open analyzer console dialog AnalyzerConsole.show(); // make sure dialog is upfront and has focus AnalyzerConsole.raise(); AnalyzerConsole.activateWindow(); } void CClientDlg::OnSettingsStateChanged ( int value ) { if ( value == Qt::Checked ) { ShowGeneralSettings ( SETTING_TAB_AUDIONET ); } else { ClientSettingsDlg.hide(); } } void CClientDlg::OnChatStateChanged ( int value ) { if ( value == Qt::Checked ) { ShowChatWindow(); } else { ChatDlg.hide(); } } void CClientDlg::OnLocalMuteStateChanged ( int value ) { pClient->SetMuteOutStream ( value == Qt::Checked ); // show/hide info label if ( value == Qt::Checked ) { lblGlobalInfoLabel->show(); } else { lblGlobalInfoLabel->hide(); } } void CClientDlg::OnTimerSigMet() { // show current level lbrInputLevelL->SetValue ( pClient->GetLevelForMeterdBLeft() ); lbrInputLevelR->SetValue ( pClient->GetLevelForMeterdBRight() ); if ( bDetectFeedback && ( pClient->GetLevelForMeterdBLeft() > NUM_STEPS_LED_BAR - 0.5 || pClient->GetLevelForMeterdBRight() > NUM_STEPS_LED_BAR - 0.5 ) ) { // mute locally and mute channel chbLocalMute->setCheckState ( Qt::Checked ); MainMixerBoard->MuteMyChannel(); // show message box about feedback issue QCheckBox* chb = new QCheckBox ( tr ( "Enable feedback detection" ) ); chb->setCheckState ( pSettings->bEnableFeedbackDetection ? Qt::Checked : Qt::Unchecked ); QMessageBox msgbox; msgbox.setText ( tr ( "Audio feedback or loud signal detected.\n\n" "We muted your channel and activated 'Mute Myself'. Please solve " "the feedback issue first and unmute yourself afterwards." ) ); msgbox.setIcon ( QMessageBox::Icon::Warning ); msgbox.addButton ( QMessageBox::Ok ); msgbox.setDefaultButton ( QMessageBox::Ok ); msgbox.setCheckBox ( chb ); QObject::connect ( chb, &QCheckBox::stateChanged, this, &CClientDlg::OnFeedbackDetectionChanged ); msgbox.exec(); } } void CClientDlg::OnTimerBuffersLED() { CMultiColorLED::ELightColor eCurStatus; // get and reset current buffer state and set LED from that flag if ( pClient->GetAndResetbJitterBufferOKFlag() ) { eCurStatus = CMultiColorLED::RL_GREEN; } else { eCurStatus = CMultiColorLED::RL_RED; } // update the buffer LED and the general settings dialog, too ledBuffers->SetLight ( eCurStatus ); } void CClientDlg::OnTimerPing() { // send ping message to the server pClient->CreateCLPingMes(); } void CClientDlg::OnPingTimeResult ( int iPingTime ) { // calculate overall delay const int iOverallDelayMs = pClient->EstimatedOverallDelay ( iPingTime ); // color definition: <= 43 ms green, <= 68 ms yellow, otherwise red CMultiColorLED::ELightColor eOverallDelayLEDColor; if ( iOverallDelayMs <= 43 ) { eOverallDelayLEDColor = CMultiColorLED::RL_GREEN; } else { if ( iOverallDelayMs <= 68 ) { eOverallDelayLEDColor = CMultiColorLED::RL_YELLOW; } else { eOverallDelayLEDColor = CMultiColorLED::RL_RED; } } // only update delay information on settings dialog if it is visible to // avoid CPU load on working thread if not necessary if ( ClientSettingsDlg.isVisible() ) { // set ping time result to general settings dialog ClientSettingsDlg.UpdateUploadRate(); } SetPingTime ( iPingTime, iOverallDelayMs, eOverallDelayLEDColor ); // update delay LED on the main window ledDelay->SetLight ( eOverallDelayLEDColor ); } void CClientDlg::OnTimerCheckAudioDeviceOk() { // check if the audio device entered the audio callback after a pre-defined // timeout to check if a valid device is selected and if we do not have // fundamental settings errors (in which case the GUI would only show that // it is trying to connect the server which does not help to solve the problem (#129)) if ( !pClient->IsCallbackEntered() ) { QMessageBox::warning ( this, APP_NAME, tr ( "Your sound card is not working correctly. " "Please open the settings dialog and check the device selection and the driver settings." ) ); } } void CClientDlg::OnTimerDetectFeedback() { bDetectFeedback = false; } void CClientDlg::OnSoundDeviceChanged ( QString strError ) { if ( !strError.isEmpty() ) { // the sound device setup has a problem, disconnect any active connection if ( pClient->IsRunning() ) { Disconnect(); } // show the error message of the device setup QMessageBox::critical ( this, APP_NAME, strError, tr ( "Ok" ), nullptr ); } // if the check audio device timer is running, it must be restarted on a device change if ( TimerCheckAudioDeviceOk.isActive() ) { TimerCheckAudioDeviceOk.start ( CHECK_AUDIO_DEV_OK_TIME_MS ); } if ( pSettings->bEnableFeedbackDetection && TimerDetectFeedback.isActive() ) { TimerDetectFeedback.start ( DETECT_FEEDBACK_TIME_MS ); bDetectFeedback = true; } // update the settings dialog ClientSettingsDlg.UpdateSoundDeviceChannelSelectionFrame(); } void CClientDlg::OnCLPingTimeWithNumClientsReceived ( CHostAddress InetAddr, int iPingTime, int iNumClients ) { // update connection dialog server list ConnectDlg.SetPingTimeAndNumClientsResult ( InetAddr, iPingTime, iNumClients ); } void CClientDlg::Connect ( const QString& strSelectedAddress, const QString& strMixerBoardLabel ) { // set address and check if address is valid if ( pClient->SetServerAddr ( strSelectedAddress ) ) { // try to start client, if error occurred, do not go in // running state but show error message try { if ( !pClient->IsRunning() ) { pClient->Start(); } } catch ( const CGenErr& generr ) { // show error message and return the function QMessageBox::critical ( this, APP_NAME, generr.GetErrorText(), "Close", nullptr ); return; } // hide label connect to server lblConnectToServer->hide(); lbrInputLevelL->setEnabled ( true ); lbrInputLevelR->setEnabled ( true ); // change connect button text to "disconnect" butConnect->setText ( tr ( "&Disconnect" ) ); // set server name in audio mixer group box title MainMixerBoard->SetServerName ( strMixerBoardLabel ); // start timer for level meter bar and ping time measurement TimerSigMet.start ( LEVELMETER_UPDATE_TIME_MS ); TimerBuffersLED.start ( BUFFER_LED_UPDATE_TIME_MS ); TimerPing.start ( PING_UPDATE_TIME_MS ); TimerCheckAudioDeviceOk.start ( CHECK_AUDIO_DEV_OK_TIME_MS ); // is single shot timer // audio feedback detection if ( pSettings->bEnableFeedbackDetection ) { TimerDetectFeedback.start ( DETECT_FEEDBACK_TIME_MS ); // single shot timer bDetectFeedback = true; } } } void CClientDlg::Disconnect() { // only stop client if currently running, in case we received // the stopped message, the client is already stopped but the // connect/disconnect button and other GUI controls must be // updated if ( pClient->IsRunning() ) { pClient->Stop(); } // change connect button text to "connect" butConnect->setText ( tr ( "C&onnect" ) ); // reset server name in audio mixer group box title MainMixerBoard->SetServerName ( "" ); // stop timer for level meter bars and reset them TimerSigMet.stop(); lbrInputLevelL->setEnabled ( false ); lbrInputLevelR->setEnabled ( false ); lbrInputLevelL->SetValue ( 0 ); lbrInputLevelR->SetValue ( 0 ); // show connect to server message lblConnectToServer->show(); // stop other timers TimerBuffersLED.stop(); TimerPing.stop(); TimerCheckAudioDeviceOk.stop(); TimerDetectFeedback.stop(); bDetectFeedback = false; //### TODO: BEGIN ###// // is this still required??? // immediately update status bar OnTimerStatus(); //### TODO: END ###// // reset LEDs ledBuffers->Reset(); ledDelay->Reset(); // clear text labels with client parameters lblPingVal->setText ( "---" ); lblPingUnit->setText ( "" ); lblDelayVal->setText ( "---" ); lblDelayUnit->setText ( "" ); // clear mixer board (remove all faders) MainMixerBoard->HideAll(); } void CClientDlg::UpdateDisplay() { // update settings/chat buttons (do not fire signals since it is an update) if ( chbSettings->isChecked() && !ClientSettingsDlg.isVisible() ) { chbSettings->blockSignals ( true ); chbSettings->setChecked ( false ); chbSettings->blockSignals ( false ); } if ( !chbSettings->isChecked() && ClientSettingsDlg.isVisible() ) { chbSettings->blockSignals ( true ); chbSettings->setChecked ( true ); chbSettings->blockSignals ( false ); } if ( chbChat->isChecked() && !ChatDlg.isVisible() ) { chbChat->blockSignals ( true ); chbChat->setChecked ( false ); chbChat->blockSignals ( false ); } if ( !chbChat->isChecked() && ChatDlg.isVisible() ) { chbChat->blockSignals ( true ); chbChat->setChecked ( true ); chbChat->blockSignals ( false ); } } void CClientDlg::SetGUIDesign ( const EGUIDesign eNewDesign ) { // remove any styling from the mixer board - reapply after changing skin MainMixerBoard->setStyleSheet ( "" ); // apply GUI design to current window switch ( eNewDesign ) { case GD_ORIGINAL: backgroundFrame->setStyleSheet ( "QFrame#backgroundFrame { border-image: url(:/png/fader/res/mixerboardbackground.png) 34px 30px 40px 40px;" " border-top: 34px transparent;" " border-bottom: 40px transparent;" " border-left: 30px transparent;" " border-right: 40px transparent;" " padding: -5px;" " margin: -5px, -5px, 0px, 0px; }" "QLabel { color: rgb(220, 220, 220);" " font: bold; }" "QRadioButton { color: rgb(220, 220, 220);" " font: bold; }" "QScrollArea { background: transparent; }" ".QWidget { background: transparent; }" // note: matches instances of QWidget, but not of its subclasses "QGroupBox { background: transparent; }" "QGroupBox::title { color: rgb(220, 220, 220); }" "QCheckBox::indicator { width: 38px;" " height: 21px; }" "QCheckBox::indicator:unchecked {" " image: url(:/png/fader/res/ledbuttonnotpressed.png); }" "QCheckBox::indicator:checked {" " image: url(:/png/fader/res/ledbuttonpressed.png); }" "QCheckBox { color: rgb(220, 220, 220);" " font: bold; }" ); #ifdef _WIN32 // Workaround QT-Windows problem: This should not be necessary since in the // background frame the style sheet for QRadioButton was already set. But it // seems that it is only applied if the style was set to default and then back // to GD_ORIGINAL. This seems to be a QT related issue... rbtReverbSelL->setStyleSheet ( "color: rgb(220, 220, 220);" "font: bold;" ); rbtReverbSelR->setStyleSheet ( "color: rgb(220, 220, 220);" "font: bold;" ); #endif ledBuffers->SetType ( CMultiColorLED::MT_LED ); ledDelay->SetType ( CMultiColorLED::MT_LED ); break; default: // reset style sheet and set original parameters backgroundFrame->setStyleSheet ( "" ); #ifdef _WIN32 // Workaround QT-Windows problem: See above description rbtReverbSelL->setStyleSheet ( "" ); rbtReverbSelR->setStyleSheet ( "" ); #endif ledBuffers->SetType ( CMultiColorLED::MT_INDICATOR ); ledDelay->SetType ( CMultiColorLED::MT_INDICATOR ); break; } // also apply GUI design to child GUI controls MainMixerBoard->SetGUIDesign ( eNewDesign ); } void CClientDlg::SetMeterStyle ( const EMeterStyle eNewMeterStyle ) { // apply MeterStyle to current window switch ( eNewMeterStyle ) { case MT_LED_STRIPE: lbrInputLevelL->SetLevelMeterType ( CLevelMeter::MT_LED_STRIPE ); lbrInputLevelR->SetLevelMeterType ( CLevelMeter::MT_LED_STRIPE ); break; case MT_LED_ROUND_BIG: lbrInputLevelL->SetLevelMeterType ( CLevelMeter::MT_LED_ROUND_BIG ); lbrInputLevelR->SetLevelMeterType ( CLevelMeter::MT_LED_ROUND_BIG ); break; case MT_BAR_WIDE: lbrInputLevelL->SetLevelMeterType ( CLevelMeter::MT_BAR_WIDE ); lbrInputLevelR->SetLevelMeterType ( CLevelMeter::MT_BAR_WIDE ); break; case MT_BAR_NARROW: lbrInputLevelL->SetLevelMeterType ( CLevelMeter::MT_BAR_WIDE ); lbrInputLevelR->SetLevelMeterType ( CLevelMeter::MT_BAR_WIDE ); break; case MT_LED_ROUND_SMALL: lbrInputLevelL->SetLevelMeterType ( CLevelMeter::MT_LED_ROUND_BIG ); lbrInputLevelR->SetLevelMeterType ( CLevelMeter::MT_LED_ROUND_BIG ); break; } // also apply MeterStyle to child GUI controls MainMixerBoard->SetMeterStyle ( eNewMeterStyle ); } void CClientDlg::OnRecorderStateReceived ( const ERecorderState newRecorderState ) { MainMixerBoard->SetRecorderState ( newRecorderState ); SetMixerBoardDeco ( newRecorderState, pClient->GetGUIDesign() ); } void CClientDlg::OnGUIDesignChanged() { SetGUIDesign ( pClient->GetGUIDesign() ); SetMixerBoardDeco ( MainMixerBoard->GetRecorderState(), pClient->GetGUIDesign() ); } void CClientDlg::OnMeterStyleChanged() { SetMeterStyle ( pClient->GetMeterStyle() ); } void CClientDlg::SetMixerBoardDeco ( const ERecorderState newRecorderState, const EGUIDesign eNewDesign ) { // return if no change if ( ( newRecorderState == eLastRecorderState ) && ( eNewDesign == eLastDesign ) ) return; eLastRecorderState = newRecorderState; eLastDesign = eNewDesign; if ( newRecorderState == RS_RECORDING ) { MainMixerBoard->setStyleSheet ( "QGroupBox::title { subcontrol-origin: margin; " " subcontrol-position: left top;" " left: 7px;" " color: rgb(255,255,255);" " background-color: rgb(255,0,0); }" ); } else { if ( eNewDesign == GD_ORIGINAL ) { MainMixerBoard->setStyleSheet ( "QGroupBox::title { subcontrol-origin: margin;" " subcontrol-position: left top;" " left: 7px;" " color: rgb(220,220,220); }" ); } else { MainMixerBoard->setStyleSheet ( "QGroupBox::title { subcontrol-origin: margin;" " subcontrol-position: left top;" " left: 7px;" " color: rgb(0,0,0); }" ); } } } void CClientDlg::SetPingTime ( const int iPingTime, const int iOverallDelayMs, const CMultiColorLED::ELightColor eOverallDelayLEDColor ) { // apply values to GUI labels, take special care if ping time exceeds // a certain value if ( iPingTime > 500 ) { const QString sErrorText = ">500"; lblPingVal->setText ( sErrorText ); lblDelayVal->setText ( sErrorText ); } else { lblPingVal->setText ( QString().setNum ( iPingTime ) ); lblDelayVal->setText ( QString().setNum ( iOverallDelayMs ) ); } lblPingUnit->setText ( "ms" ); lblDelayUnit->setText ( "ms" ); // set current LED status ledDelay->SetLight ( eOverallDelayLEDColor ); } jamulus-3.9.1+dfsg/src/analyzerconsole.h0000644000175000017500000000457514340334543017337 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #include #include #include #include #include #include #include #include "client.h" #include "util.h" /* Definitions ****************************************************************/ // defines the update time of the error rate graph #define ERR_RATE_GRAPH_UPDATE_TIME_MS 200 // ms /* Classes ********************************************************************/ class CAnalyzerConsole : public CBaseDlg { Q_OBJECT public: CAnalyzerConsole ( CClient* pNCliP, QWidget* parent = nullptr ); protected: virtual void showEvent ( QShowEvent* ); virtual void hideEvent ( QHideEvent* ); void DrawFrame(); void DrawErrorRateTrace(); int CalcYPosInGraph ( const double dAxisMin, const double dAxisMax, const double dValue ) const; CClient* pClient; QTabWidget* pMainTabWidget; QWidget* pTabWidgetBufErrRate; QLabel* pGraphErrRate; QImage GraphImage; QRect GraphErrRateCanvasRect; QRect GraphGridFrame; int iGridFrameOffset; int iLineWidth; int iMarkerSize; int iXAxisTextHeight; QColor GraphBackgroundColor; QColor GraphFrameColor; QColor GraphGridColor; QColor LineColor; QColor LineLimitColor; QColor LineMaxUpLimitColor; QTimer TimerErrRateUpdate; public slots: void OnTimerErrRateUpdate(); }; jamulus-3.9.1+dfsg/src/client.cpp0000644000175000017500000014315414340334543015735 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include "client.h" /* Implementation *************************************************************/ CClient::CClient ( const quint16 iPortNumber, const quint16 iQosNumber, const QString& strConnOnStartupAddress, const QString& strMIDISetup, const bool bNoAutoJackConnect, const QString& strNClientName, const bool bNEnableIPv6, const bool bNMuteMeInPersonalMix ) : ChannelInfo(), strClientName ( strNClientName ), Channel ( false ), /* we need a client channel -> "false" */ CurOpusEncoder ( nullptr ), CurOpusDecoder ( nullptr ), eAudioCompressionType ( CT_OPUS ), iCeltNumCodedBytes ( OPUS_NUM_BYTES_MONO_LOW_QUALITY ), iOPUSFrameSizeSamples ( DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES ), eAudioQuality ( AQ_NORMAL ), eAudioChannelConf ( CC_MONO ), iNumAudioChannels ( 1 ), bIsInitializationPhase ( true ), bMuteOutStream ( false ), fMuteOutStreamGain ( 1.0f ), Socket ( &Channel, iPortNumber, iQosNumber, "", bNEnableIPv6 ), Sound ( AudioCallback, this, strMIDISetup, bNoAutoJackConnect, strNClientName ), iAudioInFader ( AUD_FADER_IN_MIDDLE ), bReverbOnLeftChan ( false ), iReverbLevel ( 0 ), iInputBoost ( 1 ), iSndCrdPrefFrameSizeFactor ( FRAME_SIZE_FACTOR_DEFAULT ), iSndCrdFrameSizeFactor ( FRAME_SIZE_FACTOR_DEFAULT ), bSndCrdConversionBufferRequired ( false ), iSndCardMonoBlockSizeSamConvBuff ( 0 ), bFraSiFactPrefSupported ( false ), bFraSiFactDefSupported ( false ), bFraSiFactSafeSupported ( false ), eGUIDesign ( GD_ORIGINAL ), eMeterStyle ( MT_LED_STRIPE ), bEnableAudioAlerts ( false ), bEnableOPUS64 ( false ), bJitterBufferOK ( true ), bEnableIPv6 ( bNEnableIPv6 ), bMuteMeInPersonalMix ( bNMuteMeInPersonalMix ), iServerSockBufNumFrames ( DEF_NET_BUF_SIZE_NUM_BL ), pSignalHandler ( CSignalHandler::getSingletonP() ) { int iOpusError; OpusMode = opus_custom_mode_create ( SYSTEM_SAMPLE_RATE_HZ, DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES, &iOpusError ); Opus64Mode = opus_custom_mode_create ( SYSTEM_SAMPLE_RATE_HZ, SYSTEM_FRAME_SIZE_SAMPLES, &iOpusError ); // init audio encoders and decoders OpusEncoderMono = opus_custom_encoder_create ( OpusMode, 1, &iOpusError ); // mono encoder legacy OpusDecoderMono = opus_custom_decoder_create ( OpusMode, 1, &iOpusError ); // mono decoder legacy OpusEncoderStereo = opus_custom_encoder_create ( OpusMode, 2, &iOpusError ); // stereo encoder legacy OpusDecoderStereo = opus_custom_decoder_create ( OpusMode, 2, &iOpusError ); // stereo decoder legacy Opus64EncoderMono = opus_custom_encoder_create ( Opus64Mode, 1, &iOpusError ); // mono encoder OPUS64 Opus64DecoderMono = opus_custom_decoder_create ( Opus64Mode, 1, &iOpusError ); // mono decoder OPUS64 Opus64EncoderStereo = opus_custom_encoder_create ( Opus64Mode, 2, &iOpusError ); // stereo encoder OPUS64 Opus64DecoderStereo = opus_custom_decoder_create ( Opus64Mode, 2, &iOpusError ); // stereo decoder OPUS64 // we require a constant bit rate opus_custom_encoder_ctl ( OpusEncoderMono, OPUS_SET_VBR ( 0 ) ); opus_custom_encoder_ctl ( OpusEncoderStereo, OPUS_SET_VBR ( 0 ) ); opus_custom_encoder_ctl ( Opus64EncoderMono, OPUS_SET_VBR ( 0 ) ); opus_custom_encoder_ctl ( Opus64EncoderStereo, OPUS_SET_VBR ( 0 ) ); // for 64 samples frame size we have to adjust the PLC behavior to avoid loud artifacts opus_custom_encoder_ctl ( Opus64EncoderMono, OPUS_SET_PACKET_LOSS_PERC ( 35 ) ); opus_custom_encoder_ctl ( Opus64EncoderStereo, OPUS_SET_PACKET_LOSS_PERC ( 35 ) ); // we want as low delay as possible opus_custom_encoder_ctl ( OpusEncoderMono, OPUS_SET_APPLICATION ( OPUS_APPLICATION_RESTRICTED_LOWDELAY ) ); opus_custom_encoder_ctl ( OpusEncoderStereo, OPUS_SET_APPLICATION ( OPUS_APPLICATION_RESTRICTED_LOWDELAY ) ); opus_custom_encoder_ctl ( Opus64EncoderMono, OPUS_SET_APPLICATION ( OPUS_APPLICATION_RESTRICTED_LOWDELAY ) ); opus_custom_encoder_ctl ( Opus64EncoderStereo, OPUS_SET_APPLICATION ( OPUS_APPLICATION_RESTRICTED_LOWDELAY ) ); // set encoder low complexity for legacy 128 samples frame size opus_custom_encoder_ctl ( OpusEncoderMono, OPUS_SET_COMPLEXITY ( 1 ) ); opus_custom_encoder_ctl ( OpusEncoderStereo, OPUS_SET_COMPLEXITY ( 1 ) ); // Connections ------------------------------------------------------------- // connections for the protocol mechanism QObject::connect ( &Channel, &CChannel::MessReadyForSending, this, &CClient::OnSendProtMessage ); QObject::connect ( &Channel, &CChannel::DetectedCLMessage, this, &CClient::OnDetectedCLMessage ); QObject::connect ( &Channel, &CChannel::ReqJittBufSize, this, &CClient::OnReqJittBufSize ); QObject::connect ( &Channel, &CChannel::JittBufSizeChanged, this, &CClient::OnJittBufSizeChanged ); QObject::connect ( &Channel, &CChannel::ReqChanInfo, this, &CClient::OnReqChanInfo ); // The first ConClientListMesReceived handler performs the necessary cleanup and has to run first: QObject::connect ( &Channel, &CChannel::ConClientListMesReceived, this, &CClient::OnConClientListMesReceived ); QObject::connect ( &Channel, &CChannel::ConClientListMesReceived, this, &CClient::ConClientListMesReceived ); QObject::connect ( &Channel, &CChannel::Disconnected, this, &CClient::Disconnected ); QObject::connect ( &Channel, &CChannel::NewConnection, this, &CClient::OnNewConnection ); QObject::connect ( &Channel, &CChannel::ChatTextReceived, this, &CClient::ChatTextReceived ); QObject::connect ( &Channel, &CChannel::ClientIDReceived, this, &CClient::OnClientIDReceived ); QObject::connect ( &Channel, &CChannel::MuteStateHasChangedReceived, this, &CClient::MuteStateHasChangedReceived ); QObject::connect ( &Channel, &CChannel::LicenceRequired, this, &CClient::LicenceRequired ); QObject::connect ( &Channel, &CChannel::VersionAndOSReceived, this, &CClient::VersionAndOSReceived ); QObject::connect ( &Channel, &CChannel::RecorderStateReceived, this, &CClient::RecorderStateReceived ); QObject::connect ( &ConnLessProtocol, &CProtocol::CLMessReadyForSending, this, &CClient::OnSendCLProtMessage ); QObject::connect ( &ConnLessProtocol, &CProtocol::CLServerListReceived, this, &CClient::CLServerListReceived ); QObject::connect ( &ConnLessProtocol, &CProtocol::CLRedServerListReceived, this, &CClient::CLRedServerListReceived ); QObject::connect ( &ConnLessProtocol, &CProtocol::CLConnClientsListMesReceived, this, &CClient::CLConnClientsListMesReceived ); QObject::connect ( &ConnLessProtocol, &CProtocol::CLPingReceived, this, &CClient::OnCLPingReceived ); QObject::connect ( &ConnLessProtocol, &CProtocol::CLPingWithNumClientsReceived, this, &CClient::OnCLPingWithNumClientsReceived ); QObject::connect ( &ConnLessProtocol, &CProtocol::CLDisconnection, this, &CClient::OnCLDisconnection ); QObject::connect ( &ConnLessProtocol, &CProtocol::CLVersionAndOSReceived, this, &CClient::CLVersionAndOSReceived ); QObject::connect ( &ConnLessProtocol, &CProtocol::CLChannelLevelListReceived, this, &CClient::CLChannelLevelListReceived ); // other QObject::connect ( &Sound, &CSound::ReinitRequest, this, &CClient::OnSndCrdReinitRequest ); QObject::connect ( &Sound, &CSound::ControllerInFaderLevel, this, &CClient::OnControllerInFaderLevel ); QObject::connect ( &Sound, &CSound::ControllerInPanValue, this, &CClient::OnControllerInPanValue ); QObject::connect ( &Sound, &CSound::ControllerInFaderIsSolo, this, &CClient::OnControllerInFaderIsSolo ); QObject::connect ( &Sound, &CSound::ControllerInFaderIsMute, this, &CClient::OnControllerInFaderIsMute ); QObject::connect ( &Sound, &CSound::ControllerInMuteMyself, this, &CClient::OnControllerInMuteMyself ); QObject::connect ( &Socket, &CHighPrioSocket::InvalidPacketReceived, this, &CClient::OnInvalidPacketReceived ); QObject::connect ( pSignalHandler, &CSignalHandler::HandledSignal, this, &CClient::OnHandledSignal ); // start timer so that elapsed time works PreciseTime.start(); // set gain delay timer to single-shot and connect handler function TimerGain.setSingleShot ( true ); QObject::connect ( &TimerGain, &QTimer::timeout, this, &CClient::OnTimerRemoteChanGain ); // start the socket (it is important to start the socket after all // initializations and connections) Socket.Start(); // do an immediate start if a server address is given if ( !strConnOnStartupAddress.isEmpty() ) { SetServerAddr ( strConnOnStartupAddress ); Start(); } } CClient::~CClient() { // if we were running, stop sound device if ( Sound.IsRunning() ) { Sound.Stop(); } // free audio encoders and decoders opus_custom_encoder_destroy ( OpusEncoderMono ); opus_custom_decoder_destroy ( OpusDecoderMono ); opus_custom_encoder_destroy ( OpusEncoderStereo ); opus_custom_decoder_destroy ( OpusDecoderStereo ); opus_custom_encoder_destroy ( Opus64EncoderMono ); opus_custom_decoder_destroy ( Opus64DecoderMono ); opus_custom_encoder_destroy ( Opus64EncoderStereo ); opus_custom_decoder_destroy ( Opus64DecoderStereo ); // free audio modes opus_custom_mode_destroy ( OpusMode ); opus_custom_mode_destroy ( Opus64Mode ); } void CClient::OnSendProtMessage ( CVector vecMessage ) { // the protocol queries me to call the function to send the message // send it through the network Socket.SendPacket ( vecMessage, Channel.GetAddress() ); } void CClient::OnSendCLProtMessage ( CHostAddress InetAddr, CVector vecMessage ) { // the protocol queries me to call the function to send the message // send it through the network Socket.SendPacket ( vecMessage, InetAddr ); } void CClient::OnInvalidPacketReceived ( CHostAddress RecHostAddr ) { // message could not be parsed, check if the packet comes // from the server we just connected -> if yes, send // disconnect message since the server may not know that we // are not connected anymore if ( Channel.GetAddress() == RecHostAddr ) { ConnLessProtocol.CreateCLDisconnection ( RecHostAddr ); } } void CClient::OnDetectedCLMessage ( CVector vecbyMesBodyData, int iRecID, CHostAddress RecHostAddr ) { // connection less messages are always processed ConnLessProtocol.ParseConnectionLessMessageBody ( vecbyMesBodyData, iRecID, RecHostAddr ); } void CClient::OnJittBufSizeChanged ( int iNewJitBufSize ) { // we received a jitter buffer size changed message from the server, // only apply this value if auto jitter buffer size is enabled if ( GetDoAutoSockBufSize() ) { // Note: Do not use the "SetServerSockBufNumFrames" function for setting // the new server jitter buffer size since then a message would be sent // to the server which is incorrect. iServerSockBufNumFrames = iNewJitBufSize; } } void CClient::OnNewConnection() { // The oldGain and newGain arrays are used to avoid sending duplicate gain change messages. // As these values depend on the channel IDs of a specific server, we have // to reset those upon connect. // We reset to 1 because this is what the server part sets by default. for ( int iId = 0; iId < MAX_NUM_CHANNELS; iId++ ) { oldGain[iId] = newGain[iId] = 1; } // a new connection was successfully initiated, send infos and request // connected clients list Channel.SetRemoteInfo ( ChannelInfo ); // We have to send a connected clients list request since it can happen // that we just had connected to the server and then disconnected but // the server still thinks that we are connected (the server is still // waiting for the channel time-out). If we now connect again, we would // not get the list because the server does not know about a new connection. // Same problem is with the jitter buffer message. Channel.CreateReqConnClientsList(); CreateServerJitterBufferMessage(); //### TODO: BEGIN ###// // needed for compatibility to old servers >= 3.4.6 and <= 3.5.12 Channel.CreateReqChannelLevelListMes(); //### TODO: END ###// } void CClient::OnConClientListMesReceived ( CVector vecChanInfo ) { // Upon receiving a new client list, we have to reset oldGain and newGain // entries for unused channels. This ensures that a disconnected channel // does not leave behind wrong cached gain values which would leak into // any new channel which reused this channel id. int iNumConnectedClients = vecChanInfo.Size(); // Save what channel IDs are in use: bool bChanIdInUse[MAX_NUM_CHANNELS] = {}; for ( int i = 0; i < iNumConnectedClients; i++ ) { bChanIdInUse[vecChanInfo[i].iChanID] = true; } // Reset all gains for unused channel IDs: for ( int iId = 0; iId < MAX_NUM_CHANNELS; iId++ ) { if ( !bChanIdInUse[iId] ) { // reset oldGain and newGain as this channel id is currently unused and will // start with a server-side gain at 1 (100%) again. oldGain[iId] = newGain[iId] = 1; } } } void CClient::CreateServerJitterBufferMessage() { // per definition in the client: if auto jitter buffer is enabled, both, // the client and server shall use an auto jitter buffer if ( GetDoAutoSockBufSize() ) { // in case auto jitter buffer size is enabled, we have to transmit a // special value Channel.CreateJitBufMes ( AUTO_NET_BUF_SIZE_FOR_PROTOCOL ); } else { Channel.CreateJitBufMes ( GetServerSockBufNumFrames() ); } } void CClient::OnCLPingReceived ( CHostAddress InetAddr, int iMs ) { // make sure we are running and the server address is correct if ( IsRunning() && ( InetAddr == Channel.GetAddress() ) ) { // take care of wrap arounds (if wrapping, do not use result) const int iCurDiff = EvaluatePingMessage ( iMs ); if ( iCurDiff >= 0 ) { iCurPingTime = iCurDiff; // store for use by gain message sending emit PingTimeReceived ( iCurDiff ); } } } void CClient::OnCLPingWithNumClientsReceived ( CHostAddress InetAddr, int iMs, int iNumClients ) { // take care of wrap arounds (if wrapping, do not use result) const int iCurDiff = EvaluatePingMessage ( iMs ); if ( iCurDiff >= 0 ) { emit CLPingTimeWithNumClientsReceived ( InetAddr, iCurDiff, iNumClients ); } } int CClient::PreparePingMessage() { // transmit the current precise time (in ms) return PreciseTime.elapsed(); } int CClient::EvaluatePingMessage ( const int iMs ) { // calculate difference between received time in ms and current time in ms return PreciseTime.elapsed() - iMs; } void CClient::SetDoAutoSockBufSize ( const bool bValue ) { // first, set new value in the channel object Channel.SetDoAutoSockBufSize ( bValue ); // inform the server about the change CreateServerJitterBufferMessage(); } // In order not to flood the server with gain change messages, particularly when using // a MIDI controller, a timer is used to limit the rate at which such messages are generated. // This avoids a potential long backlog of messages, since each must be ACKed before the next // can be sent, and this ACK is subject to the latency of the server connection. // // When the first gain change message is requested after an idle period (i.e. the timer is not // running), it will be sent immediately, and a 300ms timer started. // // If a gain change message is requested while the timer is still running, the new gain is not sent, // but just stored in newGain[iId], and the minGainId and maxGainId updated to note the range of // IDs that must be checked when the time expires (this will usually be a single channel // unless channel grouping is being used). This avoids having to check all possible channels. // // When the timer fires, the channels minGainId <= iId < maxGainId are checked by comparing // the last sent value in oldGain[iId] with any pending value in newGain[iId], and if they differ, // the new value is sent, updating oldGain[iId] with the sent value. If any new values are // sent, the timer is restarted so that further immediate updates will be pended. void CClient::SetRemoteChanGain ( const int iId, const float fGain, const bool bIsMyOwnFader ) { QMutexLocker locker ( &MutexGain ); // if this gain is for my own channel, apply the value for the Mute Myself function if ( bIsMyOwnFader ) { fMuteOutStreamGain = fGain; } if ( TimerGain.isActive() ) { // just update the new value for sending later; // will compare with oldGain[iId] when the timer fires newGain[iId] = fGain; // update range of channel IDs to check in the timer if ( iId < minGainId ) minGainId = iId; // first value to check if ( iId >= maxGainId ) maxGainId = iId + 1; // first value NOT to check return; } // here the timer was not active: // send the actual gain and reset the range of channel IDs to empty oldGain[iId] = newGain[iId] = fGain; Channel.SetRemoteChanGain ( iId, fGain ); StartDelayTimer(); } void CClient::OnTimerRemoteChanGain() { QMutexLocker locker ( &MutexGain ); bool bSent = false; for ( int iId = minGainId; iId < maxGainId; iId++ ) { if ( newGain[iId] != oldGain[iId] ) { // send new gain and record as old gain float fGain = oldGain[iId] = newGain[iId]; Channel.SetRemoteChanGain ( iId, fGain ); bSent = true; } } // if a new gain has been sent, reset the range of channel IDs to empty and start timer if ( bSent ) { StartDelayTimer(); } } // reset the range of channel IDs to check and start the delay timer void CClient::StartDelayTimer() { maxGainId = 0; minGainId = MAX_NUM_CHANNELS; // start timer to delay sending further updates // use longer delay when connected to server with higher ping time, // double the ping time in order to allow a bit of overhead for other messages if ( iCurPingTime < DEFAULT_GAIN_DELAY_PERIOD_MS / 2 ) { TimerGain.start ( DEFAULT_GAIN_DELAY_PERIOD_MS ); } else { TimerGain.start ( iCurPingTime * 2 ); } } bool CClient::SetServerAddr ( QString strNAddr ) { CHostAddress HostAddress; if ( NetworkUtil().ParseNetworkAddress ( strNAddr, HostAddress, bEnableIPv6 ) ) { // apply address to the channel Channel.SetAddress ( HostAddress ); return true; } else { return false; // invalid address } } bool CClient::GetAndResetbJitterBufferOKFlag() { // get the socket buffer put status flag and reset it const bool bSocketJitBufOKFlag = Socket.GetAndResetbJitterBufferOKFlag(); if ( !bJitterBufferOK ) { // our jitter buffer get status is not OK so the overall status of the // jitter buffer is also not OK (we do not have to consider the status // of the socket buffer put status flag) // reset flag before returning the function bJitterBufferOK = true; return false; } // the jitter buffer get (our own status flag) is OK, the final status // now depends on the jitter buffer put status flag from the socket // since per definition the jitter buffer status is OK if both the // put and get status are OK return bSocketJitBufOKFlag; } void CClient::SetSndCrdPrefFrameSizeFactor ( const int iNewFactor ) { // first check new input parameter if ( ( iNewFactor == FRAME_SIZE_FACTOR_PREFERRED ) || ( iNewFactor == FRAME_SIZE_FACTOR_DEFAULT ) || ( iNewFactor == FRAME_SIZE_FACTOR_SAFE ) ) { // init with new parameter, if client was running then first // stop it and restart again after new initialization const bool bWasRunning = Sound.IsRunning(); if ( bWasRunning ) { Sound.Stop(); } // set new parameter iSndCrdPrefFrameSizeFactor = iNewFactor; // init with new block size index parameter Init(); if ( bWasRunning ) { // restart client Sound.Start(); } } } void CClient::SetEnableOPUS64 ( const bool eNEnableOPUS64 ) { // init with new parameter, if client was running then first // stop it and restart again after new initialization const bool bWasRunning = Sound.IsRunning(); if ( bWasRunning ) { Sound.Stop(); } // set new parameter bEnableOPUS64 = eNEnableOPUS64; Init(); if ( bWasRunning ) { Sound.Start(); } } void CClient::SetAudioQuality ( const EAudioQuality eNAudioQuality ) { // init with new parameter, if client was running then first // stop it and restart again after new initialization const bool bWasRunning = Sound.IsRunning(); if ( bWasRunning ) { Sound.Stop(); } // set new parameter eAudioQuality = eNAudioQuality; Init(); if ( bWasRunning ) { Sound.Start(); } } void CClient::SetAudioChannels ( const EAudChanConf eNAudChanConf ) { // init with new parameter, if client was running then first // stop it and restart again after new initialization const bool bWasRunning = Sound.IsRunning(); if ( bWasRunning ) { Sound.Stop(); } // set new parameter eAudioChannelConf = eNAudChanConf; Init(); if ( bWasRunning ) { Sound.Start(); } } QString CClient::SetSndCrdDev ( const QString strNewDev ) { // if client was running then first // stop it and restart again after new initialization const bool bWasRunning = Sound.IsRunning(); if ( bWasRunning ) { Sound.Stop(); } const QString strError = Sound.SetDev ( strNewDev ); // init again because the sound card actual buffer size might // be changed on new device Init(); if ( bWasRunning ) { // restart client Sound.Start(); } // in case of an error inform the GUI about it if ( !strError.isEmpty() ) { emit SoundDeviceChanged ( strError ); } return strError; } void CClient::SetSndCrdLeftInputChannel ( const int iNewChan ) { // if client was running then first // stop it and restart again after new initialization const bool bWasRunning = Sound.IsRunning(); if ( bWasRunning ) { Sound.Stop(); } Sound.SetLeftInputChannel ( iNewChan ); Init(); if ( bWasRunning ) { // restart client Sound.Start(); } } void CClient::SetSndCrdRightInputChannel ( const int iNewChan ) { // if client was running then first // stop it and restart again after new initialization const bool bWasRunning = Sound.IsRunning(); if ( bWasRunning ) { Sound.Stop(); } Sound.SetRightInputChannel ( iNewChan ); Init(); if ( bWasRunning ) { // restart client Sound.Start(); } } void CClient::SetSndCrdLeftOutputChannel ( const int iNewChan ) { // if client was running then first // stop it and restart again after new initialization const bool bWasRunning = Sound.IsRunning(); if ( bWasRunning ) { Sound.Stop(); } Sound.SetLeftOutputChannel ( iNewChan ); Init(); if ( bWasRunning ) { // restart client Sound.Start(); } } void CClient::SetSndCrdRightOutputChannel ( const int iNewChan ) { // if client was running then first // stop it and restart again after new initialization const bool bWasRunning = Sound.IsRunning(); if ( bWasRunning ) { Sound.Stop(); } Sound.SetRightOutputChannel ( iNewChan ); Init(); if ( bWasRunning ) { // restart client Sound.Start(); } } void CClient::OnSndCrdReinitRequest ( int iSndCrdResetType ) { QString strError = ""; // audio device notifications can come at any time and they are in a // different thread, therefore we need a mutex here MutexDriverReinit.lock(); { // in older QT versions, enums cannot easily be used in signals without // registering them -> workaroud: we use the int type and cast to the enum const ESndCrdResetType eSndCrdResetType = static_cast ( iSndCrdResetType ); // if client was running then first // stop it and restart again after new initialization const bool bWasRunning = Sound.IsRunning(); if ( bWasRunning ) { Sound.Stop(); } // perform reinit request as indicated by the request type parameter if ( eSndCrdResetType != RS_ONLY_RESTART ) { if ( eSndCrdResetType != RS_ONLY_RESTART_AND_INIT ) { // reinit the driver if requested // (we use the currently selected driver) strError = Sound.SetDev ( Sound.GetDev() ); } // init client object (must always be performed if the driver // was changed) Init(); } if ( bWasRunning ) { // restart client Sound.Start(); } } MutexDriverReinit.unlock(); // inform GUI about the sound card device change emit SoundDeviceChanged ( strError ); } void CClient::OnHandledSignal ( int sigNum ) { #ifdef _WIN32 // Windows does not actually get OnHandledSignal triggered QCoreApplication::instance()->exit(); Q_UNUSED ( sigNum ) #else switch ( sigNum ) { case SIGINT: case SIGTERM: // if connected, terminate connection (needed for headless mode) if ( IsRunning() ) { Stop(); } // this should trigger OnAboutToQuit QCoreApplication::instance()->exit(); break; default: break; } #endif } void CClient::OnControllerInFaderLevel ( int iChannelIdx, int iValue ) { // in case of a headless client the faders cannot be moved so we need // to send the controller information directly to the server #ifdef HEADLESS // only apply new fader level if channel index is valid if ( ( iChannelIdx >= 0 ) && ( iChannelIdx < MAX_NUM_CHANNELS ) ) { SetRemoteChanGain ( iChannelIdx, MathUtils::CalcFaderGain ( iValue ), false ); } #endif emit ControllerInFaderLevel ( iChannelIdx, iValue ); } void CClient::OnControllerInPanValue ( int iChannelIdx, int iValue ) { // in case of a headless client the panners cannot be moved so we need // to send the controller information directly to the server #ifdef HEADLESS // channel index is valid SetRemoteChanPan ( iChannelIdx, static_cast ( iValue ) / AUD_MIX_PAN_MAX ); #endif emit ControllerInPanValue ( iChannelIdx, iValue ); } void CClient::OnControllerInFaderIsSolo ( int iChannelIdx, bool bIsSolo ) { // in case of a headless client the buttons are not displayed so we need // to send the controller information directly to the server #ifdef HEADLESS // FIXME: no idea what to do here. #endif emit ControllerInFaderIsSolo ( iChannelIdx, bIsSolo ); } void CClient::OnControllerInFaderIsMute ( int iChannelIdx, bool bIsMute ) { // in case of a headless client the buttons are not displayed so we need // to send the controller information directly to the server #ifdef HEADLESS // FIXME: no idea what to do here. #endif emit ControllerInFaderIsMute ( iChannelIdx, bIsMute ); } void CClient::OnControllerInMuteMyself ( bool bMute ) { // in case of a headless client the buttons are not displayed so we need // to send the controller information directly to the server #ifdef HEADLESS // FIXME: no idea what to do here. #endif emit ControllerInMuteMyself ( bMute ); } void CClient::OnClientIDReceived ( int iChanID ) { // for headless mode we support to mute our own signal in the personal mix // (note that the check for headless is done in the main.cpp and must not // be checked here) if ( bMuteMeInPersonalMix ) { SetRemoteChanGain ( iChanID, 0, false ); } emit ClientIDReceived ( iChanID ); } void CClient::Start() { // init object Init(); // enable channel Channel.SetEnable ( true ); // start audio interface Sound.Start(); } void CClient::Stop() { // stop audio interface Sound.Stop(); // disable channel Channel.SetEnable ( false ); // wait for approx. 100 ms to make sure no audio packet is still in the // network queue causing the channel to be reconnected right after having // received the disconnect message (seems not to gain much, disconnect is // still not working reliably) QTime DieTime = QTime::currentTime().addMSecs ( 100 ); while ( QTime::currentTime() < DieTime ) { // exclude user input events because if we use AllEvents, it happens // that if the user initiates a connection and disconnection quickly // (e.g. quickly pressing enter five times), the software can get into // an unknown state QCoreApplication::processEvents ( QEventLoop::ExcludeUserInputEvents, 100 ); } // Send disconnect message to server (Since we disable our protocol // receive mechanism with the next command, we do not evaluate any // respond from the server, therefore we just hope that the message // gets its way to the server, if not, the old behaviour time-out // disconnects the connection anyway). ConnLessProtocol.CreateCLDisconnection ( Channel.GetAddress() ); // reset current signal level and LEDs bJitterBufferOK = true; SignalLevelMeter.Reset(); } void CClient::Init() { // check if possible frame size factors are supported const int iFraSizePreffered = SYSTEM_FRAME_SIZE_SAMPLES * FRAME_SIZE_FACTOR_PREFERRED; const int iFraSizeDefault = SYSTEM_FRAME_SIZE_SAMPLES * FRAME_SIZE_FACTOR_DEFAULT; const int iFraSizeSafe = SYSTEM_FRAME_SIZE_SAMPLES * FRAME_SIZE_FACTOR_SAFE; #if defined( Q_OS_IOS ) bFraSiFactPrefSupported = true; // to reduce sound init time, because we know it's supported in iOS bFraSiFactDefSupported = true; bFraSiFactSafeSupported = true; #else bFraSiFactPrefSupported = ( Sound.Init ( iFraSizePreffered ) == iFraSizePreffered ); bFraSiFactDefSupported = ( Sound.Init ( iFraSizeDefault ) == iFraSizeDefault ); bFraSiFactSafeSupported = ( Sound.Init ( iFraSizeSafe ) == iFraSizeSafe ); #endif // translate block size index in actual block size const int iPrefMonoFrameSize = iSndCrdPrefFrameSizeFactor * SYSTEM_FRAME_SIZE_SAMPLES; // get actual sound card buffer size using preferred size // TODO - iOS needs 1 init only, now: 9 inits at launch <- slow // Initially, I tried to fix this as follows (inside #ifdef ios tag): // if ( Sound.isInitialized ) // iMonoBlockSizeSam = iPrefMonoFrameSize; // else // iMonoBlockSizeSam = Sound.Init ( iPrefMonoFrameSize ); // Problem is legitimate setting changes (buffer size for example). // so the condition should be something like "if ( Sound.isInitialized and APP_IS_INIALIZING)" iMonoBlockSizeSam = Sound.Init ( iPrefMonoFrameSize ); // Calculate the current sound card frame size factor. In case // the current mono block size is not a multiple of the system // frame size, we have to use a sound card conversion buffer. if ( ( ( iMonoBlockSizeSam == ( SYSTEM_FRAME_SIZE_SAMPLES * FRAME_SIZE_FACTOR_PREFERRED ) ) && bEnableOPUS64 ) || ( iMonoBlockSizeSam == ( SYSTEM_FRAME_SIZE_SAMPLES * FRAME_SIZE_FACTOR_DEFAULT ) ) || ( iMonoBlockSizeSam == ( SYSTEM_FRAME_SIZE_SAMPLES * FRAME_SIZE_FACTOR_SAFE ) ) ) { // regular case: one of our predefined buffer sizes is available iSndCrdFrameSizeFactor = iMonoBlockSizeSam / SYSTEM_FRAME_SIZE_SAMPLES; // no sound card conversion buffer required bSndCrdConversionBufferRequired = false; } else { // An unsupported sound card buffer size is currently used -> we have // to use a conversion buffer. Per definition we use the smallest buffer // size as the current frame size. // store actual sound card buffer size (stereo) bSndCrdConversionBufferRequired = true; iSndCardMonoBlockSizeSamConvBuff = iMonoBlockSizeSam; // overwrite block size factor by using one frame iSndCrdFrameSizeFactor = 1; } // select the OPUS frame size mode depending on current mono block size samples if ( bSndCrdConversionBufferRequired ) { if ( ( iSndCardMonoBlockSizeSamConvBuff < DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES ) && bEnableOPUS64 ) { iMonoBlockSizeSam = SYSTEM_FRAME_SIZE_SAMPLES; eAudioCompressionType = CT_OPUS64; } else { iMonoBlockSizeSam = DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES; eAudioCompressionType = CT_OPUS; } } else { if ( iMonoBlockSizeSam < DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES ) { eAudioCompressionType = CT_OPUS64; } else { // since we use double size frame size for OPUS, we have to adjust the frame size factor iSndCrdFrameSizeFactor /= 2; eAudioCompressionType = CT_OPUS; } } // inits for audio coding if ( eAudioCompressionType == CT_OPUS ) { iOPUSFrameSizeSamples = DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES; if ( eAudioChannelConf == CC_MONO ) { CurOpusEncoder = OpusEncoderMono; CurOpusDecoder = OpusDecoderMono; iNumAudioChannels = 1; switch ( eAudioQuality ) { case AQ_LOW: iCeltNumCodedBytes = OPUS_NUM_BYTES_MONO_LOW_QUALITY_DBLE_FRAMESIZE; break; case AQ_NORMAL: iCeltNumCodedBytes = OPUS_NUM_BYTES_MONO_NORMAL_QUALITY_DBLE_FRAMESIZE; break; case AQ_HIGH: iCeltNumCodedBytes = OPUS_NUM_BYTES_MONO_HIGH_QUALITY_DBLE_FRAMESIZE; break; } } else { CurOpusEncoder = OpusEncoderStereo; CurOpusDecoder = OpusDecoderStereo; iNumAudioChannels = 2; switch ( eAudioQuality ) { case AQ_LOW: iCeltNumCodedBytes = OPUS_NUM_BYTES_STEREO_LOW_QUALITY_DBLE_FRAMESIZE; break; case AQ_NORMAL: iCeltNumCodedBytes = OPUS_NUM_BYTES_STEREO_NORMAL_QUALITY_DBLE_FRAMESIZE; break; case AQ_HIGH: iCeltNumCodedBytes = OPUS_NUM_BYTES_STEREO_HIGH_QUALITY_DBLE_FRAMESIZE; break; } } } else /* CT_OPUS64 */ { iOPUSFrameSizeSamples = SYSTEM_FRAME_SIZE_SAMPLES; if ( eAudioChannelConf == CC_MONO ) { CurOpusEncoder = Opus64EncoderMono; CurOpusDecoder = Opus64DecoderMono; iNumAudioChannels = 1; switch ( eAudioQuality ) { case AQ_LOW: iCeltNumCodedBytes = OPUS_NUM_BYTES_MONO_LOW_QUALITY; break; case AQ_NORMAL: iCeltNumCodedBytes = OPUS_NUM_BYTES_MONO_NORMAL_QUALITY; break; case AQ_HIGH: iCeltNumCodedBytes = OPUS_NUM_BYTES_MONO_HIGH_QUALITY; break; } } else { CurOpusEncoder = Opus64EncoderStereo; CurOpusDecoder = Opus64DecoderStereo; iNumAudioChannels = 2; switch ( eAudioQuality ) { case AQ_LOW: iCeltNumCodedBytes = OPUS_NUM_BYTES_STEREO_LOW_QUALITY; break; case AQ_NORMAL: iCeltNumCodedBytes = OPUS_NUM_BYTES_STEREO_NORMAL_QUALITY; break; case AQ_HIGH: iCeltNumCodedBytes = OPUS_NUM_BYTES_STEREO_HIGH_QUALITY; break; } } } // calculate stereo (two channels) buffer size iStereoBlockSizeSam = 2 * iMonoBlockSizeSam; vecCeltData.Init ( iCeltNumCodedBytes ); vecZeros.Init ( iStereoBlockSizeSam, 0 ); vecsStereoSndCrdMuteStream.Init ( iStereoBlockSizeSam ); opus_custom_encoder_ctl ( CurOpusEncoder, OPUS_SET_BITRATE ( CalcBitRateBitsPerSecFromCodedBytes ( iCeltNumCodedBytes, iOPUSFrameSizeSamples ) ) ); // inits for network and channel vecbyNetwData.Init ( iCeltNumCodedBytes ); // set the channel network properties Channel.SetAudioStreamProperties ( eAudioCompressionType, iCeltNumCodedBytes, iSndCrdFrameSizeFactor, iNumAudioChannels ); // init reverberation AudioReverb.Init ( eAudioChannelConf, iStereoBlockSizeSam, SYSTEM_SAMPLE_RATE_HZ ); // init the sound card conversion buffers if ( bSndCrdConversionBufferRequired ) { // inits for conversion buffer (the size of the conversion buffer must // be the sum of input/output sizes which is the worst case fill level) const int iSndCardStereoBlockSizeSamConvBuff = 2 * iSndCardMonoBlockSizeSamConvBuff; const int iConBufSize = iStereoBlockSizeSam + iSndCardStereoBlockSizeSamConvBuff; SndCrdConversionBufferIn.Init ( iConBufSize ); SndCrdConversionBufferOut.Init ( iConBufSize ); vecDataConvBuf.Init ( iStereoBlockSizeSam ); // the output conversion buffer must be filled with the inner // block size for initialization (this is the latency which is // introduced by the conversion buffer) to avoid buffer underruns SndCrdConversionBufferOut.Put ( vecZeros, iStereoBlockSizeSam ); } // reset initialization phase flag and mute flag bIsInitializationPhase = true; } void CClient::AudioCallback ( CVector& psData, void* arg ) { // get the pointer to the object CClient* pMyClientObj = static_cast ( arg ); // process audio data pMyClientObj->ProcessSndCrdAudioData ( psData ); //### TEST: BEGIN ###// // do a soundcard jitter measurement /* static CTimingMeas JitterMeas ( 1000, "test2.dat" ); JitterMeas.Measure(); */ //### TEST: END ###// } void CClient::ProcessSndCrdAudioData ( CVector& vecsStereoSndCrd ) { // check if a conversion buffer is required or not if ( bSndCrdConversionBufferRequired ) { // add new sound card block in conversion buffer SndCrdConversionBufferIn.Put ( vecsStereoSndCrd, vecsStereoSndCrd.Size() ); // process all available blocks of data while ( SndCrdConversionBufferIn.GetAvailData() >= iStereoBlockSizeSam ) { // get one block of data for processing SndCrdConversionBufferIn.Get ( vecDataConvBuf, iStereoBlockSizeSam ); // process audio data ProcessAudioDataIntern ( vecDataConvBuf ); SndCrdConversionBufferOut.Put ( vecDataConvBuf, iStereoBlockSizeSam ); } // get processed sound card block out of the conversion buffer SndCrdConversionBufferOut.Get ( vecsStereoSndCrd, vecsStereoSndCrd.Size() ); } else { // regular case: no conversion buffer required // process audio data ProcessAudioDataIntern ( vecsStereoSndCrd ); } } void CClient::ProcessAudioDataIntern ( CVector& vecsStereoSndCrd ) { int i, j, iUnused; unsigned char* pCurCodedData; // Transmit signal --------------------------------------------------------- if ( iInputBoost != 1 ) { // apply a general gain boost to all audio input: for ( i = 0, j = 0; i < iMonoBlockSizeSam; i++, j += 2 ) { vecsStereoSndCrd[j + 1] = static_cast ( iInputBoost * vecsStereoSndCrd[j + 1] ); vecsStereoSndCrd[j] = static_cast ( iInputBoost * vecsStereoSndCrd[j] ); } } // update stereo signal level meter (not needed in headless mode) #ifndef HEADLESS SignalLevelMeter.Update ( vecsStereoSndCrd, iMonoBlockSizeSam, true ); #endif // add reverberation effect if activated if ( iReverbLevel != 0 ) { AudioReverb.Process ( vecsStereoSndCrd, bReverbOnLeftChan, static_cast ( iReverbLevel ) / AUD_REVERB_MAX / 4 ); } // apply pan (audio fader) and mix mono signals if ( !( ( iAudioInFader == AUD_FADER_IN_MIDDLE ) && ( eAudioChannelConf == CC_STEREO ) ) ) { // calculate pan gain in the range 0 to 1, where 0.5 is the middle position const float fPan = static_cast ( iAudioInFader ) / AUD_FADER_IN_MAX; if ( eAudioChannelConf == CC_STEREO ) { // for stereo only apply pan attenuation on one channel (same as pan in the server) const float fGainL = MathUtils::GetLeftPan ( fPan, false ); const float fGainR = MathUtils::GetRightPan ( fPan, false ); for ( i = 0, j = 0; i < iMonoBlockSizeSam; i++, j += 2 ) { // note that the gain is always <= 1, therefore a simple cast is // ok since we never can get an overload vecsStereoSndCrd[j + 1] = static_cast ( fGainR * vecsStereoSndCrd[j + 1] ); vecsStereoSndCrd[j] = static_cast ( fGainL * vecsStereoSndCrd[j] ); } } else { // for mono implement a cross-fade between channels and mix them, for // mono-in/stereo-out use no attenuation in pan center const float fGainL = MathUtils::GetLeftPan ( fPan, eAudioChannelConf != CC_MONO_IN_STEREO_OUT ); const float fGainR = MathUtils::GetRightPan ( fPan, eAudioChannelConf != CC_MONO_IN_STEREO_OUT ); for ( i = 0, j = 0; i < iMonoBlockSizeSam; i++, j += 2 ) { // note that we need the Float2Short for stereo pan mode vecsStereoSndCrd[i] = Float2Short ( fGainL * vecsStereoSndCrd[j] + fGainR * vecsStereoSndCrd[j + 1] ); } } } // Support for mono-in/stereo-out mode: Per definition this mode works in // full stereo mode at the transmission level. The only thing which is done // is to mix both sound card inputs together and then put this signal on // both stereo channels to be transmitted to the server. if ( eAudioChannelConf == CC_MONO_IN_STEREO_OUT ) { // copy mono data in stereo sound card buffer (note that since the input // and output is the same buffer, we have to start from the end not to // overwrite input values) for ( i = iMonoBlockSizeSam - 1, j = iStereoBlockSizeSam - 2; i >= 0; i--, j -= 2 ) { vecsStereoSndCrd[j] = vecsStereoSndCrd[j + 1] = vecsStereoSndCrd[i]; } } for ( i = 0; i < iSndCrdFrameSizeFactor; i++ ) { // OPUS encoding if ( CurOpusEncoder != nullptr ) { if ( bMuteOutStream ) { iUnused = opus_custom_encode ( CurOpusEncoder, &vecZeros[i * iNumAudioChannels * iOPUSFrameSizeSamples], iOPUSFrameSizeSamples, &vecCeltData[0], iCeltNumCodedBytes ); } else { iUnused = opus_custom_encode ( CurOpusEncoder, &vecsStereoSndCrd[i * iNumAudioChannels * iOPUSFrameSizeSamples], iOPUSFrameSizeSamples, &vecCeltData[0], iCeltNumCodedBytes ); } } // send coded audio through the network Channel.PrepAndSendPacket ( &Socket, vecCeltData, iCeltNumCodedBytes ); } // Receive signal ---------------------------------------------------------- // in case of mute stream, store local data if ( bMuteOutStream ) { vecsStereoSndCrdMuteStream = vecsStereoSndCrd; } for ( i = 0; i < iSndCrdFrameSizeFactor; i++ ) { // receive a new block const bool bReceiveDataOk = ( Channel.GetData ( vecbyNetwData, iCeltNumCodedBytes ) == GS_BUFFER_OK ); // get pointer to coded data and manage the flags if ( bReceiveDataOk ) { pCurCodedData = &vecbyNetwData[0]; // on any valid received packet, we clear the initialization phase flag bIsInitializationPhase = false; } else { // for lost packets use null pointer as coded input data pCurCodedData = nullptr; // invalidate the buffer OK status flag bJitterBufferOK = false; } // OPUS decoding if ( CurOpusDecoder != nullptr ) { iUnused = opus_custom_decode ( CurOpusDecoder, pCurCodedData, iCeltNumCodedBytes, &vecsStereoSndCrd[i * iNumAudioChannels * iOPUSFrameSizeSamples], iOPUSFrameSizeSamples ); } } // for muted stream we have to add our local data here if ( bMuteOutStream ) { for ( i = 0; i < iStereoBlockSizeSam; i++ ) { vecsStereoSndCrd[i] = Float2Short ( vecsStereoSndCrd[i] + vecsStereoSndCrdMuteStream[i] * fMuteOutStreamGain ); } } // check if channel is connected and if we do not have the initialization phase if ( Channel.IsConnected() && ( !bIsInitializationPhase ) ) { if ( eAudioChannelConf == CC_MONO ) { // copy mono data in stereo sound card buffer (note that since the input // and output is the same buffer, we have to start from the end not to // overwrite input values) for ( i = iMonoBlockSizeSam - 1, j = iStereoBlockSizeSam - 2; i >= 0; i--, j -= 2 ) { vecsStereoSndCrd[j] = vecsStereoSndCrd[j + 1] = vecsStereoSndCrd[i]; } } } else { // if not connected, clear data vecsStereoSndCrd.Reset ( 0 ); } // update socket buffer size Channel.UpdateSocketBufferSize(); Q_UNUSED ( iUnused ) } int CClient::EstimatedOverallDelay ( const int iPingTimeMs ) { const float fSystemBlockDurationMs = static_cast ( iOPUSFrameSizeSamples ) / SYSTEM_SAMPLE_RATE_HZ * 1000; // If the jitter buffers are set effectively, i.e. they are exactly the // size of the network jitter, then the delay of the buffer is the buffer // length. Since that is usually not the case but the buffers are usually // a bit larger than necessary, we introduce some factor for compensation. // Consider the jitter buffer on the client and on the server side, too. const float fTotalJitterBufferDelayMs = fSystemBlockDurationMs * ( GetSockBufNumFrames() + GetServerSockBufNumFrames() ) * 0.7f; // consider delay introduced by the sound card conversion buffer by using // "GetSndCrdConvBufAdditionalDelayMonoBlSize()" float fTotalSoundCardDelayMs = GetSndCrdConvBufAdditionalDelayMonoBlSize() * 1000.0f / SYSTEM_SAMPLE_RATE_HZ; // try to get the actual input/output sound card delay from the audio // interface, per definition it is not available if a 0 is returned const float fSoundCardInputOutputLatencyMs = Sound.GetInOutLatencyMs(); if ( fSoundCardInputOutputLatencyMs == 0.0f ) { // use an alternative approach for estimating the sound card delay: // // we assume that we have two period sizes for the input and one for the // output, therefore we have "3 *" instead of "2 *" (for input and output) // the actual sound card buffer size // "GetSndCrdConvBufAdditionalDelayMonoBlSize" fTotalSoundCardDelayMs += ( 3 * GetSndCrdActualMonoBlSize() ) * 1000.0f / SYSTEM_SAMPLE_RATE_HZ; } else { // add the actual sound card latency in ms fTotalSoundCardDelayMs += fSoundCardInputOutputLatencyMs; } // network packets are of the same size as the audio packets per definition // if no sound card conversion buffer is used const float fDelayToFillNetworkPacketsMs = GetSystemMonoBlSize() * 1000.0f / SYSTEM_SAMPLE_RATE_HZ; // OPUS additional delay at small frame sizes is half a frame size const float fAdditionalAudioCodecDelayMs = fSystemBlockDurationMs / 2; const float fTotalBufferDelayMs = fDelayToFillNetworkPacketsMs + fTotalJitterBufferDelayMs + fTotalSoundCardDelayMs + fAdditionalAudioCodecDelayMs; return MathUtils::round ( fTotalBufferDelayMs + iPingTimeMs ); } jamulus-3.9.1+dfsg/src/util.h0000644000175000017500000012615314340334543015101 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #include #include #ifdef _WIN32 # include # include # include # include #elif defined( __APPLE__ ) || defined( __MACOSX ) // using mach timers for Mac # include # include # include #else // using mach nanosleep for Linux # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef _WIN32 # include #endif #ifndef HEADLESS # include # include # include # include # include # include # include # include # include # include # include # include # include "ui_aboutdlgbase.h" #endif #include "global.h" #ifndef SERVER_ONLY class CClient; // forward declaration of CClient #endif /* Definitions ****************************************************************/ #define METER_FLY_BACK 2 #define INVALID_MIDI_CH -1 // invalid MIDI channel definition /* Global functions ***********************************************************/ // converting float to short inline short Float2Short ( const float fInput ) { // lower bound if ( fInput < _MINSHORT ) { return _MINSHORT; } // upper bound if ( fInput > _MAXSHORT ) { return _MAXSHORT; } return static_cast ( fInput ); } // calculate the bit rate in bits per second from the number of coded bytes inline int CalcBitRateBitsPerSecFromCodedBytes ( const int iCeltNumCodedBytes, const int iFrameSize ) { return ( SYSTEM_SAMPLE_RATE_HZ * iCeltNumCodedBytes * 8 ) / iFrameSize; } QString GetVersionAndNameStr ( const bool bDisplayInGui = true ); QString MakeClientNameTitle ( QString win, QString client ); QString TruncateString ( QString str, int position ); /******************************************************************************\ * CVector Base Class * \******************************************************************************/ template class CVector : public std::vector { public: CVector() {} CVector ( const int iNeSi ) { Init ( iNeSi ); } CVector ( const int iNeSi, const TData tInVa ) { Init ( iNeSi, tInVa ); } CVector ( CVector const& ) = default; void Init ( const int iNewSize ); // use this init to give all elements a defined value void Init ( const int iNewSize, const TData tIniVal ); // set all values to the given reset value void Reset ( const TData tResetVal ) { std::fill ( this->begin(), this->end(), tResetVal ); } void Enlarge ( const int iAddedSize ) { std::vector::resize ( std::vector::size() + iAddedSize ); } void Add ( const TData& tI ) { Enlarge ( 1 ); std::vector::back() = tI; } int StringFiFoWithCompare ( const QString strNewValue, const bool bDoAdding = true ); // this function simply converts the type of size to integer inline int Size() const { return static_cast ( std::vector::size() ); } }; /* Implementation *************************************************************/ template void CVector::Init ( const int iNewSize ) { // clear old buffer and reserve memory for new buffer std::vector::clear(); std::vector::resize ( iNewSize ); } template void CVector::Init ( const int iNewSize, const TData tIniVal ) { // call actual init routine and reset all values to the given value Init ( iNewSize ); Reset ( tIniVal ); } // note: this is only supported for string vectors template int CVector::StringFiFoWithCompare ( const QString strNewValue, const bool bDoAdding ) { const int iVectorSize = Size(); CVector vstrTempList ( iVectorSize, "" ); // init with illegal index per definition int iOldIndex = INVALID_INDEX; // init temporary list count (may be overwritten later on) int iTempListCnt = 0; if ( bDoAdding ) { // store the new element in the current storage list at // the top, make sure we do not have more than allowed stored // elements vstrTempList[0] = strNewValue; iTempListCnt = 1; } for ( int iIdx = 0; iIdx < iVectorSize; iIdx++ ) { // first check if we still have space in our data storage if ( iTempListCnt < iVectorSize ) { // only add old element if it is not the same as the // selected one if ( std::vector::operator[] ( iIdx ).compare ( strNewValue ) ) { vstrTempList[iTempListCnt] = std::vector::operator[] ( iIdx ); iTempListCnt++; } else { iOldIndex = iIdx; } } } // copy new generated list to data base *this = vstrTempList; return iOldIndex; } /******************************************************************************\ * CFIFO Class (First In, First Out) * \******************************************************************************/ template class CFIFO : public CVector { public: CFIFO() : iCurIdx ( 0 ) {} CFIFO ( const int iNeSi ) : CVector ( iNeSi ), iCurIdx ( 0 ) {} CFIFO ( const int iNeSi, const TData tInVa ) : CVector ( iNeSi, tInVa ), iCurIdx ( 0 ) {} void Add ( const TData tNewD ); inline TData Get() { return CVector::operator[] ( iCurIdx ); } virtual void Init ( const int iNewSize ); virtual void Init ( const int iNewSize, const TData tIniVal ); protected: int iCurIdx; }; template void CFIFO::Init ( const int iNewSize ) { iCurIdx = 0; CVector::Init ( iNewSize ); } template void CFIFO::Init ( const int iNewSize, const TData tIniVal ) { iCurIdx = 0; CVector::Init ( iNewSize, tIniVal ); } template void CFIFO::Add ( const TData tNewD ) { CVector::operator[] ( iCurIdx ) = tNewD; // increment index and check for wrap around iCurIdx++; if ( iCurIdx >= CVector::Size() ) { iCurIdx = 0; } } /******************************************************************************\ * CMovingAv Class (Moving Average) * \******************************************************************************/ template class CMovingAv : public CVector { public: CMovingAv() : CVector(), iCurIdx ( 0 ), iNorm ( 0 ), dCurAvResult ( 0 ), dNoDataResult ( 0 ) {} void Add ( const TData tNewD ); void Init ( const int iNewSize, const double dNNoDRes = 0 ); void Reset(); inline double GetAverage() { // make sure we do not divide by zero if ( iNorm == 0 ) { return dNoDataResult; } else { return dCurAvResult / iNorm; } } double InitializationState() const { // make sure we do not divide by zero if ( CVector::Size() != 0 ) { return static_cast ( iNorm ) / CVector::Size(); } else { return 0; } } protected: int iCurIdx; int iNorm; double dCurAvResult; double dNoDataResult; }; template void CMovingAv::Init ( const int iNewSize, const double dNNoDRes ) { iNorm = 0; iCurIdx = 0; dCurAvResult = 0; // only for scalars! dNoDataResult = dNNoDRes; CVector::Init ( iNewSize ); } template void CMovingAv::Reset() { iNorm = 0; iCurIdx = 0; dCurAvResult = 0; // only for scalars! CVector::Reset ( TData ( 0 ) ); } template void CMovingAv::Add ( const TData tNewD ) { /* Optimized calculation of the moving average. We only add a new value and subtract the old value from the result. We only need one addition and a history buffer. */ // subtract oldest value dCurAvResult -= CVector::operator[] ( iCurIdx ); // add new value and write in memory dCurAvResult += tNewD; CVector::operator[] ( iCurIdx ) = tNewD; // increase position pointer and test if wrap iCurIdx++; if ( iCurIdx >= CVector::Size() ) { iCurIdx = 0; } // take care of norm if ( iNorm < CVector::Size() ) { iNorm++; } } /******************************************************************************\ * GUI Utilities * \******************************************************************************/ #ifndef HEADLESS // Dialog base class ----------------------------------------------------------- class CBaseDlg : public QDialog { Q_OBJECT public: CBaseDlg ( QWidget* parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags() ) : QDialog ( parent, flags ) {} public slots: void keyPressEvent ( QKeyEvent* pEvent ) { // block escape key if ( pEvent->key() != Qt::Key_Escape ) { # ifdef ANDROID if ( pEvent->key() == Qt::Key_Back ) { close(); // otherwise, dialog does not show properly again in android (nefarius2001, #832) return; } # endif QDialog::keyPressEvent ( pEvent ); } } }; // About dialog ---------------------------------------------------------------- class CAboutDlg : public CBaseDlg, private Ui_CAboutDlgBase { Q_OBJECT public: CAboutDlg ( QWidget* parent = nullptr ); }; // Licence dialog -------------------------------------------------------------- class CLicenceDlg : public CBaseDlg { Q_OBJECT public: CLicenceDlg ( QWidget* parent = nullptr ); protected: QPushButton* butAccept; public slots: void OnAgreeStateChanged ( int value ) { butAccept->setEnabled ( value == Qt::Checked ); } }; // Help menu ------------------------------------------------------------------- class CHelpMenu : public QMenu { Q_OBJECT public: CHelpMenu ( const bool bIsClient, QWidget* parent = nullptr ); protected: CAboutDlg AboutDlg; public slots: void OnHelpWhatsThis() { QWhatsThis::enterWhatsThisMode(); } void OnHelpAbout() { AboutDlg.exec(); } void OnHelpAboutQt() { QMessageBox::aboutQt ( nullptr, QString ( tr ( "About Qt" ) ) ); } void OnHelpClientGetStarted() { QDesktopServices::openUrl ( QUrl ( CLIENT_GETTING_STARTED_URL ) ); } void OnHelpServerGetStarted() { QDesktopServices::openUrl ( QUrl ( SERVER_GETTING_STARTED_URL ) ); } void OnHelpSoftwareMan() { QDesktopServices::openUrl ( QUrl ( SOFTWARE_MANUAL_URL ) ); } }; // Language combo box ---------------------------------------------------------- class CLanguageComboBox : public QComboBox { Q_OBJECT public: CLanguageComboBox ( QWidget* parent = nullptr ); void Init ( QString& strSelLanguage ); protected: int iIdxSelectedLanguage; public slots: void OnLanguageActivated ( int iLanguageIdx ); signals: void LanguageChanged ( QString strLanguage ); }; // StackedLayout which auto-reduces to the size of the currently visible widget class CMinimumStackedLayout : public QStackedLayout { Q_OBJECT public: CMinimumStackedLayout ( QWidget* parent = nullptr ) : QStackedLayout ( parent ) {} virtual QSize sizeHint() const override; }; #endif /******************************************************************************\ * Other Classes/Enums * \******************************************************************************/ // Audio channel configuration ------------------------------------------------- enum EAudChanConf { // used for settings -> enum values should be fixed CC_MONO = 0, CC_MONO_IN_STEREO_OUT = 1, CC_STEREO = 2 }; // Audio compression type enum ------------------------------------------------- enum EAudComprType { // used for protocol -> enum values must be fixed! CT_NONE = 0, CT_CELT = 1, CT_OPUS = 2, CT_OPUS64 = 3 // using OPUS with 64 samples frame size }; // Network transport flags ----------------------------------------------------- enum ENetwFlags { // used for protocol -> enum values must be fixed! NF_NONE = 0, NF_WITH_COUNTER = 1 // using a network counter to correctly order UDP packets in jitter buffer }; // Audio quality enum ---------------------------------------------------------- enum EAudioQuality { // used for settings and the comobo box index -> enum values must be fixed! AQ_LOW = 0, AQ_NORMAL = 1, AQ_HIGH = 2 }; // Get data status enum -------------------------------------------------------- enum EGetDataStat { GS_BUFFER_OK, GS_BUFFER_UNDERRUN, GS_CHAN_NOW_DISCONNECTED, GS_CHAN_NOT_CONNECTED }; // GUI design enum ------------------------------------------------------------- enum EGUIDesign { // used for settings -> enum values should be fixed GD_STANDARD = 0, GD_ORIGINAL = 1, GD_SLIMFADER = 2 }; // MeterStyle enum ------------------------------------------------------------- enum EMeterStyle { // used for settings -> enum values should be fixed MT_BAR_NARROW = 0, MT_BAR_WIDE = 1, MT_LED_STRIPE = 2, MT_LED_ROUND_SMALL = 3, MT_LED_ROUND_BIG = 4 }; // Server licence type enum ---------------------------------------------------- enum ELicenceType { // used for protocol -> enum values must be fixed! LT_NO_LICENCE = 0, LT_CREATIVECOMMONS = 1 }; // Server jam recorder state enum ---------------------------------------------- enum ERecorderState { // used for protocol -> enum values must be fixed! RS_UNDEFINED = 0, RS_NOT_INITIALISED = 1, RS_NOT_ENABLED = 2, RS_RECORDING = 3 }; // Channel sort type ----------------------------------------------------------- enum EChSortType { // used for settings -> enum values should be fixed ST_NO_SORT = 0, ST_BY_NAME = 1, ST_BY_INSTRUMENT = 2, ST_BY_GROUPID = 3, ST_BY_CITY = 4 }; // Directory type -------------------------------------------------------------- enum EDirectoryType { // used for settings -> enum values should be fixed AT_NONE = -1, // means not registered, "invalid value" AT_DEFAULT = 0, AT_ANY_GENRE2 = 1, AT_ANY_GENRE3 = 2, AT_GENRE_ROCK = 3, AT_GENRE_JAZZ = 4, AT_GENRE_CLASSICAL_FOLK = 5, AT_GENRE_CHORAL = 6, AT_CUSTOM = 7 // Must be the last entry! }; inline QString DirectoryTypeToString ( EDirectoryType eAddrType ) { switch ( eAddrType ) { case AT_NONE: return QCoreApplication::translate ( "CServerDlg", "None" ); case AT_ANY_GENRE2: return QCoreApplication::translate ( "CClientSettingsDlg", "Any Genre 2" ); case AT_ANY_GENRE3: return QCoreApplication::translate ( "CClientSettingsDlg", "Any Genre 3" ); case AT_GENRE_ROCK: return QCoreApplication::translate ( "CClientSettingsDlg", "Genre Rock" ); case AT_GENRE_JAZZ: return QCoreApplication::translate ( "CClientSettingsDlg", "Genre Jazz" ); case AT_GENRE_CLASSICAL_FOLK: return QCoreApplication::translate ( "CClientSettingsDlg", "Genre Classical/Folk" ); case AT_GENRE_CHORAL: return QCoreApplication::translate ( "CClientSettingsDlg", "Genre Choral/Barbershop" ); case AT_CUSTOM: return QCoreApplication::translate ( "CClientSettingsDlg", "Custom" ); default: // AT_DEFAULT return QCoreApplication::translate ( "CClientSettingsDlg", "Any Genre 1" ); } } // Server registration state --------------------------------------------- enum ESvrRegStatus { SRS_NOT_REGISTERED, SRS_BAD_ADDRESS, SRS_REQUESTED, SRS_TIME_OUT, SRS_UNKNOWN_RESP, SRS_REGISTERED, SRS_SERVER_LIST_FULL, SRS_VERSION_TOO_OLD, SRS_NOT_FULFILL_REQUIREMENTS }; inline QString svrRegStatusToString ( ESvrRegStatus eSvrRegStatus ) { switch ( eSvrRegStatus ) { case SRS_NOT_REGISTERED: return QCoreApplication::translate ( "CServerDlg", "Not registered" ); case SRS_BAD_ADDRESS: return QCoreApplication::translate ( "CServerDlg", "Bad address" ); case SRS_REQUESTED: return QCoreApplication::translate ( "CServerDlg", "Registration requested" ); case SRS_TIME_OUT: return QCoreApplication::translate ( "CServerDlg", "Registration failed" ); case SRS_UNKNOWN_RESP: return QCoreApplication::translate ( "CServerDlg", "Check server version" ); case SRS_REGISTERED: return QCoreApplication::translate ( "CServerDlg", "Registered" ); case SRS_SERVER_LIST_FULL: return QCoreApplication::translate ( "CServerDlg", "Directory server list full" ); case SRS_VERSION_TOO_OLD: return QCoreApplication::translate ( "CServerDlg", "Your server version is too old" ); case SRS_NOT_FULFILL_REQUIREMENTS: return QCoreApplication::translate ( "CServerDlg", "Requirements not fulfilled" ); } return QString ( QCoreApplication::translate ( "CServerDlg", "Unknown value %1" ) ).arg ( eSvrRegStatus ); } // Directory server registration outcome --------------------------------------- enum ESvrRegResult { // used for protocol -> enum values must be fixed! SRR_REGISTERED = 0, SRR_SERVER_LIST_FULL = 1, SRR_VERSION_TOO_OLD = 2, SRR_NOT_FULFILL_REQIREMENTS = 3 }; // Skill level enum ------------------------------------------------------------ enum ESkillLevel { // used for protocol -> enum values must be fixed! SL_NOT_SET = 0, SL_BEGINNER = 1, SL_INTERMEDIATE = 2, SL_PROFESSIONAL = 3 }; // define the GUI RGB colors for each skill level #define RGBCOL_R_SL_NOT_SET 255 #define RGBCOL_G_SL_NOT_SET 255 #define RGBCOL_B_SL_NOT_SET 255 #define RGBCOL_R_SL_BEGINNER 255 #define RGBCOL_G_SL_BEGINNER 255 #define RGBCOL_B_SL_BEGINNER 200 #define RGBCOL_R_SL_INTERMEDIATE 225 #define RGBCOL_G_SL_INTERMEDIATE 255 #define RGBCOL_B_SL_INTERMEDIATE 225 #define RGBCOL_R_SL_SL_PROFESSIONAL 255 #define RGBCOL_G_SL_SL_PROFESSIONAL 225 #define RGBCOL_B_SL_SL_PROFESSIONAL 225 // Stereo signal level meter --------------------------------------------------- class CStereoSignalLevelMeter { public: //### TODO: BEGIN ###// // Calculate smoothing factor from sample rate and frame size (64 or 128 samples frame size). // But tests with 128 and 64 samples frame size have shown that the meter fly back // is ok for both numbers of samples frame size with a factor of 0.99. //### TODO: END ###// CStereoSignalLevelMeter ( const bool bNIsStereoOut = true, const double dNSmoothingFactor = 0.99 ) : dSmoothingFactor ( dNSmoothingFactor ), bIsStereoOut ( bNIsStereoOut ) { Reset(); } void Update ( const CVector& vecsAudio, const int iInSize, const bool bIsStereoIn ); double GetLevelForMeterdBLeftOrMono() { return CalcLogResultForMeter ( dCurLevelLOrMono ); } double GetLevelForMeterdBRight() { return CalcLogResultForMeter ( dCurLevelR ); } static double CalcLogResultForMeter ( const double& dLinearLevel ); void Reset() { dCurLevelLOrMono = 0.0; dCurLevelR = 0.0; } protected: double UpdateCurLevel ( double dCurLevel, const double dMax ); double dCurLevelLOrMono; double dCurLevelR; double dSmoothingFactor; bool bIsStereoOut; }; // Host address ---------------------------------------------------------------- class CHostAddress { public: enum EStringMode { SM_IP_PORT, SM_IP_NO_LAST_BYTE, SM_IP_NO_LAST_BYTE_PORT }; CHostAddress() : InetAddr ( static_cast ( 0 ) ), iPort ( 0 ) {} CHostAddress ( const QHostAddress NInetAddr, const quint16 iNPort ) : InetAddr ( NInetAddr ), iPort ( iNPort ) {} CHostAddress ( const CHostAddress& NHAddr ) : InetAddr ( NHAddr.InetAddr ), iPort ( NHAddr.iPort ) {} // copy operator CHostAddress& operator= ( const CHostAddress& NHAddr ) { InetAddr = NHAddr.InetAddr; iPort = NHAddr.iPort; return *this; } // compare operator bool operator== ( const CHostAddress& CompAddr ) const { return ( ( CompAddr.InetAddr == InetAddr ) && ( CompAddr.iPort == iPort ) ); } int Compare ( const CHostAddress& other ) const; QString toString ( const EStringMode eStringMode = SM_IP_PORT ) const; QHostAddress InetAddr; quint16 iPort; }; // Instrument picture data base ------------------------------------------------ // this is a pure static class class CInstPictures { public: enum EInstCategory { IC_OTHER_INSTRUMENT, IC_WIND_INSTRUMENT, IC_STRING_INSTRUMENT, IC_PLUCKING_INSTRUMENT, IC_PERCUSSION_INSTRUMENT, IC_KEYBOARD_INSTRUMENT, IC_MULTIPLE_INSTRUMENT }; // per definition: the very first instrument is the "not used" instrument static int GetNotUsedInstrument() { return 0; } static bool IsNotUsedInstrument ( const int iInstrument ) { return iInstrument == 0; } static int GetNumAvailableInst() { return GetTable().Size(); } static QString GetResourceReference ( const int iInstrument ); static QString GetName ( const int iInstrument ); static EInstCategory GetCategory ( const int iInstrument ); static void UpdateTableOnLanguageChange() { GetTable ( true ); } //### TODO: BEGIN ###// // make use of instrument category (not yet implemented) //### TODO: END ###// protected: class CInstPictProps { public: CInstPictProps() : strName ( "" ), strResourceReference ( "" ), eInstCategory ( IC_OTHER_INSTRUMENT ) {} CInstPictProps ( const QString NsName, const QString NsResRef, const EInstCategory NeInstCat ) : strName ( NsName ), strResourceReference ( NsResRef ), eInstCategory ( NeInstCat ) {} QString strName; QString strResourceReference; EInstCategory eInstCategory; }; static bool IsInstIndexInRange ( const int iIdx ); static CVector& GetTable ( const bool bReGenerateTable = false ); }; // Locale management class ----------------------------------------------------- class CLocale { public: static QString GetCountryFlagIconsResourceReference ( const QLocale::Country eCountry /* Always a Qt5 (!) code */ ); static QMap GetAvailableTranslations(); static QPair FindSysLangTransFileName ( const QMap& TranslMap ); static void LoadTranslation ( const QString strLanguage, QCoreApplication* pApp ); static QLocale::Country WireFormatCountryCodeToQtCountry ( unsigned short iCountryCode ); static unsigned short QtCountryToWireFormatCountryCode ( const QLocale::Country eCountry ); static bool IsCountryCodeSupported ( unsigned short iCountryCode ); static QLocale::Country GetCountryCodeByTwoLetterCode ( QString sTwoLetterCode ); #if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) // ./tools/qt5-to-qt6-country-code-table.py generates these lists: constexpr int const static wireFormatToQt6Table[] = { 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 35, 36, 37, 38, 39, 40, 41, 43, 45, 46, 48, 49, 50, 51, 53, 54, 55, 57, 56, 58, 59, 118, 60, 61, 63, 64, 65, 67, 68, 69, 232, 70, 71, 72, 73, 74, 75, 77, 80, 81, 82, 83, 84, 100, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 102, 101, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 116, 117, 119, 120, 122, 123, 124, 125, 174, 218, 127, 128, 129, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 158, 159, 160, 161, 162, 163, 164, 165, 62, 166, 167, 168, 170, 169, 171, 172, 173, 175, 176, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 197, 198, 201, 202, 203, 204, 205, 206, 208, 209, 210, 212, 213, 214, 215, 216, 217, 220, 221, 196, 200, 222, 223, 224, 76, 225, 226, 227, 228, 229, 230, 231, 233, 234, 235, 236, 238, 239, 240, 241, 242, 243, 244, 245, 246, 248, 247, 250, 251, 252, 253, 254, 255, 34, 249, 256, 257, 259, 42, 260, 261, 52, 157, 207, 195, 199, 130, 14, 2, 66, 47, 115, 121, 237, 219, 44, 211, 126, 79, 177, 258, 78, }; constexpr int const static qt6CountryToWireFormat[] = { 0, 1, 248, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 247, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 233, 32, 33, 34, 35, 36, 37, 38, 238, 39, 255, 40, 41, 250, 42, 43, 44, 45, 241, 46, 47, 48, 50, 49, 51, 52, 54, 55, 152, 56, 57, 58, 249, 59, 60, 61, 63, 64, 65, 66, 67, 68, 204, 69, 261, 258, 70, 71, 72, 73, 74, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 75, 92, 91, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 251, 105, 106, 53, 107, 108, 252, 109, 110, 111, 112, 257, 115, 116, 117, 246, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 242, 144, 145, 146, 147, 148, 149, 150, 151, 153, 154, 155, 157, 156, 158, 159, 160, 113, 161, 162, 259, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 244, 199, 180, 181, 245, 200, 182, 183, 184, 185, 186, 187, 243, 188, 189, 190, 256, 191, 192, 193, 194, 195, 196, 114, 254, 197, 198, 201, 202, 203, 205, 206, 207, 208, 209, 210, 211, 62, 212, 213, 214, 215, 253, 216, 217, 218, 219, 220, 221, 222, 223, 224, 226, 225, 234, 227, 228, 229, 230, 231, 232, 235, 236, 260, 237, 239, 240, }; constexpr int const static qt6CountryToWireFormatLen = sizeof ( qt6CountryToWireFormat ) / sizeof ( qt6CountryToWireFormat[0] ); #endif }; // Info of a channel ----------------------------------------------------------- class CChannelCoreInfo { public: CChannelCoreInfo() : strName ( "" ), eCountry ( QLocale::AnyCountry ), strCity ( "" ), iInstrument ( CInstPictures::GetNotUsedInstrument() ), eSkillLevel ( SL_NOT_SET ) {} CChannelCoreInfo ( const QString NsName, const QLocale::Country& NeCountry, const QString& NsCity, const int NiInstrument, const ESkillLevel NeSkillLevel ) : strName ( NsName ), eCountry ( NeCountry ), strCity ( NsCity ), iInstrument ( NiInstrument ), eSkillLevel ( NeSkillLevel ) {} CChannelCoreInfo ( const CChannelCoreInfo& NCorInf ) : strName ( NCorInf.strName ), eCountry ( NCorInf.eCountry ), strCity ( NCorInf.strCity ), iInstrument ( NCorInf.iInstrument ), eSkillLevel ( NCorInf.eSkillLevel ) {} // compare operator bool operator!= ( const CChannelCoreInfo& CompChanInfo ) { return ( ( CompChanInfo.strName != strName ) || ( CompChanInfo.eCountry != eCountry ) || ( CompChanInfo.strCity != strCity ) || ( CompChanInfo.iInstrument != iInstrument ) || ( CompChanInfo.eSkillLevel != eSkillLevel ) ); } CChannelCoreInfo& operator= ( const CChannelCoreInfo& ) = default; // fader tag text (channel name) QString strName; // country in which the client is located QLocale::Country eCountry; // city in which the client is located QString strCity; // instrument ID of the client (which instrument is he/she playing) int iInstrument; // skill level of the musician ESkillLevel eSkillLevel; }; class CChannelInfo : public CChannelCoreInfo { public: CChannelInfo() : iChanID ( 0 ) {} CChannelInfo ( const int NiID, const CChannelCoreInfo& NCorInf ) : CChannelCoreInfo ( NCorInf ), iChanID ( NiID ) {} CChannelInfo ( const int NiID, const QString NsName, const QLocale::Country& NeCountry, const QString& NsCity, const int NiInstrument, const ESkillLevel NeSkillLevel ) : CChannelCoreInfo ( NsName, NeCountry, NsCity, NiInstrument, NeSkillLevel ), iChanID ( NiID ) {} // ID of the channel int iChanID; }; // Server info ----------------------------------------------------------------- class CServerCoreInfo { public: CServerCoreInfo() : strName ( "" ), eCountry ( QLocale::AnyCountry ), strCity ( "" ), iMaxNumClients ( 0 ), bPermanentOnline ( false ) {} CServerCoreInfo ( const QString& NsName, const QLocale::Country& NeCountry, const QString& NsCity, const int NiMaxNumClients, const bool NbPermOnline ) : strName ( NsName ), eCountry ( NeCountry ), strCity ( NsCity ), iMaxNumClients ( NiMaxNumClients ), bPermanentOnline ( NbPermOnline ) {} // name of the server QString strName; // country in which the server is located QLocale::Country eCountry; // city in which the server is located QString strCity; // maximum number of clients which can connect to the server at the same // time int iMaxNumClients; // is the server permanently online or not (flag) bool bPermanentOnline; }; class CServerInfo : public CServerCoreInfo { public: CServerInfo() : HostAddr ( CHostAddress() ), LHostAddr ( CHostAddress() ) {} CServerInfo ( const CHostAddress& NHAddr, const CHostAddress& NLAddr, const QString& NsName, const QLocale::Country& NeCountry, const QString& NsCity, const int NiMaxNumClients, const bool NbPermOnline ) : CServerCoreInfo ( NsName, NeCountry, NsCity, NiMaxNumClients, NbPermOnline ), HostAddr ( NHAddr ), LHostAddr ( NLAddr ) {} // internet address of the server CHostAddress HostAddr; // server internal address CHostAddress LHostAddr; }; // Network transport properties ------------------------------------------------ class CNetworkTransportProps { public: CNetworkTransportProps() : iBaseNetworkPacketSize ( 0 ), iBlockSizeFact ( 0 ), iNumAudioChannels ( 0 ), iSampleRate ( 0 ), eAudioCodingType ( CT_NONE ), eFlags ( NF_NONE ), iAudioCodingArg ( 0 ) {} CNetworkTransportProps ( const uint32_t iNBNPS, const uint16_t iNBSF, const uint32_t iNNACH, const uint32_t iNSR, const EAudComprType eNACT, const ENetwFlags eNFlags, const int32_t iNACA ) : iBaseNetworkPacketSize ( iNBNPS ), iBlockSizeFact ( iNBSF ), iNumAudioChannels ( iNNACH ), iSampleRate ( iNSR ), eAudioCodingType ( eNACT ), eFlags ( eNFlags ), iAudioCodingArg ( iNACA ) {} uint32_t iBaseNetworkPacketSize; uint16_t iBlockSizeFact; uint32_t iNumAudioChannels; uint32_t iSampleRate; EAudComprType eAudioCodingType; ENetwFlags eFlags; int32_t iAudioCodingArg; }; // Network utility functions --------------------------------------------------- class NetworkUtil { public: static bool ParseNetworkAddress ( QString strAddress, CHostAddress& HostAddress, bool bEnableIPv6 ); static QString FixAddress ( const QString& strAddress ); static CHostAddress GetLocalAddress(); static CHostAddress GetLocalAddress6(); static QString GetDirectoryAddress ( const EDirectoryType eDirectoryType, const QString& strDirectoryAddress ); static bool IsPrivateNetworkIP ( const QHostAddress& qhAddr ); }; // Operating system utility functions ------------------------------------------ class COSUtil { public: enum EOpSystemType { // used for protocol -> enum values must be fixed! OT_WINDOWS = 0, OT_MAC_OS = 1, OT_LINUX = 2, OT_ANDROID = 3, OT_I_OS = 4, OT_UNIX = 5 }; static QString GetOperatingSystemString ( const EOpSystemType eOSType ) { switch ( eOSType ) { case OT_WINDOWS: return "Windows"; case OT_MAC_OS: return "MacOS"; case OT_LINUX: return "Linux"; case OT_ANDROID: return "Android"; case OT_I_OS: return "iOS"; case OT_UNIX: return "Unix"; default: return "Unknown"; } } static EOpSystemType GetOperatingSystem() { #ifdef _WIN32 return OT_WINDOWS; #elif defined( __APPLE__ ) || defined( __MACOSX ) return OT_MAC_OS; #elif defined( ANDROID ) return OT_ANDROID; #else return OT_LINUX; #endif } }; // Audio reverbration ---------------------------------------------------------- class CAudioReverb { public: CAudioReverb() {} void Init ( const EAudChanConf eNAudioChannelConf, const int iNStereoBlockSizeSam, const int iSampleRate, const float fT60 = 1.1f ); void Clear(); void Process ( CVector& vecsStereoInOut, const bool bReverbOnLeftChan, const float fAttenuation ); protected: void setT60 ( const float fT60, const int iSampleRate ); bool isPrime ( const int number ); class COnePole { public: COnePole() : fA ( 0 ), fB ( 0 ) { Reset(); } void setPole ( const float fPole ); float Calc ( const float fIn ); void Reset() { fLastSample = 0; } protected: float fA; float fB; float fLastSample; }; EAudChanConf eAudioChannelConf; int iStereoBlockSizeSam; CFIFO allpassDelays[3]; CFIFO combDelays[4]; COnePole combFilters[4]; CFIFO outLeftDelay; CFIFO outRightDelay; float allpassCoefficient; float combCoefficient[4]; }; // CRC ------------------------------------------------------------------------- class CCRC { public: CCRC() : iPoly ( ( 1 << 5 ) | ( 1 << 12 ) ), iBitOutMask ( 1 << 16 ) { Reset(); } void Reset(); void AddByte ( const uint8_t byNewInput ); bool CheckCRC ( const uint32_t iCRC ) { return iCRC == GetCRC(); } uint32_t GetCRC(); protected: uint32_t iPoly; uint32_t iBitOutMask; uint32_t iStateShiftReg; }; // Mathematics utilities ------------------------------------------------------- class MathUtils { public: static int round ( double x ) { return static_cast ( ( x - floor ( x ) ) >= 0.5 ) ? static_cast ( ceil ( x ) ) : static_cast ( floor ( x ) ); } static void UpDownIIR1 ( double& dOldValue, const double& dNewValue, const double& dWeightUp, const double& dWeightDown ) { // different IIR weights for up and down direction if ( dNewValue < dOldValue ) { dOldValue = dOldValue * dWeightDown + ( 1.0 - dWeightDown ) * dNewValue; } else { dOldValue = dOldValue * dWeightUp + ( 1.0 - dWeightUp ) * dNewValue; } } static int DecideWithHysteresis ( const double dValue, const int iOldValue, const double dHysteresis ) { // apply hysteresis if ( dValue > static_cast ( iOldValue ) ) { return round ( dValue - dHysteresis ); } else { return round ( dValue + dHysteresis ); } } // calculate pan gains: in cross fade mode the pan center is attenuated // by 6 dB, otherwise the center equals full gain for both channels static inline float GetLeftPan ( const float fPan, const bool bXFade ) { return bXFade ? 1 - fPan : std::min ( 0.5f, 1 - fPan ) * 2; } static inline float GetRightPan ( const float fPan, const bool bXFade ) { return bXFade ? fPan : std::min ( 0.5f, fPan ) * 2; } // calculate linear gain from fader values which are in dB static float CalcFaderGain ( const float fValue ) { // convert actual slider range in gain values // and normalize so that maximum gain is 1 const float fInValueRange0_1 = fValue / AUD_MIX_FADER_MAX; // map range from 0..1 to range -35..0 dB and calculate linear gain if ( fValue == 0 ) { return 0; // -infinity } else { return powf ( 10.0f, ( fInValueRange0_1 - 1.0f ) * AUD_MIX_FADER_RANGE_DB / 20.0f ); } } }; /******************************************************************************\ * Timing measurement * \******************************************************************************/ // intended for debugging the timing jitter of the sound card or server timer class CTimingMeas { public: CTimingMeas ( const int iNNMeas, const QString strNFName = "" ) : iNumMeas ( iNNMeas ), vElapsedTimes ( iNNMeas ), strFileName ( strNFName ) { Reset(); } void Reset() { iCnt = INVALID_INDEX; } void Measure() { // exclude the very first measurement (initialization phase) if ( iCnt == INVALID_INDEX ) { iCnt = 0; } else { // store current measurement vElapsedTimes[iCnt++] = ElapsedTimer.nsecsElapsed(); // reset count if number of measurements are done if ( iCnt >= iNumMeas ) { iCnt = 0; // store results in a file if file name is given if ( !strFileName.isEmpty() ) { QFile File ( strFileName ); if ( File.open ( QIODevice::WriteOnly | QIODevice::Text ) ) { QTextStream streamFile ( &File ); for ( int i = 0; i < iNumMeas; i++ ) { // convert ns in ms and store the value streamFile << i << " " << static_cast ( vElapsedTimes[i] ) / 1000000 << "\n"; } } } } } ElapsedTimer.start(); } protected: int iNumMeas; CVector vElapsedTimes; QString strFileName; QElapsedTimer ElapsedTimer; int iCnt; }; // High resolution timer #if ( defined( WIN32 ) || defined( _WIN32 ) ) // using QTimer for Windows class CHighPrecisionTimer : public QObject { Q_OBJECT public: CHighPrecisionTimer ( const bool bNewUseDoubleSystemFrameSize ); void Start(); void Stop(); bool isActive() const { return Timer.isActive(); } protected: QTimer Timer; CVector veciTimeOutIntervals; int iCurPosInVector; int iIntervalCounter; bool bUseDoubleSystemFrameSize; public slots: void OnTimer(); signals: void timeout(); }; #else class CHighPrecisionTimer : public QThread { Q_OBJECT public: CHighPrecisionTimer ( const bool bUseDoubleSystemFrameSize ); void Start(); void Stop(); bool isActive() { return bRun; } protected: virtual void run(); bool bRun; # if defined( __APPLE__ ) || defined( __MACOSX ) uint64_t Delay; uint64_t NextEnd; # else long Delay; timespec NextEnd; # endif signals: void timeout(); }; #endif /******************************************************************************\ * Statistics * \******************************************************************************/ // Error rate measurement ------------------------------------------------------ class CErrorRate { public: CErrorRate() {} void Init ( const int iHistoryLength, const bool bNBlockOnDoubleErr = false ) { // initialize buffer (use "no data result" of 1.0 which stands for the // worst error rate possible) ErrorsMovAvBuf.Init ( iHistoryLength, 1.0 ); bPreviousState = true; // store setting bBlockOnDoubleErrors = bNBlockOnDoubleErr; } void Reset() { ErrorsMovAvBuf.Reset(); bPreviousState = true; } void Update ( const bool bState ) { // if two states were false, do not use the new value if ( bBlockOnDoubleErrors && bPreviousState && bState ) { return; } // add errors as values 0 and 1 to get correct error rate average if ( bState ) { ErrorsMovAvBuf.Add ( 1 ); } else { ErrorsMovAvBuf.Add ( 0 ); } // store state bPreviousState = bState; } double GetAverage() { return ErrorsMovAvBuf.GetAverage(); } double InitializationState() { return ErrorsMovAvBuf.InitializationState(); } protected: CMovingAv ErrorsMovAvBuf; bool bBlockOnDoubleErrors; bool bPreviousState; }; jamulus-3.9.1+dfsg/src/socket.cpp0000644000175000017500000004227514340334543015751 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include "socket.h" #include "server.h" #ifdef _WIN32 # include # include #else # include #endif /* Implementation *************************************************************/ // Connections ------------------------------------------------------------- // it is important to do the following connections in this class since we // have a thread transition // we have different connections for client and server, created after Init in corresponding constructor CSocket::CSocket ( CChannel* pNewChannel, const quint16 iPortNumber, const quint16 iQosNumber, const QString& strServerBindIP, bool bEnableIPv6 ) : pChannel ( pNewChannel ), bIsClient ( true ), bJitterBufferOK ( true ), bEnableIPv6 ( bEnableIPv6 ) { Init ( iPortNumber, iQosNumber, strServerBindIP ); // client connections: QObject::connect ( this, &CSocket::ProtocolMessageReceived, pChannel, &CChannel::OnProtocolMessageReceived ); QObject::connect ( this, &CSocket::ProtocolCLMessageReceived, pChannel, &CChannel::OnProtocolCLMessageReceived ); QObject::connect ( this, static_cast ( &CSocket::NewConnection ), pChannel, &CChannel::OnNewConnection ); } CSocket::CSocket ( CServer* pNServP, const quint16 iPortNumber, const quint16 iQosNumber, const QString& strServerBindIP, bool bEnableIPv6 ) : pServer ( pNServP ), bIsClient ( false ), bJitterBufferOK ( true ), bEnableIPv6 ( bEnableIPv6 ) { Init ( iPortNumber, iQosNumber, strServerBindIP ); // server connections: QObject::connect ( this, &CSocket::ProtocolMessageReceived, pServer, &CServer::OnProtocolMessageReceived ); QObject::connect ( this, &CSocket::ProtocolCLMessageReceived, pServer, &CServer::OnProtocolCLMessageReceived ); QObject::connect ( this, static_cast ( &CSocket::NewConnection ), pServer, &CServer::OnNewConnection ); QObject::connect ( this, &CSocket::ServerFull, pServer, &CServer::OnServerFull ); } void CSocket::Init ( const quint16 iNewPortNumber, const quint16 iNewQosNumber, const QString& strNewServerBindIP ) { uSockAddr UdpSocketAddr; int UdpSocketAddrLen; uint16_t* UdpPort; // first store parameters, in case reinit is required (mostly for iOS) iPortNumber = iNewPortNumber; iQosNumber = iNewQosNumber; strServerBindIP = strNewServerBindIP; #ifdef _WIN32 // for the Windows socket usage we have to start it up first //### TODO: BEGIN ###// // check for error and exit application on error //### TODO: END ###// WSADATA wsa; WSAStartup ( MAKEWORD ( 1, 0 ), &wsa ); #endif memset ( &UdpSocketAddr, 0, sizeof ( UdpSocketAddr ) ); if ( bEnableIPv6 ) { // try to create a IPv6 UDP socket UdpSocket = socket ( AF_INET6, SOCK_DGRAM, 0 ); if ( UdpSocket == -1 ) { // IPv6 requested but not available, throw error throw CGenErr ( "IPv6 requested but not available on this system.", "Network Error" ); } // The IPV6_V6ONLY socket option must be false in order for the socket to listen on both protocols. // On Linux it's false by default on most (all?) distros, but on Windows it is true by default const uint8_t no = 0; setsockopt ( UdpSocket, IPPROTO_IPV6, IPV6_V6ONLY, (const char*) &no, sizeof ( no ) ); // set the QoS const char tos = (char) iQosNumber; // Quality of Service setsockopt ( UdpSocket, IPPROTO_IPV6, IPV6_TCLASS, &tos, sizeof ( tos ) ); UdpSocketAddr.sa6.sin6_family = AF_INET6; UdpSocketAddr.sa6.sin6_addr = in6addr_any; UdpSocketAddrLen = sizeof ( UdpSocketAddr.sa6 ); UdpPort = &UdpSocketAddr.sa6.sin6_port; // where to put the port number // FIXME: If binding a dual-protocol interface to a specific address, does it cease to be dual-protocol? // TODO - ALLOW IPV6 ADDRESS // if ( !strServerBindIP.isEmpty() ) //{ // UdpSocketInAddr.sin_addr.s_addr = htonl ( QHostAddress ( strServerBindIP ).toIPv4Address() ); //} // END TODO - ALLOW IPV6 ADDRESS } else { // create the UDP socket for IPv4 UdpSocket = socket ( AF_INET, SOCK_DGRAM, 0 ); if ( UdpSocket == -1 ) { // IPv4 requested but not available, throw error (should never happen, but check anyway) throw CGenErr ( "IPv4 requested but not available on this system.", "Network Error" ); } // set the QoS const char tos = (char) iQosNumber; // Quality of Service setsockopt ( UdpSocket, IPPROTO_IP, IP_TOS, &tos, sizeof ( tos ) ); // preinitialize socket in address (only the port number is missing) UdpSocketAddr.sa4.sin_family = AF_INET; UdpSocketAddr.sa4.sin_addr.s_addr = INADDR_ANY; UdpSocketAddrLen = sizeof ( UdpSocketAddr.sa4 ); UdpPort = &UdpSocketAddr.sa4.sin_port; // where to put the port number if ( !strServerBindIP.isEmpty() ) { UdpSocketAddr.sa4.sin_addr.s_addr = htonl ( QHostAddress ( strServerBindIP ).toIPv4Address() ); } } #ifdef Q_OS_IOS // ignore the broken pipe signal to avoid crash (iOS) int valueone = 1; setsockopt ( UdpSocket, SOL_SOCKET, SO_NOSIGPIPE, &valueone, sizeof ( valueone ) ); #endif // allocate memory for network receive and send buffer in samples vecbyRecBuf.Init ( MAX_SIZE_BYTES_NETW_BUF ); // initialize the listening socket bool bSuccess; if ( bIsClient ) { if ( iPortNumber == 0 ) { // if port number is 0, bind the client to a random available port *UdpPort = htons ( 0 ); bSuccess = ( ::bind ( UdpSocket, &UdpSocketAddr.sa, UdpSocketAddrLen ) == 0 ); } else { // If the port is not available, try "NUM_SOCKET_PORTS_TO_TRY" times // with incremented port numbers. Randomize the start port, in case a // faulty router gets stuck and confused by a particular port (like // the starting port). Might work around frustrating "cannot connect" // problems (#568) const quint16 startingPortNumber = iPortNumber + rand() % NUM_SOCKET_PORTS_TO_TRY; quint16 iClientPortIncrement = 0; bSuccess = false; // initialization for while loop while ( !bSuccess && ( iClientPortIncrement <= NUM_SOCKET_PORTS_TO_TRY ) ) { *UdpPort = htons ( startingPortNumber + iClientPortIncrement ); bSuccess = ( ::bind ( UdpSocket, &UdpSocketAddr.sa, UdpSocketAddrLen ) == 0 ); iClientPortIncrement++; } } } else { // for the server, only try the given port number and do not try out // other port numbers to bind since it is important that the server // gets the desired port number *UdpPort = htons ( iPortNumber ); bSuccess = ( ::bind ( UdpSocket, &UdpSocketAddr.sa, UdpSocketAddrLen ) == 0 ); } if ( !bSuccess ) { // we cannot bind socket, throw error throw CGenErr ( "Cannot bind the socket (maybe " "the software is already running).", "Network Error" ); } } void CSocket::Close() { #ifdef _WIN32 // closesocket will cause recvfrom to return with an error because the // socket is closed -> then the thread can safely be shut down closesocket ( UdpSocket ); #elif defined( __APPLE__ ) || defined( __MACOSX ) // on Mac the general close has the same effect as closesocket on Windows close ( UdpSocket ); #else // on Linux the shutdown call cancels the recvfrom shutdown ( UdpSocket, SHUT_RDWR ); #endif } CSocket::~CSocket() { // cleanup the socket (on Windows the WSA cleanup must also be called) #ifdef _WIN32 closesocket ( UdpSocket ); WSACleanup(); #else close ( UdpSocket ); #endif } void CSocket::SendPacket ( const CVector& vecbySendBuf, const CHostAddress& HostAddr ) { int status = 0; uSockAddr UdpSocketAddr; memset ( &UdpSocketAddr, 0, sizeof ( UdpSocketAddr ) ); QMutexLocker locker ( &Mutex ); const int iVecSizeOut = vecbySendBuf.Size(); if ( iVecSizeOut > 0 ) { // send packet through network (we have to convert the constant unsigned // char vector in "const char*", for this we first convert the const // uint8_t vector in a read/write uint8_t vector and then do the cast to // const char *) for ( int tries = 0; tries < 2; tries++ ) // retry loop in case send fails on iOS { if ( HostAddr.InetAddr.protocol() == QAbstractSocket::IPv4Protocol ) { if ( bEnableIPv6 ) { // Linux and Mac allow to pass an AF_INET address to a dual-stack socket, // but Windows does not. So use a V4MAPPED address in an AF_INET6 sockaddr, // which works on all platforms. UdpSocketAddr.sa6.sin6_family = AF_INET6; UdpSocketAddr.sa6.sin6_port = htons ( HostAddr.iPort ); uint32_t* addr = (uint32_t*) &UdpSocketAddr.sa6.sin6_addr; addr[0] = 0; addr[1] = 0; addr[2] = htonl ( 0xFFFF ); addr[3] = htonl ( HostAddr.InetAddr.toIPv4Address() ); status = sendto ( UdpSocket, (const char*) &( (CVector) vecbySendBuf )[0], iVecSizeOut, 0, &UdpSocketAddr.sa, sizeof ( UdpSocketAddr.sa6 ) ); } else { UdpSocketAddr.sa4.sin_family = AF_INET; UdpSocketAddr.sa4.sin_port = htons ( HostAddr.iPort ); UdpSocketAddr.sa4.sin_addr.s_addr = htonl ( HostAddr.InetAddr.toIPv4Address() ); status = sendto ( UdpSocket, (const char*) &( (CVector) vecbySendBuf )[0], iVecSizeOut, 0, &UdpSocketAddr.sa, sizeof ( UdpSocketAddr.sa4 ) ); } } else if ( bEnableIPv6 ) { UdpSocketAddr.sa6.sin6_family = AF_INET6; UdpSocketAddr.sa6.sin6_port = htons ( HostAddr.iPort ); inet_pton ( AF_INET6, HostAddr.InetAddr.toString().toLocal8Bit().constData(), &UdpSocketAddr.sa6.sin6_addr ); status = sendto ( UdpSocket, (const char*) &( (CVector) vecbySendBuf )[0], iVecSizeOut, 0, &UdpSocketAddr.sa, sizeof ( UdpSocketAddr.sa6 ) ); } if ( status >= 0 ) { break; // do not retry if success } #ifdef Q_OS_IOS // qDebug("Socket send exception - mostly happens in iOS when returning from idle"); Init ( iPortNumber, iQosNumber, strServerBindIP ); // reinit // loop back to retry #endif } } } bool CSocket::GetAndResetbJitterBufferOKFlag() { // check jitter buffer status if ( !bJitterBufferOK ) { // reset flag and return "not OK" status bJitterBufferOK = true; return false; } // the buffer was OK, we do not have to reset anything and just return the // OK status return true; } void CSocket::OnDataReceived() { /* The strategy of this function is that only the "put audio" function is called directly (i.e. the high thread priority is used) and all other less important things like protocol parsing and acting on protocol messages is done in the low priority thread. To get a thread transition, we have to use the signal/slot mechanism (i.e. we use messages for that). */ // read block from network interface and query address of sender uSockAddr UdpSocketAddr; #ifdef _WIN32 int SenderAddrSize = sizeof ( UdpSocketAddr ); #else socklen_t SenderAddrSize = sizeof ( UdpSocketAddr ); #endif const long iNumBytesRead = recvfrom ( UdpSocket, (char*) &vecbyRecBuf[0], MAX_SIZE_BYTES_NETW_BUF, 0, &UdpSocketAddr.sa, &SenderAddrSize ); // check if an error occurred or no data could be read if ( iNumBytesRead <= 0 ) { return; } if ( UdpSocketAddr.sa.sa_family == AF_INET6 ) { if ( IN6_IS_ADDR_V4MAPPED ( &( UdpSocketAddr.sa6.sin6_addr ) ) ) { const uint32_t addr = ( (const uint32_t*) ( &( UdpSocketAddr.sa6.sin6_addr ) ) )[3]; RecHostAddr.InetAddr.setAddress ( ntohl ( addr ) ); } else { RecHostAddr.InetAddr.setAddress ( UdpSocketAddr.sa6.sin6_addr.s6_addr ); } RecHostAddr.iPort = ntohs ( UdpSocketAddr.sa6.sin6_port ); } else { // convert address of client RecHostAddr.InetAddr.setAddress ( ntohl ( UdpSocketAddr.sa4.sin_addr.s_addr ) ); RecHostAddr.iPort = ntohs ( UdpSocketAddr.sa4.sin_port ); } // check if this is a protocol message int iRecCounter; int iRecID; CVector vecbyMesBodyData; if ( !CProtocol::ParseMessageFrame ( vecbyRecBuf, iNumBytesRead, vecbyMesBodyData, iRecCounter, iRecID ) ) { // this is a protocol message, check the type of the message if ( CProtocol::IsConnectionLessMessageID ( iRecID ) ) { //### TODO: BEGIN ###// // a copy of the vector is used -> avoid malloc in real-time routine emit ProtocolCLMessageReceived ( iRecID, vecbyMesBodyData, RecHostAddr ); //### TODO: END ###// } else { //### TODO: BEGIN ###// // a copy of the vector is used -> avoid malloc in real-time routine emit ProtocolMessageReceived ( iRecCounter, iRecID, vecbyMesBodyData, RecHostAddr ); //### TODO: END ###// } } else { // this is most probably a regular audio packet if ( bIsClient ) { // client: switch ( pChannel->PutAudioData ( vecbyRecBuf, iNumBytesRead, RecHostAddr ) ) { case PS_AUDIO_ERR: case PS_GEN_ERROR: bJitterBufferOK = false; break; case PS_NEW_CONNECTION: // inform other objects that new connection was established emit NewConnection(); break; case PS_AUDIO_INVALID: // inform about received invalid packet by fireing an event emit InvalidPacketReceived ( RecHostAddr ); break; default: // do nothing break; } } else { // server: int iCurChanID; if ( pServer->PutAudioData ( vecbyRecBuf, iNumBytesRead, RecHostAddr, iCurChanID ) ) { // we have a new connection, emit a signal emit NewConnection ( iCurChanID, pServer->GetNumberOfConnectedClients(), RecHostAddr ); // this was an audio packet, start server if it is in sleep mode if ( !pServer->IsRunning() ) { // (note that Qt will delete the event object when done) QCoreApplication::postEvent ( pServer, new CCustomEvent ( MS_PACKET_RECEIVED, 0, 0 ) ); } } // check if no channel is available if ( iCurChanID == INVALID_CHANNEL_ID ) { // fire message for the state that no free channel is available emit ServerFull ( RecHostAddr ); } } } } jamulus-3.9.1+dfsg/src/socket.h0000644000175000017500000001635014340334543015411 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #include #include #include #include #include "global.h" #include "protocol.h" #include "util.h" #ifndef _WIN32 # include # include #endif // The header files channel.h and server.h require to include this header file // so we get a cyclic dependency. To solve this issue, a prototype of the // channel class and server class is defined here. class CServer; // forward declaration of CServer class CChannel; // forward declaration of CChannel /* Definitions ****************************************************************/ // number of ports we try to bind until we give up #define NUM_SOCKET_PORTS_TO_TRY 100 /* Classes ********************************************************************/ /* Base socket class -------------------------------------------------------- */ class CSocket : public QObject { Q_OBJECT public: CSocket ( CChannel* pNewChannel, const quint16 iPortNumber, const quint16 iQosNumber, const QString& strServerBindIP, bool bEnableIPv6 ); CSocket ( CServer* pNServP, const quint16 iPortNumber, const quint16 iQosNumber, const QString& strServerBindIP, bool bEnableIPv6 ); virtual ~CSocket(); void SendPacket ( const CVector& vecbySendBuf, const CHostAddress& HostAddr ); bool GetAndResetbJitterBufferOKFlag(); void Close(); protected: void Init ( const quint16 iPortNumber, const quint16 iQosNumber, const QString& strServerBindIP ); quint16 iPortNumber; quint16 iQosNumber; QString strServerBindIP; #ifdef _WIN32 SOCKET UdpSocket; #else int UdpSocket; #endif QMutex Mutex; CVector vecbyRecBuf; CHostAddress RecHostAddr; QHostAddress SenderAddress; quint16 SenderPort; CChannel* pChannel; // for client CServer* pServer; // for server bool bIsClient; bool bJitterBufferOK; bool bEnableIPv6; public: void OnDataReceived(); signals: void NewConnection(); // for the client void NewConnection ( int iChID, int iTotChans, CHostAddress RecHostAddr ); // for the server void ServerFull ( CHostAddress RecHostAddr ); void InvalidPacketReceived ( CHostAddress RecHostAddr ); void ProtocolMessageReceived ( int iRecCounter, int iRecID, CVector vecbyMesBodyData, CHostAddress HostAdr ); void ProtocolCLMessageReceived ( int iRecID, CVector vecbyMesBodyData, CHostAddress HostAdr ); }; /* Socket which runs in a separate high priority thread --------------------- */ // The receive socket should be put in a high priority thread to ensure the GUI // does not effect the stability of the audio stream (e.g. if the GUI is on // high load because of a table update, the incoming network packets must still // be put in the jitter buffer with highest priority). class CHighPrioSocket : public QObject { Q_OBJECT public: CHighPrioSocket ( CChannel* pNewChannel, const quint16 iPortNumber, const quint16 iQosNumber, const QString& strServerBindIP, bool bEnableIPv6 ) : Socket ( pNewChannel, iPortNumber, iQosNumber, strServerBindIP, bEnableIPv6 ) { Init(); } CHighPrioSocket ( CChannel* pNewChannel, const quint16 iPortNumber, const quint16 iQosNumber, bool bEnableIPv6 ) : Socket ( pNewChannel, iPortNumber, iQosNumber, "", bEnableIPv6 ) { Init(); } CHighPrioSocket ( CServer* pNewServer, const quint16 iPortNumber, const quint16 iQosNumber, const QString& strServerBindIP, bool bEnableIPv6 ) : Socket ( pNewServer, iPortNumber, iQosNumber, strServerBindIP, bEnableIPv6 ) { Init(); } virtual ~CHighPrioSocket() { NetworkWorkerThread.Stop(); } void Start() { // starts the high priority socket receive thread (with using blocking // socket request call) NetworkWorkerThread.start ( QThread::TimeCriticalPriority ); } void SendPacket ( const CVector& vecbySendBuf, const CHostAddress& HostAddr ) { Socket.SendPacket ( vecbySendBuf, HostAddr ); } bool GetAndResetbJitterBufferOKFlag() { return Socket.GetAndResetbJitterBufferOKFlag(); } protected: class CSocketThread : public QThread { public: CSocketThread ( CSocket* pNewSocket = nullptr, QObject* parent = nullptr ) : QThread ( parent ), pSocket ( pNewSocket ), bRun ( true ) { setObjectName ( "CSocketThread" ); } void Stop() { // disable run flag so that the thread loop can be exit bRun = false; // to leave blocking wait for receive pSocket->Close(); // give thread some time to terminate wait ( 5000 ); } void SetSocket ( CSocket* pNewSocket ) { pSocket = pNewSocket; } protected: void run() { // make sure the socket pointer is initialized (should be always the // case) if ( pSocket != nullptr ) { while ( bRun ) { // this function is a blocking function (waiting for network // packets to be received and processed) pSocket->OnDataReceived(); } } } CSocket* pSocket; bool bRun; }; void Init() { // Creation of the new socket thread which has to have the highest // possible thread priority to make sure the jitter buffer is reliably // filled with the network audio packets and does not get interrupted // by other GUI threads. The following code is based on: // http://qt-project.org/wiki/Threads_Events_QObjects Socket.moveToThread ( &NetworkWorkerThread ); NetworkWorkerThread.SetSocket ( &Socket ); // connect the "InvalidPacketReceived" signal QObject::connect ( &Socket, &CSocket::InvalidPacketReceived, this, &CHighPrioSocket::InvalidPacketReceived ); } CSocketThread NetworkWorkerThread; CSocket Socket; signals: void InvalidPacketReceived ( CHostAddress RecHostAddr ); }; // overlay generic, IPv4 and IPv6 sockaddr structures typedef union { struct sockaddr sa; struct sockaddr_in sa4; struct sockaddr_in6 sa6; } uSockAddr; jamulus-3.9.1+dfsg/src/rpcserver.cpp0000644000175000017500000002344014340334543016465 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2021-2022 * * Author(s): * dtinth * Christian Hoffmann * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include "global.h" #include "rpcserver.h" CRpcServer::CRpcServer ( QObject* parent, int iPort, QString strSecret ) : QObject ( parent ), iPort ( iPort ), strSecret ( strSecret ), pTransportServer ( new QTcpServer ( this ) ) { connect ( pTransportServer, &QTcpServer::newConnection, this, &CRpcServer::OnNewConnection ); /// @rpc_method jamulus/getVersion /// @brief Returns Jamulus version. /// @param {object} params - No parameters (empty object). /// @result {string} result.version - The Jamulus version. HandleMethod ( "jamulus/getVersion", [=] ( const QJsonObject& params, QJsonObject& response ) { QJsonObject result{ { "version", VERSION } }; response["result"] = result; Q_UNUSED ( params ); } ); } CRpcServer::~CRpcServer() { if ( pTransportServer->isListening() ) { qInfo() << "- stopping RPC server"; pTransportServer->close(); } } bool CRpcServer::Start() { if ( iPort < 0 ) { return false; } if ( pTransportServer->listen ( QHostAddress ( JSON_RPC_LISTEN_ADDRESS ), iPort ) ) { qInfo() << qUtf8Printable ( QString ( "- JSON-RPC: Server started on %1:%2" ) .arg ( pTransportServer->serverAddress().toString() ) .arg ( pTransportServer->serverPort() ) ); return true; } qInfo() << "- JSON-RPC: Unable to start server:" << pTransportServer->errorString(); return false; } QJsonObject CRpcServer::CreateJsonRpcError ( int code, QString message ) { QJsonObject error; error["code"] = QJsonValue ( code ); error["message"] = QJsonValue ( message ); return error; } QJsonObject CRpcServer::CreateJsonRpcErrorReply ( int code, QString message ) { QJsonObject object; object["jsonrpc"] = QJsonValue ( "2.0" ); object["error"] = CreateJsonRpcError ( code, message ); return object; } void CRpcServer::OnNewConnection() { QTcpSocket* pSocket = pTransportServer->nextPendingConnection(); if ( !pSocket ) { return; } qDebug() << "- JSON-RPC: received connection from:" << pSocket->peerAddress().toString(); vecClients.append ( pSocket ); isAuthenticated[pSocket] = false; connect ( pSocket, &QTcpSocket::disconnected, [this, pSocket]() { qDebug() << "- JSON-RPC: connection from:" << pSocket->peerAddress().toString() << "closed"; vecClients.removeAll ( pSocket ); isAuthenticated.remove ( pSocket ); pSocket->deleteLater(); } ); connect ( pSocket, &QTcpSocket::readyRead, [this, pSocket]() { while ( pSocket->canReadLine() ) { QByteArray line = pSocket->readLine(); if ( line.trimmed().isEmpty() ) { Send ( pSocket, QJsonDocument ( CreateJsonRpcErrorReply ( iErrParseError, "Parse error: Blank line received" ) ) ); continue; } QJsonParseError parseError; QJsonDocument data = QJsonDocument::fromJson ( line, &parseError ); if ( parseError.error != QJsonParseError::NoError ) { Send ( pSocket, QJsonDocument ( CreateJsonRpcErrorReply ( iErrParseError, "Parse error: Invalid JSON received" ) ) ); pSocket->disconnectFromHost(); return; } if ( data.isArray() ) { // JSON-RPC batch mode: multiple requests in an array QJsonArray output; for ( auto item : data.array() ) { if ( !item.isObject() ) { output.append ( CreateJsonRpcErrorReply ( iErrInvalidRequest, "Invalid request: Non-object item encountered in a batch request array" ) ); pSocket->disconnectFromHost(); return; } auto object = item.toObject(); QJsonObject response; response["jsonrpc"] = QJsonValue ( "2.0" ); response["id"] = object["id"]; ProcessMessage ( pSocket, object, response ); output.append ( response ); } if ( output.size() < 1 ) { Send ( pSocket, QJsonDocument ( CreateJsonRpcErrorReply ( iErrInvalidRequest, "Invalid request: Empty batch request encountered" ) ) ); pSocket->disconnectFromHost(); return; } Send ( pSocket, QJsonDocument ( output ) ); continue; } if ( data.isObject() ) { auto object = data.object(); QJsonObject response; response["jsonrpc"] = QJsonValue ( "2.0" ); response["id"] = object["id"]; ProcessMessage ( pSocket, object, response ); Send ( pSocket, QJsonDocument ( response ) ); continue; } Send ( pSocket, QJsonDocument ( CreateJsonRpcErrorReply ( iErrInvalidRequest, "Invalid request: Unrecognized JSON; a request must be either an object or an array" ) ) ); pSocket->disconnectFromHost(); return; } } ); } void CRpcServer::Send ( QTcpSocket* pSocket, const QJsonDocument& aMessage ) { pSocket->write ( aMessage.toJson ( QJsonDocument::Compact ) + "\n" ); } void CRpcServer::HandleApiAuth ( QTcpSocket* pSocket, const QJsonObject& params, QJsonObject& response ) { auto userSecret = params["secret"]; if ( !userSecret.isString() ) { response["error"] = CreateJsonRpcError ( iErrInvalidParams, "Invalid params: secret is not a string" ); return; } if ( userSecret == strSecret ) { isAuthenticated[pSocket] = true; response["result"] = "ok"; qInfo() << "- JSON-RPC: accepted valid authentication secret from" << pSocket->peerAddress().toString(); return; } response["error"] = CreateJsonRpcError ( CRpcServer::iErrAuthenticationFailed, "Authentication failed." ); qWarning() << "- JSON-RPC: rejected invalid authentication secret from" << pSocket->peerAddress().toString(); } void CRpcServer::HandleMethod ( const QString& strMethod, CRpcHandler pHandler ) { mapMethodHandlers[strMethod] = pHandler; } void CRpcServer::ProcessMessage ( QTcpSocket* pSocket, QJsonObject message, QJsonObject& response ) { if ( !message["method"].isString() ) { response["error"] = CreateJsonRpcError ( iErrInvalidRequest, "Invalid request: The `method` member is not a string" ); return; } // Obtain the params auto jsonParams = message["params"]; if ( !jsonParams.isObject() ) { response["error"] = CreateJsonRpcError ( iErrInvalidParams, "Invalid params: The `params` member is not an object" ); return; } auto params = jsonParams.toObject(); // Obtain the method name auto method = message["method"].toString(); // Authentication must be allowed when un-authed if ( method == "jamulus/apiAuth" ) { /// @rpc_method jamulus/apiAuth /// @brief Authenticates the connection which is a requirement for calling further methods. /// @param {string} params.secret - The preshared secret key. /// @result {string} result - "ok" on success HandleApiAuth ( pSocket, params, response ); return; } // Require authentication for everything else if ( !isAuthenticated[pSocket] ) { response["error"] = CreateJsonRpcError ( iErrUnauthenticated, "Unauthenticated: Please authenticate using jamulus/apiAuth first" ); qInfo() << "- JSON-RPC: rejected unauthenticated request from" << pSocket->peerAddress().toString(); return; } // Obtain the method handler auto it = mapMethodHandlers.find ( method ); if ( it == mapMethodHandlers.end() ) { response["error"] = CreateJsonRpcError ( iErrMethodNotFound, "Method not found" ); return; } // Call the method handler auto methodHandler = mapMethodHandlers[method]; methodHandler ( params, response ); Q_UNUSED ( pSocket ); } void CRpcServer::BroadcastNotification ( const QString& strMethod, const QJsonObject& aParams ) { for ( auto socket : vecClients ) { if ( !isAuthenticated[socket] ) { continue; } QJsonObject notification; notification["jsonrpc"] = "2.0"; notification["method"] = strMethod; notification["params"] = aParams; Send ( socket, QJsonDocument ( notification ) ); } } jamulus-3.9.1+dfsg/src/client.h0000644000175000017500000004100414340334543015371 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #include #include #include #include #include #ifdef USE_OPUS_SHARED_LIB # include "opus/opus_custom.h" #else # include "opus_custom.h" #endif #include "global.h" #include "socket.h" #include "channel.h" #include "util.h" #include "buffer.h" #include "signalhandler.h" #if defined( _WIN32 ) && !defined( JACK_ON_WINDOWS ) # include "sound/asio/sound.h" #else # if ( defined( Q_OS_MACX ) ) && !defined( JACK_REPLACES_COREAUDIO ) # include "sound/coreaudio-mac/sound.h" # else # if defined( Q_OS_IOS ) # include "sound/coreaudio-ios/sound.h" # else # ifdef ANDROID # include "sound/oboe/sound.h" # else # include "sound/jack/sound.h" # ifndef JACK_ON_WINDOWS // these headers are not available in Windows OS # include # include # endif # include # endif # endif # endif #endif /* Definitions ****************************************************************/ // audio in fader range #define AUD_FADER_IN_MIN 0 #define AUD_FADER_IN_MAX 100 #define AUD_FADER_IN_MIDDLE ( AUD_FADER_IN_MAX / 2 ) // audio reverberation range #define AUD_REVERB_MAX 100 // default delay period between successive gain updates (ms) // this will be increased to double the ping time if connected to a distant server #define DEFAULT_GAIN_DELAY_PERIOD_MS 50 // OPUS number of coded bytes per audio packet // TODO we have to use new numbers for OPUS to avoid that old CELT packets // are used in the OPUS decoder (which gives a bad noise output signal). // Later on when the CELT is completely removed we could set the OPUS // numbers back to the original CELT values (to reduce network load) // calculation to get from the number of bytes to the code rate in bps: // rate [pbs] = Fs / L * N * 8, where // Fs: sampling rate (SYSTEM_SAMPLE_RATE_HZ) // L: number of samples per packet (SYSTEM_FRAME_SIZE_SAMPLES) // N: number of bytes per packet (values below) #define OPUS_NUM_BYTES_MONO_LOW_QUALITY 12 #define OPUS_NUM_BYTES_MONO_NORMAL_QUALITY 22 #define OPUS_NUM_BYTES_MONO_HIGH_QUALITY 36 #define OPUS_NUM_BYTES_MONO_LOW_QUALITY_DBLE_FRAMESIZE 25 #define OPUS_NUM_BYTES_MONO_NORMAL_QUALITY_DBLE_FRAMESIZE 45 #define OPUS_NUM_BYTES_MONO_HIGH_QUALITY_DBLE_FRAMESIZE 82 #define OPUS_NUM_BYTES_STEREO_LOW_QUALITY 24 #define OPUS_NUM_BYTES_STEREO_NORMAL_QUALITY 35 #define OPUS_NUM_BYTES_STEREO_HIGH_QUALITY 73 #define OPUS_NUM_BYTES_STEREO_LOW_QUALITY_DBLE_FRAMESIZE 47 #define OPUS_NUM_BYTES_STEREO_NORMAL_QUALITY_DBLE_FRAMESIZE 71 #define OPUS_NUM_BYTES_STEREO_HIGH_QUALITY_DBLE_FRAMESIZE 165 /* Classes ********************************************************************/ class CClient : public QObject { Q_OBJECT public: CClient ( const quint16 iPortNumber, const quint16 iQosNumber, const QString& strConnOnStartupAddress, const QString& strMIDISetup, const bool bNoAutoJackConnect, const QString& strNClientName, const bool bNEnableIPv6, const bool bNMuteMeInPersonalMix ); virtual ~CClient(); void Start(); void Stop(); bool IsRunning() { return Sound.IsRunning(); } bool IsCallbackEntered() const { return Sound.IsCallbackEntered(); } bool SetServerAddr ( QString strNAddr ); double GetLevelForMeterdBLeft() { return SignalLevelMeter.GetLevelForMeterdBLeftOrMono(); } double GetLevelForMeterdBRight() { return SignalLevelMeter.GetLevelForMeterdBRight(); } bool GetAndResetbJitterBufferOKFlag(); bool IsConnected() { return Channel.IsConnected(); } EGUIDesign GetGUIDesign() const { return eGUIDesign; } void SetGUIDesign ( const EGUIDesign eNGD ) { eGUIDesign = eNGD; } EMeterStyle GetMeterStyle() const { return eMeterStyle; } void SetMeterStyle ( const EMeterStyle eNMT ) { eMeterStyle = eNMT; } EAudioQuality GetAudioQuality() const { return eAudioQuality; } void SetAudioQuality ( const EAudioQuality eNAudioQuality ); EAudChanConf GetAudioChannels() const { return eAudioChannelConf; } void SetAudioChannels ( const EAudChanConf eNAudChanConf ); int GetAudioInFader() const { return iAudioInFader; } void SetAudioInFader ( const int iNV ) { iAudioInFader = iNV; } int GetReverbLevel() const { return iReverbLevel; } void SetReverbLevel ( const int iNL ) { iReverbLevel = iNL; } bool IsReverbOnLeftChan() const { return bReverbOnLeftChan; } void SetReverbOnLeftChan ( const bool bIL ) { bReverbOnLeftChan = bIL; AudioReverb.Clear(); } void SetDoAutoSockBufSize ( const bool bValue ); bool GetDoAutoSockBufSize() const { return Channel.GetDoAutoSockBufSize(); } void SetSockBufNumFrames ( const int iNumBlocks, const bool bPreserve = false ) { Channel.SetSockBufNumFrames ( iNumBlocks, bPreserve ); } int GetSockBufNumFrames() { return Channel.GetSockBufNumFrames(); } void SetServerSockBufNumFrames ( const int iNumBlocks ) { iServerSockBufNumFrames = iNumBlocks; // if auto setting is disabled, inform the server about the new size if ( !GetDoAutoSockBufSize() ) { Channel.CreateJitBufMes ( iServerSockBufNumFrames ); } } int GetServerSockBufNumFrames() { return iServerSockBufNumFrames; } int GetUploadRateKbps() { return Channel.GetUploadRateKbps(); } // sound card device selection QStringList GetSndCrdDevNames() { return Sound.GetDevNames(); } QString SetSndCrdDev ( const QString strNewDev ); QString GetSndCrdDev() { return Sound.GetDev(); } void OpenSndCrdDriverSetup() { Sound.OpenDriverSetup(); } // sound card channel selection int GetSndCrdNumInputChannels() { return Sound.GetNumInputChannels(); } QString GetSndCrdInputChannelName ( const int iDiD ) { return Sound.GetInputChannelName ( iDiD ); } void SetSndCrdLeftInputChannel ( const int iNewChan ); void SetSndCrdRightInputChannel ( const int iNewChan ); int GetSndCrdLeftInputChannel() { return Sound.GetLeftInputChannel(); } int GetSndCrdRightInputChannel() { return Sound.GetRightInputChannel(); } int GetSndCrdNumOutputChannels() { return Sound.GetNumOutputChannels(); } QString GetSndCrdOutputChannelName ( const int iDiD ) { return Sound.GetOutputChannelName ( iDiD ); } void SetSndCrdLeftOutputChannel ( const int iNewChan ); void SetSndCrdRightOutputChannel ( const int iNewChan ); int GetSndCrdLeftOutputChannel() { return Sound.GetLeftOutputChannel(); } int GetSndCrdRightOutputChannel() { return Sound.GetRightOutputChannel(); } void SetSndCrdPrefFrameSizeFactor ( const int iNewFactor ); int GetSndCrdPrefFrameSizeFactor() { return iSndCrdPrefFrameSizeFactor; } void SetEnableOPUS64 ( const bool eNEnableOPUS64 ); bool GetEnableOPUS64() { return bEnableOPUS64; } int GetSndCrdActualMonoBlSize() { // the actual sound card mono block size depends on whether a // sound card conversion buffer is used or not if ( bSndCrdConversionBufferRequired ) { return iSndCardMonoBlockSizeSamConvBuff; } else { return iMonoBlockSizeSam; } } int GetSystemMonoBlSize() { return iMonoBlockSizeSam; } int GetSndCrdConvBufAdditionalDelayMonoBlSize() { if ( bSndCrdConversionBufferRequired ) { // by introducing the conversion buffer we also introduce additional // delay which equals the "internal" mono buffer size return iMonoBlockSizeSam; } else { return 0; } } bool GetFraSiFactPrefSupported() { return bFraSiFactPrefSupported; } bool GetFraSiFactDefSupported() { return bFraSiFactDefSupported; } bool GetFraSiFactSafeSupported() { return bFraSiFactSafeSupported; } void SetMuteOutStream ( const bool bDoMute ) { bMuteOutStream = bDoMute; } void SetRemoteChanGain ( const int iId, const float fGain, const bool bIsMyOwnFader ); void OnTimerRemoteChanGain(); void StartDelayTimer(); void SetRemoteChanPan ( const int iId, const float fPan ) { Channel.SetRemoteChanPan ( iId, fPan ); } void SetInputBoost ( const int iNewBoost ) { iInputBoost = iNewBoost; } void SetRemoteInfo() { Channel.SetRemoteInfo ( ChannelInfo ); } void CreateChatTextMes ( const QString& strChatText ) { Channel.CreateChatTextMes ( strChatText ); } void CreateCLPingMes() { ConnLessProtocol.CreateCLPingMes ( Channel.GetAddress(), PreparePingMessage() ); } void CreateCLServerListPingMes ( const CHostAddress& InetAddr ) { ConnLessProtocol.CreateCLPingWithNumClientsMes ( InetAddr, PreparePingMessage(), 0 /* dummy */ ); } void CreateCLServerListReqVerAndOSMes ( const CHostAddress& InetAddr ) { ConnLessProtocol.CreateCLReqVersionAndOSMes ( InetAddr ); } void CreateCLServerListReqConnClientsListMes ( const CHostAddress& InetAddr ) { ConnLessProtocol.CreateCLReqConnClientsListMes ( InetAddr ); } void CreateCLReqServerListMes ( const CHostAddress& InetAddr ) { ConnLessProtocol.CreateCLReqServerListMes ( InetAddr ); } int EstimatedOverallDelay ( const int iPingTimeMs ); void GetBufErrorRates ( CVector& vecErrRates, double& dLimit, double& dMaxUpLimit ) { Channel.GetBufErrorRates ( vecErrRates, dLimit, dMaxUpLimit ); } // settings CChannelCoreInfo ChannelInfo; QString strClientName; protected: // callback function must be static, otherwise it does not work static void AudioCallback ( CVector& psData, void* arg ); void Init(); void ProcessSndCrdAudioData ( CVector& vecsStereoSndCrd ); void ProcessAudioDataIntern ( CVector& vecsStereoSndCrd ); int PreparePingMessage(); int EvaluatePingMessage ( const int iMs ); void CreateServerJitterBufferMessage(); // only one channel is needed for client application CChannel Channel; CProtocol ConnLessProtocol; // audio encoder/decoder OpusCustomMode* Opus64Mode; OpusCustomEncoder* Opus64EncoderMono; OpusCustomDecoder* Opus64DecoderMono; OpusCustomEncoder* Opus64EncoderStereo; OpusCustomDecoder* Opus64DecoderStereo; OpusCustomMode* OpusMode; OpusCustomEncoder* OpusEncoderMono; OpusCustomDecoder* OpusDecoderMono; OpusCustomEncoder* OpusEncoderStereo; OpusCustomDecoder* OpusDecoderStereo; OpusCustomEncoder* CurOpusEncoder; OpusCustomDecoder* CurOpusDecoder; EAudComprType eAudioCompressionType; int iCeltNumCodedBytes; int iOPUSFrameSizeSamples; EAudioQuality eAudioQuality; EAudChanConf eAudioChannelConf; int iNumAudioChannels; bool bIsInitializationPhase; bool bMuteOutStream; float fMuteOutStreamGain; CVector vecCeltData; CHighPrioSocket Socket; CSound Sound; CStereoSignalLevelMeter SignalLevelMeter; CVector vecbyNetwData; int iAudioInFader; bool bReverbOnLeftChan; int iReverbLevel; CAudioReverb AudioReverb; int iInputBoost; int iSndCrdPrefFrameSizeFactor; int iSndCrdFrameSizeFactor; bool bSndCrdConversionBufferRequired; int iSndCardMonoBlockSizeSamConvBuff; CBuffer SndCrdConversionBufferIn; CBuffer SndCrdConversionBufferOut; CVector vecDataConvBuf; CVector vecsStereoSndCrdMuteStream; CVector vecZeros; bool bFraSiFactPrefSupported; bool bFraSiFactDefSupported; bool bFraSiFactSafeSupported; int iMonoBlockSizeSam; int iStereoBlockSizeSam; EGUIDesign eGUIDesign; EMeterStyle eMeterStyle; bool bEnableAudioAlerts; bool bEnableOPUS64; bool bJitterBufferOK; bool bEnableIPv6; bool bMuteMeInPersonalMix; QMutex MutexDriverReinit; // server settings int iServerSockBufNumFrames; // for ping measurement QElapsedTimer PreciseTime; // for gain rate limiting QMutex MutexGain; QTimer TimerGain; int minGainId; int maxGainId; float oldGain[MAX_NUM_CHANNELS]; float newGain[MAX_NUM_CHANNELS]; int iCurPingTime; CSignalHandler* pSignalHandler; protected slots: void OnHandledSignal ( int sigNum ); void OnSendProtMessage ( CVector vecMessage ); void OnInvalidPacketReceived ( CHostAddress RecHostAddr ); void OnDetectedCLMessage ( CVector vecbyMesBodyData, int iRecID, CHostAddress RecHostAddr ); void OnReqJittBufSize() { CreateServerJitterBufferMessage(); } void OnJittBufSizeChanged ( int iNewJitBufSize ); void OnReqChanInfo() { Channel.SetRemoteInfo ( ChannelInfo ); } void OnNewConnection(); void OnCLDisconnection ( CHostAddress InetAddr ) { if ( InetAddr == Channel.GetAddress() ) { emit Disconnected(); } } void OnCLPingReceived ( CHostAddress InetAddr, int iMs ); void OnSendCLProtMessage ( CHostAddress InetAddr, CVector vecMessage ); void OnCLPingWithNumClientsReceived ( CHostAddress InetAddr, int iMs, int iNumClients ); void OnSndCrdReinitRequest ( int iSndCrdResetType ); void OnControllerInFaderLevel ( int iChannelIdx, int iValue ); void OnControllerInPanValue ( int iChannelIdx, int iValue ); void OnControllerInFaderIsSolo ( int iChannelIdx, bool bIsSolo ); void OnControllerInFaderIsMute ( int iChannelIdx, bool bIsMute ); void OnControllerInMuteMyself ( bool bMute ); void OnClientIDReceived ( int iChanID ); void OnConClientListMesReceived ( CVector vecChanInfo ); signals: void ConClientListMesReceived ( CVector vecChanInfo ); void ChatTextReceived ( QString strChatText ); void ClientIDReceived ( int iChanID ); void MuteStateHasChangedReceived ( int iChanID, bool bIsMuted ); void LicenceRequired ( ELicenceType eLicenceType ); void VersionAndOSReceived ( COSUtil::EOpSystemType eOSType, QString strVersion ); void PingTimeReceived ( int iPingTime ); void RecorderStateReceived ( ERecorderState eRecorderState ); void CLServerListReceived ( CHostAddress InetAddr, CVector vecServerInfo ); void CLRedServerListReceived ( CHostAddress InetAddr, CVector vecServerInfo ); void CLConnClientsListMesReceived ( CHostAddress InetAddr, CVector vecChanInfo ); void CLPingTimeWithNumClientsReceived ( CHostAddress InetAddr, int iPingTime, int iNumClients ); void CLVersionAndOSReceived ( CHostAddress InetAddr, COSUtil::EOpSystemType eOSType, QString strVersion ); void CLChannelLevelListReceived ( CHostAddress InetAddr, CVector vecLevelList ); void Disconnected(); void SoundDeviceChanged ( QString strError ); void ControllerInFaderLevel ( int iChannelIdx, int iValue ); void ControllerInPanValue ( int iChannelIdx, int iValue ); void ControllerInFaderIsSolo ( int iChannelIdx, bool bIsSolo ); void ControllerInFaderIsMute ( int iChannelIdx, bool bIsMute ); void ControllerInMuteMyself ( bool bMute ); }; jamulus-3.9.1+dfsg/src/threadpool.h0000644000175000017500000000713514340334543016263 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2021-2022 * * Author(s): * Stefan Menzel * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #ifndef THREAD_POOL_H #define THREAD_POOL_H #include #include #include #include #include #include #include #include #include class CThreadPool { public: CThreadPool() = default; CThreadPool ( size_t ); template auto enqueue ( F&& f, Args&&... args ) -> std::future::type>; ~CThreadPool(); private: // need to keep track of threads so we can join them std::vector workers; // the task queue std::queue> tasks; // synchronization std::mutex queue_mutex; std::condition_variable condition; bool stop; }; // the constructor just launches some amount of workers inline CThreadPool::CThreadPool ( size_t threads ) : stop ( false ) { for ( size_t i = 0; i < threads; ++i ) { workers.emplace_back ( [this] { for ( ;; ) { std::function task; { std::unique_lock lock ( this->queue_mutex ); this->condition.wait ( lock, [this] { return this->stop || !this->tasks.empty(); } ); if ( this->stop && this->tasks.empty() ) { return; } task = std::move ( this->tasks.front() ); this->tasks.pop(); } task(); } } ); } } // add new work item to the pool template auto CThreadPool::enqueue ( F&& f, Args&&... args ) -> std::future::type> { using return_type = typename std::result_of::type; auto task = std::make_shared> ( std::bind ( std::forward ( f ), std::forward ( args )... ) ); std::future res = task->get_future(); { std::unique_lock lock ( queue_mutex ); // don't allow enqueueing after stopping the pool if ( stop ) throw std::runtime_error ( "enqueue on stopped CThreadPool" ); tasks.emplace ( [task]() { ( *task )(); } ); } condition.notify_one(); return res; } // the destructor joins all threads inline CThreadPool::~CThreadPool() { { std::unique_lock lock ( queue_mutex ); stop = true; } condition.notify_all(); for ( std::thread& worker : workers ) worker.join(); } #endif jamulus-3.9.1+dfsg/src/connectdlg.cpp0000644000175000017500000011300114340334543016563 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include "connectdlg.h" /* Implementation *************************************************************/ CConnectDlg::CConnectDlg ( CClientSettings* pNSetP, const bool bNewShowCompleteRegList, const bool bNEnableIPv6, QWidget* parent ) : CBaseDlg ( parent, Qt::Dialog ), pSettings ( pNSetP ), strSelectedAddress ( "" ), strSelectedServerName ( "" ), bShowCompleteRegList ( bNewShowCompleteRegList ), bServerListReceived ( false ), bReducedServerListReceived ( false ), bServerListItemWasChosen ( false ), bListFilterWasActive ( false ), bShowAllMusicians ( true ), bEnableIPv6 ( bNEnableIPv6 ) { setupUi ( this ); // Add help text to controls ----------------------------------------------- // directory QString strDirectoryWT = "" + tr ( "Directory" ) + ": " + tr ( "Shows the servers listed by the selected directory. " "You can add custom directories in Advanced Settings." ); QString strDirectoryAN = tr ( "Directory combo box" ); lblList->setWhatsThis ( strDirectoryWT ); lblList->setAccessibleName ( strDirectoryAN ); cbxDirectoryServer->setWhatsThis ( strDirectoryWT ); cbxDirectoryServer->setAccessibleName ( strDirectoryAN ); // filter QString strFilterWT = "" + tr ( "Filter" ) + ": " + tr ( "Filters the server list by the given text. Note that the filter is case insensitive. " "A single # character will filter for those servers with at least one person connected." ); QString strFilterAN = tr ( "Filter edit box" ); lblFilter->setWhatsThis ( strFilterWT ); edtFilter->setWhatsThis ( strFilterWT ); lblFilter->setAccessibleName ( strFilterAN ); edtFilter->setAccessibleName ( strFilterAN ); // show all mucisians chbExpandAll->setWhatsThis ( "" + tr ( "Show All Musicians" ) + ": " + tr ( "Uncheck to collapse the server list to show just the server details. " "Check to show everyone on the servers." ) ); chbExpandAll->setAccessibleName ( tr ( "Show all musicians check box" ) ); // server list view lvwServers->setWhatsThis ( "" + tr ( "Server List" ) + ": " + tr ( "The Connection Setup window lists the available servers registered with " "the selected directory. Use the Directory dropdown to change the directory, " "find the server you want to join in the server list, click on it, and " "then click the Connect button to connect. Alternatively, double click on " "the server name to connect." ) + "
" + tr ( "Permanent servers (those that have been listed for longer than 48 hours) are shown in bold." ) + "
" + tr ( "You can add custom directories in Advanced Settings." ) ); lvwServers->setAccessibleName ( tr ( "Server list view" ) ); // server address QString strServAddrH = "" + tr ( "Server Address" ) + ": " + tr ( "If you know the server address, you can connect to it " "using the Server name/Address field. An optional port number can be added after the server " "address using a colon as a separator, e.g. %1. " "The field will also show a list of the most recently used server addresses." ) .arg ( QString ( "example.org:%1" ).arg ( DEFAULT_PORT_NUMBER ) ); lblServerAddr->setWhatsThis ( strServAddrH ); cbxServerAddr->setWhatsThis ( strServAddrH ); cbxServerAddr->setAccessibleName ( tr ( "Server address edit box" ) ); cbxServerAddr->setAccessibleDescription ( tr ( "Holds the current server address. It also stores old addresses in the combo box list." ) ); UpdateDirectoryServerComboBox(); // init server address combo box (max MAX_NUM_SERVER_ADDR_ITEMS entries) cbxServerAddr->setMaxCount ( MAX_NUM_SERVER_ADDR_ITEMS ); cbxServerAddr->setInsertPolicy ( QComboBox::NoInsert ); // set up list view for connected clients (note that the last column size // must not be specified since this column takes all the remaining space) #ifdef ANDROID // for Android we need larger numbers because of the default font size lvwServers->setColumnWidth ( 0, 200 ); lvwServers->setColumnWidth ( 1, 130 ); lvwServers->setColumnWidth ( 2, 100 ); #else lvwServers->setColumnWidth ( 0, 180 ); lvwServers->setColumnWidth ( 1, 75 ); lvwServers->setColumnWidth ( 2, 70 ); lvwServers->setColumnWidth ( 3, 220 ); #endif lvwServers->clear(); // make sure we do not get a too long horizontal scroll bar lvwServers->header()->setStretchLastSection ( false ); // add invisible columns which are used for sorting the list and storing // the current/maximum number of clients // 0: server name // 1: ping time // 2: number of musicians (including additional strings like " (full)") // 3: location // 4: minimum ping time (invisible) // 5: maximum number of clients (invisible) lvwServers->setColumnCount ( 6 ); lvwServers->hideColumn ( 4 ); lvwServers->hideColumn ( 5 ); // per default the root shall not be decorated (to save space) lvwServers->setRootIsDecorated ( false ); // make sure the connect button has the focus butConnect->setFocus(); // for "show all servers" mode make sort by click on header possible if ( bShowCompleteRegList ) { lvwServers->setSortingEnabled ( true ); lvwServers->sortItems ( 0, Qt::AscendingOrder ); } // set a placeholder text to explain how to filter occupied servers (#397) edtFilter->setPlaceholderText ( tr ( "Filter text, or # for occupied servers" ) ); // setup timers TimerInitialSort.setSingleShot ( true ); // only once after list request #ifdef ANDROID // for the android version maximize the window setWindowState ( Qt::WindowMaximized ); #endif // Connections ------------------------------------------------------------- // list view QObject::connect ( lvwServers, &QTreeWidget::itemDoubleClicked, this, &CConnectDlg::OnServerListItemDoubleClicked ); // to get default return key behaviour working QObject::connect ( lvwServers, &QTreeWidget::activated, this, &CConnectDlg::OnConnectClicked ); // line edit QObject::connect ( edtFilter, &QLineEdit::textEdited, this, &CConnectDlg::OnFilterTextEdited ); // combo boxes QObject::connect ( cbxServerAddr, &QComboBox::editTextChanged, this, &CConnectDlg::OnServerAddrEditTextChanged ); QObject::connect ( cbxDirectoryServer, static_cast ( &QComboBox::activated ), this, &CConnectDlg::OnDirectoryServerChanged ); // check boxes QObject::connect ( chbExpandAll, &QCheckBox::stateChanged, this, &CConnectDlg::OnExpandAllStateChanged ); // buttons QObject::connect ( butCancel, &QPushButton::clicked, this, &CConnectDlg::close ); QObject::connect ( butConnect, &QPushButton::clicked, this, &CConnectDlg::OnConnectClicked ); // timers QObject::connect ( &TimerPing, &QTimer::timeout, this, &CConnectDlg::OnTimerPing ); QObject::connect ( &TimerReRequestServList, &QTimer::timeout, this, &CConnectDlg::OnTimerReRequestServList ); } void CConnectDlg::showEvent ( QShowEvent* ) { // load stored IP addresses in combo box cbxServerAddr->clear(); cbxServerAddr->clearEditText(); for ( int iLEIdx = 0; iLEIdx < MAX_NUM_SERVER_ADDR_ITEMS; iLEIdx++ ) { if ( !pSettings->vstrIPAddress[iLEIdx].isEmpty() ) { cbxServerAddr->addItem ( pSettings->vstrIPAddress[iLEIdx] ); } } // on opening the connect dialg, we always want to request a // new updated server list per definition RequestServerList(); } void CConnectDlg::RequestServerList() { // reset flags bServerListReceived = false; bReducedServerListReceived = false; bServerListItemWasChosen = false; bListFilterWasActive = false; // clear current address and name strSelectedAddress = ""; strSelectedServerName = ""; // clear server list view lvwServers->clear(); // update list combo box (disable events to avoid a signal) cbxDirectoryServer->blockSignals ( true ); if ( pSettings->eDirectoryType == AT_CUSTOM ) { // iCustomDirectoryIndex is non-zero only if eDirectoryType == AT_CUSTOM // find the combobox item that corresponds to vstrDirectoryAddress[iCustomDirectoryIndex] // (the current selected custom directory) cbxDirectoryServer->setCurrentIndex ( cbxDirectoryServer->findData ( QVariant ( pSettings->iCustomDirectoryIndex ) ) ); } else { cbxDirectoryServer->setCurrentIndex ( static_cast ( pSettings->eDirectoryType ) ); } cbxDirectoryServer->blockSignals ( false ); // Get the IP address of the directory server (using the ParseNetworAddress // function) when the connect dialog is opened, this seems to be the correct // time to do it. Note that in case of custom directories we // use iCustomDirectoryIndex as an index into the vector. // Allow IPv4 only for communicating with Directories if ( NetworkUtil().ParseNetworkAddress ( NetworkUtil::GetDirectoryAddress ( pSettings->eDirectoryType, pSettings->vstrDirectoryAddress[pSettings->iCustomDirectoryIndex] ), haDirectoryAddress, false ) ) { // send the request for the server list emit ReqServerListQuery ( haDirectoryAddress ); // start timer, if this message did not get any respond to retransmit // the server list request message TimerReRequestServList.start ( SERV_LIST_REQ_UPDATE_TIME_MS ); TimerInitialSort.start ( SERV_LIST_REQ_UPDATE_TIME_MS ); // reuse the time value } } void CConnectDlg::hideEvent ( QHideEvent* ) { // if window is closed, stop timers TimerPing.stop(); TimerReRequestServList.stop(); } void CConnectDlg::OnDirectoryServerChanged ( int iTypeIdx ) { // store the new directory type and request new list // if iTypeIdx == AT_CUSTOM, then iCustomDirectoryIndex is the index into the vector holding the user's custom directory servers // if iTypeIdx != AT_CUSTOM, then iCustomDirectoryIndex MUST be 0; if ( iTypeIdx >= AT_CUSTOM ) { // the value for the index into the vector vstrDirectoryAddress is in the user data of the combobox item pSettings->iCustomDirectoryIndex = cbxDirectoryServer->itemData ( iTypeIdx ).toInt(); iTypeIdx = AT_CUSTOM; } else { pSettings->iCustomDirectoryIndex = 0; } pSettings->eDirectoryType = static_cast ( iTypeIdx ); RequestServerList(); } void CConnectDlg::OnTimerReRequestServList() { // if the server list is not yet received, retransmit the request for the // server list if ( !bServerListReceived ) { // note that this is a connection less message which may get lost // and therefore it makes sense to re-transmit it emit ReqServerListQuery ( haDirectoryAddress ); } } void CConnectDlg::SetServerList ( const CHostAddress& InetAddr, const CVector& vecServerInfo, const bool bIsReducedServerList ) { // If the normal list was received, we do not accept any further list // updates (to avoid the reduced list overwrites the normal list (#657)). Also, // we only accept a server list from the server address we have sent the // request for this to (note that we cannot use the port number since the // receive port and send port might be different at the directory server). if ( bServerListReceived || ( InetAddr.InetAddr != haDirectoryAddress.InetAddr ) ) { return; } // special treatment if a reduced server list was received if ( bIsReducedServerList ) { // make sure we only apply the reduced version list once if ( bReducedServerListReceived ) { // do nothing return; } else { bReducedServerListReceived = true; } } else { // set flag and disable timer for resend server list request if full list // was received (i.e. not the reduced list) bServerListReceived = true; TimerReRequestServList.stop(); } // first clear list lvwServers->clear(); // add list item for each server in the server list const int iServerInfoLen = vecServerInfo.Size(); for ( int iIdx = 0; iIdx < iServerInfoLen; iIdx++ ) { // get the host address, note that for the very first entry which is // the directory server, we have to use the receive host address // instead CHostAddress CurHostAddress; if ( iIdx > 0 ) { CurHostAddress = vecServerInfo[iIdx].HostAddr; } else { // substitute the receive host address for directory server CurHostAddress = InetAddr; } // create new list view item QTreeWidgetItem* pNewListViewItem = new QTreeWidgetItem ( lvwServers ); // make the entry invisible (will be set to visible on successful ping // result) if the complete list of registered servers shall not be shown if ( !bShowCompleteRegList ) { pNewListViewItem->setHidden ( true ); } // server name (if empty, show host address instead) if ( !vecServerInfo[iIdx].strName.isEmpty() ) { pNewListViewItem->setText ( 0, vecServerInfo[iIdx].strName ); } else { // IP address and port (use IP number without last byte) // Definition: If the port number is the default port number, we do // not show it. if ( vecServerInfo[iIdx].HostAddr.iPort == DEFAULT_PORT_NUMBER ) { // only show IP number, no port number pNewListViewItem->setText ( 0, CurHostAddress.toString ( CHostAddress::SM_IP_NO_LAST_BYTE ) ); } else { // show IP number and port pNewListViewItem->setText ( 0, CurHostAddress.toString ( CHostAddress::SM_IP_NO_LAST_BYTE_PORT ) ); } } // in case of all servers shown, add the registration number at the beginning if ( bShowCompleteRegList ) { pNewListViewItem->setText ( 0, QString ( "%1: " ).arg ( 1 + iIdx, 3 ) + pNewListViewItem->text ( 0 ) ); } // show server name in bold font if it is a permanent server QFont CurServerNameFont = pNewListViewItem->font ( 0 ); CurServerNameFont.setBold ( vecServerInfo[iIdx].bPermanentOnline ); pNewListViewItem->setFont ( 0, CurServerNameFont ); // the ping time shall be shown in bold font QFont CurPingTimeFont = pNewListViewItem->font ( 1 ); CurPingTimeFont.setBold ( true ); pNewListViewItem->setFont ( 1, CurPingTimeFont ); // server location (city and country) QString strLocation = vecServerInfo[iIdx].strCity; if ( ( !strLocation.isEmpty() ) && ( vecServerInfo[iIdx].eCountry != QLocale::AnyCountry ) ) { strLocation += ", "; } if ( vecServerInfo[iIdx].eCountry != QLocale::AnyCountry ) { QString strCountryToString = QLocale::countryToString ( vecServerInfo[iIdx].eCountry ); // Qt countryToString does not use spaces in between country name // parts but they use upper case letters which we can detect and // insert spaces as a post processing #if QT_VERSION >= QT_VERSION_CHECK( 5, 0, 0 ) if ( !strCountryToString.contains ( " " ) ) { QRegularExpressionMatchIterator reMatchIt = QRegularExpression ( "[A-Z][^A-Z]*" ).globalMatch ( strCountryToString ); QStringList slNames; while ( reMatchIt.hasNext() ) { slNames << reMatchIt.next().capturedTexts(); } strCountryToString = slNames.join ( " " ); } #endif strLocation += strCountryToString; } pNewListViewItem->setText ( 3, strLocation ); // init the minimum ping time with a large number (note that this number // must fit in an integer type) pNewListViewItem->setText ( 4, "99999999" ); // store the maximum number of clients pNewListViewItem->setText ( 5, QString().setNum ( vecServerInfo[iIdx].iMaxNumClients ) ); // store host address pNewListViewItem->setData ( 0, Qt::UserRole, CurHostAddress.toString() ); // per default expand the list item (if not "show all servers") if ( bShowAllMusicians ) { lvwServers->expandItem ( pNewListViewItem ); } } // immediately issue the ping measurements and start the ping timer since // the server list is filled now OnTimerPing(); TimerPing.start ( PING_UPDATE_TIME_SERVER_LIST_MS ); } void CConnectDlg::SetConnClientsList ( const CHostAddress& InetAddr, const CVector& vecChanInfo ) { // find the server with the correct address QTreeWidgetItem* pCurListViewItem = FindListViewItem ( InetAddr ); if ( pCurListViewItem ) { // first remove any existing children DeleteAllListViewItemChilds ( pCurListViewItem ); // get number of connected clients const int iNumConnectedClients = vecChanInfo.Size(); for ( int i = 0; i < iNumConnectedClients; i++ ) { // create new list view item QTreeWidgetItem* pNewChildListViewItem = new QTreeWidgetItem ( pCurListViewItem ); // child items shall use only one column pNewChildListViewItem->setFirstColumnSpanned ( true ); // set the clients name QString sClientText = vecChanInfo[i].strName; // set the icon: country flag has priority over instrument bool bCountryFlagIsUsed = false; if ( vecChanInfo[i].eCountry != QLocale::AnyCountry ) { // try to load the country flag icon QPixmap CountryFlagPixmap ( CLocale::GetCountryFlagIconsResourceReference ( vecChanInfo[i].eCountry ) ); // first check if resource reference was valid if ( !CountryFlagPixmap.isNull() ) { // set correct picture pNewChildListViewItem->setIcon ( 0, QIcon ( CountryFlagPixmap ) ); bCountryFlagIsUsed = true; } } if ( !bCountryFlagIsUsed ) { // get the resource reference string for this instrument const QString strCurResourceRef = CInstPictures::GetResourceReference ( vecChanInfo[i].iInstrument ); // first check if instrument picture is used or not and if it is valid if ( !( CInstPictures::IsNotUsedInstrument ( vecChanInfo[i].iInstrument ) || strCurResourceRef.isEmpty() ) ) { // set correct picture pNewChildListViewItem->setIcon ( 0, QIcon ( QPixmap ( strCurResourceRef ) ) ); } } // add the instrument information as text if ( !CInstPictures::IsNotUsedInstrument ( vecChanInfo[i].iInstrument ) ) { sClientText.append ( " (" + CInstPictures::GetName ( vecChanInfo[i].iInstrument ) + ")" ); } // apply the client text to the list view item pNewChildListViewItem->setText ( 0, sClientText ); // add the new child to the corresponding server item pCurListViewItem->addChild ( pNewChildListViewItem ); // at least one server has children now, show decoration to be able // to show the children lvwServers->setRootIsDecorated ( true ); } // the clients list may have changed, update the filter selection UpdateListFilter(); } } void CConnectDlg::OnServerListItemDoubleClicked ( QTreeWidgetItem* Item, int ) { // if a server list item was double clicked, it is the same as if the // connect button was clicked if ( Item != nullptr ) { OnConnectClicked(); } } void CConnectDlg::OnServerAddrEditTextChanged ( const QString& ) { // in the server address combo box, a text was changed, remove selection // in the server list (if any) lvwServers->clearSelection(); } void CConnectDlg::OnCustomDirectoriesChanged() { QString strPreviousSelection = cbxDirectoryServer->currentText(); UpdateDirectoryServerComboBox(); // after updating the combobox, we must re-select the previous directory selection if ( pSettings->eDirectoryType == AT_CUSTOM ) { // check if the currently select custom directory still exists in the now potentially re-ordered vector, // if so, then change to its new index. (addresses Issue #1899) int iNewIndex = cbxDirectoryServer->findText ( strPreviousSelection, Qt::MatchExactly ); if ( iNewIndex == INVALID_INDEX ) { // previously selected custom directory has been deleted. change to default directory pSettings->eDirectoryType = static_cast ( AT_DEFAULT ); pSettings->iCustomDirectoryIndex = 0; RequestServerList(); } else { // find previously selected custom directory in the now potentially re-ordered vector pSettings->eDirectoryType = static_cast ( AT_CUSTOM ); pSettings->iCustomDirectoryIndex = cbxDirectoryServer->itemData ( iNewIndex ).toInt(); cbxDirectoryServer->blockSignals ( true ); cbxDirectoryServer->setCurrentIndex ( cbxDirectoryServer->findData ( QVariant ( pSettings->iCustomDirectoryIndex ) ) ); cbxDirectoryServer->blockSignals ( false ); } } else { // selected directory was not a custom directory cbxDirectoryServer->blockSignals ( true ); cbxDirectoryServer->setCurrentIndex ( static_cast ( pSettings->eDirectoryType ) ); cbxDirectoryServer->blockSignals ( false ); } } void CConnectDlg::ShowAllMusicians ( const bool bState ) { bShowAllMusicians = bState; // update list if ( bState ) { lvwServers->expandAll(); } else { lvwServers->collapseAll(); } // update check box if necessary if ( ( chbExpandAll->checkState() == Qt::Checked && !bShowAllMusicians ) || ( chbExpandAll->checkState() == Qt::Unchecked && bShowAllMusicians ) ) { chbExpandAll->setCheckState ( bState ? Qt::Checked : Qt::Unchecked ); } } void CConnectDlg::UpdateListFilter() { const QString sFilterText = edtFilter->text(); if ( !sFilterText.isEmpty() ) { bListFilterWasActive = true; const int iServerListLen = lvwServers->topLevelItemCount(); for ( int iIdx = 0; iIdx < iServerListLen; iIdx++ ) { QTreeWidgetItem* pCurListViewItem = lvwServers->topLevelItem ( iIdx ); bool bFilterFound = false; // DEFINITION: if "#" is set at the beginning of the filter text, we show // occupied servers (#397) if ( ( sFilterText.indexOf ( "#" ) == 0 ) && ( sFilterText.length() == 1 ) ) { // special case: filter for occupied servers if ( pCurListViewItem->childCount() > 0 ) { bFilterFound = true; } } else { // search server name if ( pCurListViewItem->text ( 0 ).indexOf ( sFilterText, 0, Qt::CaseInsensitive ) >= 0 ) { bFilterFound = true; } // search location if ( pCurListViewItem->text ( 3 ).indexOf ( sFilterText, 0, Qt::CaseInsensitive ) >= 0 ) { bFilterFound = true; } // search children for ( int iCCnt = 0; iCCnt < pCurListViewItem->childCount(); iCCnt++ ) { if ( pCurListViewItem->child ( iCCnt )->text ( 0 ).indexOf ( sFilterText, 0, Qt::CaseInsensitive ) >= 0 ) { bFilterFound = true; } } } // only update Hide state if ping time was received if ( !pCurListViewItem->text ( 1 ).isEmpty() || bShowCompleteRegList ) { // only update hide and expand status if the hide state has to be changed to // preserve if user clicked on expand icon manually if ( ( pCurListViewItem->isHidden() && bFilterFound ) || ( !pCurListViewItem->isHidden() && !bFilterFound ) ) { pCurListViewItem->setHidden ( !bFilterFound ); pCurListViewItem->setExpanded ( bShowAllMusicians ); } } } } else { // if the filter was active but is now disabled, we have to update all list // view items for the "ping received" hide state if ( bListFilterWasActive ) { const int iServerListLen = lvwServers->topLevelItemCount(); for ( int iIdx = 0; iIdx < iServerListLen; iIdx++ ) { QTreeWidgetItem* pCurListViewItem = lvwServers->topLevelItem ( iIdx ); // if ping time is empty, hide item (if not already hidden) if ( pCurListViewItem->text ( 1 ).isEmpty() && !bShowCompleteRegList ) { pCurListViewItem->setHidden ( true ); } else { // in case it was hidden, show it and take care of expand if ( pCurListViewItem->isHidden() ) { pCurListViewItem->setHidden ( false ); pCurListViewItem->setExpanded ( bShowAllMusicians ); } } } bListFilterWasActive = false; } } } void CConnectDlg::OnConnectClicked() { // get the IP address to be used according to the following definitions: // - if the list has focus and a line is selected, use this line // - if the list has no focus, use the current combo box text QList CurSelListItemList = lvwServers->selectedItems(); if ( CurSelListItemList.count() > 0 ) { // get the parent list view item QTreeWidgetItem* pCurSelTopListItem = GetParentListViewItem ( CurSelListItemList[0] ); // get host address from selected list view item as a string strSelectedAddress = pCurSelTopListItem->data ( 0, Qt::UserRole ).toString(); // store selected server name strSelectedServerName = pCurSelTopListItem->text ( 0 ); // set flag that a server list item was chosen to connect bServerListItemWasChosen = true; } else { strSelectedAddress = NetworkUtil::FixAddress ( cbxServerAddr->currentText() ); } // tell the parent window that the connection shall be initiated done ( QDialog::Accepted ); } void CConnectDlg::OnTimerPing() { // send ping messages to the servers in the list const int iServerListLen = lvwServers->topLevelItemCount(); for ( int iIdx = 0; iIdx < iServerListLen; iIdx++ ) { CHostAddress haServerAddress; // try to parse host address string which is stored as user data // in the server list item GUI control element if ( NetworkUtil().ParseNetworkAddress ( lvwServers->topLevelItem ( iIdx )->data ( 0, Qt::UserRole ).toString(), haServerAddress, bEnableIPv6 ) ) { // if address is valid, send ping message using a new thread #if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) QFuture f = QtConcurrent::run ( &CConnectDlg::EmitCLServerListPingMes, this, haServerAddress ); Q_UNUSED ( f ); #else QtConcurrent::run ( this, &CConnectDlg::EmitCLServerListPingMes, haServerAddress ); #endif } } } void CConnectDlg::EmitCLServerListPingMes ( const CHostAddress& haServerAddress ) { // The ping time messages for all servers should not be sent all in a very // short time since it showed that this leads to errors in the ping time // measurement (#49). We therefore introduce a short delay for each server // (since we are doing this in a separate thread for each server, we do not // block the GUI). QThread::msleep ( 11 ); emit CreateCLServerListPingMes ( haServerAddress ); } void CConnectDlg::SetPingTimeAndNumClientsResult ( const CHostAddress& InetAddr, const int iPingTime, const int iNumClients ) { // apply the received ping time to the correct server list entry QTreeWidgetItem* pCurListViewItem = FindListViewItem ( InetAddr ); if ( pCurListViewItem ) { // check if this is the first time a ping time is set const bool bIsFirstPing = pCurListViewItem->text ( 1 ).isEmpty(); bool bDoSorting = false; // update minimum ping time column (invisible, used for sorting) if // the new value is smaller than the old value int iMinPingTime = pCurListViewItem->text ( 4 ).toInt(); if ( iMinPingTime > iPingTime ) { // update the minimum ping time with the new lowest value iMinPingTime = iPingTime; // we pad to a total of 8 characters with zeros to make sure the // sorting is done correctly pCurListViewItem->setText ( 4, QString ( "%1" ).arg ( iPingTime, 8, 10, QLatin1Char ( '0' ) ) ); // update the sorting (lowest number on top) bDoSorting = true; } // for debugging it is good to see the current ping time in the list // and not the minimum ping time -> overwrite the value for debugging if ( bShowCompleteRegList ) { iMinPingTime = iPingTime; } // Only show minimum ping time in the list since this is the important // value. Temporary bad ping measurements are of no interest. // Color definition: <= 25 ms green, <= 50 ms yellow, otherwise red if ( iMinPingTime <= 25 ) { pCurListViewItem->setForeground ( 1, Qt::darkGreen ); } else { if ( iMinPingTime <= 50 ) { pCurListViewItem->setForeground ( 1, Qt::darkYellow ); } else { pCurListViewItem->setForeground ( 1, Qt::red ); } } // update ping text, take special care if ping time exceeds a // certain value if ( iMinPingTime > 500 ) { pCurListViewItem->setText ( 1, ">500 ms" ); } else { // prepend spaces so that we can sort correctly (fieldWidth of // 4 is sufficient since the maximum width is ">500") (#201) pCurListViewItem->setText ( 1, QString ( "%1 ms" ).arg ( iMinPingTime, 4, 10, QLatin1Char ( ' ' ) ) ); } // update number of clients text if ( pCurListViewItem->text ( 5 ).toInt() == 0 ) { // special case: reduced server list pCurListViewItem->setText ( 2, QString().setNum ( iNumClients ) ); } else if ( iNumClients >= pCurListViewItem->text ( 5 ).toInt() ) { pCurListViewItem->setText ( 2, QString().setNum ( iNumClients ) + " (full)" ); } else { pCurListViewItem->setText ( 2, QString().setNum ( iNumClients ) + "/" + pCurListViewItem->text ( 5 ) ); } // check if the number of child list items matches the number of // connected clients, if not then request the client names if ( iNumClients != pCurListViewItem->childCount() ) { emit CreateCLServerListReqConnClientsListMes ( InetAddr ); } // this is the first time a ping time was received, set item to visible if ( bIsFirstPing ) { pCurListViewItem->setHidden ( false ); } // Update sorting. Note that the sorting must be the last action for the // current item since the topLevelItem(iIdx) is then no longer valid. // To avoid that the list is sorted shortly before a double click (which // could lead to connecting an incorrect server) the sorting is disabled // as long as the mouse is over the list (but it is not disabled for the // initial timer of about 2s, see TimerInitialSort) (#293). if ( bDoSorting && !bShowCompleteRegList && ( TimerInitialSort.isActive() || !lvwServers->underMouse() ) ) // do not sort if "show all servers" { lvwServers->sortByColumn ( 4, Qt::AscendingOrder ); } } // if no server item has children, do not show decoration bool bAnyListItemHasChilds = false; const int iServerListLen = lvwServers->topLevelItemCount(); for ( int iIdx = 0; iIdx < iServerListLen; iIdx++ ) { // check if the current list item has children if ( lvwServers->topLevelItem ( iIdx )->childCount() > 0 ) { bAnyListItemHasChilds = true; } } if ( !bAnyListItemHasChilds ) { lvwServers->setRootIsDecorated ( false ); } // we may have changed the Hidden state for some items, if a filter was active, we now // have to update it to void lines appear which do not satisfy the filter criteria UpdateListFilter(); } QTreeWidgetItem* CConnectDlg::FindListViewItem ( const CHostAddress& InetAddr ) { const int iServerListLen = lvwServers->topLevelItemCount(); for ( int iIdx = 0; iIdx < iServerListLen; iIdx++ ) { // compare the received address with the user data string of the // host address by a string compare if ( !lvwServers->topLevelItem ( iIdx )->data ( 0, Qt::UserRole ).toString().compare ( InetAddr.toString() ) ) { return lvwServers->topLevelItem ( iIdx ); } } return nullptr; } QTreeWidgetItem* CConnectDlg::GetParentListViewItem ( QTreeWidgetItem* pItem ) { // check if the current item is already the top item, i.e. the parent // query fails and returns null if ( pItem->parent() ) { // we only have maximum one level, i.e. if we call the parent function // we are at the top item return pItem->parent(); } else { // this item is already the top item return pItem; } } void CConnectDlg::DeleteAllListViewItemChilds ( QTreeWidgetItem* pItem ) { // loop over all children while ( pItem->childCount() > 0 ) { // get the first child in the list QTreeWidgetItem* pCurChildItem = pItem->child ( 0 ); // remove it from the item (note that the object is not deleted) pItem->removeChild ( pCurChildItem ); // delete the object to avoid a memory leak delete pCurChildItem; } } void CConnectDlg::UpdateDirectoryServerComboBox() { // directory type combo box cbxDirectoryServer->clear(); cbxDirectoryServer->addItem ( DirectoryTypeToString ( AT_DEFAULT ) ); cbxDirectoryServer->addItem ( DirectoryTypeToString ( AT_ANY_GENRE2 ) ); cbxDirectoryServer->addItem ( DirectoryTypeToString ( AT_ANY_GENRE3 ) ); cbxDirectoryServer->addItem ( DirectoryTypeToString ( AT_GENRE_ROCK ) ); cbxDirectoryServer->addItem ( DirectoryTypeToString ( AT_GENRE_JAZZ ) ); cbxDirectoryServer->addItem ( DirectoryTypeToString ( AT_GENRE_CLASSICAL_FOLK ) ); cbxDirectoryServer->addItem ( DirectoryTypeToString ( AT_GENRE_CHORAL ) ); // because custom directories are always added to the top of the vector, add the vector // contents to the combobox in reverse order for ( int i = MAX_NUM_SERVER_ADDR_ITEMS - 1; i >= 0; i-- ) { if ( pSettings->vstrDirectoryAddress[i] != "" ) { // add vector index (i) to the combobox as user data cbxDirectoryServer->addItem ( pSettings->vstrDirectoryAddress[i], i ); } } } jamulus-3.9.1+dfsg/src/multicolorled.h0000644000175000017500000000421714340334543016776 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * * Description: * * SetLight(): * 0: Green * 1: Yellow * 2: Red * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #include #include #include #include "global.h" /* Classes ********************************************************************/ class CMultiColorLED : public QLabel { Q_OBJECT public: enum ELightColor { RL_DISABLED, RL_GREY, RL_GREEN, RL_YELLOW, RL_RED }; enum EType { MT_LED, MT_INDICATOR }; CMultiColorLED ( QWidget* parent = nullptr ); void Reset(); void SetLight ( const ELightColor eNewStatus ); void SetType ( const EType eNType ); protected: ELightColor eColorFlag; virtual void changeEvent ( QEvent* curEvent ); void SetColor ( const ELightColor eNewColorFlag ); QPixmap BitmCubeDisabled; QPixmap BitmCubeGrey; QPixmap BitmCubeGreen; QPixmap BitmCubeYellow; QPixmap BitmCubeRed; QPixmap BitmIndicatorGreen; QPixmap BitmIndicatorYellow; QPixmap BitmIndicatorRed; int iUpdateTime; EType eType; bool bFlagRedLi; bool bFlagGreenLi; bool bFlagYellowLi; }; jamulus-3.9.1+dfsg/src/server.h0000644000175000017500000003706614340334543015436 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #include #include #include #include #include #ifdef USE_OPUS_SHARED_LIB # include "opus/opus_custom.h" #else # include "opus_custom.h" #endif #include "global.h" #include "buffer.h" #include "signalhandler.h" #include "socket.h" #include "channel.h" #include "util.h" #include "serverlogging.h" #include "serverlist.h" #include "recorder/jamcontroller.h" #include "threadpool.h" /* Definitions ****************************************************************/ // no valid channel number #define INVALID_CHANNEL_ID ( MAX_NUM_CHANNELS + 1 ) /* Classes ********************************************************************/ template class CServerSlots : public CServerSlots { public: void OnSendProtMessCh ( CVector mess ) { SendProtMessage ( slotId - 1, mess ); } void OnReqConnClientsListCh() { CreateAndSendChanListForThisChan ( slotId - 1 ); } void OnChatTextReceivedCh ( QString strChatText ) { CreateAndSendChatTextForAllConChannels ( slotId - 1, strChatText ); } void OnMuteStateHasChangedCh ( int iChanID, bool bIsMuted ) { CreateOtherMuteStateChanged ( slotId - 1, iChanID, bIsMuted ); } void OnServerAutoSockBufSizeChangeCh ( int iNNumFra ) { CreateAndSendJitBufMessage ( slotId - 1, iNNumFra ); } protected: virtual void SendProtMessage ( int iChID, CVector vecMessage ) = 0; virtual void CreateAndSendChanListForThisChan ( const int iCurChanID ) = 0; virtual void CreateAndSendChatTextForAllConChannels ( const int iCurChanID, const QString& strChatText ) = 0; virtual void CreateOtherMuteStateChanged ( const int iCurChanID, const int iOtherChanID, const bool bIsMuted ) = 0; virtual void CreateAndSendJitBufMessage ( const int iCurChanID, const int iNNumFra ) = 0; }; template<> class CServerSlots<0> {}; class CServer : public QObject, public CServerSlots { Q_OBJECT public: CServer ( const int iNewMaxNumChan, const QString& strLoggingFileName, const QString& strServerBindIP, const quint16 iPortNumber, const quint16 iQosNumber, const QString& strHTMLStatusFileName, const QString& strDirectoryServer, const QString& strServerListFileName, const QString& strServerInfo, const QString& strServerListFilter, const QString& strServerPublicIP, const QString& strNewWelcomeMessage, const QString& strRecordingDirName, const bool bNDisconnectAllClientsOnQuit, const bool bNUseDoubleSystemFrameSize, const bool bNUseMultithreading, const bool bDisableRecording, const bool bNDelayPan, const bool bNEnableIPv6, const ELicenceType eNLicenceType ); virtual ~CServer(); void Start(); void Stop(); bool IsRunning() { return HighPrecisionTimer.isActive(); } bool PutAudioData ( const CVector& vecbyRecBuf, const int iNumBytesRead, const CHostAddress& HostAdr, int& iCurChanID ); int GetNumberOfConnectedClients(); void GetConCliParam ( CVector& vecHostAddresses, CVector& vecsName, CVector& veciJitBufNumFrames, CVector& veciNetwFrameSizeFact ); void CreateCLServerListReqVerAndOSMes ( const CHostAddress& InetAddr ) { ConnLessProtocol.CreateCLReqVersionAndOSMes ( InetAddr ); } // IPv6 Enabled bool IsIPv6Enabled() { return bEnableIPv6; } // GUI settings ------------------------------------------------------------ int GetClientNumAudioChannels ( const int iChanNum ) { return vecChannels[iChanNum].GetNumAudioChannels(); } void SetDirectoryType ( const EDirectoryType eNCSAT ) { ServerListManager.SetDirectoryType ( eNCSAT ); } EDirectoryType GetDirectoryType() { return ServerListManager.GetDirectoryType(); } bool IsDirectoryServer() { return ServerListManager.IsDirectoryServer(); } ESvrRegStatus GetSvrRegStatus() { return ServerListManager.GetSvrRegStatus(); } void SetServerName ( const QString& strNewName ) { ServerListManager.SetServerName ( strNewName ); } QString GetServerName() { return ServerListManager.GetServerName(); } void SetServerCity ( const QString& strNewCity ) { ServerListManager.SetServerCity ( strNewCity ); } QString GetServerCity() { return ServerListManager.GetServerCity(); } void SetServerCountry ( const QLocale::Country eNewCountry ) { ServerListManager.SetServerCountry ( eNewCountry ); } QLocale::Country GetServerCountry() { return ServerListManager.GetServerCountry(); } bool GetRecorderInitialised() { return JamController.GetRecorderInitialised(); } void SetEnableRecording ( bool bNewEnableRecording ); bool GetDisableRecording() { return bDisableRecording; } QString GetRecorderErrMsg() { return JamController.GetRecorderErrMsg(); } bool GetRecordingEnabled() { return JamController.GetRecordingEnabled(); } void RequestNewRecording() { JamController.RequestNewRecording(); } void SetRecordingDir ( QString newRecordingDir ) { JamController.SetRecordingDir ( newRecordingDir, iServerFrameSizeSamples, bDisableRecording ); } QString GetRecordingDir() { return JamController.GetRecordingDir(); } void SetWelcomeMessage ( const QString& strNWelcMess ); QString GetWelcomeMessage() { return strWelcomeMessage; } void SetDirectoryAddress ( const QString& sNDirectoryAddress ) { ServerListManager.SetDirectoryAddress ( sNDirectoryAddress ); } QString GetDirectoryAddress() { return ServerListManager.GetDirectoryAddress(); } QString GetServerListFileName() { return ServerListManager.GetServerListFileName(); } bool SetServerListFileName ( QString strFilename ) { return ServerListManager.SetServerListFileName ( strFilename ); } void SetAutoRunMinimized ( const bool NAuRuMin ) { bAutoRunMinimized = NAuRuMin; } bool GetAutoRunMinimized() { return bAutoRunMinimized; } void SetEnableDelayPanning ( bool bDelayPanningOn ) { bDelayPan = bDelayPanningOn; } bool IsDelayPanningEnabled() { return bDelayPan; } protected: // access functions for actual channels bool IsConnected ( const int iChanNum ) { return vecChannels[iChanNum].IsConnected(); } int FindChannel ( const CHostAddress& CheckAddr, const bool bAllowNew = false ); void InitChannel ( const int iNewChanID, const CHostAddress& InetAddr ); void FreeChannel ( const int iCurChanID ); void DumpChannels ( const QString& title ); CVector CreateChannelList(); virtual void CreateAndSendChanListForAllConChannels(); virtual void CreateAndSendChanListForThisChan ( const int iCurChanID ); virtual void CreateAndSendChatTextForAllConChannels ( const int iCurChanID, const QString& strChatText ); virtual void CreateOtherMuteStateChanged ( const int iCurChanID, const int iOtherChanID, const bool bIsMuted ); virtual void CreateAndSendJitBufMessage ( const int iCurChanID, const int iNNumFra ); virtual void SendProtMessage ( int iChID, CVector vecMessage ); template inline void connectChannelSignalsToServerSlots(); void WriteHTMLChannelList(); void WriteHTMLServerQuit(); static void DecodeReceiveDataBlocks ( CServer* pServer, const int iStartChanCnt, const int iStopChanCnt, const int iNumClients ); static void MixEncodeTransmitDataBlocks ( CServer* pServer, const int iStartChanCnt, const int iStopChanCnt, const int iNumClients ); void DecodeReceiveData ( const int iChanCnt, const int iNumClients ); void MixEncodeTransmitData ( const int iChanCnt, const int iNumClients ); virtual void customEvent ( QEvent* pEvent ); void CreateAndSendRecorderStateForAllConChannels(); // if server mode is normal or double system frame size bool bUseDoubleSystemFrameSize; int iServerFrameSizeSamples; // variables needed for multithreading support bool bUseMultithreading; int iMaxNumThreads; CVector> Futures; bool CreateLevelsForAllConChannels ( const int iNumClients, const CVector& vecNumAudioChannels, const CVector> vecvecsData, CVector& vecLevelsOut ); // do not use the vector class since CChannel does not have appropriate // copy constructor/operator CChannel vecChannels[MAX_NUM_CHANNELS]; int iMaxNumChannels; int iCurNumChannels; int vecChannelOrder[MAX_NUM_CHANNELS]; QMutex MutexChanOrder; CProtocol ConnLessProtocol; QMutex Mutex; QMutex MutexWelcomeMessage; bool bChannelIsNowDisconnected; // audio encoder/decoder OpusCustomMode* Opus64Mode[MAX_NUM_CHANNELS]; OpusCustomEncoder* Opus64EncoderMono[MAX_NUM_CHANNELS]; OpusCustomDecoder* Opus64DecoderMono[MAX_NUM_CHANNELS]; OpusCustomEncoder* Opus64EncoderStereo[MAX_NUM_CHANNELS]; OpusCustomDecoder* Opus64DecoderStereo[MAX_NUM_CHANNELS]; OpusCustomMode* OpusMode[MAX_NUM_CHANNELS]; OpusCustomEncoder* OpusEncoderMono[MAX_NUM_CHANNELS]; OpusCustomDecoder* OpusDecoderMono[MAX_NUM_CHANNELS]; OpusCustomEncoder* OpusEncoderStereo[MAX_NUM_CHANNELS]; OpusCustomDecoder* OpusDecoderStereo[MAX_NUM_CHANNELS]; CConvBuf DoubleFrameSizeConvBufIn[MAX_NUM_CHANNELS]; CConvBuf DoubleFrameSizeConvBufOut[MAX_NUM_CHANNELS]; CVector vstrChatColors; CVector vecChanIDsCurConChan; CVector> vecvecfGains; CVector> vecvecfPannings; CVector> vecvecsData; CVector> vecvecsData2; CVector vecNumAudioChannels; CVector vecNumFrameSizeConvBlocks; CVector vecUseDoubleSysFraSizeConvBuf; CVector vecAudioComprType; CVector> vecvecsSendData; CVector> vecvecfIntermediateProcBuf; CVector> vecvecbyCodedData; // Channel levels CVector vecChannelLevels; // actual working objects CHighPrioSocket Socket; // logging CServerLogging Logging; // channel level update frame interval counter int iFrameCount; // HTML file server status bool bWriteStatusHTMLFile; QString strServerHTMLFileListName; CHighPrecisionTimer HighPrecisionTimer; // server list CServerListManager ServerListManager; // jam recorder recorder::CJamController JamController; bool bDisableRecording; // GUI settings bool bAutoRunMinimized; // for delay panning bool bDelayPan; // enable IPv6 bool bEnableIPv6; // messaging QString strWelcomeMessage; ELicenceType eLicenceType; bool bDisconnectAllClientsOnQuit; CSignalHandler* pSignalHandler; std::unique_ptr pThreadPool; signals: void Started(); void Stopped(); void ClientDisconnected ( const int iChID ); void SvrRegStatusChanged(); void AudioFrame ( const int iChID, const QString stChName, const CHostAddress RecHostAddr, const int iNumAudChan, const CVector vecsData ); void CLVersionAndOSReceived ( CHostAddress InetAddr, COSUtil::EOpSystemType eOSType, QString strVersion ); // pass through from jam controller void RestartRecorder(); void StopRecorder(); void RecordingSessionStarted ( QString sessionDir ); void EndRecorderThread(); public slots: void OnTimer(); void OnNewConnection ( int iChID, int iTotChans, CHostAddress RecHostAddr ); void OnServerFull ( CHostAddress RecHostAddr ); void OnSendCLProtMessage ( CHostAddress InetAddr, CVector vecMessage ); void OnProtocolCLMessageReceived ( int iRecID, CVector vecbyMesBodyData, CHostAddress RecHostAddr ); void OnProtocolMessageReceived ( int iRecCounter, int iRecID, CVector vecbyMesBodyData, CHostAddress RecHostAddr ); void OnCLPingReceived ( CHostAddress InetAddr, int iMs ) { ConnLessProtocol.CreateCLPingMes ( InetAddr, iMs ); } void OnCLPingWithNumClientsReceived ( CHostAddress InetAddr, int iMs, int ) { ConnLessProtocol.CreateCLPingWithNumClientsMes ( InetAddr, iMs, GetNumberOfConnectedClients() ); } void OnCLSendEmptyMes ( CHostAddress TargetInetAddr ) { // only send empty message if not a directory server if ( !ServerListManager.IsDirectoryServer() ) { ConnLessProtocol.CreateCLEmptyMes ( TargetInetAddr ); } } void OnCLReqServerList ( CHostAddress InetAddr ) { ServerListManager.RetrieveAll ( InetAddr ); } void OnCLReqVersionAndOS ( CHostAddress InetAddr ) { ConnLessProtocol.CreateCLVersionAndOSMes ( InetAddr ); } void OnCLReqConnClientsList ( CHostAddress InetAddr ) { ConnLessProtocol.CreateCLConnClientsListMes ( InetAddr, CreateChannelList() ); } void OnCLRegisterServerReceived ( CHostAddress InetAddr, CHostAddress LInetAddr, CServerCoreInfo ServerInfo ) { ServerListManager.Append ( InetAddr, LInetAddr, ServerInfo ); } void OnCLRegisterServerExReceived ( CHostAddress InetAddr, CHostAddress LInetAddr, CServerCoreInfo ServerInfo, COSUtil::EOpSystemType, QString strVersion ) { ServerListManager.Append ( InetAddr, LInetAddr, ServerInfo, strVersion ); } void OnCLRegisterServerResp ( CHostAddress /* unused */, ESvrRegResult eResult ) { ServerListManager.StoreRegistrationResult ( eResult ); } void OnCLUnregisterServerReceived ( CHostAddress InetAddr ) { ServerListManager.Remove ( InetAddr ); } void OnCLDisconnection ( CHostAddress InetAddr ); void OnAboutToQuit(); void OnHandledSignal ( int sigNum ); }; Q_DECLARE_METATYPE ( CVector ) jamulus-3.9.1+dfsg/src/serverlist.cpp0000644000175000017500000011321114340334543016650 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include "serverlist.h" /* *\ --port sets the port the server listens to locally --serverbindip sets the IP the server listens to locally --serverpublicip sets the public IP where server and directory are on the same LAN Manual port forwarding is not supported: the internal port must be open to external requests. Where a router modem does automatic port forwarding, directory pings MAY open the server to requests from clients not on the same LAN as the directory. * PROTMESSID_CLM_SERVER_LIST - SERVER internal to DIRECTORY (list entry external IP same LAN) - CLIENT internal to DIRECTORY (CLM msg same LAN): use "external" fields (local LAN address) - CLIENT external to DIRECTORY (CLM msg not same LAN): use "internal" fields (registered server public IP) - SERVER external to DIRECTORY (list entry external IP not same LAN) - CLIENT internal to SERVER (CLM same IP as list entry external IP): use "internal" fields (local LAN address) - CLIENT external to SERVER (CLM not same IP as list entry external IP): use "external" fields (public IP address from protocol) --- * PROTMESSID_CLM_REGISTER_SERVER - As SERVER create CLM message using "internal" fields (IP layer is the "external" fields): - DIRECTORY not on my LAN: self-determined IP address and --port value - DIRECTORY on my LAN: --serverpublicip IP address and --port value - As DIRECTORY store received CLM message as is (IP layer address is used to access the server list) * \* */ /* Implementation *************************************************************/ // --- CServerListEntry --- CServerListEntry CServerListEntry::parse ( QString strHAddr, QString strLHAddr, QString sName, QString sCity, QString strCountry, QString strNumClients, bool isPermanent, bool bEnableIPv6 ) { CHostAddress haServerHostAddr; NetworkUtil::ParseNetworkAddress ( strHAddr, haServerHostAddr, bEnableIPv6 ); if ( CHostAddress() == haServerHostAddr ) { // do not proceed without server host address! return CServerListEntry(); } CHostAddress haServerLocalAddr; NetworkUtil::ParseNetworkAddress ( strLHAddr, haServerLocalAddr, bEnableIPv6 ); if ( haServerLocalAddr.iPort == 0 ) { haServerLocalAddr.iPort = haServerHostAddr.iPort; } // Capture parsing success of integers bool ok; QLocale::Country lcCountry = QLocale::AnyCountry; int iCountry = strCountry.trimmed().toInt ( &ok ); if ( ok && iCountry >= 0 && iCountry <= QLocale::LastCountry ) { lcCountry = static_cast ( iCountry ); } int iNumClients = strNumClients.trimmed().toInt ( &ok ); if ( !ok ) { iNumClients = 10; } return CServerListEntry ( haServerHostAddr, haServerLocalAddr, CServerCoreInfo ( FromBase64ToString ( sName.trimmed() ).left ( MAX_LEN_SERVER_NAME ), lcCountry, FromBase64ToString ( sCity.trimmed() ).left ( MAX_LEN_SERVER_CITY ), iNumClients, isPermanent ) ); } QString CServerListEntry::toCSV() { QStringList sl; sl.append ( this->HostAddr.toString() ); sl.append ( this->LHostAddr.toString() ); sl.append ( ToBase64 ( this->strName ) ); sl.append ( ToBase64 ( this->strCity ) ); sl.append ( QString::number ( this->eCountry ) ); sl.append ( QString::number ( this->iMaxNumClients ) ); sl.append ( QString::number ( this->bPermanentOnline ) ); return sl.join ( ";" ); } // --- CServerListManager --- CServerListManager::CServerListManager ( const quint16 iNPortNum, const QString& sNDirectoryAddress, const QString& strServerListFileName, const QString& strServerInfo, const QString& strServerListFilter, const QString& strServerPublicIP, const int iNumChannels, const bool bNEnableIPv6, CProtocol* pNConLProt ) : DirectoryType ( AT_NONE ), bEnableIPv6 ( bNEnableIPv6 ), ServerListFileName ( strServerListFileName ), strDirectoryAddress ( "" ), bIsDirectoryServer ( false ), eSvrRegStatus ( SRS_NOT_REGISTERED ), strMinServerVersion ( "" ), // disable version check with empty version pConnLessProtocol ( pNConLProt ), iSvrRegRetries ( 0 ) { CHostAddress haServerAddr ( NetworkUtil::GetLocalAddress().InetAddr, iNPortNum ); // set the server internal address, including internal port number QHostAddress qhaServerPublicIP; if ( strServerPublicIP == "" ) { // No user-supplied override via --serverpublicip -> use auto-detection qhaServerPublicIP = haServerAddr.InetAddr; } else { // User-supplied --serverpublicip qhaServerPublicIP = QHostAddress ( strServerPublicIP ); } qDebug() << "Using" << qhaServerPublicIP.toString() << "as external IP."; ServerPublicIP = CHostAddress ( qhaServerPublicIP, iNPortNum ); if ( bEnableIPv6 ) { // set the server internal address, including internal port number QHostAddress qhaServerPublicIP6; qhaServerPublicIP6 = NetworkUtil::GetLocalAddress6().InetAddr; qDebug() << "Using" << qhaServerPublicIP6.toString() << "as external IPv6."; ServerPublicIP6 = CHostAddress ( qhaServerPublicIP6, iNPortNum ); } // prepare the server info information QStringList slServInfoSeparateParams; int iServInfoNumSplitItems = 0; if ( !strServerInfo.isEmpty() ) { // split the different parameter strings slServInfoSeparateParams = strServerInfo.split ( ";" ); // get the number of items in the split list iServInfoNumSplitItems = slServInfoSeparateParams.count(); } /* * Init server list entry (server info for this server) with defaults. * * The client will use the built in or custom address when retrieving the server list from a directory. * The values supplied here only apply when using the server as a server, not as a directory. * * If we are a directory, we assume that we are a permanent server. */ CServerListEntry ThisServerListEntry ( haServerAddr, ServerPublicIP, "", QLocale::system().country(), "", iNumChannels, bIsDirectoryServer ); // parse the server info string according to definition: // [this server name];[this server city];[this server country as QLocale ID] (; ... ignored) // per definition, we expect at least three parameters if ( iServInfoNumSplitItems >= 3 ) { // [this server name] ThisServerListEntry.strName = slServInfoSeparateParams[0].left ( MAX_LEN_SERVER_NAME ); // [this server city] ThisServerListEntry.strCity = slServInfoSeparateParams[1].left ( MAX_LEN_SERVER_CITY ); // [this server country as QLocale ID] bool ok; const int iCountry = slServInfoSeparateParams[2].toInt ( &ok ); if ( ok ) { if ( iCountry >= 0 && CLocale::IsCountryCodeSupported ( iCountry ) ) { // Convert from externally-supplied format ("wire format", Qt5 codes) to // native format. On Qt5 builds, this is a noop, on Qt6 builds, a conversion // takes place. // We try to do such conversions at the outer-most interface which is capable of doing it. // Although the value comes from src/main -> src/server, this very place is // the first where we have access to the parsed country code: ThisServerListEntry.eCountry = CLocale::WireFormatCountryCodeToQtCountry ( iCountry ); } } else { QLocale::Country qlCountry = CLocale::GetCountryCodeByTwoLetterCode ( slServInfoSeparateParams[2] ); if ( qlCountry != QLocale::AnyCountry ) { ThisServerListEntry.eCountry = qlCountry; } } qInfo() << qUtf8Printable ( QString ( "Using server info: name = \"%1\", city = \"%2\", country/region = \"%3\" (%4)" ) .arg ( ThisServerListEntry.strName ) .arg ( ThisServerListEntry.strCity ) .arg ( slServInfoSeparateParams[2] ) .arg ( QLocale::countryToString ( ThisServerListEntry.eCountry ) ) ); } else { qWarning() << "Ignoring invalid serverinfo, please verify the parameter syntax."; } // per definition, the very first entry is this server and this entry will // never be deleted ServerList.clear(); // per definition, the first entry in the server list is the own server ServerList.append ( ThisServerListEntry ); // set the directory address - not the type, that gets done by app start up SetDirectoryAddress ( sNDirectoryAddress ); // whitelist parsing - only used when bIsDirectoryServer if ( !strServerListFilter.isEmpty() ) { // split the different parameter strings QStringList slWhitelistAddresses = strServerListFilter.split ( ";" ); QHostAddress CurWhiteListAddress; for ( int iIdx = 0; iIdx < slWhitelistAddresses.size(); iIdx++ ) { // check for special case: [version] if ( ( slWhitelistAddresses.at ( iIdx ).length() > 2 ) && ( slWhitelistAddresses.at ( iIdx ).left ( 1 ) == "[" ) && ( slWhitelistAddresses.at ( iIdx ).right ( 1 ) == "]" ) ) { strMinServerVersion = slWhitelistAddresses.at ( iIdx ).mid ( 1, slWhitelistAddresses.at ( iIdx ).length() - 2 ); } else if ( CurWhiteListAddress.setAddress ( slWhitelistAddresses.at ( iIdx ) ) ) { vWhiteList << CurWhiteListAddress; } } } // assume directoryType will get set to AT_CUSTOM if ( !strDirectoryAddress.compare ( "localhost", Qt::CaseInsensitive ) || !strDirectoryAddress.compare ( "127.0.0.1" ) ) { if ( !strMinServerVersion.isEmpty() ) { qInfo() << "Registering servers must be version" << strMinServerVersion << "or later."; } if ( !vWhiteList.isEmpty() ) { qInfo() << "Directory registration white list active. Only the following addresses can register:"; foreach ( QHostAddress hostAddress, vWhiteList ) { qInfo() << " -" << hostAddress.toString(); } } } // prepare the one shot timer for determining if this is a // permanent registered server TimerIsPermanent.setSingleShot ( true ); TimerIsPermanent.setInterval ( SERVLIST_TIME_PERMSERV_MINUTES * 60000 ); // prepare the register server response timer (single shot timer) TimerCLRegisterServerResp.setSingleShot ( true ); TimerCLRegisterServerResp.setInterval ( REGISTER_SERVER_TIME_OUT_MS ); // Connections ------------------------------------------------------------- QObject::connect ( &TimerPollList, &QTimer::timeout, this, &CServerListManager::OnTimerPollList ); QObject::connect ( &TimerPingServerInList, &QTimer::timeout, this, &CServerListManager::OnTimerPingServerInList ); QObject::connect ( &TimerPingServers, &QTimer::timeout, this, &CServerListManager::OnTimerPingServers ); QObject::connect ( &TimerRefreshRegistration, &QTimer::timeout, this, &CServerListManager::OnTimerRefreshRegistration ); QObject::connect ( &TimerCLRegisterServerResp, &QTimer::timeout, this, &CServerListManager::OnTimerCLRegisterServerResp ); QObject::connect ( &TimerIsPermanent, &QTimer::timeout, this, &CServerListManager::OnTimerIsPermanent ); QObject::connect ( QCoreApplication::instance(), &QCoreApplication::aboutToQuit, this, &CServerListManager::OnAboutToQuit ); } // set server infos -> per definition the server info of this server is // stored in the first entry of the list, we assume here that the first // entry is correctly created in the constructor of the class // and, if registered, refresh the server list entry void CServerListManager::SetServerName ( const QString& strNewName ) { if ( ServerList[0].strName != strNewName ) { ServerList[0].strName = strNewName; SetRegistered ( eSvrRegStatus != SRS_NOT_REGISTERED ); } } void CServerListManager::SetServerCity ( const QString& strNewCity ) { if ( ServerList[0].strCity != strNewCity ) { ServerList[0].strCity = strNewCity; SetRegistered ( eSvrRegStatus != SRS_NOT_REGISTERED ); } } void CServerListManager::SetServerCountry ( const QLocale::Country eNewCountry ) { if ( ServerList[0].eCountry != eNewCountry ) { ServerList[0].eCountry = eNewCountry; SetRegistered ( eSvrRegStatus != SRS_NOT_REGISTERED ); } } void CServerListManager::SetDirectoryAddress ( const QString sNDirectoryAddress ) { // if the address has not actually changed, do nothing if ( sNDirectoryAddress == strDirectoryAddress ) { return; } if ( DirectoryType != AT_CUSTOM ) { // just save the new name strDirectoryAddress = sNDirectoryAddress; return; } // sets the lock Unregister(); QMutexLocker locker ( &Mutex ); // now save the new name strDirectoryAddress = sNDirectoryAddress; SetIsDirectoryServer(); locker.unlock(); // sets the lock Register(); } void CServerListManager::SetDirectoryType ( const EDirectoryType eNCSAT ) { // if the directory type is not changing, do nothing if ( eNCSAT == DirectoryType ) { return; } // sets the lock Unregister(); QMutexLocker locker ( &Mutex ); // now update the server type DirectoryType = eNCSAT; SetIsDirectoryServer(); locker.unlock(); // sets the lock Register(); } void CServerListManager::SetIsDirectoryServer() { // this is called with the lock set // per definition: If we are registered and the directory // is the localhost address, we are in directory server mode. bool bNIsDirectoryServer = DirectoryType == AT_CUSTOM && ( !strDirectoryAddress.compare ( "localhost", Qt::CaseInsensitive ) || !strDirectoryAddress.compare ( "127.0.0.1" ) ); if ( bIsDirectoryServer == bNIsDirectoryServer ) { return; } bIsDirectoryServer = bNIsDirectoryServer; if ( bIsDirectoryServer ) { qInfo() << "Now a directory"; // Load any persistent server list (create it if it is not there) (void) Load(); } else { qInfo() << "No longer a directory server"; } } // When we unregister, set the status and stop timers void CServerListManager::Unregister() { // if not currently registered, nothing needs doing if ( DirectoryType == AT_NONE || ( DirectoryType == AT_CUSTOM && strDirectoryAddress.isEmpty() ) || eSvrRegStatus == SRS_NOT_REGISTERED ) { return; } // Update server registration status - sets the lock SetRegistered ( false ); // this is called without the lock set QMutexLocker locker ( &Mutex ); // disable service -> stop timer if ( bIsDirectoryServer ) { TimerPollList.stop(); TimerPingServerInList.stop(); } else { TimerCLRegisterServerResp.stop(); TimerRefreshRegistration.stop(); TimerPingServers.stop(); TimerIsPermanent.stop(); } ServerList[0].bPermanentOnline = false; } // When we register, set the status and start timers void CServerListManager::Register() { // if cannot currently register, or we have registered, nothing needs doing if ( DirectoryType == AT_NONE || ( DirectoryType == AT_CUSTOM && strDirectoryAddress.isEmpty() ) || eSvrRegStatus == SRS_REGISTERED ) { // there are edge cases during registration... // maybe ! ( SRS_NOT_REGISTERED || SRS_BAD_ADDRESS ) return; } // Update server registration status - sets the lock SetRegistered ( true ); // this is called without the lock set QMutexLocker locker ( &Mutex ); if ( bIsDirectoryServer ) { // start timer for polling the server list if enabled // 1 minute = 60 * 1000 ms TimerPollList.start ( SERVLIST_POLL_TIME_MINUTES * 60000 ); // start timer for sending ping messages to servers in the list TimerPingServerInList.start ( SERVLIST_UPDATE_PING_SERVERS_MS ); // directory is permanent ServerList[0].bPermanentOnline = true; } else { // reset the retry counter to zero because update was called iSvrRegRetries = 0; // start timer for registration timeout - this gets restarted // in OnTimerCLRegisterServerResp on failure TimerCLRegisterServerResp.start(); // start timer for registering this server at the directory server // 1 minute = 60 * 1000 ms TimerRefreshRegistration.start ( SERVLIST_REGIST_INTERV_MINUTES * 60000 ); // Start timer for ping the directory server in short intervals to // keep the port open at the NAT router. // If no NAT is used, we send the messages anyway since they do // not hurt (very low traffic). We also reuse the same update // time as used in the directory server for pinging the registered // servers. TimerPingServers.start ( SERVLIST_UPDATE_PING_SERVERS_MS ); // start the one shot timer for determining if this is a // permanent registered server TimerIsPermanent.start(); } } /* Directory server list functionality ****************************************/ void CServerListManager::OnTimerPingServerInList() { QMutexLocker locker ( &Mutex ); const int iCurServerListSize = ServerList.size(); // send ping to list entries except of the very first one (which is the directory // server entry) for ( int iIdx = 1; iIdx < iCurServerListSize; iIdx++ ) { // send empty message to keep NAT port open at registered server pConnLessProtocol->CreateCLEmptyMes ( ServerList[iIdx].HostAddr ); } } void CServerListManager::OnTimerPollList() { CVector vecRemovedHostAddr; QMutexLocker locker ( &Mutex ); // Check all list entries are still valid (omitting the directory server itself) for ( int iIdx = ServerList.size() - 1; iIdx > 0; iIdx-- ) { // 1 minute = 60 * 1000 ms if ( ServerList[iIdx].RegisterTime.elapsed() > ( SERVLIST_TIME_OUT_MINUTES * 60000 ) ) { // remove this list entry vecRemovedHostAddr.Add ( ServerList[iIdx].HostAddr ); ServerList.removeAt ( iIdx ); } } locker.unlock(); foreach ( const CHostAddress HostAddr, vecRemovedHostAddr ) { qInfo() << qUtf8Printable ( QString ( "Expired entry for %1" ).arg ( HostAddr.toString() ) ); } } void CServerListManager::Append ( const CHostAddress& InetAddr, const CHostAddress& LInetAddr, const CServerCoreInfo& ServerInfo, const QString strVersion ) { if ( bIsDirectoryServer ) { // if the client IP address is a private one, it's on the same LAN as the directory bool serverIsExternal = !NetworkUtil::IsPrivateNetworkIP ( InetAddr.InetAddr ); qInfo() << qUtf8Printable ( QString ( "Requested to register entry for %1 (%2): %3 (%4)" ) .arg ( InetAddr.toString() ) .arg ( LInetAddr.toString() ) .arg ( ServerInfo.strName ) .arg ( serverIsExternal ? "external" : "local" ) ); // check for minimum server version if ( !strMinServerVersion.isEmpty() ) { #if ( QT_VERSION >= QT_VERSION_CHECK( 5, 6, 0 ) ) if ( strVersion.isEmpty() || QVersionNumber::compare ( QVersionNumber::fromString ( strMinServerVersion ), QVersionNumber::fromString ( strVersion ) ) > 0 ) { pConnLessProtocol->CreateCLRegisterServerResp ( InetAddr, SRR_VERSION_TOO_OLD ); return; // leave function early, i.e., we do not register this server } #endif } // check for whitelist (it is enabled if it is not empty per definition) if ( !vWhiteList.empty() ) { // if the server is not listed, refuse registration and send registration response if ( !vWhiteList.contains ( InetAddr.InetAddr ) ) { pConnLessProtocol->CreateCLRegisterServerResp ( InetAddr, SRR_NOT_FULFILL_REQIREMENTS ); return; // leave function early, i.e., we do not register this server } } // access/modifications to the server list needs to be mutexed QMutexLocker locker ( &Mutex ); const int iCurServerListSize = ServerList.size(); // Check if server is already registered. // The very first list entry must not be checked since // this is per definition the directory server (i.e., this server) int iSelIdx = IndexOf ( InetAddr ); // if server is not yet registered, we have to create a new entry if ( iSelIdx == INVALID_INDEX ) { // check for maximum allowed number of servers in the server list if ( iCurServerListSize < MAX_NUM_SERVERS_IN_SERVER_LIST ) { // create a new server list entry and init with received data ServerList.append ( CServerListEntry ( InetAddr, LInetAddr, ServerInfo ) ); iSelIdx = iCurServerListSize; } } else { // update all data and call update registration function ServerList[iSelIdx].LHostAddr = LInetAddr; ServerList[iSelIdx].strName = ServerInfo.strName; ServerList[iSelIdx].eCountry = ServerInfo.eCountry; ServerList[iSelIdx].strCity = ServerInfo.strCity; ServerList[iSelIdx].iMaxNumClients = ServerInfo.iMaxNumClients; ServerList[iSelIdx].bPermanentOnline = ServerInfo.bPermanentOnline; ServerList[iSelIdx].UpdateRegistration(); } pConnLessProtocol->CreateCLRegisterServerResp ( InetAddr, iSelIdx == INVALID_INDEX ? ESvrRegResult::SRR_SERVER_LIST_FULL : ESvrRegResult::SRR_REGISTERED ); } } void CServerListManager::Remove ( const CHostAddress& InetAddr ) { if ( bIsDirectoryServer ) { qInfo() << qUtf8Printable ( QString ( "Requested to unregister entry for %1" ).arg ( InetAddr.toString() ) ); QMutexLocker locker ( &Mutex ); // Find the server to unregister in the list. The very first list entry // must not be removed since this is per definition the directory server // (i.e., this server). int iIdx = IndexOf ( InetAddr ); if ( iIdx > 0 ) { ServerList.removeAt ( iIdx ); } } } /* PROTMESSID_CLM_SERVER_LIST - SERVER internal to DIRECTORY (list entry external IP same LAN) - CLIENT internal to DIRECTORY (CLM msg same LAN): use "external" fields (local LAN address) - CLIENT external to DIRECTORY (CLM msg not same LAN): use "internal" fields (registered server public IP) - SERVER external to DIRECTORY (list entry external IP same LAN) - CLIENT internal to SERVER (CLM same IP as list entry external IP): use "internal" fields (local LAN address) - CLIENT external to SERVER (CLM not same IP as list entry external IP): use "external" fields (public IP address from protocol) Finally, when retrieving the entry for the directory itself life is more complicated still. It's easiest just to return "0" and allow the client connect dialogue instead to use the IP and Port from which the list was received. */ void CServerListManager::RetrieveAll ( const CHostAddress& InetAddr ) { QMutexLocker locker ( &Mutex ); if ( bIsDirectoryServer ) { // if the client IP address is a private one, it's on the same LAN as the directory bool clientIsInternal = NetworkUtil::IsPrivateNetworkIP ( InetAddr.InetAddr ); CHostAddress clientPublicAddr = InetAddr; if ( clientIsInternal && CHostAddress().InetAddr != ServerList[0].LHostAddr.InetAddr && !NetworkUtil::IsPrivateNetworkIP ( ServerList[0].LHostAddr.InetAddr ) ) { // client and directory on same LAN, directory has public IP set, that should be suitable for the // client, too (i.e. same router with same public IP will be used for both), so use it for client public IP clientPublicAddr.InetAddr = ServerList[0].LHostAddr.InetAddr; } const ushort iCurServerListSize = static_cast ( ServerList.size() ); // allocate memory for the entire list CVector vecServerInfo ( iCurServerListSize ); // copy list item for the directory and just let the protocol sort out the actual details vecServerInfo[0] = ServerList[0]; vecServerInfo[0].HostAddr = CHostAddress(); // copy the list (we have to copy it since the message requires a vector but the list is actually stored in a QList object // and not in a vector object) for ( int iIdx = 1; iIdx < iCurServerListSize; iIdx++ ) { // copy list item CServerInfo& siCurListEntry = vecServerInfo[iIdx] = ServerList[iIdx]; bool serverIsInternal = NetworkUtil::IsPrivateNetworkIP ( siCurListEntry.HostAddr.InetAddr ); bool wantHostAddr = clientIsInternal /* HostAddr is local IP if local server else external IP, so do not replace */ || ( !serverIsInternal && InetAddr.InetAddr != siCurListEntry.HostAddr.InetAddr /* external server and client have different public IPs */ ); if ( !wantHostAddr ) { vecServerInfo[iIdx].HostAddr = siCurListEntry.LHostAddr; } // do not send a "ping" to a server local to the directory (no need) if ( !serverIsInternal ) { // create "send empty message" for all other registered servers // this causes the server (vecServerInfo[iIdx].HostAddr) // to send a "reply" to the client (InetAddr or best guess public IP address if internal to directory) // - with the intent of opening the server firewall for the client pConnLessProtocol->CreateCLSendEmptyMesMes ( siCurListEntry.HostAddr, clientPublicAddr ); } } // send the server list to the client, since we do not know that the client // has a UDP fragmentation issue, we send both lists, the reduced and the // normal list after each other pConnLessProtocol->CreateCLRedServerListMes ( InetAddr, vecServerInfo ); pConnLessProtocol->CreateCLServerListMes ( InetAddr, vecServerInfo ); } } int CServerListManager::IndexOf ( CHostAddress haSearchTerm ) { // Called with lock set. // Find the server in the list. The very first list entry // per definition is the directory server // (i.e., this server). for ( int iIdx = ServerList.size() - 1; iIdx > 0; iIdx-- ) { if ( ServerList[iIdx].HostAddr == haSearchTerm ) { return iIdx; } } return INVALID_INDEX; } bool CServerListManager::SetServerListFileName ( QString strFilename ) { QMutexLocker locker ( &Mutex ); if ( ServerListFileName == strFilename ) { return true; } if ( !ServerListFileName.isEmpty() ) { // Save once to the old filename Save(); } ServerListFileName = strFilename; return Load(); } bool CServerListManager::Load() { // this is called with the lock set if ( !bIsDirectoryServer || ServerListFileName.isEmpty() ) { // this gets called again if either of the above change return true; } QFile file ( ServerListFileName ); if ( !file.open ( QIODevice::ReadWrite | QIODevice::Text ) ) { qWarning() << qUtf8Printable ( QString ( "Could not open '%1' for read/write. Please check that %2 has permission (and that there is free space)." ) .arg ( ServerListFileName ) .arg ( APP_NAME ) ); ServerListFileName.clear(); return false; } qInfo() << "Loading persistent server list file:" << ServerListFileName; // do not lose our entry CServerListEntry serverListEntry = ServerList[0]; ServerList.clear(); ServerList.append ( serverListEntry ); // use entire file content for the persistent server list CHostAddress haServerHostAddr; QTextStream in ( &file ); while ( !in.atEnd() ) { QString line = in.readLine(); QStringList slLine = line.split ( ";" ); if ( slLine.count() != 7 ) { qWarning() << qUtf8Printable ( QString ( "Could not parse '%1' successfully - bad line" ).arg ( line ) ); continue; } NetworkUtil::ParseNetworkAddress ( slLine[0], haServerHostAddr, bEnableIPv6 ); int iIdx = IndexOf ( haServerHostAddr ); if ( iIdx != INVALID_INDEX ) { qWarning() << qUtf8Printable ( QString ( "Skipping '%1' - duplicate host %2" ).arg ( line ).arg ( haServerHostAddr.toString() ) ); continue; } serverListEntry = CServerListEntry::parse ( slLine[0], slLine[1], slLine[2], slLine[3], slLine[4], slLine[5], slLine[6].toInt() != 0, bEnableIPv6 ); // We expect servers to have addresses... if ( ( CHostAddress() == serverListEntry.HostAddr ) ) { qWarning() << qUtf8Printable ( QString ( "Could not parse '%1' successfully - invalid host" ).arg ( line ) ); continue; } qInfo() << qUtf8Printable ( QString ( "Loading registration for %1 (%2): %3" ) .arg ( serverListEntry.HostAddr.toString() ) .arg ( serverListEntry.LHostAddr.toString() ) .arg ( serverListEntry.strName ) ); ServerList.append ( serverListEntry ); } return true; } void CServerListManager::Save() { // this is called with the lock set if ( ServerListFileName.isEmpty() ) { return; } QFile file ( ServerListFileName ); if ( !file.open ( QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text ) ) { // Not a useable file qWarning() << QString ( tr ( "Could not write to '%1'" ) ).arg ( ServerListFileName ); ServerListFileName.clear(); return; } QTextStream out ( &file ); // This loop *deliberately* omits the first element in the list // (that's this server, which is added automatically on start up, not read) for ( int iIdx = ServerList.size() - 1; iIdx > 0; iIdx-- ) { qInfo() << qUtf8Printable ( QString ( "Saving registration for %1 (%2): %3" ) .arg ( ServerList[iIdx].HostAddr.toString() ) .arg ( ServerList[iIdx].LHostAddr.toString() ) .arg ( ServerList[iIdx].strName ) ); out << ServerList[iIdx].toCSV() << '\n'; } } /* Registered server functionality *************************************************/ void CServerListManager::StoreRegistrationResult ( ESvrRegResult eResult ) { // we need the lock since the user might change the server properties at // any time so another response could arrive QMutexLocker locker ( &Mutex ); // we got some response, so stop the retry timer TimerCLRegisterServerResp.stop(); switch ( eResult ) { case ESvrRegResult::SRR_REGISTERED: SetSvrRegStatus ( ESvrRegStatus::SRS_REGISTERED ); break; case ESvrRegResult::SRR_SERVER_LIST_FULL: SetSvrRegStatus ( ESvrRegStatus::SRS_SERVER_LIST_FULL ); break; case ESvrRegResult::SRR_VERSION_TOO_OLD: SetSvrRegStatus ( ESvrRegStatus::SRS_VERSION_TOO_OLD ); break; case ESvrRegResult::SRR_NOT_FULFILL_REQIREMENTS: SetSvrRegStatus ( ESvrRegStatus::SRS_NOT_FULFILL_REQUIREMENTS ); break; default: SetSvrRegStatus ( ESvrRegStatus::SRS_UNKNOWN_RESP ); break; } } void CServerListManager::OnTimerPingServers() { QMutexLocker locker ( &Mutex ); // first check if directory address is valid if ( !( DirectoryAddress == CHostAddress() ) ) { // send empty message to directory server to keep NAT port open -> we do // not require any answer from the directory server pConnLessProtocol->CreateCLEmptyMes ( DirectoryAddress ); } } void CServerListManager::OnTimerCLRegisterServerResp() { QMutexLocker locker ( &Mutex ); if ( eSvrRegStatus == SRS_REQUESTED ) { iSvrRegRetries++; if ( iSvrRegRetries >= REGISTER_SERVER_RETRY_LIMIT ) { SetSvrRegStatus ( SRS_TIME_OUT ); } else { locker.unlock(); { OnTimerRefreshRegistration(); } locker.relock(); // re-start timer for registration timeout TimerCLRegisterServerResp.start(); } } } void CServerListManager::OnAboutToQuit() { { QMutexLocker locker ( &Mutex ); Save(); } // Sets the lock - also needs to come after Save() Unregister(); } void CServerListManager::SetRegistered ( const bool bIsRegister ) { // we need the lock since the user might change the server properties at // any time QMutexLocker locker ( &Mutex ); if ( !bIsRegister && eSvrRegStatus == SRS_NOT_REGISTERED ) { // not wanting to set registered, not registered, nothing to do return; } if ( bIsDirectoryServer ) { // this IS the directory, no network message to worry about SetSvrRegStatus ( bIsRegister ? SRS_REGISTERED : SRS_NOT_REGISTERED ); return; } // get the correct directory address // Note that we always have to parse the server address again since if // it is an URL of a dynamic IP address, the IP address might have // changed in the meanwhile. // Allow IPv4 only for communicating with Directories const QString strNetworkAddress = NetworkUtil::GetDirectoryAddress ( DirectoryType, strDirectoryAddress ); const bool bDirectoryAddressValid = NetworkUtil().ParseNetworkAddress ( strNetworkAddress, DirectoryAddress, false ); if ( bIsRegister ) { if ( bDirectoryAddressValid ) { // register server SetSvrRegStatus ( SRS_REQUESTED ); // For a registered server, the server properties are stored in the // very first item in the server list (which is actually no server list // but just one item long for the registered server). pConnLessProtocol->CreateCLRegisterServerExMes ( DirectoryAddress, ServerList[0].LHostAddr, ServerList[0] ); } else { SetSvrRegStatus ( SRS_BAD_ADDRESS ); } } else { // unregister server if it is registered - regardless of success of parse SetSvrRegStatus ( SRS_NOT_REGISTERED ); if ( bDirectoryAddressValid ) { pConnLessProtocol->CreateCLUnregisterServerMes ( DirectoryAddress ); } } } void CServerListManager::SetSvrRegStatus ( ESvrRegStatus eNSvrRegStatus ) { // this is called with the lock set // if status isn't a change, do nothing if ( eNSvrRegStatus == eSvrRegStatus ) { return; } // output regirstation result/update on the console qInfo() << qUtf8Printable ( QString ( "Server Registration Status update: %1" ).arg ( svrRegStatusToString ( eNSvrRegStatus ) ) ); // store the state and inform the GUI about the new status eSvrRegStatus = eNSvrRegStatus; emit SvrRegStatusChanged(); } jamulus-3.9.1+dfsg/src/serverdlgbase.ui0000644000175000017500000002555114340334543017142 0ustar vimervimer CServerDlgBase 0 0 588 560 :/png/main/res/fronticonserver.png:/png/main/res/fronticonserver.png true false 4 Client IP:Port Name Jitter Buffer Size Channels 0 0 0 Server Setup Directory STATUS Qt::Horizontal QSizePolicy::Expanding 20 20 My Server Info Name Location: City Location: Region Enable Jam Recorder New Recording 0 0 STATUS Session true Chat Window Welcome (HTML/CSS Supported) 0 0 Options Language 0 0 Recording Directory true Custom Directory address Server List Filename true Start Minimized on Windows Start Enable delay panning Qt::Vertical 20 40 Update check CLanguageComboBox QComboBox
util.h
lvwClients tabWidget cbxDirectoryType edtServerName edtLocationCity cbxLocationCountry chbEnableRecorder edtCurrentSessionDir pbtNewRecording tedWelcomeMessage cbxLanguage pbtRecordingDir edtRecordingDir tbtClearRecordingDir edtCustomDirectory pbtServerListPersistence edtServerListPersistence tbtClearServerListPersistence chbStartOnOSStart chbEnableDelayPanning
jamulus-3.9.1+dfsg/src/aboutdlgbase.ui0000644000175000017500000001413414340334543016741 0ustar vimervimer CAboutDlgBase 0 0 630 465 0 0 About :/png/main/res/fronticon.png:/png/main/res/fronticon.png true 0 0 :/png/main/res/fronticon.png Qt::AlignCenter 0 TextLabelVersion false 2 Copyright (C) 2005-2022 The Jamulus Development Team false 2 Qt::Horizontal 40 20 0 A&bout true &Libraries true &Contributors true &Translation true 6 0 0 0 0 Qt::Horizontal QSizePolicy::Expanding 20 20 &OK true true buttonOk buttonOk clicked() CAboutDlgBase accept() 20 20 20 20 jamulus-3.9.1+dfsg/src/translation/0000755000175000017500000000000014341067731016304 5ustar vimervimerjamulus-3.9.1+dfsg/src/translation/translation_nb_NO.ts0000644000175000017500000044145014340334543022272 0ustar vimervimer CAboutDlg This app enables musicians to perform real-time jam sessions over the internet. Programmet lar musikere spille sammen over Internett. There is a server which collects the audio data from each client, mixes the audio data and sends the mix back to each client. Tjeneren som samler lyddata fra hver klient mikser den og sender den til hver enkelt klient. This app uses the following libraries, resources or code snippets: Programmet bruker følgende biblioteker, ressurser, eller kodesnutter: Qt cross-platform application framework Qt-programrammeverk på tvers av plattformer Audio reverberation code by Perry R. Cook and Gary P. Scavone Lydklangkode av Perry R. Cook og Gary P. Scavone Some pixmaps are from the Noen bilder kommer fra Flag icons by Mark James Flaggikoner av Mark James Some sound samples are from Noen lydsampler er fra For details on the contributions check out the %1 Detaljer om bidragsyterne er å finne i %1 Github Contributors list GitHub-bidragsyterlisten Spanish Spansk French Fransk Portuguese Portugisisk Dutch Hollandsk Italian Italiensk German Tysk Polish Polsk Swedish Svensk Korean Koreansk Slovak Slovakisk Simplified Chinese Forenklet kinesisk Norwegian Bokmål About %1 Om %1 CAboutDlgBase About Om TextLabelVersion Versjon Copyright (C) 2005-2022 The Jamulus Development Team Opphavsrett © 2005–2022 Jamulus-utviklingslaget A&bout O&m &Libraries &Bibliotek &Contributors &Bidragsytere &Translation &Oversettelse &OK &OK CAnalyzerConsole Analyzer Console Analysatorkonsoll Error Rate of Each Buffer Size Feilrate for hver hurtiglagerstørrelse CAudioMixerBoard Personal Mix at the Server Personlig miks på tjeneren When connected to a server, the controls here allow you to set your local mix without affecting what others hear from you. The title shows the server name and, when known, whether it is actively recording. Når du kobler til en tjener vil kontrollene her la deg sette din lokale miks uten å ha innvirkning på hva andre hører fra deg. Tittelen viser tjenernavn og, (om det er kjent) hvorvidt det er et aktivt opptak. Server Tjener T R Y I N G T O C O N N E C T P R Ø V E R Å K O B L E T I L RECORDING ACTIVE OPPTAK PÅGÅR Personal Mix at: %1 Personlig miks på: %1 CChannelFader Pan Panorering Mute Forstum Solo Solo &No grouping &Ingen gruppering Assign to group Tildel til gruppe Channel Level Kanalnivå Displays the pre-fader audio level of this channel. All clients connected to the server will be assigned an audio level, the same value for every client. Viser pre-fader-lydstyrkenivå for denne kanalen. Alle klienter tilkoblet tjeneren vil bli tildelt et lydstyrkenivå, med lik verdi for hver klient. Input level of the current audio channel at the server Inngangsnivå for nåværende lydkanal på tjeneren Mixer Fader Mikser-fader Adjusts the audio level of this channel. All clients connected to the server will be assigned an audio fader, displayed at each client, to adjust the local mix. Justerer lydstyrkenivået for denne kanalen. Alle klienter tilkoblet tjeneren vil bli tildelt en lydstyrkefader, vist ved hver klient, for å justere den lokale miksen. Local mix level setting of the current audio channel at the server Lokalt miksernivåinnstilling for nåværende lydkanal på tjeneren Status Indicator Statusindikator Shows a status indication about the client which is assigned to this channel. Supported indicators are: Viser en statusindikator om klienten som er tilknyttet denne kanalen. Støttede indikatorer er: Speaker with cancellation stroke: Indicates that another client has muted you. Høyttaler med strek over indikerer at en annen klient har forstummet deg. Status indicator label Etikett for statusindikator Panning Panorering Sets the pan from Left to Right of the channel. Works only in stereo or preferably mono in/stereo out mode. Setter panoreringen fra venstre til høyre for kanalen. Fungerer kun i stereo, eller helst i mono inn/stereo ut-modus Local panning position of the current audio channel at the server Lokal panoreringsposisjon for nåværende lydkanal på tjeneren With the Mute checkbox, the audio channel can be muted. Med forstummelsesboksen avhuket vil lydkanalen forstummes. Mute button Forstummelsesknapp With the Solo checkbox, the audio channel can be set to solo which means that all other channels except the soloed channel are muted. It is possible to set more than one channel to solo. Med «Solo»-sjekkboksen kan lydkanalen settes til solo, som betyr at alle andre kanaler med unntak av påvirket/ede kanal er forstummet. Solo button Solo-knapp Group Gruppe With the Grp checkbox, a group of audio channels can be defined. All channel faders in a group are moved in proportional synchronization if any one of the group faders are moved. Med «Grp»-sjekkboksen kan lydkanaler defineres som gruppe. Alle fadere i den flyttes i proporsjonal synkronisering hvis én av gruppens fadere flyttes. Group button Gruppe-knapp Fader Tag Fader-etikett The fader tag identifies the connected client. The tag name, a picture of your instrument and the flag of your location can be set in the main window. Fader-etiketten indentifiserer tilkoblet klient. Etikettnavnet er et bilde av instrumentet ditt, og et flagg for din posisjon kan settes i hovedvinduet. Mixer channel instrument picture Mikserkanalens instrumentbilde Mixer channel label (fader tag) Mikserkanalens etikett (fader-etikett) Mixer channel country/region flag Mikserkanalsland/regionsflagg PAN PAN MUTE FORSTUM SOLO SOLO GRP GRP M F S S G G Grp Grp Alias/Name Alias/navn Instrument Instrument Location Sted Beginner Nybegynner Skill Level Ferdighetsnivå Intermediate Middels Expert Ekspert Musician Profile Musikerprofil Alias Alias CChatDlg Chat Window Sludrevindu The chat window shows a history of all chat messages. Sludrevinduet viser all sludringshistorikken. Chat history Sludringshistorikk Input Message Text Skriv meldingstekst Enter the chat message text in the edit box and press enter to send the message to the server which distributes the message to all connected clients. Your message will then show up in the chat window. Skriv sludremeldingsteksten i redigeringsboksen og trykk enter for å sende meldingen til tjeneren som sender meldingen til alle tilkoblede klienter. Meldingen din vil da vises i sludringsvinduet. New chat text edit box Ny tekstredigeringsboks for sludring Type a message here Skriv en melding her &Edit &Rediger Cl&ear Chat History T&øm sludringshistorikk &Close &Lukk Do you want to open the link '%1' in your browser? Åpne «%1»-lenken i nettleseren din? CChatDlgBase Chat Sludring &Send &Send CClientDlg Input Level Meter Inngangsnivå This shows the level of the two stereo channels for your audio input. Dette viser nivået for de to stereo-lydkanalene for din lydinngang. Make sure not to clip the input signal to avoid distortions of the audio signal. Forsikre deg om at du ikke klipper inngangssignalet, slik at du unngå forvrengning av lydsignalet. If the application is connected to a server and you play your instrument/sing into the microphone, the VU meter should flicker. If this is not the case, you have probably selected the wrong input channel (e.g. 'line in' instead of the microphone input) or set the input gain too low in the (Windows) audio mixer. Hvis programmet er tilkoblet en tjener og du spiller ditt instrument/synger i mikrofonen, vil VU-meteret røre seg. Hvis dette ikke skjer har du antageligvis valgt feil inngangskanal (f.eks. «linje inn» istedenfor mikrofoninngangen) eller satt inngangsforsterkningen for lavt i (Windows)-lydmikseren. For proper usage of the application, you should not hear your singing/instrument through the loudspeaker or your headphone when the software is not connected. This can be achieved by muting your input audio channel in the Playback mixer (not the Recording mixer!). Du bør høre synging/instrumenter gjennom høyttalerne eller hodetelefonene dine når programvaren ikke er tilkoblet. Du kan gjøre dette ved å forstumme lydinngangskanalen i avspillingsmikseren (ikke opptaksmikseren). Input level meter Inngangsnivåvisning Simulates an analog LED level meter. Simulerer et analogt LED-signalnivåpanel. Connect/Disconnect Button Koble til/fra -knapp Opens a dialog where you can select a server to connect to. If you are connected, pressing this button will end the session. Åpner en dialog der du kan velge hvilken tjener du vil koble til. Hvis du er tilkoblet kan du avslutte økten ved å trykke på denne knappen. Connect and disconnect toggle button Knapp for tilkobling og frakobling Reverb effect Lydklangseffekt Reverb can be applied to one local mono audio channel or to both channels in stereo mode. The mono channel selection and the reverb level can be modified. For example, if a microphone signal is fed in to the right audio channel of the sound card and a reverb effect needs to be applied, set the channel selector to right and move the fader upwards until the desired reverb level is reached. Lydklang kan brukes på en lokal mono-lydkanal, eller begge lydkanaler i stereomodus. Monokanalvalget og nivået for lydklangseffekten kan endres. For eksempel hvis et mikrofonsignal sendes til høyre lydkanal av lydkortet og en lydklangseffekt må legges til, kan du sette kanalvelgeren til høyre og flytte nivåregulatoren oppover til ønsket lydklangsnivå oppnås. Reverb effect level setting Nivåinnstilling for lydklangseffekt Reverb Channel Selection Kanalvalg for lydklang With these radio buttons the audio input channel on which the reverb effect is applied can be chosen. Either the left or right input channel can be selected. Disse radioknappene velger lydinngangskanalen lydklangseffekten skal brukes på. Enten venstre eller høyre inngangskanal kan velges. Left channel selection for reverb Venstrekanalsvalg for lydklang Right channel selection for reverb Høyrekanalsvalg for lydklang Delay Status LED Forsinkelsesstatus-LED Shows the current audio delay status: Viser status for forsinkelse av nåværende lyd: Green Grønn The delay is perfect for a jam session. Forsinkelsen er perfekt for samspill. Yellow Gul A session is still possible but it may be harder to play. En økt er fremdeles mulig, men det kan være vanskeligere å spille. Red Rød The delay is too large for jamming. Forsinkelsen er for lang for samspill. If this LED indicator turns red, you will not have much fun using %1. Hvis denne LED-indikatoren blir rød vil du ikke ha mye glede av å bruke %1. Delay status LED indicator LED-indikator for forsinkelsesstatus Local Jitter Buffer Status LED Status-LED for lokalt jitter-mellomlager The local jitter buffer status LED shows the current audio/streaming status. If the light is red, the audio stream is interrupted. This is caused by one of the following problems: Status-LED for lokalt jitter-mellomlager viser nåværende lyd/strømmingsstatus. Hvis lyset er rødt forstyrres lydstrømmen. Dette kan ha sitt opphav i følgende: The network jitter buffer is not large enough for the current network/audio interface jitter. Mellomlageret for nettverksjitter er ikke stort nok for nåværende størrelse på jitter fra lyd/nettverksgrensesnittet. The sound card's buffer delay (buffer size) is too small (see Settings window). Lydkortets mellomlagerforsinkelse (mellomlagerstørrelse) er for liten (sjekk innstillingsvinduet). The upload or download stream rate is too high for your internet bandwidth. Opp- eller nedlastingshastigheten som kreves er for høy for båndbredden din. The CPU of the client or server is at 100%. Prosessoren på klienten eller tjeneren jobber 100%. If this LED indicator turns red, the audio stream is interrupted. Denne LED-indikatoren blir rød når lydstrømmen forstyrres. Local Jitter Buffer status LED indicator LED-indikator for lokalt jitter-mellomlagerstatus Current Connection Status Nåværende tilkoblingsstatus The Ping Time is the time required for the audio stream to travel from the client to the server and back again. This delay is introduced by the network and should be about 20-30 ms. If this delay is higher than about 50 ms, your distance to the server is too large or your internet connection is not sufficient. Overall Delay is calculated from the current Ping Time and the delay introduced by the current buffer settings. C&onnect &Koble til &File &Fil &Connection Setup... &Tilkoblingsoppsett … &Load Mixer Channels Setup... &Last inn kanalmikserinnstillingene … &Save Mixer Channels Setup... &Lagre kanalmikserinnstillingene … E&xit &Avslutt &Edit &Rediger Clear &All Stored Solo and Mute Settings &Tøm alle lagrede solo- og forstummingsinnstillinger Set All Faders to New Client &Level Sett alle fadere til nytt klient&nivå Auto-Adjust all &Faders Auto-juster alle &fadere &View &Vis O&wn Fader First &Egen fader først N&o User Sorting &Ingen brukersortering Sort Users by &Name Sorter brukere etter &navn Sort Users by &Instrument Sorter brukere etter &instrument Sort Users by &Group Sorter brukere etter &gruppe Sort Users by &City Sorter brukere etter &by C&hat... &Sludring … &Analyzer Console... &Analysatorkonsoll … Sett&ings &Innstillinger My &Profile... Min &profil … Audio/Network &Settings... Lyd/&nettverksinnstillinger … A&dvanced Settings... A&vanserte innstillinger … %1 Directory Select Channel Setup File Velg kanaloppsettsfil user bruker users brukere Connect Koble til Settings Innstillinger Chat Sludring Enable feedback detection Skru på tilbakekoblingsoppdagelse Audio feedback or loud signal detected. We muted your channel and activated 'Mute Myself'. Please solve the feedback issue first and unmute yourself afterwards. Your sound card is not working correctly. Please open the settings dialog and check the device selection and the driver settings. Lydkortet ditt virker ikke rett. Åpne innstillingsdialogen og sjekk enhetsvalg og driverinnstillingene. Ok OK &Disconnect &Koble fra CClientDlgBase Reverb Lydklang Left Venstre Right Høyre Input Inngang L V R H Jitter Jitter Delay Forsinkelse Ping Svartidsforespørsel ms ms &Mute Myself &Forstum deg selv &Settings &Innstillinger &Chat &Sludring C&onnect &Koble til MUTED (Other people won't hear you) Forstummet (andre hører deg ikke) Set up your audio, connect to a server and start jamming! Sett opp egen lyd, koble til en tjener og spill. Update check Oppdateringssjekk CClientSettingsDlg &Close &Lukk Local Audio Input Fader Fader for lokal lydinngang Controls the relative levels of the left and right local audio channels. For a mono signal it acts as a pan between the two channels. For example, if a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows %1, where %2 is the current attenuation indicator. L V Local audio input fader (left/right) Fader for lokal lydinngang (venstre/høyre) Jitter Buffer Size Størrelse på jitter-mellomlager The jitter buffer compensates for network and sound card timing jitters. The size of the buffer therefore influences the quality of the audio stream (how many dropouts occur) and the overall delay (the longer the buffer, the higher the delay). You can set the jitter buffer size manually for the local client and the remote server. For the local jitter buffer, dropouts in the audio stream are indicated by the light below the jitter buffer size faders. If the light turns to red, a buffer overrun/underrun has taken place and the audio stream is interrupted. The jitter buffer setting is therefore a trade-off between audio quality and overall delay. If the Auto setting is enabled, the jitter buffers of the local client and the remote server are set automatically based on measurements of the network and sound card timing jitter. If Auto is enabled, the jitter buffer size faders are disabled (they cannot be moved with the mouse). If the Auto setting is enabled, the network buffers of the local client and the remote server are set to a conservative value to minimize the audio dropout probability. To tweak the audio delay/latency it is recommended to disable the Auto setting and to lower the jitter buffer size manually by using the sliders until your personal acceptable amount of dropouts is reached. The LED indicator will display the audio dropouts of the local jitter buffer with a red light. Local jitter buffer slider control Glidebryterkontroll for lokalt jittermellomlager Server jitter buffer slider control Glidebryterkontroll for tjener-jittermellomlager Auto jitter buffer switch Audio Device Lydenhet Under the Windows operating system the ASIO driver (sound card) can be selected using %1. If the selected ASIO driver is not valid an error message is shown and the previous valid driver is selected. Under macOS the input and output hardware can be selected. På Windows kan ASIO-driverrutinen (lydkort) velges ved bruk av %1. Hvis valgt ASIO-driverrutine ikke er gyldig vil en feilmelding vises og forrige gyldige driver valgt. På macOS kan inngang- og utgangsmaskinvare velges. If the driver is selected during an active connection, the connection is stopped, the driver is changed and the connection is started again automatically. Sound card device selector combo box Kombinasjonsboksvelger for lydkortsenhet If the ASIO4ALL driver is used, please note that this driver usually introduces approx. 10-30 ms of additional audio delay. Using a sound card with a native ASIO driver is therefore recommended. If you are using the kX ASIO driver, make sure to connect the ASIO inputs in the kX DSP settings panel. Hvis du bruker kX ASIO-driverrutinen må du sørge for å koble til ASIO-inngangene i kX DSP-innstillingspanelet. Sound Card Channel Mapping Lydkortets kanalvalg If the selected sound card device offers more than one input or output channel, the Input Channel Mapping and Output Channel Mapping settings are visible. For each %1 input/output channel (left and right channel) a different actual sound card channel can be selected. Left input channel selection combo box Kombinasjonsboks for valg av venstre inngangskanal Right input channel selection combo box Kombinasjonsboks for valg av høyre inngangskanal Left output channel selection combo box Kombinasjonsboks for valg av venstre utgangskanal Right output channel selection combo box Kombinasjonsboks for valg av høyre utgangskanal Enable Small Network Buffers Skru på små nettverksmellomlagre Enables support for very small network audio packets. These network packets are only actually used if the sound card buffer delay is smaller than %1 samples. The smaller the network buffers, the lower the audio latency. But at the same time the network load and the probability of audio dropouts or sound artifacts increases. Enable small network buffers check box Sound Card Buffer Delay The buffer delay setting is a fundamental setting of %1. This setting has an influence on many connection properties. Three buffer sizes can be selected Tre hurtiglagerstørrelser kan velges 64 samples: Provides the lowest latency but does not work with all sound cards. 64 samplinger: Gir lavest forsinkelse, men fungerer ikke med alle lydkort. 128 samples: Should work for most available sound cards. 128 samplinger: Bør fungere på de fleste lydkort. 256 samples: Should only be used when 64 or 128 samples is causing issues. 256 samplinger: Bør kun brukes hvis 64 eller 128 samplinger byr på problemer. Some sound card drivers do not allow the buffer delay to be changed from within %1. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. Use the appropriate tool for the interface in use to adjust this buffer size. For example, if using ASIO, use the "ASIO Device Settings" button to open the driver settings panel or if using JACK, use a tool such as QjackCtl to adjust the buffer size. Other interfaces, such as Pipewire, would require their appropriate tool being used. Please refer to the interface manual. If no buffer size is selected and all settings are disabled, this means a buffer size in use by the driver which does not match the values. %1 will still work with this setting but may have restricted performance. The actual buffer delay has influence on the connection, the current upload rate and the overall delay. The lower the buffer size, the higher the probability of a red light in the status indicator (drop outs) and the higher the upload rate and the lower the overall delay. The buffer setting is therefore a trade-off between audio quality and overall delay. Sound card driver settings Oppsett av driverrutine for lydkort This opens the driver settings of your sound card. Some drivers allow you to change buffer settings, others like ASIO4ALL lets you choose input or outputs of your device(s). More information can be found on jamulus.io. Dette åpner driverrutineinnstillingene for lydkortet ditt. Noen driverrutiner lar deg endre hurtiglagerinnstillinger. Andre som f.eks. ASIO4ALL lar deg velge innganger og utganger for din(e) enhet(er). Mer info er å finne på jamulus.io. Opens the driver settings. Note: %1 currently only supports devices with a sample rate of %2 Hz. You will not be able to select a driver/device which doesn't. For more help see jamulus.io. Åpner driverrutine-innstillingene. Merk: %1 støtter kun enheter med samplingsrate på %2 Hz for øyeblikket. Du vil ikke kunne velge en driverrutine/enhet som ikke har det. Mer info er å finne på jamulus.io. 64 samples setting radio button 128 samples setting radio button Radioknapp for valg av 128 samplinger 256 samples setting radio button Radioknapp for valg av 256 samplinger ASIO Device Settings push button Trykk-knapp for ASIO-enhetsinnstillinger Skin Drakt Select the skin to be used for the main window. Velg drakt for hovedvinduet Skin combo box Draktkombinasjonsboks Meter Style Select the meter style to be used for the level meters. The Bar (narrow) and LEDs (round, small) options only apply to the mixerboard. When Bar (narrow) is selected, the input meters are set to Bar (wide). When LEDs (round, small) is selected, the input meters are set to LEDs (round, big). The remaining options apply to the mixerboard and input meters. Meter Style combo box Language Språk Select the language to be used for the user interface. Velg språk å bruke i brukergrensesnittet. Language combo box Språk-kombinasjonsboks Audio Channels Lydkanaler Selects the number of audio channels to be used for communication between client and server. There are three modes available: Mono Mono and og Stereo Stereo These modes use one and two audio channels respectively. Disse bruker respektivt én og to lydkanaler. Mono in/Stereo-out Mono inn/stereo ut The audio signal sent to the server is mono but the return signal is stereo. This is useful if the sound card has the instrument on one input channel and the microphone on the other. In that case the two input signals can be mixed to one mono channel but the server mix is heard in stereo. Enabling Skrur på mode will increase your stream's data rate. Make sure your upload rate does not exceed the available upload speed of your internet connection. In stereo streaming mode, no audio channel selection for the reverb effect will be available on the main window since the effect is applied to both channels in this case. I stereostrømmingsmodus er det ikke noe kanalvalg for lydklangseffekten tilgjengelig fra hovedvinduet, siden effekten brukes for begge kanaler i dette tilfellet. Audio channels combo box Kombinasjonsboks for lydkanaler Audio Quality Lydkvalitet The higher the audio quality, the higher your audio stream's data rate. Make sure your upload rate does not exceed the available bandwidth of your internet connection. Audio quality combo box Kombinasjonsboks for lydkvalitet New Client Level Nytt klientnivå This setting defines the fader level of a newly connected client in percent. If a new client connects to the current server, they will get the specified initial fader level if no other fader level from a previous connection of that client was already stored. New client level edit box Redigeringsboks for nytt klientnivå Input Boost This setting allows you to increase your input signal level by factors up to 10 (+20dB). If your sound is too quiet, first try to increase the level by getting closer to the microphone, adjusting your sound equipment or increasing levels in your operating system's input settings. Only if this fails, set a factor here. If your sound is too loud, sounds distorted and is clipping, this option will not help. Do not use it. The distortion will still be there. Instead, decrease your input level by getting farther away from your microphone, adjusting your sound equipment or by decreasing your operating system's input settings. Input Boost combo box Custom Directories Egendefinerte mapper If you need to add additional directories to the Connect dialog Directory drop down, you can enter the addresses here.<br>To remove a value, select it, delete the text in the input box, then move focus out of the control. Custom Directories combo box Audio Upstream Rate Depends on the current audio packet size and compression setting. Make sure that the upstream rate is not higher than your available internet upload speed (check this with a service such as speedtest.net). Number of Mixer Panel Rows Adjust the number of rows used to arrange the mixer panel. Number of Mixer Panel Rows spin box Feedback Protection Beskyttelse mot tilbakekobling Enable feedback protection to detect acoustic feedback between microphone and speakers. Feedback Protection check box Avkryssningsboks for tilbakekoblingsbeskyttelse Audio Alerts Lydvarsler Enable audio alert when receiving a chat message and when a new client joins the session. A second sound device may be required to hear the alerts. Audio Alerts check box ASIO Device Settings ASIO-enhetsinnstillinger Mono-in/Stereo-out Mono inn/stereo ut Low Lav Normal Normal High Høy Fancy Stilig Compact Kompakt Bar (narrow) Bjelke (tynn) Bar (wide) Bjelke (bred) LEDs (stripe) LED-lys (stripe) LEDs (round, small) LED-lys (runde, små) LEDs (round, big) LED-lys (runde, store) None Ingen Musician Profile Musikerprofil Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country or region you are located in. Your city and skill level playing your instrument may also be added. Skriv navnet ditt eller et kallenavn her slik at andre musikere du vil spille med vet hvem du er. Du kan også legge til et bilde av instrumentet du spiller, eller flagget for landet eller regionen du befinner deg i. By og ferdighetsnivå for instrumentet ditt kan også legges til. What you set here will appear at your fader on the mixer board when you are connected to a %1 server. This tag will also be shown at each client which is connected to the same server as you. Alias or name edit box Redigeringsfelt for alias eller navn Instrument picture button Instrumentbildeknapp Country/region flag button Land/region-flaggknapp City edit box Redigeringsfelt for by Skill level combo box Ferdighetsnivå-kombinasjonsboks Beginner Nybegynner Intermediate Erfaren Expert Ekspert Size: Størrelse: Buffer Delay Hurtiglagringsforsinkelse Buffer Delay: Hurtiglagringsforsinkelse: Center Midten R H Drum Set Slagverk Djembe Djembe Electric Guitar Elektrisk gitar Acoustic Guitar Akustisk gitar Bass Guitar Bassgitar Keyboard Synthesizer Grand Piano Accordion Trekkspill Vocal Vokal Microphone Mikrofon Harmonica Munnspill Trumpet Trompet Trombone Trombone French Horn Valthorn Tuba Tuba Saxophone Saksofon Clarinet Klarinett Flute Fløyte Violin Fiolin Cello Cello Double Bass Recorder Blokkfløyte Streamer Strømmer Listener Lytter Guitar+Vocal Gitar+vokal Keyboard+Vocal Bodhran Bodhrán Bassoon Fagott Oboe Obo Harp Harpe Viola Bratsj Congas Congas Bongo Bongoer Vocal Bass Vocal Tenor Vocal Alto Vocal Soprano Banjo Banjo Mandolin Ukulele Ukulele Bass Ukulele Vocal Baritone Vocal Lead Mountain Dulcimer Scratching Rapping Rapping Vibraphone Vibrafon Conductor Dirigent Any Genre 2 Any Genre 3 Genre Rock Genre Jazz Genre Classical/Folk Genre Choral/Barbershop Custom Egendefinert Any Genre 1 CClientSettingsDlgBase Settings Innstillinger My Profile Min profil Musician's Profile Alias/Name Alias/navn Instrument Instrument Country/Region City By Skill Ferdighetsnivå User Interface Brukergrensesnitt Skin Drakt Meter Style Language Språk Mixer Rows Mikserrader Audio Alerts Lydvarsler Enable Skru på Audio/Network Setup Audio Device Lydenhet Driver Setup Driverrutineoppsett Input Channel Mapping L V R H Output Channel Mapping Audio Channels Lydkanaler Audio Quality Lydkvalitet Buffer Delay Hurtiglagringsforsinkelse (preferred) (foretrukket) (default) (forvalg) (safe) (trygt) Jitter Buffer Auto Automatisk Local Server Tjener Size Størrelse Enable Small Network Buffers Skru på små nettverksmellomlagre Audio Stream Rate kbps val Advanced Setup Avansert oppsett Custom Directories: Egendefinerte mapper: New Client Level Nytt klientnivå % % Input Boost Feedback Protection Tilbakekoblingsbeskyttelse Input Balance Inngangsbalanse Pan Panorering Center Midten CConnectDlg Directory Mappe Shows the servers listed by the selected directory. You can add custom directories in Advanced Settings. Directory combo box Filter Filter Filters the server list by the given text. Note that the filter is case insensitive. A single # character will filter for those servers with at least one person connected. Filtrerer tjenerlisten for angitt tekst. Merk at det ikke tas hensyn til små og store bokstaver. Et enkelt «#»-tegn viser tjenere med minst én person tilknyttet. Filter edit box Show All Musicians Vis alle musikere Uncheck to collapse the server list to show just the server details. Check to show everyone on the servers. Show all musicians check box Avkryssningsboks for visning av alle musikere Server List Tjenerliste The Connection Setup window lists the available servers registered with the selected directory. Use the Directory dropdown to change the directory, find the server you want to join in the server list, click on it, and then click the Connect button to connect. Alternatively, double click on the server name to connect. Permanent servers (those that have been listed for longer than 48 hours) are shown in bold. You can add custom directories in Advanced Settings. Du kan legge til egendefinerte mapper i de avanserte innstillingene. Server list view Tjenerlistevisning Server Address Tjeneradresse If you know the server address, you can connect to it using the Server name/Address field. An optional port number can be added after the server address using a colon as a separator, e.g. %1. The field will also show a list of the most recently used server addresses. Server address edit box Redigeringsboks for tjeneradresse Holds the current server address. It also stores old addresses in the combo box list. Filter text, or # for occupied servers Filtrer tekst, eller # for tjenere som ikke er tomme CConnectDlgBase Connection Setup Tilkoblingsoppsett Directory Mappe Filter Filter Show All Musicians Vis alle musikere Server Name Tjenernavn Ping Time Svartid Musicians Musikere Location Sted Server Address Tjeneradresse C&ancel &Avbryt &Connect &Koble til CHelpMenu &Help &Hjelp Getting &Started... &Begynn … Software &Manual... &Programvaremanual What's &This Hva er &dette &About Jamulus... &Om Jamulus … About &Qt... Om &Qt … About Qt Om Qt CLanguageComboBox Restart Required Programomstart kreves Please restart the application for the language change to take effect. Start programmet på ny for å bruke det nye språket. CLicenceDlg This server requires you accept conditions before you can join. Please read these in the chat window. Tjeneren krever at du godtar vilkårene før du kobler til. Les disse i sludringsvinduet. I have read the conditions and &agree. Jeg har lest vilkårene og &samtykker. Accept Godta Decline Avslå CMultiColorLED Red Rød Yellow Gul Green Grønn CMusProfDlg No Name Uten navn CServerDlg %1 Server %1 is the name of the main application %1-tjener Client List Klientliste The client list shows all clients which are currently connected to this server. Some information about the clients like the IP address and name are given for each connected client. Connected clients list view Listevisning av tilkoblede klienter Directory Type combo box Directory Mappe Select '%1' not to register your server with a directory. Select one of the genres to register with that directory. Velg en av sjangerne å registrere med denne mappen. Or select '%1' and specify a Custom Directory address on the Options tab to register with a custom directory. For any value except '%1', this server registers with a directory so that a %2 user can select this server in the client connect dialog server list when they choose that directory. The registration of the server is renewed periodically to make sure that all servers in the connect dialog server list are actually available. Register Server Status Status for hvorvidt tjeneren er registrert When a value other than "%1" is chosen for Directory, this will show whether registration is successful. If the registration failed, please choose a different directory. Server Name Tjenernavn The server name identifies your server in the connect dialog server list at the clients. Server name line edit Location City The city in which this server is located can be set here. If a city name is entered, it will be shown in the connect dialog server list at the clients. City where the server is located line edit Country/Region Set the country or region where the server is running. Clients will show this location in their connect dialog's server list. Combo box for location of this server Checkbox to turn on or off server recording Avkryssningsboks for å slå på eller av tjeneropptak Enable Recorder Skru på opptak Checked when the recorder is enabled, otherwise unchecked. The recorder will run when a session is in progress, if (set up correctly and) enabled. Request new recording button Forespør ny opptaksknapp New Recording Nytt opptak During a recording session, the button can be used to start a new recording. I løpet av en økt kan knappen brukes til å starte et nytt opptak. Recorder status label Recorder Status Opptaksstatus Displays the current status of the recorder. The following values are possible: No recording directory has been set or the value is not useable. Check the value in the Options tab. Recording has been switched off by the UI checkbox. Recording has been switched off, either by the UI checkbox or SIGUSR2 being received. There is no one connected to the server to record. Det er ingen tilknyttet tjeneren å spille inn. The performers are being recorded to the specified session directory. NOTE If the recording directory is not useable, the problem will be displayed in place of the session directory. Current session directory text box (read-only) Current Session Directory Enabled during recording and holds the current recording session directory. Disabled after recording or when the recorder is not enabled. Server welcome message edit box Server Welcome Message Tjener-velkomstmelding A server welcome message text is displayed in the chat window if a musician enters the server. If no message is set, the server welcome is disabled. Language Språk Select the language to be used for the user interface. Velg språk for brukergrensesnittet. Language combo box Språk-kombinasjonsboks Display dialog to select recording directory button Main Recording Directory Hovedopptaksmappe Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user %1 is running as). Main recording directory text box (read-only) The current value of the main recording directory. The chosen value must exist and be writeable (allow creation of sub-directories by the user %1 is running as). Click the button to open the dialog that allows the main recording directory to be selected. Clear the recording directory button Clear Recording Directory Click the button to clear the currently selected recording directory. This will prevent recording until a new value is selected. Custom Directory address Egendefinert mappeadresse The Custom Directory address is the address of the directory holding the server list to which this server should be added. Custom Directory line edit Server List Filename dialog push button Server List Filename Tjenerliste-filnavn Click the button to open the dialog that allows the server list persistence file name to be set. The user %1 is running as needs to be able to create the file name specified although it may already exist (it will get overwritten on save). Server List Filename text box (read-only) The current value of server list persistence file name. The user %1 is running as needs to be able to create the file name specified although it may already exist (it will get overwritten on save). Click the button to open the dialog that allows the server list persistence file name to be set. Clear the server list file name button Clear Server List Filename Click the button to clear the currently selected server list persistence file name. This will prevent persisting the server list until a new value is selected. Start Minimized on Operating System Start If the start minimized on operating system start check box is checked, the server will be started when the operating system starts up and is automatically minimized to a system task bar icon. E&xit &Avslutt &Hide %1 server &Skjul %1-tjener &Show %1 server &Vis %1-tjener %1 server %1 is the name of the main application %1-tjeneren Type a message here. If no message is set, the server welcome is disabled. &Window &Vindu Recorder failed to start. Please check available disk space and permissions and try again. Error: Select Main Recording Directory Now a directory ERROR Feil Not initialised Not enabled Ikke påskrudd Not recording Tar ikke opp Recording Innspilling None Ingen Not registered Ikke registrert Bad address Feilaktig adresse Registration requested Registrering forespurt Registration failed Registrering mislyktes Check server version Sjekk tjenerversjonen Registered Registrert Directory server list full Your server version is too old Tjenerversjonen din er for gammel Requirements not fulfilled Krav er ikke oppfylt Unknown value %1 Ukjent verdi (%1) CServerDlgBase Client IP:Port Klient-IP:port Name Navn Jitter Buffer Size Størrelse på jittermellomlager Channels Kanaler Server Setup Tjeneroppsett Directory Mappe STATUS Status My Server Info Info om min tjener Location: City Sted: by Location: Region Sted: region Enable Jam Recorder Skru på samspillsopptaker New Recording Nytt opptak Session Økt Chat Window Welcome (HTML/CSS Supported) Velkomstmelding for sludring (HTML/CSS støttes) Options Alternativer Language Consider add "(Lang)" as a suffix to ensure that users who selected the wrong language find the correct button Språk Recording Directory Opptaksmappe Custom Directory address Egendefinert mappeadresse Server List Filename Tjenerliste-filnavn Start Minimized on Windows Start Start minimert ved systemoppstart Enable delay panning Update check Oppdateringssjekk CServerListManager Could not write to '%1' Kunne ikke skrive til «%1» CSound The selected audio device is no longer present in the system. Please check your audio device. Couldn't initialise the audio driver. Check if your audio hardware is plugged in and verify your driver settings. The selected audio device is incompatible since it doesn't support a sample rate of %1 Hz. Please select another device. The current audio device configuration is incompatible because the sample rate couldn't be set to %2 Hz. Please check for a hardware switch or driver setting to set the sample rate manually and restart %1. The selected audio device is incompatible since it doesn't support %1 in/out channels. Please select another device or configuration. The selected audio device is incompatible since the required audio sample format isn't available. Please use another device. No ASIO audio device driver found. Fant ingen ASIO-lydenhetsdriver. Please install an ASIO driver before running %1. If you own a device with ASIO support, install its official ASIO driver. If not, you'll need to install a universal driver like ASIO4ALL. Installer en ASIO-lydenhetsdriver før du kjører %1. Hvis du eier en enhet med ASIO-støtte kan du installere dens offisielle ASIO-driver. Hvis ikke må du installere en universell driver som f.eks ASIO4ALL. No sound card is available in your system. CoreAudio input AudioHardwareGetProperty call failed. No sound card is available in the system. CoreAudio output AudioHardwareGetProperty call failed. The currently selected audio device is no longer present. Please check your audio device. The audio input device is no longer available. Please check if your input device is connected correctly. The sample rate on the current input device isn't %1 Hz and is therefore incompatible. Please select another device or try setting the sample rate to %1 Hz manually via Audio-MIDI-Setup (in Applications->Utilities). The audio output device is no longer available. Please check if your output device is connected correctly. Lydutgangsenheten er ikke lenger tilgjengelig. Sjekk at utgangsenheten din er tilkoblet på riktig vis. The sample rate on the current output device isn't %1 Hz and is therefore incompatible. Please select another device or try setting the sample rate to %1 Hz manually via Audio-MIDI-Setup (in Applications->Utilities). The stream format on the current input device isn't compatible with this software. Please select another device. The stream format on the current output device isn't compatible with %1. Please select another device. The buffer sizes of the current input and output audio device can't be set to a common value. Please select different input/output devices in your system settings. JACK couldn't be started automatically. Please start JACK manually and check for error messages. Kunne ikke starte JACK automatisk. Start JACK på ny automatisk og sjekk om du finner noen feilmeldinger. JACK isn't running at a sample rate of <b>%1 Hz</b>. Please use a tool like <i><a href="https://qjackctl.sourceforge.io">QjackCtl</a></i> to set the the JACK sample rate to %1 Hz. JACK kjører ikke med samplingstakt på <b>%1 Hz</b>. Bruk et verktøy som f.eks. <i><a href="https://qjackctl.sourceforge.io">QjackCtl</a></i> for å sette JACK-samplingstakten til %1 Hz. The JACK port registration failed. This is probably an error with JACK. Please stop %1 and JACK. Afterwards check if another program at a sample rate of %2 Hz can connect to JACK. Kunne ikke registrere port for JACK. Dette er antagelig en feil i JACK. Stopp %1 og JACK. Etterpå kan du sjekke om et annet program med samplingstakt på %2 Hz kan koble til JACK. The JACK port registration failed. This is probably an error with JACK. Please stop %1 and JACK. Afterwards, check if another MIDI program can connect to JACK. Kunne ikke registrere port for JACK. Dette er antagelig en feil i JACK. Stopp %1 og JACK. Etterpå kan du sjekke om et annet MIDI-program kan koble til JACK. Can't activate the JACK client. This is probably an error with JACK. Please check the JACK output. Kan ikke aktivere JACK-klienten. Dette er antagelig en feil med JACK. Sjekk JACK-utgangen. JACK was shut down. %1 requires JACK to run. Please restart %1 to start JACK again. JACK ble skrudd av. %1 krever at JACK kjører. Start %1 på ny for å starte JACK igjen. Error requesting stream stop: $s Kunne ikke forespørre stopping av strøm: $s Error closing stream: $s Kunne ikke lukke strømmen: $s CSoundBase Can't use the selected audio device because of the following error: %1 The previous driver will be selected. Kan ikke bruke valgt lydenhet fordi: %1 Forrige driver vil bli valgt. The previously selected audio device is no longer available or the driver has changed to an incompatible state. We'll attempt to find a valid audio device, but this new audio device may cause feedback. Before connecting to a server, please check your audio device settings. Tidligere valgt driver er ikke lenger tilgjengelig, eller så har den endret seg til en inkompatibel tilstand. Forsøk på å finne en gyldig lydenhet vil bli utført, men denne nye lydenheten kan forårsake tilbakekobling. Før du kobler til en tjener bør du sjekke lydenhetsinnstillingene dine. <b>%1 couldn't find a usable %2 audio device.</b><br><br> <b>%1 kunne ikke finne noen anvendbar %2-lydenhet.</b><br><br> You may be able to fix errors in the driver settings. Do you want to open these settings now? Åpne driverinnstillingene for å sjekke om du kan fikse feilene der? Can't start %1. Please restart %1 and check/reconfigure your audio settings. Kan ikke starte %1. Start %1 på ny og sjekk/sett opp lydinnstillingene dine igjen. QCoreApplication %1, Version %2 %1 is app name, %2 is version number %1, versjon %2 Released under the GNU General Public License version 2 or later (GPLv2) Lisensiert GPLv2+ global A %1 upgrade is available: <a style='color:red;' href='https://jamulus.io/upgrade?progversion=%2'>go to details and downloads</a> En %1-oppgradering er tilgjengelig: <a style='color:red;' href='https://jamulus.io/upgrade?progversion=%2'>gå til detaljer og last den ned</a> For more information use the "What's This" help (help menu, right mouse button or Shift+F1) Mer info får du ved å bruke «Hva er dette»-hjelpen (hjelpemeny, høyreklikksknapp, eller Shift+F1) jamulus-3.9.1+dfsg/src/translation/translation_zh_CN.ts0000644000175000017500000054237414340334543022307 0ustar vimervimer CAboutDlg Qt cross-platform application framework Qt 跨平台应用程序框架 Audio reverberation code by Perry R. Cook and Gary P. Scavone 音频混响代码作者为 Perry R. Cook 和 Gary P. Scavone Some pixmaps are from the 部分图像资源来自 This app enables musicians to perform real-time jam sessions over the internet. 此应用使乐手们可以在线实时进行音乐合奏。 There is a server which collects the audio data from each client, mixes the audio data and sends the mix back to each client. 这是一个收集来自各个客户端声音数据,并将音频数据混合并发回各个客户端的服务器端程序。 This app uses the following libraries, resources or code snippets: 此应用程序使用了以下依赖库,资源或代码片段: Country flag icons by Mark James 旗帜图标作者为 Mark James For details on the contributions check out the 关于贡献者的详情请参见 Flag icons by Mark James 旗帜图标作者为 Mark James Some sound samples are from 部分音频采样来自 For details on the contributions check out the %1 关于贡献者的详情请参见 %1 Github Contributors list Github 贡献者列表 Spanish 西班牙语 French 法语 Portuguese 葡萄牙语 Dutch 荷兰语 Italian 意大利语 German 德语 Polish 波兰语 Swedish 瑞典语 Korean 韩语 Slovak 斯洛伐克语 Simplified Chinese 简体中文 Norwegian Bokmål About %1 关于 %1 About 关于 CAboutDlgBase About 关于 TextLabelVersion 版本文字标签 Copyright (C) 2005-2022 The Jamulus Development Team 版权所有 (C) 2005-2021 Jamulus 开发团队 A&bout 关于(&A) &Libraries 依赖库(&L) &Contributors 贡献者(&C) &Translation 翻译者(&T) &OK 确认(&O) CAnalyzerConsole Analyzer Console 分析控制台 Error Rate of Each Buffer Size 错误的缓冲区采样率大小 CAudioMixerBoard Personal Mix at the Server 位于服务器的个人混音室 When connected to a server, the controls here allow you to set your local mix without affecting what others hear from you. The title shows the server name and, when known, whether it is actively recording. 当连接到一个服务器时,此控件将允许您设置本地混音选项而不会影响到它人实际听到您的情况。标题将会显示服务器名称,以及是否在录制状态。 Server 服务器 T R Y I N G T O C O N N E C T 尝 试 连 接 中 RECORDING ACTIVE 录制已开启 Personal Mix at: %1 个人混音室: %1 CChannelFader Pan 左右平衡 Mute 静音 Solo 独奏 &No grouping 不分组(&N) Assign to group 分配到组 The fader tag identifies the connected client. The tag name, a picture of your instrument and the flag of your location can be set in the main window. 推子标签指示了连接到的客户端。标签名称、乐器图案和您所在位置的旗帜可在主窗口中进行设置。 Mixer channel country/region flag 混音通道的国家/地区旗帜 Grp Channel Level 声道音量 Input level of the current audio channel at the server 位于服务器的当前声道的输入音量 Mixer Fader 混音推子 Local mix level setting of the current audio channel at the server 位于服务器的当前音频通道的本地混音音量设置 Status Indicator 状态指示器 Shows a status indication about the client which is assigned to this channel. Supported indicators are: 显示当前声道对应的客户端的状态指示。支持的指示有: Status indicator label 状态指示标签 Panning 左右平衡 Local panning position of the current audio channel at the server 此服务器上当前声道的本地声像位置 With the Mute checkbox, the audio channel can be muted. 使用静音勾选框,可将声道静音。 Mute button 静音按钮 Solo button 独奏按钮 Fader Tag 推子标签 Displays the pre-fader audio level of this channel. All clients connected to the server will be assigned an audio level, the same value for every client. 按推子显示当前声道的音量。所有连接到一服务器的客户端都会被分配有一个音频音量,所有客户端相同的值。 Adjusts the audio level of this channel. All clients connected to the server will be assigned an audio fader, displayed at each client, to adjust the local mix. 调整当前声道的音量。所有连接到一服务器的客户端都会被分配有一个音频推子,在客户端旁展示,用以调整本地混音。 Speaker with cancellation stroke: Indicates that another client has muted you. 被划掉的喇叭图标:表示其它客户端把你静音了。 Sets the pan from Left to Right of the channel. Works only in stereo or preferably mono in/stereo out mode. 从左到右设定声道的声像。仅对立体声或单声道输入、立体声输出模式可用。 With the Solo checkbox, the audio channel can be set to solo which means that all other channels except the soloed channel are muted. It is possible to set more than one channel to solo. 使用独奏勾选框可将声道进行独奏,即除独奏声道外的其它声道将会静音。可将多个声道设置为独奏。 Group 分组 With the Grp checkbox, a group of audio channels can be defined. All channel faders in a group are moved in proportional synchronization if any one of the group faders are moved. 通过分组勾选框,即可定义一组声道。移动一组内的任意一个推子时,所有同组的声道推子将会同时移动。 Group button 分组按钮 The fader tag identifies the connected client. The tag name, a picture of your instrument and the flag of your country can be set in the main window. 推子标签指示了连接到的客户端。标签名称、乐器图案和您所在地区的旗帜可在主窗口中进行设置。 Mixer channel instrument picture 混音通道的乐器图片 Mixer channel label (fader tag) 混音通道的标签(推子标签) Mixer channel country flag 混音通道的地区旗帜 PAN 声像 MUTE 静音 SOLO 独奏 GRP 分组 M M S S G G Alias/Name 别名/名称 Instrument 乐器 Location 位置 Skill Level 水平程度 Alias 别名 Beginner 新手 Intermediate 中级 Expert 专家 Musician Profile 乐手信息 CChatDlg Chat Window 聊天窗口 The chat window shows a history of all chat messages. 此聊天窗口显示所有历史聊天信息。 Chat history 聊天记录 Input Message Text 输入消息文本 Enter the chat message text in the edit box and press enter to send the message to the server which distributes the message to all connected clients. Your message will then show up in the chat window. 在输入框中输入聊天信息并按下回车来发送信息到服务器,服务器将会把信息分发给连接到服务器的其它所有客户端。您的信息将会显示在聊天窗口。 New chat text edit box 聊天新对话文字输入框 Type a message here 在此键入消息 &Edit 编辑(&E) Cl&ear Chat History 清除聊天记录(&C) &Close 关闭(&C) Do you want to open the link '%1' in your browser? 您想在您的浏览器中打开链接 '%1' 吗? Do you want to open the link 您想要在外置浏览器中打开链接 in an external browser? 吗? CChatDlgBase Chat 聊天 &Send 发送(&S) CClientDlg Input Level Meter 输入音量计量表 Make sure not to clip the input signal to avoid distortions of the audio signal. 请避免擦碰输入以避免音频失真。 Input level meter 输入音量计量表 Simulates an analog LED level meter. 模拟实物 LED 音量电平计量表。 Connect/Disconnect Button 连接/断开连接按钮 Connect and disconnect toggle button 连接和断开连接的开关按钮 software. 软件. Delay Status LED 延迟指示 LED If this LED indicator turns red, you will not have much fun using the 如果此 LED 指示器变红,您可能无法很愉快的使用 Delay status LED indicator 延迟状态 LED 指示器 The network jitter buffer is not large enough for the current network/audio interface jitter. 为应对当前网络/音频接口延迟而言当前网络抖动缓冲大小不够大。 This shows the level of the two stereo channels for your audio input. 这里展示了立体声的两个声道的音频输入音量。 If the application is connected to a server and you play your instrument/sing into the microphone, the VU meter should flicker. If this is not the case, you have probably selected the wrong input channel (e.g. 'line in' instead of the microphone input) or set the input gain too low in the (Windows) audio mixer. 如果应用程序已连接到了服务器且您已开始对着麦克风演奏乐器或唱歌,此 VU 计量表将开始跳动。若未发生此情况,您可能选错了输入声道或您的 (Windows) 音量合成器中的音频增益设置过低。 For proper usage of the application, you should not hear your singing/instrument through the loudspeaker or your headphone when the software is not connected. This can be achieved by muting your input audio channel in the Playback mixer (not the Recording mixer!). 为了恰当的使用此应用程序,当您未连接到服务器时您不会希望在音响或耳机中听到您的演唱或弹奏。您可以通过在音频声道(不是录制混音器!)中将自己静音来达到此目的。 Reverb effect 混响效果 Reverb can be applied to one local mono audio channel or to both channels in stereo mode. The mono channel selection and the reverb level can be modified. For example, if a microphone signal is fed in to the right audio channel of the sound card and a reverb effect needs to be applied, set the channel selector to right and move the fader upwards until the desired reverb level is reached. 可以将混响应用至本地单声道或立体声双声道上。可以调整单声道的选取和混响程度。例如,如果麦克风信号输入到了声卡的右声道并希望对其应用混响效果,从通道选取器选择右声道并向上移动推子直到达到了希望的混响程度即可。 Reverb effect level setting 混响效果程度设定 Reverb Channel Selection 混响通道选则框 With these radio buttons the audio input channel on which the reverb effect is applied can be chosen. Either the left or right input channel can be selected. 使用这些单选按钮可选择混响效果需要应用到的音频输入声道。左声道和右声道均可供选择。 Left channel selection for reverb 左通道的混响 Right channel selection for reverb 右通道的混响 Green 绿 The delay is perfect for a jam session. 该延迟很适合来场合奏。 Yellow Red Opens a dialog where you can select a server to connect to. If you are connected, pressing this button will end the session. 将打开一个供选择您要连接到的服务器的对话框。如果您已连接,按下此按钮将断开此次会话。 Shows the current audio delay status: 指示当前音频的延迟情况: A session is still possible but it may be harder to play. 仍可来场合奏但或许体验较差而难以完成。 The delay is too large for jamming. 该延迟太高,不适合进行合奏。 If this LED indicator turns red, you will not have much fun using the application. 如果此 LED 指示器变红,您可能无法很愉快的使用此应用程序。 The sound card's buffer delay (buffer size) is too small (see Settings window). 声卡的缓冲区延迟(缓冲区大小)过小(见设置窗口)。 The upload or download stream rate is too high for your internet bandwidth. 上行或下行流量频率对您的网络带宽而言过高。 The CPU of the client or server is at 100%. 客户端或服务器的 CPU 负载已达 100%。 Current Connection Status Parameter 当前连接情况参数 The Ping Time is the time required for the audio stream to travel from the client to the server and back again. This delay is introduced by the network and should be about 20-30 ms. If this delay is higher than about 50 ms, your distance to the server is too large or your internet connection is not sufficient. Ping 延迟时间是指您的音频数据从您的客户端传输到服务器再传输回来所需的耗时。此延迟由网络导致且应保持在 20-30 毫秒。若延迟高于 50 毫秒,您到服务器的距离可能过远或您的网络连接可能不可用。 Overall Delay is calculated from the current Ping Time and the delay introduced by the current buffer settings. 最终延迟由当前 Ping 延迟和当前的缓冲区大小设定组合计算而来。 If this LED indicator turns red, you will not have much fun using the %1 software. 如果此 LED 指示器变红,您可能无法很愉快的使用 %1。 C&onnect 连接(&O) software upgrade available 软件更新可用 &File 文件(&F) &View 视图(&V) &Connection Setup... 连接配置(&C)... My &Profile... 我的信息(&P)... C&hat... 聊天(&H)... &Analyzer Console... 分析控制台(&A)... N&o User Sorting 不对用户进行排序(&O) Sort Users by &City 根据城市排序用户(&C) Clear &All Stored Solo and Mute Settings 清除所有已保存的独奏和静音设定(&A) Auto-Adjust all &Faders 自动调整所有推子(&F) %1 Directory %1 目录 Ok Ok 确认 Set All Faders to New Client &Level 将所有推子设置为新客户端音量值(&L) E&xit 退出(&E) &Load Mixer Channels Setup... 加载混音器通道选项(&L)... &Save Mixer Channels Setup... 保存混音器通道选项(&S)... Sett&ings 设置(&I) Audio/Network &Settings... 音频/网络选项(&S)... A&dvanced Settings... 高级选项(&D)... &Edit 编辑(&E) If this LED indicator turns red, you will not have much fun using %1. 如果此 LED 指示器变红,您可能无法很愉快的使用 %1。 Local Jitter Buffer Status LED 本地抖动缓冲状态 LED The local jitter buffer status LED shows the current audio/streaming status. If the light is red, the audio stream is interrupted. This is caused by one of the following problems: 本地抖动缓冲区状态 LED 指示当前音频/串流状态。如果变红,表示音频流被中断了。这可能由以下问题导致: If this LED indicator turns red, the audio stream is interrupted. 如果此 LED 指示器变红,音频流则为中断状态。 Local Jitter Buffer status LED indicator 本地抖动缓冲状态 LED 指示器 Current Connection Status 当前连接状态 O&wn Fader First 优先显示自己的推子(&W) Sort Users by &Name 根据名称排序用户(&N) Sort Users by &Instrument 根据乐器排序用户(&I) Sort Users by &Group 根据分组排序用户(&G) &Settings 设置(&Z) Directory Server 目录服务器 Select Channel Setup File 选择通道配置文件 user 用户 users 用户 Connect 连接 Settings 选项 Chat 聊天 Enable feedback detection 启用自激保护 Audio feedback or loud signal detected. We muted your channel and activated 'Mute Myself'. Please solve the feedback issue first and unmute yourself afterwards. 检测到自激或过大的音频信号。 静音已启用并已为您打开了“静音自己”选项。请解决自激问题然后手动取消静音。 Your sound card is not working correctly. Please open the settings dialog and check the device selection and the driver settings. 您的声卡未正常工作。请打开设置对话框并检查设备选项和驱动设置。 &Disconnect 断开连接(&D) CClientDlgBase Delay 延迟 Input 输入 L R Jitter 抖动 Ping Ping ms ms &Mute Myself 静音自己(&M) &Settings 设置(&S) &Chat 聊天(&C) C&onnect 连接(&O) Reverb 混响 Left Right MUTED (Other people won't hear you) 已静音(别人不会听到你) Set up your audio, connect to a server and start jamming! 配置您的音频,连接到服务器然后开始合奏吧! Update check 检查更新 CClientSettingsDlg Jitter Buffer Size 抖动缓冲区大小 The jitter buffer setting is therefore a trade-off between audio quality and overall delay. 抖动缓冲选项是音频质量和总延迟之间的一种权衡。 Local jitter buffer slider control 本地抖动缓冲滑条 Server jitter buffer slider control 服务器抖动缓冲滑条 Auto jitter buffer switch 自动抖动缓冲开关 Sound Card Device 声卡设备 If the driver is selected during an active connection, the connection is stopped, the driver is changed and the connection is started again automatically. 若在一个已建立的连接过程中选择驱动,则连接会被断开,驱动也将被改变,随后将会自动重新建立连接。 Sound card device selector combo box 声卡设备选择框 If the ASIO4ALL driver is used, please note that this driver usually introduces approx. 10-30 ms of additional audio delay. Using a sound card with a native ASIO driver is therefore recommended. 如果使用 ASIO4ALL 驱动,则请注意其会引入大约 10 至 30 毫秒的额外音频延迟。建议使用具有原生 ASIO 驱动支持的声卡及其官方配套驱动。 If you are using the kX ASIO driver, make sure to connect the ASIO inputs in the kX DSP settings panel. 如果您在使用 kX ASIO 驱动,请确保在 kX DSP 设定面板中正确配置 ASIO 的输入连接。 Sound Card Channel Mapping 声卡声道映射 If the selected sound card device offers more than one input or output channel, the Input Channel Mapping and Output Channel Mapping settings are visible. 若所选的声卡设备提供了超过一个输入或输出声道,则输入声道映射和输出声道映射设置项将可见。 Left input channel selection combo box 左输入声道选择框 Right input channel selection combo box 右输入声道选择框 Left output channel selection combo box 左输出声道选择框 Right output channel selection combo box 右输出声道选择框 Enable Small Network Buffers Small Network Buffers 的作用不确定,暂定译法 启用小网络缓冲区 Enable small network buffers check box 启用小网络缓冲区勾选框 Sound Card Buffer Delay 声卡缓冲区延迟 Three buffer sizes are supported 当前支持三种缓冲区大小 Some sound card drivers do not allow the buffer delay to be changed from within %1. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. On Windows, use the ASIO Device Settings button to open the driver settings panel. On Linux, use the JACK configuration tool to change the buffer size. 一些声卡驱动不允许让 %1 来调整其缓冲区延迟。因此,缓冲区设定选项已被禁用且您应当通过其声卡驱动来调整其设置。在 Windows 中,使用 ASIO 驱动设置按钮来打开驱动设置面板。在 Linux,使用 JACK 配置工具来调整缓冲区大小。 If no buffer size is selected and all settings are disabled, this means an unsupported buffer size is in use by the driver. %1 will still work with this setting but may have restricted performance. 若没有选择缓冲区大小且所有设置项均被禁用,则表示驱动使用了不受支持的缓冲区大小。在此设置下 %1 将仍然可用,但性能可能受到限制。 The actual buffer delay has influence on the connection status, the current upload rate and the overall delay. The lower the buffer size, the higher the probability of a red light in the status indicator (drop outs) and the higher the upload rate and the lower the overall delay. 实际缓冲区延迟将影响连接状况、当前上传速率和总体延迟情况。缓冲区大小越小则状态指示亮红灯(断线)的概率将更高,上行带宽速率将更高,总体延迟则将更低。 The buffer setting is therefore a trade-off between audio quality and overall delay. 缓冲区设置则是在音质和总体延迟之间的权衡。 If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within %1. On Windows, press the ASIO Device Settings button to open the driver settings panel. On Linux, use the JACK configuration tool to change the buffer size. 若缓冲区延迟设置被禁用,则是因为音频驱动禁止 %1 修改此选项。在 Windows 中,按下 ASIO 驱动设置按钮来打开设置面板。在 Linux 中,使用 JACK 配置工具来调整缓冲区大小。 This opens the driver settings of your sound card. Some drivers allow you to change buffer settings, others like ASIO4ALL lets you choose input or outputs of your device(s). More information can be found on jamulus.io. 这将打开您声卡的驱动选项。一些驱动允许您调整缓冲区选项,其它类如 ASIO4ALL 则允许您选择音频的输入输出设备。更多信息可从 jamulus.io 了解。 Opens the driver settings. Note: %1 currently only supports devices with a sample rate of %2 Hz. You will not be able to select a driver/device which doesn't. For more help see jamulus.io. 打开驱动选项。注意:%1 目前仅支持采样率为 %2 的设备。您无法选择非此采样率的设备。更多帮助请见 jamulus.io。 64 samples setting radio button 64 采样设置单选按钮 128 samples setting radio button 128 采样设置单选按钮 256 samples setting radio button 256 采样设置单选按钮 Select the meter style to be used for the level meters. The Bar (narrow) and LEDs (round, small) options only apply to the mixerboard. When Bar (narrow) is selected, the input meters are set to Bar (wide). When LEDs (round, small) is selected, the input meters are set to LEDs (round, big). The remaining options apply to the mixerboard and input meters. 选择音量计量表所使用的计量表样式。窄条和圆形小 LED 选项仅在混音版有效。选择窄条时,输入音量计量表将被设置为条状。选择圆形小 LED 时,输入音量计量表将使用圆形大 LED。其余选项均可同时应用于混音版和输入音量计量表。 Audio Channels 音频通道 and Audio channels combo box 声道选择框 Audio Quality 音频质量 Audio quality combo box 音频质量选择框 New Client Level 新客户端音量 New client level edit box 新客户端音量编辑框 Custom Directory Server Address 自定义目录服务器地址 What you set here will appear at your fader on the mixer board when you are connected to a %1 server. This tag will also be shown at each client which is connected to the same server as you. 当你连接到一个 %1 服务器时,你填写到这里的内容会显示在代表你的那个推子上。此标签也会呈现在其它连接到相同服务器的客户端上。 Mono 单声道 The ASIO driver (sound card) can be selected using %1 under the Windows operating system. Under macOS/Linux, no sound card selection is possible. If the selected ASIO driver is not valid an error message is shown and the previous valid driver is selected. 可在 Windows 操作系统上使用 %1 选择 ASIO 驱动(声卡),在 macOS/Linux 则无声卡选择选项。若所选的 ASIO 驱动无效,则会显示一条错误信息并恢复选择到之前有效的驱动。 For each %1 input/output channel (left and right channel) a different actual sound card channel can be selected. 对于所有 %1 输入/输出声道(左右声道)均可选择对应到不同的声卡的声道。 Enables support for very small network audio packets. These network packets are only actually used if the sound card buffer delay is smaller than %1 samples. The smaller the network buffers, the lower the audio latency. But at the same time the network load and the probability of audio dropouts or sound artifacts increases. 启用超小网络音频数据包的支持。这些网络包仅会在声卡缓冲区延迟小于 %1 采样率时才启用。网络缓冲区越小,则音频延迟越低。但于此同时网络负载和产生音频中断或声音伪影的可能性将会增加。 mode will increase your stream's data rate. Make sure your upload rate does not exceed the available upload speed of your internet connection. 模式将增加您的媒体流数据频率。请确保您的上传速率未超过您实际可用的网络上传速率。 Custom Directories 自定义目录 If you need to add additional directories to the Connect dialog Directory drop down, you can enter the addresses here.<br>To remove a value, select it, delete the text in the input box, then move focus out of the control. 如果您需要在连接对话框的分类目录下拉框中添加额外的分类目录,即可在这里填写位置。<br>若要移除一个值,先将其选中,然后在输入框中删除对应的文字,在将输入焦点移出控件即可。 Custom Directories combo box 自定义分类目录下拉框 Audio Upstream Rate 音频流上行速度 Depends on the current audio packet size and compression setting. Make sure that the upstream rate is not higher than your available internet upload speed (check this with a service such as speedtest.net). 取决于当前音频数据包大小和压缩设定。请确保当前上行流量频率未超过您网络的可用上传速度(可通过类如 speedtest.net 的服务进行检测)。 Mono-in/Stereo-out 单声道输入/立体声输出 Stereo 立体声 &Close 关闭(&C) Local Audio Input Fader 本地音频输入推子 L L Local audio input fader (left/right) 本地音频输入推子(左/右) The jitter buffer compensates for network and sound card timing jitters. The size of the buffer therefore influences the quality of the audio stream (how many dropouts occur) and the overall delay (the longer the buffer, the higher the delay). 抖动缓冲区补偿了网络和声卡时值抖动。缓冲区的大小也影响了音频流的质量(发生多少丢包)和总体延迟(缓冲区越大,延迟越高)。 You can set the jitter buffer size manually for the local client and the remote server. For the local jitter buffer, dropouts in the audio stream are indicated by the light below the jitter buffer size faders. If the light turns to red, a buffer overrun/underrun has taken place and the audio stream is interrupted. 您可以在本地客户端和服务端手动设置抖动缓冲区的大小。对于本地抖动缓冲区,音频流的丢包将由抖动缓冲区大小推子下方的灯来指示。若灯变红,则表明缓冲区上溢/下溢在发生,因而音频流发生了中断。 If the Auto setting is enabled, the jitter buffers of the local client and the remote server are set automatically based on measurements of the network and sound card timing jitter. If Auto is enabled, the jitter buffer size faders are disabled (they cannot be moved with the mouse). 若选取了自动,则本地客户端和远程服务器的抖动缓冲区将根据网络情况和声卡时值抖动来自动推断。若选取了自动,则用于手动设置抖动缓冲区大小的推子也将被禁用(无法使用鼠标调节)。 If the Auto setting is enabled, the network buffers of the local client and the remote server are set to a conservative value to minimize the audio dropout probability. To tweak the audio delay/latency it is recommended to disable the Auto setting and to lower the jitter buffer size manually by using the sliders until your personal acceptable amount of dropouts is reached. The LED indicator will display the audio dropouts of the local jitter buffer with a red light. 若选取了自动,则本地客户端和远程服务器的抖动缓冲区将设为保守可使得音频丢包率最低的值。若要调整音频延迟,则推荐您禁用自动设置并手动使用滑块调低抖动缓冲区大小直到达到您满意的效果。本地音频抖动丢包时 LED 标识将指示红灯。 The buffer delay setting is a fundamental setting of %1. This setting has an influence on many connection properties. 缓冲区延迟设定是 %1 的一个基础设置项。此选项会对很多连接相关的属性有影响。 64 samples: The preferred setting. Provides the lowest latency but does not work with all sound cards. 64 采样:建议的设置。提供最低的延迟但并非支持所有声卡。 128 samples: Should work for most available sound cards. 128 采样:应该适用于大多数可用的声卡。 256 samples: Should only be used on very slow computers or with a slow internet connection. 256 采样:仅当在过慢的电脑或过慢的网络连接下使用。 Controls the relative levels of the left and right local audio channels. For a mono signal it acts as a pan between the two channels. For example, if a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows %1, where %2 is the current attenuation indicator. 控制了本地音频左右声道的相对音量。对于单声道信号,其行为为对声像的调整。例如,若麦克风连接到了右输入声道,而音量远高于麦克风的乐器被连接到了左输入声道,则将音量推子向推子上方标识 %1 的方向移动,%2 是当前的衰减指示器。 Audio Device 音频设备 Under the Windows operating system the ASIO driver (sound card) can be selected using %1. If the selected ASIO driver is not valid an error message is shown and the previous valid driver is selected. Under macOS the input and output hardware can be selected. 在 Windows 操作系统下,ASIO 驱动(声卡)可通过 %1 进行选择。若所选的 ASIO 驱动无效,则将展示错误信息并选取上一个有效的驱动。在 macOS 中,输入和输出硬件可供选择。 Three buffer sizes can be selected 三种缓冲区大小可供选择 64 samples: Provides the lowest latency but does not work with all sound cards. 64 采样:提供最低的延迟但并非支持所有声卡。 256 samples: Should only be used when 64 or 128 samples is causing issues. 256 采样:仅当在 64 或 128 采样存在问题时使用。 Some sound card drivers do not allow the buffer delay to be changed from within %1. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. Use the appropriate tool for the interface in use to adjust this buffer size. For example, if using ASIO, use the "ASIO Device Settings" button to open the driver settings panel or if using JACK, use a tool such as QjackCtl to adjust the buffer size. Other interfaces, such as Pipewire, would require their appropriate tool being used. Please refer to the interface manual. 部分声卡驱动不允许缓冲区延迟被调整到 %1。在此情况下,缓冲区延迟设置项会被禁用,此时需要从相应的显卡驱动中修改缓冲区大小的设置。例如,如果使用 ASIO,则使用“ASIO 设备选项”按钮来打开驱动设置面板,或是使用 JACK 时,使用类如 QjackCtl 的工具来调整缓冲区大小。其它音频介质,如 Pipewire,则需要使用其对应的设置工具来调整。请参照对应声卡驱动或音频介质的文档。 If no buffer size is selected and all settings are disabled, this means a buffer size in use by the driver which does not match the values. %1 will still work with this setting but may have restricted performance. 如果没有选择缓冲区大小且所有设置均被禁用,则表明驱动所使用的缓冲区大小与提供的值不匹配。在此设定下,%1 仍将可供使用,但可能存在受限的性能。 The actual buffer delay has influence on the connection, the current upload rate and the overall delay. The lower the buffer size, the higher the probability of a red light in the status indicator (drop outs) and the higher the upload rate and the lower the overall delay. 实际的缓冲区延迟的设置将影响连接、当前上行带宽以及总体延迟情况。缓冲区大小越小,则指示灯亮红的概率越大(音频丢包),对上行带宽的要求也就越高,总体延迟也就越低。 Sound card driver settings 声卡驱动选项 ASIO Device Settings push button ASIO 驱动设置按钮 Skin 皮肤 Select the skin to be used for the main window. 选择用于主窗口的皮肤。 Skin combo box 皮肤选择框 Meter Style 计量表样式 Select the meter style to be used for the level meters. The Narrow Bar and Small LEDs options only apply to the mixerboard. When Narrow Bar is selected, the input meters are set to Bar. When Small LEDs is selected, the input meters are set to Round LEDs. The remaining options apply to the mixerboard and input meters. 选择音量计量表所使用的计量表样式。窄条和小 LED 选项仅在混音版有效。选择窄条时,输入音量计量表将被设置为条状。选择小 LED 时,输入音量计量表将使用圆 LED。其余选项均可同时应用于混音版和输入音量计量表。 Meter Style combo box 计量表样式下拉框 Language 语言(Lang) Select the language to be used for the user interface. 选择用于用户界面的语言。 Language combo box 语言选择框 Selects the number of audio channels to be used for communication between client and server. There are three modes available: 设置用于连接客户端与服务器所要使用的声道数量。有三个模式可用: These modes use one and two audio channels respectively. 这些模式分别使用一个和两个声道。 Mono in/Stereo-out 单声道输入/立体声输出 The audio signal sent to the server is mono but the return signal is stereo. This is useful if the sound card has the instrument on one input channel and the microphone on the other. In that case the two input signals can be mixed to one mono channel but the server mix is heard in stereo. 发送到服务器的音频信号是单声道但接收到的是立体声。当您的声卡其中一个输入声道用于乐器而另一个用于麦克风的场景下很实用。在此情况下,两个输入信号可以合并为单声道但服务器混音仍可听到立体声。 Enabling 启用 In stereo streaming mode, no audio channel selection for the reverb effect will be available on the main window since the effect is applied to both channels in this case. 在立体声媒体流模式时,由于混响效果将被应用到所有的两个声道,故主窗口将不提供选择混响效果所应用到的声道的功能。 The higher the audio quality, the higher your audio stream's data rate. Make sure your upload rate does not exceed the available bandwidth of your internet connection. 音质越高,音频流带宽使用率也会越高。请确保您的上传速率未超过实际网络连接可用的带宽。 This setting defines the fader level of a newly connected client in percent. If a new client connects to the current server, they will get the specified initial fader level if no other fader level from a previous connection of that client was already stored. 此选项决定了新加入服务器的客户端的推子电平(音量)。若新的客户端连接到了当前服务器,若其未曾连接到此服务器并存储了其推子音量值,则其推子初始值将为此项所设置的值。 Input Boost 输入增强 This setting allows you to increase your input signal level by factors up to 10 (+20dB). If your sound is too quiet, first try to increase the level by getting closer to the microphone, adjusting your sound equipment or increasing levels in your operating system's input settings. Only if this fails, set a factor here. If your sound is too loud, sounds distorted and is clipping, this option will not help. Do not use it. The distortion will still be there. Instead, decrease your input level by getting farther away from your microphone, adjusting your sound equipment or by decreasing your operating system's input settings. 此选项允许你增加输入信号的强度最多十倍(+20dB)。若你的声卡音量过低,首先尝试通过将麦克风离近的方式提高音量,调整您的声音设备或者增加您的系统输入音量设定。若这些方法仍不奏效,则在此设置增加的强度。如果您的声卡音量过高,音频有失真或削波,则请不要使用此选项,此项无助于解决这些问题,相反,您应当考虑通过离远麦克风、降低声音设备的音量或降低系统输入音量设定的方式解决此问题。 Input Boost combo box 输入增强选择框 Audio Alerts 音频提示 Enable audio alert when receiving a chat message and when a new client joins the session. A second sound device may be required to hear the alerts. 当接收到聊天消息或新客户端加入到会话时启用音频提示。可能需要第二个音频设备以便听到对应的提示音。 Audio Alerts check box 音频提示勾选框 Bar (narrow) 窄条 Bar (wide) 条状 LEDs (stripe) 条纹 LED LEDs (round, small) 圆形小 LED LEDs (round, big) 圆形大 LED Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country or region you are located in. Your city and skill level playing your instrument may also be added. 在此填写您的名字或别名以便合奏的其他乐手知道您是谁。您也可以添加乐器的图片以及您所在国家或地区的旗帜。您还可以添加您的城市和水平程度的相关信息。 Country/region flag button 国家/地区旗帜按钮 Leave this blank unless you need to enter the address of a directory server other than the default. 若您不需要使用默认之外的目录服务器,则将此项置空。 Directory server address combo box 目录服务器地址下拉框 Number of Mixer Panel Rows 混音面板行数 Adjust the number of rows used to arrange the mixer panel. 调整用于呈现混音面板的行数。 Number of Mixer Panel Rows spin box 混音面板行数数字框 Feedback Protection 自激保护 Enable feedback protection to detect acoustic feedback between microphone and speakers. 启用自激保护以检测话筒和麦克风产生正反馈循环(自激)导致的啸叫。 Feedback Protection check box 自激保护勾选框 ASIO Device Settings ASIO 驱动设置 Low Normal 一般 High Fancy 精致 Compact 紧凑 LEDs LED Bar 条状 Narrow Bar 窄条 Round LEDs 圆形 LED Small LEDs 小 LED None preferred 偏好 Musician Profile 乐手信息 Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country you are located in. Your city and skill level playing your instrument may also be added. 在此填写您的名字或别名以便合奏的其他乐手知道您是谁。您也可以添加乐器的图片以及您所在地的旗帜。您还可以添加您的城市和水平程度的相关信息。 Alias or name edit box 名称或别名编辑框 Instrument picture button 乐器图片按钮 Country flag button 地区旗帜按钮 City edit box 城市编辑框 Skill level combo box 水平程度选择框 Beginner 新手 Intermediate 中级 Expert 专家 Size: 大小: Buffer Delay 缓冲区延迟 Buffer Delay: 缓冲区延迟: Center 中心 R Custom 自定义 Any Genre 2 任何流派 2 Any Genre 3 任何流派 3 Genre Rock 摇滚流派 Genre Jazz 爵士流派 Genre Classical/Folk 古典/民间流派 Genre Choral/Barbershop 唱诗/合唱流派 Any Genre 1 任何流派 1 Drum Set 组鼓 Djembe 非洲鼓 Electric Guitar 电吉他 Acoustic Guitar 原声吉他 Bass Guitar 贝斯 Keyboard 键盘手 Synthesizer 合成器 Grand Piano 大钢琴 Accordion 手风琴 Vocal 歌手 Microphone 麦克风 Harmonica 口琴 Trumpet 小号 Trombone 长号 French Horn 圆号 Tuba 大号 Saxophone 萨克斯 Clarinet 单簧管 Flute 长笛 Violin 小提琴 Cello 大提琴 Double Bass 低音提琴 Recorder 录音员 Streamer 直播推流员 Listener 听众 Guitar+Vocal 吉他弹唱 Keyboard+Vocal 键盘手弹唱 Bodhran 宝思兰鼓 Bassoon 大管 Oboe 双簧管 Harp 竖琴 Viola 中提琴 Congas 康茄鼓 Bongo 邦戈鼓 Vocal Bass 男低音 Vocal Tenor 男高音 Vocal Alto 女低音 Vocal Soprano 女高音 Banjo 班卓琴 Mandolin 曼陀林 Ukulele 尤克里里 Bass Ukulele 贝斯尤克里里 Vocal Baritone 男中音 Vocal Lead 领唱 Mountain Dulcimer 扬琴 Scratching 打碟 Rapping 饶舌歌手 Vibraphone 铁琴 Conductor 指挥 CClientSettingsDlgBase Settings 设置 Device 设备 Input Channel Mapping 输入声道映射 L R Output Channel Mapping 输出声道映射 Enable Small Network Buffers 启用小网络缓冲区 Buffer Delay 缓冲区延迟 Country/Region 国家/地区 (preferred) (偏好) (default) (默认) (safe) (安全) Driver Setup 驱动选项 My Profile 我的信息 Musician's Profile 乐手信息 Alias/Name 别名/名称 Instrument 乐器 Country 国家或地区 City 城市 Skill 水平 User Interface 用户界面 Meter Style 计量表样式 Mixer Rows 混音器行数 Audio Alerts 音频提示 Audio/Network Setup 音频/网络选项 Audio Device 音频设备 Jitter Buffer 抖动缓冲 Auto 自动 Local 本地 Server 服务器 Size 大小 kbps kbps Custom Directories: 自定义目录: Input Boost 输入增强 Feedback Protection 自激保护 Enable 启用 Input Balance 输入平衡 Pan 左右平衡 Center 中心 Audio Channels 音频通道 Audio Quality 音频质量 Advanced Setup 高级选项 New Client Level 新客户端音量 Skin 皮肤 Language 语言(Lang) % % Custom Directory Server Address: 自定义目录服务器地址: Audio Stream Rate 音频流速度 val CConnectDlg Directory 分类目录 Shows the servers listed by the selected directory. You can add custom directories in Advanced Settings. 根据所选分类目录展示服务器列表。您可以在高级选项中添加自定义的分类目录。 Directory combo box 分类目录下拉框 Filters the server list by the given text. Note that the filter is case insensitive. A single # character will filter for those servers with at least one person connected. 根据给定文字过滤服务器列表。请注意过滤文字并非大小写敏感的。使用单 # 字符以过滤展示至少有一个人连接到的服务器。 Uncheck to collapse the server list to show just the server details. Check to show everyone on the servers. 取消勾选以收起服务器列表来仅展示服务器信息。勾选以展示加入对应服务器的所有用户。 Server List 服务器列表 The Connection Setup window lists the available servers registered with the selected directory. Use the Directory dropdown to change the directory, find the server you want to join in the server list, click on it, and then click the Connect button to connect. Alternatively, double click on the server name to connect. 连接配置窗口列出了所选的分类目录下可供使用的服务器列表。使用分类目录下拉框来选择分类目录,在服务器列表中找到您想要加入的服务器,点击选中它,然后点击“连接”按钮以进行连接。或者,您也可以双击服务器名称来进行连接。 Permanent servers (those that have been listed for longer than 48 hours) are shown in bold. 永久服务器(指在服务器列表中存在超过 48 小时的服务器)会以粗体标识。 You can add custom directories in Advanced Settings. 您可以在高级设置中添加自定义的分类目录项。 Server list view 服务器列表视图 Server Address 服务器地址 If you know the server address, you can connect to it using the Server name/Address field. An optional port number can be added after the server address using a colon as a separator, e.g. %1. The field will also show a list of the most recently used server addresses. 如果你知道服务器地址,你可以使用服务器名称/地址一栏来连接到对应的服务器。一个可选的端口号可以附在后面,通过半角冒号作为分割符。例如:%1。此位置也将显示一个最近使用过的服务器地址的列表。 Holds the current server address. It also stores old addresses in the combo box list. 存储了当前服务器地址。在下拉列表中,也存储了旧的服务器地址列表。 The Connection Setup window shows a list of available servers. Server operators can optionally list their servers by music genre. Use the List dropdown to select a genre, click on the server you want to join and press the Connect button to connect to it. Alternatively, double click on on the server name. Permanent servers (those that have been listed for longer than 48 hours) are shown in bold. 连接配置窗口展示了所有可用服务器的列表。服务器管理员可以选择其服务器对应的流派分类。使用下拉列表选择流派,点击想要加入的服务器并点击连接按钮以连接到对应的服务器。您也可以双击服务器名称来进行连接。永久(已在列表中存在超过 48 小时的)服务器将以粗体展示。 If you know the IP address or URL of a server, you can connect to it using the Server name/Address field. An optional port number can be added after the IP address or URL using a colon as a separator, e.g. example.org: 如果您知道某个服务器的 IP 地址或 URL,您可以使用“服务器名称/地址”栏来连接到对应的服务器。在 IP 或 URL 后端可以可选的填写端口号,使用半角冒号进行隔开。例如:example.org: . The field will also show a list of the most recently used server addresses. 。此栏也会展示最近连接过的服务器地址的列表。 Server address edit box 服务器地址编辑框 Holds the current server IP address or URL. It also stores old URLs in the combo box list. 存储了当前服务器的 IP 或 URL。他也在下拉列表中存储了旧的 URL 列表。 Server List Selection 服务器列表选择框 Selects the server list to be shown. 选择希望出现在的服务器列表。 Server list selection combo box 服务器列表单选框 Filter 筛选器 The server list is filtered by the given text. Note that the filter is case insensitive. 服务器列表将会根据输入的文字进行筛选。注意筛选词对大小写不敏感。 Filter edit box 过滤器输入框 Show All Musicians 显示所有乐手 If you check this check box, the musicians of all servers are shown. If you uncheck the check box, all list view items are collapsed. 如果勾选了此勾选框,将展示所有服务器内的乐手。如果取消勾选,所有项将会被折叠。 Show all musicians check box 显示所有乐手勾选框 If you know the IP address or URL of a server, you can connect to it using the Server name/Address field. An optional port number can be added after the IP address or URL using a colon as a separator, e.g. %1. The field will also show a list of the most recently used server addresses. 如果您知道某个服务器的 IP 地址或 URL,您可以使用“服务器名称/地址”栏来连接到对应的服务器。在 IP 或 URL 后端可以可选的填写端口号,使用半角冒号进行隔开。例如:%1。此栏也将显示最近使用过的服务器地址列表。 Filter text, or # for occupied servers 过滤文字,或使用 # 选择使用的服务器 CConnectDlgBase Connection Setup 连接配置 List 列表 Directory 分类目录 Filter 过滤器 Show All Musicians 显示所有乐手 Server Name 服务器名称 Ping Time Ping 延迟 Musicians 音乐家们 Location 位置 Server Address 服务器地址 C&ancel 取消(&A) &Connect 连接(&C) CHelpMenu &Help 帮助(&H) Getting &Started... 入门(&S)... Software &Manual... 软件说明书(&M)... What's &This 这是什么(&T) &About Jamulus... 关于 Jamulus(&A)... About &Qt... 关于 &Qt... About Qt 关于 Qt CLanguageComboBox Restart Required 需要重启 Please restart the application for the language change to take effect. 请重启应用程序以使语言变更生效. CLicenceDlg This server requires you accept conditions before you can join. Please read these in the chat window. 此服务器需要你同意一些条件才可加入。请阅读聊天窗口中的内容。 I have read the conditions and &agree. 我已阅读并同意这些条件(&A)。 Accept 接受 Decline 拒绝 CMultiColorLED Red Yellow Green 绿 CMusProfDlg No Name 无名称 CServerDlg Client List 客户端列表 The client list shows all clients which are currently connected to this server. Some information about the clients like the IP address and name are given for each connected client. 客户端列表显示了所有连接到此服务器的客户端。例如 IP 地址和名称等信息由各个客户端提供。 Connected clients list view 已连接的客户端列表视图 Start Minimized on Operating System Start 操作系统启动时以最小化状态启动 Make My Server Public 将我的服务器置为公开 Register Server Status 登记服务器状态 If the start minimized on operating system start check box is checked, the server will be started when the operating system starts up and is automatically minimized to a system task bar icon. 如果选中了操作系统启动时以最小化状态启动勾选框,服务器程序将随操作系统启动时自动启动并最小化至系统任务栏。 If the Make My Server Public check box is checked, this server registers itself at the directory server so that all users of the application can see the server in the connect dialog server list and connect to it. The registration of the server is renewed periodically to make sure that all servers in the connect dialog server list are actually available. 如果勾选了将我的服务器置为公开勾选框,此服务器将在目录服务器中登记自身使得此程序的所有的用户均可在连接对话框中查看和连接到此服务器。服务器登记情况会自动刷新以确保所有所有在服务器列表中列出的服务器均实际可用。 If the Make My Server Public check box is checked, this will show whether registration with the directory server is successful. If the registration failed, please choose another server list. 如果勾选了将我的服务器置为公开勾选框,此处将显示关于服务器是否已成功登记的状态。若登记失败,请选择其它服务器列表。 Custom Directory Server Address 自定义目录服务器地址 The custom directory server address is the IP address or URL of the directory server at which the server list of the connection dialog is managed. 自定义目录服务器地址是希望从其获取可用服务器列表信息的目录服务器的 IP 或 URL。 Directory server address line edit 目录服务器地址输入框 Server List Selection 服务器列表选择框 Selects the server list (i.e. directory server address) in which your server will be added. 选择要将您的服务器添加到的服务器列表(即目录服务器地址)。 Server list selection combo box 服务器列表下拉框 Server Name 服务器名称 The server name identifies your server in the connect dialog server list at the clients. 服务器名称在客户端的连接对话框的服务器列表中对应服务器的显示标识。 Server name line edit 服务器名称编辑框 Location City 所处城市 The city in which this server is located can be set here. If a city name is entered, it will be shown in the connect dialog server list at the clients. 设置服务器所处于的城市。如果输入了城市名称,其将被显示在客户端的连接对话框的服务器列表中。 City where the server is located line edit 服务器所位于的城市的编辑框 Recording has been switched off by the UI checkbox. 录制已通过界面的勾选框关闭。 Recording has been switched off, either by the UI checkbox or SIGUSR2 being received. 录制已因界面的勾选框或因程序收到 SIGUSR2 信号而关闭。 Language 语言(Lang) Select the language to be used for the user interface. 选择用于用户界面的语言。 Language combo box 语言选择框 Display dialog to select recording directory button 打开可供选择录制存储位置的对话框的按钮 Main Recording Directory 主要录制目录 Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user Jamulus is running as). 点击按钮以打开供选择主要录制目录路径的对话框。所选值必须存在且可写(允许运行 Jamulus 所使用的用户创建子目录)。 Main recording directory text box (read-only) 主录制路径文本框(只读) The current value of the main recording directory. The chosen value must exist and be writeable (allow creation of sub-directories by the user Jamulus is running as). Click the button to open the dialog that allows the main recording directory to be selected. 当前录制目录路径的值。所选的值必须存在且可被写入(允许运行 Jamulus 的用户创建子目录)。点击按钮以打开供选择主录制目录路径的对话框。 Clear the recording directory button 清除录制目录按钮 Clear Recording Directory 清除录制目录 Click the button to clear the currently selected recording directory. This will prevent recording until a new value is selected. 点击按钮以清除当前所选择的录制路径。在设置新的位置之前将不再可以开始新的录制。 Checkbox to turn on or off server recording 开启或关闭录制的勾选框 If the Register Server check box is checked, this will show whether registration with the directory server is successful. If the registration failed, please choose another server list. 如果登记服务器勾选框被勾选,这里将展示到目录服务器的登记是否成功。若登记失败,请选择其它服务器列表。 Enable Recorder 启用录音器 Checked when the recorder is enabled, otherwise unchecked. The recorder will run when a session is in progress, if (set up correctly and) enabled. 录音功能启用时将为勾选状态,否则为未勾选状态。若已配置并开启选项,则录音功能将在会话进行中开启录制。 Current session directory text box (read-only) 当前会话目录文本框(只读) Current Session Directory 当前会话目录 Enabled during recording and holds the current recording session directory. Disabled after recording or when the recorder is not enabled. 这句话原文可能有问题 用于存储录制时当前会话所录制到的位置,录制未进行时且未开启录制功能时此项将不可用。 Recorder status label 录制状态标签 Recorder Status 录音器状态 Displays the current status of the recorder. The following values are possible: 显示当前录音功能的状态。 可能为下述值: No recording directory has been set or the value is not useable. 没有设置录制目录或填写的路径不可用 Recording has been switched off 录制已被关闭 There is no one connected to the server to record. 没有人连接到服务器以供录制。 The performers are being recorded to the specified session directory. 演奏已被录制到会话所对应的目录中。 NOTE 注意 If the recording directory is not useable, the problem will be displayed in place of the directory. 若录制路径不可用,则问题原因将显示在这里。 Server welcome message edit box 服务器欢迎信息编辑框 Server Welcome Message 服务器欢迎信息 A server welcome message text is displayed in the chat window if a musician enters the server. If no message is set, the server welcome is disabled. 当新的乐手加入服务器时,欢迎信息将会显示在聊天窗口中。若未设置欢迎信息,则服务器欢迎功能将为关闭状态。 Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user Jamulus is running as). 点击按钮以打开可供选择录制目录位置的对话框。 所选值必须存在且可写入(允许运行 Jamulus 的用户创建子目录)。 Custom Directory 自定义目录 The custom directory is the IP address or URL of the directory server at which the server list of the connection dialog is managed. 自定义目录指用于提供连接对话框中所展示的服务器列表信息的自定义的目录服务器的 IP 地址或 URL。 Custom Directory line edit 自定义目录编辑框 &Hide %1 server 隐藏 %1 服务器(&H) &Show %1 server 显示 %1 服务器(&S) %1 server %1 is the name of the main application %1 服务器 Type a message here. If no message is set, the server welcome is disabled. 在此输入消息文字。若未设定消息文字,服务器欢迎信息将为关闭状态。 %1 Server %1 is the name of the main application %1 服务器 software upgrade available 软件更新可用 Recorder failed to start. Please check available disk space and permissions and try again. Error: 录音功能启动失败。请检查可用的磁盘空间和权限然后再试一次。错误信息: ERROR 错误 Request new recording button 用于创建新的录制的按钮 Directory Type combo box 分类目录类型下拉框 Directory 分类目录 Select '%1' not to register your server with a directory. 选择 '%1' 来避免将你的服务器登记到一个目录中。 Select one of the genres to register with that directory. 选择一个流派以登记到对应的目录中。 Or select '%1' and specify a Custom Directory address on the Options tab to register with a custom directory. 或者选择 '%1' 并在设置选项卡中设置一个自定义目录地址来登记到一个自定义的目录中。 For any value except '%1', this server registers with a directory so that a %2 user can select this server in the client connect dialog server list when they choose that directory. 对于选择除 '%1' 外的所有情况,此服务器都将登记到一个目录之中,以便 %2 用户可以从客户端的连接对话框中的服务器列表中选择并连接到此服务器。 The registration of the server is renewed periodically to make sure that all servers in the connect dialog server list are actually available. 服务器的登记情况会周期性的刷新,以确保连接对话框中列出的服务器都确实可用。 When a value other than "%1" is chosen for Directory, this will show whether registration is successful. If the registration failed, please choose a different directory. 当一个非“%1”的选项被作为目录选择时,此处将呈现登记情况是否成功的状态。若登记失败,则请选择一个其它的目录。 Country/Region 国家/地区 Set the country or region where the server is running. Clients will show this location in their connect dialog's server list. 设置当前服务器所位于的国家或地区。客户端将在服务器列表对话框中展示此位置信息。 Combo box for location of this server 服务器位置的选择框 New Recording 创建新录制 During a recording session, the button can be used to start a new recording. 在一次录制会话中,此按钮可供开始新的录制。 No recording directory has been set or the value is not useable. Check the value in the Options tab. 未设置录音目录或设置的值不可用。请在设置选项卡中检查对应的选项。 If the recording directory is not useable, the problem will be displayed in place of the session directory. 如果录制目录不可用,问题将会被显示在此位置。 Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user %1 is running as). 点击按钮以打开可供选择录制目录位置的对话框。 所选值必须存在且可写入(允许运行 %1 的用户创建子目录)。 The current value of the main recording directory. The chosen value must exist and be writeable (allow creation of sub-directories by the user %1 is running as). Click the button to open the dialog that allows the main recording directory to be selected. 当前录制目录路径的值。所选的值必须存在且可被写入(允许运行 %1 的用户创建子目录)。点击按钮以打开供选择主录制目录路径的对话框。 Custom Directory address 自定义目录服务器地址 The Custom Directory address is the address of the directory holding the server list to which this server should be added. 自定义目录指用于提供连接对话框中所展示的服务器列表信息的自定义的目录服务器的地址或。 Server List Filename dialog push button 服务器列表文件名对话框按钮 Server List Filename 服务器列表文件名 Click the button to open the dialog that allows the server list persistence file name to be set. The user %1 is running as needs to be able to create the file name specified although it may already exist (it will get overwritten on save). 点击按钮以打开供选择存储服务器列表文件位置的对话框。运行 %1 的用户需要能够能够创建此文件(若对应的文件已存在则将在保存时覆盖文件内容)。 Server List Filename text box (read-only) 服务器列表文件名编辑框(只读) The current value of server list persistence file name. The user %1 is running as needs to be able to create the file name specified although it may already exist (it will get overwritten on save). Click the button to open the dialog that allows the server list persistence file name to be set. 当前持久存储服务器列表的文件名。运行 %1 的用户需要能够能够创建此文件(若对应的文件已存在则将在保存时覆盖文件内容)。点击按钮以打开可供设置持久存储服务器列表的文件名的对话框。 Clear the server list file name button 清除服务器列表文件名的按钮 Clear Server List Filename 清除服务器列表文件名 Click the button to clear the currently selected server list persistence file name. This will prevent persisting the server list until a new value is selected. 点击按钮来清除当前所选的服务器列表持久化存储的文件名。这将导致服务器列表不再持久存储到本地,直至一个新的文件名被设置。 E&xit 退出(&E) Now a directory 现在是目录了 &Hide 隐藏(&H) server 服务器 &Open 打开(&O) Server 服务器 &Window 窗口(&W) Select Main Recording Directory 选择录制存储位置 Recording 录制中 Not recording 未在录制 Not initialised 未初始化 Not enabled 未启用 Unregistered 未登记 None Not registered 未登记 Bad address 地址不正确 Registration requested 已请求登记 Registration failed 登记失败 Check server version 检查服务器版本 Registered 已登记 Directory server list full 目录服务器列表已满 Directory Server full 目录列表已满 Your server version is too old 您的服务端版本过低 Requirements not fulfilled 要求未满足 Unknown value %1 未知的值 %1 Unknown value 未知值 CServerDlgBase Client IP:Port 客户端 IP:端口 Name 名称 Jitter Buffer Size 抖动缓冲区大小 Channels 通道 Server Setup 服务器选项 List 分类列表 Location: Region 位置:地区 Session 会话 Chat Window Welcome (HTML/CSS Supported) 聊天窗口欢迎信息(支持 HTML/CSS) Options 选项 Custom Directory address 自定义目录服务器地址 Server List Filename 服务器列表文件名 Start Minimized on Windows Start 随 Windows 启动时最小化启动 Enable delay panning 启用延迟平衡 Update check 检查更新 Make My Server Public (Register My Server in the Server List) 将我的服务器置为公开(在服务器列表中登记我的服务器) STATUS 状态 Custom Directory Server Address: 自定义目录服务器地址: Recording Directory 录音存储目录 Enable Jam Recorder 启用合奏录音机 Directory 分类目录 New Recording 创建新录制 Language Consider add "(Lang)" as a suffix to ensure that users who selected the wrong language find the correct button 语言(Lang) My Server Info 我的服务器信息 Location: City 位置:城市 CServerListManager Could not write to '%1' 不能写入到 '%1' CSound Error requesting stream stop: $s 请求流停止时遇到错误: $s Error closing stream: $s 关闭流时遇到错误: $s The Jack port registering failed. Jack 端口注册失败. Required audio sample format not available. 需要的音频采样格式不可用. The selected audio device is no longer present in the system. Please check your audio device. 所选的音频设备已不存在于您的系统中。请检查您的音频设备。 Couldn't initialise the audio driver. Check if your audio hardware is plugged in and verify your driver settings. 无法初始化音频驱动。请检查您的音频硬件设备是否已经插入并检查您的驱动设定。 The selected audio device is incompatible since it doesn't support a sample rate of %1 Hz. Please select another device. 由于所选的音频设备不支持于采样率 %1 Hz 下工作,故其处于不兼容状态。请选择其它设备。 The current audio device configuration is incompatible because the sample rate couldn't be set to %2 Hz. Please check for a hardware switch or driver setting to set the sample rate manually and restart %1. 由于采样率无法被设置到 %2 Hz,故当前音频设备选项不兼容。请检查硬件上的开关或驱动设定,手动设置其采样率并重启 %1。 The selected audio device is incompatible since it doesn't support %1 in/out channels. Please select another device or configuration. 由于所选的音频设备不支持 %1 声道输入/输出,故其处于不兼容状态。请选择其它设备或配置。 The selected audio device is incompatible since the required audio sample format isn't available. Please use another device. 由于所需的采样格式不可用,故当前所选的音频设备处于不兼容状态。请使用其它设备。 No ASIO audio device driver found. 未发现 ASIO 音频设备驱动. Please install an ASIO driver before running %1. If you own a device with ASIO support, install its official ASIO driver. If not, you'll need to install a universal driver like ASIO4ALL. 请在运行 %1 前安装 ASIO 驱动。如果您由一个受 ASIO 支持的设备,请安装其官方 ASIO 驱动。若没有,您需要安装一个通用的驱动,如 ASIO4ALL。 Please install an ASIO driver before running %1. If you own a device with ASIO support, install its official ASIO driver. If not, you'll need to download and install a universal driver like ASIO4ALL. 请在运行 %1 前安装 ASIO 驱动。若您拥有支持 ASIO 的设备,则安装其官方 ASIO 驱动。若没有,您将需要下载安装一个通用的驱动(例如 ASIO4ALL)。 JACK couldn't be started automatically. Please start JACK manually and check for error messages. JACK 未能自动启动。请手动启动 JACK 并检查错误信息。 JACK isn't running at a sample rate of <b>%1 Hz</b>. Please use a tool like <i><a href="https://qjackctl.sourceforge.io">QjackCtl</a></i> to set the the JACK sample rate to %1 Hz. JACK 未在采样率 <b>%1 Hz</b> 下运行。请使用例如 <i><a href="https://qjackctl.sourceforge.io">QjackCtl</a></i> 的工具将 JACK 配置到 %1 Hz。 The JACK port registration failed. This is probably an error with JACK. Please stop %1 and JACK. Afterwards check if another program at a sample rate of %2 Hz can connect to JACK. JACK 端口注册失败。这可能是由于 JACK 的错误所至。请停止运行 %1 和 JACK。然后就检查使用采样率 %2 的其它程序是否可以连接到 JACK。 The JACK port registration failed. This is probably an error with JACK. Please stop %1 and JACK. Afterwards, check if another MIDI program can connect to JACK. JACK 端口注册失败。这可能是由于 JACK 的错误所至。请停止运行 %1 和 JACK。然后就检查其它 MIDI 程序是否可以连接到 JACK。 Can't activate the JACK client. This is probably an error with JACK. Please check the JACK output. 无法启用 JACK 客户端。这可能是由于 JACK 的错误所至。请检查 JACK 输出。 JACK was shut down. %1 requires JACK to run. Please restart %1 to start JACK again. JACK 为停止状态。%1 需要 JACK 才能运行。请重启 %1 来再次启动 JACK。 No sound card is available in your system. CoreAudio input AudioHardwareGetProperty call failed. 您的系统中没有声卡可用。CoreAudio 输入 AudioHardwareGetProperty 调用失败。 No sound card is available in the system. CoreAudio output AudioHardwareGetProperty call failed. 您的系统中没有声卡可用。CoreAudio 输入 AudioHardwareGetProperty 调用失败。 The currently selected audio device is no longer present. Please check your audio device. 当前所选的音频设备已不存在。请检查您的音频设备。 The audio input device is no longer available. Please check if your input device is connected correctly. 音频输入设备已不再可用。请检查您的音频输入设备是否已正确连接。 The sample rate on the current input device isn't %1 Hz and is therefore incompatible. Please select another device or try setting the sample rate to %1 Hz manually via Audio-MIDI-Setup (in Applications->Utilities). 当前输入设备的采样率并非 %1 Hz,故不兼容。请选择其它设备或尝试通过 音频-MIDI-选项(位于 应用程序>辅助功能)手动设定其采样率到 %1 Hz。 The audio output device is no longer available. Please check if your output device is connected correctly. 音频输出设备不再可用。请检查您的输出设备是否已正确连接。 The sample rate on the current output device isn't %1 Hz and is therefore incompatible. Please select another device or try setting the sample rate to %1 Hz manually via Audio-MIDI-Setup (in Applications->Utilities). 当前输出设备的采样率并非 %1 Hz,故不兼容。请选择其它设备或尝试通过 音频-MIDI-选项(位于 应用程序>辅助功能)手动设定其采样率到 %1 Hz。 The stream format on the current input device isn't compatible with this software. Please select another device. 当前输入设备的媒体流格式与此软件不兼容。请选择其它设备。 The stream format on the current output device isn't compatible with %1. Please select another device. 当前输出设备的媒体流格式与 %1 不兼容。请选择其它设备。 The buffer sizes of the current input and output audio device can't be set to a common value. Please select different input/output devices in your system settings. 当前音频输入输出设备的缓冲区大小无法被设定到一个常见的值。请在您的系统设置中选择其它的输入/输出设备。 CSoundBase Can't use the selected audio device because of the following error: %1 The previous driver will be selected. 由于以下原因,无法使用所选的音频设备:%1 将会使用之前的设备。 The previously selected audio device is no longer available or the driver has changed to an incompatible state. We'll attempt to find a valid audio device, but this new audio device may cause feedback. Before connecting to a server, please check your audio device settings. 之前所选的音频设备已不再可用或现处于不兼容的状态。我们将尝试寻找一个有效的音频设备,但新的设备可能会产生自激。在连接刀服务器前,请考虑检查您的音频设备设置项。 <b>%1 couldn't find a usable %2 audio device.</b><br><br> <b>%1 未发现可用的 %2 音频设备。</b><br><br> You may be able to fix errors in the driver settings. Do you want to open these settings now? 您可能可通过驱动设置来修复问题。要打开对应的设置吗? No usable %1 audio device found. 未发现可用的 %1 音频设备。 These are all the available drivers with error messages: 以下为所有可用的驱动和错误信息: Do you want to open the ASIO driver setup to try changing your configuration to a working state? 您想要打开 ASIO 驱动向导并尝试修改您的配置以达到可用状态吗? Can't start %1. Please restart %1 and check/reconfigure your audio settings. 无法启动 %1。请重启 %1 并检查/重新配置您的音频设置选项。 audio device (driver) found. 发现音频设备(驱动). QCoreApplication %1, Version %2 %1,版本 %2 Internet Jam Session Software 网络合奏软件 %1, Version %2 %1 is app name, %2 is version number %1,版本 %2 Released under the GNU General Public License version 2 or later (GPLv2) 使用 GNU 通用许可证第2版或更高版本发布 (GPLv2) This program is free software; you can redistribute it and/or modify it under 此程序是自由软件;您可以修改或重分发此程序,只要您遵守 the terms of the GNU General Public License as published by the Free Software 由自由软件基金会发布的 GNU 通用许可证的条款 Foundation; either version 2 of the License, or (at your option) any later version. 无论您依据的是本授权的第 2 版,或(您可选的)任一日后发行的版本。 There is NO WARRANTY, to the extent permitted by law. 在法律允许的范围内,不提供任何担保。 Using the following libraries, resources or code snippets: 使用了下述程序库、资源或代码片段: Qt framework Qt 应用程序框架 Opus Interactive Audio Codec Opus Interactive Audio Codec Audio reverberation code by Perry R. Cook and Gary P. Scavone 音频混响代码作者为 Perry R. Cook 和 Gary P. Scavone Some pixmaps are from the Open Clip Art Library (OCAL) 部分位图资源来自 Open Clip Art Library (OCAL) Flag icons by Mark James 旗帜图标作者为 Mark James Copyright (C) 2005-2022 The Jamulus Development Team 版权所有 (C) 2005-2022 Jamulus 开发团队 Released under the GNU General Public License (GPL) 使用 GNU 通用许可证发布 global A %1 upgrade is available: <a style='color:red;' href='https://jamulus.io/upgrade?progversion=%2'>go to details and downloads</a> %1 更新已可用:<a style='color:red;' href='https://jamulus.io/upgrade?progversion=%2'>前往详情和下载页面</a> For more information use the "What's This" help (help menu, right mouse button or Shift+F1) 更多信息请通过“这是什么”查阅(帮助菜单,鼠标右键或 Shift+F1) jamulus-3.9.1+dfsg/src/translation/translation_ko_KR.ts0000644000175000017500000067746714340334543022327 0ustar vimervimer CAboutDlg Qt cross-platform application framework Qt 크로스 플랫폼 애플리케이션 프레임워크 Audio reverberation code by Perry R. Cook and Gary P. Scavone Perry R. Cook 및 Gary P. Scavone의 오디오 잔향 코드 Some pixmaps are from the 일부 픽스 맵은 This app enables musicians to perform real-time jam sessions over the internet. 이 앱을 통해 뮤지션이 인터넷으로 실시간 잼 세션을 할 수 있습니다. There is a server which collects the audio data from each client, mixes the audio data and sends the mix back to each client. 각 클라이언트에서 오디오 데이터를 수집하고 오디오 데이터를 믹싱하고 믹스를 다시 각 클라이언트로 보내는 서버가 있습니다. This app uses the following libraries, resources or code snippets: 이 앱은 다음의 라이브러리, 리소스 또는 코드 스니펫을 사용합니다: Country flag icons by Mark James 국기 아이콘 by Mark James For details on the contributions check out the 기여에 대한 자세한 내용은 다음을 확인하세요 Flag icons by Mark James 깃발 아이콘 by Mark James Some sound samples are from 일부 사운드 샘플은 For details on the contributions check out the %1 기여에 대한 자세한 내용은 %1에서 확인하세요 Github Contributors list Github 기여자 목록 Spanish 스페인어 French 프랑스어 Portuguese 포르투갈어 Dutch 네델란드어 Italian 이태리어 German 독일어 Polish 폴란드어 Swedish 스웨덴어 Korean 한국어 Slovak 슬로바키아어 Simplified Chinese 중국어 간체 Norwegian Bokmål About %1 %1 정보 About 정보 CAboutDlgBase About 정보 TextLabelVersion 텍스트 레이블 버전 Copyright (C) 2005-2022 The Jamulus Development Team 저작권 (C) 2005-2022 Jamulus 개발 팀 A&bout 정보(&B) &Libraries 라이브러리(&L) &Contributors 기여자(&C) &Translation 번역(&T) &OK 확인(&O) CAnalyzerConsole Analyzer Console 애널라이저 콘솔 Error Rate of Each Buffer Size 각 버퍼 크기의 오류 비율 CAudioMixerBoard Personal Mix at the Server 서버에서 개인 믹싱하기 When connected to a server, the controls here allow you to set your local mix without affecting what others hear from you. The title shows the server name and, when known, whether it is actively recording. 서버에 연결했을 때, 여기의 컨트롤을 사용하여 다른 사람이 듣는 내용에 영향을 주지 않고 로컬 믹스를 설정할 수 있습니다. 제목에는 서버 이름이 표시되며, 현재 녹화 중 인지 여부가 표시됩니다. Server 서버 T R Y I N G T O C O N N E C T 연결하고 있습니다 RECORDING ACTIVE 녹음 중 Personal Mix at: %1 개인 믹싱: %1 CChannelFader Channel Level 채널 레벨 Input level of the current audio channel at the server 서버에서 현재 오디오 채널의 입력 레벨 Mixer Fader 믹서 페이더 Local mix level setting of the current audio channel at the server 서버에서 현재 오디오 채널의 로컬 믹스 레벨 설정 Status Indicator 상태 표시기 Shows a status indication about the client which is assigned to this channel. Supported indicators are: 이 채널에 할당된 클라이언트에 대한 상태 표시를 표시합니다. 지원하는 지표: Status indicator label 상태 표시기 레이블 Panning 패닝 Local panning position of the current audio channel at the server 서버에서 현재 오디오 채널의 로컬 패닝 위치 With the Mute checkbox, the audio channel can be muted. 음소거 확인란을 사용하여 오디오 채널을 음소거할 수 있습니다. Mute button 음소거 버튼 Solo button 솔로 버튼 Fader Tag 페이더 태그 The fader tag identifies the connected client. The tag name, a picture of your instrument and the flag of your location can be set in the main window. 페이더 태그는 연결된 클라이언트를 식별합니다. 태그 이름, 악기 사진 및 위치 깃발을 기본 창에서 설정할 수 있습니다. Mixer channel country/region flag 믹서 채널 국가/지역 깃발 Grp Grp Displays the pre-fader audio level of this channel. All clients connected to the server will be assigned an audio level, the same value for every client. 이 채널의 프리 페이더 오디오 레벨을 표시합니다. 서버에 연결된 모든 클라이언트에는 모든 클라이언트에 대해 동일한 오디오 레벨이 할당됩니다. &No grouping 그룹화 없음(&N) Assign to group 그룹에 할당 Adjusts the audio level of this channel. All clients connected to the server will be assigned an audio fader, displayed at each client, to adjust the local mix. 이 채널의 오디오 레벨을 조정합니다. 서버에 연결된 모든 클라이언트에는 로컬 믹스를 조정하기 위해 각 클라이언트에 표시되는 오디오 페이더가 할당됩니다. Speaker with cancellation stroke: Indicates that another client has muted you. 취소 스트로크가 있는 스피커: 다른 클라이언트가 사용자를 음소거했음을 나타냅니다. Sets the pan from Left to Right of the channel. Works only in stereo or preferably mono in/stereo out mode. 채널의 왼쪽에서 오른쪽으로 팬을 설정합니다. 스테레오 또는 가급적이면 모노 입력/스테레오 출력 모드에서만 작동합니다. With the Solo checkbox, the audio channel can be set to solo which means that all other channels except the soloed channel are muted. It is possible to set more than one channel to solo. 솔로 확인란을 사용하여 오디오 채널을 솔로로 설정할 수 있습니다. 즉, 솔로 채널을 제외한 다른 모든 채널이 음소거됩니다. 한 개 이상의 채널을 솔로로 설정할 수 있습니다. Group 그룹 With the Grp checkbox, a group of audio channels can be defined. All channel faders in a group are moved in proportional synchronization if any one of the group faders are moved. Grp 확인란을 사용하여 오디오 채널 그룹을 정의할 수 있습니다. 그룹 페이더 중 하나가 이동되면 그룹의 모든 채널 페이더가 비례 동기화로 이동됩니다. Group button 그룹 버튼 The fader tag identifies the connected client. The tag name, a picture of your instrument and the flag of your country can be set in the main window. 페이더 태그는 연결된 클라이언트를 식별합니다. 태그 이름, 악기 사진 및 국가의 국기를 메인 창에서 설정할 수 있습니다. Mixer channel instrument picture 믹서 채널 악기 사진 Mixer channel label (fader tag) 믹서 채널 레이블 (페이더 태그) Mixer channel country flag 믹서 채널 국기 PAN PAN MUTE MUTE SOLO SOLO GRP GRP M M S S G G Alias/Name 가명/이름 Instrument 악기 Location 위치 Skill Level 스킬 레벨 Alias 가명 Beginner 초보 Intermediate 중급 Expert 전문가 Musician Profile 뮤지션 프로필 Mute 음소거 Pan Solo 솔로 CChatDlg Chat Window 채팅 창 The chat window shows a history of all chat messages. 채팅 창에는 모든 채팅 메시지 기록을 보여줍니다. Chat history 채팅 기록 Input Message Text 메시지 입력 Enter the chat message text in the edit box and press enter to send the message to the server which distributes the message to all connected clients. Your message will then show up in the chat window. 편집 박스에 채팅 메시지를 입력하고 Enter 키를 누르면 연결된 모든 클라이언트에 메시지를 배포하는 서버로 메시지를 보냅니다. 그러면 메시지가 채팅 창에 표시됩니다. New chat text edit box 새로운 채팅 텍스트 편집 박스 Type a message here 메시지를 이곳에 입력하세요 &Edit 편집(&E) Cl&ear Chat History 채팅 기록 비우기(&E) &Close 닫기(&C) Do you want to open the link '%1' in your browser? 브라우저에서 '%1'링크를 여시겠습니까? Do you want to open the link 외부 브라우저에서 in an external browser? 링크를 여시겠습니까? CChatDlgBase Chat 채팅 &Send 보내기(&S) CClientDlg Input Level Meter 레벨 미터 입력 Make sure not to clip the input signal to avoid distortions of the audio signal. 오디오 신호의 왜곡을 방지하기 위해 입력 신호를 클리핑하지 않도록 하세요. Input level meter 레벨 미터 입력 Simulates an analog LED level meter. 아날로그 LED 레벨 미터를 시뮬레이션합니다. Connect/Disconnect Button 연결/해제 버튼 Connect and disconnect toggle button 연결 및 해제 토글 버튼 Local Audio Input Fader 로컬 오디오 입력 페이더 Local audio input fader (left/right) 로컬 오디오 입력 페이더 (왼쪽/오른쪽) This shows the level of the two stereo channels for your audio input. 오디오 입력에 대한 두 스테레오 채널의 레벨을 보여줍니다. If the application is connected to a server and you play your instrument/sing into the microphone, the VU meter should flicker. If this is not the case, you have probably selected the wrong input channel (e.g. 'line in' instead of the microphone input) or set the input gain too low in the (Windows) audio mixer. 애플리케이션이 서버에 연결되어 있고 악기를 연주하거나 마이크에 대고 노래하면 VU 미터가 깜박입니다. 그렇지 않다면, 입력 채널을 잘못 선택했거나(예: 마이크 입력 대신 라인 입력) 오디오 믹서에서(Windows) 입력 게인을 너무 낮게 설정했을 수 있습니다. For proper usage of the application, you should not hear your singing/instrument through the loudspeaker or your headphone when the software is not connected. This can be achieved by muting your input audio channel in the Playback mixer (not the Recording mixer!). 애플리케이션을 올바르게 사용하려면 소프트웨어가 연결되어 있지 않을 때엔 스피커나 헤드폰을 통해 노래/악기 소리가 들리지 않아야 합니다. 재생 믹서(녹음 믹서가 아님!)에서 입력 오디오 채널을 음소거하면 됩니다. Controls the relative levels of the left and right local audio channels. For a mono signal it acts as a pan between the two channels. For example, if a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows 왼쪽 및 오른쪽 로컬 오디오 채널의 상대 레벨을 제어합니다. 모노 신호의 경우 두 채널 사이의 팬 역할을 합니다. 예를 들면, 마이크가 오른쪽 입력 채널에 연결되어 있고 악기가 마이크보다 소리가 훨씬 큰 왼쪽 입력 채널에 연결되어 있는 경우 페이더 위의 레이블이 표시되는 방향으로 오디오 페이더를 이동합니다 Reverb effect 리버브 효과 Reverb can be applied to one local mono audio channel or to both channels in stereo mode. The mono channel selection and the reverb level can be modified. For example, if a microphone signal is fed in to the right audio channel of the sound card and a reverb effect needs to be applied, set the channel selector to right and move the fader upwards until the desired reverb level is reached. 리버브는 하나의 로컬 모노 오디오 채널 또는 스테레오 모드의 두 채널에 모두 적용할 수 있습니다. 모노 채널 선택 및 리버브 레벨을 수정할 수 있습니다. 예를 들면, 마이크 신호가 사운드 카드의 오른쪽 오디오 채널에 입력되고 반향 효과를 적용해야 하는 경우, 채널 선택기를 오른쪽으로 설정하고 원하는 리버브 레벨에 도달할 때까지 페이더를 위쪽으로 이동합니다. Reverb effect level setting 리버브 효과 레벨 설정 Reverb Channel Selection 리버브 채널 선택 With these radio buttons the audio input channel on which the reverb effect is applied can be chosen. Either the left or right input channel can be selected. 이 라디오 버튼으로 리버브 효과가 적용되는 오디오 입력 채널을 선택할 수 있습니다. 왼쪽 또는 오른쪽 입력 채널을 선택할 수 있습니다. Left channel selection for reverb 리버브 왼쪽 채널 선택 Right channel selection for reverb 리버브 오른쪽 채널 선택 The The Green 초록 The delay is perfect for a jam session. 지연 상태가 잼 세션에 딱 적합합니다. Yellow 노랑 Red 빨강 If this LED indicator turns red, you will not have much fun using %1. 이 LED 표시등이 빨간색으로 바뀌면 %1 사용의 즐거움이 줄어들 겁니다. Delay status LED indicator 지연 상태 LED 표시등 Opens a dialog where you can select a server to connect to. If you are connected, pressing this button will end the session. 연결할 서버를 선택할 수 있는 대화 상자를 엽니다. 연결되어 있는 경우 이 버튼을 누르면 세션이 종료됩니다. Shows the current audio delay status: 현재 오디오 지연 상태를 표시합니다: A session is still possible but it may be harder to play. 세션은 여전히 가능하지만 연주하기 더 어려울 수 있습니다. The delay is too large for jamming. 재밍을 하기에는 지연이 너무 큽니다. If this LED indicator turns red, you will not have much fun using the application. 이 LED 표시등이 빨간색으로 바뀌면 애플리케이션을 사용하는 즐거움이 줄어들 겁니다. The buffers status LED shows the current audio/streaming status. If the light is red, the audio stream is interrupted. This is caused by one of the following problems: 버퍼 상태 LED는 현재 오디오/스트리밍 상태를 보여줍니다. 표시등이 빨간색이면 오디오 스트림이 중단됩니다. 이는 다음 문제 중 하나로 인해 발생합니다: The sound card's buffer delay (buffer size) is too small (see Settings window). 사운드 카드 버퍼 지연(버퍼 크기)이 너무 작습니다(설정 창 참조). The upload or download stream rate is too high for your internet bandwidth. 업로드 또는 다운로드 스트림 속도 전송률이 인터넷 대역폭에 비해 너무 높습니다. Buffers status LED indicator 버퍼 상태 LED 표시등 C&onnect 연결(&O) software upgrade available 소프트웨어 업그레이드 가능 &File 파일(&F) &View 보기(&V) &Connection Setup... 연결 설정(&C)... My &Profile... 내 프로필(&P)... C&hat... 채팅(&H)... &Settings... &설정... &Analyzer Console... 애널라이저 콘솔(&A)... Use &Two Rows Mixer Panel &두 줄 믹서 패널 사용 Clear &All Stored Solo and Mute Settings 저장된 모든 솔로 및 음소거 설정 지우기(&A) %1 Directory %1 디렉터리 Ok 확인 E&xit 나가기(&X) &Edit 편집(&E) Center 가운데 R R L L , where , 현재 is the current attenuation indicator. 감쇠 표시기는 어디에 있습니까. Delay Status LED 지연 상태 LED Buffers Status LED 버퍼 상태 LED The network jitter buffer is not large enough for the current network/audio interface jitter. 네트워크 지터 버퍼가 현재 네트워크/오디오 인터페이스 지터에 비해 충분히 크지 않습니다. The CPU of the client or server is at 100%. 클라이언트 또는 서버의 CPU가 100%입니다. Current Connection Status Parameter 현재 연결 상태 파라미터 The Ping Time is the time required for the audio stream to travel from the client to the server and back again. This delay is introduced by the network and should be about 20-30 ms. If this delay is higher than about 50 ms, your distance to the server is too large or your internet connection is not sufficient. Ping 시간은 오디오 스트림이 클라이언트에서 서버로 이동하고 다시 돌아오는 데 필요한 시간입니다. 이 지연은 네트워크에 의해 발생하며 약 20-30ms 여야 합니다. 이 지연 시간이 약 50ms보다 크면 서버와의 거리가 너무 멀거나 인터넷 연결이 충분하지 않은 것입니다. Overall Delay is calculated from the current Ping Time and the delay introduced by the current buffer settings. 전체 지연은 현재 Ping 시간과 현재 버퍼 설정에 의해 생성된 지연으로 계산됩니다. If this LED indicator turns red, you will not have much fun using the 이 LED 표시등이 빨간색으로 바뀌면, 소프트웨어를 software. 사용하는 즐거움이 줄어들 겁니다. &Load Mixer Channels Setup... 믹서 채널 설정 불러오기(&L)... &Save Mixer Channels Setup... 믹서 채널 설정 저장하기(&S)... Sett&ings 설정(&I) Audio/Network &Settings... 오디오/네트워크 설정(&S)... A&dvanced Settings... 고급 설정(&D)... N&o User Sorting 사용자 정렬 없음(&O) If this LED indicator turns red, you will not have much fun using the %1 software. 이 LED 표시등이 빨간색으로 바뀌면 %1 소프트웨어를 사용하는 즐거움이 덜 할 겁니다. O&wn Fader First 자신의 페이더 우선(&W) Sort Users by &Name 이름별로 사용자 정렬(&N) Sort Users by &Instrument 악기별로 사용자 정렬(&I) Sort Users by &Group 그룹별로 사용자 정렬(&G) Sort Users by &City 도시별로 사용자 정렬(&C) Set All Faders to New Client &Level 모든 페이더를 새 클라이언트 및 레벨로 설정하기(&L) Local Jitter Buffer Status LED 로컬 지터 버퍼 상태 LED The local jitter buffer status LED shows the current audio/streaming status. If the light is red, the audio stream is interrupted. This is caused by one of the following problems: 로컬 지터 버퍼 상태 LED는 현재 오디오/스트리밍 상태를 보여줍니다. 표시등이 빨간색이면 오디오 스트림이 중단됩니다. 이는 다음 문제 중 하나로 인해 발생합니다: If this LED indicator turns red, the audio stream is interrupted. 이 LED 표시등이 빨간색이면 오디오 스트림이 중단됩니다. Local Jitter Buffer status LED indicator 로컬 지터 버퍼 상태 LED 표시등 Current Connection Status 현재 연결 상태 Auto-Adjust all &Faders 모든 페이더 자동 조정(&F) &Settings &설정 Directory Server 디렉터리 서버 Select Channel Setup File 채널 설정 파일 선택 user 사용자 users 사용자 Connect 연결 Settings 설정 Chat 채팅 Enable feedback detection 피드백 감지 켜기 Audio feedback or loud signal detected. We muted your channel and activated 'Mute Myself'. Please solve the feedback issue first and unmute yourself afterwards. 오디오 피드백 또는 큰 신호가 감지되었습니다. 채널을 음소거하고 '내 음소거'를 활성화했습니다. 피드백 문제를 먼저 해결하고 나중에 음소거를 해제하세요. Your sound card is not working correctly. Please open the settings dialog and check the device selection and the driver settings. 사운드 카드가 제대로 작동하지 않습니다. 설정 대화 상자를 열고 장치 선택과 드라이버 설정을 확인하세요. &Disconnect 연결 해제(&D) CClientDlgBase Delay 지연 Buffers 버퍼 Input 입력 L L R R Jitter 지터 Ping Ping ms ms &Mute Myself 음소거하기(&M) &Settings 설정(&S) &Chat 채팅(&C) C&onnect 연결(&O) Pan Center 가운데 Reverb 리버브 Left 왼쪽 Right 오른쪽 MUTED (Other people won't hear you) 음소거됨(다른 사람들이 내 말을 들을 수 없음) Set up your audio, connect to a server and start jamming! 오디오를 설정하고 서버에 연결하고 재밍을 시작해 보세요! Update check 업데이트 확인 CClientSettingsDlg Jitter Buffer Size 지터 버퍼 크기 The jitter buffer setting is therefore a trade-off between audio quality and overall delay. 지터 버퍼 설정은 오디오 품질과 전체 지연 사이의 균형을 맞추는 작업입니다. Local jitter buffer slider control 로컬 지터 버퍼 슬라이더 제어 Server jitter buffer slider control 서버 지터 버퍼 슬라이더 제어 Auto jitter buffer switch 지터 버퍼 자동 스위치 Jitter buffer status LED indicator 지터 버퍼 상태 LED 표시등 Sound Card Device 사운드 카드 The ASIO driver (sound card) can be selected using Windows 운영 체제에서는 ASIO 드라이버(사운드 카드)를 선택할 수 있지만. under the Windows operating system. Under MacOS/Linux, no sound card selection is possible. If the selected ASIO driver is not valid an error message is shown and the previous valid driver is selected. MacOS/Linux에서는 사운드 카드 선택이 불가능합니다. 선택한 ASIO 드라이버가 유효하지 않으면 오류 메시지가 표시되고 이전의 유효한 드라이버가 선택됩니다. If the driver is selected during an active connection, the connection is stopped, the driver is changed and the connection is started again automatically. 연결된 상태에서 드라이버를 선택하면 연결이 중지되고 드라이버를 바꾼 후에 자동으로 다시 연결됩니다. Sound card device selector combo box 사운드 카드 선택 콤보 박스 If the ASIO4ALL driver is used, please note that this driver usually introduces approx. 10-30 ms of additional audio delay. Using a sound card with a native ASIO driver is therefore recommended. ASIO4ALL 드라이버를 사용하는 경우 이 드라이버는 일반적으로 약 10-30ms의 추가 오디오 지연을 일으킵니다. 그러므로 기본 ASIO 드라이버와 함께 사운드 카드를 사용하는 것이 좋습니다. If you are using the kX ASIO driver, make sure to connect the ASIO inputs in the kX DSP settings panel. kX ASIO 드라이버를 사용하는 경우 kX DSP 설정 패널에서 ASIO 입력을 연결해야 합니다. Sound Card Channel Mapping 사운드 카드 채널 매핑 If the selected sound card device offers more than one input or output channel, the Input Channel Mapping and Output Channel Mapping settings are visible. 선택한 사운드 카드 장치가 한 개 이상의 입력 또는 출력 채널을 제공하는 경우 입력 채널 매핑 및 출력 채널 매핑 설정이 표시됩니다. For each 각각의 Left input channel selection combo box 왼쪽 입력 채널 선택 콤보 박스 Right input channel selection combo box 오른쪽 입력 채널 선택 콤보 박스 Left output channel selection combo box 왼쪽 출력 채널 선택 콤보 박스 Right output channel selection combo box 오른쪽 출력 채널 선택 콤보 박스 Enable Small Network Buffers 소규모 네트워크 버퍼 활성화 If enabled, the support for very small network audio packets is activated. Very small network packets are only actually used if the sound card buffer delay is smaller than 활성화하면 매우 작은 네트워크 오디오 패킷에 대한 지원이 활성화됩니다. 매우 작은 네트워크 패킷은 사운드 카드 버퍼 지연이 샘플보다 작은 경우에만 실제로 사용됩니다. samples. The smaller the network buffers, the lower the audio latency. But at the same time the network load increases and the probability of audio dropouts also increases. 네트워크 버퍼가 작을수록 오디오 대기 시간이 낮아집니다. 그러나 동시에 네트워크 부하가 증가하고 오디오 드롭아웃 가능성도 증가합니다. Enable small network buffers check box 소규모 네트워크 버퍼 활성화 체크 박스 Sound Card Buffer Delay 사운드 카드 버퍼 지연 The buffer delay setting is a fundamental setting of %1. This setting has an influence on many connection properties. 버퍼 지연 설정은 %1의 기본 설정값입니다. 이 설정은 많은 연결에 영향을 줍니다. Three buffer sizes are supported 세 가지 버퍼 크기를 지원합니다 Some sound card drivers do not allow the buffer delay to be changed from within the application. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. On Windows, press the ASIO Device Settings button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. 일부 사운드 카드 드라이버는 애플리케이션 안에서 버퍼 지연을 변경할 수 없습니다. 이 경우 버퍼 지연 설정이 비활성화되며 사운드 카드 드라이버를 사용하여 변경해야 합니다. Windows에서는 ASIO 장치 설정 버튼을 눌러 드라이버 설정 패널을 엽니다. Linux에서는 Jack 설정 도구를 사용하여 버퍼 크기를 변경합니다. The actual buffer delay has influence on the connection status, the current upload rate and the overall delay. The lower the buffer size, the higher the probability of a red light in the status indicator (drop outs) and the higher the upload rate and the lower the overall delay. 실제 버퍼 지연은 연결 상태, 현재 업로드 속도 및 전체 지연에 영향을 미칩니다. 버퍼 크기가 작을수록 상태 표시기에서 빨간색 표시등(드롭아웃)이 발생할 확률이 높아지고 업로드 속도가 빨라지고 전체 지연이 낮아집니다. The buffer setting is therefore a trade-off between audio quality and overall delay. 그러므로 버퍼 설정은 오디오 품질과 전체 지연 사이의 균형을 맞추는 작업입니다. ASIO Device Settings push button ASIO 장치 설정 푸시 버튼 input/output channel (Left and Right channel) a different actual sound card channel can be selected. 입력/출력 채널(왼쪽 및 오른쪽 채널)이 다른 실제 사운드 카드 채널을 선택할 수 있습니다. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within the software. On Windows, press the ASIO Device Settings button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. 버퍼 지연 설정이 비활성화된 경우, 오디오 드라이버가 소프트웨어 내에서 이 설정을 수정하는 것을 금지합니다. Windows에서는 ASIO 장치 설정 버튼을 눌러 드라이버 설정 패널을 엽니다. Linux에서는 Jack 설정 도구를 사용하여 버퍼 크기를 변경합니다. Sound card driver settings 사운드 카드 드라이버 설정 This opens the driver settings of your sound card. Some drivers allow you to change buffer settings, others like ASIO4ALL let you choose input or outputs of your device(s). More information can be found on jamulus.io. 사운드 카드의 드라이버 설정을 열니다. 일부 드라이버를 사용하면 버퍼 설정을 변경할 수 있고 ASIO4ALL과 같은 드라이버를 사용하면 장치의 입력 또는 출력을 선택할 수 있습니다. 자세한 내용은 jamulus.io에서 확인할 수 있습니다. Opens the driver settings. Note: 드라이버 설정을 엽니다. 메모: currently only supports devices supporting a sample rate of 현재 HZ의 샘플 속도를 지원하는 기기만 지원합니다 Hz. You will not be able to select a driver/device which doesn't. For more help see jamulus.io. 그렇지 않은 드라이버/장치는 선택할 수 없습니다. 더 많은 도움이 필요하시면 jamulus.io를 참고하세요. 64 samples setting radio button 64 샘플 설정 라디오 버튼 128 samples setting radio button 128 샘플 설정 라디오 버튼 256 samples setting radio button 256 샘플 설정 라디오 버튼 ASIO setup push button ASIO 설정 푸시 버튼 Audio Channels 오디오 채널 Audio channels combo box 오디오 채널 콤보 박스 Audio Quality 오디오 품질 Audio quality combo box 오디오 품질 콤보 박스 New Client Level 새 클라이언트 레벨 New client level edit box 새 클라이언트 레벨 편집 박스 Custom Directory Server Address 사용자 정의 디렉터리 서버 주소 Current Connection Status Parameter 현재 연결 상태 파라미터 If this LED indicator turns red, you will not have much fun using the 이 LED 표시등이 빨간색으로 바뀌면 이 소프트웨어를 사용하는 즐거움이 software. 줄어들 겁니다. Mono 모노 mode will increase your stream's data rate. Make sure your upload rate does not exceed the available upload speed of your internet connection. 모드는 스트림 데이터 속도를 높입니다. 업로드 속도가 인터넷 연결의 사용 가능한 업로드 속도를 초과하지 않는지 확인하세요. Mono-in/Stereo-out 모노-입력/스테레오-출력 Stereo 스테레오 &Close 닫기(&C) Local Audio Input Fader 로컬 오디오 입력 페이더 Controls the relative levels of the left and right local audio channels. For a mono signal it acts as a pan between the two channels. For example, if a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows 왼쪽 및 오른쪽 로컬 오디오 채널의 상대 레벨을 제어합니다. 모노 신호의 경우 두 채널 사이의 팬 역할을 합니다. 예를 들면, 마이크가 오른쪽 입력 채널에 연결되어 있고 악기가 마이크보다 훨씬 소리가 큰 왼쪽 입력 채널에 연결되어 있는 경우 페이더 위의 레이블이 표시되는 방향으로 오디오 페이더를 이동합니다 L L , where , 현재 is the current attenuation indicator. 감쇠 표시기는 어디에 있습니까. Local audio input fader (left/right) 로컬 오디오 입력 페이더 (왼쪽/오른쪽) The jitter buffer compensates for network and sound card timing jitters. The size of the buffer therefore influences the quality of the audio stream (how many dropouts occur) and the overall delay (the longer the buffer, the higher the delay). 지터 버퍼는 네트워크 및 사운드 카드 타이밍 지터를 보완합니다. 따라서 버퍼의 크기는 오디오 스트림의 품질(드롭아웃 발생 수)과 전체 지연(버퍼가 길수록 지연이 높아짐)에 영향을 줍니다. You can set the jitter buffer size manually for the local client and the remote server. For the local jitter buffer, dropouts in the audio stream are indicated by the light below the jitter buffer size faders. If the light turns to red, a buffer overrun/underrun has taken place and the audio stream is interrupted. 로컬 클라이언트와 원격 서버에 대해 지터 버퍼 크기를 수동으로 설정할 수 있습니다. 로컬 지터 버퍼의 경우 오디오 스트림의 드롭아웃은 지터 버퍼 크기 페이더 아래의 표시등으로 표시됩니다. 표시등이 빨간색으로 바뀌면 버퍼 오버런/언더런이 발생하고 오디오 스트림이 중단됩니다. If the Auto setting is enabled, the jitter buffers of the local client and the remote server are set automatically based on measurements of the network and sound card timing jitter. If Auto is enabled, the jitter buffer size faders are disabled (they cannot be moved with the mouse). 자동 설정이 활성화되면 로컬 클라이언트와 원격 서버의 지터 버퍼는 네트워크 및 사운드 카드 타이밍 지터 측정을 기반으로 자동으로 설정됩니다. 자동 활성화되면 지터 버퍼 크기 페이더가 비활성화됩니다(마우스로 이동할 수 없음). If the Auto setting is enabled, the network buffers of the local client and the remote server are set to a conservative value to minimize the audio dropout probability. To tweak the audio delay/latency it is recommended to disable the Auto setting and to lower the jitter buffer size manually by using the sliders until your personal acceptable amount of dropouts is reached. The LED indicator will display the audio dropouts of the local jitter buffer with a red light. Auto 설정이 활성화되면 오디오 드롭아웃 가능성을 최소화하기 위해 로컬 클라이언트와 원격 서버의 네트워크 버퍼가 보수적인 값으로 설정됩니다. 오디오 지연/대기 시간을 조정하려면 자동 설정을 비활성화하고 개인이 허용하는 드롭아웃 양에 도달할 때까지 슬라이더를 사용하여 수동으로 지터 버퍼 크기를 낮추는 것이 좋습니다. LED 표시기는 로컬 지터 버퍼의 오디오 드롭아웃을 빨간색으로 표시합니다. The buffer delay setting is a fundamental setting of this software. This setting has an influence on many connection properties. 버퍼 지연 설정은 본 소프트웨어의 기본 설정입니다. 이 설정은 많은 연결 속성에 영향을 줍니다. 64 samples: The preferred setting. Provides the lowest latency but does not work with all sound cards. 64 샘플: 기본값입니다. 가장 낮은 대기 시간을 제공하지만 모든 사운드 카드에서 작동하지는 않습니다. 128 samples: Should work for most available sound cards. 128 샘플: 사용 가능한 대부분의 사운드 카드에서 작동합니다. 256 samples: Should only be used on very slow computers or with a slow internet connection. 256 샘플: 매우 느린 컴퓨터나 느린 인터넷 연결에서만 사용해야 합니다. If no buffer size is selected and all settings are disabled, an unsupported buffer size is used by the driver. The application will still work with this setting but with restricted performance. 버퍼 크기를 선택하지 않고 모든 설정을 비활성화하면 드라이버에서 지원되지 않는 버퍼 크기를 사용합니다. 애플리케이션은 이 설정으로 계속 작동하지만 성능이 제한됩니다. Skin 스킨 Select the skin to be used for the main window. 메인 창에 사용할 스킨을 선택합니다. Skin combo box 스킨 콤보 박스 Select the meter style to be used for the level meters. The Bar (narrow) and LEDs (round, small) options only apply to the mixerboard. When Bar (narrow) is selected, the input meters are set to Bar (wide). When LEDs (round, small) is selected, the input meters are set to LEDs (round, big). The remaining options apply to the mixerboard and input meters. 레벨 미터에 사용할 미터 스타일을 선택합니다. 막대(좁음) 및 LED(둥근, 작은) 옵션은 믹서보드에만 적용됩니다. 바(좁음)를 선택하면 입력 미터가 바(넓음)로 설정됩니다. LED(둥근, 작은)를 선택하면 입력 미터가 LED(둥근, 큰)로 설정됩니다. 나머지 옵션은 믹서보드와 입력 미터에 적용됩니다. Language 언어 Select the language to be used for the user interface. 사용자 인터페이스에 사용할 언어를 고릅니다. Language combo box 언어 콤보 박스 Selects the number of audio channels to be used for communication between client and server. There are three modes available: 클라이언트와 서버 간의 통신에 사용할 오디오 채널 수를 선택합니다. 세 가지 모드를 사용할 수 있습니다: and 그리고 These modes use one and two audio channels respectively. 이 모드는 각각 1개 및 2개의 오디오 채널을 사용합니다. Mono in/Stereo-out 모노 입력/스테레오-출력 The audio signal sent to the server is mono but the return signal is stereo. This is useful if the sound card has the instrument on one input channel and the microphone on the other. In that case the two input signals can be mixed to one mono channel but the server mix is heard in stereo. 서버로 전송되는 오디오 신호는 모노이지만 리턴 신호는 스테레오입니다. 이것은 사운드 카드의 한 입력 채널에 악기가 있고 다른 입력 채널에 마이크가 있는 경우에 유용합니다. 이 경우 두 개의 입력 신호를 하나의 모노 채널로 믹스할 수 있지만 서버 믹스는 스테레오로 들립니다. Enabling 활성화 In stereo streaming mode, no audio channel selection for the reverb effect will be available on the main window since the effect is applied to both channels in this case. 스테레오 스트리밍 모드에서, 리버브 효과에 대한 오디오 채널 선택은 두 채널에 효과가 적용되기 때문에 이 경우 메인 창에서는 사용할 수 없습니다. The higher the audio quality, the higher your audio stream's data rate. Make sure your upload rate does not exceed the available bandwidth of your internet connection. 오디오 품질이 높을수록 오디오 스트림 데이터 속도가 높아집니다. 업로드 속도가 인터넷 연결의 사용 가능한 대역폭을 초과하지 않는지 확인하십시오. This setting defines the fader level of a newly connected client in percent. If a new client connects to the current server, they will get the specified initial fader level if no other fader level from a previous connection of that client was already stored. 이 설정은 새로 연결된 클라이언트의 페이더 레벨을 백분율로 정의합니다. 새 클라이언트가 현재 서버에 연결하는 경우 해당 클라이언트의 이전 연결에서 다른 페이더 레벨이 이미 저장되어 있지 않은 경우 지정된 초기 페이더 레벨을 가져옵니다. Input Boost 입력 부스트 This setting allows you to increase your input signal level by factors up to 10 (+20dB). If your sound is too quiet, first try to increase the level by getting closer to the microphone, adjusting your sound equipment or increasing levels in your operating system's input settings. Only if this fails, set a factor here. If your sound is too loud, sounds distorted and is clipping, this option will not help. Do not use it. The distortion will still be there. Instead, decrease your input level by getting farther away from your microphone, adjusting your sound equipment or by decreasing your operating system's input settings. 이 설정을 사용하면 입력 신호 레벨을 최대 10(+20dB)까지 높일 수 있습니다. 소리가 너무 작으면, 먼저 마이크에 더 가까이 다가가거나 음향 장비를 조정하거나 운영 체제 입력 설정에서 레벨을 높이십시오. 그게 안 되는 경우에만 여기에서 설정하세요. 소리가 너무 크거나 왜곡되고 잘리면 이 옵션이 도움이 되지는 않습니다. 사용하지 않는 게 좋습니다. 왜곡은 여전히 생깁니다. 대신 마이크에서 더 멀리 떨어지거나 음향 장비를 조정하거나 운영 체제 입력 설정을 줄여서 입력 레벨을 줄여보세요. Input Boost combo box 입력 부스트 콤보 박스 Leave this blank unless you need to enter the address of a directory server other than the default. 기본값 이외의 디렉터리 서버 주소를 입력해야 하는 경우가 아니면 이 필드를 비워 두세요. Directory server address combo box 디렉터리 서버 주소 콤보 박스 The Ping Time is the time required for the audio stream to travel from the client to the server and back again. This delay is introduced by the network and should be about 20-30 ms. If this delay is higher than about 50 ms, your distance to the server is too large or your internet connection is not sufficient. 핑 시간은 오디오 스트림이 클라이언트에서 서버로 이동하고 다시 돌아오는 데 필요한 시간입니다. 이 지연은 네트워크에 의해 발생하며 약 20-30ms 여야 합니다. 이 지연 시간이 약 50ms보다 크면 서버와의 거리가 너무 멀거나 인터넷 연결이 좋지 않은 것입니다. Overall Delay is calculated from the current Ping Time and the delay introduced by the current buffer settings. 전체 지연은 현재 설정으로 생긴 핑 시간과 지연으로 계산합니다. Audio Upstream Rate depends on the current audio packet size and compression setting. Make sure that the upstream rate is not higher than your available internet upload speed (check this with a service such as speedtest.net). 오디오 업스트림 속도는 현재 오디오 패킷 크기 및 압축 설정에 따라 다릅니다. 업스트림 속도가 사용 가능한 인터넷 업로드 속도보다 높지 않은지 확인하세요(speedtest.net과 같은 서비스에서 확인하세요). The ASIO driver (sound card) can be selected using %1 under the Windows operating system. Under macOS/Linux, no sound card selection is possible. If the selected ASIO driver is not valid an error message is shown and the previous valid driver is selected. Windows 운영 체제에서 ASIO 드라이버(사운드 카드)는 %1에서 선택할 수 있습니다. macOS/Linux에서는 사운드 카드를 선택할 수 없습니다. 선택한 ASIO 드라이버가 유효하지 않으면 오류 메시지가 표시되고 이전의 유효한 드라이버가 선택됩니다. For each %1 input/output channel (left and right channel) a different actual sound card channel can be selected. 각각의 %1 입력/출력 채널(왼쪽 및 오른쪽 채널)마다 다른 실제 사운드 카드 채널을 선택할 수 있습니다. Enables support for very small network audio packets. These network packets are only actually used if the sound card buffer delay is smaller than %1 samples. The smaller the network buffers, the lower the audio latency. But at the same time the network load and the probability of audio dropouts or sound artifacts increases. 매우 작은 네트워크 오디오 패킷에 대한 지원을 활성화합니다. 이러한 네트워크 패킷은 사운드 카드 버퍼 지연이 %1 샘플보다 작은 경우에만 실제로 사용됩니다. 네트워크 버퍼가 작을수록 오디오 대기 시간이 낮아집니다. 그러나 동시에 네트워크 로드와 오디오 드롭아웃 또는 사운드 아티팩트의 가능성이 증가합니다. Some sound card drivers do not allow the buffer delay to be changed from within %1. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. On Windows, use the ASIO Device Settings button to open the driver settings panel. On Linux, use the JACK configuration tool to change the buffer size. 일부 사운드 카드 드라이버는 버퍼 지연이 %1 내에서 변경되는 것을 허용하지 않습니다. 이 경우 버퍼 지연 설정이 비활성화되고 사운드 카드 드라이버를 사용하여 변경해야 합니다. Windows에서는 ASIO 장치 설정 버튼을 사용하여 드라이버 설정 패널을 엽니다. Linux에서는 JACK 구성 도구를 사용하여 버퍼 크기를 변경합니다. If no buffer size is selected and all settings are disabled, this means an unsupported buffer size is in use by the driver. %1 will still work with this setting but may have restricted performance. 버퍼 크기를 선택하지 않고 모든 설정을 비활성화하면 드라이버에서 지원되지 않는 버퍼 크기를 사용하고 있음을 의미합니다. %1에서도 이 설정으로 계속 작동하지만 성능이 제한될 수 있습니다. Controls the relative levels of the left and right local audio channels. For a mono signal it acts as a pan between the two channels. For example, if a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows %1, where %2 is the current attenuation indicator. 왼쪽 및 오른쪽 로컬 오디오 채널 사이의 레벨을 적절하게 제어합니다. 모노 신호의 경우 두 채널 사이의 팬 역할을 합니다. 예를 들어 마이크가 오른쪽 입력 채널에 연결되어 있고 악기가 마이크보다 훨씬 큰 왼쪽 입력 채널에 연결된 경우 페이더 위의 레이블이 %1을 표시하는 방향으로 오디오 페이더를 이동합니다. 여기서 %2는 현재 감쇠 표시기입니다. Audio Device 오디오 장치 Under the Windows operating system the ASIO driver (sound card) can be selected using %1. If the selected ASIO driver is not valid an error message is shown and the previous valid driver is selected. Under macOS the input and output hardware can be selected. Windows 운영 체제에서는 ASIO 드라이버(사운드 카드)를 %1에서 선택할 수 있습니다. 선택한 ASIO 드라이버가 유효하지 않으면 오류 메시지가 표시되고 이전의 유효한 드라이버가 선택됩니다. macOS에서는 입력 및 출력 하드웨어를 선택할 수 있습니다. Three buffer sizes can be selected 세 가지 버퍼 크기를 선택할 수 있습니다 64 samples: Provides the lowest latency but does not work with all sound cards. 64 샘플: 가장 낮은 대기 시간을 제공하지만 모든 사운드 카드에서 작동하지는 않습니다. 256 samples: Should only be used when 64 or 128 samples is causing issues. 256 샘플: 64 또는 128 샘플이 문제를 일으키는 경우에만 사용해야 합니다. Some sound card drivers do not allow the buffer delay to be changed from within %1. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. Use the appropriate tool for the interface in use to adjust this buffer size. For example, if using ASIO, use the "ASIO Device Settings" button to open the driver settings panel or if using JACK, use a tool such as QjackCtl to adjust the buffer size. Other interfaces, such as Pipewire, would require their appropriate tool being used. Please refer to the interface manual. 일부 사운드 카드 드라이버는 버퍼 지연이 %1 내에서 변경되는 것을 허용하지 않습니다. 이 경우 버퍼 지연 설정이 비활성화되고 사운드 카드 드라이버를 사용하여 변경해야 합니다. 이 버퍼 크기를 조정하려면 사용 중인 인터페이스에 적절한 도구를 사용하십시오. 예를 들어 ASIO를 사용하는 경우 "ASIO 장치 설정" 버튼을 사용하여 드라이버 설정 패널을 열거나 JACK을 사용하는 경우 QjackCtl과 같은 도구를 사용하여 버퍼 크기를 조정합니다. Pipewire와 같은 다른 인터페이스는 적절한 도구를 사용해야 합니다. 인터페이스 매뉴얼을 참조하십시오. If no buffer size is selected and all settings are disabled, this means a buffer size in use by the driver which does not match the values. %1 will still work with this setting but may have restricted performance. 버퍼 크기를 선택하지 않고 모든 설정을 비활성화하면 드라이버에서 사용 중인 버퍼 크기가 값과 일치하지 않음을 의미합니다. 이 설정으로도 %1의 작동은 계속되지만 성능이 제한될 수 있습니다. The actual buffer delay has influence on the connection, the current upload rate and the overall delay. The lower the buffer size, the higher the probability of a red light in the status indicator (drop outs) and the higher the upload rate and the lower the overall delay. 실제 버퍼 지연은 연결, 현재 업로드 속도 및 전체 지연에 영향을 미칩니다. 버퍼 크기가 작을수록 상태 표시기에서 빨간색 표시등(드롭아웃)이 발생할 확률이 높아지고 업로드 속도가 빨라지고 전체 지연이 낮아집니다. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within %1. On Windows, press the ASIO Device Settings button to open the driver settings panel. On Linux, use the JACK configuration tool to change the buffer size. 버퍼 지연 설정이 비활성화된 경우, 오디오 드라이버는 %1 내에서 이 설정을 수정할 수 없습니다. Windows에서는 ASIO 장치 설정 버튼을 눌러 드라이버 설정 패널을 엽니다. Linux에서는 JACK 구성 도구를 사용하여 버퍼 크기를 변경합니다. This opens the driver settings of your sound card. Some drivers allow you to change buffer settings, others like ASIO4ALL lets you choose input or outputs of your device(s). More information can be found on jamulus.io. 사운드 카드의 드라이버 설정을 엽니다. 일부 드라이버는 버퍼 설정을 변경할 수 있도록 하고 ASIO4ALL과 같은 다른 드라이버를 사용하면 장치의 입력 또는 출력을 선택할 수 있습니다. 자세한 내용은 jamulus.io에서 확인할 수 있습니다. Opens the driver settings. Note: %1 currently only supports devices with a sample rate of %2 Hz. You will not be able to select a driver/device which doesn't. For more help see jamulus.io. 드라이버 설정을 엽니다. 참고: 현재 샘플 속도가 %2 Hz인 장치만 %1의 지원을 받습니다. 그렇지 않은 드라이버/장치는 선택할 수 없습니다. 자세한 도움말은 jamulus.io를 참조하세요. Meter Style 미터 스타일 Select the meter style to be used for the level meters. The Narrow Bar and Small LEDs options only apply to the mixerboard. When Narrow Bar is selected, the input meters are set to Bar. When Small LEDs is selected, the input meters are set to Round LEDs. The remaining options apply to the mixerboard and input meters. 레벨 미터에 사용할 미터 스타일을 선택합니다. 좁은 바 및 소형 LED 옵션은 믹서보드에만 적용됩니다. 좁은 바를 선택하면 입력 미터가 바로 설정됩니다. 소형 LED를 선택하면 입력 미터가 원형 LED로 설정됩니다. 나머지 옵션은 믹서보드와 입력 미터에 적용됩니다. Meter Style combo box 미터 스타일 콤보 박스 and 그리고 Custom Directories 사용자 정의 디렉터리 If you need to add additional directories to the Connect dialog Directory drop down, you can enter the addresses here.<br>To remove a value, select it, delete the text in the input box, then move focus out of the control. 연결 대화상자 하위 디렉터리에 디렉터리를 추가해야 하는 경우 여기에 주소를 입력할 수 있습니다.<br>값을 제거하려면 값을 선택하고 입력 상자에서 텍스트를 삭제한 다음 컨트롤 밖으로 포커스를 이동하세요. Custom Directories combo box 사용자 정의 디렉터리 콤보 박스 Audio Upstream Rate 오디오 업스트림 속도 Depends on the current audio packet size and compression setting. Make sure that the upstream rate is not higher than your available internet upload speed (check this with a service such as speedtest.net). 현재 오디오 패킷 크기 및 압축 설정에 따라 다릅니다. 업스트림 속도가 사용 가능한 인터넷 업로드 속도보다 높지 않은지 확인합니다(speedtest.net과 같은 서비스에서 확인). Number of Mixer Panel Rows 믹서 패널 줄 수 Adjust the number of rows used to arrange the mixer panel. 믹서 패널을 정렬하는 데 사용되는 줄 수를 조정합니다. Number of Mixer Panel Rows spin box 믹서 패널 줄 수 스핀 박스 Feedback Protection 피드백 보호 Enable feedback protection to detect acoustic feedback between microphone and speakers. 피드백 보호를 활성화하여 마이크와 스피커 간의 음향 피드백을 감지합니다. Feedback Protection check box 피드백 보호 체크 박스 Audio Alerts 오디오 경고 Enable audio alert when receiving a chat message and when a new client joins the session. A second sound device may be required to hear the alerts. 채팅 메시지를 수신하고 새 클라이언트가 세션에 참여할 때 오디오 경고를 활성화합니다. 경보를 듣기 위해 두 번째 사운드 장치가 필요할 수 있습니다. Audio Alerts check box 오디오 경고 확인란 ASIO Device Settings ASIO 장치 설정 Low 낮음 Normal 보통 High 높음 Fancy 훌륭함 Compact 콤팩트 Bar (narrow) 바 (좁음) Bar (wide) 바 (넓음) LEDs (stripe) LED (줄무늬) LEDs (round, small) LED (둥근, 소형) LEDs (round, big) LED (둥근, 대형) LEDs LED Bar Narrow Bar 좁은 바 Round LEDs 둥근 LED Small LEDs 소형 LED None 없음 Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country or region you are located in. Your city and skill level playing your instrument may also be added. 여기에 여러분의 이름이나 가명을 적어서 함께 연주하고 싶은 다른 뮤지션들이 여러분이 누구인지 알 수 있도록 하세요. 연주하는 악기의 사진과 여러분이 위치한 국가 또는 지역의 국기를 추가할 수도 있습니다. 여러분의 도시 및 악기 연주 기술 수준도 추가할 수 있습니다. What you set here will appear at your fader on the mixer board when you are connected to a %1 server. This tag will also be shown at each client which is connected to the same server as you. 여기에서 설정한 내용은 %1 서버에 연결할 때 믹서 보드의 페이더에 나타납니다. 이 태그는 여러분과 동일한 서버에 연결한 각 클라이언트에도 표시됩니다. Country/region flag button 국가/지역 깃발 버튼 Center 가운데 R R Custom 사용자 정의 Any Genre 2 모든 장르 2 Any Genre 3 모든 장르 3 Genre Rock 장르 Rock Genre Jazz 장르 Jazz Genre Classical/Folk 장르 Classical/Folk Genre Choral/Barbershop 장르 Choral/Barbershop Any Genre 1 모든 장르 1 preferred 선호 Musician Profile 뮤지션 프로필 Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country you are located in. Your city and skill level playing your instrument may also be added. 여기에 여러분의 이름이나 별칭을 적어서 함께 연주하고 싶은 다른 뮤지션들이 여러분이 누구인지 알 수 있도록 하세요. 연주하는 악기의 사진과 여러분이 위치한 국가 또는 지역의 국기를 추가할 수도 있습니다. 여러분의 도시 및 악기 연주 기술 수준도 추가할 수 있습니다. What you set here will appear at your fader on the mixer board when you are connected to a Jamulus server. This tag will also be shown at each client which is connected to the same server as you. 여기에서 설정한 내용은 Jamulus 서버에 연결될 때 믹서 보드의 페이더에 나타납니다. 이 태그는 여러분과 같은 서버에 연결한 클라이언트에도 표시됩니다. Alias or name edit box 가명 또는 이름 편집 상자 Instrument picture button 악기 사진 버튼 Country flag button 국기 버튼 City edit box 도시 편집 박스 Skill level combo box 스킬 레벨 콤보 박스 Beginner 초보 Intermediate 중급 Expert 전문가 Size: 크기: Buffer Delay 버퍼 지연 Buffer Delay: 버퍼 지연: Drum Set 드럼 세트 Djembe 젬베 Electric Guitar 일렉트릭 기타 Acoustic Guitar 어쿠스틱 기타 Bass Guitar 베이스 기타 Keyboard 키보드 Synthesizer 신디사이저 Grand Piano 그랜드 피아노 Accordion 아코디언 Vocal 보컬 Microphone 마이크 Harmonica 하모니카 Trumpet 트럼펫 Trombone 트롬본 French Horn 호른 Tuba 튜바 Saxophone 색소폰 Clarinet 클라리넷 Flute 플루트 Violin 바이올린 Cello 첼로 Double Bass 콘트라베이스 Recorder 리코더 Streamer 스트리머 Listener 청취자 Guitar+Vocal 기타+보컬 Keyboard+Vocal 키보드+보컬 Bodhran 보란 Bassoon 바순 Oboe 오보에 Harp 하프 Viola 비올라 Congas 콩가 Bongo 봉고 Vocal Bass 보컬 베이스 Vocal Tenor 보컬 테너 Vocal Alto 보컬 알토 Vocal Soprano 보컬 소프라노 Banjo 벤조 Mandolin 만돌린 Ukulele 우쿨렐레 Bass Ukulele 베이스 우쿨렐레 Vocal Baritone 보컬 바리톤 Vocal Lead 리드 보컬 Mountain Dulcimer 마운틴 덜시머 Scratching 스크래치 Rapping 랩핑 Vibraphone 비브라폰 Conductor 지휘자 CClientSettingsDlgBase Settings 설정 Soundcard 사운드 카드 Device 장치 Input Channel Mapping 입력 채널 매핑 L L R R Output Channel Mapping 출력 채널 매핑 Enable Small Network Buffers 소규모 네트워크 버퍼 활성화 Buffer Delay 버퍼 지연 Country/Region 국가/지역 (preferred) (선호) (default) (기본) (safe) (안전) Driver Setup 드라이버 설정 My Profile 내 프로필 Musician's Profile 뮤지션 프로필 Alias/Name 가명/이름 Instrument 악기 Country 국가 City 도시 Skill 스킬 User Interface 사용자 인터페이스 Meter Style 미터 스타일 Mixer Rows 믹서 줄 Audio Alerts 오디오 경고 Audio/Network Setup 오디오/네트워크 설정 Audio Device 오디오 장치 Jitter Buffer 지터 버퍼 Auto 자동 Local 로컬 Server 서버 Size 크기 kbps kbps ms ms Input Boost 입력 부스트 Feedback Protection 피드백 보호 Enable 활성화 Input Balance 입력 밸런스 Pan Center 가운데 Misc 기타 등등 Audio Channels 오디오 채널 Audio Quality 오디오 품질 Measurements 측정 Advanced Setup 고급 설정 Custom Central Server Address: 사용자 지정 중앙 서버 주소: New Client Level 새 클라이언트 레벨 Skin 스킨 Language 언어 Custom Directories: 사용자 지정 디렉터리: % % Custom Directory Server Address: 사용자 지정 디렉터리 서버 주소: Audio Stream Rate 오디오 스트림 속도 val val Ping Time 핑 시간 Overall Delay 전체 지연 Local Jitter Buffer 로컬 지터 버퍼 CConnectDlg Directory 디렉터리 Shows the servers listed by the selected directory. You can add custom directories in Advanced Settings. 선택한 디렉터리 별로 나열된 서버를 표시합니다. 고급 설정에서 사용자 정의 디렉터리를 추가할 수 있습니다. Directory combo box 디렉터리 콤보 박스 Filters the server list by the given text. Note that the filter is case insensitive. A single # character will filter for those servers with at least one person connected. 주어진 텍스트로 서버 목록을 필터링합니다. 필터는 대소문자를 구분하지 않습니다. 단일 # 문자는 적어도 한 사람이 연결된 서버를 필터링합니다. Uncheck to collapse the server list to show just the server details. Check to show everyone on the servers. 서버 세부 정보만 표시하도록 서버 목록을 축소하려면 선택을 취소합니다. 서버의 모든 사람을 표시하려면 선택합니다. Server List 서버 목록 The Connection Setup window lists the available servers registered with the selected directory. Use the Directory dropdown to change the directory, find the server you want to join in the server list, click on it, and then click the Connect button to connect. Alternatively, double click on the server name to connect. 연결 설정 창에는 선택한 디렉터리에 등록된 사용 가능한 서버가 나열됩니다. 디렉터리 드롭 다운을 사용하여 디렉터리를 변경하고 서버 목록에서 가입하려는 서버를 찾아 클릭한 다음 연결 버튼을 클릭하여 연결합니다. 또는 연결할 서버 이름을 두 번 클릭합니다. Permanent servers (those that have been listed for longer than 48 hours) are shown in bold. 영구 서버(48시간 이상 나열된 서버)는 굵게 표시됩니다. You can add custom directories in Advanced Settings. 고급 설정에서 사용자 정의 디렉터리를 추가할 수 있습니다. Server list view 서버 목록 보기 Server Address 서버 주소 If you know the server address, you can connect to it using the Server name/Address field. An optional port number can be added after the server address using a colon as a separator, e.g. %1. The field will also show a list of the most recently used server addresses. 서버 주소를 알고 있는 경우 서버 이름/주소 필드를 사용하여 연결할 수 있습니다. 콜론을 구분 기호로 사용하여 서버 주소 뒤에 선택적 포트 번호를 추가할 수 있습니다. 예) %1. 필드에는 가장 최근에 사용한 서버 주소 목록도 표시됩니다. Holds the current server address. It also stores old addresses in the combo box list. 현재 서버 주소를 보유하고 콤보 상자 목록에 이전 주소를 저장합니다. The Connection Setup window shows a list of available servers. Server operators can optionally list their servers by music genre. Use the List dropdown to select a genre, click on the server you want to join and press the Connect button to connect to it. Alternatively, double click on on the server name. Permanent servers (those that have been listed for longer than 48 hours) are shown in bold. 연결 설정 창에 사용 가능한 서버 목록이 표시됩니다. 서버 운영자는 선택적으로 음악 장르별로 서버를 나열할 수 있습니다. 목록 드롭 다운을 사용하여 장르를 선택하고 참여하려는 서버를 클릭한 다음 연결 버튼을 눌러 연결합니다. 또는 서버 이름을 두 번 클릭합니다. 영구 서버(48시간 이상 나열된 서버)는 굵게 표시됩니다. If you know the IP address or URL of a server, you can connect to it using the Server name/Address field. An optional port number can be added after the IP address or URL using a colon as a separator, e.g. example.org: 서버의 IP 주소 또는 URL을 알고 있는 경우 서버 이름/주소 필드를 사용하여 연결할 수 있습니다. 콜론을 구분 기호로 사용하여 IP 주소 또는 URL 뒤에 선택적 포트 번호를 추가할 수 있습니다. 예) example.org: . The field will also show a list of the most recently used server addresses. . 이 필드에는 가장 최근에 사용한 서버 주소 목록도 표시됩니다. Server address edit box 서버 주소 편집 박스 Holds the current server IP address or URL. It also stores old URLs in the combo box list. 현재 서버 IP 주소 또는 URL을 보유하고 콤보 상자 목록에 이전 URL을 저장합니다. Server List Selection 서버 목록 선택 Selects the server list to be shown. 표시할 서버 목록을 선택합니다. Server list selection combo box 서버 목록 선택 콤보 상자 Filter 필터 The server list is filtered by the given text. Note that the filter is case insensitive. 서버 목록은 주어진 텍스트로 필터링 됩니다. 필터는 대소문자를 구분하지 않습니다. Filter edit box 필터 편집 박스 Show All Musicians 모든 뮤지션 보기 If you check this check box, the musicians of all servers are shown. If you uncheck the check box, all list view items are collapsed. 이 체크박스를 체크하면 모든 서버의 뮤지션이 표시됩니다. 체크 박스 선택을 취소하면 모든 목록 보기 항목이 취소됩니다. Show all musicians check box 모든 뮤지션 보기 체크 박스 If you know the IP address or URL of a server, you can connect to it using the Server name/Address field. An optional port number can be added after the IP address or URL using a colon as a separator, e.g. %1. The field will also show a list of the most recently used server addresses. 서버의 IP 주소 또는 URL을 알고 있는 경우 서버 이름/주소 필드를 사용하여 연결할 수 있습니다. 콜론을 구분 기호로 사용하여 IP 주소 또는 URL 뒤에 선택적 포트 번호를 추가할 수 있습니다. 예) %1. 이 필드에는 가장 최근에 사용한 서버 주소 목록도 표시됩니다. Filter text, or # for occupied servers 필터 텍스트 또는 점유 서버의 경우 # Type # for occupied servers 점유 서버의 경우 # 입력 CConnectDlgBase Connection Setup 연결 설정 List 목록 Directory 디렉터리 Filter 필터 Show All Musicians 모든 뮤지션 보기 Server Name 서버 이름 Ping Time Ping 시간 Musicians 뮤지션 Location 위치 Server Address 서버 주소 C&ancel 취소(&A) &Connect 연결(&C) CHelpMenu &Help 도움말 (&H) Getting &Started... 시작하기(&S)... Software &Manual... 소프트웨어 설명서(&M)... What's &This 이게 뭘까요(&T) &About Jamulus... Jamulus 정보(&A)... About &Qt... Qt 정보(&Q)... &About... &정보... About Qt Qt 정보 CLanguageComboBox Restart Required 다시 시작 필요 Please restart the application for the language change to take effect. 언어의 변경 사항을 적용하려면 애플리케이션을 다시 시작하세요. CLicenceDlg This server requires you accept conditions before you can join. Please read these in the chat window. 이 서버는 참여하기 전에 역관에 동의해야 합니다. 채팅창에서 읽어주세요. I have read the conditions and &agree. 약관을 읽었으며 동의합니다(&A). Accept 수락 Decline 거절 CMultiColorLED Red 빨강 Yellow 노랑 Green 초록 CMusProfDlg Alias or name edit box 별칭 또는 이름 편집 박스 Instrument picture button 악기 사진 버튼 Country flag button 국기 버튼 City edit box 도시 편집 박스 Skill level combo box 스킬 레벨 콤보 박스 None 없음 Musician Profile 뮤지션 프로필 Alias/Name 별칭/이름 Instrument 악기 Country 국가 City 도시 Skill 스킬 &Close &닫기 Beginner 초보 Intermediate 중급 Expert 전문가 Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country you are located in. Your city and skill level playing your instrument may also be added. 여기에 여러분의 이름이나 별칭을 적어서 함께 연주하고 싶은 다른 뮤지션들이 여러분이 누구인지 알 수 있도록 하세요. 연주하는 악기의 사진과 여러분이 위치한 국가 또는 지역의 국기를 추가할 수도 있습니다. 여러분의 도시 및 악기 연주 기술 수준도 추가할 수 있습니다. What you set here will appear at your fader on the mixer board when you are connected to a Jamulus server. This tag will also be shown at each client which is connected to the same server as you. 여기에서 설정한 내용은 Jamulus 서버에 연결될 때 믹서 보드의 페이더에 나타납니다. 이 태그는 여러분과 같은 서버에 연결한 클라이언트에도 표시됩니다. Drum Set 드럼 세트 Djembe 젬베 Electric Guitar 일렉트릭 기타 Acoustic Guitar 어쿠스틱 기타 Bass Guitar 베이스 기타 Keyboard 키보드 Synthesizer 신디사이저 Grand Piano 그랜드 피아노 Accordion 아코디언 Vocal 보컬 Microphone 마이크 Harmonica 하모니카 Trumpet 트럼펫 Trombone 트롬본 French Horn 호른 Tuba 튜바 Saxophone 색소폰 Clarinet 클라리넷 Flute 플루트 Violin 바이올린 Cello 첼로 Double Bass 콘트라베이스 Recorder 리코더 Streamer 스트리머 Listener 청취자 Guitar+Vocal 기타+보컬 Keyboard+Vocal 키보드+보컬 Bodhran 보란 Bassoon 바순 Oboe 오보에 Harp 하프 Viola 비올라 Congas 콩가 Bongo 봉고 Vocal Bass 보컬 베이스 Vocal Tenor 보컬 테너 Vocal Alto 보컬 알토 Vocal Soprano 보컬 소프라노 Banjo 벤조 Mandolin 만돌린 Ukulele 우쿨렐레 Bass Ukulele 베이스 우쿨렐레 Vocal Baritone 보컬 바리톤 Vocal Lead 리드 보컬 Mountain Dulcimer 마운틴 덜시머 Scratching 스크래치 Rapping 래퍼 No Name 이름 없음 CServerDlg Client List 클라이언트 목록 The client list shows all clients which are currently connected to this server. Some information about the clients like the IP address and name are given for each connected client. 클라이언트 목록에는 현재 이 서버에 연결된 모든 클라이언트가 표시됩니다. IP 주소 및 이름과 같은 클라이언트에 대한 일부 정보는 연결된 각 클라이언트에게 제공됩니다. Connected clients list view 연결된 클라이언트 목록 보기 Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user %1 is running as). 버튼을 클릭하여 기본 녹음 디렉터리를 선택할 수 있는 대화 상자를 엽니다. 선택한 값은 존재해야 하고 쓰기 가능해야 합니다(사용자 %1에 의해 실행 중인 사용자의 하위 디렉터리 생성 허용). The current value of the main recording directory. The chosen value must exist and be writeable (allow creation of sub-directories by the user %1 is running as). Click the button to open the dialog that allows the main recording directory to be selected. 메인 녹음 디렉터리의 현재 값입니다. 선택한 값은 존재해야 하고 쓰기 가능해야 합니다(사용자 %1에 의해 실행 중인 사용자의 하위 디렉터리 생성 허용). 버튼을 클릭하여 기본 녹음 디렉터리를 선택할 수 있는 대화 상자를 엽니다. Custom Directory address 사용자 정의 디렉터리 주소 The Custom Directory address is the address of the directory holding the server list to which this server should be added. 사용자 정의 디렉터리 주소는 이 서버를 추가해야 하는 서버 목록이 있는 디렉터리의 주소입니다. Server List Filename dialog push button 서버 목록 파일 이름 대화 상자 푸시 버튼 Server List Filename 서버 목록 파일이름 Click the button to open the dialog that allows the server list persistence file name to be set. The user %1 is running as needs to be able to create the file name specified although it may already exist (it will get overwritten on save). 버튼을 클릭하여 서버 목록 지속성 파일 이름을 설정할 수 있는 대화 상자를 엽니다. %1 사용자는 이미 존재할 수 있지만 지정된 파일 이름을 생성할 수 있어야 하기 때문에 실행 중입니다(저장 시 덮어쓰게 됩니다). Server List Filename text box (read-only) 서버 목록 파일 이름 텍스트 박스 (읽기 전용) The current value of server list persistence file name. The user %1 is running as needs to be able to create the file name specified although it may already exist (it will get overwritten on save). Click the button to open the dialog that allows the server list persistence file name to be set. 서버 목록 지속성 파일 이름의 현재 값입니다. %1 사용자는 이미 존재할 수 있지만 지정된 파일 이름을 생성할 수 있어야 하기 때문에 실행 중입니다(저장 시 덮어쓰게 됩니다). 버튼을 클릭하여 서버 목록 지속성 파일 이름을 설정할 수 있는 대화 상자를 엽니다. Clear the server list file name button 서버 목록 파일 이름 정리 버튼 Clear Server List Filename 서버 목록 파일이름 지우기 Click the button to clear the currently selected server list persistence file name. This will prevent persisting the server list until a new value is selected. 버튼을 클릭하여 현재 선택된 서버 목록 지속성 파일 이름을 지웁니다. 이렇게 하면 새 값을 선택할 때까지 서버 목록이 유지되지 않게 됩니다. Start Minimized on Operating System Start 운영 체제 시작 시 최소화로 시작 Make My Server Public 내 서버를 공개로 설정 Register Server Status 서버 상태 등록 If the Make My Server Public check box is checked, this will show whether registration with the directory server is successful. If the registration failed, please choose another server list. 내 서버 공개 확인란을 선택하면 디렉터리 서버에 등록이 성공했는지가 표시됩니다. 등록에 실패한 경우 다른 서버 목록을 선택하세요. If the start minimized on operating system start check box is checked, the server will be started when the operating system starts up and is automatically minimized to a system task bar icon. 운영 체제 시작 시 최소화로 시작 확인란을 선택하면 운영 체제가 시작될 때 서버가 시작되고 자동으로 시스템 작업 표시줄 아이콘으로 최소화됩니다. If the Make My Server Public check box is checked, this server registers itself at the directory server so that all users of the application can see the server in the connect dialog server list and connect to it. The registration of the server is renewed periodically to make sure that all servers in the connect dialog server list are actually available. 내 서버 공개 확인란을 선택하면 이 서버가 디렉터리 서버에 등록되어 애플리케이션의 모든 사용자가 연결 대화 상자 서버 목록에서 서버를 보고 연결할 수 있습니다. 서버 등록은 연결 대화 서버 목록의 모든 서버가 실제로 사용 가능한지 확인하기 위해 주기적으로 갱신됩니다. Custom Directory Server Address 사용자 정의 디렉터리 서버 주소 The custom directory server address is the IP address or URL of the directory server at which the server list of the connection dialog is managed. 사용자 지정 디렉터리 서버 주소는 연결 대화 상자의 서버 목록이 관리되는 디렉터리 서버의 IP 주소 또는 URL입니다. Directory server address line edit 디렉터리 서버 주소 라인 편집 Server List Selection 서버 목록 선택 Selects the server list (i.e. directory server address) in which your server will be added. 서버를 추가할 서버 목록(예: 디렉터리 서버 주소)을 선택합니다. Server list selection combo box 서버 목록 선택 콤보 박스 Server Name 서버 이름 The server name identifies your server in the connect dialog server list at the clients. 서버 이름은 클라이언트의 연결 대화 상자 서버 목록에서 서버를 식별합니다. Server name line edit 서버 이름 라인 편집 Location City 도시 위치 The city in which this server is located can be set here. If a city name is entered, it will be shown in the connect dialog server list at the clients. 이 서버가 위치한 도시를 여기에서 설정할 수 있습니다. 도시 이름을 입력하면 클라이언트의 연결 대화 상자 서버 목록에 표시됩니다. City where the server is located line edit 서버가 위치한 도시 라인 편집 Location country 국가 위치 The country in which this server is located can be set here. If a country is entered, it will be shown in the connect dialog server list at the clients. 이 서버가 있는 국가를 여기에서 설정할 수 있습니다. 국가를 입력하면 클라이언트의 연결 대화 상자 서버 목록에 표시됩니다. Country where the server is located combo box 서버가 위치한 국가 콤보 상자 Display dialog to select recording directory button 녹음 디렉터리 버튼을 선택하는 대화 상자 표시 Main Recording Directory 메인 녹음 디렉터리 Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user Jamulus is running as). 버튼을 클릭하여 기본 녹음 디렉터리를 선택할 수 있는 대화 상자를 엽니다. 선택한 값은 존재하고 쓰기 가능해야 합니다(Jamulus를 실행 중인 사용자의 하위 디렉터리 생성 허용). Main recording directory text box (read-only) 메인 녹음 디렉터리 텍스트 박스(읽기 전용) The current value of the main recording directory. The chosen value must exist and be writeable (allow creation of sub-directories by the user Jamulus is running as). Click the button to open the dialog that allows the main recording directory to be selected. 메인 녹음 디렉터리의 현재 값입니다. 선택한 값은 존재하고 쓰기 가능해야 합니다(Jamulus를 실행 중인 사용자의 하위 디렉터리 생성 허용). 버튼을 클릭하여 기본 녹음 디렉터리를 선택할 수 있는 대화 상자를 엽니다. Clear the recording directory button 녹음 디렉터리 버튼 정리 Clear Recording Directory 녹음 디렉터리 정리 Click the button to clear the currently selected recording directory. This will prevent recording until a new value is selected. 버튼을 클릭하면 현재 선택한 녹음 디렉터리가 지워집니다. 이렇게 하면 새 값이 선택될 때까지 녹음이 되지 않습니다. Checkbox to turn on or off server recording 서버 녹화를 켜거나 끄는 체크박스 If the Register Server check box is checked, this will show whether registration with the directory server is successful. If the registration failed, please choose another server list. 서버 등록 확인란을 선택하면 디렉터리 서버 등록 성공 여부를 표시합니다. 등록에 실패한 경우 다른 서버 목록을 선택하세요. Enable Recorder 녹음기 활성화 Checked when the recorder is enabled, otherwise unchecked. The recorder will run when a session is in progress, if (set up correctly and) enabled. 녹음기를 활성화하면 체크되고 그렇지 않을 땐 체크되지 않습니다. (올바르게 설정되고) 활성화된 경우 세션이 진행 중일 때 녹음기가 실행됩니다. If the recording directory is not useable, the problem will be displayed in place of the session directory. 녹음 디렉터리를 사용할 수 없는 경우 세션 디렉터리 대신 문제가 표시됩니다. Current session directory text box (read-only) 현재 세션 디렉터리 텍스트 박스 (읽기 전용) Current Session Directory 현재 세션 디렉터리 Enabled during recording and holds the current recording session directory. Disabled after recording or when the recorder is not enabled. 기록하는 동안 활성화되고 현재 기록 세션 디렉터리를 유지합니다. 녹음 후 또는 녹음기가 활성화되지 않은 경우 비활성화됩니다. Recorder status label 녹음기 상태 레이블 Recorder Status 녹음기 상태 Displays the current status of the recorder. The following values are possible: 녹음기의 현재 상태를 표시합니다. 다음 값이 가능합니다: No recording directory has been set or the value is not useable. 녹음 디렉터리가 설정되지 않았거나 값을 사용할 수 없습니다. Recording has been switched off 녹음이 꺼졌습니다 by the UI checkbox UI 체크박스로 , either by the UI checkbox or SIGUSR2 being received , UI 체크박스 또는 수신되는 SIGUSR2에 의해 There is no one connected to the server to record. 녹음할 서버에 연결된 사용자가 없습니다. The performers are being recorded to the specified session directory. 연주는 지정된 세션 디렉터리에 녹음되고 있습니다. NOTE NOTE If the recording directory is not useable, the problem will be displayed in place of the directory. 녹음 디렉터리를 사용할 수 없는 경우 디렉터리 대신 문제가 표시됩니다. Server welcome message edit box 서버 환영 메시지 편집 박스 Server Welcome Message 서버 환영 메시지 A server welcome message text is displayed in the chat window if a musician enters the server. If no message is set, the server welcome is disabled. 뮤지션이 서버에 입장하면 채팅 창에 서버 환영 텍스트 메시지가 표시됩니다. 메시지가 설정되어 있지 않으면 서버 환영이 비활성화됩니다. Language 언어 Select the language to be used for the user interface. 사용자 인터페이스에 사용할 언어를 고릅니다. Language combo box 언어 콤보 박스 Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user Jamulus is running as). 버튼을 클릭하여 기본 녹음 디렉터리를 선택할 수 있는 대화 상자를 엽니다. 선택한 값은 존재하고 쓰기 가능해야 합니다(Jamulus를 실행 중인 사용자의 하위 디렉터리 생성 허용). Custom Directory 사용자 정의 디렉터리 The custom directory is the IP address or URL of the directory server at which the server list of the connection dialog is managed. 사용자 정의 디렉터리는 연결 대화 상자의 서버 목록이 관리되는 디렉터리 서버의 IP 주소 또는 URL입니다. Custom Directory line edit 사용자 정의 디렉터리 라인 편집 &Hide %1 server %1 서버 숨기기(&H) &Show %1 server %1 서버 표시하기(&S) %1 server %1 is the name of the main application %1 서버 Type a message here. If no message is set, the server welcome is disabled. 여기에 메시지를 입력하세요. 메시지가 설정되어 있지 않으면 서버 환영이 비활성화됩니다. software upgrade available 소프트웨어 업그레이드 가능 Recorder failed to start. Please check available disk space and permissions and try again. Error: 녹음을 시작하지 못했습니다. 사용 가능한 디스크 공간과 권한을 확인하고 다시 시도해 보세요. 오류: Now a directory 현재 디렉터리 ERROR ERROR Request new recording button 새 녹음 요청 버튼 Directory Type combo box 디렉터리 유형 콤보 박스 Directory 디렉터리 Select '%1' not to register your server with a directory. 디렉터리에 서버를 등록하지 않으려면 '%1' 선택하세요. Select one of the genres to register with that directory. 해당 디렉터리에 등록할 장르 중 하나를 선택합니다. Or select '%1' and specify a Custom Directory address on the Options tab to register with a custom directory. 또는 '%1' 선택 후 옵션 탭에서 사용자 정의 디렉터리 주소를 지정하여 사용자 정의 디렉터리에 등록하세요. For any value except '%1', this server registers with a directory so that a %2 user can select this server in the client connect dialog server list when they choose that directory. '%1' 제외한 모든 값에 대해 이 서버는 %2 사용자가 해당 디렉터리를 선택할 때 클라이언트 연결 대화 상자 서버 목록에서 이 서버를 선택할 수 있도록 디렉터리에 등록합니다. The registration of the server is renewed periodically to make sure that all servers in the connect dialog server list are actually available. 서버 등록은 연결 대화 서버 목록의 모든 서버가 실제로 사용 가능한지 확인하기 위해 주기적으로 갱신됩니다. When a value other than "%1" is chosen for Directory, this will show whether registration is successful. If the registration failed, please choose a different directory. 디렉터리에 대해 "%1" 이외의 값을 선택하면 등록 성공 여부가 표시됩니다. 등록에 실패하는 경우 다른 디렉터리를 선택하세요. Country/Region 국가/지역 Set the country or region where the server is running. Clients will show this location in their connect dialog's server list. 서버가 실행되는 국가 또는 지역을 설정합니다. 클라이언트는 연결 대화 상자의 서버 목록에 이 위치를 표시합니다. Combo box for location of this server 이 서버의 위치에 대한 콤보 박스 No recording directory has been set or the value is not useable. Check the value in the Options tab. 녹음 디렉터리가 설정되지 않았거나 값을 사용할 수 없습니다. 옵션 탭에서 값을 확인하세요. Recording has been switched off by the UI checkbox. UI 체크박스에 의해 녹음이 꺼졌습니다. Recording has been switched off, either by the UI checkbox or SIGUSR2 being received. UI 체크박스 또는 수신 중인 SIGUSR2에 의해 녹음이 꺼졌습니다. New Recording 새 녹음 During a recording session, the button can be used to start a new recording. 녹음 세션 중에 버튼을 사용하여 새 녹음을 시작할 수 있습니다. E&xit 나가기(&X) &Hide &숨기기 server 서버 &Open &열기 %1 Server %1 is the name of the main application %1 서버 Select Main Recording Directory 메인 녹음 디렉터리 선택 Recording 녹음 Not recording 녹음하지 않음 Not initialised 시작하지 않음 Not enabled 활성화되지 않음 Server 서버 &Window 창(&W) Unregistered 미등록 None 없음 Not registered 등록되지 않음 Bad address 잘못된 주소 Registration requested 등록 요청 Registration failed 등록 실패 Check server version 서버 버전 확인 Registered 등록함 Directory server list full 디렉터리 서버 목록 가득 참 Your server version is too old 서버 버전이 너무 오래되었습니다 Requirements not fulfilled 요구 사항을 충족하지 않음 Unknown value %1 알 수 없는 값 %1 Unknown value 알 수 없는 값 CServerDlgBase Client IP:Port 클라이언트 IP:Port Name 이름 Jitter Buffer Size 지터 버퍼 크기 Channels 채널 Server Setup 서버 설정 List 목록 Location: Region 위치: 지역 Session 세션 Chat Window Welcome (HTML/CSS Supported) 환영 채팅 창 (HTML/CSS 지원) Options 옵션 Custom Directory address 사용자 정의 디렉터리 주소 Server List Filename 서버 목록 파일이름 Start Minimized on Windows Start Windows 시작 시 최소화로 시작 Enable delay panning 지연 패닝 활성화 Update check 업데이트 확인 Make My Server Public (Register My Server in the Server List) 내 서버 공개(서버 목록에 내 서버 등록) Genre 장르 STATUS 상태 Custom Directory Server Address: 사용자 정의 디렉터리 서버 주소: Recording Directory 녹음 디렉터리 Enable Jam Recorder 잼 녹음기 활성화 Directory 디렉터리 New Recording 새 녹음 Language Consider add "(Lang)" as a suffix to ensure that users who selected the wrong language find the correct button 언어 My Server Info 내 서버 정보 Location: City 위치: 도시 Location: Country 위치: 국가 CServerListManager Could not write to '%1' '%1'에 쓸 수 없습니다 CSound The Jack server is not running. This software requires a Jack server to run. Normally if the Jack server is not running this software will automatically start the Jack server. It seems that this auto start has not worked. Try to start the Jack server manually. Jack 서버가 실행되고 있지 않습니다. 이 소프트웨어를 실행하려면 Jack 서버가 필요합니다. 일반적으로 Jack 서버가 실행되고 있지 않으면 이 소프트웨어가 Jack 서버를 자동으로 시작합니다. 이 자동 시작이 작동하지 않은 것 같습니다. Jack 서버를 수동으로 시작해 보세요. The Jack server sample rate is different from the required one. The required sample rate is: Jack 서버 샘플 속도가 필요한 샘플 속도와 다릅니다. 필요한 샘플 속도는 다음과 같습니다: You can use a tool like <i><a href="https://qjackctl.sourceforge.io">QJackCtl</a></i> to adjust the Jack server sample rate. <i><a href="https://qjackctl.sourceforge.io">QJackCtl</a></i> 같은 도구를 사용해서 Jack 서버 샘플 속도를 조정할 수 있습니다. Make sure to set the Frames/Period to a low value like 낮은 지연을 이루려면 Frames/Period를 to achieve a low delay. 다음과 같이 낮은 값으로 설정해야 합니다. The Jack port registering failed. 잭 포트 등록에 실패했습니다. Cannot activate the Jack client. Jack 클라이언트를 활성화할 수 없습니다. The Jack server was shut down. This software requires a Jack server to run. Try to restart the software to solve the issue. 잭 서버가 종료되었습니다. 이 소프트웨어를 실행하려면 Jack 서버가 필요합니다. 문제를 해결하려면 소프트웨어를 다시 시작해 보세요. CoreAudio input AudioHardwareGetProperty call failed. It seems that no sound card is available in the system. L'appel d'entrée AudioHardwareGetProperty CoreAudio a échoué failed. Il semble qu'aucune carte son ne soit disponible dans le système. CoreAudio output AudioHardwareGetProperty call failed. It seems that no sound card is available in the system. CoreAudio output AudioHardwareGetProperty call failed. 시스템에서 사용할 수 있는 사운드 카드가 없는 것 같습니다. Current system audio input device sample rate of %1 Hz is not supported. Please open the Audio-MIDI-Setup in Applications->Utilities and try to set a sample rate of %2 Hz. 현재 시스템의 오디오 입력 장치는 %1 Hz의 샘플 속도를 지원하지 않습니다. 애플리케이션->유틸리티에서 오디오-MIDI-설정을 열고 샘플 속도를 %2 Hz로 설정해 보세요. The current selected audio device is no longer present in the system. 선택한 오디오 장치가 현재 시스템에 없습니다. The audio input device is no longer available. 오디오 입력 장치를 더 이상 사용할 수 없습니다. The audio output device is no longer available. 오디오 출력 장치를 더 이상 사용할 수 없습니다. Current system audio output device sample rate of %1 Hz is not supported. Please open the Audio-MIDI-Setup in Applications->Utilities and try to set a sample rate of %2 Hz. 현재 시스템의 오디오 출력 장치는 %1 Hz의 샘플 속도를 지원하지 않습니다. 애플리케이션->유틸리티에서 오디오-MIDI-설정을 열고 샘플 속도를 %2 Hz로 설정해 보세요. The audio input stream format for this audio device is not compatible with this software. 이 오디오 장치의 오디오 입력 스트림 형식은 이 소프트웨어와 호환되지 않습니다. The audio output stream format for this audio device is not compatible with this software. 이 오디오 장치의 오디오 출력 스트림 형식은 이 소프트웨어와 호환되지 않습니다. The buffer sizes of the current input and output audio device cannot be set to a common value. Please choose other input/output audio devices in your system settings. 현재 입출력 오디오 장치의 버퍼 크기는 공통 값으로 설정할 수 없습니다. 시스템 설정에서 다른 입력/출력 오디오 장치를 선택하세요. The audio driver could not be initialized. 오디오 드라이버를 시작할 수 없습니다. The audio device does not support the required sample rate. The required sample rate is: 오디오 장치가 필요한 샘플 속도를 지원하지 않습니다. 필요한 샘플 속도는 다음과 같습니다: The audio device does not support setting the required sampling rate. This error can happen if you have an audio interface like the Roland UA-25EX where you set the sample rate with a hardware switch on the audio device. If this is the case, please change the sample rate to 오디오 장치가 필요한 샘플링 속도 설정을 지원하지 않습니다. 이 오류는 오디오 장치의 하드웨어 스위치로 샘플 속도를 설정하는 Roland UA-25EX와 같은 오디오 인터페이스가 있는 경우 발생할 수 있습니다. 이 경우 샘플 속도를 Hz on the device and restart the Hz로 바꾸고 소프트웨어를 software. 다시 시작하세요. The audio device does not support the required number of channels. The required number of channels for input and output is: 오디오 장치가 필요한 채널 수를 지원하지 않습니다. 입력 및 출력에 필요한 채널 수는 다음과 같습니다: Required audio sample format not available. 필요한 오디오 샘플 형식을 사용할 수 없습니다. The selected audio device is no longer present in the system. Please check your audio device. 선택한 오디오 장치가 더 이상 시스템에 없습니다. 오디오 장치를 확인해 주세요. Couldn't initialise the audio driver. Check if your audio hardware is plugged in and verify your driver settings. 오디오 드라이버를 시작할 수 없습니다. 오디오 하드웨어가 연결되어 있는지 확인하시고 드라이버 설정을 확인해 주세요. The selected audio device is incompatible since it doesn't support a sample rate of %1 Hz. Please select another device. 선택한 오디오 장치는 %1 Hz의 샘플 속도를 지원하지 않으므로 호환되지 않습니다. 다른 장치를 선택해 주세요. The current audio device configuration is incompatible because the sample rate couldn't be set to %2 Hz. Please check for a hardware switch or driver setting to set the sample rate manually and restart %1. 샘플 속도를 %2 Hz로 설정할 수 없기 때문에 현재 오디오 장치 구성이 호환되지 않습니다. 샘플링 속도를 수동으로 설정하려면 하드웨어 스위치나 드라이버 설정을 확인하고 %1 다시 시작해 주세요. The selected audio device is incompatible since it doesn't support %1 in/out channels. Please select another device or configuration. 선택한 오디오 장치는 %1 입력/출력 채널을 지원하지 않으므로 호환되지 않습니다. 다른 장치 또는 구성을 선택해 주세요. The selected audio device is incompatible since the required audio sample format isn't available. Please use another device. 필요한 오디오 샘플 형식을 사용할 수 없으므로 선택한 오디오 장치가 호환되지 않습니다. 다른 장치를 사용해 주세요. No ASIO audio device driver found. ASIO 오디오 장치 드라이버를 찾을 수 없습니다. Please install an ASIO driver before running %1. If you own a device with ASIO support, install its official ASIO driver. If not, you'll need to install a universal driver like ASIO4ALL. %1 실행 전에 ASIO 드라이버를 설치해 주세요. ASIO를 지원하는 장치를 소유하고 계시면 공식 ASIO 드라이버를 설치하세요. 그렇지 않은 경우 ASIO4ALL과 같은 범용 드라이버를 설치해야 합니다. Please install an ASIO driver before running %1. If you own a device with ASIO support, install its official ASIO driver. If not, you'll need to download and install a universal driver like ASIO4ALL. %1 실행 전에 ASIO 드라이버를 설치해 주세요. ASIO를 지원하는 장치를 소유하고 계시면 공식 ASIO 드라이버를 설치하세요. 그렇지 않은 경우 ASIO4ALL과 같은 범용 드라이버를 다운로드해서 설치해야 합니다. No ASIO audio device (driver) found. ASIO 오디오 장치(드라이버)를 찾을 수 없습니다. The The software requires the low latency audio interface ASIO to work properly. This is not a standard Windows audio interface and therefore a special audio driver is required. Either your sound card has a native ASIO driver (which is recommended) or you might want to use alternative drivers like the ASIO4All driver. 소프트웨어가 제대로 작동하려면 낮은 지연 오디오 인터페이스 ASIO가 필요합니다. 이것은 표준 Windows 오디오 인터페이스가 아니므로 특별한 오디오 드라이버가 필요합니다. 사운드 카드에 기본 ASIO 드라이버(권장)가 있거나 ASIO4All 드라이버와 같은 대체 드라이버를 사용할 수 있습니다. Error requesting stream stop: $s 오류 발생 스트림 중지 요청: $s Error closing stream: $s 오류 발생 스트림 닫기: $s JACK couldn't be started automatically. Please start JACK manually and check for error messages. JACK을 자동으로 시작할 수 없습니다. JACK을 수동으로 시작하고 오류 메시지를 확인해 주세요. JACK isn't running at a sample rate of <b>%1 Hz</b>. Please use a tool like <i><a href="https://qjackctl.sourceforge.io">QjackCtl</a></i> to set the the JACK sample rate to %1 Hz. JACK이 <b>%1 Hz</b> 샘플 레이트에서 실행되고 있지 않습니다. <i><a href="https://qjackctl.sourceforge.io">QjackCtl</a></i> 같은 도구를 이용해서 JACK 샘플 속도를 %1 Hz로 설정해 주세요. The JACK port registration failed. This is probably an error with JACK. Please stop %1 and JACK. Afterwards check if another program at a sample rate of %2 Hz can connect to JACK. JACK 포트 등록에 실패했습니다. 이것은 아마도 JACK의 오류일 겁니다. %1 및 JACK을 중지해 주세요. 샘플 레이트가 %2 Hz인 다른 프로그램이 JACK에 연결할 수 있는지 확인해 주세요. The JACK port registration failed. This is probably an error with JACK. Please stop %1 and JACK. Afterwards, check if another MIDI program can connect to JACK. JACK 포트 등록에 실패했습니다. 이것은 아마도 JACK의 오류일 겁니다. %1 및 JACK을 중지해 주세요. 그런 다음 다른 MIDI 프로그램이 JACK에 연결할 수 있는지 확인해 주세요. Can't activate the JACK client. This is probably an error with JACK. Please check the JACK output. JACK 클라이언트를 활성화할 수 없습니다. 이것은 아마도 JACK의 오류일 겁니다. JACK의 출력을 확인해 주세요. JACK was shut down. %1 requires JACK to run. Please restart %1 to start JACK again. JACK이 종료되었습니다. %1의 실행에는 JACK이 필요합니다. JACK을 다시 실행하려면 %1을(를) 다시 시작하십시오. No sound card is available in your system. CoreAudio input AudioHardwareGetProperty call failed. CoreAudio input AudioHardwareGetProperty call failed. 시스템에 사용할 수 있는 사운드 카드가 없습니다. No sound card is available in the system. CoreAudio output AudioHardwareGetProperty call failed. CoreAudio output AudioHardwareGetProperty call failed. 시스템에 사용할 수 있는 사운드 카드가 없습니다. The currently selected audio device is no longer present. Please check your audio device. 선택한 오디오 장치가 더 이상 시스템에 없습니다. 오디오 장치를 확인해 주세요. The audio input device is no longer available. Please check if your input device is connected correctly. 오디오 입력 장치를 더 이상 사용할 수 없습니다. 입력 장치가 올바르게 연결되어 있는지 확인해 주세요. The sample rate on the current input device isn't %1 Hz and is therefore incompatible. Please select another device or try setting the sample rate to %1 Hz manually via Audio-MIDI-Setup (in Applications->Utilities). 현재 입력 장치의 샘플 속도가 %1 Hz가 아니므로 호환되지 않습니다. 다른 장치를 선택하시거나 오디오-MIDI-설정(애플리케이션->유틸리티)을 통해 수동으로 샘플 속도를 %1 Hz로 설정해 보세요. The audio output device is no longer available. Please check if your output device is connected correctly. 오디오 출력 장치를 더 이상 사용할 수 없습니다. 출력 장치가 올바르게 연결되어 있는지 확인해 주세요. The sample rate on the current output device isn't %1 Hz and is therefore incompatible. Please select another device or try setting the sample rate to %1 Hz manually via Audio-MIDI-Setup (in Applications->Utilities). 현재 출력 장치의 샘플 속도가 %1 Hz가 아니므로 호환되지 않습니다. 다른 장치를 선택하시거나 오디오-MIDI-설정(애플리케이션->유틸리티)을 통해 수동으로 샘플 속도를 %1 Hz로 설정해 보세요. The stream format on the current input device isn't compatible with this software. Please select another device. 현재 입력 장치의 스트림 형식이 이 소프트웨어와 호환되지 않습니다. 다른 장치를 선택해 주세요. The stream format on the current output device isn't compatible with %1. Please select another device. 현재 출력 장치의 스트림 형식과 %1의 호환이 되지 않습니다. 다른 장치를 선택해 주세요. The buffer sizes of the current input and output audio device can't be set to a common value. Please select different input/output devices in your system settings. 현재 입력 및 출력 오디오 장치의 버퍼 크기는 공통 값으로 설정할 수 없습니다. 시스템 설정에서 다른 입력/출력 장치를 선택해 주세요. CSoundBase The selected audio device could not be used because of the following error: 다음 오류로 인해 선택한 오디오 장치를 사용할 수 없습니다: The previous driver will be selected. 이전 드라이버가 선택됩니다. The previously selected audio device is no longer available or the audio driver properties have changed to a state which is incompatible with this software. We now try to find a valid audio device. This new audio device might cause audio feedback. So, before connecting to a server, please check the audio device setting. 이전에 선택한 오디오 장치를 더 이상 사용할 수 없거나 오디오 드라이버 속성이 이 소프트웨어와 호환되지 않는 상태로 변경되었습니다. 이제 유효한 오디오 장치를 찾으려고 합니다. 이 새로운 오디오 장치는 오디오 피드백을 유발할 수 있습니다. 따라서 서버에 연결하기 전에 오디오 장치 설정을 확인해 주세요. No usable 사용할 수 없음 audio device (driver) found. 오디오 장치(드라이버)를 찾았습니다. In the following there is a list of all available drivers with the associated error message: 관련 오류 메시지와 함께 사용 가능한 모든 드라이버 목록입니다: Do you want to open the ASIO driver setups? ASIO 드라이버 설정을 여시겠습니까? could not be started because of audio interface issues. 오디오 인터페이스 문제로 인해 시작할 수 없습니다. Can't use the selected audio device because of the following error: %1 The previous driver will be selected. 다음 오류 때문에 선택한 오디오 장치를 사용할 수 없습니다: %1 이전 드라이버가 선택될 겁니다. The previously selected audio device is no longer available or the driver has changed to an incompatible state. We'll attempt to find a valid audio device, but this new audio device may cause feedback. Before connecting to a server, please check your audio device settings. 이전에 선택한 오디오 장치를 더 이상 사용할 수 없거나 드라이버가 호환되지 않는 상태로 변경되었습니다. 유효한 오디오 장치를 찾으려고 시도하겠습니다. 하지만, 이 새 오디오 장치로 인해 피드백이 발생할 수 있습니다. 서버에 연결하기 전에 오디오 장치 설정을 확인해 주세요. <b>%1 couldn't find a usable %2 audio device.</b><br><br> <b>%1에서 사용 가능한 %2 오디오 장치를 찾을 수 없습니다.</b><br><br> You may be able to fix errors in the driver settings. Do you want to open these settings now? 드라이버 설정에서 오류를 수정할 수 있습니다. 지금 이 설정을 여시겠습니까? No usable %1 audio device found. 사용 가능한 %1 오디오 장치를 찾을 수 없습니다. These are all the available drivers with error messages: 다음은 오류 메시지와 함께 사용 가능한 모든 드라이버입니다: Do you want to open the ASIO driver setup to try changing your configuration to a working state? ASIO 드라이버 설정을 열어 구성을 작동 상태로 변경하시겠습니까? Can't start %1. Please restart %1 and check/reconfigure your audio settings. %1 시작할 수 없습니다. %1 다시 시작하고 오디오 설정을 확인/재구성 해주세요. QCoreApplication %1, Version %2 %1, 버전 %2 Internet Jam Session Software 인터넷 잼 세션 소프트웨어 %1, Version %2 %1 is app name, %2 is version number %1, 버전 %2 Released under the GNU General Public License version 2 or later (GPLv2) GNU 일반 공중 허가서 버전 2 또는 이후 버전에 따라 출시됨 (GPLv2) This program is free software; you can redistribute it and/or modify it under 이 프로그램은 자유 소프트웨어입니다 the terms of the GNU General Public License as published by the Free Software 자유 소프트웨어 재단에서 발행한 GNU 일반 공중 사용 허가서의 조건에 따라 이를 재배포 및/또는 수정할 수 있습니다 Foundation; either version 2 of the License, or (at your option) any later version. 라이선스 버전 2 또는 (귀하의 선택에 따라) 이후 버전. There is NO WARRANTY, to the extent permitted by law. 법이 허용하는 한도 내에서 어떠한 보증도 하지 않습니다. Using the following libraries, resources or code snippets: 다음의 libraries, resources 또는 code snippets을 사용합니다: Qt framework Qt framework Opus Interactive Audio Codec Opus Interactive Audio Codec Audio reverberation code by Perry R. Cook and Gary P. Scavone Audio reverberation code by Perry R. Cook and Gary P. Scavone Some pixmaps are from the Open Clip Art Library (OCAL) 일부 픽스맵은 OCAL(Open Clip Art Library)에서 가져온 것입니다 Flag icons by Mark James 깃발 아이콘 by Mark James Copyright (C) 2005-2022 The Jamulus Development Team Copyright (C) 2005-2022 The Jamulus Development Team Released under the GNU General Public License (GPL) GNU 일반 공중 사용 허가서에 따라 출시됨 (GPL) global A %1 upgrade is available: <a style='color:red;' href='https://jamulus.io/upgrade?progversion=%2'>go to details and downloads</a> %1 업그레이드를 사용할 수 있습니다. <a style='color:red;' href='https://jamulus.io/upgrade?progversion=%2'>세부 정보 및 다운로드로 이동</a> For more information use the "What's This" help (help menu, right mouse button or Shift+F1) 자세한 내용은 "What's This"를 사용하세요. 도움말(도움말 메뉴, 마우스 오른쪽 버튼 또는 Shift+F1) jamulus-3.9.1+dfsg/src/translation/translation_nl_NL.ts0000644000175000017500000102264314340334543022301 0ustar vimervimer CAboutDlg The De software enables musicians to perform real-time jam sessions over the internet. software stelt muzikanten in staat om real-time jamsessies uit te voeren via het internet. There is a Er is een server which collects the audio data from each server die audiodata van elke client verzamelt, client, mixes the audio data and sends the mix back to each client. deze mixt, en de mix weer terugstuurt naar iedere client. uses the following libraries, resources or code snippets: gebruikt de volgende libraries, bronnen of code snippets: Qt cross-platform application framework Qt cross-platform applicatieframework Audio reverberation code by Perry R. Cook and Gary P. Scavone Audio reverberatiecode door Perry R. Cook en Gary P. Scavone Some pixmaps are from the Sommige pixmaps zijn van de Country flag icons from Mark James Landvlag-iconen van Mark James This app enables musicians to perform real-time jam sessions over the internet. Deze applicatie stelt muzikanten in staat om real-time jamsessies uit te voeren via het internet. There is a server which collects the audio data from each client, mixes the audio data and sends the mix back to each client. Een server verzamelt de audiodata van elke client, mixt deze en stuurt de mix weer terug naar iedere client. This app uses the following libraries, resources or code snippets: Deze applicatie gebruikt de volgende libraries, bronnen of code snippets: Country flag icons by Mark James Landvlag-iconen van Mark James For details on the contributions check out the Voor details over de bijdragen, zie de Flag icons by Mark James Vlag-iconen van Mark James Some sound samples are from Sommige geluiden komen van For details on the contributions check out the %1 Voor details over de bijdragen, zie de %1 Github Contributors list Github bijdragerslijst Spanish Spaans French Frans Portuguese Portugees Dutch Nederlands Italian Italiaans German Duits Polish Pools Swedish Zweeds Korean Koreaans Slovak Slowaaks Simplified Chinese Chinees (vereenvoudigd) Norwegian Bokmål About %1 Over %1 About Over , Version , Versie Internet Jam Session Software Internet Jamsessie Software Under the GNU General Public License (GPL) Onder de GNU General Public License (GPL) CAboutDlgBase About Over TextLabelVersion Tekstlabel versie Copyright (C) 2005-2022 Volker Fischer and others Copyright (C) 2005-2022 Volker Fischer en anderen Copyright (C) 2005-2022 The Jamulus Development Team Copyright (C) 2005-2022 het Jamulus Development Team A&bout &Over &Libraries &Libraries &Contributors &Bijdragers &Translation &Vertaling &OK O&K CAnalyzerConsole Analyzer Console Analyzer console Error Rate of Each Buffer Size Foutpercentage van elke buffergrootte CAudioMixerBoard Personal Mix at the Server Eigen mix op de server When connected to a server, the controls here allow you to set your local mix without affecting what others hear from you. The title shows the server name and, when known, whether it is actively recording. Indien verbonden met de server kan hier de lokale mix ingesteld worden zonder dat hetgeen anderen horen wordt beïnvloed. De titel toont de servernaam en indien bekend is of er audio wordt opgenomen. Server Server T R Y I N G T O C O N N E C T A A N H E T V E R B I N D E N RECORDING ACTIVE GELUIDSOPNAME ACTIEF Personal Mix at: %1 Eigen mix op: %1 CChannelFader Pan Bal. Mute Demp Solo Solo &No grouping &Geen groepering Assign to group Toewijzen aan groep The fader tag identifies the connected client. The tag name, a picture of your instrument and the flag of your location can be set in the main window. De fadertag identificeert de verbonden client. De tagnaam, de afbeelding van uw instrument en een vlag van uw locatie kunnen in het hoofdvenster worden ingesteld. Mixer channel country/region flag Land/regio vlag van het kanaal Grp Grp Channel Level Kanaalniveau Displays the pre-fader audio level of this channel. All connected clients at the server will be assigned an audio level, the same value for each client. Geeft het pre-fader-audioniveau van dit kanaal weer. Alle verbonden clients op de server krijgen een audioniveau toegewezen, dezelfde waarde voor elke client. Input level of the current audio channel at the server Invoerniveau van het huidige audiokanaal op de server Mixer Fader Mixer fader Adjusts the audio level of this channel. All connected clients at the server will be assigned an audio fader at each client, adjusting the local mix. Past het geluidsniveau van dit kanaal aan. Alle verbonden clients op de server krijgen een audiofader toegewezen bij elke client, waarbij de lokale mix wordt aangepast. Local mix level setting of the current audio channel at the server Lokale instelling van het mixniveau van het huidige audiokanaal op de server Status Indicator Statusindicatie Shows a status indication about the client which is assigned to this channel. Supported indicators are: Toont de status van de muzikant die aan dit kanaal is toegewezen. Ondersteunde indicaties: Status indicator label Statusindicatielabel Panning Balans Local panning position of the current audio channel at the server Lokale balans-positie van het huidige audiokanaal op de server With the Mute checkbox, the audio channel can be muted. Met het Demp selectievakje kan het audiokanaal worden gedempt. Mute button Dempknop With the Solo checkbox, the audio channel can be set to solo which means that all other channels except of the current channel are muted. It is possible to set more than one channel to solo. Met het selectievakje Solo kan het audiokanaal worden ingesteld op solo, zodat alle overige kanalen worden gedempt. Het is mogelijk om meer dan één kanaal op solo in te stellen. Solo button Soloknop Fader Tag Fader tag The fader tag identifies the connected client. The tag name, the picture of your instrument and a flag of your country can be set in the main window. De fadertag identificeert de verbonden client. De tagnaam, de afbeelding van uw instrument en een vlag van uw land kunnen in het hoofdvenster worden ingesteld. Displays the pre-fader audio level of this channel. All clients connected to the server will be assigned an audio level, the same value for every client. Geeft het pre-fader-audioniveau van dit kanaal weer. Alle clients die verbonden zijn met de server krijgen een audioniveau toegewezen, dezelfde waarde voor elke client. Adjusts the audio level of this channel. All clients connected to the server will be assigned an audio fader, displayed at each client, to adjust the local mix. Past het geluidsniveau van dit kanaal aan. Alle verbonden clients op de server krijgen een audiofader toegewezen, waarmee de lokale mix kan worden aangepast. Speaker with cancellation stroke: Indicates that another client has muted you. Doorgestreepte luidspreker: Geeft aan dat een andere muzikant u gedempt heeft. Sets the pan from Left to Right of the channel. Works only in stereo or preferably mono in/stereo out mode. Stelt de balans in van links naar rechts. Werkt alleen in stereo of bij voorkeur voor mono in/stereo uit mode. With the Solo checkbox, the audio channel can be set to solo which means that all other channels except the soloed channel are muted. It is possible to set more than one channel to solo. Met het Solo selectievakje kan het audiokanaal worden ingesteld op solo, zodat alle overige kanalen worden gedempt. Het is mogelijk om meer dan één kanaal op solo in te stellen. Group Groep With the Grp checkbox, a group of audio channels can be defined. All channel faders in a group are moved in proportional synchronization if any one of the group faders are moved. Met het Grp selectievakje kan een groep van audiokanalen worden gedefinieerd. Alle kanaalfaders in een groep bewegen mee indien een van de faders wordt verschoven. Group button Groepknop The fader tag identifies the connected client. The tag name, a picture of your instrument and the flag of your country can be set in the main window. De fadertag identificeert de verbonden client. De tagnaam, de afbeelding van uw instrument en een vlag van uw land kunnen in het hoofdvenster worden ingesteld. Mixer channel instrument picture Afbeelding van het mengkanaalinstrument Mixer channel label (fader tag) Label van het mengkanaal (faderlabel) Mixer channel country flag Landvlag van het kanaal PAN BAL. MUTE DEMP SOLO SOLO GRP GRP M M S S G G Alias/Name Alias/naam Instrument Instrument Location Locatie Skill Level Vaardigheidsniveau Alias Alias Beginner Beginner Intermediate Gemiddeld Expert Gevorderd Musician Profile Muzikantenprofiel CChatDlg Chat Window Chatvenster The chat window shows a history of all chat messages. Het chatvenster toont een geschiedenis van alle chatberichten. Chat history Chatgeschiedenis Input Message Text Tekst van het invoerbericht Enter the chat message text in the edit box and press enter to send the message to the server which distributes the message to all connected clients. Your message will then show up in the chat window. Type het chatbericht in het bewerkingsvak in en druk op enter om het bericht naar de server te sturen, die het bericht naar alle verbonden clients distribueert. Uw bericht verschijnt dan in het chatvenster. New chat text edit box Nieuw chat tekstbewerkingsvak Type a message here Typ hier een bericht &Edit &Bewerk Cl&ear Chat History &Wis chatgeschiedenis &Close &Sluiten Do you want to open the link '%1' in your browser? Wilt u de link '%1' in uw browser openen? Do you want to open the link Wilt u de link openen in an external browser? in een externe browser? CChatDlgBase Chat Chat &Send &Verstuur Cl&ear Wiss&en &Close &Sluiten CClientDlg Input Level Meter Ingangsniveaumeter The input level indicators show the input level of the two stereo channels of the current selected audio input. De indicatoren voor het ingangsniveau geven het ingangsniveau van de twee stereokanalen van de huidige geselecteerde audio-ingang weer. Make sure not to clip the input signal to avoid distortions of the audio signal. Zorg ervoor dat u het ingangssignaal niet clipt om vervorming van het audiosignaal te voorkomen. If the Als de software is connected and you play your instrument/sing in the microphone, the LED level meter should flicker. If this is not the case, you have probably selected the wrong input channel (e.g. line in instead of the microphone input) or set the input gain too low in the (Windows) audio mixer. software is verbonden en u speelt of zingt in de microfoon, dan zou de LED-niveaumeter moeten flikkeren. Als dit niet het geval is, heeft u waarschijnlijk het verkeerde ingangskanaal gekozen (bijv. line in i.p.v. de microfooningang) of heeft u de ingangsversterking te laag ingesteld in de (Windows) audiomixer. For a proper usage of the Voor juist gebruik van de software, you should not hear your singing/instrument in the loudspeaker or your headphone when the software, moet uw zang/instrument niet hoorbaar zijn door de luidspreker of uw koptelefoon wanneer de software is not connected. This can be achieved by muting your input audio channel in the Playback mixer (not the Recording mixer!). software niet is verbonden. Dit kan worden bereikt door het geluidskanaal in de afspeelmixer (niet de opnamemixer!) te dempen. Input level meter Ingangsniveaumeter Simulates an analog LED level meter. Simuleert een analoge LED-niveaumeter. Connect/Disconnect Button Verbinden/afmelden-knop Push this button to connect to a server. A dialog where you can select a server will open. If you are connected, pressing this button will end the session. Druk op deze knop om verbinding te maken met een server. In het daaropvolgende dialoogvenster kunt u een server kunt selecteren. Als u verbonden bent, wordt de sessie beëindigd door weer op deze knop te drukken. Connect and disconnect toggle button Knop voor het opzetten en verbreken van de verbinding Clicking on this button changes the caption of the button from Connect to Disconnect, i.e., it implements a toggle functionality for connecting and disconnecting the Door op deze knop te klikken verandert het onderschrift van de knop van Verbinden naar Verbreken, d.w.z. dat het een toggle-functie heeft voor verbinden/verbreken van de software. software. Local Audio Input Fader Lokale audio-ingangsfader With the audio fader, the relative levels of the left and right local audio channels can be changed. For a mono signal it acts like a panning between the two channels. If, e.g., a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows Met de audiofader kunnen de relatieve niveaus van de linker en rechter lokale audiokanalen worden gewijzigd. Voor een monosignaal werkt het als een balans tussen de twee kanalen. Als bijvoorbeeld een microfoon is verbonden op het rechter ingangskanaal en een veel luider instrument is verbonden op het linker ingangskanaal, beweeg dan de audiofader in de richting: L L , where , waar is the current attenuation indicator. is de huidige dempingsindicator. Local audio input fader (left/right) Lokale audio-ingangsfader (links/rechts) Reverberation Level Niveau van de galm A reverberation effect can be applied to one local mono audio channel or to both channels in stereo mode. The mono channel selection and the reverberation level can be modified. If, e.g., the microphone signal is fed into the right audio channel of the sound card and a reverberation effect shall be applied, set the channel selector to right and move the fader upwards until the desired reverberation level is reached. Een galmeffect kan worden toegepast op één lokaal mono-audiokanaal of op beide kanalen in de stereomodus. De monokanaalselectie en het galmniveau kunnen worden aangepast. Als bijvoorbeeld het microfoonsignaal in het juiste audiokanaal van de geluidskaart binnenkomt en er een galmeffect wordt toegepast, zet u de kanaalkeuzeschakelaar naar rechts en beweegt u de fader omhoog tot het gewenste galmniveau is bereikt. The reverberation effect requires significant CPU so it should only be used on fast PCs. If the reverberation level fader is set to minimum (which is the default setting), the reverberation effect is switched off and does not cause any additional CPU usage. Het galmeffect vereist aanzienlijk wat CPU, zodat deze alleen op snelle PC's kan worden gebruikt. Als de fader voor het galmniveau op minimaal is ingesteld (wat de standaardinstelling is), wordt het galmeffect uitgeschakeld en veroorzaakt het geen extra CPU-gebruik. Reverberation effect level setting Instelling van het niveau van het galmeffect Reverberation Channel Selection Selectie van het galmkanaal With these radio buttons the audio input channel on which the reverberation effect is applied can be chosen. Either the left or right input channel can be selected. Met deze radioknoppen kan het audio-invoerkanaal worden gekozen waarop het galmeffect wordt toegepast. Het linker of rechter ingangskanaal kan worden gekozen. Left channel selection for reverberation Linker kanaalselectie voor galm Right channel selection for reverberation Rechter kanaalselectie voor galm Delay Status LED Vertragingsstatus LED The delay status LED indicator shows the current audio delay status. If the light is green, the delay is perfect for a jam session. If the light is yellow, a session is still possible but it may be harder to play. If the light is red, the delay is too large for jamming. De vertragingsstatus LED-indicator geeft de huidige geluidsvertragingsstatus aan. Als het lampje groen is, is de vertraging perfect voor een storingssessie. Als het lampje geel is, is een sessie nog steeds mogelijk, maar kan het moeilijker zijn om te spelen. Als het lichtje rood is, is de vertraging te groot voor een storing. If this LED indicator turns red, you will not have much fun using the Als deze LED-indicator rood wordt, zult u niet veel plezier beleven aan het gebruik van de Delay status LED indicator Vertraging status LED-indicator Buffers Status LED Buffers status LED-indicator The buffers status LED indicator shows the current audio/streaming status. If the light is green, there are no buffer overruns/underruns and the audio stream is not interrupted. If the light is red, the audio stream is interrupted caused by one of the following problems: De indicator voor de status van de buffers geeft de huidige status van de audio/streaming aan. Als het lampje groen is, zijn er geen bufferoverschrijdingen/onderschrijdingen en wordt de audiostream niet onderbroken. Als het lampje rood is, wordt de audiostream onderbroken door een van de volgende problemen: The network jitter buffer is not large enough for the current network/audio interface jitter. De buffer voor de netwerkjitter is niet groot genoeg voor de huidige netwerk-/audio-interfacejitter. The sound card buffer delay (buffer size) is set to too small a value. De buffer vertraging van de geluidskaart (buffergrootte) is op een te kleine waarde ingesteld. The upload or download stream rate is too high for the current available internet bandwidth. De upload- of downloadstroomsnelheid is te hoog voor de huidige beschikbare internetbandbreedte. This shows the level of the two stereo channels for your audio input. Dit toont het niveau van de twee stereokanalen voor de audio-invoer. If the application is connected to a server and you play your instrument/sing into the microphone, the VU meter should flicker. If this is not the case, you have probably selected the wrong input channel (e.g. 'line in' instead of the microphone input) or set the input gain too low in the (Windows) audio mixer. Indien de applicatie verbonden is met een server en in de microfoon wordt gespeeld of gezongen, dan zou de LED-niveaumeter moeten flikkeren. Als dit niet het geval is, dan heeft u waarschijnlijk het verkeerde ingangskanaal gekozen (bijv. line in i.p.v. de microfooningang) of heeft u de ingangsversterking te laag ingesteld in de (Windows) audiomixer. For proper usage of the application, you should not hear your singing/instrument through the loudspeaker or your headphone when the software is not connected. This can be achieved by muting your input audio channel in the Playback mixer (not the Recording mixer!). Voor goed gebruik van de applicatie moet u de zang of het instrument niet via de luidspreker of koptelefoon horen als de software niet verbonden is. Dit kan worden bereikt door het dempen van het audiokanaal in de afspeelmixer (niet de opnamemixer!). Clicking on this button changes the caption of the button from Connect to Disconnect, i.e., it implements a toggle functionality for connecting and disconnecting the application. Door op deze knop te klikken verandert het onderschrift van de knop van Verbinden naar Verbreken, d.w.z. dat het een toggle-functie heeft voor verbinden/verbreken. Controls the relative levels of the left and right local audio channels. For a mono signal it acts as a pan between the two channels. For example, if a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows Met de audiofader kunnen de relatieve niveaus van de linker en rechter lokale audiokanalen worden gewijzigd. Voor een monosignaal werkt het als een panning tussen de twee kanalen. Als bijvoorbeeld een microfoon is verbonden op het rechter ingangskanaal en een veel luider instrument is verbonden op het linker ingangskanaal, beweeg dan de audiofader in de richting van het label Reverb effect Galm-effect Reverb can be applied to one local mono audio channel or to both channels in stereo mode. The mono channel selection and the reverb level can be modified. For example, if a microphone signal is fed in to the right audio channel of the sound card and a reverb effect needs to be applied, set the channel selector to right and move the fader upwards until the desired reverb level is reached. Een galmeffect kan worden toegepast op één lokaal mono-audiokanaal of op beide kanalen in de stereomodus. De monokanaalselectie en het galmniveau kunnen worden aangepast. Als bijvoorbeeld het microfoonsignaal in het juiste audiokanaal van de geluidskaart binnenkomt en er een galmeffect wordt toegepast, zet u de kanaalkeuzeschakelaar naar rechts en beweegt u de fader omhoog tot het gewenste galmniveau is bereikt. Reverb effect level setting Instelling van het niveau van het galmeffect Reverb Channel Selection Selectie van het galmkanaal With these radio buttons the audio input channel on which the reverb effect is applied can be chosen. Either the left or right input channel can be selected. Met deze radioknoppen kan het audio-invoerkanaal worden gekozen waarop het galmeffect wordt toegepast. Het linker of rechter ingangskanaal kan worden gekozen. Left channel selection for reverb Linker kanaalselectie voor galm Right channel selection for reverb Rechter kanaalselectie voor galm Green Groen The delay is perfect for a jam session. De vertraging is prima voor een jamsessie. Yellow Geel Red Rood Opens a dialog where you can select a server to connect to. If you are connected, pressing this button will end the session. Laat een dialoog zien waarin u een server kunt selecteren om mee te verbinden. Indien reeds verbonden verbreekt deze knop de verbinding. Shows the current audio delay status: Toont de huidige geluidsvertragingsstatus: A session is still possible but it may be harder to play. Een sessie is nog mogelijk maar zal moeilijk gaan. The delay is too large for jamming. De vertraging is te groot voor een jamsessie. If this LED indicator turns red, you will not have much fun using the application. Als deze LED-indicator rood wordt, zult u niet veel plezier eraan beleven. The buffers status LED shows the current audio/streaming status. If the light is red, the audio stream is interrupted. This is caused by one of the following problems: De bufferstatus-LED toont de huidige audio/streaming status. Indien rood dan wordt de audio-stream onderbroken. Dit kan veroorzaakt worden door de volgende problemen: The sound card's buffer delay (buffer size) is too small (see Settings window). De buffer vertraging van de geluidskaart (buffergrootte) is op een te kleine waarde ingesteld. The upload or download stream rate is too high for your internet bandwidth. De bitsnelheid van de audio staat te hoog voor de huidige beschikbare internetbandbreedte. The CPU of the client or server is at 100%. De CPU van de client of server staat op 100%. Buffers status LED indicator Status van de buffers LED-indicator Current Connection Status Parameter Huidige verbindingsstatus-parameter The Ping Time is the time required for the audio stream to travel from the client to the server and back again. This delay is introduced by the network and should be about 20-30 ms. If this delay is higher than about 50 ms, your distance to the server is too large or your internet connection is not sufficient. De ping-tijd is de tijd die nodig is voor de audiostream om van de client naar de server en terug te reizen. Deze vertraging wordt veroorzaakt door het netwerk en bedraagt ongeveer 20-30 ms. Als deze vertraging hoger is dan circa 50 ms, dan is uw afstand tot de server te groot of is uw internetverbinding niet toereikend. Overall Delay is calculated from the current Ping Time and the delay introduced by the current buffer settings. De totale vertraging wordt berekend op basis van de huidige ping-tijd en de vertraging door de huidige bufferinstellingen. C&onnect &Verbinden software upgrade available software-update beschikbaar &File &Bestand &View &Weergave &Connection Setup... &Verbindingsinstellingen... My &Profile... Mijn &profiel... C&hat... &Chat... &Settings... &Instellingen... &Analyzer Console... &Analyzer console... N&o User Sorting Kanalen niet s&orteren Sort Users by &City Sorteer muzikanten op &Stad Use &Two Rows Mixer Panel Gebruik &Twee-rijen-mengpaneel Clear &All Stored Solo and Mute Settings &Wis alle opgeslagen solo- en demp-instellingen Auto-Adjust all &Faders Stel alle &faders automatisch in Sett&ings In&stellingen %1 Directory %1 adresboek Ok Ok Clear &All Stored Solo Settings &Wis Alle Opgeslagen Solo-instellingen Set All Faders to New Client &Level &Zet alle faders op nieuw client-niveau E&xit &Afsluiten Local Jitter Buffer Status LED Lokale jitterbuffer status LED The local jitter buffer status LED shows the current audio/streaming status. If the light is red, the audio stream is interrupted. This is caused by one of the following problems: De lokale jitterbuffer status LED geeft de huidige audio/streaming status weer. Indien deze rood is dan wordt de audio onderbroken. Dit komt door één van de volgende problemen: Local Jitter Buffer status LED indicator Lokale jitterbuffer LED status indicator If this LED indicator turns red, you will not have much fun using the %1 software. Als deze LED-indicator rood wordt, zult u niet veel plezier beleven aan het gebruik van de %1 software. &Load Mixer Channels Setup... Mixer kanaalinstellingen &laden... &Save Mixer Channels Setup... Mixer kanaalinstellingen &opslaan... &Settings &Instellingen Audio/Network &Settings... Audio-/netwerk-&instellingen... A&dvanced Settings... Geavanceer&de instellingen... &Edit B&ewerken If this LED indicator turns red, you will not have much fun using %1. Als deze LED-indicator rood wordt, zult u niet veel plezier beleven aan het gebruik van %1. If this LED indicator turns red, the audio stream is interrupted. Als deze LED-indicator rood wordt, dan wordt de audiostream onderbroken. Current Connection Status Huidige verbindingsstatus O&wn Fader First &Eigen fader eerst Sort Users by &Name Sorteer muzikanten op &Naam Sort Users by &Instrument Sorteer muzikanten op &Instrument Sort Users by &Group Sorteer muzikanten op &Groep None Geen Center Midden R R Directory Server Adresboek server Select Channel Setup File Selecteer bestand met kanaalinstellingen user gebruiker users gebruikers Connect Verbinden Settings Instellingen Chat Chat Enable feedback detection Feedback detectie inschakelen Audio feedback or loud signal detected. We muted your channel and activated 'Mute Myself'. Please solve the feedback issue first and unmute yourself afterwards. Audio feedback of zeer luid signaal gedetecteerd. We hebben uw kanaal gedempt en 'Demp mijzelf' geactiveerd. Los eerst het probleem met de audio feedback op en schakel daarna 'Demp mijzelf' uit. Your sound card is not working correctly. Please open the settings dialog and check the device selection and the driver settings. Uw geluidskaart werkt niet goed. Open het Instellingsvenster en controleer apparaatselectie en bestuurprogramma-instellingen. &Disconnect &Afmelden CClientDlgBase Delay Vertraging Buffers Buffers Input Invoer L L R R Jitter Jitter Ping Ping ms ms &Mute Myself Demp &mijzelf &Settings &Instellingen &Chat &Chat C&onnect &Verbinden Pan Balans Center Midden Reverb Galm Left Links Right Rechts MUTED (Other people won't hear you) GEDEMPT (Anderen horen u niet) Set up your audio, connect to a server and start jamming! Stel de audio in, maak verbinding met een server en begin met jammen! Update check Update controle MUTED (You are not sending any audio to the server) GEDEMPT (Je stuurt geen audio naar de server) CClientSettingsDlg Jitter Buffer Size Jitterbuffer grootte The jitter buffer compensates for network and sound card timing jitters. The size of this jitter buffer has therefore influence on the quality of the audio stream (how many dropouts occur) and the overall delay (the longer the buffer, the higher the delay). De jitterbuffer compenseert voor netwerk- en geluidskaart-timingstoestanden. De grootte van deze jitterbuffer heeft dus invloed op de kwaliteit van de audiostream (hoeveel uitvallers er optreden) en de totale vertraging (hoe langer de buffer, hoe hoger de vertraging). The jitter buffer size can be manually chosen for the local client and the remote server. For the local jitter buffer, dropouts in the audio stream are indicated by the light below the jitter buffer size faders. If the light turns to red, a buffer overrun/underrun took place and the audio stream is interrupted. De jitter-buffergrootte kan handmatig worden gekozen voor de lokale client en de externe server. Voor de lokale jitterbuffer worden drop-outs in de audiostream aangegeven door het lampje op de onderkant van de faders voor de jitterbuffergrootte. Als het lampje op rood springt, heeft er een bufferoverschrijding/onderbenedenrijding plaatsgevonden en wordt de audiostream onderbroken. The jitter buffer setting is therefore a trade-off between audio quality and overall delay. De jitterbufferinstelling is dus een afweging tussen geluidskwaliteit en totale vertraging. An auto setting of the jitter buffer size setting is available. If the check Auto is enabled, the jitter buffers of the local client and the remote server are set automatically based on measurements of the network and sound card timing jitter. If the Auto check is enabled, the jitter buffer size faders are disabled (they cannot be moved with the mouse). Een automatische instelling van de jitterbuffergrootte is beschikbaar. Als de controle Auto is ingeschakeld, worden de jitterbuffers van de lokale client en de externe server automatisch ingesteld op basis van metingen van de netwerk- en geluidskaarttimingsjitter. Als de automatische controle is ingeschakeld, zijn de faders voor de jitterbuffergrootte uitgeschakeld (ze kunnen niet met de muis worden verplaatst). If the auto setting of the jitter buffer is enabled, the network buffers of the local client and the remote server are set to a conservative value to minimize the audio dropout probability. To tweak the audio delay/latency it is recommended to disable the auto setting functionality and to lower the jitter buffer size manually by using the sliders until your personal acceptable limit of the amount of dropouts is reached. The LED indicator will visualize the audio dropouts of the local jitter buffer with a red light. In het geval dat de automatische instelling van de jitterbuffer is ingeschakeld, worden de netwerkbuffers van de lokale client en de externe server op een conservatieve waarde gezet om de kans op audio-uitval te minimaliseren. Om de audio delay/latentie te tweaken is het aan te raden om de automatische instelling uit te schakelen en de grootte van de jitterbuffer handmatig te verlagen met behulp van de schuifregelaars totdat de persoonlijke aanvaardbare limiet van het aantal drop-outs is bereikt. De LED-indicator zal de audio dropouts van de lokale jitterbuffer visualiseren met een rood lampje. Local jitter buffer slider control Lokale jitterbuffer-schuifregelaar Server jitter buffer slider control Server jitterbuffer-schuifregelaar Auto jitter buffer switch Automatische jitterbufferschakelaar Jitter buffer status LED indicator Jitterbuffer status LED-indicator Sound Card Device Geluidskaartapparaat The ASIO driver (sound card) can be selected using Het ASIO-stuurprogramma (geluidskaart) kan worden geselecteerd met behulp van under the Windows operating system. Under MacOS/Linux, no sound card selection is possible. If the selected ASIO driver is not valid an error message is shown and the previous valid driver is selected. onder het Windows besturingssysteem. Onder MacOS/Linux is geen geluidskaartkeuze mogelijk. Als het geselecteerde ASIO-stuurprogramma niet geldig is, wordt een foutmelding weergegeven en wordt het vorige geldige stuurprogramma geselecteerd. If the driver is selected during an active connection, the connection is stopped, the driver is changed and the connection is started again automatically. Als het stuurprogramma tijdens een actieve verbinding wordt geselecteerd, wordt de verbinding gestopt, wordt het stuurprogramma gewijzigd en wordt de verbinding automatisch opnieuw gestart. Sound card device selector combo box Geluidskaart apparaatselectie combobox If the ASIO4ALL driver is used, please note that this driver usually introduces approx. 10-30 ms of additional audio delay. Using a sound card with a native ASIO driver is therefore recommended. In het geval dat de ASIO4ALL driver wordt gebruikt, dient u er rekening mee te houden dat deze driver meestal ongeveer 10-30 ms extra geluidsvertraging introduceert. Het gebruik van een geluidskaart met een native ASIO-driver wordt daarom aanbevolen. If you are using the kX ASIO driver, make sure to connect the ASIO inputs in the kX DSP settings panel. Als u het kX ASIO-stuurprogramma gebruikt, zorg er dan voor dat u de ASIO-ingangen in het kX DSP-instellingenpaneel aansluit. Sound Card Channel Mapping Geluidskaart kanaaltoewijzing If the selected sound card device offers more than one input or output channel, the Input Channel Mapping and Output Channel Mapping settings are visible. In het geval dat het geselecteerde geluidskaartapparaat meer dan één ingangs- of uitgangskanaal biedt, zijn de instellingen voor het ingangs- en uitgangskanaal toewijzing zichtbaar. For each Voor elke input/output channel (Left and Right channel) a different actual sound card channel can be selected. invoer-/uitvoerkanaal (linker- en rechterkanaal) kan een ander daadwerkelijk kanaal van de geluidskaart worden geselecteerd. Left input channel selection combo box Linkeringangskanaal selectie combobox Right input channel selection combo box Rechteringangskanaal selectie combobox Left output channel selection combo box Linkeruitgangskanaal selectie combobox Right output channel selection combo box Rechteruitgangskanaal selectie combobox Enable Small Network Buffers Kleine netwerkbuffers inschakelen If enabled, the support for very small network audio packets is activated. Very small network packets are only actually used if the sound card buffer delay is smaller than Indien ingeschakeld wordt de ondersteuning voor erg kleine netwerkaudiopakketten geactiveerd. Deze worden alleen gebruikt als de buffervertraging van de geluidskaart kleiner is dan samples. The smaller the network buffers, the lower the audio latency. But at the same time the network load increases and the probability of audio dropouts also increases. samples. Hoe kleiner de netwerkbuffers, des te kleiner de audio-vertraging. Maar tegelijkertijd neemt de netwerkbelasting toe en neemt ook de kans op audio-uitval toe. Enable small network buffers check box Schakel het selectievakje kleine netwerkbuffers in Sound Card Buffer Delay Geluidskaart buffervertraging Some sound card drivers do not allow the buffer delay to be changed from within the application. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. On Windows, press the ASIO Device Settings button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Sommige stuurprogramma's van geluidskaarten staan niet toe dat de buffervertraging vanuit een toepassing kan worden gewijzigd. In dat geval is de buffervertragingsinstelling uitgeschakeld en moet deze worden gewijzigd via het stuurprogramma van de geluidskaart. In Windows drukt u op de knop ASIO Apparaatinstellingen om het instellingenpaneel van het stuurprogramma te openen. In Linux gebruikt u het configuratieprogramma van JACK om de buffergrootte te wijzigen. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within the software. On Windows, press the ASIO Device Settings button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Als de buffervertragingsinstellingen zijn uitgeschakeld, staat het stuurprogramma van de geluidskaart niet toe dat deze vanuit Jamulus te wijzigen zijn. In Windows drukt u op de knop ASIO Apparaatinstellingen om het instellingenpaneel van het stuurprogramma te openen. In Linux gebruikt u het configuratieprogramma van JACK om de buffergrootte te wijzigen. Sound card driver settings Instellingen geluidskaart-stuurprogramma This opens the driver settings of your sound card. Some drivers allow you to change buffer settings, others like ASIO4ALL let you choose input or outputs of your device(s). More information can be found on jamulus.io. Dit opent de stuurprogramma-instellingen van uw geluidskaart. Sommige stuurprogramma's laten u toe bufferinstellingen te veranderen, andere zoals ASIO4ALL laten u input of outputs kiezen. Meer informatie is te vinden op jamulus.io. Opens the driver settings. Note: Opent de stuurprogramma-instellingen. Let op: currently only supports devices supporting a sample rate of ondersteunt momenteel alleen apparaten met een sample rate van Hz. You will not be able to select a driver/device which doesn't. For more help see jamulus.io. Hz. U kunt geen stuurprogramma/apparaat selecteren die dit niet ondersteunt. Voor meer hulp zie jamulus.io. ASIO Device Settings push button ASIO Apparaatinstellingen drukknop Select the meter style to be used for the level meters. The Bar (narrow) and LEDs (round, small) options only apply to the mixerboard. When Bar (narrow) is selected, the input meters are set to Bar (wide). When LEDs (round, small) is selected, the input meters are set to LEDs (round, big). The remaining options apply to the mixerboard and input meters. Selecteer de meterstijl die voor de niveaumeters moet worden gebruikt. De opties "Balk (smal)" en "LED's (rond, klein)" zijn alleen van toepassing op het mengpaneel. Als "Balk (smal)" is geselecteerd dan worden de ingangmeters ingesteld op "Balk (breed)". Als "LED's (rond, klein)" is geselecteerd dan worden de ingangsmeters ingesteld op "LED's (rond, groot)". De overige opties zijn van toepassing op het mengpaneel en de ingangsmeters. Language Taal Select the language to be used for the user interface. Selecteer de te gebruiken taal voor de gebruikersinterface. Language combo box Taal combobox and en Audio Upstream Rate Audio upstream snelheid Depends on the current audio packet size and compression setting. Make sure that the upstream rate is not higher than your available internet upload speed (check this with a service such as speedtest.net). Deze is afhankelijk van de huidige audio pakket grootte en compressie instelling. Zorg ervoor dat de upstream snelheid niet groter is dan uw beschikbare internet upload snelheid (controleer dit met een service zoals speedtest.net). LEDs LED's Bar Balk Narrow Bar Smalle balk Round LEDs Ronde LED's Small LEDs Kleine LED's None Geen Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country or region you are located in. Your city and skill level playing your instrument may also be added. Stel hier uw naam of een alias in zodat de andere muzikanten met wie u wilt spelen weten wie u bent. Daarnaast kunt u een afbeelding toevoegen van het instrument dat u bespeelt en een vlag van het land of regio waarin u zich bevindt. De stad waar u woont en uw vaardigheidsniveau kunnen ook worden toegevoegd. What you set here will appear at your fader on the mixer board when you are connected to a %1 server. This tag will also be shown at each client which is connected to the same server as you. Wat u hier instelt verschijnt bij uw fader op het mengpaneel indien u verbonden met een %1 server. Deze tag zal ook worden getoond aan andere muzikanten die met deze server verbonden zijn. Country/region flag button Land/regio vlag knop Center Midden R R The buffer delay setting is a fundamental setting of the De instelling van de buffervertraging is een belangrijke instelling van de software. This setting has influence on many connection properties. software. Deze instelling heeft invloed op veel verbindingseigenschappen. Three buffer sizes are supported Drie buffergroottes worden ondersteund 64 samples: This is the preferred setting since it provides the lowest latency but does not work with all sound cards. 64 monsters: Dit is de voorkeursinstelling omdat het de laagste latentie geeft, maar niet met alle geluidskaarten werkt. 128 samples: This setting should work for most available sound cards. 128 monsters: Deze instelling zou moeten werken op de meeste beschikbare geluidskaarten. 256 samples: This setting should only be used if only a very slow computer or a slow internet connection is available. 256 monsters: Deze instelling mag alleen worden gebruikt als er alleen een zeer langzame computer of een langzame internetverbinding beschikbaar is. Some sound card drivers do not allow the buffer delay to be changed from within the Sommige geluidskaartbestuurders staan niet toe dat de buffervertraging wordt gewijzigd van binnenuit de software. In this case the buffer delay setting is disabled. To change the actual buffer delay, this setting has to be changed in the sound card driver. On Windows, press the ASIO Setup button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. software. In dit geval is de instelling van de buffervertraging uitgeschakeld. Om de eigenlijke buffervertraging te wijzigen, moet deze instelling in het stuurprogramma van de geluidskaart worden gewijzigd. Druk in Windows op de knop ASIO Setup om het instellingenpaneel van het stuurprogramma te openen. Op Linux gebruikt u de Jack-configuratietool om de grootte van de buffer te wijzigen. If no buffer size is selected and all settings are disabled, an unsupported buffer size is used by the driver. The Als er geen buffergrootte is geselecteerd en alle instellingen zijn uitgeschakeld, wordt een niet-ondersteunde buffergrootte gebruikt door het stuurprogramma. De software will still work with this setting but with restricted performance. software zal nog steeds werken met deze instelling, maar met beperkte prestaties. The actual buffer delay has influence on the connection status, the current upload rate and the overall delay. The lower the buffer size, the higher the probability of a red light in the status indicator (drop outs) and the higher the upload rate and the lower the overall delay. De werkelijke buffervertraging heeft invloed op de verbindingsstatus, de huidige uploadsnelheid en de totale vertraging. Hoe lager de buffergrootte, hoe hoger de kans op rood licht in de statusindicator (drop outs) en hoe hoger de uploadsnelheid en hoe lager de totale vertraging. The buffer setting is therefore a trade-off between audio quality and overall delay. De bufferinstelling is dus een afweging tussen de geluidskwaliteit en de totale vertraging. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within the Als de instellingen voor de buffervertraging zijn uitgeschakeld, is het door het audiostuurprogramma verboden om deze instelling te wijzigen vanuit de software. On Windows, press the ASIO Setup button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. software. Druk in Windows op de knop ASIO Setup om het instellingenpaneel van het stuurprogramma te openen. Op Linux gebruikt u de Jack-configuratietool om de grootte van de buffer te wijzigen. 64 samples setting radio button 64 samples instellen radioknop 128 samples setting radio button 128 samples instellen radioknop 256 samples setting radio button 256 samples instellen radioknop ASIO setup push button ASIO-instellingsdrukknop Fancy Skin Edele huid If enabled, a fancy skin will be applied to the main window. Indien ingeschakeld wordt er een fancy skin op het hoofdvenster aangebracht. Fancy skin check box Fancy skin check box Display Channel Levels Weergave Kanaalniveaus If enabled, each client channel will display a pre-fader level bar. Indien ingeschakeld, zal elk clientkanaal een pre-fader niveau balk weergeven. Display channel levels check box Vinkje bij de weergave van de kanaalniveaus Audio Channels Audiokanalen Select the number of audio channels to be used. There are three modes available. The mono and stereo modes use one and two audio channels respectively. In mono-in/stereo-out mode the audio signal which is sent to the server is mono but the return signal is stereo. This is useful if the sound card has the instrument on one input channel and the microphone on the other channel. In that case the two input signals can be mixed to one mono channel but the server mix can be heard in stereo. Selecteer het aantal te gebruiken audiokanalen. Er zijn drie modi beschikbaar. De mono- en stereomodus gebruiken respectievelijk één en twee audiokanalen. In de mono-in/stereo-uit modus is het audiosignaal dat naar de server wordt gestuurd mono, maar het retoursignaal is stereo. Dit is handig voor het geval dat de geluidskaart het instrument op het ene ingangskanaal zet en de microfoon op het andere kanaal. In dat geval kunnen de twee ingangssignalen worden gemixt naar één monokanaal, maar de servermix is in stereo te horen. Enabling the stereo streaming mode will increase the stream data rate. Make sure that the current upload rate does not exceed the available bandwidth of your internet connection. Het inschakelen van de stereo-streaming modus zal de stream-datasnelheid verhogen. Zorg ervoor dat de huidige uploadsnelheid niet hoger is dan de beschikbare bandbreedte van uw internetverbinding. In stereo streaming mode, no audio channel selection for the reverberation effect will be available on the main window since the effect is applied on both channels in this case. In het geval van de stereo streaming-mode is er geen audiokanaalselectie voor het galmeffect beschikbaar op het hoofdvenster, aangezien het effect in dit geval op beide kanalen wordt toegepast. Audio channels combo box Audiokanalen combobox Audio Quality Audiokwaliteit Select the desired audio quality. A low, normal or high audio quality can be selected. The higher the audio quality, the higher the audio stream data rate. Make sure that the current upload rate does not exceed the available bandwidth of your internet connection. Selecteer de gewenste audiokwaliteit. Er kan een lage, normale of hoge audiokwaliteit worden geselecteerd. Hoe hoger de audiokwaliteit, hoe meer audiodata moet worden verstuurd. Zorg ervoor dat de vereiste bandbreedte niet hoger is dan de beschikbare bandbreedte van uw internetverbinding. Audio quality combo box Audiokwaliteit combobox New Client Level Nieuw client-niveau The new client level setting defines the fader level of a new connected client in percent. I.e. if a new client connects to the current server, it will get the specified initial fader level if no other fader level of a previous connection of that client was already stored. De nieuwe instelling van het clientniveau definieert het faderniveau van een nieuwe verbonden client in procenten. D.w.z. als een nieuwe client verbinding maakt met de server, krijgt hij het opgegeven initiële faderniveau als er in de vorige verbinding niets is opgeslagen. New client level edit box Nieuw client-niveau bewerkingsvak Custom Directory Server Address Eigen adresboek serveradres Directory Server Address Adresboek serveradres The directory server address is the IP address or URL of the directory server at which the server list of the connection dialog is managed. With the directory server address type either the local region can be selected of the default directory servers or a manual address can be specified. Het adresboek serveradres is het IP-adres of de URL van de adresboek server waarop de serverlijst van het verbindingsdialoogvenster wordt beheerd. Met het adresboek serveradrestype kan ofwel de lokale regio worden geselecteerd van de standaard adresboek servers, ofwel kan een handmatig adres worden opgegeven. Default directory server type combo box Adresboek serveradrestype combobox Directory server address line edit Adresboek serveradres bewerkingsregel Current Connection Status Parameter Huidige verbindingsstatus-parameter The ping time is the time required for the audio stream to travel from the client to the server and back again. This delay is introduced by the network. This delay should be as low as 20-30 ms. If this delay is higher (e.g., 50-60 ms), your distance to the server is too large or your internet connection is not sufficient. De ping-tijd is de tijd die nodig is voor de audiostream om van de client naar de server en terug te reizen. Deze vertraging wordt geïntroduceerd door het netwerk. Deze vertraging moet zo laag zijn als 20-30 ms. Als deze vertraging hoger is (bijv. 50-60 ms), is uw afstand tot de server te groot of is uw internetverbinding niet toereikend. The overall delay is calculated from the current ping time and the delay which is introduced by the current buffer settings. De totale vertraging wordt berekend op basis van de huidige ping-tijd en de vertraging die door de huidige bufferinstellingen wordt veroorzaakt. The upstream rate depends on the current audio packet size and the audio compression setting. Make sure that the upstream rate is not higher than the available rate (check the upstream capabilities of your internet connection by, e.g., using speedtest.net). De upstreamsnelheid is afhankelijk van de huidige grootte van het audiopakket en de instelling van de audiocompressie. Zorg ervoor dat de upstreamsnelheid niet hoger is dan de beschikbare snelheid (controleer de upstreammogelijkheden van uw internetverbinding door bijvoorbeeld speedtest.net te gebruiken). If this LED indicator turns red, you will not have much fun using the Als deze LED-indicator rood wordt, zult u niet veel plezier beleven aan het gebruik van de software. software. ASIO Setup ASIO-instelling Mono Mono mode will increase your stream's data rate. Make sure your upload rate does not exceed the available upload speed of your internet connection. modus verhoogt de bandbreedte van de audiostream. Zorg ervoor dat deze niet hoger staat dan de beschikbare bandbreedte van uw internetverbinding. Mono-in/Stereo-out Mono-in/stereo-uit Stereo Stereo &Close &Sluiten Local Audio Input Fader Lokale audio-ingangsfader Controls the relative levels of the left and right local audio channels. For a mono signal it acts as a pan between the two channels. For example, if a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows Met de audiofader kunnen de relatieve niveaus van de linker en rechter lokale audiokanalen worden gewijzigd. Voor een monosignaal werkt het als een panning tussen de twee kanalen. Als bijvoorbeeld een microfoon is verbonden op het rechter ingangskanaal en een veel luider instrument is verbonden op het linker ingangskanaal, beweeg dan de audiofader in de richting van het label L L , where , waarbij is the current attenuation indicator. de huidige dempingsindicator is. Local audio input fader (left/right) Lokale audio-ingangsfader (links/rechts) The jitter buffer compensates for network and sound card timing jitters. The size of the buffer therefore influences the quality of the audio stream (how many dropouts occur) and the overall delay (the longer the buffer, the higher the delay). De jitterbuffer compenseert voor jitters als gevolg van netwerk- en geluidskaart timing. De grootte van de jitterbuffer beïnvloed de kwaliteit van de audiostream (aantal dropouts) en de totale vertraging (hoe groter de buffer, des te groter de vertraging). You can set the jitter buffer size manually for the local client and the remote server. For the local jitter buffer, dropouts in the audio stream are indicated by the light below the jitter buffer size faders. If the light turns to red, a buffer overrun/underrun has taken place and the audio stream is interrupted. De jitter-buffergrootte kan handmatig worden gekozen voor de client en de server. Voor de lokale jitterbuffer worden drop-outs in de audiostream aangegeven door het lampje op de onderkant van de faders voor de jitterbuffergrootte. Als het lampje op rood springt, heeft er een bufferoverschrijding/onderbenedenrijding plaatsgevonden en wordt de audiostream onderbroken. If the Auto setting is enabled, the jitter buffers of the local client and the remote server are set automatically based on measurements of the network and sound card timing jitter. If Auto is enabled, the jitter buffer size faders are disabled (they cannot be moved with the mouse). Als de Auto-instelling aanstaat worden de jitterbuffers lokaal en op de server automatisch aangepast op basis van metingen van het netwerk en de geluidskaart. Indien ingeschakeld kunnen de faders van de jitterbuffer niet handmatig worden bewogen. If the Auto setting is enabled, the network buffers of the local client and the remote server are set to a conservative value to minimize the audio dropout probability. To tweak the audio delay/latency it is recommended to disable the Auto setting and to lower the jitter buffer size manually by using the sliders until your personal acceptable amount of dropouts is reached. The LED indicator will display the audio dropouts of the local jitter buffer with a red light. In het geval dat de automatische instelling van de jitterbuffer is ingeschakeld, worden de netwerkbuffers van de lokale client en de externe server op een conservatieve waarde gezet om de kans op audio-uitval te minimaliseren. Om de audio delay/latentie te tweaken is het aan te raden om de automatische instelling uit te schakelen en de grootte van de jitterbuffer handmatig te verlagen met behulp van de schuifregelaars totdat de persoonlijke aanvaardbare limiet van het aantal drop-outs is bereikt. De LED-indicator zal de audio dropouts van de lokale jitterbuffer visualiseren met een rood lampje. The ASIO driver (sound card) can be selected using %1 under the Windows operating system. Under macOS/Linux, no sound card selection is possible. If the selected ASIO driver is not valid an error message is shown and the previous valid driver is selected. Het ASIO-stuurprogramma (geluidskaart) kan worden geselecteerd met behulp van %1 in het Windows besturingssysteem. Voor MacOS/Linux is geen geluidskaartkeuze mogelijk. Als het geselecteerde ASIO-stuurprogramma niet geldig is, wordt een foutmelding weergegeven en wordt het vorige geldige stuurprogramma geselecteerd. For each %1 input/output channel (left and right channel) a different actual sound card channel can be selected. Voor elk %1 invoer-/uitvoerkanaal (linker- en rechterkanaal) kan een ander daadwerkelijk kanaal van de geluidskaart worden geselecteerd. Enables support for very small network audio packets. These network packets are only actually used if the sound card buffer delay is smaller than %1 samples. The smaller the network buffers, the lower the audio latency. But at the same time the network load and the probability of audio dropouts or sound artifacts increases. Schakelt het gebruik van zeer kleine netwerkaudiopakketten in. Deze netwerkpakketten worden alleen gebruikt indien de geluidskaart buffer kleiner is dan %1 samples. Hoe kleiner de netwerkbuffers, des te kleiner de audio-vertraging. Maar tegelijkertijd neemt de netwerkbelasting toe en neemt ook de kans op audio-uitval toe. The buffer delay setting is a fundamental setting of %1. This setting has an influence on many connection properties. De buffervertragingsinstelling is een fundamentele instelling van %1. Deze instelling is van invloed op veel verbindingseigenschappen. Some sound card drivers do not allow the buffer delay to be changed from within %1. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. On Windows, use the ASIO Device Settings button to open the driver settings panel. On Linux, use the JACK configuration tool to change the buffer size. Sommige stuurprogramma's van geluidskaarten staan niet toe dat de buffervertraging vanuit %1 kan worden gewijzigd. In dat geval is de buffervertragingsinstelling uitgeschakeld en moet deze worden gewijzigd via het stuurprogramma van de geluidskaart. In Windows selecteert u de ASIO Apparaatinstellingen knop om het instellingenpaneel van het stuurprogramma te openen. In Linux gebruikt u het configuratieprogramma van JACK om de buffergrootte te wijzigen. If no buffer size is selected and all settings are disabled, this means an unsupported buffer size is in use by the driver. %1 will still work with this setting but may have restricted performance. Als er geen buffergrootte is geselecteerd en de buffervertragingsinstellingen zijn uitgeschakeld, dan betekent dit dat er een niet ondersteunde buffergrootte wordt gebruikt door de driver. %1 zal nog steeds werken met deze instelling maar de werking is wellicht niet optimaal. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within %1. On Windows, press the ASIO Device Settings button to open the driver settings panel. On Linux, use the JACK configuration tool to change the buffer size. Als de buffervertragingsinstellingen zijn uitgeschakeld, dan staat het stuurprogramma van de geluidskaart het niet toe deze vanuit %1 te wijzigen. In Windows selecteert u de ASIO Apparaatinstellingen knop om het instellingenpaneel van het stuurprogramma te openen. In Linux gebruikt u het configuratieprogramma van JACK om de buffergrootte te wijzigen. This opens the driver settings of your sound card. Some drivers allow you to change buffer settings, others like ASIO4ALL lets you choose input or outputs of your device(s). More information can be found on jamulus.io. Dit opent de stuurprogramma-instellingen van uw geluidskaart. Sommige stuurprogramma's laten u toe bufferinstellingen te veranderen, andere zoals ASIO4ALL laten u invoer- of uitvoerkanalen kiezen van uw apparaat. Meer informatie is te vinden op jamulus.io. Opens the driver settings. Note: %1 currently only supports devices with a sample rate of %2 Hz. You will not be able to select a driver/device which doesn't. For more help see jamulus.io. Opent de stuurprogramma-instellingen. Let op: %1 ondersteunt momenteel alleen apparaten met een sample rate van %2 Hz. U kunt geen stuurprogramma/apparaat selecteren die dit niet ondersteunt. Voor meer informatie zie jamulus.io. The buffer delay setting is a fundamental setting of this software. This setting has an influence on many connection properties. De buffervertraging is een fundamentele instelling van dit programma. Deze instelling beïnvloed vele eigenschappen van de verbinding. 64 samples: The preferred setting. Provides the lowest latency but does not work with all sound cards. 64 samples: Voorkeursinstelling. Geeft de kleinste vertraging maar werkt niet met alle geluidskaarten. 128 samples: Should work for most available sound cards. 128 samples: Werkt voor de meeste geluidskaarten. 256 samples: Should only be used on very slow computers or with a slow internet connection. 256 samples: Alleen te gebruiken bij langzame computers of met een langzame internetverbinding. Some sound card drivers do not allow the buffer delay to be changed from within the application. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. On Windows, press the ASIO Setup button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Sommige stuurprogramma's van geluidskaarten laten het niet toe de buffervertraging in het programma aan te passen. In dat geval dient het te worden aangepast bij het stuurprogramma zelf. Bij Windows, selecteer de ASIO Setup knop om dit in te stellen. Op Linux, gebruik de Jack configuration tool om de buffergrootte te veranderen. If no buffer size is selected and all settings are disabled, an unsupported buffer size is used by the driver. The application will still work with this setting but with restricted performance. Indien geen buffergrootte is aangegeven en instellingen zijn uitgeschakeld, dan gebruikt het stuurprogramma een niet-ondersteunde buffergrootte. Het programma zal niet optimaal presteren. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within the software. On Windows, press the ASIO Setup button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Sommige stuurprogramma's van geluidskaarten laten het niet toe de buffervertraging in het programma aan te passen. In dat geval dient het te worden aangepast bij het stuurprogramma zelf. Bij Windows, selecteer de ASIO Setup knop om dit in te stellen. Op Linux, gebruik de Jack configuration tool om de buffergrootte te veranderen. Skin Skin Select the skin to be used for the main window. Selecteer de te gebruiken skin voor het hoofdvenster. Skin combo box Skin combobox Selects the number of audio channels to be used for communication between client and server. There are three modes available: Selecteer het aantal audiokanalen voor communicatie tussen client en server. Er zijn drie modi beschikbaar: and en These modes use one and two audio channels respectively. Deze modi gebruiken respectievelijk een en twee audiokanalen. Mono in/Stereo-out Mono in/stereo uit The audio signal sent to the server is mono but the return signal is stereo. This is useful if the sound card has the instrument on one input channel and the microphone on the other. In that case the two input signals can be mixed to one mono channel but the server mix is heard in stereo. Het audiosignaal naar de server is mono maar wat terugkomt is stereo. Dit is handig als de geluidskaart het instrument op een invoerkanaal heeft en de microfoon op een ander. In dat geval kunnen de twee signalen gemixed worden naar een monokanaal terwijl de server mix in stereo blijft. Enabling Aanzetten In stereo streaming mode, no audio channel selection for the reverb effect will be available on the main window since the effect is applied to both channels in this case. In het geval van de stereo streaming-mode is er geen audiokanaalselectie voor het galmeffect beschikbaar op het hoofdvenster, aangezien het effect in dit geval op beide kanalen wordt toegepast. The higher the audio quality, the higher your audio stream's data rate. Make sure your upload rate does not exceed the available bandwidth of your internet connection. Hoe hoger de audiokwaliteit, des te hoger de benodigde bandbreedte. Zorg ervoor dat deze niet hoger staat dan de beschikbare bandbreedte van uw internetverbinding. This setting defines the fader level of a newly connected client in percent. If a new client connects to the current server, they will get the specified initial fader level if no other fader level from a previous connection of that client was already stored. Deze instelling stelt het faderniveau in van een nieuwe verbonden client in procenten. Als een nieuwe client verbinding maakt krijgt hij het opgegeven initiële faderniveau als dit in de vorige verbinding niet was opgeslagen. Input Boost Ingangsversterking This setting allows you to increase your input signal level by factors up to 10 (+20dB). If your sound is too quiet, first try to increase the level by getting closer to the microphone, adjusting your sound equipment or increasing levels in your operating system's input settings. Only if this fails, set a factor here. If your sound is too loud, sounds distorted and is clipping, this option will not help. Do not use it. The distortion will still be there. Instead, decrease your input level by getting farther away from your microphone, adjusting your sound equipment or by decreasing your operating system's input settings. Met deze instelling kunt u het niveau van uw ingangssignaal tot en met een factor 10 verhogen (+ 20dB). Als uw geluid te zacht is, probeer dan eerst het niveau te verhogen door dichter bij de microfoon te komen, uw geluidsapparatuur aan te passen of de niveaus in uw besturingssysteem te verhogen. Stel hier alleen een factor in als dit niet lukt. Als uw geluid te luid is, vervormd klinkt en afknapt, zal deze optie niet helpen. Gebruik het daar niet voor, de vervorming zal er nog steeds zijn. Verlaag in plaats daarvan uw ingangssignaal door verder weg te gaan van uw microfoon, uw geluidsapparatuur aan te passen of door de niveaus in uw besturingssysteem te verlagen. Input Boost combo box Ingangsversterking combobox Leave this blank unless you need to enter the address of a directory server other than the default. Laat dit leeg tenzij u een adresboek serveradres wilt invoeren dat anders is dan de standaard. Directory server address combo box Adresboek serveradres combobox The Ping Time is the time required for the audio stream to travel from the client to the server and back again. This delay is introduced by the network and should be about 20-30 ms. If this delay is higher than about 50 ms, your distance to the server is too large or your internet connection is not sufficient. De ping-tijd is de tijd die nodig is voor de audiostream om van de client naar de server en terug te reizen. Deze vertraging wordt veroorzaakt door het netwerk en bedraagt ongeveer 20-30 ms. Als deze vertraging hoger is dan circa 50 ms, dan is uw afstand tot de server te groot of is uw internetverbinding niet toereikend. Overall Delay is calculated from the current Ping Time and the delay introduced by the current buffer settings. De totale vertraging wordt berekend op basis van de huidige ping-tijd en de vertraging door de huidige bufferinstellingen. Audio Upstream Rate depends on the current audio packet size and compression setting. Make sure that the upstream rate is not higher than your available internet upload speed (check this with a service such as speedtest.net). De bitsnelheid van de audio is afhankelijk van de huidige grootte van het audiopakket en de instelling van de audiocompressie. Zorg ervoor dat de bitsnelheid niet hoger is dan de beschikbare snelheid (controleer de upstreammogelijkheden van uw internetverbinding door bijvoorbeeld speedtest.net te gebruiken). Controls the relative levels of the left and right local audio channels. For a mono signal it acts as a pan between the two channels. For example, if a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows %1, where %2 is the current attenuation indicator. Met de audiofader kunnen de relatieve niveaus van de linker en rechter lokale audiokanalen worden gewijzigd. Voor een monosignaal werkt het als een panning tussen de twee kanalen. Als bijvoorbeeld een microfoon is verbonden op het rechter ingangskanaal en een veel luider instrument is verbonden op het linker ingangskanaal, beweeg dan de audiofader in de richting van het label %1, waarbij %2 de huidige dempingsindicator is. Audio Device Audio apparaat Under the Windows operating system the ASIO driver (sound card) can be selected using %1. If the selected ASIO driver is not valid an error message is shown and the previous valid driver is selected. Under macOS the input and output hardware can be selected. Bij het Windows-besturingssysteem kan de ASIO-driver (geluidskaart/audio-interface) worden geselecteerd voor gebruik met %1. Als het geselecteerde ASIO-stuurprogramma niet geschikt is dan wordt er een foutmelding weergegeven en wordt de vorige geschikte stuurprogramma geselecteerd. Bij macOS kan de invoer- en uitvoerhardware worden geselecteerd. Three buffer sizes can be selected Er kunnen drie buffergroottes worden geselecteerd 64 samples: Provides the lowest latency but does not work with all sound cards. 64 samples: Zorgt voor de minste vertraging maar werkt niet met alle geluidskaarten. 256 samples: Should only be used when 64 or 128 samples is causing issues. 256 samples: Gebruik deze alleen indien 64 of 128 problemen veroorzaaken. Some sound card drivers do not allow the buffer delay to be changed from within %1. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. Use the appropriate tool for the interface in use to adjust this buffer size. For example, if using ASIO, use the "ASIO Device Settings" button to open the driver settings panel or if using JACK, use a tool such as QjackCtl to adjust the buffer size. Other interfaces, such as Pipewire, would require their appropriate tool being used. Please refer to the interface manual. Sommige stuurprogramma's van geluidskaarten staan niet toe dat de buffervertraging vanuit %1 kan worden gewijzigd. In dat geval is de buffervertragingsinstelling uitgeschakeld en moet deze worden gewijzigd via het stuurprogramma van de geluidskaart. Gebruik de juiste tool voor de gebruikte interface om deze buffergrootte aan te passen. Als u bijvoorbeeld ASIO gebruikt, gebruikt u de knop "ASIO Apparaatinstellingen" om het paneel met driverinstellingen te openen of als u JACK gebruikt, gebruikt u een tool zoals QjackCtl om de buffergrootte aan te passen. Voor andere interfaces, zoals Pipewire, moet het juiste programma worden gebruikt. Raadpleeg hiervoor de handleiding van de interface. If no buffer size is selected and all settings are disabled, this means a buffer size in use by the driver which does not match the values. %1 will still work with this setting but may have restricted performance. Als er geen buffergrootte is geselecteerd en alle instellingen zijn uitgeschakeld, betekent dit een buffergrootte die door het stuurprogramma wordt gebruikt en die niet overeenkomt met de waarden. %1 werkt nog steeds met deze instelling, maar heeft mogelijk beperkte prestaties. The actual buffer delay has influence on the connection, the current upload rate and the overall delay. The lower the buffer size, the higher the probability of a red light in the status indicator (drop outs) and the higher the upload rate and the lower the overall delay. De werkelijke buffervertraging heeft invloed op de verbindingsstatus, de huidige uploadsnelheid en de algehele vertraging. Hoe kleiner de buffergrootte, hoe groter de kans op een rood lampje in de statusindicator (uitval) en hoe hoger de uploadsnelheid en hoe lager de algehele vertraging. Meter Style Meterstijl Select the meter style to be used for the level meters. The Narrow Bar and Small LEDs options only apply to the mixerboard. When Narrow Bar is selected, the input meters are set to Bar. When Small LEDs is selected, the input meters are set to Round LEDs. The remaining options apply to the mixerboard and input meters. Selecteer de meterstijl die voor de niveaumeters moet worden gebruikt. De opties smalle balk en kleine LED's zijn alleen van toepassing op het mengpaneel. Als smalle balk is geselecteerd dan worden de ingangmeters ingesteld op balk. Als kleine LED's is geselecteerd dan worden de ingangsmeters ingesteld op ronde LED's. De overige opties zijn van toepassing op het mengpaneel en de ingangsmeters. Meter Style combo box Meterstijl combobox Custom Directories Eigen adresboeken If you need to add additional directories to the Connect dialog Directory drop down, you can enter the addresses here.<br>To remove a value, select it, delete the text in the input box, then move focus out of the control. Als u extra adresboeken wilt toevoegen aan de adresboek keuze in het verbindingsvenster, dan kunt u hier de adressen invoeren.<br>Als u een waarde wilt verwijderen, selecteert u deze, verwijdert u de tekst in het invoervak en verplaatst u de focus uit de vak. Custom Directories combo box Eigen adresboeken combobox Number of Mixer Panel Rows Aantal mengpaneel rijen Adjust the number of rows used to arrange the mixer panel. Stel het aantal rijen in dat gebruikt wordt in het mengpaneel. Number of Mixer Panel Rows spin box Aantal rijen in het mengpaneel spinbox Feedback Protection Feedback bescherming Enable feedback protection to detect acoustic feedback between microphone and speakers. Schakel feedback bescherming in om de akoetische feedback tussen de microfoon en luidsprekers te detecteren. Feedback Protection check box Feedback bescherming selectievakje Audio Alerts Audiowaarschuwingen Enable audio alert when receiving a chat message and when a new client joins the session. A second sound device may be required to hear the alerts. Schakel audiowaarschuwing in bij ontvangst van een chatbericht en wanneer een nieuwe client deelneemt aan de sessie. Er kan een tweede geluidsapparaat nodig zijn om de waarschuwingen te horen. Audio Alerts check box Audiowaarschuwingen checkbox ASIO Device Settings ASIO Apparaatinstellingen Low Laag Normal Normaal High Hoog Fancy Fancy Compact Compact Bar (narrow) Balk (smal) Bar (wide) Balk (breed) LEDs (stripe) LED's (streep) LEDs (round, small) LED's (rond, klein) LEDs (round, big) LED's (rond, groot) Manual Handmatig Custom Aangepast All Genres Alle genres Any Genre 2 Ieder Genre 2 Any Genre 3 Ieder Genre 3 Genre Rock Genre Rock Genre Jazz Genre Jazz Genre Classical/Folk Genre Klassiek/Folk Genre Choral/Barbershop Genre Koor/Barbershop Any Genre 1 Ieder Genre 1 Genre Classical/Folk/Choral Genre Klassiek/Folk/Zang Default Standaard Default (North America) Standaard (Noord-Amerika) preferred voorkeur Musician Profile Muzikantenprofiel Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country you are located in. Your city and skill level playing your instrument may also be added. Stel hier uw naam of een alias in zodat de andere muzikanten met wie u wilt spelen weten wie u bent. Daarnaast kunt u een instrumentfoto van het instrument dat u bespeelt en een vlag van het land waar u woont, instellen. De stad waar u woont en uw vaardigheidsniveau kunnen ook worden toegevoegd. What you set here will appear at your fader on the mixer board when you are connected to a Jamulus server. This tag will also be shown at each client which is connected to the same server as you. Wat u hier instelt verschijnt bij uw fader op het mengpaneel indien verbonden met een Jamulus-server. Deze tag zal ook worden getoond aan andere muzikanten die met deze server verbonden zijn. Alias or name edit box Alias of naam bewerkingsvak Instrument picture button Afbeelding van het instrument Country flag button Landvlag knop City edit box Stad bewerkingsvak Skill level combo box Vaardigheidsniveau combobox Beginner Beginner Intermediate Gemiddeld Expert Gevorderd Size: Grootte: Buffer Delay Buffervertraging Buffer Delay: Buffervertraging: The selected audio device could not be used because of the following error: Het geselecteerde audioapparaat kon niet worden gebruikt vanwege de volgende fout: The previous driver will be selected. Het vorige stuurprogramma wordt geselecteerd. Ok Ok Drum Set Drumstel Djembe Djembe Electric Guitar Elektrische gitaar Acoustic Guitar Akoestische gitaar Bass Guitar Basgitaar Keyboard Toetsenbord Synthesizer Synthesizer Grand Piano Piano Accordion Accordeon Vocal Zang Microphone Microfoon Harmonica Harmonica Trumpet Trompet Trombone Trombone French Horn Hoorn Tuba Tuba Saxophone Saxofoon Clarinet Klarinet Flute Fluit Violin Viool Cello Cello Double Bass Contrabas Recorder Opnemer Streamer Streamer Listener Luisteraar Guitar+Vocal Gitaar+zang Keyboard+Vocal Toetsenbord+zang Bodhran Bodhran Bassoon Fagot Oboe Hobo Harp Harp Viola Viola Congas Congas Bongo Bongo Vocal Bass Bas (stem) Vocal Tenor Tenor (stem) Vocal Alto Alt (stem) Vocal Soprano Sopraan (stem) Banjo Banjo Mandolin Mandoline Ukulele Ukelele Bass Ukulele Ukelele-bas Vocal Baritone Bariton (stem) Vocal Lead Leadzanger Mountain Dulcimer Dulcimer Scratching Scratchen Rapping Rappen Vibraphone Vibrafoon Conductor Dirigent CClientSettingsDlgBase Settings Instellingen Soundcard Geluidskaart Device Apparaat Input Channel Mapping Invoerkanaaltoewijzing L L R R Output Channel Mapping Uitvoerkanaaltoewijzing Enable Small Network Buffers Kleine netwerkbuffers inschakelen Buffer Delay Buffervertraging Country/Region Land/regio (preferred) (voorkeur) (default) (standaard) (safe) (veilig) Driver Setup Stuurprogramma-instellingen My Profile Mijn profiel Musician's Profile Muzikantenprofiel Alias/Name Alias/naam Instrument Instrument Country Land City Stad Skill Vaardigheid User Interface Gebruikersinterface Meter Style Meterstijl Mixer Rows Mengpaneel rijen Audio Alerts Audiowaarschuwingen Audio/Network Setup Audio-/netwerk-instellingen Audio Device Audio apparaat Jitter Buffer Jitterbuffer Auto Auto Local Lokaal Server Server Size Grootte kbps kbps ms ms Input Boost Ingangsversterking Feedback Protection Feedback bescherming Enable Inschakelen Input Balance Ingangsbalans Pan Balans Center Midden Misc Overige Audio Channels Audiokanalen Audio Quality Audiokwaliteit Measurements Metingen Advanced Setup Geavanceerde instellingen Custom Central Server Address: Eigen adresboek server adres: New Client Level Nieuw client-niveau Skin Skin Language Taal Custom Directories: Eigen adresboek % % Local Jitter Buffer Lokale Jitterbuffer Fancy Skin Fancy Skin Display Channel Levels Weergave Kanaalniveaus Custom Directory Server Address: Eigen adresboek serveradres: Directory Server Address: Adresboek serveradres: Audio Stream Rate Audiobitsnelheid val val Ping Time Ping-tijd Overall Delay Totale vertraging CConnectDlg Server List Serverlijst The server list shows a list of available servers which are registered at the directory server. Select a server from the list and press the connect button to connect to this server. Alternatively, double click a server from the list to connect to it. If a server is occupied, a list of the connected musicians is available by expanding the list item. Permanent servers are shown in bold font. De serverlijst toont een lijst van beschikbare servers die op de adresboek server zijn geregistreerd. Selecteer een server uit de lijst en druk op de verbindingsknop om verbinding te maken met deze server. U kunt ook dubbelklikken op een server uit de lijst om verbinding te maken met deze server. Als een server bezet is, is een lijst van de verbonden muzikanten beschikbaar door het lijstitem uit te breiden. Permanente servers worden vetgedrukt weergegeven. Note that it may take some time to retrieve the server list from the directory server. If no valid directory server address is specified in the settings, no server list will be available. Merk op dat het enige tijd kan duren om de serverlijst op te halen van de adresboek server. Als er geen geldig adresboek serveradres is opgegeven in de instellingen, zal er geen serverlijst beschikbaar zijn. Directory Adresboek Shows the servers listed by the selected directory. You can add custom directories in Advanced Settings. Toont de beschikbare servers in het gekozen adresboek. U kunt een eigen adresboek toevoegen in de geavanceerde instellingen. Directory combo box Adresboek combobox Filters the server list by the given text. Note that the filter is case insensitive. A single # character will filter for those servers with at least one person connected. Filter de serverlijst met de opgegeven tekst. Merk op dat het filter ongevoelig is voor hoofdletters. Gebruik het #-karakter om alleen servers te laten zien waarmee minimaal één persoon verbonden is. Uncheck to collapse the server list to show just the server details. Check to show everyone on the servers. Haal het vinkje weg om de serverlijst samen te vouwen en zo alleen de server gegevens te zien. Plaats een vinkje om te zien wie er met de servers verbonden zijn. The Connection Setup window lists the available servers registered with the selected directory. Use the Directory dropdown to change the directory, find the server you want to join in the server list, click on it, and then click the Connect button to connect. Alternatively, double click on the server name to connect. In het verbindingvenster worden de beschikbare servers weergegeven die zijn geregistreerd bij het geselecteerde adresboek. Gebruik de adresboek keuzelijst het adresboek te wijzigen, zoek de server waaraan u wilt deelnemen in de serverlijst, klik erop en klik vervolgens op de knop Verbinden om verbinding te maken. U kunt ook dubbelklikken op de servernaam om verbinding te maken. Permanent servers (those that have been listed for longer than 48 hours) are shown in bold. Permanente servers (die langer dan 48 uur in de lijst staan) worden vetgedrukt weergegeven. You can add custom directories in Advanced Settings. U kunt eigen adresboeken toevoegen in de geavanceerde instellingen. Server list view Serverlijstweergave Server Address Serveradres If you know the server address, you can connect to it using the Server name/Address field. An optional port number can be added after the server address using a colon as a separator, e.g. %1. The field will also show a list of the most recently used server addresses. Als u het serveradres weet, kunt u er verbinding mee maken via het veld Servernaam/Adres. Een optioneel poortnummer kan worden toegevoegd na het serveradres met een dubbele punt als scheidingsteken, b.v. %1. Het veld toont ook een lijst met de meest recent gebruikte serveradressen. Holds the current server address. It also stores old addresses in the combo box list. Bevat het huidige serveradres. Het slaat ook oude adressen op in de keuzelijst. The IP address or URL of the server running the Het IP-adres of de URL van de server waarop de server software must be set here. An optional port number can be added after the IP address or URL using a colon as a separator, e.g. example.org: serversoftware moet worden ingesteld. Een optioneel poortnummer kan worden toegevoegd na het IP-adres of de URL met een dubbele punt als scheidingsteken, bijvoorbeeld example.org: . A list of the most recent used server IP addresses or URLs is available for selection. . Een lijst met de meest recent gebruikte server-IP-adressen of URL's is beschikbaar voor selectie. The Connection Setup window shows a list of available servers. Server operators can optionally list their servers by music genre. Use the List dropdown to select a genre, click on the server you want to join and press the Connect button to connect to it. Alternatively, double click on on the server name. Permanent servers (those that have been listed for longer than 48 hours) are shown in bold. De serverlijst toont een lijst van beschikbare servers. Server beheerders kunnen hun servers optioneel op muziek genre weergeven. Gebruik de lijst optie om een genre te kiezen, klik op de server die u wilt gebruiken en druk op de verbindingsknop om verbinding te maken. U kunt ook dubbelklikken op een servernaam in de lijst om verbinding te maken. Permanente servers (die langer dan 48 uur in de lijst staan) worden vetgedrukt weergegeven. If you know the IP address or URL of a server, you can connect to it using the Server name/Address field. An optional port number can be added after the IP address or URL using a colon as a separator, e.g. example.org: Het IP-adres of de URL van de server kan bij Servernaam/Adres worden ingevoerd. Een optioneel poortnummer kan worden toegevoegd na het IP-adres of de URL met een dubbele punt als scheidingsteken, b.v. example.org: . The field will also show a list of the most recently used server addresses. . Het veld toont ook een lijst met de laatstgebruikte serveradressen. Server address edit box Serveradres bewerkingsvak Holds the current server IP address or URL. It also stores old URLs in the combo box list. Bevat het huidige server-IP-adres of de URL. Het slaat ook oude URL's op in de comboboxlijst. Server List Selection Serverlijstselectie Selects the server list to be shown. Selecteert de te tonen serverlijst. Server list selection combo box Serverlijst selectie combobox Filter Filter The server list is filtered by the given text. Note that the filter is case insensitive. De serverlijst wordt gefilterd met de gegeven tekst. Merk op dat het filter ongevoelig is voor hoofdletters. Filter edit box Filter bewerkingsvak Show All Musicians Toon alle muzikanten If you check this check box, the musicians of all servers are shown. If you uncheck the check box, all list view items are collapsed. Als u dit selectievakje aanvinkt, worden de muzikanten van alle servers getoond. Als u het selectievakje uitvinkt, worden alle items van de lijstweergave samengevouwen. Show all musicians check box Toon alle muzikanten checkbox If you know the IP address or URL of a server, you can connect to it using the Server name/Address field. An optional port number can be added after the IP address or URL using a colon as a separator, e.g. %1. The field will also show a list of the most recently used server addresses. Als u het IP-adres of de URL van de server weet, dan kunt u daar verbinding mee maken door deze in te voeren in het Servernaam/Adres veld. Een optioneel poortnummer kan worden toegevoegd na het IP-adres of de URL met een dubbele punt als scheidingsteken, b.v. %1. Het veld laat ook een lijst zien met de meest recent gebruikte serveradressen. Filter text, or # for occupied servers Filter op tekst of gebruik # voor bezette servers Type # for occupied servers Typ # voor bezette servers CConnectDlgBase Connection Setup Verbindingsinstellingen List Lijst Directory Adresboek Filter Filter Show All Musicians Toon alle muzikanten Server Name Servernaam Ping Time Ping-tijd Musicians Muzikanten Location Locatie Server Address Serveradres Server Name/Address Servernaam/Adres C&ancel &Annuleren &Connect &Verbinden CHelpMenu &Help &Hulp Getting &Started... &Aan de slag... Software &Manual... Gebruikers&handleiding... What's &This Wat Is &Dit &About Jamulus... &Over Jamulus... About &Qt... Over &Qt... &About... &Over... About Qt Over Qt CLanguageComboBox Restart Required Herstart noodzakelijk Please restart the application for the language change to take effect. Start de applicatie opnieuw om de taalwijziging door te voeren. CLicenceDlg I &agree to the above licence terms Ik &stem in met bovenstaande licentievoorwaarden This server requires you accept conditions before you can join. Please read these in the chat window. Deze server vereist dat u voorwaarden accepteert voor het verbinen. Lees deze in het chatvenster. I have read the conditions and &agree. Ik heb de voorwaarden gelezen en &stem in. Accept Accepteer Decline Niet akkoord By connecting to this server and agreeing to this notice, you agree to the following: Door verbinding te maken met deze server en akkoord te gaan met deze mededeling, gaat u akkoord met het volgende: You agree that all data, sounds, or other works transmitted to this server are owned and created by you or your licensors, and that you are making these data, sounds or other works available via the following Creative Commons License (for more information on this license, see U gaat ermee akkoord dat alle gegevens, geluiden of andere werken die naar deze server worden verzonden, eigendom zijn van en gemaakt zijn door u of uw licentiegevers, en dat u deze gegevens, geluiden of andere werken beschikbaar stelt via de volgende Creative Commons Licentie (voor meer informatie over deze licentie, zie You are free to: Je staat vrij om: Share het materiaal copy and redistribute the material in any medium or format te delen, te kopiëren en te herdistribueren in elk medium of formaat Adapt Aanpassen remix, transform, and build upon the material remixen, transformeren en bouwen op het materiaal The licensor cannot revoke these freedoms as long as you follow the license terms. De licentiegever kan deze vrijheden niet herroepen zolang u zich aan de licentievoorwaarden houdt. Under the following terms: Onder de volgende voorwaarden: Attribution Naamsvermelding You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. U moet de juiste erkenning geven, een link naar de licentie geven en aangeven of er wijzigingen zijn aangebracht. U mag dit op elke redelijke manier doen, maar niet op een manier die suggereert dat de licentiegever u of uw gebruik goedkeurt. NonCommercial Niet-commercieel You may not use the material for commercial purposes. U mag het materiaal niet voor commerciële doeleinden gebruiken. ShareAlike hareAlike If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original. Als u het materiaal remixt, transformeert of uitbouwt, moet u uw bijdragen distribueren onder dezelfde licentie als het origineel. No additional restrictions Geen extra beperkingen You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. U mag geen wettelijke voorwaarden of technologische maatregelen toepassen die anderen wettelijk beperken om iets te doen wat de licentie toestaat. CMultiColorLED Red Rood Yellow Geel Green Groen CMusProfDlg Musician Profile Muzikantenprofiel Alias/Name Alias/Naam Instrument Instrument Country Land City Stad Skill Vaardigheid &Close &Sluiten None Geen Beginner Beginner Intermediate Gemiddeld Expert Gevorderd Set your name or an alias here so that the other musicians you want to play with know who you are. Additionally you may set an instrument picture of the instrument you play and a flag of the country you are living in. The city you live in and the skill level playing your instrument may also be added. Stel hier uw naam of een alias in zodat de andere muzikanten met wie u wilt spelen weten wie u bent. Daarnaast kunt u een instrumentfoto van het instrument dat u bespeelt en een vlag van het land waar je woont, instellen. De stad waar u woont en het vaardigheidsniveau van het spelen van uw instrument kunnen ook worden toegevoegd. What you set here will appear at your fader on the mixer board when you are connected to a Wat u hier instelt, verschijnt bij uw fader op het mengpaneel wanneer u verbonden bent met een server. This tag will also show up at each client which is connected to the same server as you. If the name is left empty, the IP address is shown instead. server. Deze tag zal ook verschijnen op elke client die verbonden is met dezelfde server als u. Als de naam leeg is, wordt in plaats daarvan het IP-adres getoond. Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country you are located in. Your city and skill level playing your instrument may also be added. Stel hier uw naam of een alias in zodat de andere muzikanten met wie u wilt spelen weten wie u bent. Daarnaast kunt u een instrumentfoto van het instrument dat u bespeelt en een vlag van het land waar u woont, instellen. De stad waar u woont en uw vaardigheidsniveau kunnen ook worden toegevoegd. What you set here will appear at your fader on the mixer board when you are connected to a Jamulus server. This tag will also be shown at each client which is connected to the same server as you. Wat u hier instelt verschijnt bij uw fader op het mengpaneel indien verbonden met een Jamulus-server. Deze tag zal ook worden getoond aan andere muzikanten die met deze server verbonden zijn. Alias or name edit box Alias of naam bewerkingsvak Instrument picture button Afbeelding van het instrument Country flag button Landvlag knop City edit box Stad bewerkingsvak Skill level combo box Vaardigheidsniveau combobox Drum Set Drumstel Djembe Djembe Electric Guitar Elektrische Gitaar Acoustic Guitar Akoestische Gitaar Bass Guitar Basgitaar Keyboard Toetsenbord Synthesizer Synthesizer Grand Piano Piano Accordion Accordeon Vocal Vocaal Microphone Microfoon Harmonica Harmonica Trumpet Trompet Trombone Trombone French Horn Hoorn Tuba Tuba Saxophone Saxofoon Clarinet Klarinet Flute Fluit Violin Viool Cello Cello Double Bass Contrabas Recorder Opnemer Streamer Streamer Listener Luisteraar Guitar+Vocal Gitaar+Vocaal Keyboard+Vocal Toetsenbord+Vocaal Bodhran Bodhran Bassoon Fagot Oboe Hobo Harp Harp Viola Viola Congas Congas Bongo Bongo Vocal Bass Bas (stem) Vocal Tenor Tenor (stem) Vocal Alto Alt (stem) Vocal Soprano Sopraan (stem) Banjo Banjo Mandolin Mandoline Ukulele Ukelele Bass Ukulele Ukelele-bas Vocal Baritone Bariton (stem) Vocal Lead Leadzanger Mountain Dulcimer Dulcimer Scratching Scratchen Rapping Rappen No Name Geen naam CServerDlg Client List Clientlijst The client list shows all clients which are currently connected to this server. Some information about the clients like the IP address and name are given for each connected client. De clientlijst toont alle clients die op dit moment verbonden zijn met deze server. Voor elke verbonden client wordt enige informatie over de clients gegeven, zoals het IP-adres en de naam. Connected clients list view Overzicht van de lijst met verbonden clients Directory Type combo box Adresboek type combobox Directory Adresboek Select '%1' not to register your server with a directory. Selecteer '%1' om uw server niet in een adresboek te registreren. Select one of the genres to register with that directory. Selecteer een genre om te registreren bij die adresboek. Or select '%1' and specify a Custom Directory address on the Options tab to register with a custom directory. Of selecteer '%1' en geef een eigen adresboek op in het tabblad Opties om u te registreren bij een aangepast adresboek. For any value except '%1', this server registers with a directory so that a %2 user can select this server in the client connect dialog server list when they choose that directory. Voor elke waarde behalve '%1' registreert deze server zich bij een adresboek zodat een %2-gebruiker deze server kan selecteren in de serverlijst van het verbindingsvenster wanneer hij het betreffende adresboek kiest. The registration of the server is renewed periodically to make sure that all servers in the connect dialog server list are actually available. De registratie van de server wordt periodiek vernieuwd om er zeker van te zijn dat alle servers in het verbindingsvenster ook daadwerkelijk beschikbaar zijn. When a value other than "%1" is chosen for Directory, this will show whether registration is successful. If the registration failed, please choose a different directory. Wanneer een andere waarde dan "%1" wordt gekozen voor adresboek zal dit laten zien of de registratie is gelukt. Als de registratie is mislukt, kiest u een ander adresboek. No recording directory has been set or the value is not useable. Check the value in the Options tab. Er is geen opnamedirectory ingesteld of de waarde is niet bruikbaar. Controleer de waarde in het tabblad Opties. If the recording directory is not useable, the problem will be displayed in place of the session directory. Als de opnamedirectory niet bruikbaar is, wordt het probleem weergegeven in plaats van de sessiedirectory. Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user %1 is running as). Klik op de knop om het dialoogvenster te openen waarin de opnamedirectory kan worden geselecteerd. De gekozen waarde moet bestaan ​​en schrijfbaar zijn (laat het maken van submappen door de gebruiker toe die %1 uitgevoerd). The current value of the main recording directory. The chosen value must exist and be writeable (allow creation of sub-directories by the user %1 is running as). Click the button to open the dialog that allows the main recording directory to be selected. De huidige waarde van de opnamedirectory. De gekozen waarde moet bestaan ​​en schrijfbaar zijn (laat het maken van submappen door de gebruiker toe die %1 uitgevoerd). Klik op de knop om het dialoogvenster te openen waarin de opnamedirectory kan worden geselecteerd. Custom Directory address Eigen adresboek adres The Custom Directory address is the address of the directory holding the server list to which this server should be added. Het eigen adresboek adres is het adres van het adresboek met de serverlijst waaraan deze server moet worden toegevoegd. Server List Filename dialog push button Serverlijst bestandsnaam drukknop Server List Filename Serverlijst bestandsnaam Click the button to open the dialog that allows the server list persistence file name to be set. The user %1 is running as needs to be able to create the file name specified although it may already exist (it will get overwritten on save). Klik op de knop om het dialoogvenster te openen waarmee de bestandsnaam voor de serverlijst kan worden ingesteld. De gebruiker %1 is actief om de opgegeven bestandsnaam te kunnen maken, hoewel deze mogelijk al bestaat (deze wordt overschreven bij het opslaan). Server List Filename text box (read-only) Serverlijst bestandsnaam tekstvak (alleen lezen) The current value of server list persistence file name. The user %1 is running as needs to be able to create the file name specified although it may already exist (it will get overwritten on save). Click the button to open the dialog that allows the server list persistence file name to be set. De huidige waarde van de serverlijst bestandsnaam. De gebruiker %1 is actief om de opgegeven bestandsnaam te kunnen maken, hoewel deze mogelijk al bestaat (deze wordt overschreven bij het opslaan). Klik op de knop om het dialoogvenster te openen waarmee de bestandsnaam voor de serverlijst kan worden ingesteld. Clear the server list file name button Wis serverlijst bestandsnaam drukknop Clear Server List Filename Wis serverlijst bestandsnaam Click the button to clear the currently selected server list persistence file name. This will prevent persisting the server list until a new value is selected. Klik op de knop om de momenteel geselecteerde bestandsnaam van de serverlijst te wissen. Dit voorkomt dat de serverlijst wordt bewaard totdat een nieuwe waarde is geselecteerd. Start Minimized on Operating System Start Start geminimaliseerd bij de start van het besturingssysteem Now a directory Nu een adresboek If the start minimized on operating system start check box is checked, the Als het selectievakje Starten geminimaliseerd op het besturingssysteem is aangevinkt, wordt de server will be started when the operating system starts up and is automatically minimized to a system task bar icon. server gestart wanneer het besturingssysteem wordt opgestart en wordt automatisch geminimaliseerd tot een systeemtaakbalkpictogram. Show Creative Commons Licence Dialog Toon de Creative Commons Licentie If enabled, a Creative Commons BY-NC-SA 4.0 Licence dialog is shown each time a new user connects the server. Indien ingeschakeld, wordt een Creative Commons BY-NC-SA 4.0 Licentiedialoogvenster getoond telkens wanneer een nieuwe gebruiker de server verbindt. Make My Server Public Maak mijn server openbaar If the Make My Server Public check box is checked, this server registers itself at the directory server so that all Als het selectievakje Maak Mijn Server Openbaar is aangevinkt, registreert deze server zichzelf op de adresboek server zodat alle users can see the server in the connect dialog server list and connect to it. The registration of the server is renewed periodically to make sure that all servers in the connect dialog server list are actually available. gebruikers kunnen de server zien in de lijst van de verbindingsserver in het dialoogvenster en er verbinding mee maken. De registratie van de server wordt periodiek vernieuwd om er zeker van te zijn dat alle servers in de connect dialog server lijst daadwerkelijk beschikbaar zijn. Register Server Status Geregistreerde server status If the Make My Server Public check box is checked, this will show whether registration with the directory server is successful. Als het selectievakje Maak Mijn Server Openbaar is aangevinkt, zal dit het succes van de registratie bij de adresboek server laten zien. Directory Server Address Adresboek serveradres The Directory server address is the IP address or URL of the directory server at which this server is registered. With the directory server address type either the local region can be selected of the default directory servers or a manual address can be specified. Het adres van de adresboek server is het IP-adres of de URL van de adresboek server waarop deze server is geregistreerd. Met het type adresboek serveradres kan ofwel de lokale regio worden geselecteerd van de standaard adresboek servers of kan een handmatig adres worden opgegeven. If the Make My Server Public check box is checked, this will show whether registration with the directory server is successful. If the registration failed, please choose another server list. Als het selectievakje Maak mijn server openbaar is aangevinkt, laat dit zien of registratie bij de adresboek server is gelukt. Indien registratie mislukt, kies dan een andere serverlijst. Default directory server type combo box Standaard adresboek server type combobox If the start minimized on operating system start check box is checked, the server will be started when the operating system starts up and is automatically minimized to a system task bar icon. Als de Start geminimaliseerd bij systeemstart checkbox iss aangevinkt, zal de server gestart worden als het systeem opstart end word automatisch geminimaliseerd naar een icoon op de taakbalk. If the Make My Server Public check box is checked, this server registers itself at the directory server so that all users of the application can see the server in the connect dialog server list and connect to it. The registration of the server is renewed periodically to make sure that all servers in the connect dialog server list are actually available. Als het selectievakje Maak mijn server openbaar is aangevinkt registreert deze server zichzelf bij de adresboek server. Hierdoor kunnen alle gebruikers deze zien en er verbinding mee maken. De registratie wordt periodiek vernieuwd om ervoor te zorgen dat alle servers in de serverlijst ook daadwerkelijk beschikbaar zijn. Custom Directory Server Address Eigen adresboek serveradres The custom directory server address is the IP address or URL of the directory server at which the server list of the connection dialog is managed. Het eigen adresboek serveradres is het IP-adres of de URL van de adresboek server die de serverlijst laat zien in de verbindingsinstellingen. Directory server address line edit Adresboek server bewerkingsregel Server List Selection Serverlijstselectie Selects the server list (i.e. directory server address) in which your server will be added. Selecteert de serverlijst (i.e. het adresboek serveradres) waaraan uw server zal worden toegevoegd. Server list selection combo box Serverlijst selectie combobox Server Name Servernaam The server name identifies your server in the connect dialog server list at the clients. If no name is given, the IP address is shown instead. De naam van de server identificeert uw server in de lijst van de connect-dialoog-server bij de clients. Als er geen naam wordt gegeven, wordt in plaats daarvan het IP-adres getoond. The server name identifies your server in the connect dialog server list at the clients. De servernaam identificeert uw server in de serverlijst. Als er geen naam wordt opgegeven zal het IP-adres worden getoond. Server name line edit Servernaam bewerkingsregel Location City Locatie Stad The city in which this server is located can be set here. If a city name is entered, it will be shown in the connect dialog server list at the clients. De stad waar deze server zich bevindt kan hier worden ingesteld. Als er een plaatsnaam wordt ingevoerd, wordt deze getoond in de lijst van de connect-dialoog-server bij de clients. City where the server is located line edit Stad waar de server zich bevindt bewerkingsregel Location country Land van locatie The country in which this server is located can be set here. If a country is entered, it will be shown in the connect dialog server list at the clients. Het land waarin deze server zich bevindt kan hier worden ingesteld. Als er een land is ingevoerd, wordt dit getoond in de lijst van de verbindingsserver bij de clients. Country where the server is located combo box Land waar de server zich bevindt combobox Country/Region Land/regio Set the country or region where the server is running. Clients will show this location in their connect dialog's server list. Het land of regio waarin deze server zich bevindt kan hier worden ingesteld. Dit wordt getoond in de lijst van de verbindingsservers bij de clients. Combo box for location of this server Combobox voor de locatie van deze server Recording has been switched off by the UI checkbox. Opname is uitgeschakeld middels het vinkje in het venster. Recording has been switched off, either by the UI checkbox or SIGUSR2 being received. Opname is uitgeschakeld middels het vinkje in het venster of doordat het SIGUSR2 signaal is ontvangen. Display dialog to select recording directory button Toon venster voor het instellen van de directory voor geluidsopnames Main Recording Directory Hoofddirectory voor geluidsopnames Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user Jamulus is running as). Klik op deze knop om het venster te tonen waarin de directory voor geluidsopnames kan worden ingesteld. Deze directory moet reeds bestaan en door de gebruiker die Jamulus draait kunnen worden aangepast. Main recording directory text box (read-only) Hoofddirectory voor geluidsopnames tekstvak (alleen lezen) The current value of the main recording directory. The chosen value must exist and be writeable (allow creation of sub-directories by the user Jamulus is running as). Click the button to open the dialog that allows the main recording directory to be selected. De huidig ingestelde directory voor geluidsopnames. Deze directory moet reeds bestaan en door de gebruiker die Jamulus draait kunnen worden aangepast. Clear the recording directory button Wis aangegeven geluidsopnamedirectory Clear Recording Directory Wis aangegeven geluidsopnamedirectory Click the button to clear the currently selected recording directory. This will prevent recording until a new value is selected. Klik op deze knop om de aangegeven geluidsopnamedirectory te wissen. Opnames kunnen niet worden gemaakt zonder ingestelde geluidsopnamedirectory. Checkbox to turn on or off server recording Selectievakje om geluidsopname op de server in of uit te schakelen If the Register Server check box is checked, this will show whether registration with the directory server is successful. If the registration failed, please choose another server list. Als het selectievakje Maak Mijn Server Openbaar is aangevinkt, zal dit het succes van de registratie bij de adresboek server laten zien. Indien de registratie mislukt, kies dan een ander adresboek. Enable Recorder Geluidsopname inschakelen Checked when the recorder is enabled, otherwise unchecked. The recorder will run when a session is in progress, if (set up correctly and) enabled. Aangevinkt indien de geluidsrecorder aanstaat. De geluidsrecorder zal dan sessie opnemen. Current session directory text box (read-only) Huidige sessie directory tekstvak (alleen lezen) Current Session Directory Huidige sessie directory Enabled during recording and holds the current recording session directory. Disabled after recording or when the recorder is not enabled. Ingeschakeld tijdens geluidsopname en bevat de sessie-directory. Uitgeschakeld na geluidsopname of wanneer geluidsopname uit staat. Recorder status label Geluidsopname statuslabel Recorder Status Geluidsopname status Displays the current status of the recorder. The following values are possible: Toon de huidige status van geluidsopname. De volgende keuzes zijn mogelijk: No recording directory has been set or the value is not useable. Geen geluidsopnamedirectory ingesteld of waarde is niet bruikbaar. Recording has been switched off Geluidsopname is uitgeschakeld by the UI checkbox door het selectievak , either by the UI checkbox or SIGUSR2 being received , of door het selectievak of doordat SIGUSR2 wordt ontvangen There is no one connected to the server to record. Er is niemand verbonden met de server voor geluidsopname. The performers are being recorded to the specified session directory. Het geluid van de muzikanten wordt opgenomen in de aangegeven sessie-directory. NOTE OPMERKING If the recording directory is not useable, the problem will be displayed in place of the directory. Als de geluidsopnamedirectory niet bruikbaar is wordt het probleem getoond in plaats van de locatie. Server welcome message edit box Vak voor welkomstbericht server Server Welcome Message Welkomstbericht server A server welcome message text is displayed in the chat window if a musician enters the server. If no message is set, the server welcome is disabled. Een server welkomstbericht wordt getoond in het chatvenster als een muzikant binnenkomt. Indien niets ingesteld wordt geen welkomstbericht getoond. Language Taal Select the language to be used for the user interface. Selecteer de te gebruiken taal voor de gebruikersinterface. Language combo box Taal combobox Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user Jamulus is running as). Klik op deze knop om het venster te tonen waarin de directory voor geluidsopnames kan worden ingesteld. Deze directory moet reeds bestaan en door de gebruiker die Jamulus draait kunnen worden aangepast. Custom Directory Eigen adresboek The custom directory is the IP address or URL of the directory server at which the server list of the connection dialog is managed. Het eigen adresboek is het IP-adres of de URL van de adresboekserver waarop de serverlijst van het verbindingsvenster wordt beheerd. Custom Directory line edit Eigen adresboek regel bewerken &Hide %1 server &Verberg %1 server &Show %1 server &Toon %1 server %1 server %1 is the name of the main application %1 server Type a message here. If no message is set, the server welcome is disabled. Typ hier een bericht. Indien niets ingesteld wordt geen welkomstbericht getoond. %1 Server %1 is the name of the main application %1 server software upgrade available software-update beschikbaar Recorder failed to start. Please check available disk space and permissions and try again. Error: Opname starten mislukt. Controleer beschikbare schijfruimte en toegangsrechtern en probeer opnieuw. Fout: ERROR FOUT Displays the current status of the recorder. Toont de huidige status van de geluidsopname. Request new recording button Knop om nieuwe geluidsopname aan te vragen New Recording Nieuwe geluidsopname During a recording session, the button can be used to start a new recording. Tijdens een opnamesessie kan de knop gebruikt worden om een nieuwe opname te starten. E&xit &Afsluiten &Hide &Verbergen server server &Open &Open server server Select Main Recording Directory Selecteer hoofdgeluidsopnamedirectory Predefined Address Standaardadres Recording Neemt op Not recording Neemt niet op Not initialised Niet geïnitialiseerd Not enabled Niet ingeschakeld Manual Handmatig Default Standaard Default (North America) Standaard (Noord-Amerika) Server Server &Window &Window Unregistered Niet geregistreerd None Geen Not registered Niet geregistreerd Bad address Foutief adres Registration requested Registratie aangevraagd Registration failed Registratie is mislukt Check server version Controleer de versie van de server Registered Geregistreerd Directory server list full Adresboek server lijst vol Directory Server full Adresboek server vol Your server version is too old Uw serverversie is te oud Requirements not fulfilled Vereisten niet gehaald Unknown value %1 Onbekende waarde %1 Unknown value Onbekende waarde CServerDlgBase Client IP:Port Client IP:poort Name Naam Jitter Buffer Size Jitterbuffergrootte Channels Kanalen Server Setup Server instellingen List Adresboek Location: Region Locatie: Regio Session Sessie Chat Window Welcome (HTML/CSS Supported) Welkomstbericht chatvenster (HTML/CSS mogelijk) Options Opties Custom Directory address Eigen adresboek adres Server List Filename Serverlijst bestandsnaam Start Minimized on Windows Start Start geminimaliseerd bij systeemstart Enable delay panning Delay panning inschakelen Show Creative Commons BY-NC-SA 4.0 Licence Dialog Toon Creative Commons BY-NC-SA 4.0 Licentie Dialoog Update check Update controle Make My Server Public (Register My Server in the Server List) Maak mijn server openbaar (registreer deze in de lijst met servers) Genre Genre STATUS STATUS Custom Directory Server Address: Eigen adresboek serveradres: Recording Directory Geluidsopnamedirectory Enable Jam Recorder Activeer geluidsopname Directory Adresboek New Recording Nieuwe geluidsopname Language Consider add "(Lang)" as a suffix to ensure that users who selected the wrong language find the correct button Taal Directory Server Address: Adresboek serveradres: My Server Info Mijn serverinfo Location: City Locatie: Stad Location: Country Locatie: Land Enable jam recorder Geluidsopname activeren New recording Nieuwe geluidsopname Recordings folder Geluidsopname folder TextLabelNameVersion TextLabelNameVersion CServerListManager Could not write to '%1' Fout bij het schrijven naar '%1' CSound Error requesting stream stop: $s Fout bij het aanvragen om te stoppen: $s Error closing stream: $s Fout tijdens afsluiten: $s The Jack server is not running. This software requires a Jack server to run. Normally if the Jack server is not running this software will automatically start the Jack server. It seems that this auto start has not worked. Try to start the Jack server manually. De Jack server draait niet. Voor deze software is een Jack-server nodig om te kunnen draaien. Normaal gesproken als de Jack-server niet draait zal deze software automatisch de Jack-server opstarten. Het lijkt erop dat deze automatische start niet heeft gewerkt. Probeer de Jack server handmatig te starten. The Jack server sample rate is different from the required one. The required sample rate is: De Jack-server sample rate is anders dan de vereiste. De vereiste sample rate is: You can use a tool like <i><a href="https://qjackctl.sourceforge.io">QJackCtl</a></i> to adjust the Jack server sample rate. U kunt een tool als <i><a href="https://qjackctl.sourceforge.io">QJackCtl</a></i> gebruiken om de sample rate van de Jack-server aan te passen. Make sure to set the Frames/Period to a low value like Zorg ervoor dat u de Frames/Periode op een lage waarde instelt, zoals to achieve a low delay. om een lage vertraging te bereiken. The Jack port registering failed. De registratie van de Jack-poort is mislukt. Cannot activate the Jack client. Kan de Jack-client niet activeren. The Jack server was shut down. This software requires a Jack server to run. Try to restart the software to solve the issue. De Jack-server werd afgesloten. Voor deze software is een Jack-server nodig om te kunnen draaien. Probeer de software te herstarten om het probleem op te lossen. CoreAudio input AudioHardwareGetProperty call failed. It seems that no sound card is available in the system. CoreAudio-ingang AudioHardwareGetProperty-oproep mislukt. Het lijkt erop dat er geen geluidskaart beschikbaar is in het systeem. CoreAudio output AudioHardwareGetProperty call failed. It seems that no sound card is available in the system. CoreAudio uitgang AudioHardwareGetProperty call mislukt. Het lijkt erop dat er geen geluidskaart beschikbaar is in het systeem. Current system audio input device sample rate of %1 Hz is not supported. Please open the Audio-MIDI-Setup in Applications->Utilities and try to set a sample rate of %2 Hz. Een sample rate van %1 Hz voor het audio-ingangsapparaat van het huidige systeem wordt niet ondersteund. Open de Audio-MIDI-Setup in Applications->Utilities en probeer een sample rate van %2 Hz in te stellen. The current selected audio device is no longer present in the system. Het geselecteerde audioapparaat is niet langer in het systeem beschikbaar. The audio input device is no longer available. Het audio-invoerapparaat is niet langer beschikbaar. The audio output device is no longer available. Het audio-uitvoerapparaat is niet langer beschikbaar. Current system audio output device sample rate of %1 Hz is not supported. Please open the Audio-MIDI-Setup in Applications->Utilities and try to set a sample rate of %2 Hz. De sample rate van %1 Hz van het huidige systeem audiouitgangsapparaat wordt niet ondersteund. Open de Audio-MIDI-Setup in Applications->Utilities en probeer een sample rate van %2 Hz in te stellen. The audio input stream format for this audio device is not compatible with this software. Het audio input stream-formaat voor dit audioapparaat is niet compatibel met deze software. The audio output stream format for this audio device is not compatible with this software. Het formaat van de audio-uitgangsstroom voor dit audioapparaat is niet compatibel met deze software. The buffer sizes of the current input and output audio device cannot be set to a common value. Please choose other input/output audio devices in your system settings. De buffergrootte van het huidige in- en uitgaande audioapparaat kan niet op een gemeenschappelijke waarde worden ingesteld. Kies andere in-/uitgangsaudioapparaten in uw systeeminstellingen. The audio driver could not be initialized. De audiodriver kon niet worden geïnitialiseerd. The audio device does not support the required sample rate. The required sample rate is: Het audioapparaat ondersteunt niet de vereiste samplefrequentie. De vereiste samplefrequentie wel: The audio device does not support setting the required sampling rate. This error can happen if you have an audio interface like the Roland UA-25EX where you set the sample rate with a hardware switch on the audio device. If this is the case, please change the sample rate to Het audioapparaat biedt geen ondersteuning voor het instellen van de vereiste bemonsteringsfrequentie. Deze fout kan zich voordoen als u een audio-interface heeft zoals de Roland UA-25EX waarbij u de samplefrequentie instelt met een hardwareschakelaar op het audioapparaat. Als dit het geval is, verander dan de samplefrequentie in Hz on the device and restart the Hz op het apparaat en start de software. software. The audio device does not support the required number of channels. The required number of channels for input and output is: Het audioapparaat ondersteunt niet het vereiste aantal kanalen. Het vereiste aantal kanalen voor in- en uitvoer is: Required audio sample format not available. Vereist audiosampleformaat niet beschikbaar. The selected audio device is no longer present in the system. Please check your audio device. Het geselecteerde audio apparaat is niet langer aanwezig in het system. Controleer uw audio apparaat. Couldn't initialise the audio driver. Check if your audio hardware is plugged in and verify your driver settings. Kan het audiostuurprogramma niet initialiseren. Controleer of uw audiohardware is aangesloten en controleer uw stuurprogramma-instellingen. The selected audio device is incompatible since it doesn't support a sample rate of %1 Hz. Please select another device. Het geselecteerde audioapparaat is niet compatibel omdat het geen samplefrequentie van %1 Hz ondersteunt. Selecteer een ander apparaat. The current audio device configuration is incompatible because the sample rate couldn't be set to %2 Hz. Please check for a hardware switch or driver setting to set the sample rate manually and restart %1. De huidige configuratie van het audioapparaat is niet compatibel omdat de samplefrequentie niet kan worden ingesteld op %2 Hz. Controleer of er een hardware-switch of driver-instelling is om de samplefrequentie handmatig in te stellen en start %1 opnieuw. The selected audio device is incompatible since it doesn't support %1 in/out channels. Please select another device or configuration. Het geselecteerde audioapparaat is niet compatibel omdat het geen %1 in-/uitvoerkanalen ondersteunt. Selecteer een ander apparaat of een andere configuratie. The selected audio device is incompatible since the required audio sample format isn't available. Please use another device. Het geselecteerde audioapparaat is niet compatibel omdat het vereiste audiosampleformaat niet beschikbaar is. Gebruik een ander apparaat. No ASIO audio device driver found. Geen ASIO geluidskaart stuurprogramma gevonden. Please install an ASIO driver before running %1. If you own a device with ASIO support, install its official ASIO driver. If not, you'll need to install a universal driver like ASIO4ALL. Installeer een ASIO stuurprogramma voor het starten van %1. Indien u een apparaat heeft met ASIO ondersteuning, installeer dan de officiële ASIO driver voor dit apparaat. Indien u dit niet heeft, dan kunt u een universeel stuurprogramma zoals ASIO4ALL gebruiken. Please install an ASIO driver before running %1. If you own a device with ASIO support, install its official ASIO driver. If not, you'll need to download and install a universal driver like ASIO4ALL. Installeer een ASIO stuurprogramma voor het starten van %1. Indien u een apparaat heeft met ASIO ondersteuning, installeer dan de officiële ASIO driver. Indien u dit niet heeft, dan kunt u een universele driver zoals ASIO4ALL gebruiken. No ASIO audio device (driver) found. Geen ASIO-audioapparaat (stuurprogramma) gevonden. The De software requires the low latency audio interface ASIO to work properly. This is not a standard Windows audio interface and therefore a special audio driver is required. Either your sound card has a native ASIO driver (which is recommended) or you might want to use alternative drivers like the ASIO4All driver. software vereist de lage-latency audio-interface ASIO om goed te kunnen werken. Dit is geen standaard Windows audio-interface en daarom is een speciale audio-stuurprogramma vereist. Ofwel heeft uw geluidskaart een native ASIO stuurprogramma (die wordt aanbevolen), ofwel wilt u alternatieve drivers gebruiken zoals het ASIO4All stuurpogramma. JACK couldn't be started automatically. Please start JACK manually and check for error messages. JACK kon niet automatisch worden gestart. Start JACK handmatig en controleer op foutmeldingen. JACK isn't running at a sample rate of <b>%1 Hz</b>. Please use a tool like <i><a href="https://qjackctl.sourceforge.io">QjackCtl</a></i> to set the the JACK sample rate to %1 Hz. JACK werkt niet met een samplefrequentie van <b>%1 Hz</b>. Gebruik een tool als <i><a href="https://qjackctl.sourceforge.io">QjackCtl</a></i> om de JACK-samplefrequentie in te stellen op %1 Hz. The JACK port registration failed. This is probably an error with JACK. Please stop %1 and JACK. Afterwards check if another program at a sample rate of %2 Hz can connect to JACK. De JACK-poortregistratie is mislukt. Dit is waarschijnlijk een fout met JACK. Stop a.u.b. %1 en JACK. Controleer daarna of een ander programma met een samplefrequentie van %2 Hz verbinding kan maken met JACK. The JACK port registration failed. This is probably an error with JACK. Please stop %1 and JACK. Afterwards, check if another MIDI program can connect to JACK. De JACK-poortregistratie is mislukt. Dit is waarschijnlijk een fout met JACK. Stop a.u.b. %1 en JACK. Controleer daarna of een ander MIDI-programma verbinding kan maken met JACK. Can't activate the JACK client. This is probably an error with JACK. Please check the JACK output. Kan de JACK-client niet activeren. Dit is waarschijnlijk een fout met JACK. Controleer de JACK-uitgang. JACK was shut down. %1 requires JACK to run. Please restart %1 to start JACK again. JACK werd afgesloten. %1 vereist dat JACK wordt uitgevoerd. Herstart %1 om JACK opnieuw te starten. No sound card is available in your system. CoreAudio input AudioHardwareGetProperty call failed. Er is geen geluidskaart beschikbaar in uw systeem. CoreAudio-invoer AudioHardwareGetProperty-aanroep mislukt. No sound card is available in the system. CoreAudio output AudioHardwareGetProperty call failed. Er is geen geluidskaart beschikbaar in het systeem. CoreAudio-uitvoer AudioHardwareGetProperty-aanroep mislukt. The currently selected audio device is no longer present. Please check your audio device. Het momenteel geselecteerde audioapparaat is niet meer aanwezig. Controleer uw audioapparaat. The audio input device is no longer available. Please check if your input device is connected correctly. Het audio-invoerapparaat is niet langer beschikbaar. Controleer of uw invoerapparaat correct is aangesloten. The sample rate on the current input device isn't %1 Hz and is therefore incompatible. Please select another device or try setting the sample rate to %1 Hz manually via Audio-MIDI-Setup (in Applications->Utilities). De samplefrequentie van het huidige invoerapparaat is geen %1 Hz en is daarom niet compatibel. Selecteer een ander apparaat of probeer de samplefrequentie handmatig in te stellen op %1 Hz via Audio-MIDI-Setup (in Applications->Utilities). The audio output device is no longer available. Please check if your output device is connected correctly. Het audio-uitvoerapparaat is niet langer beschikbaar. Controleer of uw uitvoerapparaat correct is aangesloten. The sample rate on the current output device isn't %1 Hz and is therefore incompatible. Please select another device or try setting the sample rate to %1 Hz manually via Audio-MIDI-Setup (in Applications->Utilities). De samplefrequentie van het huidige uitvoerapparaat is geen %1 Hz en is daarom niet compatibel. Selecteer een ander apparaat of probeer de samplefrequentie handmatig in te stellen op %1 Hz via Audio-MIDI-Setup (in Applications->Utilities). The stream format on the current input device isn't compatible with this software. Please select another device. Het streamformaat van het huidige invoerapparaat is niet compatibel met deze software. Selecteer een ander apparaat. The stream format on the current output device isn't compatible with %1. Please select another device. Het streamformaat van het huidige uitvoerapparaat is niet compatibel met %1. Selecteer een ander apparaat. The buffer sizes of the current input and output audio device can't be set to a common value. Please select different input/output devices in your system settings. De buffergroottes van het huidige invoer- en uitvoeraudioapparaat kunnen niet op een gemeenschappelijke waarde worden ingesteld. Selecteer verschillende invoer-/uitvoerapparaten in uw systeeminstellingen. CSoundBase Invalid device selection. Ongeldige apparaatkeuze. The audio driver properties have changed to a state which is incompatible with this software. The selected audio device could not be used because of the following error: De eigenschappen van de audiodriver zijn veranderd in een toestand die niet compatibel is met deze software. Het geselecteerde audioapparaat kon niet worden gebruikt vanwege de volgende fout: Please restart the software. Start de software opnieuw op. Close Sluiten The selected audio device could not be used because of the following error: Het geselecteerde audioapparaat kon niet worden gebruikt vanwege de volgende fout: The previous driver will be selected. Het vorige stuurprogramma zal worden geselecteerd. The previously selected audio device is no longer available or the audio driver properties have changed to a state which is incompatible with this software. We now try to find a valid audio device. This new audio device might cause audio feedback. So, before connecting to a server, please check the audio device setting. Het eerder geselecteerde audioapparaat is niet langer beschikbaar of de stuurprogramma-eigenschappen zijn aangepast en werken niet met deze software. We zoeken nu naar een bruikbaar audioapparaat. Dit nieuwe audioappraat zou audio feedback kunnen veroorzaken. Controleer daarom de audioapparaat-instellingen alvorens op een server in te loggen. No usable Niet bruikbaar audio device (driver) found. audioapparaat (stuurprogramma) gevonden. In the following there is a list of all available drivers with the associated error message: Hieronder vindt u een lijst van alle beschikbare drivers met de bijbehorende foutmelding: Do you want to open the ASIO driver setups? Wilt u de ASIO-stuurprogramma's openen? could not be started because of audio interface issues. kon niet worden gestart vanwege problemen met de audio-interface. Can't use the selected audio device because of the following error: %1 The previous driver will be selected. Kan het geselecteerde audioapparaat niet gebruiken vanwege de volgende fout: %1 Het vorige stuurprogramma wordt geselecteerd. The previously selected audio device is no longer available or the driver has changed to an incompatible state. We'll attempt to find a valid audio device, but this new audio device may cause feedback. Before connecting to a server, please check your audio device settings. Het eerder geselecteerde audioapparaat is niet langer beschikbaar of het stuurprogramma is gewijzigd in een niet compatibele status. We zullen proberen een geldig audioapparaat te vinden, maar dit nieuwe audioapparaat kan feedback veroorzaken. Controleer uw audioapparaat instellingen voordat u verbinding maakt met een server. <b>%1 couldn't find a usable %2 audio device.</b><br><br> <b>%1 kan geen geschikt %2 audioapparaat vinden.</b><br><br> You may be able to fix errors in the driver settings. Do you want to open these settings now? Mogelijk kunt u fouten in de instellingen van het stuurprogramma herstellen. Wilt u deze instellingen nu openen? No usable %1 audio device found. Geen bruikbaar %1 audioapparaat gevonden. These are all the available drivers with error messages: Dit zijn de beschikbare stuurprogramma's met foutmeldingen: Do you want to open the ASIO driver setup to try changing your configuration to a working state? Wilt u de instellingen van het ASIO-stuurprogramma openen om te proberen uw configuratie in een werkende staat te veranderen? Can't start %1. Please restart %1 and check/reconfigure your audio settings. Kan %1 niet starten. Herstart %1 en controleer/configureer uw audio-instellingen opnieuw. QCoreApplication %1, Version %2 %1, Versie %2 Internet Jam Session Software Internet Jamsessie Software %1, Version %2 %1 is app name, %2 is version number %1, versie %2 Released under the GNU General Public License version 2 or later (GPLv2) Gereleased onder de GNU General Public License versie 2 of recenter (GPLv2) This program is free software; you can redistribute it and/or modify it under Dit programma is gratis software; u kunt het herdistribueren en/of wijzigen onder the terms of the GNU General Public License as published by the Free Software de voorwaarden van de GNU General Public License zoals gepubliceerd door de Free Software Foundation; either version 2 of the License, or (at your option) any later version. Foundation; ofwel versie 2 van de licentie of (naar uw keuze) een latere versie. There is NO WARRANTY, to the extent permitted by law. Er is GEEN GARANTIE, voor zover wettelijk toegestaan. Using the following libraries, resources or code snippets: Met gebruikmaking van de volgende libraries, bronnen of code snippets: Qt framework Qt framework Opus Interactive Audio Codec Opus Interactive Audio Codec Audio reverberation code by Perry R. Cook and Gary P. Scavone Audio reverberatiecode door Perry R. Cook en Gary P. Scavone Some pixmaps are from the Open Clip Art Library (OCAL) Sommige pixmaps zijn van de Open Clip Art Library (OCAL) Flag icons by Mark James Vlag-iconen van Mark James Copyright (C) 2005-2022 The Jamulus Development Team Copyright (C) 2005-2022 het Jamulus Development Team Released under the GNU General Public License (GPL) Gereleased onder de GNU General Public License (GPL) global A %1 upgrade is available: <a style='color:red;' href='https://jamulus.io/upgrade?progversion=%2'>go to details and downloads</a> Er is een nieuwe versie van %1 beschikbaar: <a style='color:red;' href='https://jamulus.io/upgrade?progversion=%2'>klik hier voor details en downloads</a> For more information use the "What's This" help (help menu, right mouse button or Shift+F1) Voor meer informatie gebruik de "Wat Is Dit" hulp (helpmenu, rechtermuisklik of Shift+F1) jamulus-3.9.1+dfsg/src/translation/wininstaller/0000755000175000017500000000000014340334543021014 5ustar vimervimerjamulus-3.9.1+dfsg/src/translation/wininstaller/de_DE.nsi0000644000175000017500000000542014340334543022470 0ustar vimervimer; German translation LangString DESKTOP_SET_SHORTCUT ${LANG_GERMAN} \ "Desktopverknüpfung erstellen" LangString INVALID_FOLDER_MSG ${LANG_GERMAN} \ "Das Zielverzeichnis existiert bereits. Bitte wähle ein anderes Zielverzeichnis." LangString RUNNING_APP_MSG ${LANG_GERMAN} \ "${APP_NAME} läuft noch. Bitte schließe das Programm und starte die Installation erneut." LangString OLD_WRONG_VER_FOUND ${LANG_GERMAN} \ "Eine alte Version von ${APP_NAME} wurde in deinem 32 Bit Programme Ordner gefunden. Wir empfehlen, dass diese Version gelöscht wird. Willst du sie jetzt löschen?" LangString OLD_WRONG_VER_FOUND_CONFIRM ${LANG_GERMAN} \ "Wenn du ohne sie zu löschen weitermachst, könnte es sein, dass deine Installation nicht mehr korrekt funktioniert. Bist du sicher, dass du die alte Version wirklich nicht löschen möchtest?" LangString OLD_VER_REMOVE_FAILED ${LANG_GERMAN} \ "Leider konnte die alte Version nicht deinstalliert werden. Trotzdem wird nun versucht die neue zu installieren, aber du kannst auch auf Abbrechen klicken um zu versuchen, die alte Version selber zu entfernen." LangString ASIO_DRIVER_HEADER ${LANG_GERMAN} \ "ASIO Treiber" LangString ASIO_DRIVER_SUB ${LANG_GERMAN} \ "${APP_NAME} benötigt einen ASIO Treiber" LangString ASIO_DRIVER_EXPLAIN ${LANG_GERMAN} \ "${APP_NAME} braucht einen ASIO Treiber um geringe Audio Latenz zu ermöglichen. Mehr Info:" LangString ASIO_DRIVER_MORE_INFO ${LANG_GERMAN} \ "Mehr Info über ASIO auf jamulus.io" LangString ASIO_DRIVER_MORE_INFO_URL ${LANG_GERMAN} \ "https://jamulus.io/de/wiki/Installation-for-Windows#asio" LangString ASIO_EXIT_NO_DRIVER ${LANG_GERMAN} \ "Um eine geringe Audio Verzögerung zu ermöglichen, braucht ${APP_NAME} einen ASIO Treiber. Da wir keinen auf deinem PC finden konnten, musst du einen, wie z.B. ASIO4ALL installieren (Infos dazu auf jamulus.io unter Installation auf Windows). Willst du trotzdem erst einmal mit der Installation von ${APP_NAME} fortfahren?" LangString JACK_DRIVER_HEADER ${LANG_GERMAN} \ "JACK Audio Connection Kit" LangString JACK_DRIVER_SUB ${LANG_GERMAN} \ "Um diese Version von ${APP_NAME} zu nutzen, benötigst du das JACK Audio Connection Kit" LangString JACK_DRIVER_EXPLAIN ${LANG_GERMAN} \ "Diese Version von ${APP_NAME} nutzt das JACK Audio Connection Kit. Bitte stelle sicher, dass es installiert ist, oder lade die Standard ASIO-Version von ${APP_NAME} von jamulus.io herunter." LangString JACK_EXIT_NO_DRIVER ${LANG_GERMAN} \ "Diese Version von ${APP_NAME} benötigt das JACK Audio Connection Kit, aber es scheint nicht auf deinem PC installiert zu sein. Du solltest zuerst JACK für Windows installieren. Möchtest du trotzdem mit der Installation von ${APP_NAME} fortfahren, ohne zuerst JACK zu installieren?" jamulus-3.9.1+dfsg/src/translation/wininstaller/pl_PL.nsi0000644000175000017500000000525714340334543022546 0ustar vimervimer; Polish translation LangString DESKTOP_SET_SHORTCUT ${LANG_POLISH} \ "Utwórz skrót na pulpicie" LangString INVALID_FOLDER_MSG ${LANG_POLISH} \ "Folder docelowy już istnieje. Proszę podać nowy folder." LangString RUNNING_APP_MSG ${LANG_POLISH} \ "${APP_NAME} wciąż działa. Proszę go zamknąć i uruchomić instalator jeszcze raz." LangString OLD_WRONG_VER_FOUND ${LANG_POLISH} \ "Starsza wersja ${APP_NAME} została odnaleziona w folderze Program Files z aplikacjami 32 bitowymi. Zaleca się usunięcie jej przed instalacją nowej wersji ${APP_NAME}. Czy chcesz ją usunąć teraz?" LangString OLD_WRONG_VER_FOUND_CONFIRM ${LANG_POLISH} \ "Jeżeli będziesz kontynuować bez uprzedniego usunięcia, nowa instalacja może być uszkodzona! Na pewno nie chcesz usunąć starszej wersji?" LangString OLD_VER_REMOVE_FAILED ${LANG_POLISH} \ "Niestety usunięcie starszej wersji było niemożliwe. Próba instalacji nowej wersji bedzie kontynuowana, ale można także nacisnąć anuluj i usunąć starszą wersję samodzielnie." LangString ASIO_DRIVER_HEADER ${LANG_POLISH} \ "sterownik ASIO" LangString ASIO_DRIVER_SUB ${LANG_POLISH} \ "Żeby używać ${APP_NAME}-a potrzebny jest sterownik ASIO" LangString ASIO_DRIVER_EXPLAIN ${LANG_POLISH} \ "${APP_NAME} wymaga sterownika ASIO żeby zapewnić dźwięk o niskich opóźnieniach. Więcej informacji:" LangString ASIO_DRIVER_MORE_INFO ${LANG_POLISH} \ "Więcej informacji o ASIO na jamulus.io" LangString ASIO_DRIVER_MORE_INFO_URL ${LANG_POLISH} \ "https://jamulus.io/wiki/Installation-for-Windows#asio" LangString ASIO_EXIT_NO_DRIVER ${LANG_POLISH} \ "${APP_NAME} wymaga sterownika ASIO do działania, ale nie można go było znaleźć na tym komputerze. Powinieneś zainstalować np. ASIO4ALL (Więcej informacji na jamulus.io w sekcji Istalacja dla Windows). Czy nadal chcesz najpierw zainstalować ${APP_NAME}?" LangString JACK_DRIVER_HEADER ${LANG_POLISH} \ "Serwer dźwięku JACK" LangString JACK_DRIVER_SUB ${LANG_POLISH} \ "Żeby używać tej wersji ${APP_NAME}-a, potrzebny jest serwer dźwięku JACK" LangString JACK_DRIVER_EXPLAIN ${LANG_POLISH} \ "Ta wersja programu ${APP_NAME} do działania potrzebuje serwera dźwięku JACK. Proszę się upewnić, że JACK jest zainstalowany lub pobrać standardową wersję ${APP_NAME}-a z jamulus.io, która używa ASIO." LangString JACK_EXIT_NO_DRIVER ${LANG_POLISH} \ "Ta wersja programu ${APP_NAME} wymaga do działania serwera dźwięku JACK, ale wygląda na to, że nie jest on zainstalowany. Najpierw trzeba zainstalować JACK-a dla Windows-a. Czy nadal chcesz kontynuować tą instalację ${APP_NAME}-a bez zainstalowanego JACK-a?" jamulus-3.9.1+dfsg/src/translation/wininstaller/fr_FR.nsi0000644000175000017500000000557114340334543022535 0ustar vimervimer; French translation LangString DESKTOP_SET_SHORTCUT ${LANG_FRENCH} \ "Créer un raccourci sur le bureau" LangString INVALID_FOLDER_MSG ${LANG_FRENCH} \ "Le dossier de destination existe déjà. Veuillez entrer un nouveau dossier de destination." LangString RUNNING_APP_MSG ${LANG_FRENCH} \ "${APP_NAME} est en cours d'exécution. Veuillez le fermer et relancer l'installation." LangString OLD_WRONG_VER_FOUND ${LANG_FRENCH} \ "Nous avons détecté une ancienne version de ${APP_NAME} dans votre dossier Program Files 32 bits. Il est fortement recommandé de le supprimer avant d'installer une nouvelle version de ${APP_NAME}. Voulez-vous le supprimer maintenant ? " LangString OLD_WRONG_VER_FOUND_CONFIRM ${LANG_FRENCH} \ "Si vous continuez sans le supprimer, votre installation risque d'être interrompue ! Êtes-vous sûr de ne pas vouloir supprimer l'ancienne version ? " LangString OLD_VER_REMOVE_FAILED ${LANG_FRENCH} \ "Désolé, nous n'avons pas pu désinstaller l'ancienne version. Nous essaierons d'installer la nouvelle version, mais vous pouvez également appuyer sur Annuler et essayer de supprimer l'ancienne version par vous-même." LangString ASIO_DRIVER_HEADER ${LANG_FRENCH} \ "Pilote ASIO" LangString ASIO_DRIVER_SUB ${LANG_FRENCH} \ "Pour utiliser ${APP_NAME}, vous avez besoin d'un pilote ASIO" LangString ASIO_DRIVER_EXPLAIN ${LANG_FRENCH} \ "${APP_NAME} a besoin d'un pilote ASIO pour fournir un son à faible latence. Plus d'informations : " LangString ASIO_DRIVER_MORE_INFO ${LANG_FRENCH} \ "Plus d'informations à propos d'ASIO sur jamulus.io" LangString ASIO_DRIVER_MORE_INFO_URL ${LANG_FRENCH} \ "https://jamulus.io/fr/wiki/Installation-for-Windows#asio" LangString ASIO_EXIT_NO_DRIVER ${LANG_FRENCH} \ "${APP_NAME} a besoin d'un pilote audio ASIO pour fonctionner, mais nous n'avons pas pu en trouver sur votre PC. Vous devriez en installer un comme ASIO4ALL (Plus d'informations sur jamulus.io sous Installation sous Windows). Voulez-vous tout de même continuer l'installation de ${APP_NAME} en premier ? " LangString JACK_DRIVER_HEADER ${LANG_FRENCH} \ "Kit de connexion audio JACK" LangString JACK_DRIVER_SUB ${LANG_FRENCH} \ "Pour utiliser cette version de ${APP_NAME}, vous devez utiliser le kit de connexion audio JACK." LangString JACK_DRIVER_EXPLAIN ${LANG_FRENCH} \ "Cette version de ${APP_NAME} utilise le kit de connexion audio JACK. Veuillez vous assurer que ce kit a été installé ou téléchargez la version standard de ${APP_NAME} sur jamulus.io qui utilise ASIO." LangString JACK_EXIT_NO_DRIVER ${LANG_FRENCH} \ "Cette version de ${APP_NAME} a besoin du kit de connexion audio JACK pour fonctionner, mais celui-ci ne semble pas être installé sur votre PC. Vous devez d'abord installer JACK pour Windows. Voulez-vous toujours continuer l'installation de ${APP_NAME} sans installer JACK d'abord ?" jamulus-3.9.1+dfsg/src/translation/wininstaller/nl_NL.nsi0000644000175000017500000000531514340334543022535 0ustar vimervimer; Dutch translation LangString DESKTOP_SET_SHORTCUT ${LANG_DUTCH} \ "Desktop shortcut maken" LangString INVALID_FOLDER_MSG ${LANG_DUTCH} \ "De doelmap bestaat al. Kies een nieuwe doelmap." LangString RUNNING_APP_MSG ${LANG_DUTCH} \ "${APP_NAME} loopt nog. Sluit het programma en start de installatie opnieuw." LangString OLD_WRONG_VER_FOUND ${LANG_DUTCH} \ "We hebben een oudere versie van ${APP_NAME} in de 32 Bit Program Files map gevonden. Deze kan het beste worden verwijderd alvorens een nieuwe versie van ${APP_NAME} te installeren. Wilt u het nu laten verwijderen?" LangString OLD_WRONG_VER_FOUND_CONFIRM ${LANG_DUTCH} \ "Als u doorgaat zonder het te verwijderen, kan de installatie mogelijk mislukken! Weet u zeker dat u de oude versie niet wil verwijderen?" LangString OLD_VER_REMOVE_FAILED ${LANG_DUTCH} \ "Helaas is het niet gelukt de oude versie te verwijderen. We zullen proberen de nieuwe versie te installeren, maar u kunt ook de installatie nu annuleren en de oude versie zelf proberen te verwijderen." LangString ASIO_DRIVER_HEADER ${LANG_DUTCH} \ "ASIO stuurprogramma" LangString ASIO_DRIVER_SUB ${LANG_DUTCH} \ "Om ${APP_NAME} te kunnen gebruiken heeft u een ASIO stuurprogramma nodig" LangString ASIO_DRIVER_EXPLAIN ${LANG_DUTCH} \ "${APP_NAME} heeft een ASIO stuurprogramma nodig voor low latency audio. Meer informatie:" LangString ASIO_DRIVER_MORE_INFO ${LANG_DUTCH} \ "Meer informatie over ASIO op jamulus.io" LangString ASIO_DRIVER_MORE_INFO_URL ${LANG_DUTCH} \ "https://jamulus.io/wiki/Installation-for-Windows#asio" LangString ASIO_EXIT_NO_DRIVER ${LANG_DUTCH} \ "${APP_NAME} heeft een ASIO audio-stuurprogramma nodig om te functioneren, en we hebben er geen op uw PC gevonden. U dient een stuurprogramma als ASIO4ALL te installeren (Meer informatie op jamulus.io onder Installation for Windows). Wilt u nog steeds verder gaan met de installatie van ${APP_NAME}?" LangString JACK_DRIVER_HEADER ${LANG_DUTCH} \ "JACK Audio Connection Kit" LangString JACK_DRIVER_SUB ${LANG_DUTCH} \ "Om deze versie van ${APP_NAME} te kunnen gebruiken heeft u de JACK Audio Connection Kit nodig" LangString JACK_DRIVER_EXPLAIN ${LANG_DUTCH} \ "Deze versie van ${APP_NAME} maakt gebruik van de JACK Audio Connection Kit. Zorg ervoor dat deze geïnstalleerd is of download de standaard versie van ${APP_NAME} op jamulus.io die gebruikt maakt van ASIO." LangString JACK_EXIT_NO_DRIVER ${LANG_DUTCH} \ "Deze ${APP_NAME} versie heeft de JACK Audio Connection Kit nodig om te functioneren, en we hebben deze niet op uw PC gevonden. U dient deze eerst zelf te installeren. Wilt u nog steeds verder gaan met de installatie van ${APP_NAME} zonder eerst JACK te installeren?" jamulus-3.9.1+dfsg/src/translation/wininstaller/en_UK.nsi0000644000175000017500000000511714340334543022534 0ustar vimervimer; English translation LangString DESKTOP_SET_SHORTCUT ${LANG_ENGLISH} \ "Create Desktop shortcut" LangString INVALID_FOLDER_MSG ${LANG_ENGLISH} \ "The destination folder already exists. Please enter a new destination folder." LangString RUNNING_APP_MSG ${LANG_ENGLISH} \ "${APP_NAME} is running. Please close it and run the setup again." LangString OLD_WRONG_VER_FOUND ${LANG_ENGLISH} \ "We detected an old version of ${APP_NAME} in your 32 Bit Program Files folder. It is strongly recommended to remove it before installing a new version of ${APP_NAME}. Do you want to remove it now?" LangString OLD_WRONG_VER_FOUND_CONFIRM ${LANG_ENGLISH} \ "If you continue without removing it, your installation might be broken! Are you sure you don't want to remove the old version?" LangString OLD_VER_REMOVE_FAILED ${LANG_ENGLISH} \ "Sorry, we couldn't uninstall the old version. We'll try to install the new one, but you can also press cancel and try to remove the old version on your own." LangString ASIO_DRIVER_HEADER ${LANG_ENGLISH} \ "ASIO driver" LangString ASIO_DRIVER_SUB ${LANG_ENGLISH} \ "To use ${APP_NAME}, you need an ASIO driver" LangString ASIO_DRIVER_EXPLAIN ${LANG_ENGLISH} \ "${APP_NAME} needs an ASIO driver to provide low latency audio. More information:" LangString ASIO_DRIVER_MORE_INFO ${LANG_ENGLISH} \ "More information about ASIO on jamulus.io" LangString ASIO_DRIVER_MORE_INFO_URL ${LANG_ENGLISH} \ "https://jamulus.io/wiki/Installation-for-Windows#asio" LangString ASIO_EXIT_NO_DRIVER ${LANG_ENGLISH} \ "${APP_NAME} needs an ASIO audio driver to work, but we couldn't find one on your PC. You should install one like ASIO4ALL (More information on jamulus.io under Installation for Windows). Do you still want to continue with the installation of ${APP_NAME} first?" LangString JACK_DRIVER_HEADER ${LANG_ENGLISH} \ "JACK Audio Connection Kit" LangString JACK_DRIVER_SUB ${LANG_ENGLISH} \ "To use this version of ${APP_NAME}, you need use the JACK Audio Connection Kit" LangString JACK_DRIVER_EXPLAIN ${LANG_ENGLISH} \ "This version of ${APP_NAME} is making use of the JACK Audio Connection Kit. Please make sure this has been installed or download the standard version of ${APP_NAME} on jamulus.io which is using ASIO." LangString JACK_EXIT_NO_DRIVER ${LANG_ENGLISH} \ "This ${APP_NAME} version needs the JACK Audio Connection Kit to work, but it doesn't seem to be installed on your PC. You should install JACK for Windows first. Do you still want to continue with the installation of ${APP_NAME} without installing JACK first?" jamulus-3.9.1+dfsg/src/translation/wininstaller/pt_PT.nsi0000644000175000017500000000551114340334543022557 0ustar vimervimer; Portuguese translation LangString DESKTOP_SET_SHORTCUT ${LANG_PORTUGUESE} \ "Criar Atalho no Ambiente de Trabalho" LangString INVALID_FOLDER_MSG ${LANG_PORTUGUESE} \ "A pasta de destino já existe. Por favor, selecione uma nova pasta de destino." LangString RUNNING_APP_MSG ${LANG_PORTUGUESE} \ "O ${APP_NAME} está em execução. Por favor, feche-o e execute o instalador novamente." LangString OLD_WRONG_VER_FOUND ${LANG_PORTUGUESE} \ "Nós detetamos uma versão antiga do ${APP_NAME} na sua pasta de Ficheiros de Programas 32 Bits. É altamente recomendado a sua remoção antes de instalar uma nova versão do ${APP_NAME}. Deseja removê-la agora?" LangString OLD_WRONG_VER_FOUND_CONFIRM ${LANG_PORTUGUESE} \ "Se continuar sem remover a instalação antiga, a sua instalação poderá ser corrompida! Tem a certeza que não deseja remover a versão antiga?" LangString OLD_VER_REMOVE_FAILED ${LANG_PORTUGUESE} \ "As nossas desculpas, mas não foi possível remover a versão antiga. Nós iremos tentar instalar a nova versão, mas pode também clicar em Cancelar e tentar remover a versão antiga manualmente." LangString ASIO_DRIVER_HEADER ${LANG_PORTUGUESE} \ "Controlador ASIO" LangString ASIO_DRIVER_SUB ${LANG_PORTUGUESE} \ "Para utilizar o ${APP_NAME}, precisa de um controlador ASIO" LangString ASIO_DRIVER_EXPLAIN ${LANG_PORTUGUESE} \ "O ${APP_NAME} precisa de um controlador ASIO para fornecer áudio de baixa latência. Mais informação:" LangString ASIO_DRIVER_MORE_INFO ${LANG_PORTUGUESE} \ "Mais informação sobre o ASIO em jamulus.io" LangString ASIO_DRIVER_MORE_INFO_URL ${LANG_PORTUGUESE} \ "https://jamulus.io/pt/wiki/Installation-for-Windows" LangString ASIO_EXIT_NO_DRIVER ${LANG_PORTUGUESE} \ "O ${APP_NAME} precisa de um controlador ASIO para funcionar, mas nós não conseguimos encontrar nenhum no seu computador. Deveria instalar um, como o ASIO4ALL (Mais informação em jamulus.io, em Instalação no Windows). Ainda quer continuar com a instalação do ${APP_NAME} primeiro?" LangString JACK_DRIVER_HEADER ${LANG_PORTUGUESE} \ "JACK Audio Connection Kit" LangString JACK_DRIVER_SUB ${LANG_PORTUGUESE} \ "Para utilizar esta versão do ${APP_NAME}, precisa de utilizar JACK Audio Connection Kit" LangString JACK_DRIVER_EXPLAIN ${LANG_PORTUGUESE} \ "Esta versão do ${APP_NAME} utiliza JACK Audio Connection Kit. Por favor, certifique-se de que isto foi instalado ou transfira a versão padrão do ${APP_NAME} em jamulus.io que está a utilizar ASIO." LangString JACK_EXIT_NO_DRIVER ${LANG_PORTUGUESE} \ "Esta versão do ${APP_NAME} precise de JACK Audio Connection Kit para funcionar, mas parece que este não está instalado no seu PC. Deveria instalar primeiro JACK para Windows. Ainda quer continuar coma instalação do ${APP_NAME} sem instalar primeiro JACK?" jamulus-3.9.1+dfsg/src/translation/wininstaller/it_IT.nsi0000644000175000017500000000535714340334543022551 0ustar vimervimer; Italian translation LangString DESKTOP_SET_SHORTCUT ${LANG_ITALIAN} \ "Crea collegamento su Desktop" LangString INVALID_FOLDER_MSG ${LANG_ITALIAN} \ "La cartella di destinazione esiste già. Selezionare una nuova cartella di destinazione." LangString RUNNING_APP_MSG ${LANG_ITALIAN} \ "${APP_NAME} è in esecuzione. Chiudere l'applicazione prima di eseguire l'installazione." LangString OLD_WRONG_VER_FOUND ${LANG_ITALIAN} \ "E' stata trovata una precedente versione di ${APP_NAME} nella cartella Programmi. E' altamente consigliato rimuoverla prima di procedere con l'insallazione di una nuova versione di ${APP_NAME}. Vuoi rimuoverla adesso?" LangString OLD_WRONG_VER_FOUND_CONFIRM ${LANG_ITALIAN} \ "Se non viene cancellata l'installazione potrebbe non andare a buona fine! Sei sicuro di voler continuare?" LangString OLD_VER_REMOVE_FAILED ${LANG_ITALIAN} \ "ERRORE: L'UNISTALLERE HA FALLITO. Cliccando OK la vecchia versione rimarrà installata nel PC verrà tentato comunque di installare la nuova versione. Premi Cancel per provare ad eliminarla manualmente." LangString ASIO_DRIVER_HEADER ${LANG_ITALIAN} \ "ASIO driver" LangString ASIO_DRIVER_SUB ${LANG_ITALIAN} \ "Per usare ${APP_NAME} hai bisogno dei driver ASIO" LangString ASIO_DRIVER_EXPLAIN ${LANG_ITALIAN} \ "${APP_NAME} ha bisogno dei driver ASIO al fine di garantire una bassa latenza audio. Maggiori Informazioni:" LangString ASIO_DRIVER_MORE_INFO ${LANG_ITALIAN} \ "Maggiori informazioni sui driver ASIO disponibili su jamulus.io" LangString ASIO_DRIVER_MORE_INFO_URL ${LANG_ITALIAN} \ "https://jamulus.io/wiki/Installation-for-Windows#asio" LangString ASIO_EXIT_NO_DRIVER ${LANG_ITALIAN} \ "Per assicurare una bassa latenza, ${APP_NAME} usa i driver ASIO. Questi non sono presenti sul PC, puoi installarne una versione come gli ASIO4ALL. Maggiori informazione su jamulus.io, trovi il link nella pagina in cui ti trovavi. Per tornarci premi su NO. Se premi 'Si', l'installazione continuerà." LangString JACK_DRIVER_HEADER ${LANG_ITALIAN} \ "JACK Audio Connection Kit" LangString JACK_DRIVER_SUB ${LANG_ITALIAN} \ "Per usare questa versione di ${APP_NAME},hai bisogno di installare il: JACK Audio Connection Kit" LangString JACK_DRIVER_EXPLAIN ${LANG_ITALIAN} \ "Per usare questa versione di ${APP_NAME} è necessario avviare il JACK Audio Connection Kit. Assicurati di averlo installato altrimenti scarica ${APP_NAME} su jamulus.io per usare gli ASIO." LangString JACK_EXIT_NO_DRIVER ${LANG_ITALIAN} \ "Questa versione di ${APP_NAME} necessita di JACK Audio Connection Kit per funzionare, ma sembra non essere installato sul tuo PC. Prima installa JACK per windows. Vuoi continuare l'installazione di ${APP_NAME} senza installare JACK?" jamulus-3.9.1+dfsg/src/translation/wininstaller/es_ES.nsi0000644000175000017500000000530414340334543022527 0ustar vimervimer; SPANISH translation LangString DESKTOP_SET_SHORTCUT ${LANG_SPANISH} \ "Crear acceso directo en Escritorio" LangString INVALID_FOLDER_MSG ${LANG_SPANISH} \ "La carpeta de destino ya existe. Por favor escoja una carpeta de destino nueva." LangString RUNNING_APP_MSG ${LANG_SPANISH} \ "${APP_NAME} se está ejecutando. Por favor ciérralo y ejecuta la instalación de nuevo." LangString OLD_WRONG_VER_FOUND ${LANG_SPANISH} \ "Hemos detectado una versión antigua de ${APP_NAME} en tu carpeta de Archivos de Programa de 32 Bit. Se recomienda encarecidamente que la elimines antes de instalar una nueva versión de ${APP_NAME}. ¿Quieres eliminarla ahora?" LangString OLD_WRONG_VER_FOUND_CONFIRM ${LANG_SPANISH} \ "Si continúas sin eliminarla, tu instalación podría fallar. ¿Estás segur@ de que no quieres eliminar la versión antigua?" LangString OLD_VER_REMOVE_FAILED ${LANG_SPANISH} \ "Lo sentimos, no ha sido posible desinstalar la versión antigua. Intentaremos instalar la nueva, pero también puedes pulsar en cancelar e intentar eliminar tú la versión antigua." LangString ASIO_DRIVER_HEADER ${LANG_SPANISH} \ "Driver ASIO" LangString ASIO_DRIVER_SUB ${LANG_SPANISH} \ "Para utilizar ${APP_NAME}, necesitas un driver ASIO" LangString ASIO_DRIVER_EXPLAIN ${LANG_SPANISH} \ "${APP_NAME} necesita un driver ASIO para proporcionar una baja latencia. Más información:" LangString ASIO_DRIVER_MORE_INFO ${LANG_SPANISH} \ "Más información sobre ASIO en jamulus.io" LangString ASIO_DRIVER_MORE_INFO_URL ${LANG_SPANISH} \ "https://jamulus.io/es/wiki/Installation-for-Windows#asio" LangString ASIO_EXIT_NO_DRIVER ${LANG_SPANISH} \ "${APP_NAME} necesita un driver de audio ASIO para funcionar, pero no hemos podido encontrar ninguno en tu PC. Deberías instalar uno como ASIO4ALL (más información en jamulus.io, en Instalación en Windows). ¿Aún quieres seguir con la instalación de ${APP_NAME} primero?" LangString JACK_DRIVER_HEADER ${LANG_SPANISH} \ "JACK Audio Connection Kit" LangString JACK_DRIVER_SUB ${LANG_SPANISH} \ "Para utilizar esta versión de ${APP_NAME}, necesitas utilizar JACK Audio Connection Kit" LangString JACK_DRIVER_EXPLAIN ${LANG_SPANISH} \ "Esta versión de ${APP_NAME} utiliza JACK Audio Connection Kit. Por favor asegúrate de que está instalado o descarga la versión estándar de ${APP_NAME} desde jamulus.io que utiliza ASIO." LangString JACK_EXIT_NO_DRIVER ${LANG_SPANISH} \ "Esta versión de ${APP_NAME} necesita JACK Audio Connection Kit para funcionar, pero no parece estar instalado en tu PC. Deberías instalar JACK para Windows primero. ¿Deseas seguir con la instalación de ${APP_NAME} sin instalar JACK primero?" jamulus-3.9.1+dfsg/src/translation/wininstaller/sv_SE.nsi0000644000175000017500000000524714340334543022556 0ustar vimervimer; Swedish translation LangString DESKTOP_SET_SHORTCUT ${LANG_SWEDISH} \ "Skapa skrivbordsgenväg" LangString INVALID_FOLDER_MSG ${LANG_SWEDISH} \ "Mappen finns redan. Ange en ny målmapp." LangString RUNNING_APP_MSG ${LANG_SWEDISH} \ "${APP_NAME} körs. Stäng den och kör installationen igen." LangString OLD_WRONG_VER_FOUND ${LANG_SWEDISH} \ "Vi upptäckte en gammal version av ${APP_NAME} i din 32-bitars programmapp. Vi rekommenderar starkt att du tar bort den innan du installerar en ny version av ${APP_NAME}. Vill du ta bort den nu?" LangString OLD_WRONG_VER_FOUND_CONFIRM ${LANG_SWEDISH} \ "Om du fortsätter utan att ta bort den finns det risk att installationen inte kommer att fungera. Är du säker på att du inte vill ta bort den gamla versionen?" LangString OLD_VER_REMOVE_FAILED ${LANG_SWEDISH} \ "Vi kunde tyvärr inte avinstallera den gamla versionen. Vi försöker installera den nya, men du kan också trycka på Avbryt och försöka ta bort den gamla versionen själv." LangString ASIO_DRIVER_HEADER ${LANG_SWEDISH} \ "ASIO-ljuddrivrutin" LangString ASIO_DRIVER_SUB ${LANG_SWEDISH} \ "För att kunna använda ${APP_NAME} behöver du en ASIO-ljuddrivrutin" LangString ASIO_DRIVER_EXPLAIN ${LANG_SWEDISH} \ "${APP_NAME} behöver en ASIO-ljuddrivrutin för att ge ljud med låg latens. Mer information:" LangString ASIO_DRIVER_MORE_INFO ${LANG_SWEDISH} \ "Mer information om ASIO hittar du på jamulus.io" LangString ASIO_DRIVER_MORE_INFO_URL ${LANG_SWEDISH} \ "https://jamulus.io/wiki/Installation-for-Windows#asio" LangString ASIO_EXIT_NO_DRIVER ${LANG_SWEDISH} \ "${APP_NAME} behöver en ASIO-ljuddrivrutin för att fungera, men vi kunde inte hitta någon på din dator. Du bör installera en som ASIO4ALL (Mer information på jamulus.io under $\"Installation for Windows$\"). Vill du fortfarande fortsätta med installationen av ${APP_NAME} först?" LangString JACK_DRIVER_HEADER ${LANG_SWEDISH} \ "JACK Audio Connection Kit" LangString JACK_DRIVER_SUB ${LANG_SWEDISH} \ "To use this version of ${APP_NAME}, you need use the JACK Audio Connection Kit" LangString JACK_DRIVER_EXPLAIN ${LANG_SWEDISH} \ "This version of ${APP_NAME} is making use of the JACK Audio Connection Kit. Please make sure this has been installed or download the standard version of ${APP_NAME} on jamulus.io which is using ASIO." LangString JACK_EXIT_NO_DRIVER ${LANG_SWEDISH} \ "This ${APP_NAME} version needs the JACK Audio Connection Kit to work, but it doesn't seem to be installed on your PC. You should install JACK for Windows first. Do you still want to continue with the installation of ${APP_NAME} without installing JACK first?" jamulus-3.9.1+dfsg/src/translation/wininstaller/installerlng.nsi0000644000175000017500000000262214340334543024227 0ustar vimervimer; Language configuration ; Additional languages can be added in this file. See https://nsis.sourceforge.io/Examples/Modern%20UI/MultiLanguage.nsi !insertmacro MUI_LANGUAGE "English" ; The first language is the default !include "${ROOT_PATH}\src\translation\wininstaller\en_UK.nsi" ; include english, standard language !insertmacro MUI_LANGUAGE "German" !include "${ROOT_PATH}\src\translation\wininstaller\de_DE.nsi" !insertmacro MUI_LANGUAGE "Italian" !include "${ROOT_PATH}\src\translation\wininstaller\it_IT.nsi" !insertmacro MUI_LANGUAGE "Dutch" !include "${ROOT_PATH}\src\translation\wininstaller\nl_NL.nsi" !insertmacro MUI_LANGUAGE "Polish" !include "${ROOT_PATH}\src\translation\wininstaller\pl_PL.nsi" !insertmacro MUI_LANGUAGE "French" !include "${ROOT_PATH}\src\translation\wininstaller\fr_FR.nsi" !insertmacro MUI_LANGUAGE "Spanish" !include "${ROOT_PATH}\src\translation\wininstaller\es_ES.nsi" !insertmacro MUI_LANGUAGE "Swedish" !include "${ROOT_PATH}\src\translation\wininstaller\sv_SE.nsi" !insertmacro MUI_LANGUAGE "PortugueseBR" !include "${ROOT_PATH}\src\translation\wininstaller\pt_BR.nsi" !insertmacro MUI_LANGUAGE "Portuguese" !include "${ROOT_PATH}\src\translation\wininstaller\pt_PT.nsi" !insertmacro MUI_LANGUAGE "SimpChinese" !include "${ROOT_PATH}\src\translation\wininstaller\zh_CN.nsi" !insertmacro MUI_LANGUAGE "Korean" !include "${ROOT_PATH}\src\translation\wininstaller\ko_KR.nsi" jamulus-3.9.1+dfsg/src/translation/wininstaller/pt_BR.nsi0000644000175000017500000000542514340334543022543 0ustar vimervimer; PortugueseBR translation LangString DESKTOP_SET_SHORTCUT ${LANG_PORTUGUESEBR} \ "Criar atalho na Área de Trabalho" LangString INVALID_FOLDER_MSG ${LANG_PORTUGUESEBR} \ "A pasta de destino já existe. Por favor, insira uma nova pasta de destino." LangString RUNNING_APP_MSG ${LANG_PORTUGUESEBR} \ "${APP_NAME} está em execução. Por favor, encerre-o e execute a instalação novamente." LangString OLD_WRONG_VER_FOUND ${LANG_PORTUGUESEBR} \ "Detectamos uma versão antiga de ${APP_NAME} em sua pasta Arquivos de Programa de 32 bits. É altamente recomendado removê-la antes de instalar uma nova versão de ${APP_NAME}. Deseja removê-la agora?" LangString OLD_WRONG_VER_FOUND_CONFIRM ${LANG_PORTUGUESEBR} \ "Se continuar sem sua remoção, sua instalação poderá ser danificada! Tem certeza que você não deseja remover a versão antiga?" LangString OLD_VER_REMOVE_FAILED ${LANG_PORTUGUESEBR} \ "Não foi possível desinstalar a versão antiga. Tentaremos instalar a nova, mas você pode também apertar cancelar e tentar remover a versão antiga por conta própria." LangString ASIO_DRIVER_HEADER ${LANG_PORTUGUESEBR} \ "Driver ASIO" LangString ASIO_DRIVER_SUB ${LANG_PORTUGUESEBR} \ "Para usar ${APP_NAME}, você necessita de um driver ASIO" LangString ASIO_DRIVER_EXPLAIN ${LANG_PORTUGUESEBR} \ "${APP_NAME} necessita de um driver ASIO para fornecer áudio com baixa latência. Mais informações:" LangString ASIO_DRIVER_MORE_INFO ${LANG_PORTUGUESEBR} \ "Mais informações sobre ASIO em jamulus.io" LangString ASIO_DRIVER_MORE_INFO_URL ${LANG_PORTUGUESEBR} \ "https://jamulus.io/wiki/Installation-for-Windows#asio" LangString ASIO_EXIT_NO_DRIVER ${LANG_PORTUGUESEBR} \ "${APP_NAME} necessita de um driver de áudio ASIO para funcionar, mas não conseguimos encontrar um no seu PC. Você deve instalar um como ASIO4ALL (Mais informações em jamulus.io em Instalação para Windows). Ainda deseja continuar com a instalação de ${APP_NAME} primeiro?" LangString JACK_DRIVER_HEADER ${LANG_PORTUGUESEBR} \ "JACK Audio Connection Kit" LangString JACK_DRIVER_SUB ${LANG_PORTUGUESEBR} \ "Para usar esta versão do ${APP_NAME}, você necessita usar o JACK Audio Connection Kit" LangString JACK_DRIVER_EXPLAIN ${LANG_PORTUGUESEBR} \ "Esta versão do ${APP_NAME} faz uso do JACK Audio Connection Kit. Certifique-se que isso foi instalado ou descarregue a versão padrão do ${APP_NAME} on jamulus.io que utiliza ASIO." LangString JACK_EXIT_NO_DRIVER ${LANG_PORTUGUESEBR} \ "Esta versão do ${APP_NAME} necessita do JACK Audio Connection Kit para funcionar, mas parece não estar instalado em seu PC. Você deve primeiramente instalar JACK para Windows. Ainda deseja continuar com a instalação do ${APP_NAME} sem instalar o JACK primeiro?" jamulus-3.9.1+dfsg/src/translation/wininstaller/ko_KR.nsi0000644000175000017500000000556514340334543022547 0ustar vimervimer; Korean translation LangString DESKTOP_SET_SHORTCUT ${LANG_KOREAN} \ "바탕화면 바로가기 만들기" LangString INVALID_FOLDER_MSG ${LANG_KOREAN} \ "대상 폴더가 이미 있습니다. 새 대상 폴더를 입력하십시오." LangString RUNNING_APP_MSG ${LANG_KOREAN} \ "${APP_NAME}가 실행 중입니다. 프로그램을 닫고 다시 실행하십시오." LangString OLD_WRONG_VER_FOUND ${LANG_KOREAN} \ "사용자의 32비트 Program Files 폴더에서 ${APP_NAME}의 이전 버전을 감지했습니다. ${APP_NAME}의 새 버전을 설치하기 전에 제거하는 것이 좋습니다. 지금 제거하시겠습니까?" LangString OLD_WRONG_VER_FOUND_CONFIRM ${LANG_KOREAN} \ "제거하지 않고 계속하면 설치가 중단될 수 있습니다! 이전 버전을 제거하지 않으시겠습니까?" LangString OLD_VER_REMOVE_FAILED ${LANG_KOREAN} \ "죄송합니다. 이전 버전을 제거할 수 없습니다. 새 버전을 설치해보겠지만, 취소를 누르고 이전 버전을 직접 제거할 수도 있습니다." LangString ASIO_DRIVER_HEADER ${LANG_KOREAN} \ "ASIO 드라이버" LangString ASIO_DRIVER_SUB ${LANG_KOREAN} \ "${APP_NAME}의 실행에는, ASIO 드라이버가 필요합니다" LangString ASIO_DRIVER_EXPLAIN ${LANG_KOREAN} \ "${APP_NAME}가 낮은 지연 시간 오디오를 제공하기 위해서는 ASIO 드라이버가 필요합니다. 더 많은 정보:" LangString ASIO_DRIVER_MORE_INFO ${LANG_KOREAN} \ "jamulus.io에 ASIO에 관한 좀 더 많은 정보가 있습니다" LangString ASIO_DRIVER_MORE_INFO_URL ${LANG_KOREAN} \ "https://jamulus.io/wiki/Installation-for-Windows#asio" LangString ASIO_EXIT_NO_DRIVER ${LANG_KOREAN} \ "${APP_NAME}에는 ASIO 오디오 드라이버가 필요하지만, 사용자의 PC에서는 발견하지 못했습니다. ASIO4ALL 같은 프로그램이 설치되어야 합니다 (jamulus.io에 대한 자세한 정보는 Windows용 설치 참조). 우선 ${APP_NAME} 먼저 설치하시겠습니까?" LangString JACK_DRIVER_HEADER ${LANG_KOREAN} \ "JACK 오디오 연결 키트" LangString JACK_DRIVER_SUB ${LANG_KOREAN} \ "이 버전의 ${APP_NAME}을(를) 사용하시려면, JACK 오디오 연결 키트가 필요합니다" LangString JACK_DRIVER_EXPLAIN ${LANG_KOREAN} \ "이 버전의 ${APP_NAME}은(는) JACK 오디오 연결 키트를 사용하고 있습니다. 이미 설치되어 있는지 확인하거나 ASIO를 사용하는 jamulus.io에서 ${APP_NAME}의 표준 버전을 다운로드하십시오." LangString JACK_EXIT_NO_DRIVER ${LANG_KOREAN} \ "이 ${APP_NAME} 버전이 작동하려면 JACK 오디오 연결 키트가 필요하지만, 사용자의 PC에 설치되어 있지 않은 것 같습니다. 먼저 Windows용 JACK을 설치해야 합니다. 그래도 JACK을 먼저 설치하지 않고 ${APP_NAME} 설치를 계속하시겠습니까?" jamulus-3.9.1+dfsg/src/translation/wininstaller/zh_CN.nsi0000644000175000017500000000477414340334543022544 0ustar vimervimer; SimpChinese translation LangString DESKTOP_SET_SHORTCUT ${LANG_SIMPCHINESE} \ "创建桌面快捷方式" LangString INVALID_FOLDER_MSG ${LANG_SIMPCHINESE} \ "目标目录已存在。请选择一个新的目标目录。" LangString RUNNING_APP_MSG ${LANG_SIMPCHINESE} \ "${APP_NAME} 正在运行中。请先将其关闭后重试。" LangString OLD_WRONG_VER_FOUND ${LANG_SIMPCHINESE} \ "我们在您的 32 位 Program Files 目录中检测到了早期版本的 ${APP_NAME}。强烈建议您在安装新版本前将其删除。您希望现在就将其删除吗?" LangString OLD_WRONG_VER_FOUND_CONFIRM ${LANG_SIMPCHINESE} \ "如果您选择继续但不移除,您的安装可能会损坏!您确定不移除旧版本吗?" LangString OLD_VER_REMOVE_FAILED ${LANG_SIMPCHINESE} \ "抱歉,我们无法卸载旧版本。我们将尝试安装新版本,但您也可以选择按下取消并自行移除旧版本。" LangString ASIO_DRIVER_HEADER ${LANG_SIMPCHINESE} \ "ASIO 驱动" LangString ASIO_DRIVER_SUB ${LANG_SIMPCHINESE} \ "要使用 Jamulus,您需要一个 ASIO 驱动" LangString ASIO_DRIVER_EXPLAIN ${LANG_SIMPCHINESE} \ "Jamulus 需要 ASIO 驱动以提供低延迟的音频。更多信息:" LangString ASIO_DRIVER_MORE_INFO ${LANG_SIMPCHINESE} \ "jamulus.io 上的关于 ASIO 的更多信息" LangString ASIO_DRIVER_MORE_INFO_URL ${LANG_SIMPCHINESE} \ "https://jamulus.io/wiki/Installation-for-Windows#asio" LangString ASIO_EXIT_NO_DRIVER ${LANG_SIMPCHINESE} \ "${APP_NAME} 需要 ASIO 音频驱动来正常工作,但在您的 PC 上未能找到。您需要首先安装一个 ASIO 驱动,例如 ASIO4ALL(更多信息请参见 jamulus.io 的 Installation for Windows 页面)。您仍希望先继续安装 ${APP_NAME} 吗?" LangString JACK_DRIVER_HEADER ${LANG_SIMPCHINESE} \ "JACK 音频连接工具" LangString JACK_DRIVER_SUB ${LANG_SIMPCHINESE} \ "要使用此版本的 ${APP_NAME},您需要配合使用 JACK 音频连接工具" LangString JACK_DRIVER_EXPLAIN ${LANG_SIMPCHINESE} \ "此版本的 ${APP_NAME} 使用了 JACK 音频连接工具。请确保其已被安装,或从 jamulus.io 获取标准版本的,使用 ASIO 的 ${APP_NAME}。" LangString JACK_EXIT_NO_DRIVER ${LANG_SIMPCHINESE} \ "当前 ${APP_NAME} 版本需要 JACK 音频连接工具来正常工作,但在您的 PC 上未能找到。您需要首先安装 JACK 的 Windows 版本。您仍希望在不先安装 JACK 的情况下继续安装 ${APP_NAME} 吗?" jamulus-3.9.1+dfsg/src/translation/translation_pt_PT.ts0000644000175000017500000103014414340334543022320 0ustar vimervimer CAboutDlg The O software enables musicians to perform real-time jam sessions over the internet. There is a permite aos músicos realizar jam sessions em tempo real pela Internet. Existe um servidor software enables musicians to perform real-time jam sessions over the internet. permite aos músicos realizar jam sessions em tempo real pela Internet. server which collects the audio data from each que reúne os dados de áudio de cada cliente There is a Existe um servidor client, mixes the audio data and sends the mix back to each client. , que mistura os dados de áudio e envia a mistura de volta para cada cliente. uses the following libraries, resources or code snippets: utiliza as seguintes bibliotecas, recursos ou partes de código: Qt cross-platform application framework Estrutura de aplicações multiplataforma Qt Audio reverberation code by Perry R. Cook and Gary P. Scavone Código de reverberação de áudio por Perry R. Cook e Gary P. Scavone Some pixmaps are from the Alguns pixmaps são do Country flag icons from Mark James Ícones de bandeira do país de Mark James This app enables musicians to perform real-time jam sessions over the internet. Esta aplicação permite que os músicos realizem sessões ''jam'' em tempo real pela Internet. There is a server which collects the audio data from each client, mixes the audio data and sends the mix back to each client. Existe um servidor que reúne os dados de áudio de cada cliente, mistura os dados de áudio e envia a mistura de volta para cada cliente. This app uses the following libraries, resources or code snippets: Esta aplicação utiliza as seguintes bibliotecas, recursos ou partes de código: Country flag icons by Mark James Ícones das bandeiras dos países por Mark James For details on the contributions check out the Para detalhes sobre as contribuições, consulte a Flag icons by Mark James Ícones de bandeiras por Mark James Some sound samples are from Algumas amostras de som provenientes de For details on the contributions check out the %1 Para detalhes sobre as contribuições, consulte a %1 Github Contributors list Lista de colaboradores do Github Spanish Espanhol French Francês Portuguese Português (Portugal) Dutch Holandês Italian Italiano German Alemão Polish Polaco Swedish Sueco Korean Coreano Slovak Eslovaco Simplified Chinese Chinês Simplificado Norwegian Bokmål About %1 Sobre %1 About Sobre o , Version , Versão Internet Jam Session Software Programa de Jam Sessions pela Internet Released under the GNU General Public License (GPL) Lançado sob a Licença Pública Geral GNU (GPL) Under the GNU General Public License (GPL) Sob a Licença Pública Geral GNU (GPL) CAboutDlgBase About Sobre TextLabelVersion TextoEtiquetaVersão Copyright (C) 2005-2022 Volker Fischer and others Copyright (C) 2005-2022 Volker Fischer e outros Copyright (C) 2005-2022 The Jamulus Development Team Direitos de Autor (C) 2005-2022 A Equipa de Desenvolvimento do Jamulus A&bout &Sobre &Libraries &Bibliotecas &Contributors &Colaboradores &Translation &Tradução Author: Volker Fischer Autor: Volker Fischer Copyright (C) 2005-2022 Copyright (C) 2005-2022 &OK &OK CAnalyzerConsole Analyzer Console Consola de Análise Error Rate of Each Buffer Size Taxa de Erros de Cada Tamanho de Buffer CAudioMixerBoard Personal Mix at the Server Mistura Pessoal no Servidor When connected to a server, the controls here allow you to set your local mix without affecting what others hear from you. The title shows the server name and, when known, whether it is actively recording. Quando ligado a um servidor, estes controles permitem que defina a sua mistura local sem afectar o que os outros ouvem. O título mostra o nome do servidor e, quando conhecido, se está gravando activamente. Server Servidor T R Y I N G T O C O N N E C T T E N T A N D O L I G A R RECORDING ACTIVE GRAVAÇÃO ACTIVA Personal Mix at: %1 Mistura Pessoal no Servidor: %1 CChannelFader Channel Level Nível do Canal Displays the pre-fader audio level of this channel. All connected clients at the server will be assigned an audio level, the same value for each client. Mostra o nível de áudio pré-fader deste canal. Todos os clientes ligados ao servidor terão atribuído um nível de áudio, o mesmo valor para cada cliente. Input level of the current audio channel at the server Nível de entrada deste canal de áudio do servidor Mixer Fader Fader da Mistura Adjusts the audio level of this channel. All connected clients at the server will be assigned an audio fader at each client, adjusting the local mix. Ajusta o nível de áudio deste canal. Por cada cliente ligado ao servidor será atribuído um fader de áudio em todos os clientes, podendo cada um ajustar a sua mistura local. Local mix level setting of the current audio channel at the server Configuração do nível de mistura local deste canal de áudio do servidor Status Indicator Indicador de Estado Shows a status indication about the client which is assigned to this channel. Supported indicators are: Mostra uma indicação de estado sobre o cliente que está atribuído a este canal. Os indicadores suportados são: Speaker with cancellation stroke: Indicates that the other client has muted you. Alti-falante com sinal de proibição: Indica que o cliente silenciou o teu canal. Status indicator label Etiqueta do indicador de estado Panning Panorâmica Sets the panning position from Left to Right of the channel. Works only in stereo or preferably mono in/stereo out mode. Define a posição de panorâmica da esquerda para a direita do canal. Funciona apenas no modo estéreo ou, de preferência, no modo Entrada Mono/Saída Estéreo. Local panning position of the current audio channel at the server Posição de panorâmica local do canal de áudio atual no servidor With the Mute checkbox, the audio channel can be muted. Com a caixa de seleção Silenciar, o canal de áudio pode ser silenciado. Mute button Botão Silenciar With the Solo checkbox, the audio channel can be set to solo which means that all other channels except of the current channel are muted. It is possible to set more than one channel to solo. Com a caixa de seleção Solo, o canal de áudio pode ser definido como solo, o que significa que todos os outros canais, exceto o canal atual, serão silenciados. É possível definir mais que um canal no modo solo. Solo button Botão Solo Fader Tag Identificador do Fader The fader tag identifies the connected client. The tag name, the picture of your instrument and a flag of your country can be set in the main window. O Identificador do fader identifica o cliente ligado. O nome no identificador, a imagem do instrumento e a bandeira do país podem ser definidos no Meu Perfil. Grp Grp Displays the pre-fader audio level of this channel. All clients connected to the server will be assigned an audio level, the same value for every client. Mostra o nível de áudio pré-fader deste canal. A todos os clientes ligados ao servidor será atribuído um nível de áudio, o mesmo valor para cada cliente. &No grouping &Sem grupo Assign to group Atribuir a grupo Adjusts the audio level of this channel. All clients connected to the server will be assigned an audio fader, displayed at each client, to adjust the local mix. Ajusta o nível de áudio deste canal. A todos os clientes ligados ao servidor será atribuído um fader de áudio,exibido em cada cliente, para ajustar a mistura local. Speaker with cancellation stroke: Indicates that another client has muted you. Alti-falante com sinal de proibição: Indica que o cliente silenciou o teu canal. Sets the pan from Left to Right of the channel. Works only in stereo or preferably mono in/stereo out mode. Define a posição de panorâmica da esquerda para a direita do canal. Funciona apenas no modo estéreo ou, de preferência, no modo Entrada Mono/Saída Estéreo. With the Solo checkbox, the audio channel can be set to solo which means that all other channels except the soloed channel are muted. It is possible to set more than one channel to solo. Com a caixa de seleção Solo, o canal de áudio pode ser definido como solo, o que significa que todos os outros canais, exceto o canal atual, serão silenciados. É possível definir mais que um canal no modo solo. Group Grupo With the Grp checkbox, a group of audio channels can be defined. All channel faders in a group are moved in proportional synchronization if any one of the group faders are moved. Com a caixa de seleção Grp, um grupo de canais de áudio pode ser definido. Todos os faders de canal de um grupo são movidos em sincronização se algum dos faders do grupo for movido. Group button Botão de Grupo The fader tag identifies the connected client. The tag name, a picture of your instrument and the flag of your country can be set in the main window. O Identificador do fader identifica o cliente ligado. O nome no identificador, a imagem do instrumento e a bandeira do país podem ser definidos no Meu Perfil. Mixer channel instrument picture Imagem do instrumento do canal da mistura Mixer channel label (fader tag) Identificação do canal da mistura (identificador do fader) Mixer channel country flag Bandeira do país do canal da mistura PAN PAN MUTE MUTE SOLO SOLO GRP GRP M M S S G G Alias/Name Nome/Pseudónimo Instrument Instrumento Location Localização Skill Level Nível de Habilidade Alias Pseudónimo Beginner Principiante The fader tag identifies the connected client. The tag name, a picture of your instrument and the flag of your location can be set in the main window. O Identificador do fader identifica o cliente ligado. O nome no identificador, a imagem do instrumento e a bandeira de sua localização podem ser definidos na janela principal. Mixer channel country/region flag Bandeira do país/região do canal da mistura Intermediate Intermediário Expert Avançado Musician Profile Perfil do músico Mute Silenciar Pan Pan Solo Solo CChatDlg Chat Window Janela de Mensagens The chat window shows a history of all chat messages. A janela de mensagens mostra um histórico de todas as mensagens enviadas durante a sessão. Chat history Histórico de Mensagens Input Message Text Texto da Mensagem Enter the chat message text in the edit box and press enter to send the message to the server which distributes the message to all connected clients. Your message will then show up in the chat window. Introduza o texto da mensagem no campo de introdução e pressione Enter para enviar a mensagem ao servidor, que distribui a mensagem a todos os clientes ligados. A sua mensagem será exibida na janela de mensagens. New chat text edit box Campo de edição de texto da mensagem Type a message here Insira uma mensagem aqui &Edit E&ditar Cl&ear Chat History &Limpar Histórico &Close &Fechar Do you want to open the link '%1' in your browser? Deseja abrir o link '%1' em seu navegador? Do you want to open the link Quer abrir o link in an external browser? num navegador externo? CChatDlgBase Chat Mensagens &Send &Enviar Cl&ear &Limpar &Close &Fechar CClientDlg Input Level Meter Medidor do Nível de Entrada The input level indicators show the input level of the two stereo channels of the current selected audio input. Os indicadores do nível de entrada mostram o nível dos dois canais stereo da entrada de áudio selecionada. Make sure not to clip the input signal to avoid distortions of the audio signal. Certifique-se de não clipar o sinal de entrada para evitar distorções no sinal de áudio. If the Se o cliente software, you should not hear your singing/instrument in the loudspeaker or your headphone when the , não deve ouvir a sua voz/instrumento diretamente nas colunas ou nos headphones enquanto o cliente software is connected and you play your instrument/sing in the microphone, the LED level meter should flicker. If this is not the case, you have probably selected the wrong input channel (e.g. line in instead of the microphone input) or set the input gain too low in the (Windows) audio mixer. estiver ligado a um servidor e tocar o seu instrumento/cantar no microfone, os LEDs do medidor do nível de entrada devem piscar. Se tal não acontecer, provavelmente selecionou o canal de entrada errado (por exemplo, entrada de linha em vez da entrada do microfone) ou ajustou o ganho da entrada muito baixo no misturador de áudio (Windows) ou na placa de som. For a proper usage of the Para um uso adequado do cliente software is not connected. This can be achieved by muting your input audio channel in the Playback mixer (not the Recording mixer!). não estiver ligado a um servidor. Isso pode ser feito silenciando (mute) o canal da entrada de áudio no dispositivo de reprodução (não no dispositivo de captura!) Input level meter Medidor do nível de entrada Simulates an analog LED level meter. Simula um medidor de nível analógico LED. Connect/Disconnect Button Botão de Ligar/Desligar Push this button to connect to a server. A dialog where you can select a server will open. If you are connected, pressing this button will end the session. Pressione este botão para se ligar a um servidor. Uma janela será aberta onde pode selecionar um servidor. Se já estiver ligado a um servidor, pressionar este botão encerrará a sessão. Connect and disconnect toggle button Botão de alternação entre ligar e desligar Clicking on this button changes the caption of the button from Connect to Disconnect, i.e., it implements a toggle functionality for connecting and disconnecting the Clicar nesse botão altera a legenda do botão de Ligar para Desligar, ou seja, implementa uma funcionalidade de alternação para conectar e desconectar o cliente software. . Local Audio Input Fader Fader da Entrada Local de Áudio Local audio input fader (left/right) Fader de entrada local de áudio (esquerdo/direito) Reverberation effect level setting Ajuste do nível do efeito de reverberação Left channel selection for reverberation Seleção do canal esquerdo para reverberação Right channel selection for reverberation Seleção do canal direito para reverberação If this LED indicator turns red, you will not have much fun using the Se este indicador LED ficar vermelho, não se vai divertir muito ao usar o This shows the level of the two stereo channels for your audio input. Isto mostra o nível dos dois canais estéreo para a sua entrada de áudio. If the application is connected to a server and you play your instrument/sing into the microphone, the VU meter should flicker. If this is not the case, you have probably selected the wrong input channel (e.g. 'line in' instead of the microphone input) or set the input gain too low in the (Windows) audio mixer. Se a aplicação estiver ligada a um servidor e tocar o seu instrumento/cantar no microfone, os LEDs do medidor do nível de entrada devem piscar. Se tal não acontecer, provavelmente selecionou o canal de entrada errado (por exemplo, entrada de linha em vez da entrada do microfone) ou ajustou o ganho da entrada muito baixo no misturador de áudio (Windows) ou na placa de som. For proper usage of the application, you should not hear your singing/instrument through the loudspeaker or your headphone when the software is not connected. This can be achieved by muting your input audio channel in the Playback mixer (not the Recording mixer!). Para um uso adequado da aplicação, não deve ouvir a sua voz/instrumento diretamente nas colunas ou nos headphones enquanto a aplicação não estiver ligada a um servidor. Isso pode ser feito silenciando (mute) o canal da entrada de áudio no dispositivo de reprodução (não no dispositivo de captura!). Clicking on this button changes the caption of the button from Connect to Disconnect, i.e., it implements a toggle functionality for connecting and disconnecting the application. Clicar nesse botão altera a legenda do botão de Ligar para Desligar, ou seja, implementa uma funcionalidade de alternação para conectar e desconectar a aplicação. Controls the relative levels of the left and right local audio channels. For a mono signal it acts as a pan between the two channels. For example, if a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows Controla os níveis relativos dos canais esquerdo e direito. Para um sinal mono, actua como uma panorâmica entre os dois canais. Por exemplo, se um microfone estiver ligado no canal direito e um instrumento estiver ligado no canal esquerdo, mais alto que o microfone, mova o fader de áudio numa direção em que a etiqueta acima do fader mostre Reverb effect Efeito de Reverberação Reverb can be applied to one local mono audio channel or to both channels in stereo mode. The mono channel selection and the reverb level can be modified. For example, if a microphone signal is fed in to the right audio channel of the sound card and a reverb effect needs to be applied, set the channel selector to right and move the fader upwards until the desired reverb level is reached. O efeito de reverberação pode ser aplicado a um canal local de áudio mono ou a ambos os canais no modo estéreo. A seleção do canal mono e o nível de reverberação podem ser modificados. Por exemplo, se o sinal do microfone for alimentado no canal de áudio direito da placa de som, e for necessário aplicar um efeito de reverberação, ajuste o seletor de canal para a direita e mova o fader para cima até que o nível de reverberação desejado seja atingido. Reverb effect level setting Ajuste do nível do efeito de reverberação Reverb Channel Selection Seleção do Canal de Reverberação With these radio buttons the audio input channel on which the reverb effect is applied can be chosen. Either the left or right input channel can be selected. Com estes botões de seleção, pode ser escolhido o canal de entrada de áudio no qual o efeito de reverberação é aplicado. Pode ser selecionado o canal de entrada esquerdo ou direito. Left channel selection for reverb Seleção do canal esquerdo para reverberação Right channel selection for reverb Seleção do canal direito para reverberação Green Verde The delay is perfect for a jam session. A latência é perfeita para uma jam session. Yellow Amarelo Red Vermelho If this LED indicator turns red, you will not have much fun using %1. Se este indicador LED ficar vermelho, não se vai divertir muito ao usar o %1. Delay status LED indicator Indicador LED do estado de latência Opens a dialog where you can select a server to connect to. If you are connected, pressing this button will end the session. Abre uma caixa de diálogo onde pode seleccionar a que servidor se ligar. Se estiver ligado, pressionar este botão vai terminar a sessão. Shows the current audio delay status: Mostra o estado actual da latência de áudio: A session is still possible but it may be harder to play. Ainda é possível fazer uma sessão, mas poderá ser mais difícil tocar a tempo. The delay is too large for jamming. A latência é demasiada para tocar a tempo. If this LED indicator turns red, you will not have much fun using the application. Se este indicador LED ficar vermelho, não se vai divertir muito ao usar a aplicação. The buffers status LED shows the current audio/streaming status. If the light is red, the audio stream is interrupted. This is caused by one of the following problems: O indicador LED do estado dos buffers mostra o estado atual do áudio/transmissão. Se a luz estiver vermelha, o fluxo de áudio é interrompido. Isto é causado por um dos seguintes problemas: The sound card's buffer delay (buffer size) is too small (see Settings window). O buffer (tamanho do buffer) da placa de som é demasiado pequeno (verificar janela das Definições). The upload or download stream rate is too high for your internet bandwidth. A taxa de envio ou de transferência é muito alta para a sua largura de banda da Internet. Buffers status LED indicator Indicador LED do estado dos buffers C&onnect &Ligar software upgrade available actualização de software disponível &File &Ficheiro &View &Ver &Connection Setup... &Ligar a Servidor... My &Profile... Meu &Perfil... C&hat... &Mensagens... &Settings... &Definições... &Analyzer Console... Consola de &Análise... Use &Two Rows Mixer Panel &Usar Painel de Mistura de Duas Linhas Clear &All Stored Solo and Mute Settings Limpar &Todas as Configurações de Solo e Mudo %1 Directory Diretório %1 Ok Ok E&xit &Sair &Edit &Editar &Sort Users by Name Ordenar os Canais por &Nome... None Nenhum Center Centro R R L L With the audio fader, the relative levels of the left and right local audio channels can be changed. For a mono signal it acts like a panning between the two channels. If, e.g., a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows Com o fader de áudio, os níveis relativos dos canais locais esquerdo e direito podem ser alterados. Para um sinal mono, atua como uma panorâmica entre os dois canais. Se, por exemplo, um microfone estiver ligado no canal direito e um instrumento estiver ligado no canal esquerdo, mais alto que o microfone, mova o fader de áudio numa direção em que a etiqueta acima do fader mostre , where , onde is the current attenuation indicator. é o indicador de atenuação atual. Reverberation Level Nível de Reverberação A reverberation effect can be applied to one local mono audio channel or to both channels in stereo mode. The mono channel selection and the reverberation level can be modified. If, e.g., the microphone signal is fed into the right audio channel of the sound card and a reverberation effect shall be applied, set the channel selector to right and move the fader upwards until the desired reverberation level is reached. Um efeito de reverberação pode ser aplicado a um canal local de áudio mono ou a ambos os canais no modo estéreo. A seleção do canal mono e o nível de reverberação podem ser modificados. Se, por exemplo, o sinal do microfone for alimentado no canal de áudio direito da placa de som, e for aplicado um efeito de reverberação, ajuste o seletor de canal para a direita e mova o fader para cima até que o nível de reverberação desejado seja atingido. The reverberation effect requires significant CPU so it should only be used on fast PCs. If the reverberation level fader is set to minimum (which is the default setting), the reverberation effect is switched off and does not cause any additional CPU usage. O efeito de reverberação requer uma utilização do CPU significativa, de forma a que só deve ser usado em PCs rápidos. Se o atenuador do nível de reverberação estiver definido como mínimo (que é a configuração padrão), o efeito de reverberação será desativado e não causará nenhum uso adicional do CPU. Reverberation Channel Selection Seleção do Canal de Reverberação With these radio buttons the audio input channel on which the reverberation effect is applied can be chosen. Either the left or right input channel can be selected. Com estes botões de seleção, pode ser escolhido o canal de entrada de áudio no qual o efeito de reverberação é aplicado. Pode ser selecionado o canal de entrada esquerdo ou direito. Delay Status LED LED do Estado da Latência The delay status LED indicator shows the current audio delay status. If the light is green, the delay is perfect for a jam session. If the light is yellow, a session is still possible but it may be harder to play. If the light is red, the delay is too large for jamming. O indicador LED do estado da latência mostra o estado atual do atraso do áudio. Se a luz estiver verde, o atraso é perfeito para uma jam session. Se a luz estiver amarela, uma sessão ainda é possível, mas pode ser mais difícil tocar sincronizado. Se a luz estiver vermelha, o atraso é demasiado grande para uma sessão de jamming. Buffers Status LED LED do Estado dos Buffers The buffers status LED indicator shows the current audio/streaming status. If the light is green, there are no buffer overruns/underruns and the audio stream is not interrupted. If the light is red, the audio stream is interrupted caused by one of the following problems: O indicador LED do estado dos buffers mostra o estado atual do áudio/transmissão. Se a luz estiver verde, não haverá buffer em excesso/déficit e o fluxo de áudio não será interrompido. Se a luz estiver vermelha, o fluxo de áudio é interrompido devido a um dos seguintes problemas: The network jitter buffer is not large enough for the current network/audio interface jitter. O jitter buffer da rede não é grande o suficiente para o jitter atual da interface de rede/áudio. The sound card buffer delay (buffer size) is set to too small a value. O atraso do buffer da placa de som (buffer size) está definido para um valor demasiado baixo. The upload or download stream rate is too high for the current available internet bandwidth. A taxa de upload ou download é muito alta para a largura de banda disponível na ligação à Internet. The CPU of the client or server is at 100%. O CPU do cliente ou servidor está a 100%. Current Connection Status Parameter Parâmetros do Estado da Ligação The Ping Time is the time required for the audio stream to travel from the client to the server and back again. This delay is introduced by the network and should be about 20-30 ms. If this delay is higher than about 50 ms, your distance to the server is too large or your internet connection is not sufficient. A latência da ligação é o tempo necessário para o fluxo de áudio viajar do cliente para o servidor e vice-versa. Esta latência é introduzida pela rede e deve ser cerca de 20-30 ms. Se esta latência for maior que 50 ms, a distância até ao servidor é muito grande ou sua ligação à Internet não é suficiente. Overall Delay is calculated from the current Ping Time and the delay introduced by the current buffer settings. A latência geral é calculada a partir da latência da ligação atual e do atraso introduzido pelas configurações do buffer. If this LED indicator turns red, you will not have much fun using the %1 software. Se este indicador LED ficar vermelho, não se vai divertir muito ao usar o software %1. &Load Mixer Channels Setup... A&brir configuração da mistura... &Save Mixer Channels Setup... Salvar &configuração da mistura... O&wn Fader First P&róprio Fader Primeiro Sett&ings Def&inições Audio/Network &Settings... Definições de Audio/&Rede... A&dvanced Settings... &Definições Avançadas... N&o User Sorting Nã&o Ordenar Canais If this LED indicator turns red, the audio stream is interrupted. Se este indicador LED ficar vermelho, o fluxo de áudio é interrompido. Current Connection Status Estado da Ligação Sort Users by &Name Ordenar Canais por &Nome Sort Users by &Instrument Ordenar Canais por &Instrumento Sort Users by &Group Ordenar Canais por &Grupo Sort Users by &City Ordenar Canais por &Cidade Set All Faders to New Client &Level Definir Todos os Canais para Níve&l de Novo Cliente Local Jitter Buffer Status LED LED de estado do jitter buffer local The local jitter buffer status LED shows the current audio/streaming status. If the light is red, the audio stream is interrupted. This is caused by one of the following problems: O indicador LED do estado do buffer local mostra o estado atual do áudio/transmissão. Se a luz estiver vermelha, o fluxo de áudio é interrompido. Isto é causado por um dos seguintes problemas: Local Jitter Buffer status LED indicator Indicador LED de estado do jitter buffer local Auto-Adjust all &Faders Ajustar Auto. todos os &Faders &Settings Definiçõe&s Directory Server Servidor de Diretório Select Channel Setup File Selecione o ficheiro de configuração da mistura user utilizador users utilizadores Connect Ligar Settings Definições Chat Mensagens Enable feedback detection Activar detecção de feedback Audio feedback or loud signal detected. We muted your channel and activated 'Mute Myself'. Please solve the feedback issue first and unmute yourself afterwards. Foi detectado feedback de audio ou sinal alto. O seu canal foi silenciado e foi activada a função 'Silenciar-me'. Por favor resolva o problema de feedback antes de continuar. Your sound card is not working correctly. Please open the settings dialog and check the device selection and the driver settings. A sua placa de som não está a funcionar correctamente. Abra a janela das definições e verifique a selecção do dispositivo e as configurações do driver. &Disconnect &Desligar CClientDlgBase Delay Latência Buffers Buffers Input Entrada L L R R Jitter Jitter Ping Ping ms ms &Mute Myself Silenciar-&me &Settings Definiçõe&s &Chat Me&nsagens C&onnect &Ligar Pan Pan Center Centro Reverb Reverb Left Esquerdo Right Direito MUTED (Other people won't hear you) MUDO (Outras pessoas não o vão ouvir) Set up your audio, connect to a server and start jamming! Configure o seu áudio, ligue-se a um servidor e comece a tocar! Update check Verificação de actualização CClientSettingsDlg Jitter Buffer Size Tamanho do Jitter Buffer The jitter buffer compensates for network and sound card timing jitters. The size of this jitter buffer has therefore influence on the quality of the audio stream (how many dropouts occur) and the overall delay (the longer the buffer, the higher the delay). O jitter buffer (ou buffer de instabilidade) compensa os desvios de temporização da rede e da placa de som. O tamanho desse jitter buffer influencia, portanto, a qualidade do fluxo de áudio (quantas interrupções ocorrem) e a latência geral (quanto maior o buffer, maior a latência). The jitter buffer size can be manually chosen for the local client and the remote server. For the local jitter buffer, dropouts in the audio stream are indicated by the light below the jitter buffer size faders. If the light turns to red, a buffer overrun/underrun took place and the audio stream is interrupted. O tamanho do jitter buffer pode ser escolhido manualmente para o cliente local e o servidor remoto. Para o jitter buffer local, as interrupções no fluxo de áudio são indicadas pela luz na parte inferior dos faders do jitter buffer. Se a luz ficar vermelha, ocorreu um excesso/déficit do buffer e o fluxo de áudio é interrompido. The jitter buffer setting is therefore a trade-off between audio quality and overall delay. A configuração do jitter buffer é, portanto, uma troca entre a qualidade do áudio e o atraso geral. An auto setting of the jitter buffer size setting is available. If the check Auto is enabled, the jitter buffers of the local client and the remote server are set automatically based on measurements of the network and sound card timing jitter. If the Auto check is enabled, the jitter buffer size faders are disabled (they cannot be moved with the mouse). Está disponível uma configuração automática do tamanho do jitter buffer. Se a opção Auto estiver ativada, os jitter buffers do cliente local e do servidor remoto serão configurados automaticamente com base nas medições da instabilidade de sincronização da rede e da placa de som. Se a opção Auto estiver ativada, os faders do jitter buffer serão desativados (não poderão ser movidos manualmente). If the auto setting of the jitter buffer is enabled, the network buffers of the local client and the remote server are set to a conservative value to minimize the audio dropout probability. To tweak the audio delay/latency it is recommended to disable the auto setting functionality and to lower the jitter buffer size manually by using the sliders until your personal acceptable limit of the amount of dropouts is reached. The LED indicator will visualize the audio dropouts of the local jitter buffer with a red light. Caso a configuração automática do jitter buffer estiver ativada, os buffers de rede do cliente local e do servidor remoto são configurados com um valor conservador para minimizar a probabilidade de perda de áudio. Para ajustar o atraso/latência do áudio, é recomendável desativar a funcionalidade de configuração automática e diminuir o tamanho do jitter buffer manualmente usando os controles deslizantes até que a quantidade de perdas de áudio lhe sejam pessoalmente aceitáveis. O indicador LED representará as interrupções de áudio do jitter buffer local através de uma luz vermelha. Local jitter buffer slider control Controle deslizante do jitter buffer local Server jitter buffer slider control Controle deslizante do jitter buffer do servidor Auto jitter buffer switch Interruptor do jitter buffer automático Jitter buffer status LED indicator Indicador LED de estado do jitter buffer Sound Card Device Dispositivo da Placa de Som The ASIO driver (sound card) can be selected using O driver ASIO (placa de som) pode ser selecionado usando o under the Windows operating system. Under MacOS/Linux, no sound card selection is possible. If the selected ASIO driver is not valid an error message is shown and the previous valid driver is selected. no Windows. No MacOS/Linux, não é possível seleccionar a placa de som. Se o driver ASIO selecionado não for válido, uma mensagem de erro será exibida e o driver válido anterior será selecionado. If the driver is selected during an active connection, the connection is stopped, the driver is changed and the connection is started again automatically. Se o driver for selecionado durante uma ligação ativa, a ligação será interrompida, o driver será alterado e a ligação reiniciada automaticamente. Sound card device selector combo box Seletor de dispositivo da placa de som If the ASIO4ALL driver is used, please note that this driver usually introduces approx. 10-30 ms of additional audio delay. Using a sound card with a native ASIO driver is therefore recommended. Caso o driver ASIO4ALL seja usado, note que esse driver geralmente introduz aprox. 10-30 ms de atraso de áudio adicional. Dado isto, é recomendável usar uma placa de som com um driver ASIO nativo. If you are using the kX ASIO driver, make sure to connect the ASIO inputs in the kX DSP settings panel. Se estiver a usar o driver kX ASIO, certifique-se de ligar as entradas ASIO no painel de configurações do kX DSP. Sound Card Channel Mapping Mapeamento de Canais da Placa de Som If the selected sound card device offers more than one input or output channel, the Input Channel Mapping and Output Channel Mapping settings are visible. Caso o dispositivo selecionado da placa de som ofereça mais que um canal de entrada ou saída, as configurações de Mapeamento de canais de entrada e de saída estarão visíveis. For each Para cada canal de entrada/saída do input/output channel (Left and Right channel) a different actual sound card channel can be selected. (canal esquerdo e direito), um canal real da placa de som pode ser selecionado. Left input channel selection combo box Seletor de canal de entrada esquerdo Right input channel selection combo box Seletor de canal de entrada direito Left output channel selection combo box Seletor de canal de saída esquerdo Right output channel selection combo box Seletor de canal de saída direito Enable Small Network Buffers Activar Buffers de Rede Pequenos If enabled, the support for very small network audio packets is activated. Very small network packets are only actually used if the sound card buffer delay is smaller than Se ativado, o suporte para pacotes de áudio de rede muito pequenos é ativado. Pacotes de rede muito pequenos serão apenas realmente usados se o atraso do buffer da placa de som for menor que samples. The smaller the network buffers, the lower the audio latency. But at the same time the network load increases and the probability of audio dropouts also increases. amostras. Quanto menor o buffer da rede, menor a latência do áudio. Mas, ao mesmo tempo, a carga da rede e a probabilidade de interrupção do áudio também aumentam. Enable small network buffers check box Caixa de activação de buffers de rede pequenos Sound Card Buffer Delay Atraso do Buffer da Placa de Som Some sound card drivers do not allow the buffer delay to be changed from within the application. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. On Windows, press the ASIO Device Settings button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Alguns drivers da placa de som não permitem que o atraso do buffer seja definido a partir da aplicação. Nesse case, a configuração de atraso do buffer é desabilitada e terá que ser alterada usando o driver da placa de som. No Windows, pressione o botão Definições do Dispositivo ASIO para abrir o painel de configurações do driver. No Linux, use a ferramenta de configuração Jack para alterar o tamanho do buffer. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within the software. On Windows, press the ASIO Device Settings button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Se as configurações de atraso do buffer estiverem desactivadas, o driver de áudio não permite essa configuração através da aplicação. No Windows, pressione o botão Definições do Dispositivo ASIO para abrir o painel de configurações do driver. No Linux, use a ferramenta de configuração Jack para alterar o tamanho do buffer. Sound card driver settings Definições do driver da placa de som This opens the driver settings of your sound card. Some drivers allow you to change buffer settings, others like ASIO4ALL let you choose input or outputs of your device(s). More information can be found on jamulus.io. Isto abre as configurações do driver da sua placa de som. Alguns drivers permitem que altere as configurações do buffer, outros como o ASIO4ALL permitem que escolha a entrada ou saída do(s) seu(s) dispositivo(s). Mais informações podem ser encontradas em jamulus.io. Opens the driver settings. Note: Abre as configurações do driver. Nota: currently only supports devices supporting a sample rate of de momento apenas suporta dispositivos que suportem uma taxa de amostragem de Hz. You will not be able to select a driver/device which doesn't. For more help see jamulus.io. Hz. Não poderá seleccionar um driver/dispositivo que não suporte. Para obter ajuda, visite jamulus.io. ASIO Device Settings push button Botão das Definições do Dispositivo ASIO Select the meter style to be used for the level meters. The Bar (narrow) and LEDs (round, small) options only apply to the mixerboard. When Bar (narrow) is selected, the input meters are set to Bar (wide). When LEDs (round, small) is selected, the input meters are set to LEDs (round, big). The remaining options apply to the mixerboard and input meters. Selecione o estilo a ser usado para os medidores de nível. As opções Barra (estreita) e LEDs (redondo, pequeno) aplicam-se apenas à mesa do mixer. Quando a Barra (estreita) é selecionada, os medidores de entrada são definidos como Barra (larga). Quando LEDs (redondo, pequeno) é selecionado, os medidores de entrada são definidos como LEDs (redondo, grande). As opções restantes aplicam-se à secção da mistura e aos medidores de entrada. Language Idioma Select the language to be used for the user interface. Selecione o idioma para ser utilizado na interface do usuário. Language combo box Seletor de idioma and e Audio Upstream Rate Taxa de Transmissão de Áudio Depends on the current audio packet size and compression setting. Make sure that the upstream rate is not higher than your available internet upload speed (check this with a service such as speedtest.net). Depende do tamanho do pacote de áudio e da configuração da compactação de áudio. Verifique se a taxa de transmissão não é maior que a sua taxa de upload disponível (verifique isto com um serviço como o speedtest.net). None Nenhum Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country or region you are located in. Your city and skill level playing your instrument may also be added. Escreva o seu nome ou um pseudónimo aqui para que os outros músicos com quem quer tocar saibam quem você é. Além disso, pode também definir uma imagem do instrumento que toca e uma bandeira do país ou região onde vive. A cidade onde vive e o nível de habilidade com o seu instrumento também podem ser adicionados. What you set here will appear at your fader on the mixer board when you are connected to a %1 server. This tag will also be shown at each client which is connected to the same server as you. O que definir aqui aparecerá por baixo do seu fader na secção de mistura quando estiver ligado a um servidor %1. Esta etiqueta também será exibida em cada cliente que estiver ligado ao mesmo servidor. Country/region flag button Botão da bandeira do país/região Center Centro R R The buffer delay setting is a fundamental setting of the A configuração do atraso do buffer (buffer delay) é uma configuração fundamental do cliente software. This setting has influence on many connection properties. . Esta configuração tem influência em muitas propriedades da ligação. Three buffer sizes are supported Três tamanhos de buffer são suportados 64 samples: This is the preferred setting since it provides the lowest latency but does not work with all sound cards. 64 amostras: esta é a configuração preferida, pois oferece menor latência, mas não funciona com todas as placas de som. 128 samples: This setting should work for most available sound cards. 128 amostras: esta configuração deve funcionar na maioria das placas de som disponíveis. 256 samples: This setting should only be used if only a very slow computer or a slow internet connection is available. 256 amostras: esta configuração deve ser usada se apenas estiver disponível um computador muito lento ou uma ligação lenta à Internet. Some sound card drivers do not allow the buffer delay to be changed from within the Alguns drivers da placa de som não permitem que o atraso do buffer seja alterado pelo cliente software. In this case the buffer delay setting is disabled. To change the actual buffer delay, this setting has to be changed in the sound card driver. On Windows, press the ASIO Setup button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. . Nesse caso, a configuração de atraso do buffer estará desativada. Para alterar o atraso do buffer, essa configuração deve ser alterada no driver da placa de som. No Windows, pressione o botão Configuração do Driver para abrir o painel de configurações do driver. No Linux, use a ferramenta de configuração Jack para alterar o atraso do buffer. If no buffer size is selected and all settings are disabled, an unsupported buffer size is used by the driver. The Se nenhum atraso do buffer estiver selecionado e todas as configurações estiverem desativadas, um atraso do buffer não suportado será usado pelo driver. O cliente software will still work with this setting but with restricted performance. ainda funcionará com essa configuração, mas com desempenho restrito. The actual buffer delay has influence on the connection status, the current upload rate and the overall delay. The lower the buffer size, the higher the probability of a red light in the status indicator (drop outs) and the higher the upload rate and the lower the overall delay. O atraso do buffer influencia o estado da ligação, a taxa de upload atual e a latência geral. Quanto menor o atraso do buffer, maior a probabilidade de a luz vermelha no indicador de estado (interrupções), maior a taxa de upload e menor a latência geral. The buffer setting is therefore a trade-off between audio quality and overall delay. A configuração do buffer é, portanto, uma troca entre qualidade de áudio e latência geral. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within the Se as configurações de atraso do buffer estiverem desativadas, é porque o driver de áudio proibe modificar essa configuração a partir do cliente software. On Windows, press the ASIO Setup button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. . No Windows, pressione o botão <i>Configuração do Driver</i> para abrir o painel de configurações do driver. No Linux, use a ferramenta de configuração <i>Jack</i> para alterar o atraso do buffer. 64 samples setting radio button Botão de configuração de 64 amostras 128 samples setting radio button Botão de configuração de 128 amostras 256 samples setting radio button Botão de configuração de 256 amostras ASIO setup push button Botão de configuração do ASIO Fancy Skin Skin Sofisticada If enabled, a fancy skin will be applied to the main window. Se ativada, uma skin sofisticada será aplicada à janela principal. Fancy skin check box Caixa de ativação da skin sofisticada Display Channel Levels Mostrar Níveis de Canais If enabled, each client channel will display a pre-fader level bar. Se ativado, cada canal de cliente exibirá uma barra de nível pré-fader. Display channel levels check box Caixa de activação para exibir níveis de canais Audio Channels Canais de Áudio Select the number of audio channels to be used. There are three modes available. The mono and stereo modes use one and two audio channels respectively. In mono-in/stereo-out mode the audio signal which is sent to the server is mono but the return signal is stereo. This is useful if the sound card has the instrument on one input channel and the microphone on the other channel. In that case the two input signals can be mixed to one mono channel but the server mix can be heard in stereo. Selecione o número de canais de áudio a serem usados. Existem três modos disponíveis. Os modos mono e estéreo usam um e dois canais de áudio, respectivamente. No modo Entrada Mono/Saída Estéreo, o sinal de áudio enviado ao servidor é mono, mas o sinal de retorno é estéreo. Isso é útil quando a placa de som coloca o instrumento e o microfone em canais diferentes. Nesse caso, os dois sinais de entrada podem ser misturados num canal mono, mas a mistura do servidor pode ser ouvida em estéreo. Enabling the stereo streaming mode will increase the stream data rate. Make sure that the current upload rate does not exceed the available bandwidth of your internet connection. Ativar o modo de transmissão estéreo aumenta a taxa do fluxo de dados. Verifique que a taxa de transmissão não excede a largura de banda disponível da sua ligação à Internet. In stereo streaming mode, no audio channel selection for the reverberation effect will be available on the main window since the effect is applied on both channels in this case. No modo de transmissão estéreo, nenhuma seleção de canal de áudio para o efeito de reverberação estará disponível na janela principal, pois o efeito é aplicado em ambos os canais. Audio channels combo box Seletor de canais áudio Audio Quality Qualidade de Áudio Select the desired audio quality. A low, normal or high audio quality can be selected. The higher the audio quality, the higher the audio stream data rate. Make sure that the current upload rate does not exceed the available bandwidth of your internet connection. Selecione a qualidade de áudio desejada. Pode ser selecionada uma qualidade de áudio baixa, normal ou alta. Quanto maior a qualidade do áudio, maior a taxa de dados do fluxo de áudio. Verifique que a taxa de transmissão não excede a largura de banda disponível da sua ligação à Internet. Audio quality combo box Seletor de qualidade áudio New Client Level Nível de Novo Cliente The new client level setting defines the fader level of a new connected client in percent. I.e. if a new client connects to the current server, it will get the specified initial fader level if no other fader level of a previous connection of that client was already stored. A configuração de nível de novo cliente define, em percentagem, o nível do fader de um novo cliente ligado. Por exemplo, se um cliente novo se ligar ao servidor atual, o seu canal terá o nível inicial do fader especificado, excepto quando um diferente nível do fader de uma ligação anterior desse mesmo cliente já tenha sido definido. New client level edit box Caixa de edição no nível de novo cliente Custom Directory Server Address Endereço do Servidor de Diretório Personalizado The custom directory server address is the IP address or URL of the directory server at which the server list of the connection dialog is managed. This address is only used if the custom server list is selected in the connection dialog. O endereço personalizado do servidor central é o endereço IP ou URL do servidor central no qual a lista de servidores da Configuração de Ligação é gerida. Este endereço é usado apenas se a lista de servidores personalizados estiver selecionada na Configuração de Ligação. Directory Server Address Endereço do servidor central The directory server address is the IP address or URL of the directory server at which the server list of the connection dialog is managed. With the directory server address type either the local region can be selected of the default directory servers or a manual address can be specified. O endereço do servidor central é o endereço IP ou URL do servidor central a partir do qual é gerida a lista de servidores do diálogo de ligação. Com a configuração do endereço do servidor central, é possível selecionar um dos servidores centrais padrão ou especificar um endereço manual. Default directory server type combo box Seletor de servidor central padrão Directory server address line edit Caixa de edição do endereço do servidor central Current Connection Status Parameter Parâmetros do Estado da Ligação The ping time is the time required for the audio stream to travel from the client to the server and back again. This delay is introduced by the network. This delay should be as low as 20-30 ms. If this delay is higher (e.g., 50-60 ms), your distance to the server is too large or your internet connection is not sufficient. A latência da ligação é o tempo necessário para o fluxo de áudio viajar do cliente para o servidor e vice-versa. Esta latência é introduzida pela rede. Esta latência deve ser tão baixa quanto 20-30 ms. Se esta latência for maior (por exemplo, 50-60 ms), a distância até ao servidor é muito grande ou sua ligação à Internet não é suficiente. The overall delay is calculated from the current ping time and the delay which is introduced by the current buffer settings. A latência geral é calculada a partir da latência da ligação atual e do atraso introduzido pelas configurações do buffer. The upstream rate depends on the current audio packet size and the audio compression setting. Make sure that the upstream rate is not higher than the available rate (check the upstream capabilities of your internet connection by, e.g., using speedtest.net). A taxa de transmissão depende do tamanho do pacote de áudio e da configuração de compactação de áudio. Verifique se a taxa de transmissão não é maior que a taxa disponível (verifique a taxa de upload da sua ligação à Internet usando, por exemplo, o speedtest.net). If this LED indicator turns red, you will not have much fun using the Se este indicador LED ficar vermelho, não se irá divertir muito ao usar o software. . ASIO Setup Configuração ASIO Mono Mono mode will increase your stream's data rate. Make sure your upload rate does not exceed the available upload speed of your internet connection. vai aumentar a quantidade de dados da transmissão. Verifique se a taxa de upload não ultrapassa a velocidade de upload disponível da sua ligação à Internet. Audio Upstream Rate depends on the current audio packet size and compression setting. Make sure that the upstream rate is not higher than your available internet upload speed (check this with a service such as speedtest.net). A taxa de transmissão do áudio depende do tamanho do pacote de áudio e da configuração da compactação de áudio. Verifique se a taxa de transmissão não é maior que a sua taxa de upload disponível (verifique isto com um serviço como o speedtest.net). Mono-in/Stereo-out Entrada Mono/Saída Estéreo Stereo Estéreo &Close &Fechar Local Audio Input Fader Fader da Entrada Local de Áudio Controls the relative levels of the left and right local audio channels. For a mono signal it acts as a pan between the two channels. For example, if a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows Controla os níveis relativos dos canais esquerdo e direito. Para um sinal mono, actua como uma panorâmica entre os dois canais. Por exemplo, se um microfone estiver ligado no canal direito e um instrumento estiver ligado no canal esquerdo, mais alto que o microfone, mova o fader de áudio numa direção em que a etiqueta acima do fader mostre L L , where , onde is the current attenuation indicator. é o indicador de atenuação atual. Local audio input fader (left/right) Fader de entrada local de áudio (esquerdo/direito) The jitter buffer compensates for network and sound card timing jitters. The size of the buffer therefore influences the quality of the audio stream (how many dropouts occur) and the overall delay (the longer the buffer, the higher the delay). O jitter buffer (ou buffer de instabilidade) compensa os desvios de temporização da rede e da placa de som. O tamanho do buffer influencia, portanto, a qualidade do fluxo de áudio (quantas interrupções ocorrem) e a latência geral (quanto maior o buffer, maior a latência). You can set the jitter buffer size manually for the local client and the remote server. For the local jitter buffer, dropouts in the audio stream are indicated by the light below the jitter buffer size faders. If the light turns to red, a buffer overrun/underrun has taken place and the audio stream is interrupted. Pode escolher o tamanho do jitter buffer manualmente para o cliente local e o servidor remoto. Para o jitter buffer local, as interrupções no fluxo de áudio são indicadas pela luz na parte inferior dos faders do jitter buffer. Se a luz ficar vermelha, ocorreu um excesso/déficit do buffer e o fluxo de áudio é interrompido. If the Auto setting is enabled, the jitter buffers of the local client and the remote server are set automatically based on measurements of the network and sound card timing jitter. If Auto is enabled, the jitter buffer size faders are disabled (they cannot be moved with the mouse). Caso a configuração automática estiver activada, os buffers de rede do cliente local e do servidor remoto são configurados automaticamente com um valor conservador para minimizar a probabilidade de perda de áudio. Se o modo automático estiver ligado, os controlos estarão desactivados (não podem ser alterados pelo utilizador). If the Auto setting is enabled, the network buffers of the local client and the remote server are set to a conservative value to minimize the audio dropout probability. To tweak the audio delay/latency it is recommended to disable the Auto setting and to lower the jitter buffer size manually by using the sliders until your personal acceptable amount of dropouts is reached. The LED indicator will display the audio dropouts of the local jitter buffer with a red light. Caso a configuração automática do jitter buffer estiver ativada, os buffers de rede do cliente local e do servidor remoto são configurados com um valor conservador para minimizar a probabilidade de perda de áudio. Para ajustar o atraso/latência do áudio, é recomendável desativar a funcionalidade de configuração automática e diminuir o tamanho do jitter buffer manualmente usando os controles deslizantes até que a quantidade de perdas de áudio lhe sejam pessoalmente aceitáveis. O indicador LED representará as interrupções de áudio do jitter buffer local através de uma luz vermelha. For each %1 input/output channel (left and right channel) a different actual sound card channel can be selected. Para cada canal de entrada/saída do %1 (canal esquerdo e direito), um canal real da placa de som pode ser selecionado. Enables support for very small network audio packets. These network packets are only actually used if the sound card buffer delay is smaller than %1 samples. The smaller the network buffers, the lower the audio latency. But at the same time the network load and the probability of audio dropouts or sound artifacts increases. Habilita suporte para pacotes de áudio de rede muito pequenos. Esses pacotes de rede só são realmente usados se o buffer de atraso da placa de som for menor que %1 amostras. Quanto menores os buffers de rede, menor a latência do áudio. Mas, ao mesmo tempo, a carga da rede e a probabilidade de falhas de áudio ou artefatos de som aumentam. The buffer delay setting is a fundamental setting of %1. This setting has an influence on many connection properties. A definição do atraso do 'buffer'' é uma definição fundamental do %1. Esta definição tem influência em muitas propriedades da ligação. Some sound card drivers do not allow the buffer delay to be changed from within %1. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. On Windows, use the ASIO Device Settings button to open the driver settings panel. On Linux, use the JACK configuration tool to change the buffer size. Alguns drivers da placa de som não permitem que o atraso do buffer seja alterado a partir do %1. Nesse caso, a configuração de atraso do buffer estará desativada e deve ser alterada no driver da placa de som. No Windows, pressione o botão Configuração do Dispositivo ASIOr para abrir o painel de configurações do driver. No Linux, use a ferramenta de configuração JACK para alterar o tamanho do buffer. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within %1. On Windows, press the ASIO Device Settings button to open the driver settings panel. On Linux, use the JACK configuration tool to change the buffer size. Se as configurações de atraso do buffer estiverem desativadas, é porque o driver de áudio proibe modificar essa configuração a partir do %1. No Windows, pressione o botão Configuração do Driver para abrir o painel de configurações do driver. No Linux, use a ferramenta de configuração JACK para alterar o tamanho do buffer. This opens the driver settings of your sound card. Some drivers allow you to change buffer settings, others like ASIO4ALL lets you choose input or outputs of your device(s). More information can be found on jamulus.io. Isto abre as configurações do driver da sua placa de som. Alguns drivers permitem que altere as configurações do buffer, outros como o ASIO4ALL permitem que escolha a entrada ou saída do(s) seu(s) dispositivo(s). Mais informações podem ser encontradas em jamulus.io. Opens the driver settings. Note: %1 currently only supports devices with a sample rate of %2 Hz. You will not be able to select a driver/device which doesn't. For more help see jamulus.io. Abre as configurações do drive. Nota: %1 somente suporta dispositivos com uma taxa de amostragem de %2 Hz. Você não poderá selecionar um driver/dispositivo que não suporte. Para obter mais ajuda, consulte jamulus.io. The buffer delay setting is a fundamental setting of this software. This setting has an influence on many connection properties. A configuração do atraso do buffer (buffer delay) é uma configuração fundamental da aplicação. Esta configuração tem influência em muitas propriedades da ligação. 64 samples: The preferred setting. Provides the lowest latency but does not work with all sound cards. 64 amostras: Cnfiguração preferida. Fornece menor latência, mas não funciona com todas as placas de som. 128 samples: Should work for most available sound cards. 128 amostras: Deve funcionar na maioria das placas de som disponíveis. 256 samples: Should only be used on very slow computers or with a slow internet connection. 256 amostras: Deve apenas ser usada se tiver um computador muito lento ou uma ligação lenta à Internet. Some sound card drivers do not allow the buffer delay to be changed from within the application. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. On Windows, press the ASIO Setup button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Alguns drivers da placa de som não permitem que o atraso do buffer seja alterado pela aplicação. Nesse caso, a configuração de atraso do buffer estará desativada e deve ser alterada no driver da placa de som. No Windows, pressione o botão Configuração do Driver para abrir o painel de configurações do driver. No Linux, use a ferramenta de configuração Jack para alterar o atraso do buffer. If no buffer size is selected and all settings are disabled, an unsupported buffer size is used by the driver. The application will still work with this setting but with restricted performance. Se nenhum atraso do buffer estiver selecionado e todas as configurações estiverem desativadas, um atraso do buffer não suportado será usado pelo driver. A aplicação ainda funcionará com essa configuração, mas com desempenho restrito. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within the software. On Windows, press the ASIO Setup button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Se as configurações de atraso do buffer estiverem desativadas, é porque o driver de áudio proibe modificar essa configuração a partir da aplicação. No Windows, pressione o botão Configuração do Driver para abrir o painel de configurações do driver. No Linux, use a ferramenta de configuração Jack para alterar o atraso do buffer. Skin Tema Select the skin to be used for the main window. Selecione o tema a ser usado na janela principal. Skin combo box Caixa de selecção do tema Selects the number of audio channels to be used for communication between client and server. There are three modes available: Selecione o número de canais de áudio a serem usados para a comunicação entre cliente e servidor. Existem três modos disponíveis: and e These modes use one and two audio channels respectively. Estes modos usam um e dois canais de áudio, respectivamente. Mono in/Stereo-out Entrada Mono/Saída Estéreo The audio signal sent to the server is mono but the return signal is stereo. This is useful if the sound card has the instrument on one input channel and the microphone on the other. In that case the two input signals can be mixed to one mono channel but the server mix is heard in stereo. O sinal de áudio enviado ao servidor é mono, mas o sinal de retorno é estéreo. Isso é útil quando a placa de som coloca o instrumento e o microfone em canais diferentes. Nesse caso, os dois sinais de entrada podem ser misturados num canal mono, mas a mistura do servidor pode ser ouvida em estéreo. Enabling Activar o modo In stereo streaming mode, no audio channel selection for the reverb effect will be available on the main window since the effect is applied to both channels in this case. No modo de transmissão estéreo, nenhuma seleção de canal de áudio para o efeito de reverberação estará disponível na janela principal, pois o efeito é aplicado em ambos os canais. The higher the audio quality, the higher your audio stream's data rate. Make sure your upload rate does not exceed the available bandwidth of your internet connection. Quanto maior a qualidade de áudio, maior a quantidade de dados da transmissão. Verifique se a taxa de upload não ultrapassa a velocidade de upload disponível da sua ligação à Internet. This setting defines the fader level of a newly connected client in percent. If a new client connects to the current server, they will get the specified initial fader level if no other fader level from a previous connection of that client was already stored. Esta opção define o nível do fader de um cliente novo, em percentagem. Se um cliente novo se liga ao mesmo servidor, este irá ter o nível do fader específicado, excepto se já definiu o nível do fader desse cliente previamente. Input Boost Ampliação de Sinal de Entrada This setting allows you to increase your input signal level by factors up to 10 (+20dB). If your sound is too quiet, first try to increase the level by getting closer to the microphone, adjusting your sound equipment or increasing levels in your operating system's input settings. Only if this fails, set a factor here. If your sound is too loud, sounds distorted and is clipping, this option will not help. Do not use it. The distortion will still be there. Instead, decrease your input level by getting farther away from your microphone, adjusting your sound equipment or by decreasing your operating system's input settings. Esta definição permite aumentar o nível de sinal de entrada até um factor de 10 (+20dB). Se o seu som está muito baixo, tente primeiro aumentar o nível posicionando-se mais perto do microfone, ajustando o seu equipamento de áudio ou aumentando o volume nas definições do seu sistema operativo. Apenas se tudo isto falhar deverá tentar esta opção. Se o seu som estiver demasiado alto, distorcido ou a clipar, esta opção não irá ajudar. A distorção irá permanecer. Em vez disso, diminua o volume do sinal de entrada afastando-se do microfone, ajustando o seu equipamento de som ou baixando o volume nas definições do seu sistema operativo. Input Boost combo box Caixa de selecção da Ampliação de Sinal de Entrada Leave this blank unless you need to enter the address of a directory server other than the default. Deixe este campo em branco excepto se necessitar de introduzir um endereço alternativo de um servidor de diretório. Directory server address combo box Caixa de Selecção do Servidor de Diretório The Ping Time is the time required for the audio stream to travel from the client to the server and back again. This delay is introduced by the network and should be about 20-30 ms. If this delay is higher than about 50 ms, your distance to the server is too large or your internet connection is not sufficient. A latência da ligação é o tempo necessário para o fluxo de áudio viajar do cliente para o servidor e vice-versa. Esta latência é introduzida pela rede e deve ser cerca de 20-30 ms. Se esta latência for maior que 50 ms, a distância até ao servidor é muito grande ou sua ligação à Internet não é suficiente. Overall Delay is calculated from the current Ping Time and the delay introduced by the current buffer settings. A latência geral é calculada a partir da latência da ligação atual e do atraso introduzido pelas configurações do buffer. Controls the relative levels of the left and right local audio channels. For a mono signal it acts as a pan between the two channels. For example, if a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows %1, where %2 is the current attenuation indicator. Controla os níveis relativos dos canais esquerdo e direito. Para um sinal mono, actua como uma panorâmica entre os dois canais. Por exemplo, se um microfone estiver ligado no canal direito e um instrumento estiver ligado no canal esquerdo, mais alto que o microfone, mova o fader de áudio numa direção em que a etiqueta acima do fader mostre %1, onde %2 é o indicador de atenuação. Audio Device Dispositivo de Áudio Under the Windows operating system the ASIO driver (sound card) can be selected using %1. If the selected ASIO driver is not valid an error message is shown and the previous valid driver is selected. Under macOS the input and output hardware can be selected. No sistema operacional Windows o driver ASIO (placa de som) pode ser selecionado usando %1. Se o driver ASIO selecionado não for válido, uma mensagem de erro será exibida e o driver válido anterior será selecionado. No macOS o hardware de entrada e saída pode ser selecionado. Three buffer sizes can be selected Três tamanhos de buffer podem ser selecionados 64 samples: Provides the lowest latency but does not work with all sound cards. 64 amostras: Fornece menor latência, mas não funciona com todas as placas de som. 256 samples: Should only be used when 64 or 128 samples is causing issues. 256 amostras: Deve apenas ser usada quando 64 ou 128 amostras estiver causando problemas. Some sound card drivers do not allow the buffer delay to be changed from within %1. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. Use the appropriate tool for the interface in use to adjust this buffer size. For example, if using ASIO, use the "ASIO Device Settings" button to open the driver settings panel or if using JACK, use a tool such as QjackCtl to adjust the buffer size. Other interfaces, such as Pipewire, would require their appropriate tool being used. Please refer to the interface manual. Alguns drivers de placa de som não permitem que o atraso do buffer seja alterado de dentro do %1. Nesse caso, a configuração de atraso do buffer está desabilitada e deve ser alterada usando o driver da placa de som. Use a ferramenta apropriada para a interface em uso para ajustar o tamanho do buffer. Por exemplo, se estiver usando ASIO, use o botão "Definições de Dispositivo ASIO" para abrir o painel de configurações do driver ou se estiver usando JACK, use uma ferramenta como QjackCtl para ajustar o tamanho do buffer. Outras interfaces, como o Pipewire, exigem o uso de sua ferramenta apropriada. Consulte o manual da interface. If no buffer size is selected and all settings are disabled, this means a buffer size in use by the driver which does not match the values. %1 will still work with this setting but may have restricted performance. Se nenhum tamanho do buffer estiver selecionado e todas as configurações estiverem desativadas, significa que um tamanho do buffer em uso pelo driver não combina os valores. %1 ainda funcionará com essa configuração, mas com desempenho restrito. The actual buffer delay has influence on the connection, the current upload rate and the overall delay. The lower the buffer size, the higher the probability of a red light in the status indicator (drop outs) and the higher the upload rate and the lower the overall delay. O atraso do buffer influencia a ligação, a taxa de upload atual e a latência geral. Quanto menor o tamanho do buffer, maior a probabilidade de a luz vermelha no indicador de estado (interrupções), maior a taxa de upload e menor a latência geral. Meter Style Estilo do Medidor Meter Style combo box Seletor do Estilo do Medidor Custom Directories Diretórios Personalizados If you need to add additional directories to the Connect dialog Directory drop down, you can enter the addresses here.<br>To remove a value, select it, delete the text in the input box, then move focus out of the control. Se você precisa acrescentar diretórios adicionais no menu lista Diretório do diálogo de Ligação, insira os endereços aqui.<br>Para remover um valor, selecione-o, exclua o texto na caixa de entrada e mova o foco para fora do controle. Custom Directories combo box Caixa de seleção do Diretório Personalizado Number of Mixer Panel Rows Número de Linhas do Painel de Mistura Adjust the number of rows used to arrange the mixer panel. Ajusta o número de linhas utilizadas para organizar o painel de mistura. Number of Mixer Panel Rows spin box Caixa de Selecção do Número de Linhas do Painel de Mistura Feedback Protection Protecção Contra Feedback Enable feedback protection to detect acoustic feedback between microphone and speakers. Active a protecção contra feedback para detectar feedback acústico entre o microfone e as colunas. Feedback Protection check box Caixa de Activação da Protecção Contra Feedback Audio Alerts Alertas de Áudio Enable audio alert when receiving a chat message and when a new client joins the session. A second sound device may be required to hear the alerts. Ative o alerta de áudio ao receber uma mensagem de bate-papo e quando um novo cliente ingressar na sessão. Um segundo dispositivo de som pode ser necessário para ouvir os alertas. Audio Alerts check box Caixa de seleção de Alertas de Áudio ASIO Device Settings Definições do Dispositivo ASIO Low Baixa Normal Normal High Alta Fancy Sofisticado Compact Compacto Bar (narrow) Barra (estreita) Bar (wide) Barra (larga) LEDs (stripe) LEDs (faixa) LEDs (round, small) LEDs (redondo, pequeno) LEDs (round, big) LEDs (redondo, grande) Manual Manual Custom Personalizado All Genres Servidor Geral Any Genre 2 Qualquer Estilo 2 Any Genre 3 Qualquer Estilo 3 Genre Rock Estilo Rock Genre Jazz Estilo Jazz Genre Classical/Folk Estilo Clássico/Folk Genre Choral/Barbershop Estilo Coral/Barbershop Any Genre 1 Qualquer Estilo 1 Genre Rock/Jazz Servidor Rock/Jazz Genre Classical/Folk/Choral Serv. Clássica/Folclore/Coro Default Servidor Padrão Default (North America) Servidor Padrão (America do Norte) preferred preferido Musician Profile Perfil do músico Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country you are located in. Your city and skill level playing your instrument may also be added. Escreva o seu nome ou um pseudónimo aqui para que os outros músicos com quem quer tocar saibam quem você é. Além disso, pode também definir uma imagem do instrumento que toca e uma bandeira do país onde vive. A cidade onde vive e o nível de habilidade com o seu instrumento também podem ser adicionados. What you set here will appear at your fader on the mixer board when you are connected to a Jamulus server. This tag will also be shown at each client which is connected to the same server as you. O que definir aqui aparecerá por baixo do seu fader na secção de mistura quando estiver ligado a um servidor Esta etiqueta também será exibida em cada cliente que estiver ligado ao mesmo servidor. Alias or name edit box Caixa de edição do nome ou pseudônimo Instrument picture button Botão da imagem do instrumento Country flag button Botão da bandeira do país City edit box Caixa de edição da cidade Skill level combo box Caixa do nível de habilidade Beginner Principiante Intermediate Intermediário Expert Avançado Size: Tamanho: Buffer Delay Atraso do buffer Buffer Delay: Atraso do buffer: The selected audio device could not be used because of the following error: O dispositivo de áudio selecionado não pôde ser usado devido ao seguinte erro: The previous driver will be selected. O driver anterior será selecionado. Ok Ok Drum Set Bateria Djembe Djembe Electric Guitar Guitarra Elétrica Acoustic Guitar Guitarra Acústica Bass Guitar Baixo Keyboard Teclado Synthesizer Sintetizador Grand Piano Piano de Cauda Accordion Acordeão Vocal Voz Microphone Microfone Harmonica Harmónica Trumpet Trompete Trombone Trombone French Horn Trompa Francesa Tuba Tuba Saxophone Saxofone Clarinet Clarinete Flute Flauta Violin Violino Cello Violoncelo Double Bass Contrabaixo Recorder Gravador Streamer Streamer Listener Ouvinte Guitar+Vocal Guitarra+Voz Keyboard+Vocal Teclado+Voz Bodhran Bodhrán Bassoon Fagote Oboe Oboé Harp Harpa Viola Viola de Arco Congas Congas Bongo Bongo Vocal Bass Voz Baixo Vocal Tenor Voz Tenor Vocal Alto Voz Alto Vocal Soprano Voz Soprano Banjo Banjo Mandolin Bandolim Ukulele Ukulele Bass Ukulele Ukulele Baixo Vocal Baritone Voz Barítono Vocal Lead Voz Principal Mountain Dulcimer Saltério dos Apalaches Scratching Scratching Rapping Rapping Vibraphone Vibrafone Conductor Maestro CClientSettingsDlgBase Settings Definições Soundcard Placa de Som Device Dispositivo Input Channel Mapping Mapeamento do Canal de Entrada L L R R Output Channel Mapping Mapeamento do Canal de Saída Enable Small Network Buffers Activar Buffers de Rede Pequenos Buffer Delay Atraso do buffer Country/Region País/Região (preferred) (preferido) (default) (padrão) (safe) (seguro) Driver Setup Configuração do Driver My Profile Meu Perfil Musician's Profile Perfil do Músico Alias/Name Nome/Alcunha Instrument Instrumento Country País City Cidade Skill Habilidade User Interface Interface de Utilizador Meter Style Estilo do Medidor Mixer Rows Linhas de Mistura Audio Alerts Alertas de Áudio Audio/Network Setup Configuração Audio/Rede Audio Device Dispositivo de Áudio Jitter Buffer Jitter Buffer Auto Auto Local Local Server Servidor Size Tamanho kbps kbps Custom Directories: Diretórios Personalizados: Input Boost Ampliação de Sinal de Entrada Feedback Protection Protecção Contra Feedback Enable Activar Input Balance Panorâmica da Entrada Pan Pan Center Centro Misc Outras Config. Audio Channels Canais de Áudio Audio Quality Qualidade de Áudio Measurements Medições Advanced Setup Configurações Avançadas Custom Central Server Address: Servidor Central Personalizado: New Client Level Nível de Novo Cliente Skin Tema Language Linguagem % % Local Jitter Buffer Jitter Buffer Local Fancy Skin Skin Sofisticada Display Channel Levels Mostrar Níveis de Canais Custom Directory Server Address: Endereço do Servidor de Diretório Personalizado: Directory Server Address: Endereço do Servidor Central: Audio Stream Rate Taxa de Transmissão de Áudio val val Ping Time Latência da Ligação Overall Delay Latência Geral CConnectDlg Server List Lista de servidores The server list shows a list of available servers which are registered at the directory server. Select a server from the list and press the connect button to connect to this server. Alternatively, double click a server from the list to connect to it. If a server is occupied, a list of the connected musicians is available by expanding the list item. Permanent servers are shown in bold font. A lista de servidores mostra a os servidores disponíveis registados no servidor central. Selecione um servidor da lista e pressione o botão Ligar para se ligar a este servidor. Como alternativa, clique duas vezes num servidor da lista para se ligar ao mesmo. Se um servidor estiver ocupado, uma lista dos músicos ligados estará disponível expandindo o item da lista. Os servidores permanentes são mostrados em negrito. Note that it may take some time to retrieve the server list from the directory server. If no valid directory server address is specified in the settings, no server list will be available. Observe que pode demorar algum tempo para obter a lista de servidores do servidor central. Se nenhum endereço de servidor central válido for especificado nas definições, nenhuma lista de servidores estará disponível. Directory Diretório Shows the servers listed by the selected directory. You can add custom directories in Advanced Settings. Exibe os servidores listados por diretório selecionado. Você pode adicionar diretórios personalizados em Configurações Avançadas. Directory combo box Seletor de Diretório Filters the server list by the given text. Note that the filter is case insensitive. A single # character will filter for those servers with at least one person connected. Filtra a lista de servidores pelo texto fornecido. Observe que o filtro não diferencia maiúsculas de minúsculas. Um único caractere # filtrará os servidores com pelo menos uma pessoa ligada. Uncheck to collapse the server list to show just the server details. Check to show everyone on the servers. Desmarque para recolher a lista de servidores e mostrar apenas os detalhes. The Connection Setup window lists the available servers registered with the selected directory. Use the Directory dropdown to change the directory, find the server you want to join in the server list, click on it, and then click the Connect button to connect. Alternatively, double click on the server name to connect. A janela de Configuração de Conexão lista os servidores disponíveis registados no diretório selecionado. Use o menu lista para alterar o diretório, localize o servidor que deseja ingressar na lista de servidores, clique nele e, em seguida clique no botão Conectar para conectar-se. Como alternativa, clique duas vezes no nome do servidor para conectar-se. Permanent servers (those that have been listed for longer than 48 hours) are shown in bold. Servidores permanentes (aqueles que estão listados por mais de 48 horas) são mostrados em negrito. You can add custom directories in Advanced Settings. Você pode adicionar diretórios personalizados em Configurações Avançadas. Server list view Vista da lista de servidores Server Address Endereço do servidor If you know the server address, you can connect to it using the Server name/Address field. An optional port number can be added after the server address using a colon as a separator, e.g. %1. The field will also show a list of the most recently used server addresses. Se você souber o endereço do servidor, poderá ligar-se a ele usando o campo Nome/Endereço do servidor. Um número de porta opcional pode ser adicionado após o endereço do servidor usando dois pontos como separador, por exemplo %1. O campo também mostrará uma lista dos endereços de servidor usados mais recentemente. Holds the current server address. It also stores old addresses in the combo box list. Contém o endereço do servidor atual. Também armazena endereços antigos na lista do seletor. The IP address or URL of the server running the O endereço IP ou URL do servidor executando o servidor server software must be set here. An optional port number can be added after the IP address or URL using a colon as a separator, e.g. example.org: deve ser definido aqui. Um número de porta opcional pode ser adicionado após o endereço IP ou URL usando o caractere dois pontos como separador, por exemplo, example.org: . A list of the most recent used server IP addresses or URLs is available for selection. . Uma lista dos endereços IP ou URLs dos servidores usados recentemente está disponível para seleção. The Connection Setup window shows a list of available servers. Server operators can optionally list their servers by music genre. Use the List dropdown to select a genre, click on the server you want to join and press the Connect button to connect to it. Alternatively, double click on on the server name. Permanent servers (those that have been listed for longer than 48 hours) are shown in bold. A janela Configuração da ligação mostra uma lista de servidores disponíveis. Os operadores dos servidores podem registar os seus servidores por género musical. Utilize o menu Lista para selecionar um género, clique no servidor ao qual se deseja ligar e pressione o botão Ligar. Como alternativa, clique duas vezes no nome do servidor. Servidores permanentes (aqueles que estão registados há mais de 48 horas) são mostrados em negrito. If you know the IP address or URL of a server, you can connect to it using the Server name/Address field. An optional port number can be added after the IP address or URL using a colon as a separator, e.g. example.org: Se souver o endereço IP ou URL de um servidor, pode ligar-se a este utilizando o campo Nome/Endereço do Servidor. Um número de porta opcional pode ser adicionado após o endereço IP ou URL usando o caractere dois pontos como separador, por exemplo, example.org: . The field will also show a list of the most recently used server addresses. . Este campo também irá mostrar uma lista dos endereços IP ou URLs dos servidores usados recentemente. Server address edit box Caixa de edição do endereço do servidor Holds the current server IP address or URL. It also stores old URLs in the combo box list. Contém o endereço IP ou URL do servidor atual. Também armazena URLs antigos na lista do seletor. Server List Selection Selecção da Lista de Servidores Selects the server list to be shown. Seleciona a lista de servidores a ser apresentada. Server list selection combo box Caixa de selecção de lista de servidores Filter Filtro The server list is filtered by the given text. Note that the filter is case insensitive. A lista de servidores é filtrada pelo texto fornecido. Note que o filtro não diferencia maiúsculas de minúsculas. Filter edit box Caixa de edição do filtro Show All Musicians Mostrar Todos os Músicos If you check this check box, the musicians of all servers are shown. If you uncheck the check box, all list view items are collapsed. Se marcar esta caixa de seleção, os músicos de todos os servidores serão mostrados. Se desmarcar a caixa de seleção, todos os itens em exibição na lista serão recolhidos. Show all musicians check box Caixa de seleção para mostrar músicos If you know the IP address or URL of a server, you can connect to it using the Server name/Address field. An optional port number can be added after the IP address or URL using a colon as a separator, e.g. %1. The field will also show a list of the most recently used server addresses. Se você souber o endereço IP ou URL de um servidor, poderá conectar-se a ele usando o campo Nome/Endereço de Servidor. Um número de porta opcional pode ser adicionado após o endereço IP ou URL usando dois pontos como separador, por exemplo, %1. O campo também mostrará uma lista de servidores usados mais recentemente. Filter text, or # for occupied servers Filtrar texto, ou # para servidores ocupados Type # for occupied servers Escreve # para servidores ocupados CConnectDlgBase Connection Setup Configuração da Ligação List Lista Directory Diretório Filter Filtro Show All Musicians Mostrar Todos os Músicos Server Name Nome do Servidor Ping Time Latência Musicians Músicos Location Localização Server Address Endereço do Servidor C&ancel &Cancelar &Connect &Ligar CHelpMenu &Help &Ajuda Getting &Started... Como Começa&r... Software &Manual... &Manual do Programa... What's &This O que é &isto &About Jamulus... &Sobre o Jamulus... About &Qt... Sobre o &Qt... &About... &Sobre... About Qt Sobre o Qt CLanguageComboBox Restart Required Reinicio necessário Please restart the application for the language change to take effect. Por favor reinicie a aplicação para a alteração de linguagem ter efeito. CLicenceDlg I &agree to the above licence terms Eu &aceito os termos da licença acima This server requires you accept conditions before you can join. Please read these in the chat window. Este servidor requer que aceite as condições antes de poder entrar. Por favor leia as condições na janela de mensagens. I have read the conditions and &agree. Li &as condições e concordo. Accept Aceitar Decline Rejeitar By connecting to this server and agreeing to this notice, you agree to the following: Ao ligar-se a este servidor e concordar com este aviso, está a concordar com o seguinte: You agree that all data, sounds, or other works transmitted to this server are owned and created by you or your licensors, and that you are making these data, sounds or other works available via the following Creative Commons License (for more information on this license, see Você concorda que todos os dados, sons ou outros trabalhos transmitidos para este servidor pertencem e são criados por você ou por seus licenciadores, e que você está disponibilizando esses dados, sons ou outros trabalhos através da seguinte licença Creative Commons (para obter mais informações sobre esta licença, consulte You are free to: Você tem o direito de: Share Compartilhar copy and redistribute the material in any medium or format copiar e redistribuir o material em qualquer suporte ou formato Adapt Adaptar remix, transform, and build upon the material remisturar, transformar, e criar a partir do material The licensor cannot revoke these freedoms as long as you follow the license terms. O licenciante não pode revogar estes direitos desde que você respeite os termos da licença. Under the following terms: De acordo com os termos seguintes: Attribution Atribuição You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. Você deve atribuir o devido crédito, fornecer um link para a licença, e indicar se foram feitas alterações. Você pode fazê-lo de qualquer forma razoável, mas não de uma forma que sugira que o licenciante o apoia ou aprova o seu uso. NonCommercial NãoComercial You may not use the material for commercial purposes. Você não pode usar o material para fins comerciais. ShareAlike CompartilhaIgual If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original. Se você remisturar, transformar, ou criar a partir do material, tem de distribuir as suas contribuições ao abrigo da mesma licença que o original. No additional restrictions Sem restrições adicionais You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. Você não pode aplicar termos jurídicos ou medidas de caráter tecnológico que restrinjam legalmente outros de fazerem algo que a licença permita. CMultiColorLED Red Vermelho Yellow Amarelo Green Verde CMusProfDlg server. This tag will also show up at each client which is connected to the same server as you. If the name is left empty, the IP address is shown instead. . Esta identificação também será exibida em cada cliente ligado ao mesmo servidor que você. Se o nome estiver vazio, o endereço IP será mostrado. Alias or name edit box Caixa de edição do nome ou pseudônimo Instrument picture button Botão da imagem do instrumento Country flag button Botão da bandeira do país City edit box Caixa de edição da cidade Skill level combo box Caixa do nível de habilidade None Nenhum Musician Profile Perfil do músico Alias/Name Nome/Alcunha Instrument Instrumento Country País City Cidade Skill Habilidade &Close &Fechar Beginner Principiante Intermediate Intermediário Expert Avançado Set your name or an alias here so that the other musicians you want to play with know who you are. Additionally you may set an instrument picture of the instrument you play and a flag of the country you are living in. The city you live in and the skill level playing your instrument may also be added. Defina o seu nome ou um pseudônimo aqui para que os outros músicos com quem quer tocar saibam quem você é. Além disso, pode definir uma imagem do instrumento que toca e uma bandeira do país em que vive. A cidade em que vive e o nível de habilidade com o seu instrumento também podem ser adicionados. What you set here will appear at your fader on the mixer board when you are connected to a O que definir aqui aparecerá por baixo do seu fader na secção de mistura quando estiver ligado a um servidor Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country you are located in. Your city and skill level playing your instrument may also be added. Escreva o seu nome ou um pseudónimo aqui para que os outros músicos com quem quer tocar saibam quem você é. Além disso, pode também definir uma imagem do instrumento que toca e uma bandeira do país onde vive. A cidade onde vive e o nível de habilidade com o seu instrumento também podem ser adicionados. What you set here will appear at your fader on the mixer board when you are connected to a Jamulus server. This tag will also be shown at each client which is connected to the same server as you. O que definir aqui aparecerá por baixo do seu fader na secção de mistura quando estiver ligado a um servidor Esta etiqueta também será exibida em cada cliente que estiver ligado ao mesmo servidor. Drum Set Bateria Djembe Djembe Electric Guitar Guitarra Elétrica Acoustic Guitar Guitarra Acústica Bass Guitar Baixo Keyboard Teclado Synthesizer Sintetizador Grand Piano Piano de Cauda Accordion Acordeão Vocal Voz Microphone Microfone Harmonica Harmónica Trumpet Trompete Trombone Trombone French Horn Trompa Francesa Tuba Tuba Saxophone Saxofone Clarinet Clarinete Flute Flauta Violin Violino Cello Violoncelo Double Bass Contrabaixo Recorder Gravador Streamer Streamer Listener Ouvinte Guitar+Vocal Guitarra+Voz Keyboard+Vocal Teclado+Voz Bodhran Bodhrán Bassoon Fagote Oboe Oboé Harp Harpa Viola Viola de Arco Congas Congas Bongo Bongo Vocal Bass Voz Baixo Vocal Tenor Voz Tenor Vocal Alto Voz Alto Vocal Soprano Voz Soprano Banjo Banjo Mandolin Bandolim Ukulele Ukulele Bass Ukulele Ukulele Baixo Vocal Baritone Voz Barítono Vocal Lead Voz Principal Mountain Dulcimer Saltério dos Apalaches Scratching Scratching Rapping Rapping No Name Sem Nome CServerDlg Client List Lista de Clientes The client list shows all clients which are currently connected to this server. Some information about the clients like the IP address and name are given for each connected client. A lista de clientes mostra todos os clientes que estão atualmente ligados a este servidor. Algumas informações sobre os clientes, como o endereço IP e o nome, são fornecidas para cada cliente ligado. Connected clients list view Lista de clientes ligados Directory Type combo box Seletor de Tipo de Diretório Directory Diretório Select '%1' not to register your server with a directory. Selecione '%1' para não registar seu servidor com um diretório. Select one of the genres to register with that directory. Selecione um dos gêneros para registar-se nesse diretório. Or select '%1' and specify a Custom Directory address on the Options tab to register with a custom directory. Ou selecione '%1' e especifique um endereço de Diretório Personalizado na guia Opções para registar-se com um diretório personalizado. For any value except '%1', this server registers with a directory so that a %2 user can select this server in the client connect dialog server list when they choose that directory. Para qualquer valor, exceto '%1',este servidor regista-se em um diretório para que um usuário %2 possa selecioná-lo na lista de servidores da caixa de diálogo de ligação do cliente ao escolher esse diretório. The registration of the server is renewed periodically to make sure that all servers in the connect dialog server list are actually available. O registo do servidor é renovado periodicamente para garantir que todos os servidores na lista do diálogo de ligação estejam realmente acessíveis. When a value other than "%1" is chosen for Directory, this will show whether registration is successful. If the registration failed, please choose a different directory. Quando um valor direfente de "%1" for escolhido para Diretório, isso mostrará se o registo foi bem sucedido. Se o registo falhou, escolha um diretório diferente. No recording directory has been set or the value is not useable. Check the value in the Options tab. Nenhum diretório de gravação foi definido ou o valor não pode ser usado. Verifique o valor na guia Opções. If the recording directory is not useable, the problem will be displayed in place of the session directory. Se o diretório de gravação não for utilizável, o problema será exibido no lugar do diretório de sessão. Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user %1 is running as). Clique no botão para abrir o diálogo que permite selecionar o diretório de gravação principal. O diretório escolhido deve existir e ser gravável (permitir a criação de subdiretórios pelo utilizador com o qual %1 está sendo corrido). The current value of the main recording directory. The chosen value must exist and be writeable (allow creation of sub-directories by the user %1 is running as). Click the button to open the dialog that allows the main recording directory to be selected. O valor atual do diretório principal de gravação. O valor escolhido deve existir e ser gravável (permite criação de subdiretórios pelo uutilizador com o qual %1 está sendo corrido.). Clique no botão para abrir o diálogo que permite selecionar o diretório principal de gravação. Custom Directory address End. de Diretório Personalizado The Custom Directory address is the address of the directory holding the server list to which this server should be added. O endereço do Diretório Personalizado é o endereço do diretório que contém a lista de servidores ao qual esse servidor deve ser adicionado. Server List Filename dialog push button Botão de diálogo do arquivo da Lista de Servidores Server List Filename Arquivo da Lista de Servidores Click the button to open the dialog that allows the server list persistence file name to be set. The user %1 is running as needs to be able to create the file name specified although it may already exist (it will get overwritten on save). Clique no botão para abrir o diálogo que permite definir o nome do arquivo de persistência da lista de servidores. O utilizador com o qual %1 está sendo corrido necessita ser capaz de criar o nome do arquivo especificado, embora ele já exista (será substituído ao salvar). Server List Filename text box (read-only) Caixa de texto com o arquivo da Lista de Servidores (apenas leitura) The current value of server list persistence file name. The user %1 is running as needs to be able to create the file name specified although it may already exist (it will get overwritten on save). Click the button to open the dialog that allows the server list persistence file name to be set. O valor atual do nome do arquivo de persistência da lista de servidores. O usuário com o qual %1 está sendo corrido precisa ser capaz de criar o nome do arquivo especificado, embora ele já exista (será substituído ao salvar). Clique no botão para abrir o diálogo que permite definir o nome do arquivo de persistência da lista de servidores. Clear the server list file name button Botão para limpar arquivo da lista de servidores Clear Server List Filename Limpar Arquivo da Lista de Servidores Click the button to clear the currently selected server list persistence file name. This will prevent persisting the server list until a new value is selected. Carregue no botão para limpar o nome do arquivo de persistência da lista de servidores atualmente selecionado. Isso impedirá a persistência da lista de servidores até que um novo valor seja selecionado. Start Minimized on Operating System Start Iniciar Minimizado com o Sistema Operativo Now a directory Agora um diretório If the start minimized on operating system start check box is checked, the Se a caixa de seleção Iniciar Minimizado com o Sistema Operativo estiver marcada, o servidor server will be started when the operating system starts up and is automatically minimized to a system task bar icon. será iniciado quando o sistema operativo for iniciado, e minimizado automaticamente para um ícone da barra de tarefas do sistema. Show Creative Commons Licence Dialog Mostrar Diálogo da Licença Creative Commons If enabled, a Creative Commons BY-NC-SA 4.0 Licence dialog is shown each time a new user connects the server. Se ativada, uma caixa de diálogo Creative Commons BY-NC-SA 4.0 será exibida sempre que um novo utilizador se ligar ao servidor. Make My Server Public Tornar Servidor Público If the Make My Server Public check box is checked, this server registers itself at the directory server so that all Se a caixa de seleção Tornar Servidor Público estiver marcada, esse servidor irá registar-se no servidor central para que todos os utilizadores do users can see the server in the connect dialog server list and connect to it. The registration of the server is renewed periodically to make sure that all servers in the connect dialog server list are actually available. possam ver o servidor na lista do diálogo de ligação e ligar-se a ele. O registo do servidor é renovado periodicamente para garantir que todos os servidores na lista de diálogo de ligação estejam realmente disponíveis. Register Server Status Estado de Registo do Servidor If the Make My Server Public check box is checked, this will show whether registration with the directory server is successful. Se a caixa de seleção Tornar Servidor Público estiver marcada, isto mostrará o sucesso ou insucesso do registo no servidor central. Directory Server Address Endereço do servidor central The Directory server address is the IP address or URL of the directory server at which this server is registered. With the directory server address type either the local region can be selected of the default directory servers or a manual address can be specified. O endereço do servidor central é o endereço IP ou o URL do servidor central no qual esse servidor será registado. Com o menu dos servidores centrais, é possível selecionar um dos servidores centrais padrão ou especificar um endereço manual. If the Make My Server Public check box is checked, this will show whether registration with the directory server is successful. If the registration failed, please choose another server list. Se a caixa de seleção Tornar Meu Servidor Público fôr seleccionada, isto apresentará se o registro no servidor de diretório foi bem-sucedido. Se o registo falhar, escolha outra lista de servidores. Default directory server type combo box Seletor do servidor central padrão If the start minimized on operating system start check box is checked, the server will be started when the operating system starts up and is automatically minimized to a system task bar icon. Se a caixa de seleção Iniciar Minimizado com o Sistema Operativo estiver marcada, o servidor será iniciado quando o sistema operativo for iniciado, e minimizado automaticamente para um ícone da barra de tarefas do sistema. If the Make My Server Public check box is checked, this server registers itself at the directory server so that all users of the application can see the server in the connect dialog server list and connect to it. The registration of the server is renewed periodically to make sure that all servers in the connect dialog server list are actually available. Se a caixa de seleção Tornar Servidor Público estiver marcada, este servidor irá registar-se no servidor de diretório para que todos os utilizadores da aplicação o possam ver na lista de servidores e ligar-se a ele. O registo dos servidores é renovado periodicamente para garantir que todos os servidores na lista estão realmente disponíveis. Custom Directory Server Address Endereço do Servidor de Diretório Personalizado The custom directory server address is the IP address or URL of the directory server at which the server list of the connection dialog is managed. O endereço do servidor de diretório personalizado é o endereço IP ou URL do servidor de diretório no qual a lista de servidores da Configuração da Ligação é gerida. Directory server address line edit Caixa de edição do endereço do servidor de diretório Server List Selection Selecção da Lista de Servidores Selects the server list (i.e. directory server address) in which your server will be added. Seleciona a lista de servidores (ou seja, endereço do servidor de diretório) à qual seu servidor será adicionado. Server list selection combo box Caixa de selecção de lista de servidores Server Name Nome do Servidor The server name identifies your server in the connect dialog server list at the clients. If no name is given, the IP address is shown instead. O nome do servidor identifica o servidor na lista do diálogo de ligação exibido nos clientes. Se nenhum nome for fornecido, o endereço IP será mostrado. The server name identifies your server in the connect dialog server list at the clients. O nome do servidor identifica o servidor na lista do diálogo de ligação exibido nos clientes. Server name line edit Caixa de edição do nome do servidor Location City ;Localização: Cidade The city in which this server is located can be set here. If a city name is entered, it will be shown in the connect dialog server list at the clients. A cidade onde este servidor está localizado pode ser definida aqui. Se um nome de cidade for inserido, este será mostrado na lista do diálogo de ligação dos clientes. City where the server is located line edit Caixa de edição da cidade onde o servidor se encontra Location country Localização: País The country in which this server is located can be set here. If a country is entered, it will be shown in the connect dialog server list at the clients. O país em que este servidor está localizado pode ser definido aqui. Se um país for inserido, ele será mostrado na lista do diálogo de logação dos clientes. Country where the server is located combo box Seletor do país onde o servidor de encontra Country/Region País/Região Set the country or region where the server is running. Clients will show this location in their connect dialog's server list. Defina o país ou a região onde o servidor está a ser executado. Os clientes irão exibir esta localização na janela da ligação da lista de servidores. Combo box for location of this server Caixa de seleção para localização deste servidor Recording has been switched off by the UI checkbox. As gravações foram desactivadas pela caixa de seleção da IU. Recording has been switched off, either by the UI checkbox or SIGUSR2 being received. As gravações foram desactivadas pela caixa de seleção da IU ou por sinal SIGUSR2 ser recebido. Display dialog to select recording directory button Mostrar diálogo para selecionar botão do directorio de gravação Main Recording Directory Diretório Principal das Gravações Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user Jamulus is running as). Clique no botão para abrir o diálogo que permite selecionar o directório das gravações. O directório escolhido deve existir e ter permissões de escrita (deve permitir a criação de sub-pastas pelo utilizador que está a correr o Jamulus). Main recording directory text box (read-only) Caixa de texto do diretório das gravações (só de leitura) The current value of the main recording directory. The chosen value must exist and be writeable (allow creation of sub-directories by the user Jamulus is running as). Click the button to open the dialog that allows the main recording directory to be selected. O valor actual do diretório das gravações. O valor escolhido deve existir e ter permissões de escrita (deve permitir a criação de sub-pastas pelo utilizador que está a correr o Jamulus). Clique no botão para abrir a caixa de diálogo que permite selecionar o diretório das gravações. Clear the recording directory button Botão para limpar diretório de gravações Clear Recording Directory Limpar diretório de gravações Click the button to clear the currently selected recording directory. This will prevent recording until a new value is selected. Carregue no botão para limpar o valor do diretório selecionado actualmente. Isto irá prevenir gravações até que um novo valor seja selecionado. Checkbox to turn on or off server recording Caixa de selecção para ligar ou desligar a gravação no servidor If the Register Server check box is checked, this will show whether registration with the directory server is successful. If the registration failed, please choose another server list. Se a caixa de seleção Registrar Servidor fôr seleccionada, isto apresentará se o registro no servidor de diretório foi bem-sucedido. Se o registo falhar, escolha outra lista de servidores. Enable Recorder Activar Gravador Checked when the recorder is enabled, otherwise unchecked. The recorder will run when a session is in progress, if (set up correctly and) enabled. Activo quando o gravador estiver ligado, caso contrário inactivo. O gravador irá correr quando uma sessão estiver a decorrer, se (correctamente configurado e ) activo. Current session directory text box (read-only) Caixa de texto com a pasta da gravação actual (apenas leitura) Current Session Directory Pasta da Sessão Acual Enabled during recording and holds the current recording session directory. Disabled after recording or when the recorder is not enabled. Activo durante a gravação e exibe a pasta da gravação actual. Inactivo depois de gravação ou quando o gravador não estiver ligado. Recorder status label Etiqueta do estado do Gravador Recorder Status Estado do Gravador Displays the current status of the recorder. The following values are possible: Mostra o estado actual do gravadro. Os valores possíveis são: No recording directory has been set or the value is not useable. O directório de gravaçãos não foi definido ou não é utilizável. Recording has been switched off As gravações foram desactivadas by the UI checkbox pela caixa de selecção da interface , either by the UI checkbox or SIGUSR2 being received , pela caixa de selecção da interface ou por sinal SIGUSR2 ser recebido There is no one connected to the server to record. Não está ninguém ligado ao servidor para gravar. The performers are being recorded to the specified session directory. Os artistas estão a ser gravados para o diretório de sessão especificado. NOTE NOTE If the recording directory is not useable, the problem will be displayed in place of the directory. Se o directório das gravações não for utilizável, o problema será apresentado em vez do directório. Server welcome message edit box Caixa de edição da mensagem de Boas-Vindas do Servidor Server Welcome Message Mesagem de Boas-Vindas do Servidor A server welcome message text is displayed in the chat window if a musician enters the server. If no message is set, the server welcome is disabled. Uma mensagem de boas vindas do servidor é exibida na janela de mensagens quando um utilizador entra no servidor. Se não houver nenhuma mensagem definida, a mensagem do servidor ficará inactiva. Language Idioma Select the language to be used for the user interface. Selecione o idioma a ser utilizado na interface do usuário. Language combo box Caixa de seleção de idioma Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user Jamulus is running as). Clique no botão para abrir o diálogo que permite selecionar o directório das gravações. O directório escolhido deve existir e ter permissões de escrita (deve permitir a criação de sub-pastas pelo utilizador que está a correr o Jamulus). Custom Directory Diretório Personalizado The custom directory is the IP address or URL of the directory server at which the server list of the connection dialog is managed. O diretório personalizado é o endereço IP ou URL do servidor de diretório no qual a lista de servidores da Configuração da Ligação é gerida. Custom Directory line edit Caixa de edição do Diretório Personalizado &Hide %1 server &Ocultar servidor %1 &Show %1 server Mostrar &servidor %1 %1 server %1 is the name of the main application Servidor %1 Type a message here. If no message is set, the server welcome is disabled. Insira uma mensagem aqui. Se não houver nenhuma mensagem definida, a mensagem do servidor ficará inactiva. %1 Server %1 is the name of the main application Servidor %1 software upgrade available actualização de software disponível Recorder failed to start. Please check available disk space and permissions and try again. Error: O Gravador falhou a inicialização. Por favor verifique se tem espaço em disco e permições e tente de novo. Erro: ERROR ERRO Displays the current status of the recorder. Mostra o estado actual do gravador. Request new recording button Botão para começar nova gravação New Recording Nova Gravação During a recording session, the button can be used to start a new recording. Durante uma sessão de gravação, este botão pode ser usado para começar uma nova gravação. E&xit &Sair &Hide &Esconder servidor server &Open &Abrir servidor server Select Main Recording Directory Seleciona o Diretório Principal das Gravações Predefined Address Endereço Predefinido Recording A gravar Not recording Não está a gravar Not initialised Não inicializado Not enabled Desactivado Manual Manual Default Servidor Padrão Default (North America) Servidor Padrão (America do Norte) Server - Servidor &Window &Janela Unregistered Não Registado None Nenhum Not registered Não registado Bad address Endereço incorrecto Registration requested Registo solicitado Registration failed Falha no registo Check server version Verifique versão do servidor Registered Registado Directory server list full Lista de servidores no diretório cheia Directory Server full Servidor de Diretório cheio Your server version is too old A versão do seu servidor é muito antiga Requirements not fulfilled Requisitos não cumpridos Unknown value %1 Valor desconhecido %1 Unknown value Valor desconhecido CServerDlgBase Client IP:Port IP do Cliente:Porta Name Nome do Servidor Jitter Buffer Size Tamanho do Jitter Buffer Channels Canais Server Setup Configuração do Servidor List Lista Location: Region Localização: Região Session Sessão Chat Window Welcome (HTML/CSS Supported) Mensagem de Boas Vindas (HTML/CSS Suportado) Options Opções Custom Directory address End. de Diretório Personalizado Server List Filename Arquivo da Lista de Servidores Start Minimized on Windows Start Iniciar Minimizado com o Sistema Operativo Enable delay panning Activar Panorâmica do Delay Show Creative Commons BY-NC-SA 4.0 Licence Dialog Mostrar Diálogo da Licença Creative Commons BY-NC-SA 4.0 Update check Verificação de actualização Make My Server Public (Register My Server in the Server List) Tornar Servidor Público (Registar na Lista de Servidores) Genre Género STATUS ESTADO Custom Directory Server Address: Endereço do Servidor de Diretório Personalizado: Recording Directory Diretório das Gravações Enable Jam Recorder Activar Gravador Directory Diretório New Recording Nova Gravação Language Consider add "(Lang)" as a suffix to ensure that users who selected the wrong language find the correct button Linguagem Directory Server Address: Endereço do Servidor Central: My Server Info Informação do Servidor Location: City Localização: Cidade Location: Country Localização: País Enable jam recorder Activar gravação New recording Nova gravação Recordings folder Pasta de gravações TextLabelNameVersion TextLabelNameVersion CServerListManager Could not write to '%1' Não foi possível gravar em '%1' CSound The Jack server is not running. This software requires a Jack server to run. Normally if the Jack server is not running this software will automatically start the Jack server. It seems that this auto start has not worked. Try to start the Jack server manually. O servidor Jack não está em execução. Este programa requer um servidor Jack para ser executado. Normalmente, se o servidor Jack não estiver em execução, este programa iniciará automaticamente o servidor Jack. Parece que esse início automático não funcionou. Tente iniciar o servidor Jack manualmente. The Jack server sample rate is different from the required one. The required sample rate is: A taxa de amostragem (sample rate) do servidor Jack é diferente da necessária. A taxa de amostragem necessária é: You can use a tool like <i><a href="https://qjackctl.sourceforge.io">QJackCtl</a></i> to adjust the Jack server sample rate. Pode usar uma ferramenta como <i><a href="https://qjackctl.sourceforge.io">QJackCtl</a></i> para ajustar a taxa de amostragem do servidor Jack. Make sure to set the Frames/Period to a low value like Certifique-se de definir Frames/Período para um valor baixo como to achieve a low delay. para obter uma latência baixa. The Jack port registering failed. O registo da porta Jack falhou. Cannot activate the Jack client. Não é possível ativar o cliente Jack. The Jack server was shut down. This software requires a Jack server to run. Try to restart the software to solve the issue. O servidor Jack foi desligado. Este programa requer um servidor Jack para ser executado. Tente reiniciar o programa para resolver o problema. CoreAudio input AudioHardwareGetProperty call failed. It seems that no sound card is available in the system. A entrada do CoreAudio falhou na chamada AudioHardwareGetProperty. Parece que nenhuma placa de som está disponível no sistema. CoreAudio output AudioHardwareGetProperty call failed. It seems that no sound card is available in the system. A saída do CoreAudio falhou na chamada AudioHardwareGetProperty. Parece que nenhuma placa de som está disponível no sistema. Current system audio input device sample rate of %1 Hz is not supported. Please open the Audio-MIDI-Setup in Applications->Utilities and try to set a sample rate of %2 Hz. A taxa de amostragem (sample rate) de %1 Hz do dispositivo de entrada de áudio atual não é suportada. Por favor, abra o Audio-MIDI-Setup em Applications-> Utilities e tente definir uma taxa de amostragem de %2 Hz. The current selected audio device is no longer present in the system. O dispositivo de áudio actualmente seleccionado não se encontra presente no sistema. The audio input device is no longer available. O dispositivo de entrada de áudio não se encontra disponível. The audio output device is no longer available. O dispositivo de saída de áudio não se encontra disponível. Current system audio output device sample rate of %1 Hz is not supported. Please open the Audio-MIDI-Setup in Applications->Utilities and try to set a sample rate of %2 Hz. A taxa de amostragem (sample rate) de %1 Hz do dispositivo de saída de áudio atual não é suportada. Por favor, abra o Audio-MIDI-Setup em Applications-> Utilities e tente definir uma taxa de amostragem de %2 Hz. The audio input stream format for this audio device is not compatible with this software. O formato do fluxo de entrada de áudio para este dispositivo de áudio não é compatível com este programa. The audio output stream format for this audio device is not compatible with this software. O formato do fluxo de saída de áudio para este dispositivo de áudio não é compatível com este programa. The buffer sizes of the current input and output audio device cannot be set to a common value. Please choose other input/output audio devices in your system settings. Os tamanhos de buffer do dispositivo de áudio de entrada e saída atual não podem ser definidos para um valor comum. Por favor, escolha outros dispositivos de áudio de entrada/saída nas configurações do seu sistema. The audio driver could not be initialized. O driver de áudio não pôde ser inicializado. The audio device does not support the required sample rate. The required sample rate is: O dispositivo de áudio não suporta a taxa de amostragem (sample rate) necessária. A taxa de amostragem necessária é: The audio device does not support setting the required sampling rate. This error can happen if you have an audio interface like the Roland UA-25EX where you set the sample rate with a hardware switch on the audio device. If this is the case, please change the sample rate to O dispositivo de áudio não suporta definir a taxa de amostragem (sample rate) necessária. Este erro pode ocorrer se você tiver uma interface de áudio como o Roland UA-25EX, onde se define a taxa de amostragem através de um interruptor de hardware no dispositivo de áudio. Se for esse o caso, altere a taxa de amostragem para Hz on the device and restart the Hz no dispositivo e reinicie o cliente software. . The audio device does not support the required number of channels. The required number of channels for input and output is: O dispositivo de áudio não suporta o número necessário de canais. O número necessário de canais para entrada e saída é: Required audio sample format not available. Formato de amostra de áudio necessário não disponível. The selected audio device is no longer present in the system. Please check your audio device. O dispositivo de áudio actualmente seleccionado não se encontra presente no sistema. Verifique seu dispositivo de áudio. Couldn't initialise the audio driver. Check if your audio hardware is plugged in and verify your driver settings. Não foi possível inicializar o driver de áudio. Confirme se seu equipamento de áudio está conectado e verifique suas configurações do driver. The selected audio device is incompatible since it doesn't support a sample rate of %1 Hz. Please select another device. O dispositivo de áudio selecionado é incompatível uma vez que não suporta uma taxa de amostras de %1 Hz. Por favor, selecione outro dispositivo. The current audio device configuration is incompatible because the sample rate couldn't be set to %2 Hz. Please check for a hardware switch or driver setting to set the sample rate manually and restart %1. A configuração do dispositivo de áudio atual é incompatível pois não foi possível definir a taxa de amostras em %2 Hz. Verifique se o equipamento possui alguma chave ou configuração de driver para definir manualmente a taxa de amostras e reiniciar o %1. The selected audio device is incompatible since it doesn't support %1 in/out channels. Please select another device or configuration. O dispositivo de áudio selecionado é incompatível uma vez que não suporta %1 canais de entrada/saída. Por favor, selecione outro dispositivo ou configuração. The selected audio device is incompatible since the required audio sample format isn't available. Please use another device. O dispositivo de áudio selecionado é incompatível uma vez que o formato de áudio requerido não está disponível. Por favor, selecione outro dispositivo. No ASIO audio device driver found. Não foi encontrado um controlador ASIO do dispositivo de áudio. Please install an ASIO driver before running %1. If you own a device with ASIO support, install its official ASIO driver. If not, you'll need to install a universal driver like ASIO4ALL. Por favor, instale um controlador ASIO driver antes de executar o %1. Se tem um dispositivo com suporte ASIO, instale o controlador ASIO oficial. Se não, precisará de instalar um controlador ASIO universal, como o ASIO4ALL. Please install an ASIO driver before running %1. If you own a device with ASIO support, install its official ASIO driver. If not, you'll need to download and install a universal driver like ASIO4ALL. Por favor instale um driver ASIO driver antes de correr o %1. Se detém um dispositivo com suporte ASIO, instale o driver ASIO oficial. Se não, precisa de utilizar um driver ASIO universal como o ASIO4ALL. No ASIO audio device (driver) found. Nenhum dispositivo de áudio ASIO (driver) encontrado. The O programa software requires the low latency audio interface ASIO to work properly. This is not a standard Windows audio interface and therefore a special audio driver is required. Either your sound card has a native ASIO driver (which is recommended) or you might want to use alternative drivers like the ASIO4All driver. requer que a interface de áudio de baixa latência ASIO funcione corretamente. Esta não é uma interface de áudio padrão do Windows e, portanto, é necessário um driver de áudio especial. Ou a sua placa de som possui um driver ASIO nativo (recomendado), ou pode usar drivers alternativos, como o driver ASIO4All. Error requesting stream stop: $s Erro ao requisitar paragem do stream: $s Error closing stream: $s Erro ao fechar o stream: $s JACK couldn't be started automatically. Please start JACK manually and check for error messages. Não foi possível iniciar o JACK automaticamente. Inicie o JACK manualmente e verifique se há mensagens de erro. JACK isn't running at a sample rate of <b>%1 Hz</b>. Please use a tool like <i><a href="https://qjackctl.sourceforge.io">QjackCtl</a></i> to set the the JACK sample rate to %1 Hz. JACK não está em execução com uma taxa de amostras de <b>%1 Hz</b>. Por favor, use uma ferramenta, como <i><a=href="https://qjackctl.sourceforge.io">QjackCtl</a></i> para definir a taxa de amostras de JACK para %1 Hz. The JACK port registration failed. This is probably an error with JACK. Please stop %1 and JACK. Afterwards check if another program at a sample rate of %2 Hz can connect to JACK. O registo da porta JACK falhou. Provavelmente isso é um erro com JACK. Pare %1 e JACK. Depois, verifique se outro programa com uma taxa de amostragem de %2 Hz pode ligar-se ao JACK. The JACK port registration failed. This is probably an error with JACK. Please stop %1 and JACK. Afterwards, check if another MIDI program can connect to JACK. O registo da porta JACK falhou. Provavelmente isso é um erro com JACK. Pare %1 e JACK. Depois, verifique se outro programa MIDI pode ligar-se ao JACK. Can't activate the JACK client. This is probably an error with JACK. Please check the JACK output. Não é possível ativar o cliente JACK. Provavelmente isso é um erro com JACK. Verifique a saída JACK. JACK was shut down. %1 requires JACK to run. Please restart %1 to start JACK again. JACK foi encerrado. %1 requer JACK para correr. Reinicie %1 para iniciar JACK novamente. No sound card is available in your system. CoreAudio input AudioHardwareGetProperty call failed. Nenhuma placa de som está disponível em seu sistema. A entrada do CoreAudio falhou na chamada AudioHardwareGetProperty. No sound card is available in the system. CoreAudio output AudioHardwareGetProperty call failed. Nenhuma placa de som está disponível em seu sistema. A saída do CoreAudio falhou na chamada AudioHardwareGetProperty. The currently selected audio device is no longer present. Please check your audio device. O dispositivo de áudio selecionado não está mais presente. Verifique seu dispositivo de áudio. The audio input device is no longer available. Please check if your input device is connected correctly. O dispositivo de entrada de áudio não está mais disponível. Verifique se seu dispositivo de entrada está corretamente ligado. The sample rate on the current input device isn't %1 Hz and is therefore incompatible. Please select another device or try setting the sample rate to %1 Hz manually via Audio-MIDI-Setup (in Applications->Utilities). A taxa de amostragem no dispositivo de entrada atual não é %1 Hz e, portanto, é incompatível. Selecione outro dispositivo ou tente definir manualmente a taxa de amostragem para %1 Hz via Configuração de Áudio e MIDI (em Aplicativos->Utilitários). The audio output device is no longer available. Please check if your output device is connected correctly. O dispositivo de saída de áudio não está mais disponível. Verifique se seu dispositivo de saída está corretamente ligaado. The sample rate on the current output device isn't %1 Hz and is therefore incompatible. Please select another device or try setting the sample rate to %1 Hz manually via Audio-MIDI-Setup (in Applications->Utilities). A taxa de amostragem no dispositivo de saída atual não é %1 Hz e, portanto, é incompatível. Selecione outro dispositivo ou tente definir manualmente a taxa de amostragem para %1 Hz via Configuração de Áudio e MIDI (em Aplicativos->Utilitários). The stream format on the current input device isn't compatible with this software. Please select another device. O formato do fluxo no dispositivo de entrada atual não é compatível com este software. Por favor, selecione outro dispositivo. The stream format on the current output device isn't compatible with %1. Please select another device. O formato do fluxo no dispositivo de saída atual não é compatível com %1. Por favor, selecione outro dispositivo. The buffer sizes of the current input and output audio device can't be set to a common value. Please select different input/output devices in your system settings. Os tamanhos de buffer do dispositivo de áudio de entrada e saída atual não podem ser definidos para um valor comum. Por favor, selecione outros dispositivos de entrada/saída nas suas configurações. CSoundBase Invalid device selection. Seleção de dispositivo inválida. The audio driver properties have changed to a state which is incompatible with this software. The selected audio device could not be used because of the following error: As propriedades do driver de áudio foram alteradas para um estado incompatível com este programa. O dispositivo de áudio selecionado não pôde ser usado devido ao seguinte erro: Please restart the software. Por favor reinicie o programa. Close Fechar The selected audio device could not be used because of the following error: O dispositivo de áudio selecionado não pôde ser usado devido ao seguinte erro: The previous driver will be selected. O driver seleccionado anteriormente será utilizado. The previously selected audio device is no longer available or the audio driver properties have changed to a state which is incompatible with this software. We now try to find a valid audio device. This new audio device might cause audio feedback. So, before connecting to a server, please check the audio device setting. O dispositivo de áudio seleccionado anteriormente deixou de estar disponível, ou as propriedades do driver de áudio foram alteradas para um estado incompatível com este software. Iremos tentar encontrar um dispositivo áudio válido. Este novo dispositivo de áudio poderá causar feedback de áudio. Antes de se ligar a um servidor, verifique a configuração do dispositivo de áudio. No usable Nenhum dispositivo de áudio (driver) audio device (driver) found. utilizável encontrado. In the following there is a list of all available drivers with the associated error message: De seguida verá uma lista de todos os drivers disponíveis com a mensagem de erro associada: Do you want to open the ASIO driver setups? Deseja abrir as configurações do driver ASIO? could not be started because of audio interface issues. não pôde ser iniciado devido a problemas na interface de áudio. Can't use the selected audio device because of the following error: %1 The previous driver will be selected. Não é possível usar o dispositivo de áudio selecionado devido ao seguinte erro: %1. O driver anterior será selecionado. The previously selected audio device is no longer available or the driver has changed to an incompatible state. We'll attempt to find a valid audio device, but this new audio device may cause feedback. Before connecting to a server, please check your audio device settings. O dispositivo de áudio selecionado anteriormente não está mais disponível ou o driver mudou para um estado incompatível. Tentaremos encontrar um dispositivo de áudio válido, mas esse novo dispositivo pode causar microfonia. Antes de ligar-se a um servidor, verifique suas definições de dispositivo de áudio. <b>%1 couldn't find a usable %2 audio device.</b><br><br> <b>%1 não encontrou um dispositivo de áudio %2 utilizável </b><br><br> You may be able to fix errors in the driver settings. Do you want to open these settings now? Você pode corrigir erros nas configurações do driver. Deseja abrir essas configurações agora? No usable %1 audio device found. Nenhum dispositivo de áudio %1 utilizável foi encontrado. These are all the available drivers with error messages: Estes são todos os drivers disponíveis com mensagens de erro: Do you want to open the ASIO driver setup to try changing your configuration to a working state? Deseja abrir a configuração do driver ASIO para tentar alterar sua configuração para um estado de funcionamento? Can't start %1. Please restart %1 and check/reconfigure your audio settings. Não é possível iniciar %1. Reinicie %1 e verifique/reconfigure suas definições de áudio. QCoreApplication %1, Version %2 %1, Versão %2 Internet Jam Session Software Programa de Jam Sessions pela Internet %1, Version %2 %1 is app name, %2 is version number %1, Versão %2 Released under the GNU General Public License version 2 or later (GPLv2) Lançado sob a Licença Pública Geral GNU versão 2 (GPLv2) This program is free software; you can redistribute it and/or modify it under Este programa é um software livre; você pode redistribuí-lo e/ou modificá-lo sob the terms of the GNU General Public License as published by the Free Software os termos da Licença Pública Geral GNU, conforme publicado pela Free Software Foundation; either version 2 of the License, or (at your option) any later version. Foundation, seja a versão 2 da Licença ou (a seu critério) qualquer versão posterior. There is NO WARRANTY, to the extent permitted by law. NÃO HÁ GARANTIA, até o limite permitido por lei. Using the following libraries, resources or code snippets: Utilizando as seguintes bibliotecas, recursos ou partes de código: Qt framework Framework Qt Opus Interactive Audio Codec No need to translate names. Opus Interactive Audio Codec Audio reverberation code by Perry R. Cook and Gary P. Scavone Código de reverberação de áudio por Perry R. Cook e Gary P. Scavone Some pixmaps are from the Open Clip Art Library (OCAL) Alguns pixmaps são da Open Clip Art Library (OCAL) Flag icons by Mark James Ícones de bandeiras por Mark James Copyright (C) 2005-2022 The Jamulus Development Team Copyright (C) 2005-2022 A Equipa de Desenvolvimento do Jamulus Released under the GNU General Public License (GPL) Lançado sob a Licença Pública Geral GNU (GPL) global A %1 upgrade is available: <a style='color:red;' href='https://jamulus.io/upgrade?progversion=%2'>go to details and downloads</a> Está disponível uma atualização %1: <a style='color:red' href=https://jamulus.io/upgrade?progversion=%2'>vá para detalhes e transferências</a> For more information use the "What's This" help (help menu, right mouse button or Shift+F1) Para mais informações, use "O que é isto" (menu Ajuda, botão direito do rato ou Shift + F1) jamulus-3.9.1+dfsg/src/translation/translation_de_DE.ts0000644000175000017500000103546314340334543022243 0ustar vimervimer CAboutDlg The Die software enables musicians to perform real-time jam sessions over the internet. Software ermöglicht Musikern über das Internet in Echtzeit zu jammen. server which collects the audio data from each Server, der die Audiodaten von allen There is a Es gibt einen client, mixes the audio data and sends the mix back to each client. Musikern sammelt, zusammen mischt und wieder an alle verbundenen Musikern zurück schickt. uses the following libraries, resources or code snippets: verwendet die folgenden Bibliotheken, Ressourcen oder Codeschnipsel: Qt cross-platform application framework Qt plattformübergreifender Anwendungsrahmen Audio reverberation code by Perry R. Cook and Gary P. Scavone Halleffekt von Perry R. Cook und Gary P. Scavone Some pixmaps are from the Einige Bilder sind von Country flag icons from Mark James Die Bilder der Länderflaggen sind von Mark James This app enables musicians to perform real-time jam sessions over the internet. Diese Software ermöglicht Musikern über das Internet in Echtzeit zu jammen. There is a server which collects the audio data from each client, mixes the audio data and sends the mix back to each client. Es gibt einen Server, der die Audiodaten von allen Musikern sammelt, zusammen mischt und wieder an alle verbundenen Musiker zurück schickt. This app uses the following libraries, resources or code snippets: Diese Applikation verwendet die folgenden Bibliotheken, Ressourcen oder Codeschnipsel: Country flag icons by Mark James Die Bilder der Länderflaggen sind von Mark James For details on the contributions check out the Die Details über die Codebeiträge findet man in der Flag icons by Mark James Die Bilder der Länderflaggen sind von Mark James Some sound samples are from Einige Audio samples sind von For details on the contributions check out the %1 Details über Codebeiträge findet man in der %1 Github Contributors list Github Liste der Mitwirkenden Spanish Spanisch French Französisch Portuguese Portugiesisch Dutch Holländisch Italian Italienisch German Deutsch Polish Polnisch Swedish Schwedisch Korean Koreanisch Slovak Slowakisch Simplified Chinese Vereinfachtes Chinesisch Norwegian Bokmål About %1 Über %1 About Über Released under the GNU General Public License (GPL) Unter der GNU General Public License (GPL) Under the GNU General Public License (GPL) Unter der GNU General Public License (GPL) CAboutDlgBase About Über TextLabelVersion Copyright (C) 2005-2022 Volker Fischer and others Copyright (C) 2005-2022 Volker Fischer und andere Copyright (C) 2005-2022 The Jamulus Development Team Copyright (C) 2005-2022 beim Jamulus Entwicklungs Team A&bout Ü&ber &Libraries Bib&liotheken &Contributors &Mitwirkende &Translation Überse&tzung &OK CAnalyzerConsole Analyzer Console Analyzer Konsole Error Rate of Each Buffer Size Fehlerrate für jede Puffergröße CAudioMixerBoard Personal Mix at the Server Eigener Mix am Server When connected to a server, the controls here allow you to set your local mix without affecting what others hear from you. The title shows the server name and, when known, whether it is actively recording. Wenn man mit einem Server verbunden ist, dann kann man hier den eigenen Mix verstellen ohne dass man etwas daran verändert, was die anderen von mir hören. Der Titel zeigt den Servernamen an und falls bekannt den Aufnahmestatus des Servers. Server T R Y I N G T O C O N N E C T V E R B I N D U N G S A U F B A U RECORDING ACTIVE AUFNAHME AKTIV Personal Mix at: %1 Eigener Mix am Server: %1 CChannelFader Channel Level Kanalpegel Displays the pre-fader audio level of this channel. All connected clients at the server will be assigned an audio level, the same value for each client. Zeigt den Audiopegel vor dem Lautstärkeregler des Kanals. Allen verbundenen Musikern am Server wird ein Audiopegel zugewiesen. Input level of the current audio channel at the server Eingangspegel des aktuellen Musikers am Server Mixer Fader Kanalregler Adjusts the audio level of this channel. All connected clients at the server will be assigned an audio fader at each client, adjusting the local mix. Regelt die Lautstärke des Kanals. Für alle Musiker, die gerade am Server verbunden sind, wird ein Lautstärkeregler angezeigt. Damit kann man seinen eigenen lokalen Mix erstellen. Local mix level setting of the current audio channel at the server Lokale Mixerpegeleinstellung des aktuellen Kanals am Server Status Indicator Statusanzeige Shows a status indication about the client which is assigned to this channel. Supported indicators are: Zeigt den Status über den Musiker, der dem Kanal zugewiesen ist. Unterstützte Indikatoren sind: Speaker with cancellation stroke: Indicates that the other client has muted you. Durchgestrichener Lautsprecher: Zeigt an, dass der andere Musiker dich stummgeschaltet hat. Status indicator label Statusanzeige Panning Pan Sets the panning position from Left to Right of the channel. Works only in stereo or preferably mono in/stereo out mode. Legt die Pan-Position von Links nach Rechts fest. Der Pan funktioniert nur im Stereo oder Mono-In/Stereo-Out Modus. Local panning position of the current audio channel at the server Lokale Pan-Position von dem aktuellen Audiokanal am Server With the Mute checkbox, the audio channel can be muted. Mit dem Mute-Schalter kann man den Kanal stumm schalten. Mute button Mute Schalter With the Solo checkbox, the audio channel can be set to solo which means that all other channels except of the current channel are muted. It is possible to set more than one channel to solo. Bei aktiviertem Solo Status hört man nur diesen Kanal. Alle anderen Kanäle sind stumm geschaltet. Es ist möglich mehrere Kanäle auf Solo zu stellen. Dann hört man nur die Kanäle, die auf Solo gestellt wurden. Solo button Solo Schalter Fader Tag Kanalbeschriftung The fader tag identifies the connected client. The tag name, the picture of your instrument and a flag of your country can be set in the main window. Mit der Kanalbeschriftung wird der verbundene Teilnehmen identifiziert. Der Name, ein Bild des Instruments und eine Flagge des eigenen Landes kann im eigenen Profil ausgewählt werden. Grp Grp Displays the pre-fader audio level of this channel. All clients connected to the server will be assigned an audio level, the same value for every client. Zeigt den Audiopegel vor dem Lautstärkeregler des Kanals. Allen verbundenen Musikern am Server wird ein Audiopegel zugewiesen. &No grouping &Keine Gruppierung Assign to group Zuweisung zur Gruppe Adjusts the audio level of this channel. All clients connected to the server will be assigned an audio fader, displayed at each client, to adjust the local mix. Regelt die Lautstärke des Kanals. Für alle Musiker, die gerade am Server verbunden sind, wird ein Lautstärkeregler angezeigt. Damit kann man seinen eigenen lokalen Mix erstellen. Speaker with cancellation stroke: Indicates that another client has muted you. Durchgestrichener Lautsprecher: Zeigt an, dass der andere Musiker dich stummgeschaltet hat. Sets the pan from Left to Right of the channel. Works only in stereo or preferably mono in/stereo out mode. Legt die Pan-Position von Links nach Rechts fest. Der Pan funktioniert nur im Stereo oder Mono-In/Stereo-Out Modus. With the Solo checkbox, the audio channel can be set to solo which means that all other channels except the soloed channel are muted. It is possible to set more than one channel to solo. Bei aktiviertem Solo Status hört man nur diesen Kanal. Alle anderen Kanäle sind stumm geschaltet. Es ist möglich mehrere Kanäle auf Solo zu stellen. Dann hört man nur die Kanäle, die auf Solo gestellt wurden. Group Gruppe With the Grp checkbox, a group of audio channels can be defined. All channel faders in a group are moved in proportional synchronization if any one of the group faders are moved. Mit dem Grp-Knopf kann eine Gruppe von Kanälen definiert werden. Wenn man einen Lautstärkeregler einer Kanalgruppe verändert, dann werden alle anderen Regler der Gruppe gleichermaßen verändert. Group button Gruppenknopf The fader tag identifies the connected client. The tag name, a picture of your instrument and the flag of your country can be set in the main window. Mit der Kanalbeschriftung wird der verbundene Teilnehmen identifiziert. Der Name, ein Bild des Instruments und eine Flagge des eigenen Landes kann im eigenen Profil ausgewählt werden. Mixer channel instrument picture Mixerkanal Instrumentenbild Mixer channel label (fader tag) Mixerkanalbeschriftung Mixer channel country flag Mixerkanal Landesflagge PAN MUTE SOLO GRP GRP M S G G Alias/Name Instrument Instrument Location Standort Skill Level Spielstärke Alias Alias Beginner Anfänger The fader tag identifies the connected client. The tag name, a picture of your instrument and the flag of your location can be set in the main window. Durch die Kanalbeschriftung wird der verbundene Teilnehmer identifiziert. Der Name, ein Bild des Instruments und eine Flagge des eigenen Landes kann im eigenen Profil ausgewählt werden. Mixer channel country/region flag Mixerkanal Landes-/Regionsflagge Intermediate Mittlere Spielstärke Expert Experte Musician Profile Profil des Musikers Mute Mute Pan Pan Solo Solo CChatDlg Chat Window Chatfenster The chat window shows a history of all chat messages. Das Chatfenster zeigt den Verlauf aller Chatnachrichten. Chat history Chatverlauf Input Message Text Chatnachricht Eingabefeld Enter the chat message text in the edit box and press enter to send the message to the server which distributes the message to all connected clients. Your message will then show up in the chat window. Tippe die Chatnachricht in dieses Feld und drücke anschließend die Eingabetaste um die Nachricht an den Server zu schicken. Der Server verteilt die Nachricht anschließend an alle Musiker. Die eigene Nachricht wird dann im Chatfenster angezeigt. New chat text edit box Chatnachrichteneingabefeld Type a message here Nachricht eingeben &Edit B&earbeiten Cl&ear Chat History Lösch&en des Chatverlaufs &Close &Schließen Do you want to open the link '%1' in your browser? Willst Du den Link '%1' in Deinem Browser öffnen? Do you want to open the link Willst du den Link in an external browser? in einem externen Browser öffnen? CChatDlgBase Chat Chat &Send &Senden Cl&ear &Löschen &Close &Schließen CClientDlg Input Level Meter Eingangspegelanzeige The input level indicators show the input level of the two stereo channels of the current selected audio input. Die Eingangspegelanzeige zeigt den Pegel der beiden Stereokanäle der selektierten Audiohardware an. Make sure not to clip the input signal to avoid distortions of the audio signal. Man sollte darauf achten, dass das Signal nicht zu stark ausgesteuert ist, um Verzerrungen des Signal zu vermeiden. If the Wenn die software is connected and you play your instrument/sing in the microphone, the LED level meter should flicker. If this is not the case, you have probably selected the wrong input channel (e.g. line in instead of the microphone input) or set the input gain too low in the (Windows) audio mixer. Software verbunden ist und die spielst dein Instrument, dann sollte die Eingangspegelanzeige flackern. Wenn das nicht der Fall ist, dann ist wahrscheinlich der falsche Eingangskanal ausgewählt (z.B. der Line-In-Kanal anstatt des Mikrofonkanals) oder der Eingangsregler im (Windows) Systemmixer ist zu niedrig eingestellt. For a proper usage of the Um die software, you should not hear your singing/instrument in the loudspeaker or your headphone when the Software optimal zu nutzen, sollte man sein eigenes Instrument oder Gesang nicht im Lautsprecher oder Kopfhörer hören, wenn die software is not connected. This can be achieved by muting your input audio channel in the Playback mixer (not the Recording mixer!). Software nicht verbunden ist. Das kann man erreichen, indem man den Eingangskanal im Wiedergabemixer stumm schaltet. Input level meter Eingangspegelanzeige Simulates an analog LED level meter. Simuliert eine analoge LED-Signalpegelanzeige. Connect/Disconnect Button Verbinden-/Trennschalter Push this button to connect to a server. A dialog where you can select a server will open. If you are connected, pressing this button will end the session. Drücke diesen Knopf um sich mit dem Server zu verbinden. Es wird ein Fenster angezeigt, in dem man den Server auswählen kann. Wenn man gerade verbunden ist und den Knopf drückt, dann wird die Verbindung getrennt und die Session wird beendet. Connect and disconnect toggle button Schalter zum Verbinden und Trennen Clicking on this button changes the caption of the button from Connect to Disconnect, i.e., it implements a toggle functionality for connecting and disconnecting the Wenn man diesen Knopf drückt, dann wird die Beschriftung des Knopfes von Verbinden zu Trennen geändert, das heißt, dass er eine Umschaltfunktion hat zum Verbinden und Trennen der software. Software. Local Audio Input Fader Lokaler Eingangspegelregler Local audio input fader (left/right) Lokaler Eingangsregler Reverberation effect level setting Halleffekt Pegelregler Left channel selection for reverberation Auswahl linker Kanal für Halleffekt Right channel selection for reverberation Auswahl rechter Kanal für Halleffekt If this LED indicator turns red, you will not have much fun using the Wenn diese LED rot leuchtet, dann wirst du keinen Spaß haben mit der This shows the level of the two stereo channels for your audio input. Die Eingangspegelanzeige zeigt den Pegel der beiden Stereokanäle der selektierten Audiohardware an. If the application is connected to a server and you play your instrument/sing into the microphone, the VU meter should flicker. If this is not the case, you have probably selected the wrong input channel (e.g. 'line in' instead of the microphone input) or set the input gain too low in the (Windows) audio mixer. Wenn die Software verbunden ist und du spielst dein Instrument, dann sollte die Eingangspegelanzeige flackern. Wenn das nicht der Fall ist, dann ist wahrscheinlich der falsche Eingangskanal ausgewählt (z.B. der Line-In-Kanal anstatt des Mikrofonkanals) oder der Eingangsregler im (Windows) Systemmixer ist zu niedrig eingestellt. For proper usage of the application, you should not hear your singing/instrument through the loudspeaker or your headphone when the software is not connected. This can be achieved by muting your input audio channel in the Playback mixer (not the Recording mixer!). Um die Software optimal zu nutzen, sollte man sein eigenes Instrument oder Gesang nicht im Lautsprecher oder Kopfhörer hören, wenn die Software nicht verbunden ist. Das kann man erreichen, indem man den Eingangskanal im Wiedergabemixer stumm schaltet. Clicking on this button changes the caption of the button from Connect to Disconnect, i.e., it implements a toggle functionality for connecting and disconnecting the application. Wenn man diesen Knopf drückt, dann wird die Beschriftung des Knopfes von Verbinden zu Trennen geändert, das heißt, dass er eine Umschaltfunktion hat zum Verbinden und Trennen der Applikation. Controls the relative levels of the left and right local audio channels. For a mono signal it acts as a pan between the two channels. For example, if a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows Mit diesem Einstellregler kann der relative Pegel vom linken und rechten Eingangskanal verändert werden. Für ein Mono-Signal verhält sich der Regler wie ein Pan-Regler. Wenn, z.B., ein Mikrofon am rechten Kanal angeschlossen ist und das Instrument am linken Eingangskanal ist viel lauter als das Mikrofon, dann kann man den Lautstärkeunterschied mit diesem Regler kompensieren indem man den Regler in eine Richtung verschiebt, so dass über dem Regler Reverb effect Halleffektregler Reverb can be applied to one local mono audio channel or to both channels in stereo mode. The mono channel selection and the reverb level can be modified. For example, if a microphone signal is fed in to the right audio channel of the sound card and a reverb effect needs to be applied, set the channel selector to right and move the fader upwards until the desired reverb level is reached. Der Halleffekt kann auf einen selektierten Mono-Audiokanal oder auf beide Stereoaudiokanäle angewendet werden. Die Mono-Kanalselektion und die Hallstärke können eingestellt werden. Wenn z.B. ein Mikrofonsignal auf dem rechten Kanal anliegt und ein Halleffekt soll auf das Mikrofonsignal angewendet werden, dann muss die Hallkanalselektion auf rechts eingestellt werden und der Hallregler muss erhöht werden, bis die gewünschte Stärke des Halleffekts erreicht ist. Reverb effect level setting Halleffekt Pegelregler Reverb Channel Selection Halleffekt Kanalselektion With these radio buttons the audio input channel on which the reverb effect is applied can be chosen. Either the left or right input channel can be selected. Mit diesen Knöpfen kann ausgewählt werden, auf welches Eingangssignal der Halleffekt angewendet werden soll. Entweder der rechte oder linke Eingangskanal kann ausgewählt werden. Left channel selection for reverb Auswahl linker Kanal für Halleffekt Right channel selection for reverb Auswahl rechter Kanal für Halleffekt The Die Green Grün The delay is perfect for a jam session. Die Verzögerung it gering genug für das Jammen. Yellow Gelb Red Rot If this LED indicator turns red, you will not have much fun using %1. Wenn diese LED rot leuchtet, dann wirst du wenig Spaß mit %1 haben. Delay status LED indicator LED Stautuslampe für die Verzögerung Opens a dialog where you can select a server to connect to. If you are connected, pressing this button will end the session. Wenn man diesen Knopf drückt, dann wird die Beschriftung des Knopfes von Verbinden zu Trennen geändert, das heißt, dass er eine Umschaltfunktion hat zum Verbinden und Trennen der Software. Shows the current audio delay status: Die Status-LED für die Verzögerung zeigt eine Bewertung der Gesamtverzögerung des Audiosignals: The delay is perfect for a jam session Die Verzögerung ist gering genug für das Jammen. A session is still possible but it may be harder to play. Man kann noch spielen aber es wird schwieriger Lieder mit hohem Tempo zu spielen. The delay is too large for jamming. Die Verzögerung ist zu hoch zum Jammen. If this LED indicator turns red, you will not have much fun using the application. Wenn diese LED rot leuchtet, dann wirst du keinen Spaß haben mit der Software. The buffers status LED shows the current audio/streaming status. If the light is red, the audio stream is interrupted. This is caused by one of the following problems: Die Status-LED für den Netzwerkpuffer zeigt den aktuellen Status des Netzwerkstroms. Wenn die LED grün ist, dann gibt es keine Pufferprobleme. Wenn die LED rot anzeigt, dann ist der Netzwerkstrom kurz unterbrochen. Dies kann folgende Ursachen haben: The sound card's buffer delay (buffer size) is too small (see Settings window). Der Soundkartenpuffer ist zu klein eingestellt. The upload or download stream rate is too high for your internet bandwidth. Die Upload-Rate der Internetverbindung ist zu klein für den Netzwerkdatenstrom. Buffers status LED indicator LED Statuslampe für den Netzwerkpuffer Current Connection Status Parameter Aktueller Verbindungsstatus Parameter The Ping Time is the time required for the audio stream to travel from the client to the server and back again. This delay is introduced by the network and should be about 20-30 ms. If this delay is higher than about 50 ms, your distance to the server is too large or your internet connection is not sufficient. Als Ping wird die Zeit bezeichnet, die der Audiodatenstrom benötigt, um vom Client zum Server und wieder zurück zu kommen. Diese Verzögerung wird durch das Netzwerk hervorgerufen und sollte um 20-30 ms betragen. Wenn dieser Wert größer ist als 50ms, ist entweder der Abstand zum Server zu groß oder die Internetverbindung nicht ausreichend. Overall Delay is calculated from the current Ping Time and the delay introduced by the current buffer settings. Die Gesamtverzögerung setzt sich aus der Ping-Zeit und der Verzögerung, die durch die aktuellen Puffereinstellungen verursacht wird zusammen. C&onnect &Verbinden software upgrade available Softwareupdate verfügbar &File &Datei &View &Ansicht &Connection Setup... &Verbinden... My &Profile... Mein &Profil... C&hat... C&hat... &Settings... &Einstellungen... &Analyzer Console... &Analyzer Konsole... Use &Two Rows Mixer Panel Benu&tze zwei Zeilen für das Mischpult Clear &All Stored Solo and Mute Settings &Lösche alle gespeicherten Solo- und Mute-Einstellungen &Settings Ein&stellungen Connect Verbinden Settings Einstellungen Chat Chat Enable feedback detection Aktiviere Feedback-Erkennung Audio feedback or loud signal detected. We muted your channel and activated 'Mute Myself'. Please solve the feedback issue first and unmute yourself afterwards. Audio-Feedback oder lautes Signal erkannt. Wir haben Deinen Kanal stummgeschaltet und die Funktion 'Stummschalten' aktiviert. Bitte behebe zunächst die Ursache des Feedback-Problems, bevor Du die Stummschaltung wieder rückgängig machst. Your sound card is not working correctly. Please open the settings dialog and check the device selection and the driver settings. Die Soundkarte funktioniert nicht ordnungsgemäß. Bitte überprüfe die Soundkartenauswahl und die Einstellungen der Soundkarte. Ok Ok E&xit &Beenden &Edit B&earbeiten &Sort Users by Name &Sortiere Kanäle nach Namen None Keine Center Mitte With the audio fader, the relative levels of the left and right local audio channels can be changed. For a mono signal it acts like a panning between the two channels. If, e.g., a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows Mit diesem Einstellregler kann der relative Pegel vom linken und rechten Eingangskanal verändert werden. Für ein Mono-Signal verhält sich der Regler wie ein Pan-Regler. Wenn, z.B., ein Mikrofon am rechten Kanal angeschlossen ist und das Instrument am linken Eingangskanal ist viel lauter als das Mikrofon, dann kann man den Lautstärkeunterschied mit diesem Regler kompensieren indem man den Regler in eine Richtung verschiebt, so dass über dem Regler , where angezeigt wird, wobei is the current attenuation indicator. die aktuelle Dämpfung anzeigt. Reverberation Level Halleffektregler A reverberation effect can be applied to one local mono audio channel or to both channels in stereo mode. The mono channel selection and the reverberation level can be modified. If, e.g., the microphone signal is fed into the right audio channel of the sound card and a reverberation effect shall be applied, set the channel selector to right and move the fader upwards until the desired reverberation level is reached. Der Halleffekt kann auf einen selektierten Mono-Audiokanal oder auf beide Stereoaudiokanäle angewendet werden. Die Mono-Kanalselektion und die Hallstärke können eingestellt werden. Wenn z.B. ein Mikrofonsignal auf dem rechten Kanal anliegt und ein Halleffekt soll auf das Mikrofonsignal angewendet werden, dann muss die Hallkanalselektion auf rechts eingestellt werden und der Hallregler muss erhöht werden, bis die gewünschte Stärke des Halleffekts erreicht ist. The reverberation effect requires significant CPU so it should only be used on fast PCs. If the reverberation level fader is set to minimum (which is the default setting), the reverberation effect is switched off and does not cause any additional CPU usage. Die Berechnung des Halleffekts benötigt etwas Rechenleistung, so dass der Halleffekt nur bei schnellen Computern angewendet werden sollte. Wenn der Hallregler ganz nach unten gezogen ist, dann ist der Halleffekt ausgeschaltet und verbraucht keine Rechenleistung mehr. Reverberation Channel Selection Halleffekt Kanalselektion With these radio buttons the audio input channel on which the reverberation effect is applied can be chosen. Either the left or right input channel can be selected. Mit diesen Knöpfen kann ausgewählt werden, auf welches Eingangssignal der Halleffekt angewendet werden soll. Entweder der rechte oder linke Eingangskanal kann ausgewählt werden. Delay Status LED Status LED für die Verzögerung The delay status LED indicator shows the current audio delay status. If the light is green, the delay is perfect for a jam session. If the light is yellow, a session is still possible but it may be harder to play. If the light is red, the delay is too large for jamming. Die Status-LED für die Verzögerung zeigt eine Bewertung der Gesamtverzögerung des Audiosignals. Wenn die LED grün leuchtet, dann ist die Verzögerung gering genug für das Jammen. Wenn die LED gelb anzeigt kann man noch spielen aber es wird schwieriger Lieder mit hohem Tempo zu spielen. Wenn die LED rot anzeigt, dann ist die Verzögerung zu hoch zum Jammen. Buffers Status LED Status LED für den Netzwerkpuffer The buffers status LED indicator shows the current audio/streaming status. If the light is green, there are no buffer overruns/underruns and the audio stream is not interrupted. If the light is red, the audio stream is interrupted caused by one of the following problems: Die Status-LED für den Netzwerkpuffer zeigt den aktuellen Status des Netzwerkstroms. Wenn die LED grün ist, dann gibt es keine Pufferprobleme. Wenn die LED rot anzeigt, dann ist der Netzwerkstrom kurz unterbrochen. Dies kann folgende Ursachen haben: The network jitter buffer is not large enough for the current network/audio interface jitter. Der Netzwerkpuffer ist nicht groß genug eingestellt für die aktuellen Netzwerkbedingungen. The sound card buffer delay (buffer size) is set to too small a value. Der Soundkartenpuffer ist zu klein eingestellt. The upload or download stream rate is too high for the current available internet bandwidth. Die Upload-Rate der Internetverbindung ist zu klein für den Netzwerkdatenstrom. The CPU of the client or server is at 100%. Die CPU des Computers ist voll ausgelastet. If this LED indicator turns red, the audio stream is interrupted. Wenn diese LED rot leuchtet, ist der Audio-Stream unterbrochen. Current Connection Status Aktueller Verbindungsstatus &Load Mixer Channels Setup... &Laden der Konfiguration der Mixerkanäle... &Save Mixer Channels Setup... &Speichern der Konfiguration der Mixerkanäle... Sett&ings E&instellungen Audio/Network &Settings... Audio/Netzwerk-&Einstellungen... A&dvanced Settings... E&rweiterte Einstellungen... N&o User Sorting Keine Kanals&ortierung Local Jitter Buffer Status LED Lokaler Jitter Buffer Status LED The local jitter buffer status LED shows the current audio/streaming status. If the light is red, the audio stream is interrupted. This is caused by one of the following problems: Die Lokale Jitter Buffer Status LED zeigt den aktuellen Audio/Streaming Status. Rotes Licht bedeutet, dass der Audio-Datenstrom unterbrochen ist. Das wird durch folgende Problemen verursacht: Local Jitter Buffer status LED indicator Lokaler Jitter Buffer Status LED Indikator If this LED indicator turns red, you will not have much fun using the %1 software. Wenn diese LED rot leuchtet, dann wirst du wenig Spaß mit der %1 Software haben. O&wn Fader First Eigener &Kanal zuerst Sort Users by &Name Sortiere die Kanäle nach dem &Namen Sort Users by &Instrument Sortiere die Kanäle nach dem &Instrument Sort Users by &Group Sortiere die Kanäle nach der &Gruppe Sort Users by &City Sortiere die Kanäle nach der &Stadt %1 Directory %1 Verzeichnisserver Clear &All Stored Solo Settings &Lösche alle gespeicherten Solo-Einstellungen Set All Faders to New Client &Level Setze alle Lautstärken auf den &Pegel für neuen Teilnehmer Auto-Adjust all &Faders Automatisches Einpegeln (aller &Fader) Directory Server Verzeichnisserver Select Channel Setup File Auswählen der Datei für die Konfiguration der Mixerkanäle user Musiker users Musiker The soundcard device does not work correctly. Please check the device selection and the driver settings. Die Soundkarte funktioniert nicht ordnungsgemäß. Bitte überprüfe die Soundkartenauswahl und die Einstellungen der Soundkarte. &Disconnect &Trennen CClientDlgBase Delay Verzögerung Buffers Puffer Input Eingang L R Jitter Jitter Ping Ping ms ms &Mute Myself Stu&mmschalten &Settings Ein&stellungen &Chat &Chat C&onnect &Verbinden Center Mitte Reverb Halleffekt Left Links Right Rechts MUTED (Other people won't hear you) Stumm (Die anderen hören dich nicht) Set up your audio, connect to a server and start jamming! Richte deine Soundkarte ein, verbinde Dich mit einem Server und beginne zu jammen! Update check Update check MUTED (You are not sending any audio to the server) Stumm (Es wird kein Ton zum Server gesendet) CClientSettingsDlg Jitter Buffer Size Netzwerkpuffergröße The jitter buffer compensates for network and sound card timing jitters. The size of this jitter buffer has therefore influence on the quality of the audio stream (how many dropouts occur) and the overall delay (the longer the buffer, the higher the delay). Der Netzwerkpuffer kompensiert die Netzwerk- und Soundkarten-Timing-Schwankungen. Die Größe des Netzwerkpuffers hat Auswirkungen auf die Qualität des Audiosignals (wie viele Aussetzer auftreten) und die Gesamtverzögerung (je länger der Puffer, desto größer ist die Verzögerung). The jitter buffer size can be manually chosen for the local client and the remote server. For the local jitter buffer, dropouts in the audio stream are indicated by the light below the jitter buffer size faders. If the light turns to red, a buffer overrun/underrun took place and the audio stream is interrupted. Die Netzwerkpuffergröße kann manuell verstellt werden, jeweils getrennt für die Applikation und den Server. Für den lokalen Netzwerkpuffer werden die Aussetzer durch die LED-Anzeige unter den Reglern angezeigt. Wenn die Lampe rot anzeigt, dann hat ein Pufferüberlauf oder ein Leerlauf des Puffers stattgefunden und der Audiodatenstrom wurde kurz unterbrochen. The jitter buffer setting is therefore a trade-off between audio quality and overall delay. Die Netzwerkpuffergröße ist deshalb ein Kompromiss zwischen Audioqualität und Gesamtverzögerung. An auto setting of the jitter buffer size setting is available. If the check Auto is enabled, the jitter buffers of the local client and the remote server are set automatically based on measurements of the network and sound card timing jitter. If the Auto check is enabled, the jitter buffer size faders are disabled (they cannot be moved with the mouse). Die Netzwerkpuffergröße kann automatisch eingestellt werden. Wenn die Automatik aktiviert ist, dann werden die Netzwerkpuffer der Applikation und des Servers getrennt basierend auf Messungen der Netzwerkschwankungen eingestellt. Wenn die Automatik aktiviert ist, dann sind die beiden Regler gesperrt für die manuelle Verstellung (sie können nicht mit der Maus verändert werden). If the auto setting of the jitter buffer is enabled, the network buffers of the local client and the remote server are set to a conservative value to minimize the audio dropout probability. To tweak the audio delay/latency it is recommended to disable the auto setting functionality and to lower the jitter buffer size manually by using the sliders until your personal acceptable limit of the amount of dropouts is reached. The LED indicator will visualize the audio dropouts of the local jitter buffer with a red light. Wenn die Automatik zum Einstellen der Netzwerkpuffer aktiviert ist, dann werden die Netzwerkpuffer der Applikation und des entfernten Servers auf einen konservativen Wert eingestellt, um eine möglichst gute Audioqualität zu garantieren. Um die Gesamtverzögerung zu optimieren, bietet es sich an, die Automatik zu deaktivieren und die Netzwerkpuffer etwas kleiner einzustellen. Die Werte sollte man so weit reduzieren, bis die Audioqualität gerade noch der persönlichen Akzeptanz entspricht. Die LED-Anzeige hilft dabei die Audioaussetzer verursacht durch den lokalen Netzwerkpuffer zu visualisieren (wenn die LED rot leuchtet). Local jitter buffer slider control Lokale Netzwerkpuffergröße Schieberegler Server jitter buffer slider control Server Netzwerkpuffergröße Schieberegler Auto jitter buffer switch Automatik für die Netzwerkpuffergröße aktivieren Jitter buffer status LED indicator Netzwerkpuffer Status LED Sound Card Device Soundkartengerät The ASIO driver (sound card) can be selected using Der ASIO-Treiber (Soundkarte) kann ausgewählt werden mit der under the Windows operating system. Under MacOS/Linux, no sound card selection is possible. If the selected ASIO driver is not valid an error message is shown and the previous valid driver is selected. Software unter Windows. Unter MacOS und Linux kann man die Soundkarte nicht auswählen. Wenn der selektierte ASIO-Treiber nicht gültig ist, dann wird eine Fehlermeldung angezeigt und der vorherige gültige Treiber wird wieder ausgewählt. If the driver is selected during an active connection, the connection is stopped, the driver is changed and the connection is started again automatically. Wenn der Treiber während eine aktiven Verbindung ausgewählt wird, dann wird die Verbindung gestoppt, der neue Treiber ausgewählt und anschließend wird die Verbindung automatisch wiederhergestellt. Sound card device selector combo box Soundkarten Auswahlbox If the ASIO4ALL driver is used, please note that this driver usually introduces approx. 10-30 ms of additional audio delay. Using a sound card with a native ASIO driver is therefore recommended. Falls der ASIO4All-Treiber verwendet wird, kann es sein, dass dieser Treiber zusätzliche 10-30 ms Verzögerung hinzufügt. Aus diesem Grund sollte man bevorzugt einen nativen ASIO-Treiber der Soundkarte verwenden, der mit dem Produkt mitgeliefert wurde. If you are using the kX ASIO driver, make sure to connect the ASIO inputs in the kX DSP settings panel. Falls der kx ASIO-Treiber verwendet wird, dann muss man darauf achten, dass die ASIO-Eingänge im kx DSP-Einstellungsfenster verbunden sind. Sound Card Channel Mapping Soundkarten Kanalzuweisung If the selected sound card device offers more than one input or output channel, the Input Channel Mapping and Output Channel Mapping settings are visible. Falls die ausgewählte Soundkarte mehr als zwei Eingangs- oder Ausgangskanäle unterstützt, dann werden die Steuerelemente für die Kanalzuweisung angezeigt. For each Für jeden input/output channel (Left and Right channel) a different actual sound card channel can be selected. Eingangs-/Ausgangskanal (linker und rechter Kanal) kann ein beliebiger Soundkartenkanal zugewiesen werden. Left input channel selection combo box Linker Eingang Kanalauswahlbox Right input channel selection combo box Rechter Eingang Kanalauswahlbox Left output channel selection combo box Linker Ausgang Kanalauswahlbox Right output channel selection combo box Rechter Ausgang Kanalauswahlbox Enable Small Network Buffers Aktiviere kleine Netzwerkpuffer If enabled, the support for very small network audio packets is activated. Very small network packets are only actually used if the sound card buffer delay is smaller than Falls aktiviert wird die Unterstützung für sehr kleine Netzwerk-Audiopakete aktiviert. Sehr kleine Netzwerkpakete werden nur dann verwendet, wenn der Soundkartenpuffer kleiner als samples. The smaller the network buffers, the lower the audio latency. But at the same time the network load increases and the probability of audio dropouts also increases. Samples ist. Je kleiner die Netzwerkpakete sind, desto kleiner ist auch die Audioverzögerung. Aber gleichzeitig wird dadurch die Netzwerklast erhöht und die Wahrscheinlichkeit für Audioaussetzer erhöht sich dadurch auch. Enable small network buffers check box Aktiviere kleine Netzwerkpuffer Schalter Sound Card Buffer Delay Soundkarten Puffergröße Some sound card drivers do not allow the buffer delay to be changed from within the application. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. On Windows, press the ASIO Device Settings button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Einige Audiotreiber verhindern das Umstellen der Puffer-Verzögerung aus einer Anwendung heraus. In diesem Falle wird die Einstellung der Puffer-Verzögerung in Jamulus deaktiviert und sollte daher im Treiber des Audiointerfaces selbst geändert werden. Unter Windows kann man diese Einstellung über den Knopf "ASIO-Geräte-Einstellungen" erreichen. Unter Linux sollte man das Jack-Configuration-Tool verwenden, um die Puffergrösse zu ändern. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within the software. On Windows, press the ASIO Device Settings button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Wenn die Puffer-Verzögerungs-Einstellungen deaktiviert sind, verbietet der Audio-Treiber die entsprechenden Änderungen aus der Anwendung heraus. Um die Treiber-Einstellungen unter Windows zu öffnen, betätige den Button "ASIO-Geräte-Einstellungen". Um die Puffergröße unter Linux zu ändern, benutze das "Jack Configuration Tool". Sound card driver settings Soundkarten Einstellungen This opens the driver settings of your sound card. Some drivers allow you to change buffer settings, others like ASIO4ALL let you choose input or outputs of your device(s). More information can be found on jamulus.io. Öffnet die Treiber-Einstellungen der Soundkarte. Einige Treiber erlauben die Änderung der Puffer-Einstellungen, andere wie z.B. ASIO4ALL ermöglichen es Dir, die Audio Ein- und Ausgänge Deiner angeschlossenen Audiogeräte auszuwählen. Weitere Informationen hierzu findest Du auf jamulus.io. Opens the driver settings. Note: Öffnet die Treibereinstellungen. Beachte: currently only supports devices supporting a sample rate of unterstützt aktuell nur Geräte, die eine Sample Rate von Hz. You will not be able to select a driver/device which doesn't. For more help see jamulus.io. Hz erlauben. Es ist ist nicht möglich, einen Treiber / ein Gerät auszuwählen, welches dies nicht unterstützt. Für weitere Hilfe siehe jamulus.io. The ASIO driver (sound card) can be selected using %1 under the Windows operating system. Under macOS/Linux, no sound card selection is possible. If the selected ASIO driver is not valid an error message is shown and the previous valid driver is selected. Der ASIO Treiber (Soundkarte) kann %1 unter Windows ausgewählt werden. Unter macOS/Linux ist keine Auswahl der Soundkarte möglich. Wenn der ausgewählte ASIO Treiber nicht kompatibel ist, wird eine Fehlermeldung angezeigt und der vorher ausgewählte passende Treiber eingestellt. For each %1 input/output channel (left and right channel) a different actual sound card channel can be selected. Für jeden %1 Eingabe/Ausgabekanal (Linker und Rechter Kanal) können unterschiedliche Soundkarten-Kanäle ausgewählt werden. Enables support for very small network audio packets. These network packets are only actually used if the sound card buffer delay is smaller than %1 samples. The smaller the network buffers, the lower the audio latency. But at the same time the network load and the probability of audio dropouts or sound artifacts increases. Aktiviert die Unterstützung für sehr kleine Netzwerk-Audio-Pakete. Diese Netzwerk Pakete werden nur benutzt wenn die Soundkarten Pufferverzögerung kleiner als %1 Samples ist. Je kleiner die Netzwerk Puffer, desto geringer die Audio-Latenz. Gleichzeitig steigt aber die Netzwerk-Belastung und die Wahrscheinlichkeit von Audio-Aussetzern oder Sound-Artefakten. Some sound card drivers do not allow the buffer delay to be changed from within %1. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. On Windows, use the ASIO Device Settings button to open the driver settings panel. On Linux, use the JACK configuration tool to change the buffer size. Einige Soundkarten Treiber erlauben keine Änderung der Puffergröße aus %1 heraus. In diesem Fall ist die Puffergrößeneinstellung deaktiviert und die Puffergröße muss im Soundkarten Treiber eingestellt werden. Benutze unter Windows den ASIO Geräteeinstellungsknopf um die Treibereinstellungen anzuzeigen. Benutze unter Linux das JACK-Konfigurationstool um die Puffergröße zu ändern. If no buffer size is selected and all settings are disabled, this means an unsupported buffer size is in use by the driver. %1 will still work with this setting but may have restricted performance. Wenn keine Puffergröße ausgewählt ist und alle Einstellungen deaktiviert sind bedeutet das, dass eine nicht unterstützte Puffergröße vom Treiber verwendet wird. %1 wird nun eventuell nur eingeschränkt funktionieren. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within %1. On Windows, press the ASIO Device Settings button to open the driver settings panel. On Linux, use the JACK configuration tool to change the buffer size. Wenn die Puffer Verzögerungseinstellungen deaktiviert sind, verbietet der Audio-Treiber eine Veränderung aus %1 heraus. Unter Windows, klicke auf den Button für die ASIO-Geräte-Einstellungen, um das Treibereinstellungspanel anzuzeigen. Unter Linux benutze das JACK-Konfigurationstool um die Puffergröße zu ändern. This opens the driver settings of your sound card. Some drivers allow you to change buffer settings, others like ASIO4ALL lets you choose input or outputs of your device(s). More information can be found on jamulus.io. Öffnet die Treibereinstellungen Deiner Soundkarte. Einige Treiber erlauben Dir die Puffer-Einstellungen zu ändern, andere wie ASIO4ALL lassen Dich die Ein- oder Ausgänge deiner Geräte auswählen. Weitere Infos findest du auf jamulus.io. Opens the driver settings. Note: %1 currently only supports devices with a sample rate of %2 Hz. You will not be able to select a driver/device which doesn't. For more help see jamulus.io. Öffnet die Treiber Einstellungen. Achtung: %1 unterstützt aktuell nur Geräte mit einer Samplerate von %2 Hz. Andere Geräte lassen sich nicht auswählen. Weitere Infos findest du auf jamulus.io. ASIO Device Settings push button ASIO-Geräte-Einstellungs-Knopf Select the meter style to be used for the level meters. The Bar (narrow) and LEDs (round, small) options only apply to the mixerboard. When Bar (narrow) is selected, the input meters are set to Bar (wide). When LEDs (round, small) is selected, the input meters are set to LEDs (round, big). The remaining options apply to the mixerboard and input meters. Wähle den Stil aus, der für die Pegel-Messer benutzt wird. Die Stile "Balken (schmal)" und "LEDs (rund, klein)" beziehen sich nur auf den Mixerbereich. Die Auswahl des Stils "Balken (schmal)" sorgt dafür, dass die Eingangspegelanzeigen dennoch mit breiten Balken dargestellt werden. Wenn der Stil "LEDs (rund, klein)" ausgwählt ist, entsprechen die Eingangspegelanzeigen dem Stil "LEDs (rund, groß)". Die anderen Optionen beziehen sich sowohl auf den Mixer als auch auf die Eingangspegelanzeigen. Language Sprache Select the language to be used for the user interface. Wähle die Sprache der Benutzeroberfläche aus. Language combo box Sprache Combo-Box The buffer delay setting is a fundamental setting of %1. This setting has an influence on many connection properties. Die Puffer Verzögerungs-/Größeneinstellung ist eine fundamentale Einstellung von %1. Diese Einstellung hat Einfluss auf viele Verbindungsparameter. Controls the relative levels of the left and right local audio channels. For a mono signal it acts as a pan between the two channels. For example, if a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows %1, where %2 is the current attenuation indicator. Mit diesem Regler kann der relative Pegel vom linken und rechten Eingangskanal verändert werden. Für ein Mono-Signal verhält er sich wie ein Pan-Regler. Wenn z.B. ein Mikrofon am rechten Kanal angeschlossen ist und das Instrument am linken Eingangskanal viel lauter als das Mikrofon ist, dann bewege den Audio-Regler in die Richtung, in der das Label über dem Kanal %1 anzeigt; %2 ist der aktuelle Dämpfungsindikator. Audio Device Audiogerät Under the Windows operating system the ASIO driver (sound card) can be selected using %1. If the selected ASIO driver is not valid an error message is shown and the previous valid driver is selected. Under macOS the input and output hardware can be selected. Unter Windows kann der ASIO-Treiber (Soundkarte) mit %1 ausgewählt werden. Wenn der ausgewählte ASIO-Treiber nicht kompatibel ist, wird eine Fehlermeldung angezeigt und der vorherige kompatible Treiber ausgewählt. Unter macOS kann die Eingangs- und Ausgangshardware ausgewählt werden. Three buffer sizes can be selected Drei Puffergrößen werden unterstützt 64 samples: Provides the lowest latency but does not work with all sound cards. 64 Samples: Führt zur geringsten Verzögerung, funktioniert aber nicht mit allen Soundkarten. 256 samples: Should only be used when 64 or 128 samples is causing issues. 256 Samples: Diese Einstellung sollte nur dann verwendet werden, wenn 64 oder 128 Samples schlechte Ergebnisse liefern. Some sound card drivers do not allow the buffer delay to be changed from within %1. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. Use the appropriate tool for the interface in use to adjust this buffer size. For example, if using ASIO, use the "ASIO Device Settings" button to open the driver settings panel or if using JACK, use a tool such as QjackCtl to adjust the buffer size. Other interfaces, such as Pipewire, would require their appropriate tool being used. Please refer to the interface manual. Manche Soundkartentreiber erlauben es nicht, die Puffergröße innerhalb von %1 zu ändern. In diesem Fall ist die Einstellung für die Puffergröße deaktiviert und muss über den Soundkartentreiber geändert werden. Verwende das entsprechende Tool für deine Schnittstelle um die Puffergröße anzupassen. Wenn du z. B. ASIO nutzt, verwenden die Schaltfläche "ASIO-Geräteeinstellungen", um das Bedienfeld mit den Treibereinstellungen zu öffnen, oder wenn du JACK nutzt, verwende ein Tool wie QjackCtl, um die Puffergröße anzupassen. Für andere Schnittstellen, wie z. B. Pipewire, muss das entsprechende Tool verwendet werden. Bitte lese dazu das Handbuch der Schnittstelle. If no buffer size is selected and all settings are disabled, this means a buffer size in use by the driver which does not match the values. %1 will still work with this setting but may have restricted performance. Wenn keine Puffergröße ausgewählt ist und alle Einstellungen deaktiviert sind, bedeutet das, dass eine Puffergröße vom Treiber verwendet wird, die nicht den Standardwerten entspricht. %1 wird zwar trotzdem funktionieren, aber eventuell eine schlechtere Leistung bringen. The actual buffer delay has influence on the connection, the current upload rate and the overall delay. The lower the buffer size, the higher the probability of a red light in the status indicator (drop outs) and the higher the upload rate and the lower the overall delay. Die Puffergröße hat einen Einfluss auf den Verbindungsstatus, die aktuelle Upload-Rate und die Gesamtverzögerung. Je kleiner der Puffer, desto größer ist die Wahrscheinlichkeit für das Auftreten einer rot leuchtenden LED (was Audioaussetzer anzeigt), eine höhere Upload-Rate und eine niedrigere Gesamtverzögerung. Meter Style Pegel-Messer-Stil Select the meter style to be used for the level meters. The Narrow Bar and Small LEDs options only apply to the mixerboard. When Narrow Bar is selected, the input meters are set to Bar. When Small LEDs is selected, the input meters are set to Round LEDs. The remaining options apply to the mixerboard and input meters. Wähle den Pegel-Messer-Stil aus, der für die Schieberegler genutzt wird. Die schmalen Balken und kleinen LEDs werden nur im Mixer angezeigt. Wenn die schmalen Balken ausgewählt sind, sind die Eingangspegelanzeigen Balken. Wenn kleine LEDs ausgwählt sind, sind die Eingangspegelanzeigen runde LEDs. Die anderen Optionen verändern sowohl den Mixer, als auch die Eingangspegelanzeigen. Meter Style combo box Pegel-Messer-Stil Combo-Box Input Boost Eingangs-Verstärkung This setting allows you to increase your input signal level by factors up to 10 (+20dB). If your sound is too quiet, first try to increase the level by getting closer to the microphone, adjusting your sound equipment or increasing levels in your operating system's input settings. Only if this fails, set a factor here. If your sound is too loud, sounds distorted and is clipping, this option will not help. Do not use it. The distortion will still be there. Instead, decrease your input level by getting farther away from your microphone, adjusting your sound equipment or by decreasing your operating system's input settings. Diese Einstellung erlaubt es Dir, Dein Eingangs-Signal um bis zu Faktor 10 (+20dB) zu verstärken. Wenn Dein Sound zu leise ist, versuche zunächst das Signal zu verbessern, indem Du entweder näher an das Mikrofon gehst, Dein Audioequipment lauter stellst oder die Pegel in den Eingangs-Einstellungen Deines Betriebssystems erhöhst. Nur wenn das nicht klappt, setze hier einen Verstärkungsfaktor. Falls der Sound zu laut ist und verzerrt oder übersteuert, wird dir diese Option nicht helfen. Bitte nutze sie dann auch nicht. Verringere stattdessen Deinen Eingnagspegel, indem Du entweder weiter weg vom Mikrofon gehst, Dein Audioequipment leiser stellst oder die Pegel in den Eingangs-Einstellungen Deines Betriebssystems verringerst. Input Boost combo box Eingangs-Verstärkungs Combo box Directory server address combo box Verzeichnisserveradresse Combo-Box Audio Upstream Rate Audio-Upstream Rate Depends on the current audio packet size and compression setting. Make sure that the upstream rate is not higher than your available internet upload speed (check this with a service such as speedtest.net). Hängt von der aktuellen Audio-Paketgröße und den Kompressionseinstellungen ab. Stelle sicher, dass die Upstream-Rate nicht höher ist als Deine verfügbare Internet Upload Geschwindigkeit ist (das kann z.B. mit einem Service wie speedtest.net überprüft werden). Number of Mixer Panel Rows Anzahl der Mischpult-Reihen Adjust the number of rows used to arrange the mixer panel. Anzahl der Reihen des Mischpults einstellen. Number of Mixer Panel Rows spin box Anzahl Mischpult Reihen spin box Feedback Protection Feedback-Schutz Enable feedback protection to detect acoustic feedback between microphone and speakers. Aktiviere den Feedback-Schutz, um ein akustisches Feedback zwischen Mikrofon und Lautsprechern zu erkennen. Feedback Protection check box Feedback-Erkennungs check box Audio Alerts Audiohinweise Enable audio alert when receiving a chat message and when a new client joins the session. A second sound device may be required to hear the alerts. Aktiviert Audiohinweise beim Empfang einer Chat-Nachricht bzw. wenn ein neuer Client beitritt. Möglicherweise ist ein zweites Audiogerät erforderlich, um die Hinweise zu hören. Audio Alerts check box Audiohinweise Checkbox ASIO Device Settings ASIO-Geräte-Einstellungen Fancy Schick Compact Kompakt Bar (narrow) Balken (schmal) Bar (wide) Balken (breit) LEDs (stripe) LEDs (Streifen) LEDs (round, small) LEDs (rund, klein) LEDs (round, big) LEDs (rund, groß) LEDs LEDs Bar Balken Narrow Bar Schmale Balken Round LEDs Runde LEDs Small LEDs Kleine LEDs None Nichts Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country or region you are located in. Your city and skill level playing your instrument may also be added. Setze hier deinen Namen oder ein Pseudonym, damit andere Musiker wissen, wer Du bist. Du kannst auch ein Bild deines Instruments und die Flagge deines Landes oder der Region, in der du dich befindest, hinzufügen. Auch Deine Stadt und die Spielstärke deines Instruments kannst du angeben. What you set here will appear at your fader on the mixer board when you are connected to a %1 server. This tag will also be shown at each client which is connected to the same server as you. Was Du hier einträgst erscheint in Deinem Schieberegler auf dem Mischpult, sobald Du mit einem %1 Server verbunden bist. Diese Kennung wird auch in jedem Client angezeigt, der mit dem selben Server wie Du verbunden ist. Country/region flag button Land/Regionsflaggenknopf Center Mitte R R The buffer delay setting is a fundamental setting of the Die Soundkartenpuffergröße ist eine fundamentale Einstellung der software. This setting has influence on many connection properties. Software. Diese Einstellung hat Einfluss auf viele andere Verbindungseigenschaften. Three buffer sizes are supported Drei Puffergrößen werden unterstützt 64 samples: This is the preferred setting since it provides the lowest latency but does not work with all sound cards. 64 Samples: Dies ist die bevorzugte Einstellung weil es die geringste Verzögerung hat. Diese Puffergröße funktioniert allerdings nicht mit allen Soundkarten. 128 samples: This setting should work for most available sound cards. 128 Samples: Diese Puffergröße sollte mit den meisten Soundkarten funktionieren. 256 samples: This setting should only be used if only a very slow computer or a slow internet connection is available. 256 Samples: Diese Einstellung sollte nur dann verwendet werden, wenn man einen langsamen Computer oder eine langsame Internetverbindung hat. Some sound card drivers do not allow the buffer delay to be changed from within the Manche Soundkartentreiber unterstützen nicht das Verändern der Puffergröße innerhalb der software. In this case the buffer delay setting is disabled. To change the actual buffer delay, this setting has to be changed in the sound card driver. On Windows, press the ASIO Setup button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Software. In diesem Fall ist die Einstellungsmöglichkeit für die Puffergröße deaktiviert. Die Puffergröße muss man stattdessen direkt im Soundkartentreiber durchführen. Unter Windows kann man den ASIO-Einstellungen Knopf drücken um die Treibereinstellungen zu öffnen. Unter Linux benutzt man das Jack-Konfigurationsprogramm um die Puffergröße einzustellen. If no buffer size is selected and all settings are disabled, an unsupported buffer size is used by the driver. The Falls keiner der vorgegebenen Puffergrößen ausgeählt ist und alle Einstellungen deaktiviert sind, dann wird eine nicht unterstützte Puffergröße im Soundkartentreiber verwendet. Die software will still work with this setting but with restricted performance. Software funktioniert trotzdem aber es könnte eine größere Verzögerung resultieren. The actual buffer delay has influence on the connection status, the current upload rate and the overall delay. The lower the buffer size, the higher the probability of a red light in the status indicator (drop outs) and the higher the upload rate and the lower the overall delay. Die Puffergröße hat einen Einfluss auf den Verbindungsstatus, die aktuelle Upload-Rate und die Gesamtverzögerung. Je kleiner der Puffer, desto größer ist die Wahrscheinlichkeit für das Auftreten einer rot leuchtenden LED (was Audioaussetzer anzeigt), eine höheren Upload-Rate und eine niedrigere Gesamtverzögerung. The buffer setting is therefore a trade-off between audio quality and overall delay. Die Puffergröße ist somit ein Kompromiss zwischen Audioqualität und Gesamtverzögerung. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within the Falls die Puffergröße nicht verstellt werden kann, dann hat der Soundkartentreiber die Einstellung gesperrt man kann es nicht innerhalb der software. On Windows, press the ASIO Setup button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Software verändern. Unter Windows kann man den ASIO-Einstellungen Knopf drücken, um die Treibereinstellungen zu öffnen. Unter Linux kann man ein Jack-Konfigurationswerkzeug verwenden, um die Puffergröße zu verändern. 64 samples setting radio button 64 Samples Einstellknopf 128 samples setting radio button 128 Samples Einstellknopf 256 samples setting radio button 256 Samples Einstellknopf ASIO setup push button ASIO-Einstellungen Knopf Fancy Skin Schicke Oberfläche If enabled, a fancy skin will be applied to the main window. Falls aktiviert wird eine schicke Oberfläche im Hauptfenster verwendet. Fancy skin check box Schicke Oberfläche Schalter Display Channel Levels Zeige Kanalsignalpegel If enabled, each client channel will display a pre-fader level bar. Falls aktiviert wird eine Signalpegelanzeige neben jedem Kanalfader angezeigt, welcher den Pegel vor dem Fader anzeigt. Display channel levels check box Zeige Kanalpegel Schalter Audio Channels Audiokanäle Select the number of audio channels to be used. There are three modes available. The mono and stereo modes use one and two audio channels respectively. In mono-in/stereo-out mode the audio signal which is sent to the server is mono but the return signal is stereo. This is useful if the sound card has the instrument on one input channel and the microphone on the other channel. In that case the two input signals can be mixed to one mono channel but the server mix can be heard in stereo. Hiermit kann man die Anzahl an Audiokanälen auswählen. Es gibt drei Modi. Die Mono- und Stereomodi verwenden jeweils einen oder zwei Kanäle. Im Mono-In/Stereo-Out Modus wird ein Monosignal zum Server geschickt aber es kommt ein Stereo-Signal zurück vom Server. Dies ist nützlich für den Fall, dass man an die Soundkarte ein Instrument an den einen Eingangskanal und ein Mikrofon an den anderen Eingangskanal angeschlossen hat. In diesem Fall können die beiden Signale zusammen gemischt werden und an den Server geschickt werden aber man kann das Stereo-Signal von den anderen Musikern hören. Enabling the stereo streaming mode will increase the stream data rate. Make sure that the current upload rate does not exceed the available bandwidth of your internet connection. Wenn man den Stereo-Modus verwendet, dann ist die Übertragungsrate etwas höher. Man muss sicher stellen, dass die Internetverbindung die höhere Rate übertragen kann. In stereo streaming mode, no audio channel selection for the reverberation effect will be available on the main window since the effect is applied on both channels in this case. Wenn der Stereo-Modus ausgewählt wurde, dann verschwindet die Kanalselektion für den Halleffekt im Hauptfenster, da der Effekt auf beide Stereokanäle angewendet wird. Audio channels combo box Audiokanal Auswahlbox Audio Quality Audioqualität Select the desired audio quality. A low, normal or high audio quality can be selected. The higher the audio quality, the higher the audio stream data rate. Make sure that the current upload rate does not exceed the available bandwidth of your internet connection. Wählt die gewünschte Audioqualität aus. Es wird eine niedrige, mittlere und hohe Audioqualität angeboten. Je höher die Audioqualität, desto höher ist die Netzwerkübertragungsrate. Man muss sicherstellen, dass die Internetverbindung die höhere Rate übertragen kann. Audio quality combo box Audioqualität Auswahlbox New Client Level Pegel für neuen Teilnehmer The new client level setting defines the fader level of a new connected client in percent. I.e. if a new client connects to the current server, it will get the specified initial fader level if no other fader level of a previous connection of that client was already stored. Der Pegel für neue Teilnehmer definiert die Fadereinstellung, wenn sich ein Teilnehmer neu mit dem Server verbindet. D.h. wenn ein neuer Fader erscheint, dann wird er auf den voreingestellten Pegel gesetzt. Eine Ausnahme bildet der Fall, dass der Teilnehmer vorher schon mal mit dem Server verbunden war und der Pegel gespeichert war. New client level edit box Neuer Teilnehmer Pegel Einstellbox Custom Directory Server Address Benutzerdefinierte Verzeichnisserveradresse The custom directory server address is the IP address or URL of the directory server at which the server list of the connection dialog is managed. This address is only used if the custom server list is selected in the connection dialog. Die Verzeichnisserveradresse ist die IP-Adresse oder URL des Verzeichnisservers, der die Serverliste organisiert und bereitstellt. Diese Adresse wird nur benutzt, wenn die benutzerdefinierte Serverliste im Verbindungsdialog ausgewählt wird. Directory Server Address Verzeichnisserveradresse The directory server address is the IP address or URL of the directory server at which the server list of the connection dialog is managed. With the directory server address type either the local region can be selected of the default directory servers or a manual address can be specified. Die Verzeichnisserveradresse ist die IP-Adresse oder URL des Verzeichnisservers, der die Serverliste organisiert und bereitstellt. Mit der Verzeichnisserveradresse kann entweder die örtliche Region festgelegt werden (durch Auswahl des entsprechenden vorgegebenen Verzeichnisservers) oder man gibt eine beliebige Adresse manuell ein. Default directory server type combo box Voreingestellter Verzeichnisservertyp Auswahlbox Directory server address line edit Verzeichnisserveradresse Eingabefeld Current Connection Status Parameter Verbindungsstatus Parameter The ping time is the time required for the audio stream to travel from the client to the server and back again. This delay is introduced by the network. This delay should be as low as 20-30 ms. If this delay is higher (e.g., 50-60 ms), your distance to the server is too large or your internet connection is not sufficient. Die Ping-Zeit ist die Zeit, die der Audiodatenstrom benötigt, um von der Applikation zum Server und zurück zu kommen. Diese Verzögerung wird vom Netzwerk hervorgerufen. Diese Verzögerung sollte so um die 20-30 ms sein. Falls die Verzögerung größer ist (z.B. 50-60 ms), der Abstand zum Server ist zu groß oder die Internetverbindung ist nicht ausreichend. The overall delay is calculated from the current ping time and the delay which is introduced by the current buffer settings. Die Gesamtverzögerung setzt sich zusammen aus der Ping-Zeit und die Verzögerung, die durch die Puffergrößen verursacht wird. The upstream rate depends on the current audio packet size and the audio compression setting. Make sure that the upstream rate is not higher than the available rate (check the upstream capabilities of your internet connection by, e.g., using speedtest.net). Die Upload-Rate hängt von der Soundkartenpuffergröße und die Audiokomprimierung ab. Man muss sicher stellen, dass die Upload-Rate immer kleiner ist als die Rate, die die Internetverbindung zur Verfügung stellt (man kann die Upload-Rate des Internetproviders z.B. mit speedtest.net überprüfen). If this LED indicator turns red, you will not have much fun using the Wenn diese LED rot leuchtet, dann wirst du keinen Spaß haben mit der software. Software. ASIO Setup ASIO-Einstellung Mono and und mode will increase your stream's data rate. Make sure your upload rate does not exceed the available upload speed of your internet connection. Modus ist die Übertragungsrate etwas höher. Man muss sicher stellen, dass die Internetverbindung die höhere Rate übertragen kann. Custom Directories Benutzerdefinierte Verzeichnisse If you need to add additional directories to the Connect dialog Directory drop down, you can enter the addresses here.<br>To remove a value, select it, delete the text in the input box, then move focus out of the control. Um einen weiteren Verzeichnisserver im Verbinden-Dialog Drop-Down anzuzeigen, kann hier eine Adresse eingetragen werden.<br>Um einen Eintrag zu löschen, muss der Wert in der Textbox markiert und gelöscht werden. Sobald der Fokus aus der Textbox ist, taucht der Server nicht mehr auf. Custom Directories combo box Benutzerdefinierte Verzeichnisserveradresse Combo-Box Mono-in/Stereo-out Mono-In/Stereo-Out Stereo &Close &Schließen Local Audio Input Fader Lokaler Eingangspegelregler Controls the relative levels of the left and right local audio channels. For a mono signal it acts as a pan between the two channels. For example, if a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows Mit diesem Einstellregler kann der relative Pegel vom linken und rechten Eingangskanal verändert werden. Für ein Mono-Signal verhält sich der Regler wie ein Pan-Regler. Wenn, z.B., ein Mikrofon am rechten Kanal angeschlossen ist und das Instrument am linken Eingangskanal ist viel lauter als das Mikrofon, dann kann man den Lautstärkeunterschied mit diesem Regler kompensieren indem man den Regler in eine Richtung verschiebt, so dass über dem Regler L L , where angezeigt wird, wobei is the current attenuation indicator. die aktuelle Dämpfung anzeigt. Local audio input fader (left/right) Lokaler Eingangsregler (Links/Rechts) The jitter buffer compensates for network and sound card timing jitters. The size of the buffer therefore influences the quality of the audio stream (how many dropouts occur) and the overall delay (the longer the buffer, the higher the delay). Der Netzwerkpuffer kompensiert die Netzwerk- und Soundkarten-Timing-Schwankungen. Die Größe des Netzwerkpuffers hat Auswirkungen auf die Qualität des Audiosignals (wie viele Aussetzer auftreten) und die Gesamtverzögerung (je länger der Puffer, desto größer ist die Verzögerung). You can set the jitter buffer size manually for the local client and the remote server. For the local jitter buffer, dropouts in the audio stream are indicated by the light below the jitter buffer size faders. If the light turns to red, a buffer overrun/underrun has taken place and the audio stream is interrupted. Die Netzwerkpuffergröße kann manuell verstellt werden, jeweils getrennt für die Applikation und den Server. Für den lokalen Netzwerkpuffer werden die Aussetzer durch die LED-Anzeige unter den Reglern angezeigt. Wenn die Lampe rot anzeigt, dann hat ein Pufferüberlauf oder ein Leerlauf des Puffers stattgefunden und der Audiodatenstrom wurde kurz unterbrochen. If the Auto setting is enabled, the jitter buffers of the local client and the remote server are set automatically based on measurements of the network and sound card timing jitter. If Auto is enabled, the jitter buffer size faders are disabled (they cannot be moved with the mouse). Die Netzwerkpuffergröße kann automatisch eingestellt werden. Wenn die Automatik aktiviert ist, dann werden die Netzwerkpuffer der Applikation und des Servers getrennt basierend auf Messungen der Netzwerkschwankungen eingestellt. Wenn die Automatik aktiviert ist, dann sind die beiden Regler gesperrt für die manuelle Verstellung (sie können nicht mit der Maus verändert werden). If the Auto setting is enabled, the network buffers of the local client and the remote server are set to a conservative value to minimize the audio dropout probability. To tweak the audio delay/latency it is recommended to disable the Auto setting and to lower the jitter buffer size manually by using the sliders until your personal acceptable amount of dropouts is reached. The LED indicator will display the audio dropouts of the local jitter buffer with a red light. Wenn die Automatik zum Einstellen der Netzwerkpuffer aktiviert ist, dann werden die Netzwerkpuffer der Applikation und des entfernten Servers auf einen konservativen Wert eingestellt, um eine möglichst gute Audioqualität zu garantieren. Um die Gesamtverzögerung zu optimieren, bietet es sich an, die Automatik zu deaktivieren und die Netzwerkpuffer etwas kleiner einzustellen. Die Werte sollte man so weit reduzieren, bis die Audioqualität gerade noch der persönlichen Akzeptanz entspricht. Die LED-Anzeige hilft dabei die Audioaussetzer verursacht durch den lokalen Netzwerkpuffer zu visualisieren (wenn die LED rot leuchtet). The buffer delay setting is a fundamental setting of this software. This setting has an influence on many connection properties. Die Soundkartenpuffergröße ist eine fundamentale Einstellung der Software. Diese Einstellung hat Einfluss auf viele andere Verbindungseigenschaften. 64 samples: The preferred setting. Provides the lowest latency but does not work with all sound cards. 64 Samples: Dies ist die bevorzugte Einstellung weil es die geringste Verzögerung hat. Diese Puffergröße funktioniert allerdings nicht mit allen Soundkarten. 128 samples: Should work for most available sound cards. 128 Samples: Diese Puffergröße sollte mit den meisten Soundkarten funktionieren. 256 samples: Should only be used on very slow computers or with a slow internet connection. 256 Samples: Diese Einstellung sollte nur dann verwendet werden, wenn man einen langsamen Computer oder eine langsame Internetverbindung hat. Some sound card drivers do not allow the buffer delay to be changed from within the application. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. On Windows, press the ASIO Setup button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Manche Soundkartentreiber unterstützen nicht das Verändern der Puffergröße innerhalb der Software. In diesem Fall ist die Einstellungsmöglichkeit für die Puffergröße deaktiviert. Die Puffergröße muss man stattdessen direkt im Soundkartentreiber durchführen. Unter Windows kann man den ASIO-Einstellungen Knopf drücken um die Treibereinstellungen zu öffnen. Unter Linux benutzt man das Jack-Konfigurationsprogramm um die Puffergröße einzustellen. If no buffer size is selected and all settings are disabled, an unsupported buffer size is used by the driver. The application will still work with this setting but with restricted performance. Falls keiner der vorgegebenen Puffergrößen ausgeählt ist und alle Einstellungen deaktiviert sind, dann wird eine nicht unterstützte Puffergröße im Soundkartentreiber verwendet. Die Software funktioniert trotzdem aber es könnte eine größere Verzögerung resultieren. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within the software. On Windows, press the ASIO Setup button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Falls keiner der vorgegebenen Puffergrößen ausgeählt ist und alle Einstellungen deaktiviert sind, dann wird eine nicht unterstützte Puffergröße im Soundkartentreiber verwendet. Unter Windows kann man den ASIO-Einstellungen Knopf drücken, um die Treibereinstellungen zu öffnen. Unter Linux kann man ein Jack-Konfigurationswerkzeug verwenden, um die Puffergröße zu verändern. Skin Oberfläche Select the skin to be used for the main window. Wählt die Oberfläche aus, die für das Hauptfenster verwendet werden soll. Skin combo box Oberfläche Combo-Box Selects the number of audio channels to be used for communication between client and server. There are three modes available: Hiermit kann man die Anzahl an Audiokanälen auswählen. Es gibt drei Modi: and und These modes use one and two audio channels respectively. Diese Modi verwenden jeweils einen oder zwei Audiokanäle. Mono in/Stereo-out The audio signal sent to the server is mono but the return signal is stereo. This is useful if the sound card has the instrument on one input channel and the microphone on the other. In that case the two input signals can be mixed to one mono channel but the server mix is heard in stereo. Ein Monosignal wird zum Server geschickt aber es kommt ein Stereo-Signal zurück vom Server. Dies ist nützlich für den Fall, dass man an die Soundkarte ein Instrument an den einen Eingangskanal und ein Mikrofon an den anderen Eingangskanal angeschlossen hat. In diesem Fall können die beiden Signale zusammen gemischt werden und an den Server geschickt werden aber man kann das Stereo-Signal von den anderen Musikern hören. Enabling Im mode will increase your stream's data rate. Make sure your upload rate does not exceed the available upload speed of your internet connection. Modus ist die Übertragungsrate etwas höher. Man muss sicher stellen, dass die Internetverbindung die höhere Rate übertragen kann. In stereo streaming mode, no audio channel selection for the reverb effect will be available on the main window since the effect is applied to both channels in this case. Wenn der Stereo-Modus ausgewählt wurde, dann verschwindet die Kanalselektion für den Halleffekt im Hauptfenster, da der Effekt auf beide Stereokanäle angewendet wird. The higher the audio quality, the higher your audio stream's data rate. Make sure your upload rate does not exceed the available bandwidth of your internet connection. Je höher die Audioqualität, desto höher ist die Netzwerkübertragungsrate. Man muss sicherstellen, dass die Internetverbindung die höhere Rate übertragen kann. This setting defines the fader level of a newly connected client in percent. If a new client connects to the current server, they will get the specified initial fader level if no other fader level from a previous connection of that client was already stored. Der Pegel für neue Teilnehmer definiert die Fadereinstellung, wenn sich ein Teilnehmer neu mit dem Server verbindet. D.h. wenn ein neuer Fader erscheint, dann wird er auf den voreingestellten Pegel gesetzt. Eine Ausnahme bildet der Fall, dass der Teilnehmer vorher schon mal mit dem Server verbunden war und der Pegel gespeichert war. Leave this blank unless you need to enter the address of a directory server other than the default. Lass diese Box leer, außer Du nutzt eine vom Standard abweichende Verzeichnisserver Adresse. The Ping Time is the time required for the audio stream to travel from the client to the server and back again. This delay is introduced by the network and should be about 20-30 ms. If this delay is higher than about 50 ms, your distance to the server is too large or your internet connection is not sufficient. Die Ping-Zeit ist die Zeit, die der Audiodatenstrom benötigt, um von der Applikation zum Server und zurück zu kommen. Diese Verzögerung wird vom Netzwerk hervorgerufen. Diese Verzögerung sollte so um die 20-30 ms sein. Falls die Verzögerung größer ist (z.B. 50-60 ms), der Abstand zum Server ist zu groß oder die Internetverbindung ist nicht ausreichend. Overall Delay is calculated from the current Ping Time and the delay introduced by the current buffer settings. Die Gesamtverzögerung setzt sich zusammen aus der Ping-Zeit und die Verzögerung, die durch die Puffergrößen verursacht wird. Audio Upstream Rate depends on the current audio packet size and compression setting. Make sure that the upstream rate is not higher than your available internet upload speed (check this with a service such as speedtest.net). Die Upload-Rate hängt von der Soundkartenpuffergröße und die Audiokomprimierung ab. Man muss sicher stellen, dass die Upload-Rate immer kleiner ist als die Rate, die die Internetverbindung zur Verfügung stellt (man kann die Upload-Rate des Internetproviders z.B. mit speedtest.net überprüfen). Low Niedrig Normal Normal High Hoch Manual Manuell Custom Benutzerdefiniert All Genres Alle Genres Any Genre 2 Alle Genres 2 Any Genre 3 Alle Genres 3 Genre Rock Genre Rock Genre Jazz Genre Jazz Genre Classical/Folk Genre Klassik/Volksmusik Genre Choral/Barbershop Genre Chor/Barbershop Any Genre 1 Alle Genres 1 Genre Rock/Jazz Genre Rock/Jazz Genre Classical/Folk/Choral Genre Klassik/Volksmusik/Chor Default Standard Default (North America) Standard (Nordamerika) preferred bevorzugt Musician Profile Musiker-Profil Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country you are located in. Your city and skill level playing your instrument may also be added. Schreibe den Namen oder Alias hier rein so dass die anderen Musikern mit denen du spielst wissen wer du bist. Zusätzlich kannst du dein Instrument auswählen und eine Flagge des Landes auswählen in dem du dich befindest. Deine Stadt und deine Spielstärke des Instruments kannst du ebenso angeben. What you set here will appear at your fader on the mixer board when you are connected to a Jamulus server. This tag will also be shown at each client which is connected to the same server as you. Was man hier sieht wird auch am Fader im Mixer angezeigt, wenn du mit einem Server verbunden bist. Dieses Schild wird auch bei allen anderen Musikern, die mit dem gleichen Server verbunden sind, angezeigt. Alias or name edit box Alias oder Name Eingabefeld Instrument picture button Instrumentenbild Knopf Country flag button Landesflagge Knopf City edit box Stadt Eingabefeld Skill level combo box Fähigkeit Auswahlbox Beginner Anfänger Intermediate Mittlere Spielstärke Expert Experte Size: Größe: Buffer Delay Puffergröße Buffer Delay: Puffergröße: Predefined Address Vordefinierte Adresse The selected audio device could not be used because of the following error: Das ausgewählte Audiogerät kann aus folgendem Grund nicht verwendet werden: The previous driver will be selected. Der vorherige Treiber wird wieder ausgewählt. Drum Set Schlagzeug Djembe Djembe Electric Guitar E-Gitarre Acoustic Guitar Akustikgitarre Bass Guitar E-Bass Keyboard Keyboard Synthesizer Synthesizer Grand Piano Flügel Accordion Akkordeon Vocal Gesang Microphone Mikrofon Harmonica Mundharmonika Trumpet Trompete Trombone Posaune French Horn Waldhorn Tuba Tuba Saxophone Saxophon Clarinet Klarinette Flute Flöte Violin Violine Cello Cello Double Bass Kontrabass Recorder Blockflöte Streamer Streamer Listener Zuhörer Guitar+Vocal Gitarre+Gesang Keyboard+Vocal Keyboard+Gesang Bodhran Bodhran Bassoon Fagott Oboe Oboe Harp Harfe Viola Viola Congas Congas Bongo Bongos Vocal Bass Gesang Bass Vocal Tenor Gesang Tenor Vocal Alto Gesang Alt Vocal Soprano Gesang Sopran Banjo Banjo Mandolin Mandoline Ukulele Ukulele Bass Ukulele Bass Ukulele Vocal Baritone Gesang Bariton Vocal Lead Gesang Lead Mountain Dulcimer Mountain Dulcimer Scratching Scratching Rapping Rapper Vibraphone Vibraphon Conductor Dirigent CClientSettingsDlgBase Settings Einstellungen Soundcard Soundkarte Device Gerät Input Channel Mapping Eingangskanalauswahl L R Output Channel Mapping Ausgangskanalauswahl Enable Small Network Buffers Aktiviere kleine Netzwerkpuffer Buffer Delay Puffergröße Country/Region Land/Region (preferred) (bevorzugt) (default) (standard) (safe) (sicher) Driver Setup Treibereinstellungen My Profile Mein Profil Musician's Profile Musiker-Profil Alias/Name Alias/Name Instrument Instrument Country Land City Stadt Skill Können User Interface Benutzeroberfläche Meter Style Pegel-Messer-Stil Mixer Rows Mischpult-Reihen Audio Alerts Audiohinweise Audio/Network Setup Audio-/Netzwerk-Einstellungen Audio Device Audiogerät Jitter Buffer Netzwerkpuffer Auto Local Lokal Server Server Size Größe kbps kbps Custom Directories: Benutzerdefinierte Verzeichnisse: Input Boost Eingangsverstärkung Feedback Protection Feedback-Schutz Enable Aktivieren Input Balance Eingangs-Balance Pan Pan Center Mitte Misc Sonstiges Audio Channels Audiokanäle Audio Quality Audioqualität Measurements Messungen Advanced Setup Erweiterte Einstellungen Custom Central Server Address: Benutzerdefinierte Verzeichnisserver-Adresse New Client Level Pegel für neuen Teilnehmer Skin Oberfläche Language Sprache % Local Jitter Buffer Lokaler Jitterbuffer Fancy Skin Schicke Oberfläche Display Channel Levels Zeige Signalpegel Custom Directory Server Address: Benutzerdefinierte Verzeichnisserveradresse: Directory Server Address: Verzeichnisserveradresse: Audio Stream Rate Netzwerkrate val Wert Ping Time Ping-Zeit Overall Delay Gesamtverzögerung CConnectDlg Server List Severliste The server list shows a list of available servers which are registered at the directory server. Select a server from the list and press the connect button to connect to this server. Alternatively, double click a server from the list to connect to it. If a server is occupied, a list of the connected musicians is available by expanding the list item. Permanent servers are shown in bold font. Die Serverliste zeigt eine Liste von verfügbaren Server, die sich am Verzeichnisserver registriert haben. Markiere einen Server von der Liste und drücke den Knopf Verbinden um eine Verbindung zu dem Server aufzubauen. Alternativ kann man auch den Server in der Liste direkt doppelklicken. Wenn ein Server belegt ist, dann wird eine Liste der verbundenen Musikern angezeigt. Server, die länger online sind (permanente Server) werden in Fettschrift dargestellt. Note that it may take some time to retrieve the server list from the directory server. If no valid directory server address is specified in the settings, no server list will be available. Es kann einen Moment dauern, bis die Serverliste vom Verzeichnisserver empfangen wird. Falls keine gültige Verzeichnisserveradresse in den Einstellungen angegeben ist, kann keine Liste angezeigt werden. Directory Verzeichnis Shows the servers listed by the selected directory. You can add custom directories in Advanced Settings. Zeigt die Server, die vom ausgewählten Verzeichnis gelistet werden an. Du kannst benutzerdefinierte Verzeichnisse in den erweiterten Einstellungen hinzufügen. Directory combo box Verzeichnis Combo-Box Filters the server list by the given text. Note that the filter is case insensitive. A single # character will filter for those servers with at least one person connected. Filtert die Serverliste nach dem eingegebenen Text. Beachte, dass der Filter Groß- und Kleinschreibung nicht berücksichtigt. Ein einzelnes #-Zeichen filtert nach den Servern, mit denen mindestens eine Person verbunden ist. Uncheck to collapse the server list to show just the server details. Check to show everyone on the servers. Deaktiviere das Kästchen, um die Serverliste zu minimieren und nur die Server-Details zu sehen. Aktiviere es, um alle Personen auf den Servern zu sehen. The Connection Setup window lists the available servers registered with the selected directory. Use the Directory dropdown to change the directory, find the server you want to join in the server list, click on it, and then click the Connect button to connect. Alternatively, double click on the server name to connect. Im Verbinden-Fenster werden die verfügbaren Server aufgelistet, die für das ausgewählte Verzeichnis registriert sind. Verwende das Verzeichnis-Dropdown-Menü, um das Verzeichnis zu ändern, suche den Server, mit dem du dich verbinden möchtest in der Serverliste, klicke ihn an und klicke danach auf die Schaltfläche Verbinden, um eine Verbindung herzustellen. Alternativ kannst du auch den Servernamen doppelklicken, um eine Verbindung herzustellen. Permanent servers (those that have been listed for longer than 48 hours) are shown in bold. Permanente Server (Server, die länger als 48 Stunden gelistet sind) werden fett gedruckt. You can add custom directories in Advanced Settings. Du kannst benutzerdefinierte Verzeichnisse in den erweiterten Einstellungen hinzufügen. Server list view Serverliste Anzeige Server Address Serveradresse If you know the server address, you can connect to it using the Server name/Address field. An optional port number can be added after the server address using a colon as a separator, e.g. %1. The field will also show a list of the most recently used server addresses. Wenn Sie die Serveradresse kennen, können Sie über das Feld Servername/Adresse eine Verbindung zu ihr herstellen. Nach der Serveradresse kann eine optionale Portnummer mit einem Doppelpunkt als Trennzeichen eingefügt werden, z. B. %1. In diesem Feld wird auch eine Liste der zuletzt verwendeten Serveradressen angezeigt. Holds the current server address. It also stores old addresses in the combo box list. Enthält die aktuelle Serveradresse. Außerdem werden alte Adressen in der Combo-Box gespeichert. The IP address or URL of the server running the Die IP-Adresse oder URL des Servers, auf der die server software must be set here. An optional port number can be added after the IP address or URL using a colon as a separator, e.g. example.org: Serversoftware läuft wird hier angegeben. Optional kann eine Portnummer angefügt werden. Diese wird hinter der IP-Adresse durch ein Doppelpunkt getrennt angegeben. Beispiel: example.org: . A list of the most recent used server IP addresses or URLs is available for selection. . Eine Liste der letzten IP-Adressen oder URLs wird gespeichert und kann nachträglich wieder ausgewählt werden. The Connection Setup window shows a list of available servers. Server operators can optionally list their servers by music genre. Use the List dropdown to select a genre, click on the server you want to join and press the Connect button to connect to it. Alternatively, double click on on the server name. Permanent servers (those that have been listed for longer than 48 hours) are shown in bold. Die Serverliste zeigt eine Liste von verfügbaren Server, die sich am Verzeichnisserver registriert haben. Markiere einen Server von der Liste und drücke den Knopf Verbinden um eine Verbindung zu dem Server aufzubauen. Alternativ kann man auch den Server in der Liste direkt doppelklicken. Wenn ein Server belegt ist, dann wird eine Liste der verbundenen Musikern angezeigt. Server, die länger online sind (permanente Server) werden in Fettschrift dargestellt. If you know the IP address or URL of a server, you can connect to it using the Server name/Address field. An optional port number can be added after the IP address or URL using a colon as a separator, e.g. example.org: Die IP-Adresse oder URL des Servers, auf der die Serversoftware läuft wird hier angegeben. Optional kann eine Portnummer angefügt werden. Diese wird hinter der IP-Adresse durch ein Doppelpunkt getrennt angegeben. Beispiel: example.org: . The field will also show a list of the most recently used server addresses. . Eine Liste der letzten IP-Adressen oder URLs wird gespeichert und kann nachträglich wieder ausgewählt werden. Server address edit box Serveradresse Eingabefeld Holds the current server IP address or URL. It also stores old URLs in the combo box list. Enthält die aktuelle Server-IP-Adresse oder URL. Es speichert auch alte URLs in der Auswahlliste. Server List Selection Serverlistenauswahl Selects the server list to be shown. Wählt die Serverliste aus, die angezeigt werden soll. Server list selection combo box Severlistenauswahl Selektion Filter Filter The server list is filtered by the given text. Note that the filter is case insensitive. Die Serverliste kann mit dem eingegebenen Text gefiltert werden, d.h. es werden nur Einträge angezeigt, die dem Filtertext entsprechen. Die Groß- und Kleinschreibung des Filtertexts wird dabei nicht beachtet. Filter edit box Filtereingabefeld Show All Musicians Zeige alle Musiker If you check this check box, the musicians of all servers are shown. If you uncheck the check box, all list view items are collapsed. Ist diese Einstellung angehakt, dann werden alle Musiker auf allen Servern angezeigt. Wird der Haken entfernt, dann werden alle Listeneinträge eingeklappt und die verbundenen Musikernamen werden verborgen. Show all musicians check box Zeige alle Musiker Schalter If you know the IP address or URL of a server, you can connect to it using the Server name/Address field. An optional port number can be added after the IP address or URL using a colon as a separator, e.g. %1. The field will also show a list of the most recently used server addresses. Wenn Du die IP-Adresse oder URL eines Servers kennst, kannst du über das Feld "Severadresse" eine Verbindung zu ihm herstellen. Nach der IP-Adresse oder URL kann eine optionale Portnummer mit einem Doppelpunkt als Trennzeichen eingefügt werden, z.B. %1. In diesem Feld wird auch eine Liste der zuletzt verwendeten Serveradressen angezeigt. Filter text, or # for occupied servers Filter Text, oder # für belegte Server Type # for occupied servers # eingeben für belegte Server CConnectDlgBase Connection Setup Verbindungseinstellung List Liste Directory Verzeichnis Filter Filter Show All Musicians Zeige alle Musiker Server Name Servername Ping Time Ping-Zeit Musicians Musiker Location Standort Server Address Serveradresse C&ancel A&bbrechen &Connect &Verbinden CHelpMenu &Help &Hilfe Getting &Started... &Erste Schritte... Software &Manual... Software&handbuch... What's &This Konte&xthilfe &About Jamulus... Ü&ber Jamulus... About &Qt... Über &Qt... &About... Ü&ber... About Qt Über Qt CLanguageComboBox Restart Required Neustart erforderlich Please restart the application for the language change to take effect. Bitte starte die Applikation neu um die Änderung der Spracheinstellung anzuwenden. CLicenceDlg I &agree to the above licence terms Ich &stimme den Lizenzbedingungen zu This server requires you accept conditions before you can join. Please read these in the chat window. Dieser Server verlangt, dass man Bedingungen akzeptiert, bevor man sich verbinden kann. Bitte ließ die Bedingungen im Chat-Fenster. I have read the conditions and &agree. Ich h&abe die Bedingungen gelesen und ich stimme zu. Accept Einwilligen Decline Ablehnen By connecting to this server and agreeing to this notice, you agree to the following: Durch das Verbinden mit diesem Server und das Akzeptieren des Lizenztextes willigst du folgenden Bedingungen ein: You agree that all data, sounds, or other works transmitted to this server are owned and created by you or your licensors, and that you are making these data, sounds or other works available via the following Creative Commons License (for more information on this license, see Sie stimmen zu, dass alle Daten, Klänge oder andere Arbeiten, die zum Server gesendet werden, Ihnen gehören oder von Ihnen selbst oder einem Lizenzgeber erstellt wurden und dass Sie diese Daten, Klänge oder andere Arbeiten unter die folgende Creative Commons Lizenz stellen (Für weitere Informationen über die Lizenz, siehe You are free to: Sie dürfen: Share Teilen copy and redistribute the material in any medium or format das Material in jedwedem Format oder Medium vervielfältigen und weiterverbreiten Adapt Bearbeiten remix, transform, and build upon the material das Material remixen, verändern und darauf aufbauen The licensor cannot revoke these freedoms as long as you follow the license terms. Der Lizenzgeber kann diese Freiheiten nicht widerrufen solange Sie sich an die Lizenzbedingungen halten. Under the following terms: Unter folgenden Bedingungen: Attribution Namensnennung You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. Sie müssen angemessene Urheber- und Rechteangaben machen, einen Link zur Lizenz beifügen und angeben, ob Änderungen vorgenommen wurden. Diese Angaben dürfen in jeder angemessenen Art und Weise gemacht werden, allerdings nicht so, dass der Eindruck entsteht, der Lizenzgeber unterstütze gerade Sie oder Ihre Nutzung besonders. NonCommercial Nicht kommerziell You may not use the material for commercial purposes. Sie dürfen das Material nicht für kommerzielle Zwecke nutzen. ShareAlike Weitergabe unter gleichen Bedingungen If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original. Wenn Sie das Material remixen, verändern oder anderweitig direkt darauf aufbauen, dürfen Sie Ihre Beiträge nur unter derselben Lizenz wie das Original verbreiten. No additional restrictions Keine weiteren Einschränkungen You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. Sie dürfen keine zusätzlichen Klauseln oder technische Verfahren einsetzen, die anderen rechtlich irgendetwas untersagen, was die Lizenz erlaubt. CMultiColorLED Red Rot Yellow Gelb Green Grün CMusProfDlg server. This tag will also show up at each client which is connected to the same server as you. If the name is left empty, the IP address is shown instead. Server. Dieses Schild wird auch bei allen anderen Musikern, die mit dem gleichen Server verbunden sind, angezeigt. Wenn der Name leer gelassen wurde, dann wird die IP-Adresse stattdessen angezeigt. Alias or name edit box Alias oder Name Eingabefeld Instrument picture button Instrumentenbild Knopf Country flag button Landesflagge Knopf City edit box Stadt Eingabefeld Skill level combo box Fähigkeit Auswahlbox None Kein Musician Profile Musikerprofil Country Land City Stadt Skill Können &Close &Schließen Beginner Anfänger Intermediate Mittlere Spielstärke Expert Experte Set your name or an alias here so that the other musicians you want to play with know who you are. Additionally you may set an instrument picture of the instrument you play and a flag of the country you are living in. The city you live in and the skill level playing your instrument may also be added. Schreibe den Namen oder Alias hier rein so dass die anderen Musikern mit denen du spielst wissen wer du bist. Zusätzlich kannst du dein Instrument auswählen und eine Flagge des Landes auswählen in dem du dich befindest. Deine Stadt und deine Spielstärke des Instruments kannst du ebenso angeben. What you set here will appear at your fader on the mixer board when you are connected to a Was man hier sieht wird auch am Fader im Mixer angezeigt, wenn du mit einem Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country you are located in. Your city and skill level playing your instrument may also be added. Schreibe den Namen oder Alias hier rein so dass die anderen Musikern mit denen du spielst wissen wer du bist. Zusätzlich kannst du dein Instrument auswählen und eine Flagge des Landes auswählen in dem du dich befindest. Deine Stadt und deine Spielstärke des Instruments kannst du ebenso angeben. What you set here will appear at your fader on the mixer board when you are connected to a Jamulus server. This tag will also be shown at each client which is connected to the same server as you. If the name is left empty, the IP address is shown instead. Was man hier sieht wird auch am Fader im Mixer angezeigt, wenn du mit einem Server verbunden bist. Dieses Schild wird auch bei allen anderen Musikern, die mit dem gleichen Server verbunden sind, angezeigt. What you set here will appear at your fader on the mixer board when you are connected to a Jamulus server. This tag will also be shown at each client which is connected to the same server as you. Was man hier sieht wird auch am Fader im Mixer angezeigt, wenn du mit einem Server verbunden bist. Dieses Schild wird auch bei allen anderen Musikern, die mit dem gleichen Server verbunden sind, angezeigt. Drum Set Schlagzeug Djembe Djembe Electric Guitar E-Gitarre Acoustic Guitar Akustikgitarre Bass Guitar E-Bass Keyboard Keyboard Synthesizer Synthesizer Grand Piano Flügel Accordion Akkordeon Vocal Gesang Microphone Mikrofon Harmonica Mundharmonika Trumpet Trompete Trombone Posaune French Horn Waldhorn Tuba Tuba Saxophone Saxophon Clarinet Klarinette Flute Flöte Violin Violine Cello Cello Double Bass Kontrabass Recorder Recorder Listener Zuhörer Guitar+Vocal Gitarre+Gesang Keyboard+Vocal Keyboard+Gesang Bassoon Fagott Oboe Oboe Harp Harfe Viola Viola Congas Congas Bongo Bongos Vocal Bass Gesang Bass Vocal Tenor Gesang Tenor Vocal Alto Gesang Alt Vocal Soprano Gesang Sopran Banjo Banjo Mandolin Mandoline Vocal Baritone Gesang Bariton Vocal Lead Gesang Lead Mountain Dulcimer Mountain Dulcimer Scratching Scratching Rapping Rapper No Name Kein Name CServerDlg Client List Musikerliste The client list shows all clients which are currently connected to this server. Some information about the clients like the IP address and name are given for each connected client. Die Musikerliste zeigt alle gerade mit dem Server verbunden Musiker an. Für jeden Musiker werden zusätzliche Informationen wie die IP-Adresse und Namen angezeigt. Connected clients list view Musikerliste Directory Type combo box Verzeichnis Combo-Box Directory Verzeichnis Select '%1' not to register your server with a directory. Wähle "%1", um den Server nicht mit einem Verzeichnis zu registrieren. Select one of the genres to register with that directory. Wählen Sie eines der Genres aus, um sich in diesem Verzeichnis zu registrieren. Or select '%1' and specify a Custom Directory address on the Options tab to register with a custom directory. Oder wähle "%1" und gebe in der Registerkarte "Optionen" eine benutzerdefinierte Verzeichnisadresse an, um dich bei einem benutzerdefinierten Verzeichnis zu registrieren. For any value except '%1', this server registers with a directory so that a %2 user can select this server in the client connect dialog server list when they choose that directory. Bei jedem Wert außer '%1' registriert sich dieser Server bei einem Verzeichnis, so dass ein %2-Benutzer diesen Server in der Serverliste des Client-Verbindungsdialogs auswählen kann, sobald er dieses Verzeichnis wählt. The registration of the server is renewed periodically to make sure that all servers in the connect dialog server list are actually available. Die Registrierung des Servers wird in regelmäßigen Abständen erneuert, um sicherzustellen, dass alle Server in der Serverliste des Verbindungsdialogs tatsächlich verfügbar sind. When a value other than "%1" is chosen for Directory, this will show whether registration is successful. If the registration failed, please choose a different directory. Wenn ein anderer Wert als "%1" für Verzeichnis gewählt wird, zeigt dies an, ob die Registrierung erfolgreich war. Wenn die Registrierung fehlgeschlagen ist, wählen Sie bitte ein anderes Verzeichnis. No recording directory has been set or the value is not useable. Check the value in the Options tab. Es wurde kein Aufzeichnungsverzeichnis festgelegt oder der Wert ist nicht verwendbar. Überprüfen Sie den Wert unter der Registerkarte Optionen. If the recording directory is not useable, the problem will be displayed in place of the session directory. Wenn das Aufzeichnungsverzeichnis nicht verfügbar ist, wird anstelle des Verzeichnisses der Fehler angezeigt. Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user %1 is running as). Klicken Sie auf die Schaltfläche , um das Dialogfeld zu öffnen, in dem Sie das Hauptverzeichnis für die Aufzeichnung auswählen können. Der gewählte Wert muss existieren und beschreibbar sein (die Erstellung von Unterverzeichnissen durch den Benutzer, unter dem %1 läuft, muss möglich sein). The current value of the main recording directory. The chosen value must exist and be writeable (allow creation of sub-directories by the user %1 is running as). Click the button to open the dialog that allows the main recording directory to be selected. Der aktuelle Wert des Aufnahmeverzeichnisses. Der gewählte Wert muss existieren und beschreibbar sein (die Erstellung von Unterverzeichnissen durch den Benutzer, unter dem %1 läuft, muss möglich sein). Klicke auf die Schaltfläche, um das Dialogfeld zu öffnen, in dem das Verzeichnis für die Aufzeichnung ausgewählt werden kann. Custom Directory address Benutzerdefinierte Verzeichnisadresse The Custom Directory address is the address of the directory holding the server list to which this server should be added. Die Adresse des benutzerdefinierten Verzeichnisses ist die Adresse des Verzeichnisses, das die Serverliste enthält, zu der dieser Server hinzugefügt werden soll. Server List Filename dialog push button Serverliste Dateiname Dialog Button Server List Filename Serverliste Dateiname Click the button to open the dialog that allows the server list persistence file name to be set. The user %1 is running as needs to be able to create the file name specified although it may already exist (it will get overwritten on save). Klicke auf die Schaltfläche, um das Dialogfeld zu öffnen, in dem du den Namen der Persistenzdatei der Serverliste festlegen kannst. Der Benutzer, unter dem %1 läuft, muss in der Lage sein, den angegebenen Dateinamen zu erstellen, auch wenn er bereits existiert (er wird beim Speichern überschrieben). Server List Filename text box (read-only) Serverliste Dateiname Textbox (schreibgeschützt) The current value of server list persistence file name. The user %1 is running as needs to be able to create the file name specified although it may already exist (it will get overwritten on save). Click the button to open the dialog that allows the server list persistence file name to be set. Der aktuelle Wert des Dateinamens für die Persistenz der Serverliste. Der Benutzer, unter dem %1 läuft, muss in der Lage sein, den angegebenen Dateinamen zu erstellen, auch wenn er bereits existiert (sie wird beim Speichern überschrieben). Klicken Sie auf die Schaltfläche , um das Dialogfeld zu öffnen, in dem Sie den Namen der Serverlisten-Persistenzdatei festlegen können. Clear the server list file name button Schaltfläche Dateiname der Serverliste löschen Clear Server List Filename Serverliste Dateiname Feld löschen Click the button to clear the currently selected server list persistence file name. This will prevent persisting the server list until a new value is selected. Klicke auf diese Schaltfläche, um den Namen der aktuell ausgewählten Serverlisten-Persistenzdatei zu löschen. Dadurch wird verhindert, dass die Serverliste bestehen bleibt, bis ein neuer Wert ausgewählt wird. Start Minimized on Operating System Start Starte minimiert beim Starten des Betriebssystems Now a directory Jetzt ein Verzeichnis If the start minimized on operating system start check box is checked, the Wenn diese Funktion angehakt ist, dann wird der server will be started when the operating system starts up and is automatically minimized to a system task bar icon. Server automatisch mit dem Betriebssystemstart geladen und erscheint minimiert in der Systemleiste als Icon. Show Creative Commons Licence Dialog Zeige den Creative Commons Lizenzdialog If enabled, a Creative Commons BY-NC-SA 4.0 Licence dialog is shown each time a new user connects the server. Falls aktiviert wird ein Create Commons BY-NC-SA 4.0 Lizenzdialog angezeigt, wenn ein neuer Teilnehmer versucht sich mit dem Server zu verbinden. Make My Server Public Veröffentliche meinen Server If the Make My Server Public check box is checked, this server registers itself at the directory server so that all Mit dieser Funktion wird der eigene Server in der Serverliste des Verzeichnisservers registriert so dass alle anderen Applikationsnutzer den users can see the server in the connect dialog server list and connect to it. The registration of the server is renewed periodically to make sure that all servers in the connect dialog server list are actually available. Server in der Liste sehen können und sich mit ihm verbinden können. Die Registrierung mit dem Verzeichnisserver wird periodisch erneuert um sicherzugehen, dass alle registrierten Server auch wirklich erreichbar sind. Register Server Status Registrierungsstatus If the Make My Server Public check box is checked, this will show whether registration with the directory server is successful. Wenn der eigene Server veröffentlicht wurde, dann zeigt der Registrierungsstatus and, ob die Registrierung erfolgreich war oder nicht. Directory Server Address Verzeichnisserveradresse The Directory server address is the IP address or URL of the directory server at which this server is registered. With the directory server address type either the local region can be selected of the default directory servers or a manual address can be specified. Die Verzeichnisserveradrees ist die IP-Adresse oder URL des Verzeichnisservers bei dem man sich registrieren möchte. Mit dem Verzeichnisservertyp legt man die Region fest, in der man sich befindet. Außerdem kann eine freie Adresse eingetragen werden. If the Make My Server Public check box is checked, this will show whether registration with the directory server is successful. If the registration failed, please choose another server list. Wenn die Checkbox "Veröffentliche meinen Server" angewählt ist, wird angezeigt ob die Registrierung am Verzeichnis erfolgreich ist. The Directory server address is the IP address or URL of the directory server at which this server is registered. Pre-defined server addresses are available Die Verzeichnisserveradresse ist die IP-Adresse oder URL des Verzeichnisservers bei dem man sich registrieren möchte. Vordefinierte Serveradressen sind verfügbar. Default directory server type combo box Voreingestellter Verzeichnisservertyp Auswahlbox If the start minimized on operating system start check box is checked, the server will be started when the operating system starts up and is automatically minimized to a system task bar icon. Wenn diese Funktion angehakt ist, dann wird der Server automatisch mit dem Betriebssystemstart geladen und erscheint minimiert in der Systemleiste als Icon. If the Make My Server Public check box is checked, this server registers itself at the directory server so that all users of the application can see the server in the connect dialog server list and connect to it. The registration of the server is renewed periodically to make sure that all servers in the connect dialog server list are actually available. Mit dieser Funktion wird der eigene Server in der Serverliste des Verzeichnisservers registriert so dass alle anderen Applikationsnutzer den Server in der Liste sehen können und sich mit ihm verbinden können. Die Registrierung mit dem Verzeichnisserver wird periodisch erneuert um sicherzugehen, dass alle registrierten Server auch wirklich erreichbar sind. Custom Directory Server Address Benutzerdefinierte Verzeichnisserveradresse The custom directory server address is the IP address or URL of the directory server at which the server list of the connection dialog is managed. Die benutzerdefinierte Verzeichnisserveradresse ist die IP-Adresse oder URL des Verzeichnisservers, der die Serverliste für den Verbindungsdialog bereitstellt. Directory server address line edit Verzeichnisserveradresse Eingabefeld Server List Selection Serverlistenauswahl Selects the server list (i.e. directory server address) in which your server will be added. Wählt die Serverliste (d.h. die Verzeichnisserveradresse) aus, in der dein Server registriert werden soll. Server list selection combo box Severlistenauswahl Selektion Server Name Servername The server name identifies your server in the connect dialog server list at the clients. If no name is given, the IP address is shown instead. Der Servername identifiziert deinen Server in der Serverliste. Falls kein Name angegeben wurde, dann wird die IP-Adresse stattdessen angezeigt. The server name identifies your server in the connect dialog server list at the clients. Der Servername identifiziert deinen Server in der Serverliste. Server name line edit Servername Eingabefeld Location City Standort Stadt The city in which this server is located can be set here. If a city name is entered, it will be shown in the connect dialog server list at the clients. Hier kann man die Stadt angeben, in der sich der Server befindet. Falls eine Stadt angegeben wurde, dann wird die in der Serverliste angezeigt. City where the server is located line edit Stadt in der sich der Server befindet Eingabefeld Location country Standort Land The country in which this server is located can be set here. If a country is entered, it will be shown in the connect dialog server list at the clients. Hier kann man das Land eingeben, in dem sich der Server befindet. Falls ein Land angegeben wurde, dann wird das in der Serverliste angezeigt. Country where the server is located combo box Land in dem sich der Server befindet Auswahlbox Country/Region Land/Region Set the country or region where the server is running. Clients will show this location in their connect dialog's server list. Setze das Land oder die Region wo der Server läuft. Clients werden diese Location in der Liste im Verbindungsdialog anzeigen. Combo box for location of this server Combobox für die Location dieses Servers Recording has been switched off by the UI checkbox. Die Aufnahme wurde über die Checkbox in der Benutzeroberfläche ausgeschaltet. Recording has been switched off, either by the UI checkbox or SIGUSR2 being received. Die Aufnahme wurde entweder durch eine Auswahl in der Benutzeroberfläche oder das SIGUSR2 Signal beendet. Display dialog to select recording directory button Zeige den Dialog zum das Aufnahmeverzeichnis festzulegen Knopf Main Recording Directory Aufnahmehauptverzeichnis Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user Jamulus is running as). Drücke den Knopf um einen Dialog anzuzeigen in dem man das Hauptverzeichnis für die Aufnahmen festlegen kann. Das Verzeichnis muss existieren und schreibbar sein (es muss für das Benutzerkonto, das die Applikation ausführt, möglich sein Unterverzeichnisse anzulegen). Main recording directory text box (read-only) Hauptaufnahmeverzeichnis Textbox (schreibgeschützt) The current value of the main recording directory. The chosen value must exist and be writeable (allow creation of sub-directories by the user Jamulus is running as). Click the button to open the dialog that allows the main recording directory to be selected. Dies ist das aktuelle Aufnahmeverzeichnis. Das Verzeichnis muss existieren und der Benutzer Jamulus muss Schreibrechte haben und Verzeichnisse erstellen können. Wenn man den Knopf drückt, dann erscheint ein Dialog zum Auswählen des Verzeichnisses. Clear the recording directory button Lösche das Aufnahmeverzeichnis Knopf Clear Recording Directory Zurücksetzen des Aufnahmeverzeichnisses Click the button to clear the currently selected recording directory. This will prevent recording until a new value is selected. Drücke den Knopf um das aktuelle Aufnahmeverzeichnis zurückzusetzen. Damit wird eine neue Aufnahme verhindert bis wieder ein neues Verzeichnis gesetzt wurde. Checkbox to turn on or off server recording Schalter zum aktivieren oder deaktivieren der Aufnahmefunktion If the Register Server check box is checked, this will show whether registration with the directory server is successful. If the registration failed, please choose another server list. Wenn die Checkbox "Veröffentliche meinen Server in der Serverliste" angewählt ist, wird angezeigt, ob die Registrierung am Verzeichnisserver erfolgreich ist. Wenn die Registrierung fehlgeschlagen ist, wähle bitte eine andere Liste aus. Enable Recorder Aktiviere die Aufnahmefunktion Checked when the recorder is enabled, otherwise unchecked. The recorder will run when a session is in progress, if (set up correctly and) enabled. Angehakt, wenn die Aufnahmefunktion aktiviert ist. Die Aufnahme wird automatisch gestartet, wenn eine Jam-Session läuft. Current session directory text box (read-only) Aktuelle Session Checkbox Current Session Directory Verzeichnisname für das Speichern der Aufnahmen Enabled during recording and holds the current recording session directory. Disabled after recording or when the recorder is not enabled. Wenn die Aufnahmefunktion aktiviert ist, dann kann das Verzeichnis ausgewählt werden, in dem die Aufnahmen gespeichert werden. Recorder status label Recorder Statusanzeige Recorder Status Aufnahmestatus Displays the current status of the recorder. The following values are possible: Zeigt den aktuellen Status der Aufnahmefunktion an. Die folgenden Zustände sind möglich: No recording directory has been set or the value is not useable. Es wurde kein Aufnahmeverzeichnis gesetzt oder es wurde ein ungültiges Aufnahmeverzeichnis angegeben. Recording has been switched off Die Aufnahme wurde beendet by the UI checkbox in der Benutzerschnittstelle , either by the UI checkbox or SIGUSR2 being received , entweder von der Auswahl in der Benutzeroberfläche oder von einem empfangenen SIGUSR2-Signal There is no one connected to the server to record. Es ist kein Musiker mit dem Server verbunden. The performers are being recorded to the specified session directory. Die Aufnahme ist aktiv. NOTE HINWEIS If the recording directory is not useable, the problem will be displayed in place of the directory. Wenn das Aufnahmeverzeichnis ungültig ist, dann wird die Problembeschreibung anstelle des Verzeichnisnamens angezeigt. Server welcome message edit box Server Willkommenstext Eingabefeld Server Welcome Message Server Willkommensnachricht A server welcome message text is displayed in the chat window if a musician enters the server. If no message is set, the server welcome is disabled. Eine Server Willkommensnachricht wird im Chat-Fenster angezeigt, wenn sich ein Musiker mit dem Server verbindet. Ist kein Text gesetzt, dann ist die Willkommensnachricht deaktiviert. Language Sprache Select the language to be used for the user interface. Wähle die Sprache der Benutzeroberfläche aus. Language combo box Sprache Combo-Box Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user Jamulus is running as). Klicke auf den Knopf, um einen Dialog anzuzeigen, in dem man das Hauptverzeichnis für die Aufnahmen festlegen kann. Das Verzeichnis muss existieren und schreibbar sein (es muss für das Benutzerkonto, das die Applikation ausführt, möglich sein, Unterverzeichnisse anzulegen). Custom Directory Benutzerdefiniertes Verzeichnis The custom directory is the IP address or URL of the directory server at which the server list of the connection dialog is managed. Die benutzerdefinierte Verzeichnisserveradresse ist die IP-Adresse oder URL des Verzeichnisservers, der die Serverliste für den Verbindungsdialog bereitstellt. Custom Directory line edit Benutzerdefinierte Verzeichnisse Zeile bearbeiten &Hide %1 server Mi&nimiere %1 Server &Show %1 server Zeige %1 &Server %1 server %1 is the name of the main application %1 Server Type a message here. If no message is set, the server welcome is disabled. Willkommensnachricht eingeben. Ist kein Text gesetzt, dann ist die Willkommensnachricht deaktiviert. %1 Server %1 is the name of the main application %1 Server software upgrade available Softwareupdate verfügbar Recorder failed to start. Please check available disk space and permissions and try again. Error: Aufnahme konnte nicht gestartet werden. Bitte überprüfe den verfügbaren Speicherplatz sowie die Zugriffsrechte und versuche es erneut. Fehler: ERROR FEHLER Displays the current status of the recorder. Zeigt den Aufnahmestatus an. Request new recording button Anfordern einer neuen Aufnahme New Recording Neue Aufnahme During a recording session, the button can be used to start a new recording. Mit diesem Knopf kann man die Aufnahme neu starten (d.h. es wird eine neue Aufnahmedatei angelegt). E&xit &Beenden &Hide &Ausblenden vom server Server &Open Ö&ffne den server Server Select Main Recording Directory Wähle das Aufnahmehauptverzeichnis aus Predefined Address Vordefinierte Adresse Recording Aufnahme Not recording Keine Aufnahme Not initialised Nicht initialisiert Not enabled Nicht aktiviert Manual Manuell Default Standard Default (North America) Standard (Nordamerika) &Window &Fenster Unregistered Nicht registriert None Keins Not registered Nicht registriert Bad address Ungültige Adresse Registration requested Registrierung angefordert Registration failed Registrierung fehlgeschlagen Check server version Überprüfe Version des Servers Registered Registriert Directory server list full Verzeichnis Server-Liste voll Directory Server full Verzeichnisserver voll Your server version is too old Deine Serverversion ist zu alt Requirements not fulfilled Anfoderungen nicht erfüllt Unknown value %1 Unbekannter Wert %1 Unknown value Unbekannter Wert CServerDlgBase Client IP:Port Teilnehmer IP:Port Name Name Jitter Buffer Size Netzwerkpuffergröße Channels Kanäle Server Setup Server Konfiguration List Liste Location: Region Location: Region Session Session Chat Window Welcome (HTML/CSS Supported) Chat-Fenster Willkommensnachricht (HTML/CSS wird unterstützt) Options Optionen Custom Directory address Benutzerdefinierte Verzeichnisadresse Server List Filename Serverliste Dateiname Start Minimized on Windows Start Starte minimiert beim Windows-Start Enable delay panning Aktiviere verzögertes Panning Show Creative Commons BY-NC-SA 4.0 Licence Dialog Zeige den Creative Commons BY-NC-SA 4.0 Lizenzdialog Update check Update check Make My Server Public (Register My Server in the Server List) Veröffentliche meinen Server in der Serverliste Genre Genre STATUS Custom Directory Server Address: Benutzerdefinierte Verzeichnisserveradresse: Recording Directory Aufnahmeverzeichnis Enable Jam Recorder Aktiviere die Aufnahmefunktion Directory Verzeichnis New Recording Neue Aufnahme Language Consider add "(Lang)" as a suffix to ensure that users who selected the wrong language find the correct button Sprache Directory Server Address: Verzeichnisserveradresse My Server Info Meine Serverinformationen Location: City Standort: Stadt Location: Country Standort: Land Enable jam recorder Aktivere die Aufnahme New recording Neue Aufnahme Recordings folder Verzeichnis für die Aufnahmen CServerListManager Could not write to '%1' Konnte nicht nach '%1' schreiben CSound The Jack server is not running. This software requires a Jack server to run. Normally if the Jack server is not running this software will automatically start the Jack server. It seems that this auto start has not worked. Try to start the Jack server manually. Der Jack-Server läuft nicht. Diese Software benötigt aber einen Jack-Server um zu funktionieren. Normalerweise wird der Jack-Server automatisch gestartet. Es scheint so, als hätte dieser Automatismus nicht funktioniert. Versuche den Jack-Server manuell zu starten. The Jack server sample rate is different from the required one. The required sample rate is: Die Jack-Server-Samplerate ist verschieden zu der benötigen. Die benötigte Samplerate ist: You can use a tool like <i><a href="https://qjackctl.sourceforge.io">QJackCtl</a></i> to adjust the Jack server sample rate. Du kannst ein Werkzeug wie <i><a href="https://qjackctl.sourceforge.io">QJackCtl</a></li> verwenden um die Samplerate umzustellen. Make sure to set the Frames/Period to a low value like Versichere dich, dass die Frames/Perioden auf einen niedrigen Wert wie zum Beispiel to achieve a low delay. eingestellt ist um eine niedrige Verzögerung zu erreichen. The Jack port registering failed. Die Jack-Portregistrierung ist fehlgeschlagen. Cannot activate the Jack client. Der Jack-Client kann nicht aktiviert werden. The Jack server was shut down. This software requires a Jack server to run. Try to restart the software to solve the issue. Der Jack-Server wurde gestoppt. Diese Software benötigt aber einen aktiven Jack-Server um zu funktionieren. Versuche die Software neu zu starten um das Problem zu lösen. CoreAudio input AudioHardwareGetProperty call failed. It seems that no sound card is available in the system. CoreAudio Eingang AudioHardwareGetProperty Aufruf schlug fehl. Es scheint als wäre keine Soundkarte im System vorhanden. CoreAudio output AudioHardwareGetProperty call failed. It seems that no sound card is available in the system. CoreAudio Ausgang AudioHardwareGetProperty Aufruf schlug fehl. Es scheint, dass keine Soundkarte ist im System verfügbar. The previously selected audio device is no longer available. The system default audio device will be selected instead. Die vorher ausgewählte Soundkarte ist nicht mehr im System verfügbar. Die System-Standardsoundkarte wird nun stattdessen ausgewählt. Current audio input device is no longer available. Das aktuelle Audiogerät für den Toneingang ist nicht mehr verfügbar. Current system audio input device sample rate of %1 Hz is not supported. Please open the Audio-MIDI-Setup in Applications->Utilities and try to set a sample rate of %2 Hz. Die aktuelle Eingangssamplerate von %1 Hz wird nicht unterstützt. Bitte öffne die Audio-MIDI-Setup-Applikation in Applikationen->Werkzeuge und versuche die Samplerate auf %2 Hz einzustellen. Current audio output device is no longer available. Das aktuelle Audiogerät für den Tonausgang ist nicht mehr verfügbar. The current selected audio device is no longer present in the system. Die ausgewählte Soundkarte ist nicht mehr im System verfügbar. The audio input device is no longer available. Das aktuelle Audiogerät für den Toneingang ist nicht mehr verfügbar. The audio output device is no longer available. Das aktuelle Audiogerät für den Tonausgang ist nicht mehr verfügbar. Current system audio output device sample rate of %1 Hz is not supported. Please open the Audio-MIDI-Setup in Applications->Utilities and try to set a sample rate of %2 Hz. Die aktuelle Ausgangssamplerate von %1 Hz wird nicht unterstützt. Bitte öffne die Audio-MIDI-Setup-Applikation in Applikationen->Werkzeuge und versuche die Samplerate auf %2 Hz einzustellen. The audio input stream format for this audio device is not compatible with this software. Das Audioeingangsstromformat von diesem Audiogerät ist nicht kompatibel mit dieser Software. The audio output stream format for this audio device is not compatible with this software. Das Audioausgangsstromformat von diesem Audiogerät ist nicht kompatibel mit dieser Software. The buffer sizes of the current input and output audio device cannot be set to a common value. Please choose other input/output audio devices in your system settings. Die Puffergrößen vom aktuellen Eingangs- und Ausgangsaudiogerät kann nicht auf einen gemeinsamen Wert eingestellt werden. Bitte wähle ein anderes Eingangs-/Ausgangsgerät aus der Geräteliste aus. The audio driver could not be initialized. Der Audiotreiber konnte nicht initialisiert werden. The audio device does not support the required sample rate. The required sample rate is: Das Audiogerät unterstützt nicht die benötigte Samplerate. Die benötigte Samplerate ist: The audio device does not support setting the required sampling rate. This error can happen if you have an audio interface like the Roland UA-25EX where you set the sample rate with a hardware switch on the audio device. If this is the case, please change the sample rate to Das Audiogerät unterstützt nicht die benötigte Samplerate. Dieser Fehler kann auftreten, wenn ein Audiogerät wie das Roland UA-25EX verwendet wird, bei dem die Samplerate per Schalter am Gerät verstellt werden muss. Falls das der Fall sein sollte, dann stelle bitte den Schalter auf Hz on the device and restart the Hz am Gerät und starte die software. Software neu. The audio device does not support the required number of channels. The required number of channels for input and output is: Das Audiogerät unterstützt nicht die benötigte Anzahl an Kanälen. Die benötigte Anzahl an Kanälen für den Eingang und den Ausgang ist: Required audio sample format not available. Das benötigte Audio Sampleformat ist nicht verfügbar. The selected audio device is no longer present in the system. Please check your audio device. Das gewählte Audio Gerät ist nicht mehr im System verfügbar. Bitte überprüfe Dein Audio Gerät. Couldn't initialise the audio driver. Check if your audio hardware is plugged in and verify your driver settings. Der Audio-Treiber konnte nicht initialisiert werden. Überprüfe, ob Deine Audio Hardware angeschlossen ist und überprüfe die Treiber Einstellungen. The selected audio device is incompatible since it doesn't support a sample rate of %1 Hz. Please select another device. Das gewählte Audio Gerät ist nicht kompatibel, da es eine Samplerate von %1 Hz nicht unterstützt. Bitte wähle ein anderes Gerät. The current audio device configuration is incompatible because the sample rate couldn't be set to %2 Hz. Please check for a hardware switch or driver setting to set the sample rate manually and restart %1. Die aktuelle Audio-Geräte-Konfiguration ist inkompatibel, weil die Samplerate nicht auf %2 Hz gesetzt werden konnte. Bitte suche nach einem Hardwareknopf oder einer Treibereinstellung, mit der du die Sample Rate manuell setzen kannst. Starte %1 dann neu. The selected audio device is incompatible since it doesn't support %1 in/out channels. Please select another device or configuration. Das gewählte Audio Gerät ist nicht kompatibel, da es %1 Ein/Ausgangskanäle nicht unterstützt. Bitte wähle ein anderes Gerät oder eine andere Konfiguration. The selected audio device is incompatible since the required audio sample format isn't available. Please use another device. Das gewählte Audio Gerät ist nicht kompatibel, da das benötigte Audio Sample Format nicht verfügbar ist. Bitte wähle ein anderes Gerät. No ASIO audio device driver found. Kein ASIO-Audio-Treiber gefunden. Please install an ASIO driver before running %1. If you own a device with ASIO support, install its official ASIO driver. If not, you'll need to install a universal driver like ASIO4ALL. Bitte installiere einen ASIO Treiber bevor du %1 startest. Wenn Du ein Gerät mit ASIO Support besitzt, installiere seinen offziellen ASIO Treiber. Falls nicht, musst Du einen Universaltreiber wie ASIO4ALL instalieren. Please install an ASIO driver before running %1. If you own a device with ASIO support, install its official ASIO driver. If not, you'll need to download and install a universal driver like ASIO4ALL. Bitte installiere einen ASIO-Treiber bevor Du %1 startest. Wenn Du ein Gerät mit ASIO-Unterstützung hast, installiere dessen offiziellen ASIO-Treiber. Wenn nicht, mußt Du Dir einen universellen Treiber wie z.B. ASIO4ALL herunterladen und installieren. No ASIO audio device (driver) found. Kein ASIO-Gerätetreiber wurde gefunden. The Die software requires the low latency audio interface ASIO to work properly. This is not a standard Windows audio interface and therefore a special audio driver is required. Either your sound card has a native ASIO driver (which is recommended) or you might want to use alternative drivers like the ASIO4All driver. Software benötigt aber ein ASIO Audiointerface um zu funktionieren. Dies ist keine Standard-Windowsschnittstelle und benötigt deshalb einen speziellen Treiber. Entweder die Soundkarte liefert einen nativen ASIO-Treiber mit (was empfohlen wird) oder man versucht es mit dem ASIO4All-Universaltreiber. Error requesting stream stop: $s Fehler beim Anfordern stream stop: $s Error closing stream: $s Fehler beim Schließen des Datenstroms: $s JACK couldn't be started automatically. Please start JACK manually and check for error messages. JACK konnte nicht automatisch gestartet werden. Bitte starte JACK manuell und suche nach Fehlermeldungen. JACK isn't running at a sample rate of <b>%1 Hz</b>. Please use a tool like <i><a href="https://qjackctl.sourceforge.io">QjackCtl</a></i> to set the the JACK sample rate to %1 Hz. JACK läuft nicht mit einer Samplerate von <b>%1 Hz</b>. Bitte benutze ein Tool wie <i><a href="https://qjackctl.sourceforge.io">QjackCtl</a></i>, um die JACK Sample Rate auf %1 Hz zu setzen. The JACK port registration failed. This is probably an error with JACK. Please stop %1 and JACK. Afterwards check if another program at a sample rate of %2 Hz can connect to JACK. Die JACK Portregistrierung ist fehlgeschlagen. Das ist wahrscheinlich ein JACK Fehler. Bitte stoppe %1 und JACK. Danach prüfe, ob ein anderes Programm mit einer Samplerate von %2 Hz sich mit JACK verbinden lässt. The JACK port registration failed. This is probably an error with JACK. Please stop %1 and JACK. Afterwards, check if another MIDI program can connect to JACK. Die JACK Portregistrierung ist fehlgeschlagen. Das ist wahrscheinlich ein JACK Fehler. Bitte stoppe %1 und JACK. Danach prüfe, ob ein anderes MIDI Programm sich mit JACK verbinden lässt. Can't activate the JACK client. This is probably an error with JACK. Please check the JACK output. Kann den JACK Client nicht aktivieren. Dies ist wahrscheinlich ein Fehler mit JACK. Bitte überprüfe den JACK-Ausgang. JACK was shut down. %1 requires JACK to run. Please restart %1 to start JACK again. JACK wurde beendet. Um %1 zu nutzen, muss JACK laufen. Bitte starte %1 neu, um JACK wieder zu starten. No sound card is available in your system. CoreAudio input AudioHardwareGetProperty call failed. Es wurde keine Soundkarte ist im System gefunden. Der CoreAudio input AudioHardwareGetProperty call ist fehlgeschlagen. No sound card is available in the system. CoreAudio output AudioHardwareGetProperty call failed. Es wurde keine Soundkarte ist im System gefunden. Der CoreAudio output AudioHardwareGetProperty call ist fehlgeschlagen. The currently selected audio device is no longer present. Please check your audio device. Das momentan ausgewählte Audio Gerät ist nicht mehr verfügbar. Bitte überprüfe dein Audiogerät. The audio input device is no longer available. Please check if your input device is connected correctly. Das momentan ausgewählte Audio Eingangsgerät ist nicht mehr verfügbar. Bitte überprüfe, ob Dein Eingangsgerät korrekt angeschlossen ist. The sample rate on the current input device isn't %1 Hz and is therefore incompatible. Please select another device or try setting the sample rate to %1 Hz manually via Audio-MIDI-Setup (in Applications->Utilities). Die Sample Rate des aktuellen Eingangsgerät beträgt nicht %1 Hz und ist somit nicht kompatibel. Bitte wähle ein anderes Gerät oder versuche manuell die Sample Rate auf %1 Hz zu setzen. Probiere das über das Audio-MIDI Setup (In Programme>Dienstprogramme). The audio output device is no longer available. Please check if your output device is connected correctly. Das momentan ausgewählte Audio Ausgangsgerät ist nicht mehr verfügbar. Bitte überprüfe, ob Dein Ausgangsgerät korrekt angeschlossen ist. The sample rate on the current output device isn't %1 Hz and is therefore incompatible. Please select another device or try setting the sample rate to %1 Hz manually via Audio-MIDI-Setup (in Applications->Utilities). Die Sample Rate des aktuellen Ausgangsgeräts beträgt nicht %1 Hz und ist somit nicht kompatibel. Bitte wähle ein anderes Gerät oder versuche manuell die Sample Rate über das Audio-MIDI Setup (In Programme>Dienstprogramme) auf %1 Hz zu setzen. The stream format on the current input device isn't compatible with this software. Please select another device. Das Stream Format des aktuellen Eingangsgeräts ist nicht kompatibel mit dieser Software. Bitte wähle ein anderes Gerät. The stream format on the current output device isn't compatible with %1. Please select another device. Das Stream Format des aktuellen Ausgangsgeräts ist nicht kompatibel mit %1. Bitte wähle ein anderes Gerät. The buffer sizes of the current input and output audio device can't be set to a common value. Please select different input/output devices in your system settings. Die Puffergrösse der aktuellen Ein- und Ausgangs Geräte können nicht auf den gleichen Wert gesetzt werden. Bitte wähle andere Input/-Output Geräte in Deinen System Einstellungen aus. CSoundBase Invalid device selection. Ungültige Geräteauswahl. The audio driver properties have changed to a state which is incompatible with this software. The selected audio device could not be used because of the following error: Die Audiotreibereigenschaften haben sich geändert. Die neuen Einstellungen sind nicht mehr kompatibel zu dieser Software. Das ausgewählte Audiogerät konnte nicht benutzt werden wegen folgendem Fehler: Please restart the software. Bitte starte die Software neu. The selected audio device could not be used because of the following error: Das ausgewählte Audiogerät kann aus folgendem Grund nicht verwendet werden: The previous driver will be selected. Der vorherige Treiber wird wieder ausgewählt. The previously selected audio device is no longer available or the audio driver properties have changed to a state which is incompatible with this software. We now try to find a valid audio device. This new audio device might cause audio feedback. So, before connecting to a server, please check the audio device setting. Das aktuell ausgewählte Audiogerät ist nicht mehr verfügbar oder die Treibereinstellungen sind nicht mehr mit dieser Software kompatibel. Es wird nun versucht, ein funktionierendes Audiogerät zu finden. Dieses neue Audiogerät könnte eine Tonrückkopplung verursachen. Bitte überprüfe deswegen die Audiogeräteeinstellungen vor der nächsten Verbindung mit dem Server. No usable Kein benutzbares audio device (driver) found. Audiogerät (Treiber) konnte gefunden werden. In the following there is a list of all available drivers with the associated error message: Im folgenden wird eine Liste aller gefundenen Audiogeräte mit entsprechender Fehlermeldung angezeigt: Do you want to open the ASIO driver setups? Willst du die ASIO-Treibereinstellungen öffnen? could not be started because of audio interface issues. konnte nicht gestartet werden wegen Problemen mit dem Audiogerät. Can't use the selected audio device because of the following error: %1 The previous driver will be selected. Das gewählte Audiogerät kann aufgrund des folgenden Fehlers nicht genutzt werden: %1. Der vorherige Treiber wird gewählt. The previously selected audio device is no longer available or the driver has changed to an incompatible state. We'll attempt to find a valid audio device, but this new audio device may cause feedback. Before connecting to a server, please check your audio device settings. Der vorher ausgewählte Audio Gerätetreiber ist nicht mehr verfügbar oder der Treiber ist in einen inkompatiblen Status gewechselt. Wir werden versuchen, ein passendes Audio Gerät zu finden, aber das neue Audio Gerät könnte Rückkoppelung verursachen. Überprüfe die Audiogeräte vor dem Verbinden mit einem Server. <b>%1 couldn't find a usable %2 audio device.</b><br><br> <b>%1 konnte kein nutzbares %2 Audiogerät finden.</b><br><br> You may be able to fix errors in the driver settings. Do you want to open these settings now? Du kannst die Fehler eventuell in den Treibereinstellungen beheben. Möchtest du diese Einstellungen jetzt öffnen? No usable %1 audio device found. Kein nutzbares %1 Audiogerät gefunden. These are all the available drivers with error messages: Das sind alle verfügbaren Treiber mit Fehlermeldungen: Do you want to open the ASIO driver setup to try changing your configuration to a working state? Möchtest Du den das ASIO Treiber Setup öffnen und versuchen eine funktionsfähige Konfiguration wiederherzustellen? Can't start %1. Please restart %1 and check/reconfigure your audio settings. %1 kann nicht gestartet werden. Bitte starte %1 neu und prüfe Deine Audio Einstellungen. QCoreApplication %1, Version %2 %1, Version %2 Internet Jam Session Software Internet Jam Session Software %1, Version %2 %1 is app name, %2 is version number %1, Version %2 Released under the GNU General Public License version 2 or later (GPLv2) Veröffentlicht unter der GNU General Public License version 2 oder später (GPLv2) Using the following libraries, resources or code snippets: Die folgenden Bibliotheken, Ressourcen oder Codeschnipsel werden verwendet: Qt framework Qt framework Opus Interactive Audio Codec Opus Interactive Audio Codec Audio reverberation code by Perry R. Cook and Gary P. Scavone Halleffekt von Perry R. Cook und Gary P. Scavone Some pixmaps are from the Open Clip Art Library (OCAL) Manche Pixmaps sind aus der Open Clip Art Library (OCAL) Flag icons by Mark James Die Bilder der Länderflaggen sind von Mark James Copyright (C) 2005-2022 The Jamulus Development Team Copyright (C) 2005-2022 beim Jamulus Entwicklungs Team Released under the GNU General Public License (GPL) Unter der GNU General Public License (GPL) global A %1 upgrade is available: <a style='color:red;' href='https://jamulus.io/upgrade?progversion=%2'>go to details and downloads</a> Ein %1 Upgrade ist verfügbar: <a style='color:red;' href='https://jamulus.io/de/upgrade?progversion=%2'>öffne Details und Downloads</a> For more information use the "What's This" help (help menu, right mouse button or Shift+F1) Für weitere Informationen verwende die "Kontexthilfe" (Hilfe-Menü, rechte Maustaste oder Tastenkombination Shift+F1) jamulus-3.9.1+dfsg/src/translation/translation_es_ES.ts0000644000175000017500000103654214340334543022300 0ustar vimervimer CAboutDlg The El software software enables musicians to perform real-time jam sessions over the internet. There is a software permite a músicos realizar jam sessions en tiempo real por internet. Hay un software enables musicians to perform real-time jam sessions over the internet. permite a músicos realizar jam sessions en tiempo real por internet. server which collects the audio data from each que recoge el audio de cada cliente There is a Hay un servidor client, mixes the audio data and sends the mix back to each client. , mezcla el audio y lo envía de vuelta a cada cliente. uses the following libraries, resources or code snippets: utiliza las siguientes librerías, recursos o fragmentos de código: Qt cross-platform application framework Qt cross-platform application framework Audio reverberation code by Perry R. Cook and Gary P. Scavone Código de reverberación de audio de Perry R. Cook y Gary P. Scavone Some pixmaps are from the Algunos pixmaps son del Country flag icons from Mark James Iconos de banderas nacionales de Mark James This app enables musicians to perform real-time jam sessions over the internet. Esta aplicación permite a músicos realizar jam sessions en tiempo real por internet. There is a server which collects the audio data from each client, mixes the audio data and sends the mix back to each client. Hay un servidor que recoge el audio de cada cliente, los combina y envía la mezcla de vuelta a cada cliente. This app uses the following libraries, resources or code snippets: Esta aplicación utiliza las siguientes librerías, recursos o fragmentos de código: Country flag icons by Mark James Iconos de banderas nacionales de Mark James For details on the contributions check out the Para más detalles sobre los contribuidores consulta la Flag icons by Mark James Iconos de banderas de Mark James Some sound samples are from Algunas muestras de audio son de For details on the contributions check out the %1 Para detalles sobre las contribuciones mira la %1 Github Contributors list lista de Contribuidores en Github Spanish Español French Francés Portuguese Portugués Dutch Neerlandés Italian Italiano German Alemán Polish Polaco Swedish Sueco Korean Coreano Slovak Eslovaco Simplified Chinese Chino Simplificado Norwegian Bokmål About %1 Acerca de %1 About Acerca de , Version , Versión Internet Jam Session Software Internet Jam Session Software Released under the GNU General Public License (GPL) Publicado bajo la GNU General Public License (GPL) Under the GNU General Public License (GPL) Bajo la GNU General Public License (GPL) CAboutDlgBase About Acerca de TextLabelVersion TextLabelVersion Copyright (C) 2005-2022 Volker Fischer and others Copyright (C) 2005-2022 Volker Fischer y otros Copyright (C) 2005-2022 The Jamulus Development Team Copyright (C) 2005-2022 El Equipo de Desarrollo de Jamulus A&bout &Acerca de &Libraries &Librerías &Contributors &Contribuidores &Translation &Traducción &OK &OK CAnalyzerConsole Analyzer Console Analyzer Console Error Rate of Each Buffer Size Tasa de Error de Cada Tamaño de Buffer CAudioMixerBoard Personal Mix at the Server Mezcla personal en el Servidor When connected to a server, the controls here allow you to set your local mix without affecting what others hear from you. The title shows the server name and, when known, whether it is actively recording. Estando conectado a un servidor, estos controles te permiten hacer tu mezcla personal sin afectar lo que otros escuchan de tí. El título muestra el nombre del servidor y, cuando se conoce, si está activamente grabando. Server Servidor T R Y I N G T O C O N N E C T I N T E N T A N D O C O N E C T A R RECORDING ACTIVE GRABACIÓN ACTIVA Personal Mix at: %1 Mezcla Personal en el Servidor: %1 CChannelFader Channel Level Nivel Canal Displays the pre-fader audio level of this channel. All connected clients at the server will be assigned an audio level, the same value for each client. Muestra el nivel de audio pre-fader de este canal. Todos los clientes conectados al servidor tienen un nivel de audio asignado, el mismo para cada cliente. Input level of the current audio channel at the server Nivel de entrada del canal de audio actual en el servidor Mixer Fader Fader Mezclador Adjusts the audio level of this channel. All connected clients at the server will be assigned an audio fader at each client, adjusting the local mix. Ajusta el nivel de audio de este canal. Todos los clientes conectados al servidor tienen asignado un fader en el cliente, ajustando la mezcla local. Local mix level setting of the current audio channel at the server Ajuste local de la mezcla del canal de audio actual en el servidor Status Indicator Indicador de Estado Shows a status indication about the client which is assigned to this channel. Supported indicators are: Muestra una indicación del estado del cliente asignado a este canal. Los indicadores soportados son: Speaker with cancellation stroke: Indicates that the other client has muted you. Altavoz tachado: Indica que el otro cliente te ha muteado. Status indicator label Etiqueta indicador estado Panning Paneo Sets the panning position from Left to Right of the channel. Works only in stereo or preferably mono in/stereo out mode. Fija el paneo de Izquierda a Derecha del canal. Solo funciona en estéreo o preferiblemente en modo Entrada mono/Salida estéreo. Local panning position of the current audio channel at the server Posición local del paneo del canal de audio actual en el servidor With the Mute checkbox, the audio channel can be muted. Activando Mute, se puede silenciar el canal de audio. Mute button Botón Mute With the Solo checkbox, the audio channel can be set to solo which means that all other channels except of the current channel are muted. It is possible to set more than one channel to solo. Activando Solo, todos los demás canales de audio excepto este se mutean. Es posible activar esta función para más de un canal. Solo button Botón Solo Fader Tag Etiqueta Fader The fader tag identifies the connected client. The tag name, the picture of your instrument and a flag of your country can be set in the main window. La etiqueta del fader identifica al cliente conectado. El nombre de la etiqueta, la imagen de tu instrumento y la bandera de tu país se pueden establecer en la ventana principal. Grp Grp Displays the pre-fader audio level of this channel. All clients connected to the server will be assigned an audio level, the same value for every client. Muestra el nivel de audio pre-fader de este canal. Todos los clientes conectados al servidor tienen un nivel de audio asignado, el mismo valor para cada cliente. &No grouping &Sin grupos Assign to group Asignar a grupo Adjusts the audio level of this channel. All clients connected to the server will be assigned an audio fader, displayed at each client, to adjust the local mix. Ajusta el nivel de audio de este canal. Todos los clientes conectados al servidor tendrán asignado un fader, mostrado en cada cliente, para ajustar la mezcla local. Speaker with cancellation stroke: Indicates that another client has muted you. Altavoz tachado: Indica que otro cliente te ha muteado. Sets the pan from Left to Right of the channel. Works only in stereo or preferably mono in/stereo out mode. Fija el paneo de Izquierda a Derecha del canal. Solo funciona en modo estéreo o preferiblemente en modo Entrada mono/Salida estéreo. With the Solo checkbox, the audio channel can be set to solo which means that all other channels except the soloed channel are muted. It is possible to set more than one channel to solo. Activando Solo, todos los demás canales de audio excepto este se silencian. Es posible activar esta función para más de un canal. Group Grupo With the Grp checkbox, a group of audio channels can be defined. All channel faders in a group are moved in proportional synchronization if any one of the group faders are moved. Activando Grp se puede definir un grupo de canales. Todos los faders de un grupo se mueven en sincronización proporcional si se mueve cualquier fader del grupo. Group button Botón grupo The fader tag identifies the connected client. The tag name, a picture of your instrument and the flag of your country can be set in the main window. La etiqueta del fader identifica al cliente conectado. El nombre de la etiqueta, la imagen de tu instrumento y la bandera de tu país se pueden establecer en la ventana principal. Mixer channel instrument picture Imagen mezclador canal instrumento Mixer channel label (fader tag) Etiqueta mezclador canal (etiqueta fader) Mixer channel country flag Bandera país mezclador canal PAN PAN MUTE MUTE SOLO SOLO GRP GRP M M S S G G Alias/Name Alias/Nombre Instrument Instrumento Location Ubicación Skill Level Nivel Habilidad Alias Alias Beginner Principiante The fader tag identifies the connected client. The tag name, a picture of your instrument and the flag of your location can be set in the main window. La etiqueta del fader identifica el cliente conectado. El nombre de la etiqueta, una imagen de tu instrumento y la bandera de tu ubicación se pueden establecer en la ventana principal. Mixer channel country/region flag País/región del canal del mezclador Intermediate Intermedio Expert Experto Musician Profile Perfil Músico Mute Mute Pan Paneo Solo Solo CChatDlg Chat Window Ventana Chat The chat window shows a history of all chat messages. La ventana del chat muestra un historial de todos los mensajes. Chat history Historial chat Input Message Text Texto Mensaje Enter the chat message text in the edit box and press enter to send the message to the server which distributes the message to all connected clients. Your message will then show up in the chat window. Teclea el mensaje en el campo y pulsa Enter para enviar el mensaje al servidor, el cual distribuye el mensaje a todos los clientes conectados. Tu mensaje se mostrará en la ventana del chat. New chat text edit box Campo nuevo texto chat Type a message here Teclea un mensaje aquí &Edit E&ditar Cl&ear Chat History Li&mpiar Historial Chat &Close &Cerrar Do you want to open the link '%1' in your browser? ¿Quieres abrir el enlace '%1' en tu navegador? Do you want to open the link ¿Quieres abrir el enlace in an external browser? en un navegador externo? CChatDlgBase Chat Chat &Send &Enviar Cl&ear Va&ciar &Close &Cerrar CClientDlg Input Level Meter Indicador nivel entrada The input level indicators show the input level of the two stereo channels of the current selected audio input. Los indicadores de nivel de entrada muestran el nivel de entrada de los dos canales estéreo de la entrada de audio actualmente seleccionada. Make sure not to clip the input signal to avoid distortions of the audio signal. Asegúrate de no clipear la señal de entrada para evitar distorsiones de la señal de audio. If the Si el software software is connected and you play your instrument/sing in the microphone, the LED level meter should flicker. If this is not the case, you have probably selected the wrong input channel (e.g. line in instead of the microphone input) or set the input gain too low in the (Windows) audio mixer. está conectado y tocas tu instrumento/cantas por el micrófono, el LED del indicador debería parpadear. Si no es así, seguramente has seleccionado el canal de entrada equivocado (por ej. line in en lugar de la entrada del micrófono) o está muy bajo el gain de entrada en el mezclador de audio (Windows). For a proper usage of the Para un uso adecuado del software software, you should not hear your singing/instrument in the loudspeaker or your headphone when the , no deberías oír tu voz/instrumento por el altavoz o los auriculares cuando el software software is not connected. This can be achieved by muting your input audio channel in the Playback mixer (not the Recording mixer!). no está conectado. Esto se puede hacer muteando tu entrada de audio en el mezclador de Reproducción (¡y no en el de Grabación!). Input level meter Indicador nivel entrada Simulates an analog LED level meter. Simula un indicador analógico de LEDs. Connect/Disconnect Button Botón Conexión/Desconexión Push this button to connect to a server. A dialog where you can select a server will open. If you are connected, pressing this button will end the session. Pulsa este botón para conectar con un servidor. Se abrirá una ventana donde puedes seleccionar un servidor. Si estás conectado, este botón finalizará la sesión. Connect and disconnect toggle button Botón de conexión y desconexión Clicking on this button changes the caption of the button from Connect to Disconnect, i.e., it implements a toggle functionality for connecting and disconnecting the Pulsando este botón cambia el texto del mismo de Conectar a Desconectar; esto es, tiene la función de conmutador para conectar y desconectar el software software. . Local Audio Input Fader Fader Entrada Audio Local Local audio input fader (left/right) Fader entrada audio local (izq/dcho) Reverberation effect level setting Nivel efecto reverberación Left channel selection for reverberation Selección canal izq para reverberación Right channel selection for reverberation Selección canal dcho para reverberación If this LED indicator turns red, you will not have much fun using the Si este indicador LED se vuelve rojo, no te divertirás demasiado utilizando el This shows the level of the two stereo channels for your audio input. Esto muestra los niveles de los dos canales estéreo de tu entrada de audio. If the application is connected to a server and you play your instrument/sing into the microphone, the VU meter should flicker. If this is not the case, you have probably selected the wrong input channel (e.g. 'line in' instead of the microphone input) or set the input gain too low in the (Windows) audio mixer. Si la aplicación está conectada a un servidor y tocas tu instrumento/cantas por el micrófono, el vúmetro debería parpadear. Si no es así, seguramente has seleccionado el canal de entrada equivocado (por ej. line in en lugar de la entrada del micrófono) o está muy bajo el gain de entrada en el mezclador de audio (Windows). For proper usage of the application, you should not hear your singing/instrument through the loudspeaker or your headphone when the software is not connected. This can be achieved by muting your input audio channel in the Playback mixer (not the Recording mixer!). Para un uso adecuado de la aplicación, no deberías oír tu voz/instrumento por el altavoz o los auriculares cuando el software no está conectado. Esto se puede realizar silenciando tu canal de entrada de audio en el mezclador de Reproducción (¡no el de Grabación!). Clicking on this button changes the caption of the button from Connect to Disconnect, i.e., it implements a toggle functionality for connecting and disconnecting the application. Pulsando este botón cambia el texto del mismo de Conectar a Desconectar; esto es, tiene la función de conmutador para conectar y desconectar el software. Controls the relative levels of the left and right local audio channels. For a mono signal it acts as a pan between the two channels. For example, if a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows Controla los niveles relativos de los canales locales de audio derecho e izquierdo. Para una señal mono actúa como paneo entre los dos canales. Por ej., si se conecta un miocrófono al canal derecho y un instrumento al izquierdo que suena mucho más alto que el micrófono, mueve el fader en una dirección donde la etiqueta sobre el fader muestra Reverb effect Efecto reverb Reverb can be applied to one local mono audio channel or to both channels in stereo mode. The mono channel selection and the reverb level can be modified. For example, if a microphone signal is fed in to the right audio channel of the sound card and a reverb effect needs to be applied, set the channel selector to right and move the fader upwards until the desired reverb level is reached. Se puede aplicar un efecto de reverb a un canal local de audio mono o a ambos canales en modo estéreo. Se puede modificar la selección de canales en modo mono y el nivel de reverb. Por ej., si la señal del micrófono va por el canal derecho de la tarjeta de sonido y se desea aplicar reverb, cambia el selector de canal a derecho y sube el fader hasta alcanzar el nivel de reverb deseado. Reverb requires significant CPU so it should only be used on fast PCs. If the reverb level fader is set to minimum (the default setting), the effect is switched off and does not cause any additional CPU usage. El efecto de reverb requiere un esfuerzo importante del procesador, por lo que solo debería usarse en ordenadores potentes. Si se deja el fader de reverb al mínimo (la configuración por defecto), el efecto estará desactivado y no significará ninguna carga adicional para el procesador. Reverb effect level setting Nivel efecto reverb Reverb Channel Selection Selección Canal Reverb With these radio buttons the audio input channel on which the reverb effect is applied can be chosen. Either the left or right input channel can be selected. Con estos botones se puede escoger el canal de entrada de audio al que se aplica el efecto de reverb. Se pueden elegir los canales de entrada izquierdo o derecho. Left channel selection for reverb Selección canal izq para reverb Right channel selection for reverb Selección canal dcho para reverb The El software Green Verde The delay is perfect for a jam session. El retardo es perfecto para una jam session. Yellow Amarillo Red Rojo If this LED indicator turns red, you will not have much fun using the application Si este indicador LED se vuelve rojo, no te divertirás demasiado utilizando la aplicación Delay status LED indicator Indicador LED estado retardo Opens a dialog where you can select a server to connect to. If you are connected, pressing this button will end the session. Abre un diálogo donde puedes escoger un servidor al cual conectarte. Si estás conectado, pulsar este botón finalizará la sesión. Shows the current audio delay status: Muestra el estado actual del retardo de audio: The delay is perfect for a jam session El retardo es perfecto para una jam session A session is still possible but it may be harder to play. Una sesión aún es posible pero quizá sea más difícil tocar. The delay is too large for jamming. El retardo es demasiado grande para tocar. If this LED indicator turns red, you will not have much fun using the application. Si este indicador LED se vuelve rojo, no te divertirás demasiado utilizando la aplicación. The buffers status LED shows the current audio/streaming status. If the light is red, the audio stream is interrupted. This is caused by one of the following problems: El LED de estado de buffers muestra el estado actual del flujo de audio. Si está rojo, hay interrupciones en el flujo de audio. Esto puede ser causado por alguno de los siguientes problemas: The sound card's buffer delay (buffer size) is too small (see Settings window). El retardo de buffer de la tarjeta de audio (tamaño buffer) tiene un valor demasiado bajo (ver ventana de Configuración). The upload or download stream rate is too high for your internet bandwidth. La tasa de subida o bajada es demasiado alta para tu ancho de banda de Internet. Buffers status LED indicator Indicador LED estado buffers Current Connection Status Parameter Parámetro Estado Conexión Actual The Ping Time is the time required for the audio stream to travel from the client to the server and back again. This delay is introduced by the network and should be about 20-30 ms. If this delay is higher than about 50 ms, your distance to the server is too large or your internet connection is not sufficient. El Tiempo Ping es el tiempo que requiere el flujo de audio para viajar desde el cliente al servidor y volver. Este retardo lo determina la red y debería ser de unos 20-30 ms. Si este retardo es de unos 50 ms, la distancia al servidor es demasiado grande o tu conexión a internet no es óptima. Overall Delay is calculated from the current Ping Time and the delay introduced by the current buffer settings. El Retardo Total se calcula con el Tiempo Ping actual y el retardo ocasionado por la configuración de buffers. C&onnect C&onectar software upgrade available Actualización de software disponible &File &Archivo &View &Ver &Connection Setup... &Configuración de Conexión... My &Profile... Mi &Perfil... C&hat... C&hat... &Settings... C&onfiguración... &Analyzer Console... &Analyzer Console... Use &Two Rows Mixer Panel Usar Dos Filas Para Ven&tana Mezclador Clear &All Stored Solo and Mute Settings &Eliminar Todas las Configuraciones de Solo y Mute %1 Directory %1 Directorio Ok Ok E&xit &Salir &Edit &Editar Sort Users by &Group Ordenar Usuarios de Canal por &Grupo None Ninguno Center Centro R R L L With the audio fader, the relative levels of the left and right local audio channels can be changed. For a mono signal it acts like a panning between the two channels. If, e.g., a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows Con el fader de audio, los niveles relativos de los canales locales de audio derecho e izquierdo pueden cambiarse. Para una señal mono actúa como paneo entre los dos canales. Por ej., si se conecta un miocrófono al canal derecho y un instrumento al izquierdo que suena mucho más alto que el micrófono, mueve el fader en una dirección donde la etiqueta sobre el fader muestra , where , donde is the current attenuation indicator. es el indicador actual de atenuación. Reverberation Level Nivel Reverberación A reverberation effect can be applied to one local mono audio channel or to both channels in stereo mode. The mono channel selection and the reverberation level can be modified. If, e.g., the microphone signal is fed into the right audio channel of the sound card and a reverberation effect shall be applied, set the channel selector to right and move the fader upwards until the desired reverberation level is reached. Se puede aplicar un efecto de reverberación a un canal local de audio mono o a ambos canales en modo estéreo. Se puede modificar la selección de canales en modo mono y el nivel de reverberación. Por ej., si la señal del micrófono va por el canal derecho de la tarjeta de sonido y se desea aplicar reverberación, cambia el selector de canal a derecho y sube el fader hasta alcanzar el nivel de reverberación deseado. The reverberation effect requires significant CPU so it should only be used on fast PCs. If the reverberation level fader is set to minimum (which is the default setting), the reverberation effect is switched off and does not cause any additional CPU usage. El efecto de reverberación require un esfuerzo importante del procesador, por lo que solo debería usarse en ordenadores potentes. Si se deja el fader de reverberación al mínimo (la configuración por defecto), el efecto estará desactivado y no significará ninguna carga adicional para el procesador. Reverberation Channel Selection Selección Canal Reverberación With these radio buttons the audio input channel on which the reverberation effect is applied can be chosen. Either the left or right input channel can be selected. Con estos botones se puede escoger el canal de entrada de audio al que se aplica el efecto de reverberación. Se pueden elegir los canales de entrada izquierdo o derecho. Delay Status LED LED Estado Retardo The delay status LED indicator shows the current audio delay status. If the light is green, the delay is perfect for a jam session. If the light is yellow, a session is still possible but it may be harder to play. If the light is red, the delay is too large for jamming. El indicador LED del estado del retardo muestra el estado actual del retardo del audio. Si está en verde, el retardo es perfecto para una jam session. Si está en amarillo, la sesión aún es posible, pero quizá sea más difícil tocar. Si está en rojo, el retardo es demasiado alto para tocar. Buffers Status LED LED Estado Buffers The buffers status LED indicator shows the current audio/streaming status. If the light is green, there are no buffer overruns/underruns and the audio stream is not interrupted. If the light is red, the audio stream is interrupted caused by one of the following problems: El indicador LED del estado de buffers muestra el estado actual del flujo de audio. Si está verde, no hay problemas de buffer y no se interrumpe el flujo de audio. Si está rojo, el flujo de audio se interrumpe, a causa de uno de los siguientes problemas: The network jitter buffer is not large enough for the current network/audio interface jitter. El jitter buffer de red no es lo suficientemente grande para el jitter actual de la red/interfaz de audio. The sound card buffer delay (buffer size) is set to too small a value. El retardo de buffer de la tarjeta de audio (tamaño buffer) tiene un valor demasiado bajo. The upload or download stream rate is too high for the current available internet bandwidth. La tasa de subida o bajada is demasiado alta para el ancho de banda disponible de internet. The CPU of the client or server is at 100%. El procesador del cliente o del servidor está al 100%. If this LED indicator turns red, the audio stream is interrupted. Si este indicador LED se vuelve rojo, se interrumpe el flujo de audio. Current Connection Status Estado Actual de Conexión &Load Mixer Channels Setup... C&argar Configuración Canales Mezclador... &Save Mixer Channels Setup... &Guardar Configuración Canales Mezclador... Sett&ings Configurac&ión Audio/Network &Settings... Configuración de Audio/&Red... A&dvanced Settings... Configuración Avanza&da... N&o User Sorting N&o Ordenar Usuarios If this LED indicator turns red, you will not have much fun using %1. Si este indicador LED se vuelve rojo, no te divertirás demasiado utilizando %1. Local Jitter Buffer Status LED LED estado Jitter Buffer local The local jitter buffer status LED shows the current audio/streaming status. If the light is red, the audio stream is interrupted. This is caused by one of the following problems: El LED de estado de jitter buffer local muestra el estado actual del flujo de audio. Si está rojo, hay interrupciones en el flujo de audio. Esto puede ser causado por alguno de los siguientes problemas: Local Jitter Buffer status LED indicator Indicador LED estado Jitter Buffer local If this LED indicator turns red, you will not have much fun using the %1 software. Si este indicador LED se vuelve rojo, no te divertirás demasiado utilizando el software %1. O&wn Fader First Fader Pro&pio Primero Sort Users by &Name Ordenar Usuarios por &Nombre Sort Users by &Instrument Ordenar Usuarios por &Instrumento Sort Users by &City Ordenar Usuarios por &Ciudad Clear &All Stored Solo Settings &Eliminar Configuraciones Guardadas de Solo Set All Faders to New Client &Level Todos los Faders al Nivel C&liente Nuevo Auto-Adjust all &Faders Auto-Ajustar todos los &Faders &Settings Co&nfiguración Directory Server Servidor de Directorio Select Channel Setup File Seleccionar Archivo Configuración Canales user usuario users usuarios Connect Conectar Settings Configuración Chat Chat Enable feedback detection Activar detección de retroalimentación Audio feedback or loud signal detected. We muted your channel and activated 'Mute Myself'. Please solve the feedback issue first and unmute yourself afterwards. Detectada retroalimentación de audio o una señal muy alta. Hemos silenciado tu canal y activado 'Silenciarme Yo'. Por favor resuelve el problema de retroalimentación primero y después desactiva 'Silenciarme Yo'. Your sound card is not working correctly. Please open the settings dialog and check the device selection and the driver settings. Tu tarjeta de sonido no está funcionando correctamente. Por favor abre la ventana de configuración y comprueba la selección de dispositivo y la configuración del driver. &Disconnect &Desconectar CClientDlgBase Delay Retardo Buffers Buffers Input Entrada L L R R Jitter Jitter Ping Ping ms ms &Mute Myself Silenciar&me Yo &Settings Co&nfiguración &Chat &Chat C&onnect C&onectar Pan Paneo Center Centro Reverb Reverb Left Izq Right Dcho MUTED (Other people won't hear you) SILENCIADO (Otras personas no te escucharán) Set up your audio, connect to a server and start jamming! Configura tu audio, conéctate a un servidor y ¡empieza a tocar! Update check Comprobación de actualización MUTED (You are not sending any audio to the server) MUTEADO (No estás enviando audio al servidor) CClientSettingsDlg Jitter Buffer Size Tamaño Jitter Buffer The jitter buffer compensates for network and sound card timing jitters. The size of this jitter buffer has therefore influence on the quality of the audio stream (how many dropouts occur) and the overall delay (the longer the buffer, the higher the delay). El jitter buffer compensa el jitter de la red y la tarjeta de audio. El tamaño de este buffer tiene por tanto un impacto sobre la calidad del flujo de audio (el número de caídas de la señal) y el retardo total (a mayor buffer, mayor retardo). The jitter buffer size can be manually chosen for the local client and the remote server. For the local jitter buffer, dropouts in the audio stream are indicated by the light below the jitter buffer size faders. If the light turns to red, a buffer overrun/underrun took place and the audio stream is interrupted. El tamaño del jitter buffer se puede establecer para el cliente local y para el servidor remoto. Para el jitter buffer local, las caídas del flujo de audio se indican mediante la luz debajo de los faders del jitter buffer. Si la luz se vuelve roja, significa que ha habido una interrupción del flujo de audio. The jitter buffer setting is therefore a trade-off between audio quality and overall delay. Por tanto la configuración del jitter buffer es un compromiso entre calidad y retardo total. An auto setting of the jitter buffer size setting is available. If the check Auto is enabled, the jitter buffers of the local client and the remote server are set automatically based on measurements of the network and sound card timing jitter. If the Auto check is enabled, the jitter buffer size faders are disabled (they cannot be moved with the mouse). Hay disponible una configuración automática del jitter buffer. Si se activa Auto, los jitter buffers del cliente local y del servidor remoto se configuran automáticamente basándose en mediciones del jitter de la red y la tarjeta de audio. Si se activa esta opción, los faders quedan deshabilitados (no pueden moverse con el ratón). If the auto setting of the jitter buffer is enabled, the network buffers of the local client and the remote server are set to a conservative value to minimize the audio dropout probability. To tweak the audio delay/latency it is recommended to disable the auto setting functionality and to lower the jitter buffer size manually by using the sliders until your personal acceptable limit of the amount of dropouts is reached. The LED indicator will visualize the audio dropouts of the local jitter buffer with a red light. En caso de activar la configuración automática del jitter buffer, los buffers de red del cliente local y del servidor remoto se asignan a un valor conservador para minimizar la probabilidad de fallos de audio. Para ajustar el retardo de audio/latencia se recomienda desactivar la función automática y bajar los valores de jitter buffer manualmente utilizando los controles deslizantes hasta alcanzar un límite aceptable de caídas de audio. El indicador LED ofrece una visualización de las caídas de audio mediante una luz roja. Local jitter buffer slider control Control deslizante jitter buffer local Server jitter buffer slider control Control deslizante jitter buffer servidor Auto jitter buffer switch Interruptor auto jitter buffer Jitter buffer status LED indicator Indicador LED estado jitter buffer Sound Card Device Dispositivo de Audio The ASIO driver (sound card) can be selected using El driver ASIO (tarjeta de audio) se puede seleccionar utilizando under the Windows operating system. Under MacOS/Linux, no sound card selection is possible. If the selected ASIO driver is not valid an error message is shown and the previous valid driver is selected. en el sistema operativo Windows. En MacOs/Linux no es posible seleccionar la tarjeta de audio. Si el driver ASIO no es válido se muestra un mensaje de error y se selecciona el driver válido anterior. If the driver is selected during an active connection, the connection is stopped, the driver is changed and the connection is started again automatically. Si el driver se selecciona durante una conexión activa, la conexión se detiene, se cambia el driver y la conexión se reanuda automáticamente. Sound card device selector combo box Selector de dispositivo de audio If the ASIO4ALL driver is used, please note that this driver usually introduces approx. 10-30 ms of additional audio delay. Using a sound card with a native ASIO driver is therefore recommended. En caso de utilizar el driver ASIO4ALL, por favor ten en cuenta que este driver normalmente introduce una latencia adicional de 10-30 ms. Por tanto se recomienda utilizar la tarjeta de audio con un driver nativo. If you are using the kX ASIO driver, make sure to connect the ASIO inputs in the kX DSP settings panel. Si utilizas el driver kX ASIO, asegúrate de conectar las entradas ASIO en el panel de configuración de kX DSP. Sound Card Channel Mapping Mapeo Canales Tarjeta Audio If the selected sound card device offers more than one input or output channel, the Input Channel Mapping and Output Channel Mapping settings are visible. Si el dispositivo de audio ofrece más de un canal de entrada o salida, son visibles las configuraciones para el Mapeo de Canales de Entrada y de Salida. For each Para cada input/output channel (Left and Right channel) a different actual sound card channel can be selected. canal de entrada/salida (canal Izquierdo y Derecho) se puede seleccionar un canal diferente de la tarjeta de audio. Left input channel selection combo box Selección canal entrada izquierdo Right input channel selection combo box Selección canal entrada derecho Left output channel selection combo box Selección canal salida izquierdo Right output channel selection combo box Selección canal salida derecho Enable Small Network Buffers Activar Buffers Red Pequeños If enabled, the support for very small network audio packets is activated. Very small network packets are only actually used if the sound card buffer delay is smaller than Si se activa, se habilita el soporte para paquetes de red de audio muy pequeños. Solo se utilizan estos paquetes pequeños si el retardo de buffer de la tarjeta de audio es menor de samples. The smaller the network buffers, the lower the audio latency. But at the same time the network load increases and the probability of audio dropouts also increases. muestras. Cuanto menores los buffers de red, menor la latencia de audio. Pero al mismo tiempo, aumenta la carga de red y la probabilidad de caídas de audio también aumenta. Enable small network buffers check box Activar buffers de red pequeños Sound Card Buffer Delay Retardo Buffer Tarjeta Audio Some sound card drivers do not allow the buffer delay to be changed from within the application. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. On Windows, press the ASIO Device Settings button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Algunos drivers de tarjeta de sonido no permiten cambiar el retardo de buffer desde la aplicación. En este caso se deshabilita la configuración del retardo de buffer y se debe cambiar utilizando el driver de la tarjeta de sonido. En Windows, haz clic en el botón de Configuración del Dispositivo ASIO para abrir el panel de configuración. En Linux, utiliza la herramienta de configuración de JACK para cambiar el tamaño del buffer. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within the software. On Windows, press the ASIO Device Settings button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Si la configuración del retardo de buffer está deshabilitada, el driver de audio no permite cambiar este ajuste desde la aplicación. En Windows, haz clic en el botón de Configuración del Dispositivo ASIO para abrir el panel de configuración. En Linux, utiliza la herramienta de configuración de JACK para cambiar el tamaño del buffer. Sound card driver settings Configuración de la tarjeta de sonido This opens the driver settings of your sound card. Some drivers allow you to change buffer settings, others like ASIO4ALL let you choose input or outputs of your device(s). More information can be found on jamulus.io. Esto abre la configuración del driver de tu tarjeta de sonido. Algunos drivers te permiten cambiar la configuración del buffer; otros como ASIO4ALL te permiten escoger las entradas o salidas de tu(s) dispositivo(s). Se puede encontrar más información en jamulus.io. Opens the driver settings. Note: Abre la configuración del driver. Nota: currently only supports devices supporting a sample rate of actualmente solo soporta dispositivos con una tasa de muestreo de Hz. You will not be able to select a driver/device which doesn't. For more help see jamulus.io. Hz. No podrás seleccionar un driver/dispositivo que no lo haga. Para más ayuda, ver jamulus.io. The ASIO driver (sound card) can be selected using %1 under the Windows operating system. Under macOS/Linux, no sound card selection is possible. If the selected ASIO driver is not valid an error message is shown and the previous valid driver is selected. El driver ASIO (tarjeta de audio) se puede seleccionar utilizando %1 en el sistema operativo Windows. En MacOs/Linux no es posible seleccionar la tarjeta de audio. Si el driver ASIO no es válido se muestra un mensaje de error y se selecciona el driver válido anterior. For each %1 input/output channel (left and right channel) a different actual sound card channel can be selected. Para cada canal de entrada/salida (canal derecho e izquierdo) de %1 se puede seleccionar una tarjeta de sonido diferente. Enables support for very small network audio packets. These network packets are only actually used if the sound card buffer delay is smaller than %1 samples. The smaller the network buffers, the lower the audio latency. But at the same time the network load and the probability of audio dropouts or sound artifacts increases. Habilita el soporte para paquetes de red de audio muy pequeños. Solo se utilizan estos paquetes pequeños si el retardo de buffer de la tarjeta de audio es menor de %1 muestras. Cuanto menores los buffers de red, menor la latencia de audio. Pero al mismo tiempo, aumenta la carga de red y la probabilidad de caídas de audio también aumenta. Some sound card drivers do not allow the buffer delay to be changed from within %1. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. On Windows, use the ASIO Device Settings button to open the driver settings panel. On Linux, use the JACK configuration tool to change the buffer size. Algunos drivers de tarjetas de audio no permiten cambiar el retardo de buffer desde %1. En este caso se deshabilita la configuración del retardo de buffer y se debe cambiar utilizando el driver de la tarjeta de sonido. En Windows, haz clic en el botón de Configuración del Dispositivo ASIO para abrir el panel de configuración. En Linux, utiliza la herramienta de configuración de JACK para cambiar el tamaño del buffer. If no buffer size is selected and all settings are disabled, this means an unsupported buffer size is in use by the driver. %1 will still work with this setting but may have restricted performance. Si no hay ningún tamaño de buffer seleccionado y todas las configuraciones están deshabilitadas, el driver está utilizando un tamaño de buffer no soportado. %1 seguirá funcionando con esta configuración pero con un rendimiento limitado. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within %1. On Windows, press the ASIO Device Settings button to open the driver settings panel. On Linux, use the JACK configuration tool to change the buffer size. Si la configuración de retardo de buffers se encuentra deshabilitada, es porque el driver de audio prohíbe la modificación de este parámetro desde dentro de %1. En Windows, haz clic en el botón de Configuración del Dispositivo ASIO para abrir el panel de configuración. En Linux, utiliza la herramienta de configuración de JACK para cambiar el tamaño del buffer. This opens the driver settings of your sound card. Some drivers allow you to change buffer settings, others like ASIO4ALL lets you choose input or outputs of your device(s). More information can be found on jamulus.io. Esto abre la configuración del driver de tu tarjeta de sonido. Algunos drivers te permiten cambiar los ajustes del buffer; otros, como ASIO4ALL, te permiten elegir las entradas o salidas de tu(s) dispositivo(s). Se puede encontrar más información en jamulus.io. Opens the driver settings. Note: %1 currently only supports devices with a sample rate of %2 Hz. You will not be able to select a driver/device which doesn't. For more help see jamulus.io. Abre la configuración del driver. Nota: %1 actualmente solo soporta dispositivos con una tasa de muestreo de %2 Hz. No podrás seleccionar un driver/dispositivo que no lo haga. Para más ayuda, ver jamulus.io. ASIO Device Settings push button Botón de Configuración Dispositivo ASIO Select the meter style to be used for the level meters. The Bar (narrow) and LEDs (round, small) options only apply to the mixerboard. When Bar (narrow) is selected, the input meters are set to Bar (wide). When LEDs (round, small) is selected, the input meters are set to LEDs (round, big). The remaining options apply to the mixerboard and input meters. Selecciona el estilo a utilizar para los indicadores de nivel. Barra (estrecha) y LEDs (redondos, pequeños) solo se aplican al cuadro de mezclas. Cuando se selecciona Barra (estrecha), los vúmetros de entrada se configuran como Barra (ancha). Cuando se selecciona LEDs (redondos, pequeños), los vúmetros de entrada se configuran como LEDs (redondos, grandes). Las opciones restantes se aplican al cuadro de mezclas y a los vúmetros de entrada. Language Idioma Select the language to be used for the user interface. Selecciona el idioma a utilizar para el interfaz de usuario. Language combo box Campo Idioma The buffer delay setting is a fundamental setting of %1. This setting has an influence on many connection properties. Este parámetro es una parte fundamental de la configuración de %1. Este parámetro tiene un impacto sobre muchas propiedades de la conexión. Controls the relative levels of the left and right local audio channels. For a mono signal it acts as a pan between the two channels. For example, if a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows %1, where %2 is the current attenuation indicator. Controla los niveles relativos de los canales locales de audio derecho e izquierdo. Para una señal mono actúa como paneo entre los dos canales. Por ej., si se conecta un miocrófono al canal derecho y un instrumento al izquierdo que suena mucho más alto que el micrófono, mueve el fader en una dirección donde la etiqueta sobre el fader muestra %1, donde %2 es el indicador actual de atenuación. Audio Device Dispositivo de Audio Under the Windows operating system the ASIO driver (sound card) can be selected using %1. If the selected ASIO driver is not valid an error message is shown and the previous valid driver is selected. Under macOS the input and output hardware can be selected. En el sistema operativo WIndows se puede seleccionar el driver ASIO (tarjeta de audio) utilizando %1. Si el driver ASIO seleccionado no es válido, se muestra un mensaje de error y se selecciona el anterior driver válido. En macOS se puede seleccionar el hardware de entrada y salida. Three buffer sizes can be selected Se pueden seleccionar tres tamaños de buffer 64 samples: Provides the lowest latency but does not work with all sound cards. 64 muestras: Ofrece la latencia más baja, pero no funciona con todas las tarjetas de audio. 256 samples: Should only be used when 64 or 128 samples is causing issues. 256 muestras: Solo debería utilizarse cuando hay problemas con 64 ó 128 muestras. Some sound card drivers do not allow the buffer delay to be changed from within %1. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. Use the appropriate tool for the interface in use to adjust this buffer size. For example, if using ASIO, use the "ASIO Device Settings" button to open the driver settings panel or if using JACK, use a tool such as QjackCtl to adjust the buffer size. Other interfaces, such as Pipewire, would require their appropriate tool being used. Please refer to the interface manual. Algunos drivers de tarjetas de sonido no permiten cambiar el retardo de buffer desde %1. En este caso la configuración del retardo de buffer está deshabilitada y debe cambiarse utilizando el driver de la tarjeta de sonido. Utiliza la herramienta apropiada del interfaz en uso para ajustar este tamalo de buffer. Por ejemplo, si utilizas ASIO, usa el botón de "Configuración Dispositivo ASIO" para abrir el panel de configuración del driver o si utilizas JACK, usa una herramienta como QjackCtl para ajustar el tamaño del buffer. Otros interfaces, como Pipewire, requerirán el uso de la herramienta apropiada. Por favor consulta el manual del interfaz. If no buffer size is selected and all settings are disabled, this means a buffer size in use by the driver which does not match the values. %1 will still work with this setting but may have restricted performance. Si no hay ningún tamaño de buffer seleccionado y todas las configuraciones están deshabilitadas, significa que el driver está utilizando un tamaño de buffer que no corresponde a los valores. %1 seguirá funcionando con esta configuración pero podría tener un rendimiento limitado. The actual buffer delay has influence on the connection, the current upload rate and the overall delay. The lower the buffer size, the higher the probability of a red light in the status indicator (drop outs) and the higher the upload rate and the lower the overall delay. El retardo del buffer tiene un impacto en la conexión, la tasa de subida y el retardo total. Cuanto menor sea el tamaño del buffer, mayor la probabilidad de que haya una luz roja en el indicador de estado (caídas de audio), mayor la tasa de subida y menor el retardo total. Meter Style Estilo del Vúmetro Select the meter style to be used for the level meters. The Narrow Bar and Small LEDs options only apply to the mixerboard. When Narrow Bar is selected, the input meters are set to Bar. When Small LEDs is selected, the input meters are set to Round LEDs. The remaining options apply to the mixerboard and input meters. Selecciona el estilo a utilizar para los indicadores de nivel. Las opciones de Barra Estrecha y LEDs Pequeños solo se aplican al cuadro de mezclas. Cuando se selecciona Barra Estrecha, los vúmetros de entrada se configuran como Barra. Cuando se selecciona LEDs Pequeños, los vúmetros de entrada se configuran como LEDs Redondos. Las opciones restantes se aplican al cuadro de mezclas y a los vúmetros de entrada. Meter Style combo box Casilla para Estilo del Vúmetro Input Boost Aumento de Entrada This setting allows you to increase your input signal level by factors up to 10 (+20dB). If your sound is too quiet, first try to increase the level by getting closer to the microphone, adjusting your sound equipment or increasing levels in your operating system's input settings. Only if this fails, set a factor here. If your sound is too loud, sounds distorted and is clipping, this option will not help. Do not use it. The distortion will still be there. Instead, decrease your input level by getting farther away from your microphone, adjusting your sound equipment or by decreasing your operating system's input settings. Este ajuste te permite aumentar tu señal de entrada en unfactor de hasta 10 (+20dB). Si tu audio es muy bajo, primero intenta aumentar el nivel acercándote al micrófono, ajustando tu equipo de sonido o aumentando la configuración de entrada de audio de tu sistema operativo. Solamente si lo anterior falla, establece un factor aquí. Si tu sonido es muy alto, suena distorsionado y clipea, esta opción no ayudará. No la utilices. La distorsión seguirá ahí. En su lugar, reduce tu nivel de entrada alejándote de tu micrófono, ajusta tu equipo de audio o reduce la configuración de entrada de audio de tu sistema operativo. Input Boost combo box Desplegable de Aumento de Entrada Directory server address combo box Campo para dirección servidor de directorio Audio Upstream Rate Tasa de Subida de Audio Depends on the current audio packet size and compression setting. Make sure that the upstream rate is not higher than your available internet upload speed (check this with a service such as speedtest.net). Depende del tamaño actual de paquetes de audio y la configuración de compresión de audio. Asegúrate de que la tasa de subida no es mayor que la velocidad de subida disponible (comprueba la tasa de subida de tu conexión a internet, por ej. con speedtest.net). Number of Mixer Panel Rows Número de Filas Panel del Mezclador Adjust the number of rows used to arrange the mixer panel. Ajusta el número de filas utilizado para organizar el panel del mezclador. Number of Mixer Panel Rows spin box Casilla para Número de Filas Panel del Mezclador Feedback Protection Protección contra Retroalimentación Enable feedback protection to detect acoustic feedback between microphone and speakers. Activa la protección contra retroalimentación para detectar retroalimentación entre el micrófono y los altavoces. Feedback Protection check box Casilla para Protección contra Retroalimentación Audio Alerts Alertas Sonoras Enable audio alert when receiving a chat message and when a new client joins the session. A second sound device may be required to hear the alerts. Activa la alerta sonora al recibir un mensaje de chat y cuando un nuevo cliente se une a la sesión. Para escuchar las alertas puede ser necesario un segundo dispositivo de audio. Audio Alerts check box Casilla Alertas Sonoras ASIO Device Settings Configuración Dispositivo ASIO Fancy Oscuro Compact Compacto Bar (narrow) Barra (estrecha) Bar (wide) Barra (ancha) LEDs (stripe) LEDs (franja) LEDs (round, small) LEDs (redondos, pequeños) LEDs (round, big) LEDs (redondos, grandes) LEDs LEDs Bar Barra Narrow Bar Barra Estrecha Round LEDs LEDs Redondos Small LEDs LEDs Pequeños None Ninguno Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country or region you are located in. Your city and skill level playing your instrument may also be added. Escribe tu nombre o un alias aquí para que otros músicos con quien quieras tocar sepan quién eres. Puedes además añadir una imagen del instrumento que tocas y la bandera del país o la región donde te ubicas. Tu ciudad y tu nivel de habilidad con el instrumento también pueden añadirse. What you set here will appear at your fader on the mixer board when you are connected to a %1 server. This tag will also be shown at each client which is connected to the same server as you. Lo que introduzcas aquí aparecerá en tu fader del mezclador cuando te conectes a un servidor %1. Esta etiqueta también se mostrará a cada cliente que se conecte al mismo servidor que tú. Country/region flag button Botón bandera país/región Center Centro R R The buffer delay setting is a fundamental setting of the Este parámetro es una parte fundamental de la configuración del software software. This setting has influence on many connection properties. . Este parámetro tiene un impacto sobre muchas propiedades de la conexión. Three buffer sizes are supported Hay soporte para tres tamaños de buffer 64 samples: This is the preferred setting since it provides the lowest latency but does not work with all sound cards. 64 muestras: Es la configuración aconsejada puesto que ofrece la latencia más baja, aunque no funciona con todas las tarjetas de audio. 128 samples: This setting should work for most available sound cards. 128 muestras: Esta configuración debería de funcionar con la mayoría de tarjetas de audio. 256 samples: This setting should only be used if only a very slow computer or a slow internet connection is available. 256 muestras: Esta configuración solo debería usarse con un ordenador muy lento o con una conexión a internet muy lenta. Some sound card drivers do not allow the buffer delay to be changed from within the Algunos drivers de tarjetas de audio no permiten cambiar el retardo de buffer desde el software software. In this case the buffer delay setting is disabled. To change the actual buffer delay, this setting has to be changed in the sound card driver. On Windows, press the ASIO Setup button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. . En este caso la configuración del retardo de buffer se deshabilita. Para cambiarlo, esta configuración debe realizarse en el driver de la tarjeta de audio. En Windows, pulsa el botón de Configuración ASIO para acceder al panel de configuración. En Linux, utiliza la herramienta de configuración de Jack para cambiar el tamaño del buffer. If no buffer size is selected and all settings are disabled, an unsupported buffer size is used by the driver. The Si no hay ningún tamaño de buffer seleccionado y todas las configuraciones están deshabilitadas, el driver está utilizando un tamaño de buffer no soportado. El software software will still work with this setting but with restricted performance. seguirá funcionando con esta configuración pero con un rendimiento limitado. The actual buffer delay has influence on the connection status, the current upload rate and the overall delay. The lower the buffer size, the higher the probability of a red light in the status indicator (drop outs) and the higher the upload rate and the lower the overall delay. El retardo del buffer tiene un impacto en el estado de la conexión, la tasa de subida y el retardo total. Cuanto menor sea el retardo del buffer, mayor la probabilidad de que el indicador de estado esté en rojo (caídas de audio), mayor la tasa de subida y menor el retardo total. The buffer setting is therefore a trade-off between audio quality and overall delay. Por tanto la configuración del buffer es un compromiso entre calidad de audio y retardo total. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within the Si la configuración de retardo de buffers se encuentra deshabilitada, es porque el driver de audio prohíbe la modificación de este parámetro desde dentro del software software. On Windows, press the ASIO Setup button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. . En Windows, pulsa el botón de Configuración ASIO para abrir el panel de configuración del driver. En Linux, utiliza la herramienta de configuración de Jack para cambiar el tamaño del buffer. 64 samples setting radio button Configuración 64 muestras 128 samples setting radio button Configuración 128 muestras 256 samples setting radio button Configuración 256 muestras ASIO setup push button Botón configuración ASIO Fancy Skin Interfaz Oscura If enabled, a fancy skin will be applied to the main window. Si se activa, se aplicará un aspecto oscuro a la ventana principal. Fancy skin check box Activar interfaz oscura Display Channel Levels Mostrar Niveles Canales If enabled, each client channel will display a pre-fader level bar. Si se activa, cada canal de cliente mostrará una barra de nivel pre-fader. Display channel levels check box Mostrar niveles canales Audio Channels Canales Audio Select the number of audio channels to be used. There are three modes available. The mono and stereo modes use one and two audio channels respectively. In mono-in/stereo-out mode the audio signal which is sent to the server is mono but the return signal is stereo. This is useful if the sound card has the instrument on one input channel and the microphone on the other channel. In that case the two input signals can be mixed to one mono channel but the server mix can be heard in stereo. Selecciona el número de canales de audio a utilizar. Hay tres modos disponibles. Los modos mono y estéreo utilizan uno y dos canales de audio respectivamente. En modo entrada-mono/salida-estéreo la señal de audio enviada al servidor es mono pero la señal que vuelve es estéreo. Esto es útil si la tarjeta de audio tiene un instrumento en un canal de entrada y un micrófono en el otro. En ese caso las dos señales de entrada pueden combinarse en un canal mono pero la mezcla del servidor se escucha en estéreo. Enabling the stereo streaming mode will increase the stream data rate. Make sure that the current upload rate does not exceed the available bandwidth of your internet connection. Activar el modo estéreo aumentará la tasa de envío de datos. Asegúrate de que la tasa de subida no excede el ancho de banda disponible en tu conexión a internet. In stereo streaming mode, no audio channel selection for the reverberation effect will be available on the main window since the effect is applied on both channels in this case. En el caso del modo estéreo, no estará disponible la selección de canal para el efecto de reverberación en la ventana principal puesto que en este caso el efecto se aplicará a ambos canales. Audio channels combo box Selección canales audio Audio Quality Calidad Audio Select the desired audio quality. A low, normal or high audio quality can be selected. The higher the audio quality, the higher the audio stream data rate. Make sure that the current upload rate does not exceed the available bandwidth of your internet connection. Selecciona la calidad de audio deseada. Se puede seleccionar una calidad baja, normal o alta. Cuanto mayor la calidad del audio, mayor la tasa de transferencia de datos de audio. Asegúrate de que la tasa de subida no excede el ancho de banda disponible en tu conexión a internet. Audio quality combo box Selección calidad audio New Client Level Nivel Cliente Nuevo The new client level setting defines the fader level of a new connected client in percent. I.e. if a new client connects to the current server, it will get the specified initial fader level if no other fader level of a previous connection of that client was already stored. La configuración del nivel de clientes nuevos define el nivel del fader para una nueva conexión expresado en un porcentaje. Esto es, si un cliente nuevo se conecta al servidor actual, su fader tomará el valor especificado si no se ha guardado ningún valor de una conexión anterior de ese cliente. New client level edit box Campo para nivel nuevo cliente Custom Directory Server Address Dirección Personalizada Servidor de Directorio The custom directory server address is the IP address or URL of the directory server at which the server list of the connection dialog is managed. This address is only used if the custom server list is selected in the connection dialog. La dirección personalizada del servidor central es la dirección IP o URL del servidor central en el cual se gestiona la lista de servidores de la ventana de conexión. Esta dirección solo se utiliza si se selecciona la lista personalizada en la ventana de conexión. Directory Server Address Dirección Servidor Central The directory server address is the IP address or URL of the directory server at which the server list of the connection dialog is managed. With the directory server address type either the local region can be selected of the default directory servers or a manual address can be specified. La dirección del servidor central es la dirección IP o URL del servidor central en el que se gestiona la lista de servidores en la ventana de conexión. Aquí se puede escoger la región local de entre los servidores centrales por defecto o se puede especificar una dirección manualmente. Default directory server type combo box Selección servidor central Directory server address line edit Dirección servidor central Current Connection Status Parameter Parámetro Estado Conexión Actual The ping time is the time required for the audio stream to travel from the client to the server and back again. This delay is introduced by the network. This delay should be as low as 20-30 ms. If this delay is higher (e.g., 50-60 ms), your distance to the server is too large or your internet connection is not sufficient. El ping es el tiempo que requiere el flujo de audio para viajar desde el cliente al servidor y volver. Este retardo lo determina la red. Esta cifra debería ser de unos 20-30 ms. Si este retardo es mayor (por ej. 50-60 ms), la distancia al servidor es demasiado grande o tu conexión a internet no es óptima. The overall delay is calculated from the current ping time and the delay which is introduced by the current buffer settings. El retardo total se calcula con el ping y el retardo ocasionado por la configuración de buffers. The upstream rate depends on the current audio packet size and the audio compression setting. Make sure that the upstream rate is not higher than the available rate (check the upstream capabilities of your internet connection by, e.g., using speedtest.net). La tasa de subida depende del tamaño actual de paquetes de audio y la configuración de compresión de audio. Asegúrate de que la tasa de subida no es mayor que la tasa disponible (comprueba la tasa de subida de tu conexión a internet, por ej. con speedtest.net). If this LED indicator turns red, you will not have much fun using the Si este indicador LED se vuelve rojo, no te divertirás demasiado utilizando el software. software. ASIO Setup Configuración ASIO Mono Mono and y mode will increase your stream's data rate. Make sure your upload rate does not exceed the available upload speed of your internet connection. aumentará la tasa de datos. Asegúrate de que tu tasa de subida no excede el valor de subida disponible con tu ancho de banda de Internet. Custom Directories Directorios Personalizados If you need to add additional directories to the Connect dialog Directory drop down, you can enter the addresses here.<br>To remove a value, select it, delete the text in the input box, then move focus out of the control. Si necesitas añadir directorios adicionales a la lista de Directorios en la ventana de Conectar, puedes escribir las direcciones aquí <br>Para eliminar un valor, selecciónalo, borra el texto en el campo y haz clic fuera del campo. Custom Directories combo box Casilla Directorios Personalizados Mono-in/Stereo-out Entrada mono/Salida estéreo Stereo Estéreo &Close &Cerrar Local Audio Input Fader Fader Entrada Audio Local Controls the relative levels of the left and right local audio channels. For a mono signal it acts as a pan between the two channels. For example, if a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows Controla los niveles relativos de los canales locales de audio derecho e izquierdo. Para una señal mono actúa como paneo entre los dos canales. Por ej., si se conecta un miocrófono al canal derecho y un instrumento al izquierdo que suena mucho más alto que el micrófono, mueve el fader en una dirección donde la etiqueta sobre el fader muestra L L , where , donde is the current attenuation indicator. es el indicador actual de atenuación. Local audio input fader (left/right) Fader entrada audio local (izq/dcho) The jitter buffer compensates for network and sound card timing jitters. The size of the buffer therefore influences the quality of the audio stream (how many dropouts occur) and the overall delay (the longer the buffer, the higher the delay). El jitter buffer compensa el jitter de la red y la tarjeta de audio. El tamaño de este buffer tiene por tanto un impacto sobre la calidad del flujo de audio (el número de caídas de la señal) y el retardo total (a mayor buffer, mayor retardo). You can set the jitter buffer size manually for the local client and the remote server. For the local jitter buffer, dropouts in the audio stream are indicated by the light below the jitter buffer size faders. If the light turns to red, a buffer overrun/underrun has taken place and the audio stream is interrupted. El tamaño del jitter buffer se puede establecer manualmente para el cliente local y para el servidor remoto. Para el jitter buffer local, las caídas del flujo de audio se indican mediante la luz debajo de los faders del jitter buffer. Si la luz se vuelve roja, significa que ha habido una interrupción del flujo de audio. If the Auto setting is enabled, the jitter buffers of the local client and the remote server are set automatically based on measurements of the network and sound card timing jitter. If Auto is enabled, the jitter buffer size faders are disabled (they cannot be moved with the mouse). En caso de activar Auto, los jitter buffer del cliente local y del servidor remoto se ajustan automáticamente basándose en mediciones del jitter de la red y de la tarjeta de audio. Si se activa Auto, los faders del jitter buffer se deshabilitan (no pueden moverse con el ratón). If the Auto setting is enabled, the network buffers of the local client and the remote server are set to a conservative value to minimize the audio dropout probability. To tweak the audio delay/latency it is recommended to disable the Auto setting and to lower the jitter buffer size manually by using the sliders until your personal acceptable amount of dropouts is reached. The LED indicator will display the audio dropouts of the local jitter buffer with a red light. En caso de activar Auto, los buffers de red del cliente local y del servidor remoto se asignan a un valor conservador para minimizar la probabilidad de fallos de audio. Para ajustar el retardo de audio/latencia se recomienda desactivar la función Auto y bajar los valores de jitter buffer manualmente utilizando los controles deslizantes hasta alcanzar un límite aceptable de caídas de audio. El indicador LED ofrece una visualización de las caídas de audio mediante una luz roja. The buffer delay setting is a fundamental setting of this software. This setting has an influence on many connection properties. El retardo de buffer es un parámetro fundamental de este software. Este parámetro tiene un impacto sobre muchas propiedades de la conexión. 64 samples: The preferred setting. Provides the lowest latency but does not work with all sound cards. 64 muestras: La configuración aconsejada. Ofrece la latencia más baja, aunque no funciona con todas las tarjetas de audio. 128 samples: Should work for most available sound cards. 128 muestras: Debería de funcionar con la mayoría de tarjetas de audio. 256 samples: Should only be used on very slow computers or with a slow internet connection. 256 muestras: Esta configuración solo debería usarse con un ordenador muy lento o con una conexión a internet muy lenta. Some sound card drivers do not allow the buffer delay to be changed from within the application. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. On Windows, press the ASIO Setup button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Algunos drivers de tarjetas de audio no permiten cambiar el retardo de buffer desde dentro de la aplicación. En este caso la configuración del retardo de buffer se deshabilita y debe modificarse utilizando el driver de la tarjeta de audio. En Windows, pulsa el botón de Configuración ASIO para acceder al panel de configuración. En Linux, utiliza la herramienta de configuración de Jack para cambiar el tamaño del buffer. If no buffer size is selected and all settings are disabled, an unsupported buffer size is used by the driver. The application will still work with this setting but with restricted performance. Si no hay ningún tamaño de buffer seleccionado y todas las configuraciones están deshabilitadas, el driver está utilizando un tamaño de buffer no soportado. La aplicación arrancará pero con rendimiento limitado. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within the software. On Windows, press the ASIO Setup button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Si la configuración de retardo de buffers se encuentra deshabilitada, es porque el driver de audio prohíbe la modificación de este parámetro desde dentro del software. En Windows, pulsa el botón de Configuración ASIO para abrir el panel de configuración del driver. En Linux, utiliza la herramienta de configuración de Jack para cambiar el tamaño del buffer. Skin Skin Select the skin to be used for the main window. Elige el skin a utilizar para la ventana principal. Skin combo box Campo skin Selects the number of audio channels to be used for communication between client and server. There are three modes available: Selecciona el número de canales de audio a utilizar para la comunicación entre cliente y servidor. Hay tres modos disponibles: and y These modes use one and two audio channels respectively. Estos modos utilizan uno y dos canales de audio respectivamente. Mono in/Stereo-out Entrada Mono/Salida Estéreo The audio signal sent to the server is mono but the return signal is stereo. This is useful if the sound card has the instrument on one input channel and the microphone on the other. In that case the two input signals can be mixed to one mono channel but the server mix is heard in stereo. La señal de audio enviada al servidor es mono pero la señal de vuelta es estéreo. Esto es útil si la tarjeta de audio tiene el instrumento en una entrada y el micrófono en la otra. En este caso se pueden mezclar las dos señales de entrada a un canal mono pero la mezcla del servidor se escucha en estéreo. Enabling Habilitar el modo mode will increase your stream's data rate. Make sure your upload rate does not exceed the available upload speed of your internet connection. aumentará la tasa de datos. Asegúrate de que tu tasa de subida no excede el valor de subida disponible con tu ancho de banda de Internet. In stereo streaming mode, no audio channel selection for the reverb effect will be available on the main window since the effect is applied to both channels in this case. En modo estéreo, no habrá ninguna selección de canal para el efecto de reverb en la ventana principal porque el efecto se aplica a ambos canales en este caso. The higher the audio quality, the higher your audio stream's data rate. Make sure your upload rate does not exceed the available bandwidth of your internet connection. Cuanto mayor la calidad del audio, mayor la tasa de subida del audio. Asegúrate de que tu tasa de subida no excede el ancho de banda de tu conexión a Internet. This setting defines the fader level of a newly connected client in percent. If a new client connects to the current server, they will get the specified initial fader level if no other fader level from a previous connection of that client was already stored. Este ajuste define el nivel del fader de una nueva conexión de cliente, en porcentaje. Si se conecta un nuevo cliente al servidor actual, el nivel inicial de su fader tomará este valor si no se ha especificado anteriormente un valor para ese cliente de una conexión anterior. Leave this blank unless you need to enter the address of a directory server other than the default. Deja esto en blanco a menos que necesites escribir la dirección de un servidor de directorio distinto a los que hay por defecto. The Ping Time is the time required for the audio stream to travel from the client to the server and back again. This delay is introduced by the network and should be about 20-30 ms. If this delay is higher than about 50 ms, your distance to the server is too large or your internet connection is not sufficient. El Ping es el tiempo que requiere el flujo de audio para viajar desde el cliente al servidor y volver. Este retardo lo determina la red y debería ser de unos 20-30 ms. Si este retardo es de unos 50 ms, la distancia al servidor es demasiado grande o tu conexión a internet no es óptima. Overall Delay is calculated from the current Ping Time and the delay introduced by the current buffer settings. El Retardo Total se calcula con el Ping actual y el retardo ocasionado por la configuración de buffers. Audio Upstream Rate depends on the current audio packet size and compression setting. Make sure that the upstream rate is not higher than your available internet upload speed (check this with a service such as speedtest.net). La Tasa de Subida de Audio depende del tamaño actual de paquetes de audio y la configuración de compresión de audio. Asegúrate de que la tasa de subida no es mayor que la velocidad de subida disponible (comprueba la tasa de subida de tu conexión a internet, por ej. con speedtest.net). Low Baja Normal Normal High Alta Manual Manual Custom Personalizado All Genres Todos los Géneros Genre Rock/Jazz Género Rock/Jazz Genre Classical/Folk/Choral Género Clásica/Folk/Coro Any Genre 2 Cualquier Género 2 Any Genre 3 Cualquier Género 3 Genre Rock Género Rock Genre Jazz Género Jazz Genre Classical/Folk Género Clásico/Folk Genre Choral/Barbershop Género Coral/Barbershop Any Genre 1 Cualquier Género 1 Default Predeterminado Default (North America) Por defecto (Norteamérica) preferred aconsejado Musician Profile Perfil Músico Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country you are located in. Your city and skill level playing your instrument may also be added. Escribe tu nombre o alias aquí para que otros músicos con quien quieras tocar te reconozcan. Puedes además añadir una imagen del instrumento que tocas y la bandera del país donde te ubicas. Tu ciudad y tu nivel de habilidad con el instrumento también pueden añadirse. What you set here will appear at your fader on the mixer board when you are connected to a Jamulus server. This tag will also be shown at each client which is connected to the same server as you. Lo que introduzcas aquí aparecerá en tu fader del mezclador cuando te conectes a un servidor Jamulus. Esta etiqueta también se mostrará en cada cliente conectado al mismo servidor que tú. Alias or name edit box Campo para alias o nombre Instrument picture button Botón imagen instrumento Country flag button Botón bandera país City edit box Casilla para editar ciudad Skill level combo box Casilla para nivel de habilidad Beginner Principiante Intermediate Intermedio Expert Experto Size: Tamaño: Buffer Delay Retardo Buffer Buffer Delay: Retardo Buffer: Predefined Address Dirección Preestablecida The selected audio device could not be used because of the following error: El dispositivo de audio seleccionado no puede utilizarse a causa del siguiente error: The previous driver will be selected. Se utilizará el driver anterior. Ok Ok Drum Set Batería Djembe Djembé Electric Guitar Guitarra Eléctrica Acoustic Guitar Guitarra Acústica Bass Guitar Bajo Eléctrico Keyboard Teclado Synthesizer Sintetizador Grand Piano Piano de Cola Accordion Acordeón Vocal Voz Microphone Micrófono Harmonica Armónica Trumpet Trompeta Trombone Trombón French Horn Trompa Tuba Tuba Saxophone Saxofón Clarinet Clarinete Flute Flauta Violin Violín Cello Violonchelo Double Bass Contrabajo Recorder Grabadora Streamer Streamer Listener Oyente Guitar+Vocal Guitarra+Voz Keyboard+Vocal Teclado+Voz Bodhran Bodhran Bassoon Fagot Oboe Oboe Harp Arpa Viola Viola Congas Congas Bongo Bongo Vocal Bass Voz Bajo Vocal Tenor Voz Tenor Vocal Alto Voz Alto Vocal Soprano Voz Soprano Banjo Banjo Mandolin Mandolina Ukulele Ukulele Bass Ukulele Ukulele Barítono Vocal Baritone Voz Barítono Vocal Lead Voz Principal Mountain Dulcimer Dulcémele de Montaña Scratching Scratching Rapping Rapeo Vibraphone Vibráfono Conductor Director CClientSettingsDlgBase Settings Configuración Soundcard Tarjeta Sonido Device Dispositivo Input Channel Mapping Mapeo Canales Entrada L L R R Output Channel Mapping Mapeo Canales Salida Enable Small Network Buffers Activar Buffers Pequeños Buffer Delay Retardo Buffer Country/Region País/Región (preferred) (aconsejado) (default) (predeterminado) (safe) (seguro) Driver Setup Configuración Driver My Profile Mi Perfil Musician's Profile Perfil del Músico Alias/Name Alias/Nombre Instrument Instrumento Country País City Ciudad Skill Habilidad User Interface Interfaz de Usuario Meter Style Estilo del Vúmetro Mixer Rows Filas Mezclador Audio Alerts Alertas Sonoras Audio/Network Setup Configuración Audio/Red Audio Device Dispositivo de Audio Jitter Buffer Jitter Buffer Auto Auto Local Local Server Servidor Size Valor kbps kbps ms ms Input Boost Aumento de Entrada Feedback Protection Protección contra Retroalimentación Enable Activar Input Balance Balance Entrada Pan Paneo Center Centro Misc Varios Audio Channels Canales Audio Audio Quality Calidad Audio Measurements Mediciones Advanced Setup Configuración Avanzada Custom Central Server Address: Dirección Personalizada Servidor Central: New Client Level Nivel Cliente Nuevo Skin Skin Language Idioma Custom Directories: Directorios Personalizados: % % Local Jitter Buffer Jitter Buffer Local Fancy Skin Intfaz Oscura Display Channel Levels Mostrar Nivel Canales Custom Directory Server Address: Dirección Personalizada Servidor de Directorio: Directory Server Address: Dirección Servidor Central: Audio Stream Rate Tasa Muestreo Audio val val Ping Time Tiempo Ping Overall Delay Retardo Total CConnectDlg Server List Lista Servidores The server list shows a list of available servers which are registered at the directory server. Select a server from the list and press the connect button to connect to this server. Alternatively, double click a server from the list to connect to it. If a server is occupied, a list of the connected musicians is available by expanding the list item. Permanent servers are shown in bold font. La lista de servidores muestra una lista de servidores disponibles que se encuentran registrados en el servidor central. Escoge un servidor de la lista y pulsa el botón de conectar para conectarte a este servidor. También es posible realizar la conexión haciendo doble clic en un servidor de la lista. Si un servidor está ocupado, se puede desplegar una lista de los músicos conectados al pulsar el icono al lado del nombre. Los servidores permanentes se muestran en negrita. Note that it may take some time to retrieve the server list from the directory server. If no valid directory server address is specified in the settings, no server list will be available. Ten en cuenta que puede llevar un tiempo recuperar la lista de servidores del servidor central. Si no se especifica una dirección válida en la configuración, no habrá ninguna lista de servidores disponible. Directory Directorio Shows the servers listed by the selected directory. You can add custom directories in Advanced Settings. Muestra los servidores listados por el directorio seleccionado. Puedes añadir directorios personalizados en Configuración Avanzada. Directory combo box Casilla Directorio Filters the server list by the given text. Note that the filter is case insensitive. A single # character will filter for those servers with at least one person connected. Filtra la lista de servidores con el texto dado. Nótese que el filtro no distingue entre mayúsculas y minúsculas. Un único caracter # filtrará los servidores con al menos una persona conectada. Uncheck to collapse the server list to show just the server details. Check to show everyone on the servers. Deshabilita para colapsar la lista de servidores para solo mostrar los detalles del servidor. Habilita para mostrar todos los conectados a los servidores. The Connection Setup window lists the available servers registered with the selected directory. Use the Directory dropdown to change the directory, find the server you want to join in the server list, click on it, and then click the Connect button to connect. Alternatively, double click on the server name to connect. La ventana de Configuración de Conexión lista los servidores disponibles registrados con el directorio seleccionado. Utiliza el desplegable de Directorios para cambiar de directorio, encuentra el servidor al que te quieres conectar, haz clic en él, y luego haz clic en el botón de Conectar para conectarte. También puedes hacer doble clic en el nombre del servidor para conectarte. Permanent servers (those that have been listed for longer than 48 hours) are shown in bold. Los servidores permanentes (aquellos que han estado en la lista durante más de 48 horas) se muestran en negrita. You can add custom directories in Advanced Settings. Puedes añadir directorios personalizados en Configuración Avanzada. Server list view Vista lista de servidores Server Address Dirección Servidor If you know the server address, you can connect to it using the Server name/Address field. An optional port number can be added after the server address using a colon as a separator, e.g. %1. The field will also show a list of the most recently used server addresses. Si conoces la dirección del servidor, puedes conectarte a él utilizando el campo de Nombre/Dirección Servidor. Opcionalmente se puede añadir un número de puerto tras la dirección del servidor utilizando dos puntos como separador, por ej. %1. El campo también mostrará una lista de las direcciones de servidores utilizadas más recientemente. Holds the current server address. It also stores old addresses in the combo box list. Contiene la dirección del servidor actual. También guarda direcciones antiguas en la lista desplegable. The IP address or URL of the server running the La dirección IP o URL del servidor ejecutando el software del servidor server software must be set here. An optional port number can be added after the IP address or URL using a comma as a separator, e.g. example.org: debe introducirse aquí. Se puede añadir un número de puerto opcional detrás de la dirección IP o URL utilizando dos puntos como separador, por ej. ejemplo.org: server software must be set here. An optional port number can be added after the IP address or URL using a colon as a separator, e.g. example.org: debe introducirse aquí. Se puede añadir un número de puerto opcional detrás de la dirección IP o URL utilizando dos puntos como separador, por ej. ejemplo.org: . A list of the most recent used server IP addresses or URLs is available for selection. . Hay disponible una lista de las direcciones IP o URLs utilizadas más recientemente para su selección. The Connection Setup window shows a list of available servers. Server operators can optionally list their servers by music genre. Use the List dropdown to select a genre, click on the server you want to join and press the Connect button to connect to it. Alternatively, double click on on the server name. Permanent servers (those that have been listed for longer than 24 hours) are shown in bold. La ventana de Conexión muestra una lista de servidores disponibles. Opcionalmente los administradores de los servidores pueden listar sus servidores por género musical. Utiliza el menú Lista para escoger un género, escoge un servidor de la lista y pulsa el botón de Conectar para conectarte a él. También es posible realizar la conexión haciendo doble clic en un servidor de la lista. Los servidores permanentes (aquellos que llevan más de 24 horas en la lista) se muestran en negrita. The Connection Setup window shows a list of available servers. Server operators can optionally list their servers by music genre. Use the List dropdown to select a genre, click on the server you want to join and press the Connect button to connect to it. Alternatively, double click on on the server name. Permanent servers (those that have been listed for longer than 48 hours) are shown in bold. La ventana de Conexión muestra una lista de servidores disponibles. Opcionalmente los administradores de los servidores pueden listar sus servidores por género musical. Utiliza el menú Lista para escoger un género, escoge un servidor de la lista y pulsa el botón de Conectar para conectarte a él. También es posible realizar la conexión haciendo doble clic en un servidor de la lista. Los servidores permanentes (aquellos que llevan más de 48 horas en la lista) se muestran en negrita. If you know the IP address or URL of a server, you can connect to it using the Server name/Address field. An optional port number can be added after the IP address or URL using a colon as a separator, e.g. example.org: Si conoces la dirección IP o URL de un servidor, puedes conectarte a él utilizando el nombre/dirección del Servidor. Se puede añadir un número de puerto opcional tras la dirección IP o URL utilizando dos puntos como separador, por ej. 'ejemplo.org': . The field will also show a list of the most recently used server addresses. . El campo también mostrará una lista de los servidores utilizados recientemente. Server address edit box Selección dirección servidor Holds the current server IP address or URL. It also stores old URLs in the combo box list. Contiene la dirección IP o URL actual del servidor. También guarda viejas URL en la lista. Server List Selection Selección Lista de Servidores Selects the server list to be shown. Selecciona la lista de servidores a mostrar. Server list selection combo box Selección lista de servidores Filter Filtro The server list is filtered by the given text. Note that the filter is case insensitive. La lista de servidores se filtra con el texto introducido. El filtro no es sensible a mayúsculas/minúsculas. Filter edit box Campo filtro Show All Musicians Mostrar Todos los Músicos If you check this check box, the musicians of all servers are shown. If you uncheck the check box, all list view items are collapsed. Si activas esta opción, se mostrarán los músicos de todos los servidores. Si lo desactivas, se colapsan todas las listas. Show all musicians check box Selección Mostrar todos los músicos If you know the IP address or URL of a server, you can connect to it using the Server name/Address field. An optional port number can be added after the IP address or URL using a colon as a separator, e.g. %1. The field will also show a list of the most recently used server addresses. Si conoces la dirección IP o la URL de un servidor, puedes conectarte a él utilizando el campo de Nombre/Dirección Servidor. Se puede añadir opcionalmente un número de puerto tras la dirección IP utilizando dos puntos como separador, por ej. %1. El campo tambień mostrará una lista de las direcciones de servidores utilizadas más recientemente. Filter text, or # for occupied servers Texto de filtrado, o # para servidores ocupados Type # for occupied servers Escribe # para servidores ocupados CConnectDlgBase Connection Setup Configuración Conexión List Lista Directory Directorio Filter Filtro Show All Musicians Mostrar Todos los Músicos Server Name Nombre Servidor Ping Time Tiempo Ping Musicians Músicos Location Ubicación Server Address Dirección Servidor C&ancel C&ancelar &Connect &Conectar CHelpMenu &Help A&yuda Getting &Started... &Cómo Empezar... Software &Manual... Manual del &Software... What's &This Qué es &Esto &About Jamulus... &Acerca de Jamulus... About &Qt... Acerca de &Qt... &About... &Acerca de... About Qt Acerca de Qt CLanguageComboBox Restart Required Reinicio Necesario Please restart the application for the language change to take effect. Por favor reinicia la aplicación para que el cambio de idioma surta efecto. CLicenceDlg I &agree to the above licence terms &Acepto los términos de la licencia arriba expuestos This server requires you accept conditions before you can join. Please read these in the chat window. Este servidor requiere que aceptes ciertas condiciones antes de unirte. Por favor léelas en la ventana del chat. I have read the conditions and &agree. He leído las condiciones y las &acepto. Accept Acepto Decline No Acepto By connecting to this server and agreeing to this notice, you agree to the following: Al conectarte a este servidor y aceptar esta notificación, aceptas lo siguiente: You agree that all data, sounds, or other works transmitted to this server are owned and created by you or your licensors, and that you are making these data, sounds or other works available via the following Creative Commons License (for more information on this license, see Ud. declara que todos los datos, audios u otras obras transmitidas a este servidor son la propiedad de Ud. y creadas por Ud. o sus licenciatarios, y que pone a disposición de terceras partes estos datos, audios u otras obras mediante la siguiente Licencia Creative Commons (para más información sobre esta licencia, ver You are free to: Ud. es libre de: Share Compartir copy and redistribute the material in any medium or format copiar y redistribuir el material en cualquier medio o formato Adapt Adaptar remix, transform, and build upon the material remezclar, transformar y construir a partir del material The licensor cannot revoke these freedoms as long as you follow the license terms. El licenciante no puede revocar estas libertades en tanto Ud. siga los términos de la licencia. Under the following terms: Bajo los siguientes términos: Attribution Atribución You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. Ud. debe dar crédito de manera adecuada, brindar un enlace a la licencia, e indicar si se han realizado cambios. Puede hacerlo en cualquier forma razonable, pero no de forma tal que sugiera que Ud. o su uso tienen el apoyo de la licenciante. NonCommercial No-Comercial You may not use the material for commercial purposes. No puede utilizar el material con fines comerciales. ShareAlike ShareAlike If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original. Si remezcla, transforma o construye sobre el material, debe distribuir sus contribuciones bajo la misma licencia que el original. No additional restrictions Sin restricciones adicionales You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. No puede aplicar términos legales o medidas tecnológicas que restringan legalmente a otras personas de hacer cualquier cosa permitida por la licencia. CMultiColorLED Red Rojo Yellow Amarillo Green Verde CMusProfDlg server. This tag will also show up at each client which is connected to the same server as you. If the name is left empty, the IP address is shown instead. Esta etiqueta también se mostrará a cada cliente conectado al mismo servidor que tú. Se se deja vacío, se muestra la dirección IP en su lugar. Alias or name edit box Campo para alias o nombre Instrument picture button Botón imagen instrumento Country flag button Botón bandera país City edit box Ciudad Skill level combo box Nivel de habilidad None Ninguno Musician Profile Perfil Músico Alias/Name Alias/Nombre Instrument Instrumento Country País City Ciudad Skill Habilidad &Close &Cerrar Beginner Principiante Intermediate Intermedio Expert Experto Set your name or an alias here so that the other musicians you want to play with know who you are. Additionally you may set an instrument picture of the instrument you play and a flag of the country you are living in. The city you live in and the skill level playing your instrument may also be added. Escribe tu nombre o alias aquí para que los demás músicos con quien quieras tocar te reconozcan. Puedes además añadir una imagen del instrumento que tocas y la bandera del país donde vives. La ciudad donde vives y tu nivel de habilidad con el instrumento también pueden añadirse. What you set here will appear at your fader on the mixer board when you are connected to a Lo que introduzcas aquí aparecerá en tu fader del mezclador cuando te conectes a un servidor Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country you are located in. Your city and skill level playing your instrument may also be added. Escribe tu nombre o alias aquí para que otros músicos con quien quieras tocar te reconozcan. Puedes además añadir una imagen del instrumento que tocas y la bandera del país donde vives. La ciudad donde vives y tu nivel de habilidad con el instrumento también pueden añadirse. What you set here will appear at your fader on the mixer board when you are connected to a Jamulus server. This tag will also be shown at each client which is connected to the same server as you. If the name is left empty, the IP address is shown instead. Lo que introduzcas aquí aparecerá en tu fader del mezclador cuando te conectes a un servidor. Esta etiqueta también se mostrará en cada cliente conectado al mismo servidor que tú. Si se deja el nombre vacío, se muestra la dirección IP en su lugar. What you set here will appear at your fader on the mixer board when you are connected to a Jamulus server. This tag will also be shown at each client which is connected to the same server as you. Lo que introduzcas aquí aparecerá en tu fader del mezclador cuando te conectes a un servidor Jamulus. Esta etiqueta también se mostrará en cada cliente conectado al mismo servidor que tú. Drum Set Batería Djembe Djembé Electric Guitar Guitarra Eléctrica Acoustic Guitar Guitarra Acústica Bass Guitar Bajo Eléctrico Keyboard Teclado Synthesizer Sintetizador Grand Piano Piano de Cola Accordion Acordeón Vocal Voz Microphone Micrófono Harmonica Armónica Trumpet Trompeta Trombone Trombón French Horn Trompa Tuba Tuba Saxophone Saxofón Clarinet Clarinete Flute Flauta Violin Violín Cello Violonchelo Double Bass Contrabajo Recorder Grabadora Streamer Streamer Listener Oyente Guitar+Vocal Guitarra+Voz Keyboard+Vocal Teclado+Voz Bodhran Bodhran Bassoon Fagot Oboe Oboe Harp Arpa Viola Viola Congas Congas Bongo Bongo Vocal Bass Voz Bajo Vocal Tenor Voz Tenor Vocal Alto Voz Alto Vocal Soprano Voz Soprano Banjo Banjo Mandolin Mandolina Ukulele Ukulele Bass Ukulele Ukulele Barítono Vocal Baritone Voz Barítono Vocal Lead Voz Principal Mountain Dulcimer Dulcémele de Montaña Scratching Scratching Rapping Rapeo No Name Sin Nombre CServerDlg Client List Lista Clientes The client list shows all clients which are currently connected to this server. Some information about the clients like the IP address and name are given for each connected client. La lista de clientes muestra todos los clientes actualmente conectados a este servidor. Alguna información sobre los clientes como la dirección IP y el nombre aparecen para cada cliente conectado. Connected clients list view Vista lista clientes conectados Directory Type combo box Desplegable Tipo de Directorio Directory Directorio Select '%1' not to register your server with a directory. Selecciona '%1' para no registrar tu servidor en un directorio. Select one of the genres to register with that directory. Selecciona uno de los géneros para registrarte en ese directorio. Or select '%1' and specify a Custom Directory address on the Options tab to register with a custom directory. O selecciona '%1' y especifica una dirección de Directorio Personalizado en la pestaña de Opciones para registrarte en un directorio personalizado. For any value except '%1', this server registers with a directory so that a %2 user can select this server in the client connect dialog server list when they choose that directory. Para cualquier valor excepto '%1', este servidor se registra en un directorio para que un usuario de %2 pueda seleccionar este servidor de la lista de servidores en la ventana de conexión del cliente cuando escogen ese directorio. The registration of the server is renewed periodically to make sure that all servers in the connect dialog server list are actually available. El registro del servidor se renueva periódicamente para asegurarse de que todos los servidores en la lista de servidores en la ventana de conexión están realmente disponibles. When a value other than "%1" is chosen for Directory, this will show whether registration is successful. If the registration failed, please choose a different directory. Cuando se escoge un valor distinto a "%1" para el Directorio, esto mostrará si el registro ha tenido éxito. Si el registro fracasa, por favor elige otro directorio. No recording directory has been set or the value is not useable. Check the value in the Options tab. No se ha establecido un directorio de grabación o el valor no puede utilizarse. Comprueba el valor en la pestaña de Opciones. If the recording directory is not useable, the problem will be displayed in place of the session directory. Si el directorio de grabaciones no puede utilizarse, se mostrará el problema en lugar del directorio de la sesión. Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user %1 is running as). Pulsa el botón para abrir la ventana que permite seleccionar el directorio principal de grabaciones. El valor escogido debe existir y tener permiso de escritura (permitir la creación de sub-directorios por parte del usuario ejecutando %1). The current value of the main recording directory. The chosen value must exist and be writeable (allow creation of sub-directories by the user %1 is running as). Click the button to open the dialog that allows the main recording directory to be selected. El valor actual del directorio principal de grabaciones. El valor escogido debe existir y tener permisos de escritura (permitir la creación de sub-directorios por parte del usuario ejecutando %1). Pulsa el botón para abrir el diálogo que permite seleccionar el directorio principal de grabaciones. Custom Directory address Dirección Directorio Personalizado The Custom Directory address is the address of the directory holding the server list to which this server should be added. La dirección del Directorio Personalizado es la dirección del directorio que contiene la lista de servidores al cual debe añadirse este servidor. Server List Filename dialog push button Botón ventana Nombre Archivo Lista de Servidores Server List Filename Nombre Archivo Lista de Servidores Click the button to open the dialog that allows the server list persistence file name to be set. The user %1 is running as needs to be able to create the file name specified although it may already exist (it will get overwritten on save). Pulsa el botón para abrir la ventana que permite establecer el nombre del archivo de persistencia para la lista de servidores. El usuario ejecutando %1 debe poder crear el nombre de archivo especificado aunque ya exista (se sobreescribirá al guardar). Server List Filename text box (read-only) Caja texto Nombre Archivo Lista de Servidores (solo lectura) The current value of server list persistence file name. The user %1 is running as needs to be able to create the file name specified although it may already exist (it will get overwritten on save). Click the button to open the dialog that allows the server list persistence file name to be set. Valor actual del nombre del archivo de persistencia para la lista de servidores. El usuario ejecutando %1 debe poder crear el nombre de archivo especificado aunque ya exista (se sobreescribirá al guardar). Pulsa el botón para abrir la ventana que permite establecer el nombre del archivo de persistencia para la lista de servidores. Clear the server list file name button Vaciar el botón del nombre del archivo de lista de servidores Clear Server List Filename Vaciar Nombre del Archivo de Lista de Servidores Click the button to clear the currently selected server list persistence file name. This will prevent persisting the server list until a new value is selected. Pulsa el botón para vaciar el nombre del archivo de persistencia para la lista de servidores actualmente seleccionado. Esto impedirá la persistencia de la lista de servidores hasta que se seleccione un nuevo valor. Start Minimized on Operating System Start Arranca Minimizado al Arrancar Sistema Operativo Now a directory Ahora un directorio If the start minimized on operating system start check box is checked, the Si se activa el arranque al arrancar el sistema operativo, el server will be started when the operating system starts up and is automatically minimized to a system task bar icon. servidor arrancará cuando arranque el sistema operativo y se minimizará automáticamente a un icono en la barra de tareas. Show Creative Commons Licence Dialog Mostrar Diálogo de Licencia Creative Commons If enabled, a Creative Commons BY-NC-SA 4.0 Licence dialog is shown each time a new user connects the server. Si se activa, se mostrará un diálogo con la Licencia Creative Commons BY-NC-SA 4.0 cada vez que un cliente nuevo se conecte al servidor. Make My Server Public Mi Servidor es Público If the Make My Server Public check box is checked, this server registers itself at the directory server so that all Si se activa Mi Servidor es Público, este servidor se registra en el servidor central para que todos los usuarios de users can see the server in the connect dialog server list and connect to it. The registration of the server is renewed periodically to make sure that all servers in the connect dialog server list are actually available. puedan ver el servidor en la lista de servidores de la ventana de conexión y puedan conectarse a él. El registro del servidor se renueva periódicamente para asegurarse de que todos los servidores en la lista se encuentren realmente disponibles. Register Server Status Estado Registro Servidor If the Make My Server Public check box is checked, this will show whether registration with the directory server is successful. Si se ha activado Mi Servidor es Público, esto mostrará si se ha registrado en el servidor central con éxito. Directory Server Address Dirección Servidor Central The Directory server address is the IP address or URL of the directory server at which this server is registered. With the directory server address type either the local region can be selected of the default directory servers or a manual address can be specified. La dirección del Servidor Central es la dirección IP o URL del servidor central en el que se ha registrado este servidor. Aquí se puede escoger la región local de entre los servidores centrales por defecto o se puede especificar una dirección manualmente. If the Make My Server Public check box is checked, this will show whether registration with the directory server is successful. If the registration failed, please choose another server list. Si se activa Mi Servidor es Público, se mostrará si el registro con el servidor de directorio ha tenido éxito. Si el registro falla, por favor escoge otra lista de servidores. Default directory server type combo box Selección servidor central If the start minimized on operating system start check box is checked, the server will be started when the operating system starts up and is automatically minimized to a system task bar icon. Si se activa el arranque al arrancar el sistema operativo, el servidor arrancará cuando arranque el sistema operativo y se minimizará automáticamente a un icono en la barra de tareas. If the Make My Server Public check box is checked, this server registers itself at the directory server so that all users of the application can see the server in the connect dialog server list and connect to it. The registration of the server is renewed periodically to make sure that all servers in the connect dialog server list are actually available. Si se activa Mi Servidor es Público, este servidor se registra en el servidor de directorio para que todos los usuarios de la aplicación puedan ver el servidor en la lista de servidores de la ventana de conexión y conectarse a él. El registro del servidor se renueva periódicamente para asegurarse de que todos los servidores en la lista se encuentren realmente disponibles. Custom Directory Server Address Dirección Personalizada Servidor de Directorio The custom directory server address is the IP address or URL of the directory server at which the server list of the connection dialog is managed. La dirección personalizada del servidor de directorio es la dirección IP o URL del servidor de directorio en el cual se gestiona la lista de servidores de la ventana de conexión. Directory server address line edit Edición dirección servidor de directorio Server List Selection Selección Lista Servidores Selects the server list (i.e. directory server address) in which your server will be added. Selecciona la lista de servidores (por ej. dirección servidor de directorio) al que se añadirá tu servidor. Server list selection combo box Selección lista de servidores Server Name Nombre Servidor The server name identifies your server in the connect dialog server list at the clients. If no name is given, the IP address is shown instead. El nombre del servidor identifica a tu servidor en la lista de conexión de servidores de los clientes. Si no se especifica un nombre, se muestra la dirección IP en su lugar. The server name identifies your server in the connect dialog server list at the clients. El nombre del servidor identifica a tu servidor en la lista de conexión de servidores de los clientes. Server name line edit Nombre del servidor Location City Ubicación Ciudad The city in which this server is located can be set here. If a city name is entered, it will be shown in the connect dialog server list at the clients. Aquí se puede especificar la ciudad en donde se ubica el servidor. Si se introduce una ciudad, se mostrará en la lista de conexión de servidores de los clientes. City where the server is located line edit Ciudad en donde se encuentra en servidor Location country Ubicación país The country in which this server is located can be set here. If a country is entered, it will be shown in the connect dialog server list at the clients. Aquí se puede especificar el país en donde se ubica el servidor. Si se introduce un país, se mostrará en la lista de conexión de servidores de los clientes. Country where the server is located combo box País en donde se encuentra el servidor Country/Region País/Región Set the country or region where the server is running. Clients will show this location in their connect dialog's server list. Establece el país o la región donde se ejecuta el servidor. Los clientes mostrarán esta ubicación en la lista de servidores de su ventana de conexión. Combo box for location of this server Campo para la ubicación de este servidor Recording has been switched off by the UI checkbox. La grabación se ha apagado con la casilla de la interfaz gráfica. Recording has been switched off, either by the UI checkbox or SIGUSR2 being received. La grabación se ha apagado, bien a través de la casilla de la interfaz gráfica o por haber recibido SIGUSR2. Display dialog to select recording directory button Mostrar diálogo para seleccionar botón de directorio de grabación Main Recording Directory Directorio Principal de Grabación Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user Jamulus is running as). Pulsa el botón para abrir el diálogo que permite seleccionar el directorio principal de grabación. El valor escogido debe existir y tener permisos de escritura (permitir la creación de sub-directorios por parte del usuario ejecutando Jamulus). Main recording directory text box (read-only) Caja de texto del directorio principal de grabación (solo lectura) The current value of the main recording directory. The chosen value must exist and be writeable (allow creation of sub-directories by the user Jamulus is running as). Click the button to open the dialog that allows the main recording directory to be selected. El valor actual del directorio principal de grabación. El valor escogido debe existir y tener permisos de escritura (permitir la creación de sub-directorios por parte del usuario ejecutando Jamulus). Pulsa el botón para abrir el diálogo que permite seleccionar el directorio principal de grabación. Clear the recording directory button Vaciar botón de directorio de grabación Clear Recording Directory Vaciar Directorio de Grabación Click the button to clear the currently selected recording directory. This will prevent recording until a new value is selected. Pulsa el botón para vaciar el directorio de grabación actualmente seleccionado. Esto impedirá la grabación hasta que se seleccione un nuevo valor. Checkbox to turn on or off server recording Campo para activar/desactivar la grabación desde el servidor If the Register Server check box is checked, this will show whether registration with the directory server is successful. If the registration failed, please choose another server list. Si se activa la casilla de Registrar Servidor, esto mostrará si el registro con el servidor de directorio ha tenido éxito. Si falla el registro, por favor elige otra lista de servidores. Enable Recorder Habilitar Grabación Checked when the recorder is enabled, otherwise unchecked. The recorder will run when a session is in progress, if (set up correctly and) enabled. Activado cuando la grabación está habilitada. La grabación se ejecutará cuando una sesión esté en marcha, si está habilitada (y correctamente configurada). Current session directory text box (read-only) Campo para directorio sesión actual (solo lectura) Current Session Directory Directorio Sesión Actual Enabled during recording and holds the current recording session directory. Disabled after recording or when the recorder is not enabled. Habilitado durante la grabación y guarda el directorio actual de grabación, Deshabilitado tras la grabación o cuando la grabación no está habilitada. Recorder status label Etiqueta estado grabación Recorder Status Estado Grabación Displays the current status of the recorder. The following values are possible: Muestra el estado actual de la grabación. Son posibles los siguientes valores: No recording directory has been set or the value is not useable. No se ha establecido ningún directorio de grabación o el valor no es utilizable. Recording has been switched off La grabación se ha apagado by the UI checkbox mediante la casilla del interfaz , either by the UI checkbox or SIGUSR2 being received , bien mediante la casilla del interfaz o la recepción de SIGUSR2 There is no one connected to the server to record. No hay nadie conectado al servidor para grabar. The performers are being recorded to the specified session directory. Los intérpretes están siendo grabados al directorio de sesión especificado. NOTE NOTA If the recording directory is not useable, the problem will be displayed in place of the directory. Si el directorio de grabación no es utilizable, se mostrará el problema en lugar del directorio. Server welcome message edit box Campo edición mensaje bienvenida servidor Server Welcome Message Mensaje Bienvenida Servidor A server welcome message text is displayed in the chat window if a musician enters the server. If no message is set, the server welcome is disabled. Se muestra un mensaje de bienvenida al servidor cuando un músico entra al mismo. Si no se escribe ningún mensaje, la bienvenida se deshabilita. Language Idioma Select the language to be used for the user interface. Selecciona el idioma a utilizar para el interfaz de usuario. Language combo box Campo Idioma Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user Jamulus is running as). Pulsa el botón para abrir el diálogo que permite seleccionar el directorio principal de grabación. El valor escogido debe existir y tener permisos de escritura (permitir la creación de sub-directorios por parte del usuario ejecutando Jamulus). Custom Directory Directorio Personalizado The custom directory is the IP address or URL of the directory server at which the server list of the connection dialog is managed. El directorio personalizado es la dirección IP o URL del servidor de directorio en el cual se gestiona la lista de servidores de la ventana de conexión. Custom Directory line edit Edición de línea de Directorio Personalizado &Hide %1 server &Ocultar servidor %1 &Show %1 server Mo&strar servidor %1 %1 server %1 is the name of the main application %1 servidor Type a message here. If no message is set, the server welcome is disabled. Escribe un mensaje aquí. Si se deja vacío, el mensaje de bienvenida del servidor se deshabilita. %1 Server %1 is the name of the main application %1 Servidor software upgrade available Actualización de software disponible Recorder failed to start. Please check available disk space and permissions and try again. Error: La grabadora no pudo iniciarse. Por favor comprueba el espacio en disco y los permisos y prueba de nuevo. Error: ERROR ERROR Displays the current status of the recorder. Muestra el estado actual de la grabación. Request new recording button Botón Solicitar nueva grabación New Recording Nueva Grabación During a recording session, the button can be used to start a new recording. Durante una sesión de grabación, el botón puede utilizarse para comenzar una nueva grabación. E&xit &Salir &Hide &Ocultar servidor &Open &Abrir servidor server Select Main Recording Directory Seleccionar Directorio Principal de Grabación Predefined Address Dirección Preestablecida Recording Grabando Not recording No grabando Not initialised No inicializado Not enabled No habilitado Manual Manual Default Por defecto Default (North America) Por defecto (Norteamérica) Server : Servidor &Window &Ventana Unregistered Sin registrar None Ninguno Not registered No registrado Bad address Dirección no válida Registration requested Registro solicitado Registration failed Error de registro Check server version Comprueba la versión del servidor Registered Registrado Directory server list full Lista de servidores llena en Directorio Directory Server full Servidor de Directorio lleno Your server version is too old La versión de tu servidor es demasiado antigua Requirements not fulfilled No se cumplen los requisitos Unknown value %1 Valor desconocido %1 Unknown value Valor desconocido CServerDlgBase Client IP:Port IP:Puerto cliente Name Nombre Jitter Buffer Size Tamaño Jitter Buffer Channels Canales Server Setup Conf. Servidor List Lista Location: Region Ubicación: Región Session Sesión Chat Window Welcome (HTML/CSS Supported) Ventana Mensaje Bienvenida (HTML/CSS Soportado) Options Opciones Custom Directory address Dirección Directorio Personalizado Server List Filename Nombre Archivo Lista de Servidores Start Minimized on Windows Start Arranca Minimizado al Arrancar Windows Enable delay panning Activar paneo con retardo Show Creative Commons BY-NC-SA 4.0 Licence Dialog Mostrar Diálogo de Licencia Creative Commons BY-NC-SA 4.0 Update check Comprobación de actualización Make My Server Public (Register My Server in the Server List) Mi Servidor es Público (Registra Mi Servidor en la Lista de Servidores) Genre Género STATUS ESTADO Custom Directory Server Address: Dirección Personalizada Servidor de Directorio: Recording Directory Directorio de Grabación Enable Jam Recorder Activar Grabación de Jams Directory Directorio New Recording Nueva Grabación Language Consider add "(Lang)" as a suffix to ensure that users who selected the wrong language find the correct button Idioma Directory Server Address: Dirección Servidor Central: My Server Info Info Mi Servidor Location: City Ubicación: Ciudad Location: Country Ubicación: País Enable jam recorder Habilitar grabación Jam New recording Nueva grabación Recordings folder Carpeta grabaciones TextLabelNameVersion TextLabelNameVersion CServerListManager Could not write to '%1' No se pudo escribir a '%1' CSound The Jack server is not running. This software requires a Jack server to run. Normally if the Jack server is not running this software will automatically start the Jack server. It seems that this auto start has not worked. Try to start the Jack server manually. El servidor Jack no está arrancado. Este software necesita el servidor Jack para funcionar. Normalmente, si el servidor no está arrancado este software lo arrancará automáticamente. Parece que este auto-arranque no ha funcionado. Intenta arrancar el servidor Jack manualmente. The Jack server sample rate is different from the required one. The required sample rate is: La tasa de muestreo del servidor Jack es distinta a la requerida. La tasa de muestreo requerida es: You can use a tool like <i><a href="https://qjackctl.sourceforge.io">QJackCtl</a></i> to adjust the Jack server sample rate. Puedes utilizar una herramiento como <i><a href="https://qjackctl.sourceforge.io">QJackCtl</a></i> para ajustar la tasa de muestreo del servidor Jack. Make sure to set the Frames/Period to a low value like Asegúrate de establecer los Cuadros/Período en un valor bajo como to achieve a low delay. para conseguir un retardo bajo. The Jack port registering failed. El registro de puertos de Jack falló. Cannot activate the Jack client. No se puede activar el cliente Jack. The Jack server was shut down. This software requires a Jack server to run. Try to restart the software to solve the issue. El servidor Jack se ha cerrado. Este software necesita el servidor Jack para funcionar. Intenta reiniciar el software para solucionar este problema. CoreAudio input AudioHardwareGetProperty call failed. It seems that no sound card is available in the system. CoreAudio input AudioHardwareGetProperty call failed. Parece ser que el sistema no tiene una tarjeta de sonido disponible. CoreAudio output AudioHardwareGetProperty call failed. It seems that no sound card is available in the system. CoreAudio output AudioHardwareGetProperty call failed. Parece ser que el sistema no tiene una tarjeta de sonido disponible. Current system audio input device sample rate of %1 Hz is not supported. Please open the Audio-MIDI-Setup in Applications->Utilities and try to set a sample rate of %2 Hz. La tasa de muestreo actual del dispositivo de audio de entrada de %1 Hz no está soportada. Por favor, abre Configuración-Audio-MIDI en Aplicaciones->Utilidades e intenta configurar una tasa de muestreo de %2 Hz. The current selected audio device is no longer present in the system. El dispositivo de audio seleccionado actualmente ya no está presente en el sistema. The audio input device is no longer available. El dispositivo de entrada de audio ya no está disponible. The audio output device is no longer available. El dispositivo de salida de audio ya no está disponible. Current system audio output device sample rate of %1 Hz is not supported. Please open the Audio-MIDI-Setup in Applications->Utilities and try to set a sample rate of %2 Hz. La tasa de muestreo actual del dispositivo de audio de salida de %1 Hz no está soportada. Por favor, abre Configuración-Audio-MIDI en Aplicaciones->Utilidades e intenta configurar una tasa de muestreo de %2 Hz. The audio input stream format for this audio device is not compatible with this software. El formato de transmisión de audio de entrada para este dispositivo de audio no es compatible con este software. The audio output stream format for this audio device is not compatible with this software. El formato de transmisión de audio de salida para este dispositivo de audio no es compatible con este software. The buffer sizes of the current input and output audio device cannot be set to a common value. Please choose other input/output audio devices in your system settings. Los tamaños de buffer del dispositivo actual de entrada/salida de audio no pueden establecerse en un valor común. Por favor, selecciona otros dispositivos de entrada/salida de audio en la configuración del sistema. The audio driver could not be initialized. No se pudo iniciar el driver de audio. The audio device does not support the required sample rate. The required sample rate is: El dispositivo de audio no soporta la tasa de muestreo requerida. La tasa de muestreo requerida es de: The audio device does not support setting the required sampling rate. This error can happen if you have an audio interface like the Roland UA-25EX where you set the sample rate with a hardware switch on the audio device. If this is the case, please change the sample rate to El dispositivo de audio no permite establecer la tasa de muestreo requerida. Este error puede suceder si tienes un dispositivo de audio como el Roland UA-25EX en el que se configura mediante un interruptor físico en el dispositivo. Si es este el caso, por favor cambia la tasa de muestreo a Hz on the device and restart the Hz en el dispositivo y reinicie el software software. . The audio device does not support the required number of channels. The required number of channels for input and output is: El dispositivo de audio no soporta el número de canales requerido. El número de canales requerido es de: Required audio sample format not available. Formato de muestras de audio requerido no disponible. The selected audio device is no longer present in the system. Please check your audio device. El dispositivo seleccionado ya no está presente en el sistema. Por favor comprueba tu dispositivo de audio. Couldn't initialise the audio driver. Check if your audio hardware is plugged in and verify your driver settings. No se pudo inicializar el driver de audio. Comprueba que tu hardware de audio esté conectado y verifica la configuración del driver. The selected audio device is incompatible since it doesn't support a sample rate of %1 Hz. Please select another device. El dispositivo de audio seleccionado es incompatible ya que no soporta una tasa de muestreo de %1 Hz. Por favor selecciona otro dispositivo. The current audio device configuration is incompatible because the sample rate couldn't be set to %2 Hz. Please check for a hardware switch or driver setting to set the sample rate manually and restart %1. La configuración actual del dispositivo de audio es incompatible porque no se pudo establecer la tasa de muestreo en %2 Hz. Por favor comprueba si hay un interruptor físico o un ajuste del driver para establecer la tasa de muestreo manualmente y reinicia %1. The selected audio device is incompatible since it doesn't support %1 in/out channels. Please select another device or configuration. El dispositivo de audio seleccionado es incompatible ya que no soporta %1 canales de entrada/salida. Por favor selecciona otro dispositivo u otra configuración. The selected audio device is incompatible since the required audio sample format isn't available. Please use another device. El dispositivo de audio seleccionado es incompatible ya que el formato requerido de muestreo de audio no está disponible. Por favor utiliza otro dispositivo. No ASIO audio device driver found. No se ha encontrado un dispositivo de audio ASIO. Please install an ASIO driver before running %1. If you own a device with ASIO support, install its official ASIO driver. If not, you'll need to install a universal driver like ASIO4ALL. Por favor instala un driver ASIO antes de ejecutar %1. Si tienes un dispositivo con soporte ASIO, instala su driver ASIO oficial. Si no, tendrás que instalar un driver universal como ASIO4ALL. Please install an ASIO driver before running %1. If you own a device with ASIO support, install its official ASIO driver. If not, you'll need to download and install a universal driver like ASIO4ALL. Por favor instala un driver ASIO antes de ejecutar %1. Si tienes un dispositivo con soporte ASIO, instala su driver ASIO oficial. Si no, tendrás que descargar e instalar un driver universal como ASIO4ALL. No ASIO audio device (driver) found. No se ha encontrado un dispositivo ASIO (driver). The El software software requires the low latency audio interface ASIO to work properly. This is not a standard Windows audio interface and therefore a special audio driver is required. Either your sound card has a native ASIO driver (which is recommended) or you might want to use alternative drivers like the ASIO4All driver. requiere la interfaz de audio de baja latencia ASIO para funcionar correctamente. No es una interfaz estándar de Windows y por tanto se requiere un driver de audio especial. Tu tarjeta de audio podría tener un driver ASIO nativo (lo recomendado) o quizá quieras probar un driver alternativo como ASIO4All. Error requesting stream stop: $s Error petición parada transmisión: $s Error closing stream: $s Error cerrando transmisión: $s JACK couldn't be started automatically. Please start JACK manually and check for error messages. JACK no pudo iniciarse automáticamente. Por favor arranca JACK manualmente y comprueba si hay mensajes de error. JACK isn't running at a sample rate of <b>%1 Hz</b>. Please use a tool like <i><a href="https://qjackctl.sourceforge.io">QjackCtl</a></i> to set the the JACK sample rate to %1 Hz. JACK no está utilizando una tasa de muestreo de <b>%1 Hz</b>. Por favor utiliza una herramienta como <i><a href="https://qjackctl.sourceforge.io">QjackCtl</a></i> para establecer la tasa de muestreo de JACK en %1 Hz. The JACK port registration failed. This is probably an error with JACK. Please stop %1 and JACK. Afterwards check if another program at a sample rate of %2 Hz can connect to JACK. El registro de puertos de JACK falló. Probablemente sea un error en JACK. Por favor detén %1 y JACK. Después, comprueba si otro programa con una tasa de muestreo de %2 Hz puede conectarse a JACK. The JACK port registration failed. This is probably an error with JACK. Please stop %1 and JACK. Afterwards, check if another MIDI program can connect to JACK. El registro de puertos de JACK falló. Probablemente sea un error en JACK. Por favor detén %1 y JACK. Después, comprueba si otro programa MIDI puede conectarse a JACK. Can't activate the JACK client. This is probably an error with JACK. Please check the JACK output. No se pudo activar el cliente de JACK. Probablemente sea un error en JACK. Por favor comprueba la salida de JACK. JACK was shut down. %1 requires JACK to run. Please restart %1 to start JACK again. JACK se cerró. %1 requiere que se ejecute JACK. Por favor reinicia %1 para arrancar JACK de nuevo. No sound card is available in your system. CoreAudio input AudioHardwareGetProperty call failed. No hay ninguna tarjeta de sonido disponible en tu sistema. Falló CoreAudio input AudioHardwareGetProperty. No sound card is available in the system. CoreAudio output AudioHardwareGetProperty call failed. No hay ninguna tarjeta de sonido disponible en el sistema. Falló CoreAudio output AudioHardwareGetProperty. The currently selected audio device is no longer present. Please check your audio device. El dispositivo de audio seleccionado actualmente ya no está presente. Por favor comprueba tu dispositivo de audio. The audio input device is no longer available. Please check if your input device is connected correctly. El dispositivo de entrada de audio ya no está disponible. Por favor comprueba que tu dispositivo de entrada está conectado correctamente. The sample rate on the current input device isn't %1 Hz and is therefore incompatible. Please select another device or try setting the sample rate to %1 Hz manually via Audio-MIDI-Setup (in Applications->Utilities). La tasa de muestreo en el dispositivo actual de entrada no es de %1 Hz y por tanto es incompatible. Por favor selecciona otro dispositivo o intenta establecer la tasa de muestro en %1 Hz manualmente a través de la Configuración de Audio-MIDI (en Aplicaciones->Utilidades). The audio output device is no longer available. Please check if your output device is connected correctly. El dispositivo de salida de audio ya no está disponible. Por favor comprueba que tu dispositivo de salida está conectado correctamente. The sample rate on the current output device isn't %1 Hz and is therefore incompatible. Please select another device or try setting the sample rate to %1 Hz manually via Audio-MIDI-Setup (in Applications->Utilities). La tasa de muestreo en el dispositivo actual de salida no es de %1 Hz y por tanto es incompatible. Por favor selecciona otro dispositivo o intenta establecer la tasa de muestro en %1 Hz manualmente a través de la Configuración de Audio-MIDI (en Aplicaciones->Utilidades). The stream format on the current input device isn't compatible with this software. Please select another device. El formato de transmisión del dispositivo actual de entrada es incompatible con este software. Por favor selecciona otro dispositivo. The stream format on the current output device isn't compatible with %1. Please select another device. El formato de transmisión del dispositivo actual de salida es incompatible con %1. Por favor selecciona otro dispositivo. The buffer sizes of the current input and output audio device can't be set to a common value. Please select different input/output devices in your system settings. Los tamaños de buffer de entrada y salida de audio del dispositivo actual no se pueden establecer en un valor común. Por favor selecciona otros dispositivos de entrada/salida en tu configuración de sistema. CSoundBase Invalid device selection. Selección de dispositivo no válida. The audio driver properties have changed to a state which is incompatible with this software. The selected audio device could not be used because of the following error: Las propiedades del driver de audio han cambiado a un estado que es incompatible con este software. El dispositivo de audio seleccionado no se pudo utilizar a causa del siguiente error: Please restart the software. Por favor reinicie el software. Close Cerrar The selected audio device could not be used because of the following error: El dispositivo de audio seleccionado no puede utilizarse a causa del siguiente error: The previous driver will be selected. Se seleccionará el driver anterior. The previously selected audio device is no longer available or the audio driver properties have changed to a state which is incompatible with this software. We now try to find a valid audio device. This new audio device might cause audio feedback. So, before connecting to a server, please check the audio device setting. El dispositivo de audio seleccionado anteriormente ya no está disponible o las propiedades del driver han cambiado a un estado que es incompatible con este software. Intentaremos ahora encontrar un dispositivo de audio válido. Este nuevo dispositivo puede ocasionar retroalimentación de audio. Por tanto, antes de conectarte a un servidor, comprueba la configuración del dispositivo de audio. No usable Ningún driver audio device (driver) found. de audio utilizable encontrado. In the following there is a list of all available drivers with the associated error message: A continuación hay una lista de todos los drivers disponibles con el error asociado: Do you want to open the ASIO driver setups? ¿Quieres abrir la configuración del driver ASIO? could not be started because of audio interface issues. no pudo arrancar debido a problemas con el dispositivo de audio. Can't use the selected audio device because of the following error: %1 The previous driver will be selected. No se puede utilizar el dispositivo de audio seleccionado por el siguiente error: %1 Se seleccionará el driver anterior. The previously selected audio device is no longer available or the driver has changed to an incompatible state. We'll attempt to find a valid audio device, but this new audio device may cause feedback. Before connecting to a server, please check your audio device settings. El dispositivo de audio seleccionado anteriormente ya no está disponible o el driver ha cambiado a un estado incompatible. Intentaremos encontrar un dispositivo de audio válido, pero este nuevo dispositivo puede ocasionar retroalimentación. Antes de conectarte a un servidor, por favor comprueba la configuración del dispositivo de audio. <b>%1 couldn't find a usable %2 audio device.</b><br><br> <b>%1 no pudo encontrar un dispositivo de audio %2.</b><br><br> You may be able to fix errors in the driver settings. Do you want to open these settings now? Quizá puedas arreglar errores en la configuración del driver. ¿Quieres abrir la configuración ahora? No usable %1 audio device found. No se encontró ningún dispositivo de audio %1 utilizable. These are all the available drivers with error messages: Estos son todos los drivers de audio disponible con mensajes de error: Do you want to open the ASIO driver setup to try changing your configuration to a working state? ¿Deseas abrir la configuración del driver de ASIO para intentar cambiar tu configuración a un estado funcional? Can't start %1. Please restart %1 and check/reconfigure your audio settings. No se puede iniciar %1. Por favor reinicia %1 y comprueba/vuelve a configurar tus ajustes de audio. QCoreApplication %1, Version %2 %1, Versión %2 Internet Jam Session Software Internet Jam Session Software %1, Version %2 %1 is app name, %2 is version number %1, Versión %2 Released under the GNU General Public License version 2 or later (GPLv2) Publicado bajo la GNU General Public License versión 2 o posterior (GPLv2) the terms of the GNU General Public License as published by the Free Software los términos de la GNU General Public License tal como lo publica la Free Software Foundation; either version 2 of the License, or (at your option) any later version. Foundation; bien bajo la versión 2 de la Licencia, o (a tu elección) cualquier versión posterior. There is NO WARRANTY, to the extent permitted by law. No existe NINGUNA GARANTÍA, en la medida permitida por la ley aplicable. Using the following libraries, resources or code snippets: Utilizando las siguientes librerías, recursos o fragmentos de código: Qt framework Qt framework Opus Interactive Audio Codec Opus Interactive Audio Codec Audio reverberation code by Perry R. Cook and Gary P. Scavone Código de reverberación de audio de Perry R. Cook y Gary P. Scavone Some pixmaps are from the Open Clip Art Library (OCAL) Algunos pixmaps son de la Open Clip Art Library (OCAL) Flag icons by Mark James Iconos de banderas de Mark James Copyright (C) 2005-2022 The Jamulus Development Team Copyright (C) 2005-2022 The Jamulus Development Team Released under the GNU General Public License (GPL) Publicado bajo la GNU General Public License (GPL) global A %1 upgrade is available: <a style='color:red;' href='https://jamulus.io/upgrade?progversion=%2'>go to details and downloads</a> Hay una actualización de %1 disponible: <a style='color:red;' href='https://jamulus.io/upgrade?progversion=%2'>ir a detalles y descargas</a> For more information use the "What's This" help (help menu, right mouse button or Shift+F1) Para más información utiliza "¿Qué es Esto?" (menú de ayuda, botón derecho del ratón o Shift+F1) jamulus-3.9.1+dfsg/src/translation/translation_it_IT.ts0000644000175000017500000103010014340334543022272 0ustar vimervimer CAboutDlg The Il software software enables musicians to perform real-time jam sessions over the internet. permette ai musicisti di creare jam session in real time attraverso internet. There is a Attraverso un Server server which collects the audio data from each che acquisisce i dati audio da ogni client, mixes the audio data and sends the mix back to each client. client; mixa i dati audio e li rimanda ad ogni client. uses the following libraries, resources or code snippets: usa le seguenti librerie, risorse o parti di codice: Qt cross-platform application framework Audio reverberation code by Perry R. Cook and Gary P. Scavone Audio reverberation sviluppato da Perry R. Cook and Gary P. Scavone Some pixmaps are from the Alcune pixmaps provengono da Country flag icons from Mark James Icone delle bandiere a cura di Mark James This app enables musicians to perform real-time jam sessions over the internet. Dà la possibilità ai musicisti di realizzare sessioni live attraverso internet. There is a server which collects the audio data from each client, mixes the audio data and sends the mix back to each client. Il server acquisisce i dati audio di ogni client, mixa i dati audio e li rimanda ad ogni client connesso. This app uses the following libraries, resources or code snippets: Questa applicazione usa le seguenti librerie, risorse e parti di codice: Country flag icons by Mark James Le icone delle bandiere sono state realizzate da Marl James For details on the contributions check out the Per maggiori informazioni su chi ha contribuito, visitare Flag icons by Mark James Bandiere create da Mark James Some sound samples are from Alcuni campioni audio provengono da For details on the contributions check out the %1 Per maggiorni dettagli su chi contribuisce al progetto visitare %1 Github Contributors list Lista dei collaboratori su Github Spanish Spagnolo French Francese Portuguese Portoghese Dutch Olandese Italian Italiano German Tedesco Polish Polacco Swedish Svedese Korean Slovak Slovacco Simplified Chinese Cinese Semplificato Norwegian Bokmål About %1 Informazioni su %1 About Informazioni su , Version , Versione Released under the GNU General Public License (GPL) Rilasciato sotto licensa GNU General Public License (GPL) Under the GNU General Public License (GPL) Sotto la GNU General Public License (GPL) CAboutDlgBase About Informazioni su TextLabelVersion Versione Copyright (C) 2005-2022 Volker Fischer and others Copyright (C) 2005-2022 Volker Fischer e altri Copyright (C) 2005-2022 The Jamulus Development Team Copyright (C) 2005-2022 Team di sviluppo Jamulus A&bout I&nformazioni &Libraries &Librerie &Contributors &Collaboratori &Translation &Traduzioni &OK &OK CAnalyzerConsole Analyzer Console Consolle Analizzatore Error Rate of Each Buffer Size Tasso di errore per ogni Buffer CAudioMixerBoard Personal Mix at the Server Mixer personale sul Server When connected to a server, the controls here allow you to set your local mix without affecting what others hear from you. The title shows the server name and, when known, whether it is actively recording. Quando connessi i fader permettono di regolare i volumi in locale senza influenzare l'ascolto degli altri utenti. L'intestazione mostra il nome de server, se valorizzato, e le informazioni sullo stato della sessione di registrazione se attiva. Server Server T R Y I N G T O C O N N E C T I N A T T E S A D I C O N N E S S I O N E RECORDING ACTIVE Sessione con Registrazione Attiva Personal Mix at: %1 Mixer personale sul Server: %1 CChannelFader Pan Bilanciamento Mute Mute Solo Solo &No grouping &Non Assegnato Assign to group Assegna al Gruppo The fader tag identifies the connected client. The tag name, a picture of your instrument and the flag of your location can be set in the main window. Il fader identifica il client connesso. Il nikname, un'immagine del tuo strumento e la bandiera del tuo paese, possono essere impostati nella finestra principale. Mixer channel country/region flag Bandiera della regione o paese relativa al canale del mixer Grp Grp Channel Level Volume Displays the pre-fader audio level of this channel. All connected clients at the server will be assigned an audio level, the same value for each client. Visualizza il livello audio pre-fader di questo canale. A tutti i client connessi al server verrà assegnato un livello audio, lo stesso valore per ciascun client. Input level of the current audio channel at the server Livello di input del canale audio corrente sul server Mixer Fader Mixer Fader Adjusts the audio level of this channel. All connected clients at the server will be assigned an audio fader at each client, adjusting the local mix. Regola il livello audio di questo canale. A tutti i client connessi al server verrà assegnato un fader audio su ciascun client, regolando il mix locale. Local mix level setting of the current audio channel at the server Impostazione del livello di volume locale del canale audio corrente sul server Status Indicator Indicatore di Stato Shows a status indication about the client which is assigned to this channel. Supported indicators are: Visualizza lo stato del client assegnato a questo canale. Gli Stati supportati sono: Speaker with cancellation stroke: Indicates that the other client has muted you. Altoparlante segnato: Indica che un altro client ha messo in mute il tuo canale. Status indicator label Etichetta dell'indicatore di stato Panning Bilanciamento Sets the panning position from Left to Right of the channel. Works only in stereo or preferably mono in/stereo out mode. Imposta il Bilanciamento da Sinistra a Destra del canale. Funzione abilitata in modalità stereo oppure in modalità mono in/stereo out. Local panning position of the current audio channel at the server Bilancimento locale del canale audio corrente sul server With the Mute checkbox, the audio channel can be muted. Quando il Mute è selezionato, il canale audio è mutato. Mute button Pulsante Mute With the Solo checkbox, the audio channel can be set to solo which means that all other channels except of the current channel are muted. It is possible to set more than one channel to solo. Quando il Solo è attivo, il canale audio sarà in modalità solista escludendo gli altri canali che non saranno più udibili. E' possibile attivare il solo su più canali per sentirli contemporaneamente. Solo button Pulsante Solo Fader Tag Tag Fader The fader tag identifies the connected client. The tag name, the picture of your instrument and a flag of your country can be set in the main window. Il tag fader identifica il client connesso. Il nome del tag, l'immagine del tuo strumento e una bandiera del tuo paese possono essere impostati nella finestra principale del profilo. Displays the pre-fader audio level of this channel. All clients connected to the server will be assigned an audio level, the same value for every client. Visualizza il livello "pre-fader" di questo canale. Tutti i client connessi al server avranno assegnato un livello audio, lo stesso valore per ogni client. Adjusts the audio level of this channel. All clients connected to the server will be assigned an audio fader, displayed at each client, to adjust the local mix. Regola il livello audio di questo canale. A tutti i client connessi sarà assegnatu un fader per regolare il mix audio locale. Speaker with cancellation stroke: Indicates that another client has muted you. Altoparlate con il segnale rosso: indica che un altro client ha messo il tuo canale in mute. Sets the pan from Left to Right of the channel. Works only in stereo or preferably mono in/stereo out mode. Regola il bilanciamento Sinistro - Destro del canale. Funziona solo se abilitata la funzione stereo oppure "mono-in/stereo-out". With the Solo checkbox, the audio channel can be set to solo which means that all other channels except the soloed channel are muted. It is possible to set more than one channel to solo. Se selezionato il pulsate "Solo", il canale audio sarà settato nella modalità di "Solo" ovvero tutti i canali saranno mutati ad eccezione di quelli in modalità "Solo". Group Raggruppa With the Grp checkbox, a group of audio channels can be defined. All channel faders in a group are moved in proportional synchronization if any one of the group faders are moved. Con il comando Rag, può essere definito un gruppo di canali. Tutti i canali raggruppati possono essere modificati in modo proporzionale muovendo uno dei fader del gruppo. Group button Raggruppa The fader tag identifies the connected client. The tag name, a picture of your instrument and the flag of your country can be set in the main window. La targa sotto il Fader identifica il client connesso. Il nome, l'immagine dello strumento, e la bandiera della nazionalità possono essere settati tramite la finestra del profilo. Mixer channel instrument picture Immagine dello strumento Mixer channel label (fader tag) Etichetta del Canale (fader tag) Mixer channel country flag Bandiera del Paese PAN Bil. (L / R) MUTE MUTE SOLO SOLO GRP GRP M M S S G G Alias/Name Identificativo/Nome Instrument Strumento Location Località Skill Level Livello di Preparazione Alias Alias Beginner Principiante Intermediate Livello Intermedio Expert Esperto Musician Profile Profilo del Musicista CChatDlg Chat Window Finestra della Chat The chat window shows a history of all chat messages. La finestra della chat mostra la storia di tutti i messaggi. Chat history Storia della Chat Input Message Text Input Messaggio di Testo Enter the chat message text in the edit box and press enter to send the message to the server which distributes the message to all connected clients. Your message will then show up in the chat window. Immettere il testo del messaggio di chat nella casella di testo e premere Invio per inviare il messaggio al server che distribuirà il messaggio a tutti i client connessi. Il tuo messaggio verrà quindi visualizzato nella finestra di chat. New chat text edit box Nuova casella di testo della chat Type a message here Inserisi un messaggio qui &Edit &Modifica Cl&ear Chat History Cance&lla Storico Chat &Close &Chiudi Do you want to open the link '%1' in your browser? Vuoi aprire il link '%1' nel tuo Browser? Do you want to open the link Vuoi che il sia aperto in an external browser? sul browser? CChatDlgBase Chat Chat &Send &Invia Cl&ear Can&ella &Close &Chiudi CClientDlg Input Level Meter Livello Segnale d'ingresso The input level indicators show the input level of the two stereo channels of the current selected audio input. L'idicatore del segnale in ingresso mostra il livello dei due canali stereo scelti come input. Make sure not to clip the input signal to avoid distortions of the audio signal. Controllare di non saturare il livello di input per evitare distorsioni nel segnale audio. If the Se software is connected and you play your instrument/sing in the microphone, the LED level meter should flicker. If this is not the case, you have probably selected the wrong input channel (e.g. line in instead of the microphone input) or set the input gain too low in the (Windows) audio mixer. è collegato, suonando lo strumento oppure cantando con il microfono, l'idicatore a LED dovrebbe illuninarsi. In caso contrario probabilmente hai selezionato il canale di ingresso errato (ad es. Line in anziché l'ingresso del microfono) oppure hai impostato un guadagno di input troppo basso nel mixer audio (Windows). For a proper usage of the Per un uso corretto di software, you should not hear your singing/instrument in the loudspeaker or your headphone when the non dovresti sentire la voce o lo strumento nelle casse o nelle cuffie quando software is not connected. This can be achieved by muting your input audio channel in the Playback mixer (not the Recording mixer!). il programma non è connesso. Basta disattivare il canale audio in ingresso nel mixer di riproduzione (non nel mixer di registrazione!). Input level meter Indicatore del Segnale in ingresso Simulates an analog LED level meter. Simula un indicatore a LED analogico. Connect/Disconnect Button Pulsante: Connetti-Disconnetti Push this button to connect to a server. A dialog where you can select a server will open. If you are connected, pressing this button will end the session. Cliccare il pulsante per connettersi ad un server. Si aprirà una finestra da dove poter scegliere a quale server connettersi. Se si è già connessi cliccando questo pulsante la connessione verrà interrotta. Connect and disconnect toggle button Pulsante di connessione e disconnessione Clicking on this button changes the caption of the button from Connect to Disconnect, i.e., it implements a toggle functionality for connecting and disconnecting the Facendo clic su questo pulsante si modifica la dicitura del pulsante da Connetti a Disconnetti, ovvero implementa una funzionalità di attivazione / disattivazione per la connessione e disconnessione del software. programma. Local Audio Input Fader Fader per l'input audio locale With the audio fader, the relative levels of the left and right local audio channels can be changed. For a mono signal it acts like a panning between the two channels. If, e.g., a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows Con questo fader, è possibile modificare i livelli relativi dei canali audio sinistro e destro. Per un segnale mono si comporta come un mix tra i due canali. Se, ad esempio, un microfono è collegato al canale di ingresso destro e uno strumento è collegato al canale di ingresso sinistro che è molto più forte del microfono, spostare il fader audio nella direzione opposta a L (Sinistra) per bilanciare i volumi L L , where , dove is the current attenuation indicator. si trova l'attuale indicatore di attenuazione. Local audio input fader (left/right) Fader di input locale (Sinistro/Destro) Reverberation Level Livello di Riverbero A reverberation effect can be applied to one local mono audio channel or to both channels in stereo mode. The mono channel selection and the reverberation level can be modified. If, e.g., the microphone signal is fed into the right audio channel of the sound card and a reverberation effect shall be applied, set the channel selector to right and move the fader upwards until the desired reverberation level is reached. Un effetto di riverbero può essere applicato al canale mono o ad entrambi i canali stereo. La selezione del canale mono e il livello di riverbero possono essere modificati. Se, ad esempio, il segnale del microfono viene immesso nel canale audio destro della scheda audio e deve essere applicato un effetto di riverbero, impostare il selettore di canale a destra e spostare il fader verso l'alto fino a raggiungere il livello di riverbero desiderato. The reverberation effect requires significant CPU so it should only be used on fast PCs. If the reverberation level fader is set to minimum (which is the default setting), the reverberation effect is switched off and does not cause any additional CPU usage. L'effetto di riverbero richiede un uso significativo della CPU, quindi è raccomandabile usarlo su computer veloci. Se il livello del riverbero è messo al minimo (come di default), l'effetto è disattivato e non causa rallentamenti sulla CPU. Reverberation effect level setting Settaggio del livello di Riverbero Reverberation Channel Selection Selettore di canale per il Riverbero With these radio buttons the audio input channel on which the reverberation effect is applied can be chosen. Either the left or right input channel can be selected. Con questi pulsanti di opzione è possibile scegliere il canale d'ingresso audio su cui viene applicato l'effetto di riverbero. È possibile selezionare il canale di input sinistro o destro. Left channel selection for reverberation Canale Sinistro per il Riverbero Right channel selection for reverberation Canale Destro per il Riverbero Delay Status LED LED di Stato del Delay The delay status LED indicator shows the current audio delay status. If the light is green, the delay is perfect for a jam session. If the light is yellow, a session is still possible but it may be harder to play. If the light is red, the delay is too large for jamming. Il LED di stato del delay indica graficamente il valore assunto in quel momento. Se verde il delay è nei valori ottimali, se giallo indica che durante la sessione si possono verificare situazioni in cui può diventare difficile suonare, se rosso il delay è troppo alto per una sessione. If this LED indicator turns red, you will not have much fun using the Se il LED diventa rosso avrete difficoltà nel suonare con Delay status LED indicator LED di stato del Delay Buffers Status LED LED di Stato del Buffer The buffers status LED indicator shows the current audio/streaming status. If the light is green, there are no buffer overruns/underruns and the audio stream is not interrupted. If the light is red, the audio stream is interrupted caused by one of the following problems: Il LED di stato del buffer indica la qualità dello straming. Se verde non sono presenti anomalie nel buffer e lo stream audio non subirà interruzioni. Se rosso lo stream audio subirà interruzioni per causa di uno dei seguenti motivi: The network jitter buffer is not large enough for the current network/audio interface jitter. Il Jitter Buffer non è grande abbastanza per la tipologia di rete/interfaccia audio usate. The sound card buffer delay (buffer size) is set to too small a value. Il buffer delay della scheda audio è impostato su un valore troppo basso. The upload or download stream rate is too high for the current available internet bandwidth. La quantià di dati in upload o in download è eccessiva rispetto alla banda internet disponibile. This shows the level of the two stereo channels for your audio input. Visualizza il livello di input dei due canali stereo. If the application is connected to a server and you play your instrument/sing into the microphone, the VU meter should flicker. If this is not the case, you have probably selected the wrong input channel (e.g. 'line in' instead of the microphone input) or set the input gain too low in the (Windows) audio mixer. Se il programma è connesso ad un server e voi state suonando o cantando, il VU-Meter sarà in funzione. Se ciò non accade probabilemnte avete settato un ingresso errato oppure il livello di input è troppo basso. For proper usage of the application, you should not hear your singing/instrument through the loudspeaker or your headphone when the software is not connected. This can be achieved by muting your input audio channel in the Playback mixer (not the Recording mixer!). Per un corretto utilizzo dell'applicazione, non è possibile ascoltare il canto o lo strumento attraverso l'altoparlante o le cuffie quando il programma non è collegato. Basta disattivare l'audio del canale di ingresso nel mixer di riproduzione (non nel mixer di registrazione!). Clicking on this button changes the caption of the button from Connect to Disconnect, i.e., it implements a toggle functionality for connecting and disconnecting the application. Cliccando su questo pulsante il stato passa da Connesso a Disconnesso, implementa infatti la funzionalità di connessione-disconnessione del programma. Controls the relative levels of the left and right local audio channels. For a mono signal it acts as a pan between the two channels. For example, if a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows Controlla i livelli relativi dei canali audio locali sinistro e destro. Per un segnale mono funge da pan tra i due canali. Ad esempio, se un microfono è collegato al canale di ingresso destro e uno strumento è collegato al canale di ingresso sinistro che è molto più forte del microfono, spostare il cursore audio in una direzione in cui viene mostrata l'etichetta sopra il fader Reverb effect Effetto Reverbero Reverb can be applied to one local mono audio channel or to both channels in stereo mode. The mono channel selection and the reverb level can be modified. For example, if a microphone signal is fed in to the right audio channel of the sound card and a reverb effect needs to be applied, set the channel selector to right and move the fader upwards until the desired reverb level is reached. Il Reverbero può essere applicato sia in modalità mono che stereo. La selezione del canale mono e il livello di riverbero possono essere modificati. Ad esempio, se un segnale del microfono viene immesso nel canale audio destro della scheda audio e deve essere applicato un effetto di riverbero, impostare il selettore di canale su destra e spostare il fader verso l'alto fino a raggiungere il livello di riverbero desiderato. Reverb effect level setting Livello dell'effetto di Reverbero Reverb Channel Selection Selezione Canale Reverbero With these radio buttons the audio input channel on which the reverb effect is applied can be chosen. Either the left or right input channel can be selected. Con questi pulsanti di opzione è possibile scegliere il canale di ingresso audio su cui viene applicato l'effetto riverbero. È possibile selezionare il canale di input sinistro o destro. Left channel selection for reverb Canale Sinistro per il Reverbero Right channel selection for reverb Canale Destro per il Reverbero Green Verde The delay is perfect for a jam session. Il delay è perfetto per una live session. Yellow Giallo Red Rosso Opens a dialog where you can select a server to connect to. If you are connected, pressing this button will end the session. Apre una finestra di dialogo in cui è possibile selezionare un server a cui connettersi. Se si è connessi, premere questo pulsante per terminare la sessione. Shows the current audio delay status: Visualizza lo stato corrente del delay: A session is still possible but it may be harder to play. Una sessione è ancora possibile ma potrebbe essere più difficile suonare. The delay is too large for jamming. Il delay è eccessivo per una live session. If this LED indicator turns red, you will not have much fun using the application. Se il LED diventa rosso non si avrà una buona esperinza di utilizzo dell'applicazione. The buffers status LED shows the current audio/streaming status. If the light is red, the audio stream is interrupted. This is caused by one of the following problems: Il LED di stato del buffer mostra lo stato audio dello streaming corrente. Se la luce è rossa, il flusso audio viene interrotto. Ciò è causato da uno dei seguenti problemi: The sound card's buffer delay (buffer size) is too small (see Settings window). Il ritardo della scheda audio(ovvero il buffer size) è troppo basso (vedere i Settaggi della Scheda). The upload or download stream rate is too high for your internet bandwidth. La banda passante per lo stream (upload e download) è troppo rispetto alla qualità della connessione internet. The CPU of the client or server is at 100%. La CPU del client è satura al 100%. Buffers status LED indicator Led di stato del Buffer Current Connection Status Parameter Parametri attuali di connessione The Ping Time is the time required for the audio stream to travel from the client to the server and back again. This delay is introduced by the network and should be about 20-30 ms. If this delay is higher than about 50 ms, your distance to the server is too large or your internet connection is not sufficient. Il ping è il tempo necessario affinché il flusso audio passi dal client al server e viceversa. Questo ritardo è introdotto dalla rete e dovrebbe essere di circa 20-30 ms. Se questo ritardo è superiore a circa 50 ms, la distanza dal server è eccessiva o la connessione a Internet non è sufficiente. Overall Delay is calculated from the current Ping Time and the delay introduced by the current buffer settings. Il ritardo complessivo viene calcolato dal tempo di ping corrente e dal ritardo introdotto dalle impostazioni del buffer correnti. C&onnect C&onnetti software upgrade available Nuova versione disponibile &File &File &View &Vista &Connection Setup... Setup C&onnessione... My &Profile... &Profilo Personale... C&hat... C&hat... &Settings... &Settaggi... &Analyzer Console... &Analizzatore... N&o User Sorting N&on Riordinare i Canali Sort Users by &City Ordina i Canali per &Città di provenienza Use &Two Rows Mixer Panel Abilita &Vista su due Righe Clear &All Stored Solo and Mute Settings &Riprisitna tutti gli stati salvati di SOLO e MUTE Auto-Adjust all &Faders Auto regolazione &Fader Sett&ings Settag&i %1 Directory %1 Cartella Ok Ok Ok Clear &All Stored Solo Settings &Ripristina i canali settati in "Solo" Set All Faders to New Client &Level Setta &Livelli del Mixer al valore impostato per i Nuovi Utenti E&xit &Uscita Local Jitter Buffer Status LED Led di stato del Jitter Locale The local jitter buffer status LED shows the current audio/streaming status. If the light is red, the audio stream is interrupted. This is caused by one of the following problems: Il led di stato del Jitter Locale indica lo stato dello strem audio. Se diventa rosso l'audio risulta scadente. Questo è dovuto a diversi problemi: Local Jitter Buffer status LED indicator Indicatore Led del Jitter Buffer If this LED indicator turns red, you will not have much fun using the %1 software. Se questo indicatore LED diventa rosso, non sarai in grado di suonare e non riuscirai a divertirti tramite questo %1 software. &Load Mixer Channels Setup... &Carica Setup Mixer... &Save Mixer Channels Setup... &Salva Setup Mixer... &Settings &Settaggi Audio/Network &Settings... &Impostazioni Audio/Rete... A&dvanced Settings... Impostazioni A&vanzate... &Edit &Modifica If this LED indicator turns red, you will not have much fun using %1. Se questo indicatore LED diventa rosso, avrai difficoltà di ascolto mentre usi %1. If this LED indicator turns red, the audio stream is interrupted. Se questo indicatore LED diventa rosso , il flusso audio si interromperà. Current Connection Status Stato della connessione O&wn Fader First Metti il mio &fader prima degli altri Sort Users by &Name Ordina canali per &Nome Sort Users by &Instrument Ordina canali per &Strumento Sort Users by &Group Ordina Canali per Nome &Utente &Sort Users by Name &Canali in ordine Alfabetico None Nullo Center Centro R R Directory Server Server di Directory Select Channel Setup File Selezione File di Setup dei Canali user utente users utenti Connect Connetti Settings Impostazioni Chat Chat Enable feedback detection Abilita riconoscimento feedback Audio feedback or loud signal detected. We muted your channel and activated 'Mute Myself'. Please solve the feedback issue first and unmute yourself afterwards. Feedback audio o segnale forte rilevato. E' stato disattivato l'audio del tuo canale ed inserito il "Disattiva Inputt". Si prega di risolvere prima il problema dei larsen e dei ritorni e successivamente riattivare l'audio. Your sound card is not working correctly. Please open the settings dialog and check the device selection and the driver settings. Se la tua interfaccia non funziona correttamente, apri la schermata dei settaggi e controlla se è stata selezionata l'interfaccia corretta ed il suo relativo driver. &Disconnect Disco&nnetti CClientDlgBase Delay Delay Buffers Buffer Input Ingresso L L R R Jitter Jitter Ping Ping ms ms &Mute Myself &Disattiva Input &Settings &Settaggi &Chat &Chat C&onnect C&onnetti Pan Bilanciamento Center Centro Reverb Riverbero Left Left (Sinistra) Right Right (Destra) MUTED (Other people won't hear you) Muto (gli altri non possono sentirti) Set up your audio, connect to a server and start jamming! Configura la tua scheda audio, connettiti ad un server e suona! Update check Controlla Aggiornamenti CClientSettingsDlg Jitter Buffer Size Dimensione Jitter Bufer The jitter buffer compensates for network and sound card timing jitters. The size of this jitter buffer has therefore influence on the quality of the audio stream (how many dropouts occur) and the overall delay (the longer the buffer, the higher the delay). Il Jitter Buffer compensa i ritardi della rete o della scheda audio. La sua dimensione influisce sulla qualità dello stream audio (troppe interruzioni) e sull'OverAll delay (più grande è il buffer, più alto è il delay). The jitter buffer size can be manually chosen for the local client and the remote server. For the local jitter buffer, dropouts in the audio stream are indicated by the light below the jitter buffer size faders. If the light turns to red, a buffer overrun/underrun took place and the audio stream is interrupted. La dimensione del Jitter Buffer può essere settata manualmente sia per il client che per il server. Le problematiche del buffer locale sono segnalate dal LED posto sotto i Fader del Jitter buffer. Se il LED è rosso il buffer è corrotto e lo streamaudio subisce interruzioni. The jitter buffer setting is therefore a trade-off between audio quality and overall delay. I settaggi del jitter buffer regolano il compromesso tra qualità audio e ritardo generale. An auto setting of the jitter buffer size setting is available. If the check Auto is enabled, the jitter buffers of the local client and the remote server are set automatically based on measurements of the network and sound card timing jitter. If the Auto check is enabled, the jitter buffer size faders are disabled (they cannot be moved with the mouse). E' disponibile la funzione di regolazine Automatica del Jitter Buffer. Se Abilitata il Jitter Buffer Locale e Remoto saranno settati in base a delle misure effettuate sulla rete e sul ritardo della scheda audio. In questo caso i fader di regolazione saranno disabilitati(non potranno essere mossi con il muose). If the auto setting of the jitter buffer is enabled, the network buffers of the local client and the remote server are set to a conservative value to minimize the audio dropout probability. To tweak the audio delay/latency it is recommended to disable the auto setting functionality and to lower the jitter buffer size manually by using the sliders until your personal acceptable limit of the amount of dropouts is reached. The LED indicator will visualize the audio dropouts of the local jitter buffer with a red light. Nel caso in cui sia abilitata l'impostazione automatica del jitter buffer, i buffer di rete del client locale e del server remoto sono impostati su un valore di tipo conservativo per ridurre al minimo la probabilità di dropout audio. Per modificare il ritardo / latenza audio, si consiglia di disabilitare la funzionalità di impostazione automatica e di ridurre manualmente la dimensione del JitterBuffer utilizzando i fader fino a raggiungere il limite personale per una qualità audio accettabile. L'indicatore LED visualizzerà i dropout audio del Jitter Buffer locale diventando rosso. Local jitter buffer slider control Controlli per la gestione del Jitter Buffer Server jitter buffer slider control Fader del Jitter Buffer del Server Auto jitter buffer switch Switch Jitter Buffer Automatico Jitter buffer status LED indicator LED di stato del Jitter Buffer Sound Card Device Scheda Audio The ASIO driver (sound card) can be selected using I driver ASIO (scheda audio) possono essere selezionati usando under the Windows operating system. Under MacOS/Linux, no sound card selection is possible. If the selected ASIO driver is not valid an error message is shown and the previous valid driver is selected. su sistemi operativi Windows. Su MacOS/Linux, non è possibile cambiare driver audio. Se il driver ASIO selezionato non è valido un errore viene visualizzato ripristinando il driver precedentemente attivo e funzionante. If the driver is selected during an active connection, the connection is stopped, the driver is changed and the connection is started again automatically. Se il driver viene cambiato mentre si è connessi ad un server, la connessione verrà fermata, il driver sarà sostituito e successivamente la connessione verrà ripristinata automaticamente. Sound card device selector combo box Box per la selezione della scheda audio If the ASIO4ALL driver is used, please note that this driver usually introduces approx. 10-30 ms of additional audio delay. Using a sound card with a native ASIO driver is therefore recommended. Nel caso in cui vengano usati i driver ASIO4ALL bisogna sapere che questi di solito introducono 10-30 ms di ritardo aggiuntivo. Si consiglia di usare driver ASIO nativi per la scheda audio in uso. If you are using the kX ASIO driver, make sure to connect the ASIO inputs in the kX DSP settings panel. Se si usano i driver kX ASIO, accertarsi di connettere l'input ASIO nel pannello dei settaggi kX DSP. Sound Card Channel Mapping Mappa dei Canali della Scheda Audio If the selected sound card device offers more than one input or output channel, the Input Channel Mapping and Output Channel Mapping settings are visible. Se la scheda audio dispone di diversi Input o Output, verrà visualizzata la mappa dei canali di input e di output. For each Per ciascun input/output channel (Left and Right channel) a different actual sound card channel can be selected. input/output (Canale Sinistro e Destro) può essere selezionata una scheda audio diversa. Left input channel selection combo box Box per la selezione dell'Ingresso Sinistro (Left) Right input channel selection combo box Box per la selezione dell'Ingresso Destro (Right) Left output channel selection combo box Box per la selezione dell'uscita Sinistra (Left) Right output channel selection combo box Box per la selezione dell'uscita Destra (Right) Enable Small Network Buffers Abilita Riduzione Buffer di Rete If enabled, the support for very small network audio packets is activated. Very small network packets are only actually used if the sound card buffer delay is smaller than Se abilitato, viene attivata la possibilità di usare piccoli pacchetti di rete. L'uso di pacchetti di rete di dimensione ridotta è attivo se la scheda audio supporta un buffer delay inferiore a samples. The smaller the network buffers, the lower the audio latency. But at the same time the network load increases and the probability of audio dropouts also increases. samples. Più piccoli sono i pacchetti di rete minore sarà la latenza, ma allo stesso tempo aumenta il carico di rete umentando la possibilità di dropout audio. Enable small network buffers check box Check Box per abilitare la riduzione dei pacchetti di rete Sound Card Buffer Delay Buffer Delay della scheda audio The buffer delay setting is a fundamental setting of the Settare correttamente il Buffer Delay è un operazione fondamentale su software. This setting has influence on many connection properties. Questo settaggio ha influenza su molte proprietà di connessione. Three buffer sizes are supported Le dimensioni dei Buffer supportati sono 64 samples: This is the preferred setting since it provides the lowest latency but does not work with all sound cards. 64 Campioni: Per le basse latenze ma non funziona su tutte le schede audio. 128 samples: This setting should work for most available sound cards. 128 Campioni: Settaggio che trova compatibilità con la maggiorparte delle schede audio. 256 samples: This setting should only be used if only a very slow computer or a slow internet connection is available. 256 Campiono: Settaggio usato su computer connessi a reti lente o su PC obsoleti. Some sound card drivers do not allow the buffer delay to be changed from within the Molte Schede audio non permettono di modificare il buffer delay direttamente tramite l'interfaccia di software. In this case the buffer delay setting is disabled. To change the actual buffer delay, this setting has to be changed in the sound card driver. On Windows, press the ASIO Setup button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. In questo caso il Buffer Delay va settato direttamente tramite il software di gestione del driver della scheda audio. Su Windows cliccare sul bottone ASIO Setup per aprire il pannello dei driver. Su linux usare il pannello di configurazione di Jack per settare la dimensione del buffer. If no buffer size is selected and all settings are disabled, an unsupported buffer size is used by the driver. The Se non è selezionata alcuna scelta e le possibilità di scelta sono disabilitate, significa che è in uso una dimensione del buffer non supportata dal driver. Il programma software will still work with this setting but with restricted performance. funzionerà ma con performance ridotte. The actual buffer delay has influence on the connection status, the current upload rate and the overall delay. The lower the buffer size, the higher the probability of a red light in the status indicator (drop outs) and the higher the upload rate and the lower the overall delay. Il Buffer Delay influenza lo stato della connessione, la velocità di upload e l'Overall Delay. Usare una dimensione troppo bassa del buffer comporta, maggiore probabilità che l'indicatore di stato diventi rosso (drop outs) consumo di banda in upload e una diminuzione dell'Overall Delay. The buffer setting is therefore a trade-off between audio quality and overall delay. L'impostazione del buffer è quindi un compromesso tra qualità audio e ritardo generale. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within the Se le impostazioni del buffer delay sono disabilitate, il driver audio non può modificare questa impostazione tramite software. On Windows, press the ASIO Setup button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Su Windows premere il bottone ASIo setup per aprire il pannello di settaggio del driver. Su Linux usare il tool di configurazione di Jack per modificare la dimensione del buffer. 64 samples setting radio button Pulsante per abilitare 64 Campioni 128 samples setting radio button Pulsante per abilitare 128 Campioni 256 samples setting radio button Pulsante per abilitare 256 Campioni ASIO setup push button Pulsante del pannello di setup ASIO Fancy Skin Tema Fantaia If enabled, a fancy skin will be applied to the main window. Se selezionato questo tema verrà applicato alla finestra principale. Fancy skin check box Check Box Tema Fantasia Display Channel Levels Mostra livelli canali audio If enabled, each client channel will display a pre-fader level bar. Se abilitato su ogni client apparirà un metet a LED prima del Fader. Display channel levels check box Check Box per abilitare la visualizzazione dei livelli dei canali audio Audio Channels Canali Audio Select the number of audio channels to be used. There are three modes available. The mono and stereo modes use one and two audio channels respectively. In mono-in/stereo-out mode the audio signal which is sent to the server is mono but the return signal is stereo. This is useful if the sound card has the instrument on one input channel and the microphone on the other channel. In that case the two input signals can be mixed to one mono channel but the server mix can be heard in stereo. Seleziona il numero dei canali audio che saranno usati. Si possono usare tre modalità. In modalità mono e in modalità stereo vengono usati rispettivamente uno o due canali. Nella modalità mono-in/stereo-out il segnale inviato al server è mono ma il segnale di ritorno è stereo. Questà modalità è utile se si collega lo strumento su di un canale e il microfono nell'altro. In questo modo i due segnali verranno mixati su di un canale mono ma sarà possibile ascoltare il mix ricevuto dal server in stereo. Enabling the stereo streaming mode will increase the stream data rate. Make sure that the current upload rate does not exceed the available bandwidth of your internet connection. Abilitando lo streaming stereo verrà incrementato l'uso dei dati in upload. Accertarsi di avere velocità in upload sufficiente per lo stream. In stereo streaming mode, no audio channel selection for the reverberation effect will be available on the main window since the effect is applied on both channels in this case. Nel caso in cui si una lo streaming stereo, non sarà possibile selezionare su quale canale far intervenire il riverbero inquanto sarà applicato ad entrambi i canali Left e Right. Audio channels combo box Combo Box Canali Audio Audio Quality Qualità Audio Select the desired audio quality. A low, normal or high audio quality can be selected. The higher the audio quality, the higher the audio stream data rate. Make sure that the current upload rate does not exceed the available bandwidth of your internet connection. Selezionare la qualità audio desiderata. Si può scegliere tra Low (Bassa), normal (standard), high (Alta). Maggiore è la qualità settata più alto sarà il valore di streaming audio. Accertarsi di avere sufficiente banda in upload. Audio quality combo box Combo Box Qualità Audio New Client Level Livello Volume Nuovo Client The new client level setting defines the fader level of a new connected client in percent. I.e. if a new client connects to the current server, it will get the specified initial fader level if no other fader level of a previous connection of that client was already stored. Settare il livello per il nuovo client definisce il livello, in percentuale, di ingresso per un nuovo utente che si connette. Un nuovo client che si connette alla sessione assume un volume uguale a quello settato se non ci sono livelli memorizzati per questo client in precedenti connessioni con lo stesso. New client level edit box Box per modificare il livello di ingresso di un nuovo client Custom Directory Server Address Indirizzo personalizzato del Server di Directory The custom directory server address is the IP address or URL of the directory server at which the server list of the connection dialog is managed. This address is only used if the custom server list is selected in the connection dialog. L'indirizzo personalizzato del server centrale è un indirizzo IP o URL di un server centrale in cui viene gestito l'elenco dei server della finestra di dialogo della connessione. Questo indirizzo viene utilizzato solo se l'elenco dei server personalizzati è selezionato nella finestra di dialogo della connessione. Directory Server Address Indirizzo Server Centrale The directory server address is the IP address or URL of the directory server at which the server list of the connection dialog is managed. With the directory server address type either the local region can be selected of the default directory servers or a manual address can be specified. L'indirizzo del server centrale è un indirizzo IP o URL in cui viene gestito l'elenco dei server tramite la finestra di gestione delle connessioni. Selezionanto il tipo di indirizzo del server centrale è possibile selezionare la regione dei server online. E' possibile inoltre specificare un indirizzo manuale. Default directory server type combo box Box per l'indirizzo del Server Centrale Directory server address line edit Modifica indirizzo Server Centrale Current Connection Status Parameter Parametri attuali di connessione The ping time is the time required for the audio stream to travel from the client to the server and back again. This delay is introduced by the network. This delay should be as low as 20-30 ms. If this delay is higher (e.g., 50-60 ms), your distance to the server is too large or your internet connection is not sufficient. Il Ping è il tempo richiesto dallo stream audio per essere trasmesso dal client al server e tornare indietro. Questo ritardo è introdotto dalla rete. Questo ritardo dovrebbe non superare i 20-30 ms. Se tale ritardo supera i 50-60 ms significa che la distanza dal server è eccessiva oppure che la connessione non è adeguata. The overall delay is calculated from the current ping time and the delay which is introduced by the current buffer settings. L'Overall è un valore calcolato in base al ping corrente e al ritardo introdotto dai settaggi del buffer. The upstream rate depends on the current audio packet size and the audio compression setting. Make sure that the upstream rate is not higher than the available rate (check the upstream capabilities of your internet connection by, e.g., using speedtest.net). La velocità di trasferimento dati in upload dipende dalla dimensione dei pacchetti audio e dai settaggi di compressione dell'audio. Assicurarsi di non usare valori di upstream non adeguati alla propria connessione (è possibile verificare tali valori mediante un test sulla propria connessione, usando per esempio il sito speedtest.net). If this LED indicator turns red, you will not have much fun using the Se questo indicatore a LED diventa rosso non si godrà di un esperienza ottimale del programma software. . ASIO Setup ASIO Setup Mono Mono and e mode will increase your stream's data rate. Make sure your upload rate does not exceed the available upload speed of your internet connection. modalità che aumenterà la velocità dei dati del tuo stream. Assicurati che la tua velocità di upload non superi la velocità di upload disponibile per la tua connessione Internet. Mono-in/Stereo-out Mono-in/Stereo-out Stereo Stereo &Close &Chiudi Local Audio Input Fader Fader per l'input audio locale Controls the relative levels of the left and right local audio channels. For a mono signal it acts as a pan between the two channels. For example, if a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows Controlla i livelli relativi dei canali audio locali sinistro e destro. Per un segnale mono funge da pan tra i due canali. Ad esempio, se un microfono è collegato al canale di ingresso destro e uno strumento è collegato al canale di ingresso sinistro che è molto più forte del microfono, spostare il cursore audio in una direzione in cui viene mostrata l'etichetta sopra il fader L L , where , dove is the current attenuation indicator. si trova l'attuale indicatore di attenuazione. Local audio input fader (left/right) Fader di input locale (Sinistro/Destro) The jitter buffer compensates for network and sound card timing jitters. The size of the buffer therefore influences the quality of the audio stream (how many dropouts occur) and the overall delay (the longer the buffer, the higher the delay). Il Jitter Buffer compensa i ritardi della rete e della scheda audio. La dimensione del buffer influenza quindi la qualità del flusso audio (quando si verificano i dropout) e il ritardo complessivo (più è alto il buffer, maggiore è il ritardo). You can set the jitter buffer size manually for the local client and the remote server. For the local jitter buffer, dropouts in the audio stream are indicated by the light below the jitter buffer size faders. If the light turns to red, a buffer overrun/underrun has taken place and the audio stream is interrupted. È possibile impostare manualmente la dimensione delJitter Buffer per il client locale e il server remoto. Per il Jitter Buffer locale, i dropout nel flusso audio sono indicati dalla luce sotto i fader del Jitter Buffer. Se la luce diventa rossa, si è verificato un sovraccarico / underrun del buffer e il flusso audio viene interrotto. If the Auto setting is enabled, the jitter buffers of the local client and the remote server are set automatically based on measurements of the network and sound card timing jitter. If Auto is enabled, the jitter buffer size faders are disabled (they cannot be moved with the mouse). Se la modalità "Auto" è abilitata il Jitter Buffer si regolerà automaticamente sulla base di misure sulla rete e sulle latenze della scheda audio. Quando la modalità "Auto" è abilitata i fader saranno disabilitati. If the Auto setting is enabled, the network buffers of the local client and the remote server are set to a conservative value to minimize the audio dropout probability. To tweak the audio delay/latency it is recommended to disable the Auto setting and to lower the jitter buffer size manually by using the sliders until your personal acceptable amount of dropouts is reached. The LED indicator will display the audio dropouts of the local jitter buffer with a red light. Se l'impostazione Auto è abilitata, i buffer di rete del client locale e del server remoto vengono impostati su un valore conservativo per ridurre al minimo la probabilità di interruzione dell'audio. Per modificare il ritardo / latenza audio, si consiglia di disabilitare l'impostazione Auto e di ridurre manualmente la dimensione del buffer utilizzando i fader fino a raggiungere una qualità audio accettabile. L'indicatore LED mostrerà i dropout audio del Jitter Buffer locale con una luce rossa. The buffer delay setting is a fundamental setting of this software. This setting has an influence on many connection properties. Il Buffer Delay è un settaggio fondamentale per questo programma. Questo settaggio influenza molte propriètà di connessione. 64 samples: The preferred setting. Provides the lowest latency but does not work with all sound cards. 64 Campiono: Settaggio preferito. Permette di ottenere latenze bassissime ma non tutto le schede audio supportano questo valore. 128 samples: Should work for most available sound cards. La modalità "128 Samples" è compatibile con la maggior parte delle schede audio. 256 samples: Should only be used on very slow computers or with a slow internet connection. 256 Campioni: Usato su computer vecchi o su connessioni lente. Some sound card drivers do not allow the buffer delay to be changed from within the application. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. On Windows, press the ASIO Setup button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Alcune driver non permettono il settaggio del buffer delay quando il programma è avviato. In questo caso la scelta del buffer delay è disabilitata è puo essere modificata avviando il software del driver della scheda audio. Su windows cliccare su "ASIO Setup" per aprire i settings del driver ASIO. Su Linux usare la configurazione di Jack per modificare la dimensione del Buffer. If no buffer size is selected and all settings are disabled, an unsupported buffer size is used by the driver. The application will still work with this setting but with restricted performance. Si nessuna delle opzioni di Buffer è selezionata vuol dire che una dimensione non supportata è in uso da parte del driver. Il programma continuerà a funzionare con performance limitate. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within the software. On Windows, press the ASIO Setup button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Se le impostazioni di ritardo del buffer sono disabilitate, il driver audio non può modificare questa impostazione dal programma. Su Windows, premi il pulsante ASIO Setup per aprire il pannello delle impostazioni del driver. Su Linux, utilizzare lo strumento di configurazione Jack per modificare la dimensione del buffer. Some sound card drivers do not allow the buffer delay to be changed from within the application. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. On Windows, press the ASIO Device Settings button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Molte schede audio non consentono la modifica del buffer dall'applicazione.In questo caso la possibilità di cambiare il buffer delay è disabilitato di default e questo parametro va variato mediante il software del driver della scheda audio. Su windows basta preme il pulsante ASIO per aprire il pannello di controllo dei driver. Su linux usare il software di configurazione di Jack. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within the software. On Windows, press the ASIO Device Settings button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Se non è possibile variare il buffer delay, vuol dire che non è possibile farlo tramite il software ma tramite il driver. Su windows basta preme il pulsante ASIO per aprire il pannello di controllo dei driver. Su linux usare il software di configurazione di Jack. Sound card driver settings Settaggi scheda audio This opens the driver settings of your sound card. Some drivers allow you to change buffer settings, others like ASIO4ALL let you choose input or outputs of your device(s). More information can be found on jamulus.io. Aprirà il software di gestione della scheda audio. I driver danno la possibilità di modificare i valori del buffer delay e in alcuni casi, come con gli ASIO4ALL di scegliere gli input e gli output da usare. Altre informazioni sono disponibili sul sito jamulus.io. Opens the driver settings. Note: Apri il software di configurazione. Note: currently only supports devices supporting a sample rate of attualmente supporta solo dispositivi che supportano una frequenza di campionamento di Hz. You will not be able to select a driver/device which doesn't. For more help see jamulus.io. Hz. Non sarai in grado di selezionare un driver / dispositivo che non supporta tale impostazione. Per ulteriori informazioni, vedere jamulus.io. ASIO Device Settings push button Pulsante per i settaggi del driver ASIO Skin Vista Select the skin to be used for the main window. Selezione la vista da applicare alla finestra principale. Skin combo box Box di selezione Vista Select the meter style to be used for the level meters. The Bar (narrow) and LEDs (round, small) options only apply to the mixerboard. When Bar (narrow) is selected, the input meters are set to Bar (wide). When LEDs (round, small) is selected, the input meters are set to LEDs (round, big). The remaining options apply to the mixerboard and input meters. Selezionare lo stile del Meter da utilizzare per i livelli audio. L'opzione "Barra LED stretta e LED piccoli si applicano solo al mixer. Quando si seleziona "Barre Strette", gli indicatori di input sono impostati su Barre. Quando si seleziona LED Piccoli, gli indicatori di ingresso sono impostati su LED rotondi. Le restanti opzioni si applicano all mixer ed ai Meter delgli input. Language Lingua Select the language to be used for the user interface. Seleziona la lingua da usare per l'interfaccia utente. Language combo box Box di selezione lingua Selects the number of audio channels to be used for communication between client and server. There are three modes available: Seleziona il numero di canali audio da utilizzare per la comunicazione tra client e server. Sono disponibili tre modalità: and e These modes use one and two audio channels respectively. Questa modalità usa rispettivamente uno o due canali audio. Mono in/Stereo-out Mono in/Stereo-out The audio signal sent to the server is mono but the return signal is stereo. This is useful if the sound card has the instrument on one input channel and the microphone on the other. In that case the two input signals can be mixed to one mono channel but the server mix is heard in stereo. Il segnale audio inviato al server è mono ma il segnale di ritorno è stereo. Ciò è utile se la scheda audio ha lo strumento su un canale di ingresso e il microfono sull'altro. In tal caso, i due segnali di ingresso possono essere miscelati su un canale mono ma il mix del server viene ascoltato in stereo. Enabling Abilitando In stereo streaming mode, no audio channel selection for the reverb effect will be available on the main window since the effect is applied to both channels in this case. Nella modalità stereo, nessuna selezione di canali audio per l'effetto riverbero sarà disponibile nella finestra principale poiché in questo caso l'effetto viene applicato ad entrambi i canali. The higher the audio quality, the higher your audio stream's data rate. Make sure your upload rate does not exceed the available bandwidth of your internet connection. Maggiore è la qualità audio, maggiore è la quantità dei dati del flusso audio. Assicurati che la tua velocità di upload non superi la larghezza di banda disponibile della tua connessione Internet. This setting defines the fader level of a newly connected client in percent. If a new client connects to the current server, they will get the specified initial fader level if no other fader level from a previous connection of that client was already stored. Questa impostazione definisce il livello di dissolvenza di un client appena connesso in percentuale. Se un nuovo client si connette al server corrente, otterrà il livello di fader iniziale specificato se nessun altro livello di fader da una precedente connessione di quel client era già memorizzato. Input Boost Gain Ingresso This setting allows you to increase your input signal level by factors up to 10 (+20dB). If your sound is too quiet, first try to increase the level by getting closer to the microphone, adjusting your sound equipment or increasing levels in your operating system's input settings. Only if this fails, set a factor here. If your sound is too loud, sounds distorted and is clipping, this option will not help. Do not use it. The distortion will still be there. Instead, decrease your input level by getting farther away from your microphone, adjusting your sound equipment or by decreasing your operating system's input settings. Questa impostazione consente di aumentare il livello del segnale in ingresso tramite fattori di moltiplicazione di guadagno fino a 10 (ovvero + 20dB). Se il suono è troppo basso provare, prima ad aumentare il guadagno, di avvicinarsi al microfono, regolare i livelli della scheda audio o regolare i livelli nelle impostazioni di input del sistema. Se non si riesce ad ottenere un livello di ingresso soddisfacente, impostare un fattore di guadagno adeguato. Se il suono è gia troppo forte risulterà distorto ed in clipping, questa opzione in questo caso non ti sarà utile. In questi casi dovrai diminuire il livello di ingresso: allontanati dal microfono, regola la scheda audio o regola i livelli delle impostazioni di ingresso del sistema operativo. Input Boost combo box Casella del Gain d'Ingresso Leave this blank unless you need to enter the address of a directory server other than the default. Lasciare vuoto questo campo a meno che non sia necessario immettere l'indirizzo di un server di directory diverso da quello predefinito. Directory server address combo box Casella dell'indirizzo del server di directory The Ping Time is the time required for the audio stream to travel from the client to the server and back again. This delay is introduced by the network and should be about 20-30 ms. If this delay is higher than about 50 ms, your distance to the server is too large or your internet connection is not sufficient. Il ping è il tempo necessario affinché il flusso audio passi dal client al server e viceversa. Questo ritardo è introdotto dalla rete e dovrebbe essere di circa 20-30 ms. Se questo ritardo è superiore a circa 50 ms, la distanza dal server è eccessiva o la connessione a Internet non è sufficiente. Overall Delay is calculated from the current Ping Time and the delay introduced by the current buffer settings. Il ritardo complessivo viene calcolato dal tempo di ping corrente e dal ritardo introdotto dalle impostazioni del buffer correnti. Audio Upstream Rate depends on the current audio packet size and compression setting. Make sure that the upstream rate is not higher than your available internet upload speed (check this with a service such as speedtest.net). L'Upstream audio dipende dalle dimensioni del pacchetto audio e dalle impostazioni di compressione correnti. Assicurati che la velocità di upstream non sia superiore alla velocità della tua connessione (controlla questo con un servizio come speedtest.net). The ASIO driver (sound card) can be selected using %1 under the Windows operating system. Under macOS/Linux, no sound card selection is possible. If the selected ASIO driver is not valid an error message is shown and the previous valid driver is selected. I driver ASIO possono essere selezionati usando %1 su Windows. Su macOS/Linux, non è possibile effettuare la selezione della scheda audio. Se il driver selezionato non è valido un messaggio di errore informa che verrà ripristinato il driver precedente. For each %1 input/output channel (left and right channel) a different actual sound card channel can be selected. Per ciascun %1 input/output (canali sinistro e destro) può essere selezionata una scheda audio diversa. Enables support for very small network audio packets. These network packets are only actually used if the sound card buffer delay is smaller than %1 samples. The smaller the network buffers, the lower the audio latency. But at the same time the network load and the probability of audio dropouts or sound artifacts increases. Abilita il supporto per pacchetti audio di rete molto piccoli. Questi pacchetti di rete vengono effettivamente utilizzati solo se il ritardo del buffer della scheda audio è inferiore a %1 campioni. Più piccoli sono i pacchetti di rete, minore sarà la latenza audio. Ma allo stesso tempo aumenta il carico di rete e la probabilità di avere problemi durante l'ascolto. Some sound card drivers do not allow the buffer delay to be changed from within %1. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. On Windows, use the ASIO Device Settings button to open the driver settings panel. On Linux, use the JACK configuration tool to change the buffer size. Alcuni driver di schede audio non consentono di modificare il ritardo del buffer da %1. In questo caso l'impostazione del ritardo del buffer è disabilitata e deve essere modificata utilizzando il driver della scheda audio. Su Windows, usa il pulsante Impostazioni dispositivo ASIO per aprire il pannello delle impostazioni del driver. Su Linux, usa lo strumento di configurazione JACK per modificare la dimensione del buffer. If no buffer size is selected and all settings are disabled, this means an unsupported buffer size is in use by the driver. %1 will still work with this setting but may have restricted performance. Se non è stato selezionato un valore di dimensione del buffer e tutte le impostazioni sono disabilitate, significa che una dimensione del buffer non supportata è in uso dal driver. %1 continuerà a funzionare con questa impostazione ma potrebbe avere prestazioni limitate. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within %1. On Windows, press the ASIO Device Settings button to open the driver settings panel. On Linux, use the JACK configuration tool to change the buffer size. Se le impostazioni del ritardo del buffer sono disabilitate, il driver audio proibisce di modificare questa impostazione dall'interno di %1. Su Windows, premere il pulsante Impostazioni dispositivo ASIO per aprire il pannello delle impostazioni del driver. Su Linux, usa lo strumento di configurazione JACK per modificare la dimensione del buffer. This opens the driver settings of your sound card. Some drivers allow you to change buffer settings, others like ASIO4ALL lets you choose input or outputs of your device(s). More information can be found on jamulus.io. Apre le impostazioni del driver della tua scheda audio. Alcuni driver ti consentono di modificare le impostazioni del buffer, altri come ASIO4ALL ti consentono di scegliere input o output dei tuoi dispositivi. Maggiori informazioni possono essere trovate su jamulus.io. Opens the driver settings. Note: %1 currently only supports devices with a sample rate of %2 Hz. You will not be able to select a driver/device which doesn't. For more help see jamulus.io. Apre le impostazioni del driver. Nota: %1 attualmente supporta solo dispositivi con una frequenza di campionamento di %2 Hz. Non sarai in grado di selezionare un driver/dispositivo che non lo supporta. Per ulteriore assistenza, vedere jamulus.io. The buffer delay setting is a fundamental setting of %1. This setting has an influence on many connection properties. L'impostazione del ritardo del buffer è un'impostazione fondamentale di %1. Questa impostazione ha un'influenza su molte proprietà di connessione. Controls the relative levels of the left and right local audio channels. For a mono signal it acts as a pan between the two channels. For example, if a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows %1, where %2 is the current attenuation indicator. Controlla i livelli dei canali audio della scheda sinistro e destro. Per un segnale mono funge da mixer tra i due canali. Ad esempio, se un microfono è collegato al canale di ingresso destro e uno strumento è collegato al canale di ingresso sinistro che è molto più forte del microfono, spostare il fader audio per bilanciare gli ingressi, l'etichetta sopra il fader mostra %1, dove %2 è l'indicatore di attenuazione. Audio Device Dispositivo Audio Under the Windows operating system the ASIO driver (sound card) can be selected using %1. If the selected ASIO driver is not valid an error message is shown and the previous valid driver is selected. Under macOS the input and output hardware can be selected. Su Windows è possibile selezionare il driver ASIO (scheda audio) utilizzando %1. Se il driver ASIO selezionato non è valido, viene visualizzato un messaggio di errore e viene selezionato un driver valido. In macOS è possibile selezionare l'hardware di input e output. Three buffer sizes can be selected È possibile sceliere tra tre possibilità di dimensioni del buffer 64 samples: Provides the lowest latency but does not work with all sound cards. La modalità "64 Samples" garantisce una minore latenza ma non è applicabile a tutte le schede audio. 256 samples: Should only be used when 64 or 128 samples is causing issues. La modalità "256 Samples" si usa quando non si possono usare le impostazioni a 64 o 128 Samples, per non avere problemi. Some sound card drivers do not allow the buffer delay to be changed from within %1. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. Use the appropriate tool for the interface in use to adjust this buffer size. For example, if using ASIO, use the "ASIO Device Settings" button to open the driver settings panel or if using JACK, use a tool such as QjackCtl to adjust the buffer size. Other interfaces, such as Pipewire, would require their appropriate tool being used. Please refer to the interface manual. Alcuni driver di alcune schede audio non permettono la modifica del buffer da %1. In questo caso la funzione di modifica del buffer risulta disabilitata e andrà modificata direttamente dal driver della scheda audio. Usare il programma fornito dal produttore per modificare i parametri del buffer. Per esempio se usi i driver ASIO, puoi usare il bottone "ASIO Device Settings" per aprire il pannello di controllo oppure se si usa JACK si dovrà usare il tool QJackCtl per accedere ai parametri della scheda. Altre interfacce, come Pipewire, potrebbero richiedere un tool proprietario. In questo caso fare riferimento al manuale utente. If no buffer size is selected and all settings are disabled, this means a buffer size in use by the driver which does not match the values. %1 will still work with this setting but may have restricted performance. Se non è possibile selezionare le impostazioni sulla dimensione del buffer significa che i settaggi non sono compatibili con il driver o che non corrisponde ai valori. %1, continuerà a funzionare, ma con prestazioni limitate. The actual buffer delay has influence on the connection, the current upload rate and the overall delay. The lower the buffer size, the higher the probability of a red light in the status indicator (drop outs) and the higher the upload rate and the lower the overall delay. L'effettivo ritardo del buffer ha influenza sulla connessione, sulla velocità di upload e sul ritardo complessivo. Minore è la dimensione del buffer, maggiore è la probabilità di avere il LED rosso nell'indicatore di stato (drop out), maggiore è la velocità di upload, minore è il ritardo complessivo. Meter Style Stile dei Vu-Meter Select the meter style to be used for the level meters. The Narrow Bar and Small LEDs options only apply to the mixerboard. When Narrow Bar is selected, the input meters are set to Bar. When Small LEDs is selected, the input meters are set to Round LEDs. The remaining options apply to the mixerboard and input meters. Selezionare lo stile del VU-Meter da utilizzare per i livelli audio. L'opzione "Barra LED stretta e LED piccoli si applicano solo al mixer. Quando si seleziona "Barre Strette", gli indicatori di input sono impostati su Barre. Quando si seleziona LED Piccoli, gli indicatori di ingresso sono impostati su LED rotondi. Le restanti opzioni si applicano all mixer ed ai VU-Meter delgli input. Meter Style combo box Box selezione stile VU-Meter Custom Directories Cartella predefinita If you need to add additional directories to the Connect dialog Directory drop down, you can enter the addresses here.<br>To remove a value, select it, delete the text in the input box, then move focus out of the control. Se devi aggiungere altri indirizzi al menu a discesa della finestra di dialogo Connetti, puoi inserire gli indirizzi qui.<br>Per rimuovere un valore, selezionalo, elimina il testo nella casella di input, quindi clicca su qualsiasi area della finesta. Custom Directories combo box Combo box della Cartella Predefinita Audio Upstream Rate Audio Upstream Rate Depends on the current audio packet size and compression setting. Make sure that the upstream rate is not higher than your available internet upload speed (check this with a service such as speedtest.net). Dipende dalla dimensione del pacchetto audio e dall'impostazione di compressione. Assicurati che la velocità di upstream non sia superiore alla velocità di upload disponibile dal tuo provider (verificalo con un servizio come speedtest.net). Number of Mixer Panel Rows Numero di Righe su cui disporre il Mixer Adjust the number of rows used to arrange the mixer panel. Regola il numero di righe su cui saranno disposti i controlli del mixer. Number of Mixer Panel Rows spin box Numero di Righe su cui disporre il Mixer Feedback Protection Protezione dai Larser Enable feedback protection to detect acoustic feedback between microphone and speakers. Abilita la protezione dai larsen per rilevare il feedback acustico tra il microfono e gli altoparlanti. Feedback Protection check box Casella Protezione dai Larser Audio Alerts Avvisi Audio Enable audio alert when receiving a chat message and when a new client joins the session. A second sound device may be required to hear the alerts. Abilita gli avvisi audio quando ricevi un messaggio in chat e quando un nuovo utente entra nella sessione. Sarà necessario un secondo device audio per ascoltare questi avvisi. Audio Alerts check box CheckBox Avvisi Audio ASIO Device Settings Configurasione driver ASIO Low Low Normal Normal High High Fancy Fantasia Compact Compatto Bar (narrow) Barre (Sottili) Bar (wide) Barre (larghe) LEDs (stripe) LED (strip) LEDs (round, small) LED (Piccoli, rotondi) LEDs (round, big) LED (Rotondi, grandi) LEDs LED Bar Barre Narrow Bar Barre Sottili Round LEDs LED Rotondi Small LEDs LED Piccoli None Nullo Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country or region you are located in. Your city and skill level playing your instrument may also be added. Scrivi qui il tuo nome o uno pseudonimo in modo che gli altri musicisti con cui vuoi suonare sappiano chi sei. Puoi anche aggiungere un'immagine dello strumento che suoni e una bandiera del paese o della regione in cui ti trovi. Potrebbero anche essere aggiunti la tua città e il livello di abilità nel suonare il tuo strumento. Country/region flag button Bandiera del paese o della regione preferred consigliato Musician Profile Profilo del Musicista Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country you are located in. Your city and skill level playing your instrument may also be added. Scrivi qui il tuo nome o un alias in modo che gli altri musicisti con cui vuoi suonare sappiano chi sei. Puoi anche aggiungere una foto dello strumento che suoni e una bandiera del paese in cui ti trovi. Puoi anche aggiungere la tua città e il tuo livello di abilità nel suonare il tuo strumento. What you set here will appear at your fader on the mixer board when you are connected to a %1 server. This tag will also be shown at each client which is connected to the same server as you. Quello che imposti qui apparirà sul tuo fader sulla scheda del mixer quando sei connesso a un server %1. Questo tag verrà mostrato anche su ogni client connesso al tuo stesso server. What you set here will appear at your fader on the mixer board when you are connected to a Jamulus server. This tag will also be shown at each client which is connected to the same server as you. Ciò che hai impostato apparirà sul tuo fader sulla scheda del mixer quando sei collegato a un server Jamulus. Questo tag verrà mostrato anche su ogni client collegato allo stesso server. Alias or name edit box Box di modifica Nome o Alias Instrument picture button Immagine dello strumento Country flag button Pulsante bandiera del paese City edit box Box di modifica Città Skill level combo box Livello di Abilità Beginner Principiante Intermediate Intermedio Expert Esperto Size: Livello: Buffer Delay Buffer Delay Buffer Delay: Buffer Delay: Center Centro R R Predefined Address Indirizzo Preferito The selected audio device could not be used because of the following error: La scheda audio selezionata non può essere usata per i seguenti motivi: The previous driver will be selected. Sarà ripristinato il driver precedentemente usato. Ok Ok Custom Personalizzato All Genres Tutti i Generi Any Genre 2 Tutti i Generi 2 Any Genre 3 Tutti i Generi 3 Genre Rock Genere Rock Genre Jazz Genere Jazz Genre Classical/Folk Genere Classica / Folk Genre Choral/Barbershop Genere Corale / Barbershop Any Genre 1 Tutti i Generi 1 Genre Classical/Folk/Choral Genere Classica/Folk/Corale Default Default Drum Set Batteria Djembe Djembe Electric Guitar Chitarra elettrica Acoustic Guitar Chitarra Acustica Bass Guitar Basso Elettrico Keyboard Tastiera Synthesizer Sintetizzatore Grand Piano Grand Piano Accordion Fisarmonica Vocal Voce Microphone Microfono Harmonica Armonica Trumpet Tromba Trombone Trombone French Horn Corno Francese Tuba Tuba Saxophone Sassofono Clarinet Clarinet Flute Flauto Violin Violino Cello Cello Double Bass Contrabbasso Recorder Recorder Streamer Streamer Listener Ascoltatore Guitar+Vocal Chitarra+Voce Keyboard+Vocal Tastiera+Voce Bodhran Bodhran Bassoon Fagotto Oboe Oboe Harp Arpa Viola Viola Congas Congas Bongo Bongo Vocal Bass Voce Basso Vocal Tenor Voce Tenore Vocal Alto Voce Alto Vocal Soprano Voce Soprano Banjo Banjo Mandolin Mandolino Ukulele Uculele Bass Ukulele Uculele Basso Vocal Baritone Voce Baritono Vocal Lead Vocal Lead Mountain Dulcimer Dulcimer Scratching Scratching Rapping Rapping Vibraphone Vibrafono Conductor Conduttore CClientSettingsDlgBase Settings Settaggi Soundcard Scheda Audio Device Dispositivo Input Channel Mapping Mappa Canali di Input L L R R Output Channel Mapping Mappa Canali di Output Enable Small Network Buffers Abilita riduzione dimensione Buffer Buffer Delay Buffer Delay Country/Region Paese/Regione (preferred) (Consigliato) (default) (default) (safe) (sicuro) Driver Setup Setup Driver My Profile Il Mio profilo Musician's Profile Profilo del Musicista Alias/Name Alias/Nome Instrument Strumento Country Paese City Città Skill Livello User Interface Interfaccia Meter Style Stile del VU-Meter Mixer Rows Righe Mixer Audio Alerts Avvisi Audio Audio/Network Setup Impostazioni Audio/Rete Audio Device Dispositivo Audio Jitter Buffer Jitter Buffer Auto Auto Local Locale Server Server Size Livello kbps kbps Custom Directories: Directory personalizzata: Input Boost Gain Ingresso Feedback Protection Protezione dai Larsen Enable Abilita Input Balance Bilanciamento Ingresso Pan Bilanciamento Center Centro Misc Altri Parametri Audio Channels Canali Audio Audio Quality Qualità Audio Measurements Misure Advanced Setup Impostazioni Avanzate Custom Central Server Address: Indirizzo server centrale personalizzato: New Client Level Livello Nuovo Client Skin Vista Language Lingua % % Local Jitter Buffer Jitter Locale Fancy Skin Tema Fantasia Display Channel Levels Visualizza Livelli Canali Custom Directory Server Address: Indirizzo Server di Directory alternativo: Directory Server Address: Indirizzo Server Centrale: Audio Stream Rate Velocità dello Streaming val val Ping Time Ping Overall Delay Overall Delay CConnectDlg Server List Lista dei Server The server list shows a list of available servers which are registered at the directory server. Select a server from the list and press the connect button to connect to this server. Alternatively, double click a server from the list to connect to it. If a server is occupied, a list of the connected musicians is available by expanding the list item. Permanent servers are shown in bold font. La lista dei server mostra i server disponibili che si sono registrati sul server centrale. Selezionare un server dalla lista e preme connetti per entrane nella sessione. Altrimenti eseguire un doppio click sul nome del server in lista per connettersi. Se ad un server sono già connessi altri client sarà possibili vedere una lista di musicisti connessi a tale server. I server che sono registrati come permanenti sono visualizzati in grassetto. Note that it may take some time to retrieve the server list from the directory server. If no valid directory server address is specified in the settings, no server list will be available. Si noti che potrebbe essere necessario del tempo per recuperare l'elenco dei server dal server centrale. Se nelle impostazioni non è specificato alcun indirizzo di server centrale valido, non sarà disponibile alcun elenco di server. Directory Cartella Shows the servers listed by the selected directory. You can add custom directories in Advanced Settings. Mostra i server elencati dalla cartella selezionata. Puoi aggiungere cartelle personalizzate in Impostazioni avanzate. Directory combo box Box della Cartella Filters the server list by the given text. Note that the filter is case insensitive. A single # character will filter for those servers with at least one person connected. Filtra l'elenco dei server in base al testo specificato. Si noti che il filtro non fa distinzione tra maiuscole e minuscole. Un singolo carattere # filtrerà per quei server con almeno una persona connessa. Uncheck to collapse the server list to show just the server details. Check to show everyone on the servers. Deseleziona per comprimere l'elenco dei server. Seleziona per mostrare tutti sui server. The Connection Setup window lists the available servers registered with the selected directory. Use the Directory dropdown to change the directory, find the server you want to join in the server list, click on it, and then click the Connect button to connect. Alternatively, double click on the server name to connect. La finestra Configurazione connessione elenca i server disponibili registrati con la cartella selezionata. Utilizzare il menu a discesa "Directory" per modificare la cartella, trovare il server a cui connettersi nell'elenco dei server, fare clic su di esso, quindi fare clic sul pulsante Connetti. In alternativa, fare doppio clic sul nome del server per connettersi. Permanent servers (those that have been listed for longer than 48 hours) are shown in bold. I server permanenti (quelli che sono stati elencati per più di 48 ore) sono mostrati in grassetto. You can add custom directories in Advanced Settings. Puoi aggiungere cartelle personalizzate in Impostazioni avanzate. Server list view Lista dei Server Server Address Indirizzo del Server If you know the server address, you can connect to it using the Server name/Address field. An optional port number can be added after the server address using a colon as a separator, e.g. %1. The field will also show a list of the most recently used server addresses. Se conosci l'indirizzo del server, puoi connetterti utilizzando il campo Nome/Indirizzo del server. È possibile aggiungere un numero di porta (opzionale) dopo l'indirizzo del server utilizzando i due punti come separatore, ad es. %1. Il campo mostrerà anche un elenco degli indirizzi utilizzati più di recente. Holds the current server address. It also stores old addresses in the combo box list. Contiene l'indirizzo del server a cui connettersi. Memorizza anche i vecchi indirizzi, che compariranno nel menù a tendina. The IP address or URL of the server running the L'indirizzo IP o l'URL del server in cui è attivo server software must be set here. An optional port number can be added after the IP address or URL using a colon as a separator, e.g. example.org: come server deve essere settato qui. Una porta di connessione opzionale può essere specificata aggiungendo i due punti ed il numero della porta dopo l'indirizzo. Es. example.org: . A list of the most recent used server IP addresses or URLs is available for selection. .Una lista di server recentementi usati è disponibile mediante il menù a tendina. The Connection Setup window shows a list of available servers. Server operators can optionally list their servers by music genre. Use the List dropdown to select a genre, click on the server you want to join and press the Connect button to connect to it. Alternatively, double click on on the server name. Permanent servers (those that have been listed for longer than 48 hours) are shown in bold. La finestra "Connessioni" mostra un elenco di server disponibili. Gli operatori di server possono facoltativamente elencare i loro server per genere musicale. Utilizzare l'elenco a discesa per selezionare un genere, fare clic sul server a cui si desidera accedere e premere il pulsante Connetti per connettersi ad esso. In alternativa, fai doppio clic sul nome del server. I server permanenti (quelli che sono stati elencati per più di 48 ore) sono mostrati in grassetto. If you know the IP address or URL of a server, you can connect to it using the Server name/Address field. An optional port number can be added after the IP address or URL using a colon as a separator, e.g. example.org: Se si conosce l'indirizzo IP o l'URL di un server, è possibile connettersi ad esso utilizzando il campo Nome / indirizzo server. Un numero di porta opzionale può essere aggiunto dopo l'indirizzo IP o l'URL usando i due punti come separatore, ad esempio: esempio.org: . The field will also show a list of the most recently used server addresses. . Il campo mostrerà anche un elenco degli indirizzi server utilizzati più di recente. Server address edit box Box di editing dell'indirizzo del server Holds the current server IP address or URL. It also stores old URLs in the combo box list. Contiene l'indirizzo IP o l'URL del server corrente. Memorizza anche i vecchi URL visibili aprendo il menù a tendina. Server List Selection Lista dei Server selezionabili Selects the server list to be shown. Seleziona la lista dei server da visualizzare. Server list selection combo box Box di selezione Lista Server Filter Filtro The server list is filtered by the given text. Note that the filter is case insensitive. L'elenco dei server è filtrato secondo il testo inserito. Si noti che il filtro non fa distinzione tra maiuscole e minuscole. Filter edit box Box di modifica del Filtro Show All Musicians Visualizza tutti i Musicisti If you check this check box, the musicians of all servers are shown. If you uncheck the check box, all list view items are collapsed. Se questa casella è selezionata, saranno visualizzati tutti i musicisti connessi nei vari server. Se non selezionata la lista sarà compattata. Show all musicians check box Box di Visualizzazione dei Musicisti If you know the IP address or URL of a server, you can connect to it using the Server name/Address field. An optional port number can be added after the IP address or URL using a colon as a separator, e.g. %1. The field will also show a list of the most recently used server addresses. Se si conosce l'indirizzo IP o l'URL di un server, è possibile connettersi ad esso utilizzando il campo Nome/Indirizzo server. È possibile aggiungere un numero di porta facoltativo dopo l'indirizzo IP o l'URL utilizzando i due punti come separatore, ad esempio %1. Il campo mostrerà anche un elenco degli indirizzi del server utilizzati di recente. Filter text, or # for occupied servers Filtro con testo, oppure # per visualizzare solo i server con utenti attivi Type # for occupied servers Inserisci # per i server con persone CConnectDlgBase Connection Setup Setup Connessioni List Lista Directory Directory Filter Filtro Show All Musicians Visualizza Musicisti Server Name Nome Server Ping Time Ping Time Musicians Musicisti Location Località Server Address Indirizzo del Server Server Name/Address Nome server/Indirizzo C&ancel C&ancella &Connect &Connetti CHelpMenu &Help &Aiuto Getting &Started... &Introduzione... Software &Manual... &Manuale Software... What's &This &Cos'è Questo &About Jamulus... I&nformazioni su Jamulus... About &Qt... Informazioni su &Qt... &About... I&nformazioni su... About Qt Informazioni su Qt CLanguageComboBox Restart Required Riavvio Richiesto Please restart the application for the language change to take effect. Perfavore Riavvia il programma oer rendere effettive le modifiche. CLicenceDlg I &agree to the above licence terms &Accetto i termini di licenza This server requires you accept conditions before you can join. Please read these in the chat window. Il server richiede che tu accetti le condizioni prima di accedere. Leggi il regolamento nella finestra di chat. I have read the conditions and &agree. Ho letto ed &accetto. Accept Accetto Decline Declino By connecting to this server and agreeing to this notice, you agree to the following: Collegandosi a questo server e accettando questo avviso, si accetta quanto segue: You agree that all data, sounds, or other works transmitted to this server are owned and created by you or your licensors, and that you are making these data, sounds or other works available via the following Creative Commons License (for more information on this license, see Dichiari che tutti i dati, audio o altre opere trasmessi a questo server sono di tua proprietà e creati da te o dai tuoi licenziatari e che rendi questi dati, audio o altre opere disponibili a terzi mediante la seguente Licenza Creative Commons (per ulteriori informazioni su questa licenza, vedere You are free to: Sei libero di: Share Condividere copy and redistribute the material in any medium or format copiare e ridistribuire il materiale in qualsiasi supporto o formato Adapt Adattare remix, transform, and build upon the material remixare, trasformare e modificare il materiale The licensor cannot revoke these freedoms as long as you follow the license terms. Il licenziante non può revocare queste libertà fintanto che segui i termini della licenza. Under the following terms: Sotto i seguenti requisiti: Attribution Attribuzione You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. È necessario accreditare in modo appropriato, fornire un collegamento alla licenza e indicare se sono state apportate modifiche. Puoi farlo in modo ragionevole, ma non in modo tale da suggerire a te o al tuo utilizzo il supporto del licenziante. NonCommercial Non Commerciale You may not use the material for commercial purposes. Non è possibile utilizzare il materiale a fini commerciali. ShareAlike Condividere allo stesso modo If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original. Se remixate, trasformate o sviluppate il materiale, dovete distribuire i vostri contributi con la stessa licenza dell'originale. No additional restrictions Nessuna restrizione aggiuntiva You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. Non è possibile applicare termini legali o misure tecnologiche che impediscono legalmente ad altre persone di fare qualsiasi cosa consentita dalla licenza. CMultiColorLED Red Rosso Yellow Giallo Green Verde CMusProfDlg Musician Profile Profilo del Musicista Alias/Name Nome/Alias Instrument Strumento Country Paese City Città Skill Livello &Close &Chiudi None None Beginner Principiante Intermediate Intermedio Expert Esperto Set your name or an alias here so that the other musicians you want to play with know who you are. Additionally you may set an instrument picture of the instrument you play and a flag of the country you are living in. The city you live in and the skill level playing your instrument may also be added. Scrivi qui il tuo nome o alias in modo che gli altri musicisti con cui vuoi suonare ti riconoscano. Puoi anche aggiungere un'immagine dello strumento che suoni e la bandiera del paese in cui vivi. È inoltre possibile aggiungere la città in cui vivi e il tuo livello di abilità con lo strumento. What you set here will appear at your fader on the mixer board when you are connected to a Quello che inserisci qui apparirà nel tuo fader del mixer quando ti connetti a un server server. This tag will also show up at each client which is connected to the same server as you. If the name is left empty, the IP address is shown instead. questo tag verrà mostrato anche a ciascun client connesso allo stesso server. Se viene lasciato vuoto, verrà visualizzato l'indirizzo IP. Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country you are located in. Your city and skill level playing your instrument may also be added. Scrivi qui il tuo nome o un alias in modo che gli altri musicisti con cui vuoi suonare sappiano chi sei. Puoi anche aggiungere una foto dello strumento che suoni e una bandiera del paese in cui ti trovi. Puoi anche aggiungere la tua città e il tuo livello di abilità nel suonare il tuo strumento. What you set here will appear at your fader on the mixer board when you are connected to a Jamulus server. This tag will also be shown at each client which is connected to the same server as you. Ciò che hai impostato apparirà sul tuo fader sulla scheda del mixer quando sei collegato a un server Jamulus. Questo tag verrà mostrato anche su ogni client collegato allo stesso server. Alias or name edit box Box di modifica Nome o Alias Instrument picture button Immagine dello strumento Country flag button Pulsante bandiera del paese City edit box Box di modifica Città Skill level combo box Livello di Abilità Drum Set Batteria Djembe Djembe Electric Guitar Chitarra elettrica Acoustic Guitar Chitarra Acustica Bass Guitar Basso Elettrico Keyboard Tastiera Synthesizer Sintetizzatore Grand Piano Grand Piano Accordion Fisarmonica Vocal Voce Microphone Microfono Harmonica Armonica Trumpet Tromba Trombone Trombone French Horn Corno Francese Tuba Tuba Saxophone Sassofono Clarinet Clarinet Flute Flauto Violin Violino Cello Cello Double Bass Contrabbasso Recorder Recorder Streamer Streamer Listener Ascoltatore Guitar+Vocal Chitarra+Voce Keyboard+Vocal Tastiera+Voce Bodhran Bodhran Bassoon Fagotto Oboe Oboe Harp Arpa Viola Viola Congas Congas Bongo Bongo Vocal Bass Voce Basso Vocal Tenor Voce Tenore Vocal Alto Voce Alto Vocal Soprano Voce Soprano Banjo Banjo Mandolin Mandolino Ukulele Uculele Bass Ukulele Uculele Basso Vocal Baritone Voce Baritono Vocal Lead Vocal Lead Mountain Dulcimer Dulcimer Scratching Scratching Rapping Rapping No Name Senza Nome CServerDlg Client List Lista dei Client The client list shows all clients which are currently connected to this server. Some information about the clients like the IP address and name are given for each connected client. L'elenco dei client mostra tutti i client attualmente connessi a questo server. Alcune informazioni sui client come l'indirizzo IP e il nome vengono visualizzate per ciascun client collegato. Connected clients list view Lista dei Client Connessi Directory Type combo box ComboBox della categoria della Rubrica Directory Rubrica Select '%1' not to register your server with a directory. Selezionare '%1' per non registrare il tuo server in una rubrica. Select one of the genres to register with that directory. Selezionare un genere per registrare il tuo server in quella rubrica. Or select '%1' and specify a Custom Directory address on the Options tab to register with a custom directory. Oppure seleziona '%1' e specifica un indirizzo personalizzato per una Rubrica nel tab Opzioni per registrare il server in una rubrica personalizzata. For any value except '%1', this server registers with a directory so that a %2 user can select this server in the client connect dialog server list when they choose that directory. Per qualsiasi valore eccetto '%1', questo server si registra su una rubrica in modo che un utente %2 possa trovare questo server nell'elenco dei server nella finestra di dialogo di connessione dei client della rubrica selezionata. The registration of the server is renewed periodically to make sure that all servers in the connect dialog server list are actually available. La registrazione del server viene rinnovata periodicamente per assicurarsi che tutti i server nell'elenco siano effettivamente disponibili. When a value other than "%1" is chosen for Directory, this will show whether registration is successful. If the registration failed, please choose a different directory. Quando viene scelto un valore diverso da "%1" per la rubrica, verrà mostrato se la registrazione è andata a buon fine. Se la registrazione non è riuscita, scegli una rubrica diversa. No recording directory has been set or the value is not useable. Check the value in the Options tab. Non è stata impostata alcuna cartella per la registrazione o il percorso non è valido. Controllare il valore nella scheda Opzioni. If the recording directory is not useable, the problem will be displayed in place of the session directory. Se la cartella di registrazione non è disponibile, il problema verrà visualizzato al posto della directory di sessione. Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user %1 is running as). Fare clic sul pulsante per aprire la finestra di dialogo che consente di selezionare la cartella di registrazione principale. Il percorso scelto deve esistere e deve avere i permessi di lattura/scrittura (consenti la creazione di sottodirectory da parte dell'utente %1 in esecuzione). The current value of the main recording directory. The chosen value must exist and be writeable (allow creation of sub-directories by the user %1 is running as). Click the button to open the dialog that allows the main recording directory to be selected. Il valore corrente della cartella di registrazione principale. Il valore scelto deve esistere ed avere i permessi di lettura/scrittura (consenti la creazione di sottodirectory da parte dell'utente %1 in esecuzione). Fare clic sul pulsante per aprire la finestra di dialogo che consente di selezionare la cartella di registrazione principale. Custom Directory address Indirizzo della Rubrica personalizzata The Custom Directory address is the address of the directory holding the server list to which this server should be added. L'indirizzo della rubrica personalizzato è l'indirizzo della Rubrica contenente l'elenco dei server a cui questo server deve essere aggiunto. Server List Filename dialog push button Pulsante Nome file elenco server Server List Filename Filename lista dei server Click the button to open the dialog that allows the server list persistence file name to be set. The user %1 is running as needs to be able to create the file name specified although it may already exist (it will get overwritten on save). Fare clic sul pulsante per aprire la finestra di dialogo che consente di impostare il nome del file di persistenza dell'elenco dei server. L'utente %1 è in esecuzione poiché deve essere in grado di creare il file specificato anche se potrebbe già esistere (verrà sovrascritto al salvataggio). Server List Filename text box (read-only) File della lista dei Server (Sola lettura) The current value of server list persistence file name. The user %1 is running as needs to be able to create the file name specified although it may already exist (it will get overwritten on save). Click the button to open the dialog that allows the server list persistence file name to be set. Il nome del file di dell'elenco dei server. L'utente %1 è in esecuzione poiché deve essere in grado di creare file specificato anche se potrebbe già esistere (verrà sovrascritto al salvataggio). Fare clic sul pulsante per aprire la finestra di dialogo che consente di impostare il nome del file dell'elenco dei server. Clear the server list file name button Bottone per cancellare il file della lista dei server Clear Server List Filename Cancella lista Server Click the button to clear the currently selected server list persistence file name. This will prevent persisting the server list until a new value is selected. Usare il bottone per canellare la lista dei server selezionata. Questo impedirà la persistenza dell'elenco dei server fino a quando non viene selezionato un nuovo valore. Start Minimized on Operating System Start Avvia ridotto a icona all'avvio del sistema operativo Now a directory Ora una rubrica If the start minimized on operating system start check box is checked, the Se è selezionato l'avvio in modalità minimizzata il server server will be started when the operating system starts up and is automatically minimized to a system task bar icon. si avvierà all'apertura del sistema operativo e si ridurrà automaticamente a icona sulla barra delle applicazioni. Show Creative Commons Licence Dialog Mostra finestra di dialogo Licenza Creative Commons If enabled, a Creative Commons BY-NC-SA 4.0 Licence dialog is shown each time a new user connects the server. Se attivato, verrà visualizzata una finestra di dialogo con la licenza BY-NC-SA 4.0 di Creative Commons ogni volta che un nuovo client si connette al server. Make My Server Public Rendi il mio server pubblico If the Make My Server Public check box is checked, this server registers itself at the directory server so that all Se il Rendi il mio server Pubblico è attivato, questo server si registrerà con il server centrale in modo che tutti gli utenti di users can see the server in the connect dialog server list and connect to it. The registration of the server is renewed periodically to make sure that all servers in the connect dialog server list are actually available. possono vedere il server nell'elenco dei server nella finestra di connessione e possono connettersi ad esso. La registrazione del server viene periodicamente aggiornata per garantire che tutti i server nell'elenco siano effettivamente disponibili. Register Server Status Stato di registrazione del server If the Make My Server Public check box is checked, this will show whether registration with the directory server is successful. Se il Rendi il Server Pubblico è stato attivato, mostrerà se ti sei registrato correttamente al server centrale. Directory Server Address Indirizzo Server Centrale The Directory server address is the IP address or URL of the directory server at which this server is registered. With the directory server address type either the local region can be selected of the default directory servers or a manual address can be specified. L'indirizzo del server centrale è l'indirizzo IP o URL del server centrale in cui è registrato questo server. Qui puoi scegliere la regione locale dai server centrali predefiniti oppure puoi specificare un indirizzo manualmente. Default directory server type combo box Box di selezione Server Centrale If the start minimized on operating system start check box is checked, the server will be started when the operating system starts up and is automatically minimized to a system task bar icon. Se la casella di controllo "Avvia ridotto a icona" all'avvio del sistema operativo è selezionata, il server verrà avviato all'avvio del sistema operativo e verrà automaticamente ridotto a icona a icona nella barra delle attività del sistema. If the Make My Server Public check box is checked, this server registers itself at the directory server so that all users of the application can see the server in the connect dialog server list and connect to it. The registration of the server is renewed periodically to make sure that all servers in the connect dialog server list are actually available. Se la casella di controllo "Rendi pubblico il mio server" è selezionata, questo server si registra sul server di directory in modo che tutti gli utenti possano vedere il server nell'elenco dei server. La registrazione del server viene rinnovata periodicamente per assicurarsi che tutti i server nell'elenco siano effettivamente disponibili. If the Make My Server Public check box is checked, this will show whether registration with the directory server is successful. If the registration failed, please choose another server list. Se la casella di controllo Rendi il mio server pubblico è selezionata, mostrerà se la registrazione con il server di directory è andata a buon fine. Se la registrazione non è riuscita, selezionare un altro elenco di server. Custom Directory Server Address Indirizzo Server di Directory alternativo The custom directory server address is the IP address or URL of the directory server at which the server list of the connection dialog is managed. L'indirizzo del server di directory alternativo è l'indirizzo IP o l'URL del server di directory in cui viene gestito l'elenco dei server della finestra di dialogo della connessione. Directory server address line edit Modifica Server di Directory Server List Selection Lista di selezione ei Server Selects the server list (i.e. directory server address) in which your server will be added. Seleziona la lista dei server(es. indirizzo central server) nel quale il tuo server sarà aggiunto. Server list selection combo box Box di selezione dei server Server Name Nome del server The server name identifies your server in the connect dialog server list at the clients. If no name is given, the IP address is shown instead. Il nome del server identifica il tuo server nell'elenco dei server sul client. Se non viene specificato un nome, viene invece visualizzato l'indirizzo IP. The server name identifies your server in the connect dialog server list at the clients. Il nome del server identifica il tuo server nell'elenco dei server nella finestra di dialogo di connessione sui client. Server name line edit Nome del server Location City Ubicazione Città The city in which this server is located can be set here. If a city name is entered, it will be shown in the connect dialog server list at the clients. Qui è possibile specificare la città in cui si trova il server. Se viene inserita una città, verrà visualizzata nell'elenco dei server sul client. City where the server is located line edit Citta del Server Location country Ubicazione Paese The country in which this server is located can be set here. If a country is entered, it will be shown in the connect dialog server list at the clients. Qui è possibile specificare il paese in cui si trova il server. Se viene inserito un paese, verrà visualizzato nell'elenco dei server sul client. Country where the server is located combo box Box del Paese dove si trova il server Country/Region Paese/Regione Set the country or region where the server is running. Clients will show this location in their connect dialog's server list. Imposta il paese o la regione in cui è in esecuzione il server. I client mostreranno questa posizione nell'elenco dei server nella loro finestra di dialogo di connessione. Combo box for location of this server Casella per la posizione di questo server Recording has been switched off by the UI checkbox. La registrazione è stata fermata mediante il box presente sull'interfaccia. Recording has been switched off, either by the UI checkbox or SIGUSR2 being received. La registrazione è stata fermata mediante il box presente sull'interfaccia oppure dalla ricezione del segnale SIGUSR2. Display dialog to select recording directory button Visualizza la finestra di dialogo per selezionare il pulsante della directory di registrazione Main Recording Directory Cartella Principale di Registrazione Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user Jamulus is running as). Fare clic sul pulsante per aprire la finestra di dialogo che consente di selezionare la directory di registrazione principale. Il Percorso scelto deve esistere ed non essere protetto da scrittura (autorizzare l'utente Jamulus alla creazione di cartelle e sottocartelle). Main recording directory text box (read-only) Casella di testo della Cartella principale di registrazione (sola lettura) The current value of the main recording directory. The chosen value must exist and be writeable (allow creation of sub-directories by the user Jamulus is running as). Click the button to open the dialog that allows the main recording directory to be selected. Il valore corrente della directory di registrazione principale. Il percorso scelto deve esistere e non essere protetto da scrittura (autorizzare l'utente Jamulus alla creazine di cartelle e sottocartelle). Fare clic sul pulsante per aprire la finestra di dialogo che consente di selezionare la directory di registrazione principale. Clear the recording directory button Bottone per cancellare il contenuto della cartella di registrazione Clear Recording Directory Cancella cartella di Registrazione Click the button to clear the currently selected recording directory. This will prevent recording until a new value is selected. Premere il pulsante per eliminare la cartella di registrazione. Ciò impedirà la registrazione fino a quando non viene selezionato un nuovo percorso valido. Checkbox to turn on or off server recording Spunta per abilitare o disabilitare la registrazione sul server If the Register Server check box is checked, this will show whether registration with the directory server is successful. If the registration failed, please choose another server list. Se la casella di controllo Registra server è selezionata, verrà segnalato se la registrazione con il server della cartella principale è andata a buon fine. Se la registrazione non è riuscita, scegli un altro elenco di server. Enable Recorder Abilita Registrazione Checked when the recorder is enabled, otherwise unchecked. The recorder will run when a session is in progress, if (set up correctly and) enabled. Se selezionato la registrazione è abilitata. La registrazione verrà eseguito quando è in corso una sessione, se (impostato correttamente e abilitato). Current session directory text box (read-only) Casella di testo per la Cartella della sessione Corrente (Sola Lettura) Current Session Directory Cartella della sessione Corrente Enabled during recording and holds the current recording session directory. Disabled after recording or when the recorder is not enabled. Abilitato durante la registrazione e imposta la directory della sessione di registrazione. Disabilitato dopo la registrazione o quando il registratore non è abilitato. Recorder status label Etichetta dello stato di Registrazione Recorder Status Stato di Registrazione Displays the current status of the recorder. The following values are possible: Visualizza lo stato della registrazione. Sono applicati i seguenti valori: No recording directory has been set or the value is not useable. Cartella per la registrazione non settata o non utilizzabile. Recording has been switched off La Registrazione è stata disattivata by the UI checkbox dalla Checkbok sull'UI , either by the UI checkbox or SIGUSR2 being received , dalla casella di controllo dell'interfaccia utente o dalla ricezione di SIGUSR2 There is no one connected to the server to record. Non c'è nessuno collegato al server per registrare. The performers are being recorded to the specified session directory. Gli artisti vengono registrati nella directory della sessione specificata. NOTE NOTE If the recording directory is not useable, the problem will be displayed in place of the directory. Se la directory di registrazione non è utilizzabile, il problema verrà visualizzato al posto della directory. Server welcome message edit box Casella di modifica del messaggio di benvenuto del server Server Welcome Message Messaggio di Benvenuto del Server A server welcome message text is displayed in the chat window if a musician enters the server. If no message is set, the server welcome is disabled. Un messaggio di benvenuto del server viene visualizzato nella finestra di chat se un musicista entra nel server. Se non viene impostato alcun messaggio, il benvenuto del server è disabilitato. Language Lingua Select the language to be used for the user interface. Seleziona la lingua da usare per l'interfaccia utente. Language combo box Box di selezione lingua Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user Jamulus is running as). Fare clic sul pulsante per aprire la finestra di dialogo che consente di selezionare la cartella di registrazione principale. Il percorso scelto deve esistere ed avere i giusti permessi di lettura/scrittura (consente la creazione di sottodirectory da parte dell'utente con cui Jamulus è in esecuzione). Custom Directory Cartella Personalizzata The custom directory is the IP address or URL of the directory server at which the server list of the connection dialog is managed. La cartella personalizzata è l'indirizzo IP o l'URL del Gestore in cui è presente l'elenco dei server della finestra di dialogo di connessione. Custom Directory line edit Modifica Cartella Personalizzata &Hide %1 server &Nascondi %1 server &Show %1 server &Visualizza %1 server %1 server %1 is the name of the main application %1 server Type a message here. If no message is set, the server welcome is disabled. Digita qui un messaggio. Se non viene impostato alcun messaggio, il benvenuto del server è disabilitato. %1 Server %1 is the name of the main application %1 server software upgrade available Disponibile Aggiornamento Recorder failed to start. Please check available disk space and permissions and try again. Error: Registrazione non avviata. Controlla lo spazio su disco e le autorizzazioni disponibili e riprova. Errore: ERROR ERRORE Displays the current status of the recorder. Visualizza lo stato del registratore. Request new recording button Pulsante per una nuova registrazione New Recording Nuova Registrazione During a recording session, the button can be used to start a new recording. Durante una sessione di registrazione questo pulsante può essere usato per iniziare una nuova registrazione. E&xit &Esci &Hide &Nascondi server server &Open &Apri server server Server Server &Window &Finestra Select Main Recording Directory Seleziona la directory di registrazione principale Predefined Address Indirizzo Predefinito Recording Registrazione Not recording Registrazione Ferma Not initialised Non inizializato Not enabled Non Abilitata Unregistered Non registrato None None Not registered Non Registrato Bad address Indirizzo Errato Registration requested Registrazione richiesta Registration failed Registrazione fallita Check server version Controlla Versione server Registered Registrato Directory server list full Lista Server della Rubrica piena Directory Server full Server Directory pieno Your server version is too old La tua versione del server è troppo vecchia Requirements not fulfilled Requisiti non soddisfatti Unknown value %1 Valore sconosciuto %1 Unknown value Valore sconosciuto CServerDlgBase Client IP:Port Client IP:Porta Name Nome Jitter Buffer Size Dimensione Jitter Buffer Channels Canali Server Setup Settaggi Server List Lista Location: Region Posizione: Regione Session Sessione Chat Window Welcome (HTML/CSS Supported) Finesta Chat Messaggio di Benvenuto (Supporta HTML/CSS) Options Opzioni Custom Directory address Indirizzo personalizzato Rubrica Server List Filename File Lista Server Start Minimized on Windows Start Avvio Minimizzato all'avvio di Windows Enable delay panning Abilita bilanciamento del delay Show Creative Commons BY-NC-SA 4.0 Licence Dialog Visualizza la finestra Creative Commons BY-NC-SA 4.0 Licence Update check Controlla Aggiornamenti Make My Server Public (Register My Server in the Server List) Rendi il server Pubblico (Regista il server nella lista dei server pubblici) Genre Genere STATUS STATO Custom Directory Server Address: Indirizzo server di directory alternativo: Recording Directory Directory di Registrazione Enable Jam Recorder Abilita Registrazione Jam Directory Cartella New Recording Nuova Registrazione Language Consider add "(Lang)" as a suffix to ensure that users who selected the wrong language find the correct button Lingua Directory Server Address: Indirizzo Server Centrale: My Server Info Informazioni sul Server Location: City Ubicazione: Città Location: Country Ubicazione: Paese Enable jam recorder Abilita Registrazione Jam New recording Nuova Registrazione Recordings folder Cartella di Registrazione TextLabelNameVersion TextLabelNameVersion CServerListManager Could not write to '%1' Impossibile scrivere su '%1' CSound Error requesting stream stop: $s Errore durante la richiesta di interruzione del flusso: $s Error closing stream: $s Errore chiusura dello stream: $s The Jack server is not running. This software requires a Jack server to run. Normally if the Jack server is not running this software will automatically start the Jack server. It seems that this auto start has not worked. Try to start the Jack server manually. Il server Jack non è attivo. Questo software necessita del server Jack per funzionare. Normalmente, se il server non è attivo, questo software lo avvierà automaticamente. Sembra che questo avvio automatico non abbia funzionato. Prova ad avviare manualmente il server Jack. The Jack server sample rate is different from the required one. The required sample rate is: La frequenza di campionamento del server Jack è diversa da quella richiesta. La frequenza di campionamento richiesta è: You can use a tool like <i><a href="https://qjackctl.sourceforge.io">QJackCtl</a></i> to adjust the Jack server sample rate. È possibile utilizzare uno strumento come <i> <a href="https://qjackctl.sourceforge.io"> QJackCtl </a> </i> per regolare la frequenza di campionamento del server Jack. Make sure to set the Frames/Period to a low value like Assicurati di impostare Frames / Periodo su un valore basso come to achieve a low delay. per ottenere un ritardo più basso. The Jack port registering failed. Registro delle porte di Jack non riuscito. Cannot activate the Jack client. Jack client non può essere attivato. The Jack server was shut down. This software requires a Jack server to run. Try to restart the software to solve the issue. Il server Jack non è attivo. Questo software necessita del server Jack per funzionare. Prova a riavviare il software per risolvere questo problema. CoreAudio input AudioHardwareGetProperty call failed. It seems that no sound card is available in the system. Ingresso CoreAudio Chiamata AudioHardwareGetProperty non riuscita. Sembra che il sistema non abbia una scheda audio disponibile. CoreAudio output AudioHardwareGetProperty call failed. It seems that no sound card is available in the system. Uscita CoreAudio Chiamata AudioHardwareGetProperty non riuscita. Sembra che il sistema non abbia una scheda audio disponibile. Current system audio input device sample rate of %1 Hz is not supported. Please open the Audio-MIDI-Setup in Applications->Utilities and try to set a sample rate of %2 Hz. La frequenza di campionamento corrente del dispositivo audio in ingresso di %1 Hz non è supportata. Apri Impostazioni-Audio-MIDI in Applicazioni-> Utilità e prova a impostare una frequenza di campionamento di %2 Hz. The current selected audio device is no longer present in the system. L'attuale interfaccia selezionata non è disponibile nel sistema. The audio input device is no longer available. L'input selezionato non è stato trovato. The audio output device is no longer available. L'usicta audio selezionata non è stata trovata. Current system audio output device sample rate of %1 Hz is not supported. Please open the Audio-MIDI-Setup in Applications->Utilities and try to set a sample rate of %2 Hz. La frequenza di campionamento corrente del dispositivo audio in uscita %1 Hz non è supportata. Apri Impostazioni-Audio-MIDI in Applicazioni-> Utilità e prova a impostare una frequenza di campionamento di %2 Hz. The audio input stream format for this audio device is not compatible with this software. Il formato di trasmissione audio in ingresso per questo dispositivo audio non è supportato da questo software. The audio output stream format for this audio device is not compatible with this software. Il formato di trasmissione audio in uscita per questo dispositivo audio non è supportato da questo software. The buffer sizes of the current input and output audio device cannot be set to a common value. Please choose other input/output audio devices in your system settings. Le dimensioni del buffer dell'attuale dispositivo di input / output audio non possono essere impostate su un valore comune. Seleziona altri dispositivi di input / output audio nelle impostazioni di sistema. The audio driver could not be initialized. Il driver audio non può essere inizializzato. The audio device does not support the required sample rate. The required sample rate is: Il dispositivo audio non supporta la frequenza di campionamento richiesta. La frequenza di campionamento richiesta è: The audio device does not support setting the required sampling rate. This error can happen if you have an audio interface like the Roland UA-25EX where you set the sample rate with a hardware switch on the audio device. If this is the case, please change the sample rate to Il dispositivo audio non consente di impostare la frequenza di campionamento richiesta. Questo errore può verificarsi se si dispone di un dispositivo audio come il Roland UA-25EX in cui è configurato mediante un interruttore fisico sul dispositivo. In tal caso, modificare la frequenza di campionamento a Hz on the device and restart the Hz sul dispositivo e riavviare il programma software. . The audio device does not support the required number of channels. The required number of channels for input and output is: Il dispositivo audio non supporta il numero richiesto di canali. Il numero di canali richiesti è: Required audio sample format not available. Formato di campionamento audio richiesto non disponibile. The selected audio device is no longer present in the system. Please check your audio device. Il dispositivo audio selezionato non è più presente nel sistema. Controlla il tuo dispositivo audio. Couldn't initialise the audio driver. Check if your audio hardware is plugged in and verify your driver settings. Impossibile inizializzare il driver audio. Controlla se il tuo hardware audio è collegato e verifica le impostazioni del driver. The selected audio device is incompatible since it doesn't support a sample rate of %1 Hz. Please select another device. Il dispositivo audio selezionato non è compatibile poiché non supporta una frequenza di campionamento di %1 Hz. Seleziona un altro dispositivo. The current audio device configuration is incompatible because the sample rate couldn't be set to %2 Hz. Please check for a hardware switch or driver setting to set the sample rate manually and restart %1. L'attuale configurazione del dispositivo audio non è compatibile perché non è stato possibile impostare la frequenza di campionamento su %2 Hz. Verifica la presenza di un interruttore hardware o di un'impostazione del driver per impostare manualmente la frequenza di campionamento e riavviare %1. The selected audio device is incompatible since it doesn't support %1 in/out channels. Please select another device or configuration. Il dispositivo audio selezionato non è compatibile poiché non supporta %1 canali di ingresso/uscita. Seleziona un altro dispositivo o configurazione. The selected audio device is incompatible since the required audio sample format isn't available. Please use another device. Il dispositivo audio selezionato non è compatibile poiché il formato del campione audio richiesto non è disponibile. Si prega di utilizzare un altro dispositivo. No ASIO audio device driver found. Nessun driver ASIO trovato. Please install an ASIO driver before running %1. If you own a device with ASIO support, install its official ASIO driver. If not, you'll need to install a universal driver like ASIO4ALL. Installa un driver ASIO prima di eseguire %1. Se possiedi un dispositivo con supporto ASIO, installa il suo driver ASIO ufficiale. In caso contrario, dovrai installare un driver universale come ASIO4ALL. Please install an ASIO driver before running %1. If you own a device with ASIO support, install its official ASIO driver. If not, you'll need to download and install a universal driver like ASIO4ALL. Installa un driver ASIO prima di cominciare %1. Se possiedi un dispositivo con supporto ASIO, installa il suo driver ASIO ufficiale. In caso contrario, dovrai scaricare e installare un driver universale come ASIO4ALL. No ASIO audio device (driver) found. Non è stato trovato un dispositivo ASIO (driver). The Il programma software requires the low latency audio interface ASIO to work properly. This is not a standard Windows audio interface and therefore a special audio driver is required. Either your sound card has a native ASIO driver (which is recommended) or you might want to use alternative drivers like the ASIO4All driver. richiede che l'interfaccia audio ASIO a bassa latenza funzioni correttamente. Non è un'interfaccia standard di Windows e quindi è necessario un driver audio speciale. La tua scheda audio potrebbe avere un driver ASIO nativo (consigliato) o potresti provare un driver alternativo come ASIO4All. JACK couldn't be started automatically. Please start JACK manually and check for error messages. JACK non può essere avviato automaticamente. Avvia JACK manualmente e controlla i messaggi di errore. JACK isn't running at a sample rate of <b>%1 Hz</b>. Please use a tool like <i><a href="https://qjackctl.sourceforge.io">QjackCtl</a></i> to set the the JACK sample rate to %1 Hz. JACK non è in esecuzione a una frequenza di campionamento di <b>%1 Hz</b>. Utilizza uno strumento come <i><a href="https://qjackctl.sourceforge.io">QjackCtl</a></i> per impostare la frequenza di campionamento JACK su %1 Hz. The JACK port registration failed. This is probably an error with JACK. Please stop %1 and JACK. Afterwards check if another program at a sample rate of %2 Hz can connect to JACK. La registrazione della porta JACK non è riuscita. Questo è probabilmente un errore con JACK. Per favore, ferma %1 e JACK. Successivamente controlla se un altro programma con una frequenza di campionamento di %2 Hz può connettersi a JACK. The JACK port registration failed. This is probably an error with JACK. Please stop %1 and JACK. Afterwards, check if another MIDI program can connect to JACK. La registrazione della porta JACK non è riuscita. Questo è probabilmente un errore di JACK. Per favore, ferma %1 e JACK. Successivamente, controlla se un altro programma MIDI può connettersi a JACK. Can't activate the JACK client. This is probably an error with JACK. Please check the JACK output. Impossibile attivare il client JACK. Questo è probabilmente un errore di JACK. Si prega di controllare gli errori su JACK. JACK was shut down. %1 requires JACK to run. Please restart %1 to start JACK again. JACK è stato chiuso. %1 richiede l'esecuzione di JACK. Riavvia %1 per riavviare JACK. No sound card is available in your system. CoreAudio input AudioHardwareGetProperty call failed. Nessuna scheda audio è disponibile nel tuo sistema. Ingresso CoreAudio Chiamata AudioHardwareGetProperty non riuscita. No sound card is available in the system. CoreAudio output AudioHardwareGetProperty call failed. Nessuna scheda audio è disponibile nel sistema. Uscita CoreAudio Chiamata AudioHardwareGetProperty non riuscita. The currently selected audio device is no longer present. Please check your audio device. Il dispositivo audio attualmente selezionato non è più presente. Controlla il tuo dispositivo audio. The audio input device is no longer available. Please check if your input device is connected correctly. Il dispositivo audio attualmente selezionato non è più presente. Controlla le connessioni sul tuo dispositivo audio. The sample rate on the current input device isn't %1 Hz and is therefore incompatible. Please select another device or try setting the sample rate to %1 Hz manually via Audio-MIDI-Setup (in Applications->Utilities). La frequenza di campionamento sul dispositivo selezionato non è %1 Hz ed è quindi incompatibile. Seleziona un altro dispositivo o prova a impostare manualmente la frequenza di campionamento su %1 Hz tramite Audio-MIDI-Setup (in Applicazioni->Utility). The audio output device is no longer available. Please check if your output device is connected correctly. Il dispositivo di uscita audio non è più disponibile. Si prega di verificare se il dispositivo di output è collegato correttamente. The sample rate on the current output device isn't %1 Hz and is therefore incompatible. Please select another device or try setting the sample rate to %1 Hz manually via Audio-MIDI-Setup (in Applications->Utilities). La frequenza di campionamento sul dispositivo selezionato non è %1 Hz ed è quindi incompatibile. Seleziona un altro dispositivo o prova a impostare manualmente la frequenza di campionamento su %1 Hz tramite Audio-MIDI-Setup (in Applicazioni->Utility). The stream format on the current input device isn't compatible with this software. Please select another device. Il formato del flusso sul dispositivo di input corrente non è compatibile con questo software. Seleziona un altro dispositivo. The stream format on the current output device isn't compatible with %1. Please select another device. Il formato del flusso sul dispositivo di output corrente non è compatibile con %1. Seleziona un altro dispositivo. The buffer sizes of the current input and output audio device can't be set to a common value. Please select different input/output devices in your system settings. La dimensione del buffer sul dispositivo audio selezionato non può essere impostata su un valore comune tra input e output. Si prega di selezionare diversi dispositivi di input/output nelle impostazioni di sistema. CSoundBase Invalid device selection. Device Selezionato non valido. The audio driver properties have changed to a state which is incompatible with this software. The selected audio device could not be used because of the following error: I settaggi del driver audio sono stati cambiati con parametri incompatibili con questo programma. La scheda audio selezionata non può essere usata a causa dei seguenti errori: Please restart the software. Perfavore riavvia il programma. Close Chiudi The selected audio device could not be used because of the following error: La scheda audio selezionata non può essere usata per i seguenti motivi: The previous driver will be selected. Sarà ripristinato il driver precedentemente usato. The previously selected audio device is no longer available or the audio driver properties have changed to a state which is incompatible with this software. We now try to find a valid audio device. This new audio device might cause audio feedback. So, before connecting to a server, please check the audio device setting. La precedente interfaccia audio non è stata trovata o il driver è stato cambiato con uno incompatibile con questo software. Verrà cercata un'interfaccia audio valida. Questa nuova interfaccia potrebbe causare ritorni di seganle audio. Prima di connettersi ad un server controllare i settaggi della scheda. No usable Device Non utilizzabile audio device (driver) found. driver non trovati. In the following there is a list of all available drivers with the associated error message: Di seguito è riportato un elenco di tutti i driver disponibili con errore associato: Do you want to open the ASIO driver setups? Vuoi aprire il setup dei Driver Audio ASIO? could not be started because of audio interface issues. Impossibile avviare a causa di problemi con il dispositivo audio. Can't use the selected audio device because of the following error: %1 The previous driver will be selected. Impossibile utilizzare il dispositivo audio selezionato a causa del seguente errore: %1 Verrà selezionato il driver precedente. The previously selected audio device is no longer available or the driver has changed to an incompatible state. We'll attempt to find a valid audio device, but this new audio device may cause feedback. Before connecting to a server, please check your audio device settings. Il dispositivo audio selezionato in precedenza non è più disponibile o il driver è passato a uno stato incompatibile. Cercheremo di trovare un dispositivo audio valido. Prima di connetterti a un server, controlla le connessioni sul tuo dispositivo audio dalle impostazioni. <b>%1 couldn't find a usable %2 audio device.</b><br><br> <b>%1 Impossibile trovare una valida %2 scheda audio.</b><br><br> You may be able to fix errors in the driver settings. Do you want to open these settings now? Puoi risolvare il problema aprendo il software del driver. Vuoi aprire la schermata dei settaggi adesso? No usable %1 audio device found. Nessun dispositivo audio utilizzabile %1 trovato. These are all the available drivers with error messages: Questi sono tutti i driver disponibili con messaggi di errore: Do you want to open the ASIO driver setup to try changing your configuration to a working state? Vuoi aprire la configurazione del driver ASIO per provare a cambiare la tua configurazione? Can't start %1. Please restart %1 and check/reconfigure your audio settings. Impossibile avviare %1. Riavvia %1 e controlla/riconfigura le tue impostazioni audio. QCoreApplication %1, Version %2 %1 Versione, Versione %2 Internet Jam Session Software Programma per Jam Session su Internet %1, Version %2 %1 is app name, %2 is version number %1, Versione %2 Released under the GNU General Public License version 2 or later (GPLv2) Rilasciato sotto la GNU General Public License versione 2 o successive (GPLv2) This program is free software; you can redistribute it and/or modify it under Questo programma è un software gratuito; puoi ridistribuirlo e/o modificarlo in the terms of the GNU General Public License as published by the Free Software i termini della GNU General Public License come pubblicata dal Software Libero Foundation; either version 2 of the License, or (at your option) any later version. Fondazione; la versione 2 della Licenza o (a scelta dell'utente) qualsiasi versione successiva. There is NO WARRANTY, to the extent permitted by law. NON C'è ALCUNA GARANZIA, nella misura consentita dalla legge. Using the following libraries, resources or code snippets: Utilizzo delle seguenti librerie, risorse o frammenti di codice: Qt framework Framework Qt Opus Interactive Audio Codec Codec audio interattivo Opus Audio reverberation code by Perry R. Cook and Gary P. Scavone Audio reverberation sviluppato da Perry R. Cook and Gary P. Scavone Some pixmaps are from the Open Clip Art Library (OCAL) Alcune pixmap provengono dalla Open Clip Art Library (OCAL) Flag icons by Mark James Iconde delle Bandiere di Mark James Copyright (C) 2005-2022 The Jamulus Development Team Copyright (C) 2005-2022 Team di sviluppo Jamulus Released under the GNU General Public License (GPL) Rilasciato sotto licensa GNU General Public License (GPL) global A %1 upgrade is available: <a style='color:red;' href='https://jamulus.io/upgrade?progversion=%2'>go to details and downloads</a> È disponibile un aggiornamento %1: <a style='color:red;' href='https://jamulus.io/upgrade?progversion=%2'>vai a dettagli e download</a> For more information use the "What's This" help (help menu, right mouse button or Shift+F1) Per maggiori informazioni usare il comando "Cos'è Questo" (Menù Aiuto, Tasto destro del mouse oppure Shift+F1) jamulus-3.9.1+dfsg/src/translation/translation_pl_PL.ts0000644000175000017500000070036514340334543022310 0ustar vimervimer CAboutDlg Qt cross-platform application framework Qt - między-platformowe szablony aplikacji Audio reverberation code by Perry R. Cook and Gary P. Scavone Kod algorytmu pogłosu: Perry R. Cook i Gary P Scavone Some pixmaps are from the Niektóre obrazki pochodzą z This app enables musicians to perform real-time jam sessions over the internet. Aplikacja pozwala muzykom na sesje dźwiękowe w czasie rzeczywistym przez internet. There is a server which collects the audio data from each client, mixes the audio data and sends the mix back to each client. To jest serwer, który zbiera dane audio każdego uczestnika i już zmiksowane odsyła do każdego. This app uses the following libraries, resources or code snippets: Aplikacja korzysta z następująuch bibliotek, źródeł lub fragmentów kodu: Country flag icons by Mark James Ikony flag poszczególnych krajów: Mark James For details on the contributions check out the Aby znaleźć szczegółowe informacje o współtwórcach sprawdź Flag icons by Mark James Ikony flag: Mark James Some sound samples are from Niektóre próbki dźwiękowe pochodzą z For details on the contributions check out the %1 Aby znaleźć szczegółowe informacje o współtwórcach sprawdź %1 Github Contributors list Lista współautorów na Github-ie Spanish hiszpański French francuski Portuguese portugalski Dutch holenderski Italian włoski German niemiecki Polish polski Swedish szwedzki Korean koreański Slovak słowacki Simplified Chinese Chiński uproszczony Norwegian Bokmål About %1 O programie %1 About O programie CAboutDlgBase About O programie TextLabelVersion Copyright (C) 2005-2022 Volker Fischer and others Copyright (C) 2005-2022 Volker Fischer i inni Copyright (C) 2005-2022 The Jamulus Development Team Copyright (C) 2005-2022 Zespół programistów Jamulus-a A&bout O &programie &Libraries &Biblioteki &Contributors &Współtwórcy &Translation &Tłumaczenia &OK &OK CAnalyzerConsole Analyzer Console Konsola analizatora Error Rate of Each Buffer Size Częstotliwość występowania błędu dla każdego rozmiaru bufora CAudioMixerBoard Personal Mix at the Server Własny miks na serwerze When connected to a server, the controls here allow you to set your local mix without affecting what others hear from you. The title shows the server name and, when known, whether it is actively recording. Podczas połączenia z serwerem, znajdujące się tutaj opcje pozwalają ustawić własny miks bez wpływu na to jak inni ciebie słyszą. W tytule zawarta jest nazwa serwera oraz to, czy nagrywanie jest aktywne. Server Serwer T R Y I N G T O C O N N E C T P R Ó B U J Ę S I Ę P O Ł Ą C Z Y Ć RECORDING ACTIVE NAGRYWANIE AKTYWNE Personal Mix at: %1 Własny miks na: %1 CChannelFader Pan Panorama Mute Wycisz Solo Solo &No grouping &Nie grupuj Assign to group Przypisz do grupy Channel Level Poziom kanału Input level of the current audio channel at the server Poziom wejściowy aktualnego kanału audio na serwerze Mixer Fader Suwak miksera Local mix level setting of the current audio channel at the server Lokalne ustawienie poziomu miksowania bieżącego kanału audio na serwerze Status Indicator Wskaźnik stanu Shows a status indication about the client which is assigned to this channel. Supported indicators are: Pokazuje wskazanie statusu uczestnika, który jest przypisany do tego kanału. Wskazana oznaczają: Status indicator label Etykieta wskaźnika stanu Panning Ustawienia panoramy Local panning position of the current audio channel at the server Lokalna pozycja panoramy aktualnego kanału dźwiękowego na serwerze With the Mute checkbox, the audio channel can be muted. Pole wyboru wycisza kanał audio. Mute button Przycisk wyciszenia Solo button Przycisk funkcji Solo Group Grupa With the Grp checkbox, a group of audio channels can be defined. All channel faders in a group are moved in proportional synchronization if any one of the group faders are moved. Pole wybory GR służy do definiowania grupy kanałów dźwiękowych. Kiedy jeden z suwaków w grupie jest przesuwany, wszystkie inne przesuwane są proporcjonalnie. Group button Przycisk grupy Fader Tag Etykieta suwaka The fader tag identifies the connected client. The tag name, a picture of your instrument and the flag of your location can be set in the main window. Oznaczenie suwaka idenyfikuje podłączonego uczestnika. Nazwę, ikonę instrumentu i flagę kraju uczestnika ustawia się w głównym oknie programu. Mixer channel country/region flag Flaga kraju/regionu widoczna na kanale miksera Alias Nazwa Displays the pre-fader audio level of this channel. All clients connected to the server will be assigned an audio level, the same value for every client. Pokazuje początkowy poziom dźwięku suwaka tego kanału. Każdemu uczetnikowi podłączającemu się do tego serwera zostanie ustawiony ten poziom, ta sama wartość dla każdego. Adjusts the audio level of this channel. All clients connected to the server will be assigned an audio fader, displayed at each client, to adjust the local mix. Regulacja poziomu dźwięku tego kanału. Wszystkim klientom połączonym z serwerem zostanie przypisany suwak, wyświetlany przy każdym kliencie, w celu dostosowania lokalnego miksowania. Speaker with cancellation stroke: Indicates that another client has muted you. Przekreślony głośnik: Oznacza, że któryś użytkownik cię wyciszył. Sets the pan from Left to Right of the channel. Works only in stereo or preferably mono in/stereo out mode. Ustawia panoramę do prawej strony kanału. Działa tylko w trybie stereo lub najlepiej mono in/stereo out. With the Solo checkbox, the audio channel can be set to solo which means that all other channels except the soloed channel are muted. It is possible to set more than one channel to solo. Za pomocą tego pola wyboru, kanał audio może być ustawiony na solo, co oznacza, że wszystkie inne kanały są wyciszone. Możliwe jest ustawienie więcej niż jednego kanału w tym trybie. The fader tag identifies the connected client. The tag name, a picture of your instrument and the flag of your country can be set in the main window. Oznaczenie suwaka idenyfikuje podłączonego uczestnika. Nazwa, obrazek i flaga kraju ustawia się w głównym oknie programu. Mixer channel instrument picture Obrazek instrumentu dla kanału miksera Mixer channel label (fader tag) Etykieta kanału mieksera (nazwa suwaka) Mixer channel country flag Flaga kraju kanału miksera PAN PANORAMA MUTE WYCISZENIE SOLO SOLO GRP GR M W S S G G Grp Gr Alias/Name Nick/Nazwa Instrument Instrument Location Lokalizacja Skill Level Poziom umiejętności Beginner Początkujący Intermediate Średniozaawansowany Expert Ekspert Musician Profile Profil muzyka CChatDlg Chat Window Okno Czatu The chat window shows a history of all chat messages. Okno rozmowy pokazuje historię wszystkich widomości czatu. Chat history Historia czatu Input Message Text Wprowadzanie wiadomości czatu Enter the chat message text in the edit box and press enter to send the message to the server which distributes the message to all connected clients. Your message will then show up in the chat window. Wpisz tekst widomości w polu edycji i wciśnij enter, aby wysłać wiadomość do serwera, który roześle ją do wszystkich podłączonych osób. Twoja wiadomość pojawi się w oknie czatu. New chat text edit box Pole edycji nowego tekstu czatu Type a message here Napisz tu wiadomość &Edit &Edytuj Cl&ear Chat History &Wyczyść historię rozmowy &Close &Zamknij Do you want to open the link '%1' in your browser? Czy chcesz otworzyć link '%1' w przeglądarce? Do you want to open the link Chcesz otworzyć ten link in an external browser? w zewnętrznej przeglądarce? CChatDlgBase Chat Czat &Send &Wyślij CClientDlg Input Level Meter Miernik Poziomu Wejścia Make sure not to clip the input signal to avoid distortions of the audio signal. Aby uniknąć zniekształceń sygnału audio, należy upewnić się, że sygnał wejściowy nie jest obcinany. Input level meter Miernik poziomu wejścia Simulates an analog LED level meter. Symuluje analogową diodę miernika poziomu. Connect/Disconnect Button Przycisk Połącz/Rozłącz Connect and disconnect toggle button Przycisk przełącznika połącz i rozłącz Local Audio Input Fader Fader Lokalnego Wejścia Audio L L , where , gdzie is the current attenuation indicator. jest wskaźnik aktualnego tłumienia. Local audio input fader (left/right) Suwak lokalnego wejścia audio Delay Status LED Dioda stanu opóźnienia Delay status LED indicator Wskaźnik diody stanu opóźnienia Buffers Status LED Dioda stanu buforów The network jitter buffer is not large enough for the current network/audio interface jitter. Bufor dla odchyleń sieciowych nie jest wystarczający dla aktualnych odchyleń interfejsu sieciowego/dźwiękowego. This shows the level of the two stereo channels for your audio input. Pokazuje poziom dwóch kanałów stereo dla wejścia audio. If the application is connected to a server and you play your instrument/sing into the microphone, the VU meter should flicker. If this is not the case, you have probably selected the wrong input channel (e.g. 'line in' instead of the microphone input) or set the input gain too low in the (Windows) audio mixer. Jeśli aplikacja jest już podłączona do serwera i grasz na instrumencie/śpiewasz do mikrofonu, miernik VU powinien migać. Jeśli tak nie jest, prawdopodobnie wybrany został niewłaściwy kanał wejściowy (np. wejście liniowe zamiast wejścia mikrofonowego) lub ustawione zostało zbyt niskie wzmocnienie wejściowe w mikserze audio (Windows). For proper usage of the application, you should not hear your singing/instrument through the loudspeaker or your headphone when the software is not connected. This can be achieved by muting your input audio channel in the Playback mixer (not the Recording mixer!). W celu prawidłowego korzystania z aplikacji nie należy słyszeć śpiewu/instrumentu przez głośnik lub słuchawki, gdy oprogramowanie nie jest podłączone. Można to osiągnąć wyciszając wejściowy kanał audio w mikserze odtwarzającym (nie w mikserze nagrywającym!). Opens a dialog where you can select a server to connect to. If you are connected, pressing this button will end the session. otwiera okno wyboru serwera. do którego można się podłączyć, a gdy połączono, naciśnięcie tego przycisku spowoduje zakończenie sesji. Controls the relative levels of the left and right local audio channels. For a mono signal it acts as a pan between the two channels. For example, if a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows Kontroluje względne poziomy lewego i prawego lokalnego kanału audio. Na przykład, jeśli mikrofon jest podłączony do prawego kanału wejściowego, a instrument jest podłączony do lewego kanału wejściowego, który jest znacznie głośniejszy od mikrofonu, należy przesunąć suwak audio w kierunku, w którym pokazuje etykieta nad suwakiem Reverb effect Efekt pogłosu Reverb can be applied to one local mono audio channel or to both channels in stereo mode. The mono channel selection and the reverb level can be modified. For example, if a microphone signal is fed in to the right audio channel of the sound card and a reverb effect needs to be applied, set the channel selector to right and move the fader upwards until the desired reverb level is reached. Pogłos może być zastosowany do jednego lokalnego kanału audio mono lub do obu kanałów w trybie stereo. Wybór kanału monofonicznego i poziom pogłosu mogą być modyfikowane. Na przykład, jeśli sygnał z mikrofonu jest podawany do prawego kanału audio karty dźwiękowej i konieczne jest zastosowanie efektu pogłosu, należy ustawić przełącznik wyboru kanału w prawo i przesunąć suwak w górę, aż do osiągnięcia żądanego poziomu pogłosu. Reverb effect level setting Ustawienie poziomu efektu pogłosu Reverb Channel Selection Wybór kanału z pogłosem With these radio buttons the audio input channel on which the reverb effect is applied can be chosen. Either the left or right input channel can be selected. Za pomocą tych przycisków wyboru można ustawić kanał wejściowy audio, na którym zostanie zastosowany efekt pogłosu. Można wybrać lewy lub prawy. Left channel selection for reverb Wybór lewego kanału dla pogłosu Right channel selection for reverb Wybór prawego kanału dla pogłosu Shows the current audio delay status: Pokazuje obecny status opóźnienia audio: Green Zielony The delay is perfect for a jam session. Opóźnienie jest idealne dla sesji. Yellow Żółty A session is still possible but it may be harder to play. Sesja jest nadal możliwa, ale może być trudniej grać. Red Czerwony The delay is too large for jamming. Opóźnienie jest zbyt duże dla sesji. If this LED indicator turns red, you will not have much fun using the application. Jeśli ta dioda zmieni kolor na czerwony, korzystanie z aplikacji może być utrudnione. %1 Directory %1 Serwer zbiorczy The buffers status LED shows the current audio/streaming status. If the light is red, the audio stream is interrupted. This is caused by one of the following problems: Dioda stanu buforów pokazuje aktualny status audio/transmisji. Jeśli dioda świeci na czerwono, strumień audio zostaje przerwany. Może to być spowodowane przez jeden z poniższych problemów: The sound card's buffer delay (buffer size) is too small (see Settings window). Opóźnienie bufora karty dźwiękowej (rozmiar bufora) jest zbyt małe (patrz okno Ustawienia). The upload or download stream rate is too high for your internet bandwidth. Prędkość przesyłania lub pobierania strumienia audio jest zbyt wysoka dla dostępnej prędkości internetu. The CPU of the client or server is at 100%. Obciążenie CPU klienta lub serwera wynosi 100%. Buffers status LED indicator Dioda wskazująca stan buforów Current Connection Status Parameter Wskaźnik aktualnego stanu połączenia The Ping Time is the time required for the audio stream to travel from the client to the server and back again. This delay is introduced by the network and should be about 20-30 ms. If this delay is higher than about 50 ms, your distance to the server is too large or your internet connection is not sufficient. Czas Ping Time to czas potrzebny do przejścia strumienia audio od klienta do serwera i z powrotem. To opóźnienie jest wywoływane przez sieć internetową i powinno wynosić około 20-30 ms. Jeśli jest większe niż około 50 ms, odległość do serwera jest zbyt duża lub szybkość połączenia internetowego nie jest wystarczająca. Overall Delay is calculated from the current Ping Time and the delay introduced by the current buffer settings. Całkowite opóźnienie jest obliczane na podstawie bieżącego ping-a i opóźnienia wynikającego z aktualnych ustawień bufora. If this LED indicator turns red, you will not have much fun using the Jeśli ta dioda zmieni kolor na czerwony może być utrudnione korzystanie z software. -a. C&onnect &Połącz software upgrade available dostępna aktualizacja oprogramowania &File P&lik &Load Mixer Channels Setup... Wczytaj ustawienia kanałów &miksera... &Save Mixer Channels Setup... Zapi&sz ustawienia kanałów miksera... &View &Widok &Connection Setup... &Konfiguracja połączenia... My &Profile... Mój &profil... C&hat... &Czat... &Settings... &Ustawienia... &Analyzer Console... Konsola &analizatora... N&o User Sorting &Bez sortowania kanałów If this LED indicator turns red, you will not have much fun using the %1 software. Jeśli ta dioda zmieni kolor na czerwony, korzystanie z aplikacji %1 może być utrudnione. O&wn Fader First &Własny suwak na początku Sort Users by &Name Sortuj kanały według &nazwy Sort Users by &Instrument Sortuj kanały według &instrumentu Sort Users by &Group Sortuj kanały według &grupy Sort Users by &City Sortuj kanały według &miasta Auto-Adjust all &Faders &Automatycznie dopasuj wszystkie suwaki If this LED indicator turns red, you will not have much fun using %1. Jeśli ta dioda zmieni kolor na czerwony, korzystanie z %1-a może być utrudnione. Local Jitter Buffer Status LED Dioda statusu lokalnego bufora opóźnień The local jitter buffer status LED shows the current audio/streaming status. If the light is red, the audio stream is interrupted. This is caused by one of the following problems: Dioda lokalnego bufora opóźnień pokazuje status aktualnego strumienia audio. Jeżeli jest czerwona to strumień jest przerywany. Powodem tego może być jedna z poniższych przyczyn: If this LED indicator turns red, the audio stream is interrupted. Jeśli ta dioda zmieni kolor na czerwony, to strumień audio został przerwany. Local Jitter Buffer status LED indicator Wskaźnik stanu lokalnego bufora opóźnień &Settings &Ustawienia Connect Połącz Settings Ustawienia Chat Czat Enable feedback detection Wykrywaj sprzężenia Audio feedback or loud signal detected. We muted your channel and activated 'Mute Myself'. Please solve the feedback issue first and unmute yourself afterwards. Wykryto sprzężenie lub za głośny sygnał. Twój kanał został wyciszony i włączono „Wycisz mnie”. Napraw przyczynę sprzęgania i wtedy wyłącz swoje wyciszenie. Ok Ok Clear &All Stored Solo Settings Wy&czyść wszystkie zachowane ustawienia użytkowników Set All Faders to New Client &Level Ustaw suwaki do określonego w ustawieniach &poziomu E&xit &Wyjdź Current Connection Status Wskaźnik aktualnego połączenia Sett&ings Ustaw&ienia Audio/Network &Settings... &Ustawienia dźwięku i sieci... A&dvanced Settings... Ustawienia &zaawansowane... &Edit &Edytuj Use &Two Rows Mixer Panel Używaj &dwurzędowego panelu miksera Clear &All Stored Solo and Mute Settings Wy&czyść wszystkie ustawienia solo/wycissz Center Środek R P Directory Server Serwer adresowy Select Channel Setup File Wybierz plik ustawień kanału user użytkownik users użytkownicy Your sound card is not working correctly. Please open the settings dialog and check the device selection and the driver settings. Twoja karta dźwiękowa nie działa prawidłowo. Proszę otworzyć okno ustawień dźwięku i sprawdzić wybrane urządzenie i ustawienia sterownika. &Disconnect &Rozłącz CClientDlgBase Delay Opóźnienie Buffers Bufory Input Wejście L L R P Jitter Odchylenie Ping Ping ms ms &Mute Myself Wycisz &Mnie &Settings &Ustawienia &Chat &Czat C&onnect &Połącz Pan Panorama Center Środek Reverb Pogłos Left Lewy Right Prawy MUTED (Other people won't hear you) WYCISZONY (Inni nie będą cię słyszeć) Set up your audio, connect to a server and start jamming! Ustaw dźwięk, połącz się z serwerem i zacznij sesję! Update check Sprawdzanie uaktualnień CClientSettingsDlg Jitter Buffer Size Rozmiar bufora odchyleń The jitter buffer setting is therefore a trade-off between audio quality and overall delay. Wartość bufora odchyleń jest więc kompromisem pomiędzy jakością dźwięku a całkowitym opóźnieniem. Local jitter buffer slider control Suwak kontrolujący lokalny bufor odchyleń Server jitter buffer slider control Suwak kontrolujący bufor odchyleń na serwerze Auto jitter buffer switch Przełącznik automatycznego rozmiaru bufora odchyleń Jitter buffer status LED indicator Dioda stanu bufora odchyleń Sound Card Device Urządzenie dźwiękowe The ASIO driver (sound card) can be selected using Sterownik ASIO (karta dźwiękowa) można wybrać za pomocą programu under the Windows operating system. Under MacOS/Linux, no sound card selection is possible. If the selected ASIO driver is not valid an error message is shown and the previous valid driver is selected. w systemie operacyjnym Windows. W systemie MacOS/Linux nie ma możliwości wyboru karty dźwiękowej. Jeśli wybrany sterownik ASIO nie jest prawidłowy, wyświetlany jest komunikat o błędzie i wybierany jest poprzedni prawidłowy sterownik. If the driver is selected during an active connection, the connection is stopped, the driver is changed and the connection is started again automatically. Jeżeli podczas aktywnego połączenia zostanie wybrany sterownik, to połączenie zostanie przerwane, sterownik zostanie zmieniony i połączenie zostanie ponownie automatycznie uruchomione. Sound card device selector combo box Pole wyboru urządzenia karty dźwiękowej If you are using the kX ASIO driver, make sure to connect the ASIO inputs in the kX DSP settings panel. Jeśli używasz sterownika kX ASIO, upewnij się, że podłączyłeś wejścia ASIO w panelu ustawień kX DSP. Sound Card Channel Mapping Mapowanie kanałów kart dźwiękowych For each Dla każdego input/output channel (Left and Right channel) a different actual sound card channel can be selected. kanał wejściowy/wyjściowy (kanał prawy i lewy) - mogą być wybrane różne kanały karty dźwiękowej. Left input channel selection combo box Pole wyboru lewego kanału wejściowego Right input channel selection combo box Pole wyboru prawego kanału wejściowego Left output channel selection combo box Pole wyboru lewego kanału wyjściowego Right output channel selection combo box Pole wyboru prawego kanału wyjściowego Enable Small Network Buffers Używaj małych buforów sieciowych If enabled, the support for very small network audio packets is activated. Very small network packets are only actually used if the sound card buffer delay is smaller than Jeśli jest włączona jest obsługa bardzo małych sieciowych pakietów audio. Bardzo małe pakiety sieciowe są rzeczywiście wykorzystywane tylko wtedy, gdy opóźnienie bufora karty dźwiękowej jest mniejsze niż Enable small network buffers check box Pole wyboru Włącz Małe Bufory Sieciowe Sound Card Buffer Delay Opóźnienie Bufora Karty Dźwiękowej The buffer delay setting is a fundamental setting of %1. This setting has an influence on many connection properties. Ustawienie bufora opóźnień jest kluczowe w programie %1. Ma to wpływ na wiele cech połączenia. Three buffer sizes are supported Obsługiwane są trzy wielkości buforów Some sound card drivers do not allow the buffer delay to be changed from within the application. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. On Windows, press the ASIO Device Settings button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Niektóre sterowniki kart dźwiękowych nie pozwalają na zmianę opóźnienia bufora z poziomu aplikacji. W tym przypadku ustawienie opóźnienia bufora jest wyłączone i musi zostać zmienione za pomocą sterownika karty dźwiękowej. W systemie Windows, naciśnij przycisk Ustawienia ASIO, aby otworzyć panel ustawień ASIO. W systemie Linux, aby zmienić rozmiar bufora użyj programu do konfiguracji serwera JACK. The buffer setting is therefore a trade-off between audio quality and overall delay. Wartość bufora odchyleń jest więc kompromisem pomiędzy jakością dźwięku a całkowitym opóźnieniem. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within the software. On Windows, press the ASIO Device Settings button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Jeśli ustawienia opóźnienia bufora są wyłączone, sterownik audio nie może modyfikować tego ustawienia z poziomu programu. W systemie Windows naciśnij przycisk Ustawienia ASIO, aby otworzyć panel ustawień sterownika. W systemie Linux, użyj narzędzia konfiguracyjnego JACK-a do zmiany rozmiaru bufora. Sound card driver settings Ustawienia sterownika karty dźwiękowej This opens the driver settings of your sound card. Some drivers allow you to change buffer settings, others like ASIO4ALL let you choose input or outputs of your device(s). More information can be found on jamulus.io. Otwiera ustawienia sterownika karty dźwiękowej. Niektóre sterowniki pozwalają na zmianę ustawień bufora, a inne, jak ASIO4ALL dają możliwość wyboru urządzenia dźwiękowego dla wejścia i wyjścia. Więcej informacji na stronie jamulus.io. Opens the driver settings. Note: Otwiera ustawienia sterownika. Wskazówka: currently only supports devices supporting a sample rate of aktualnie wspierane są tylko urządzenia dźwiękowe obsługujące częstotliwość próbkowania Hz. You will not be able to select a driver/device which doesn't. For more help see jamulus.io. Hz. Nie da się wybrać urządzenia/sterownika które tego nie obsługuje. Aby znaleźć więcej pomocy, zobacz stronę jamulus.io. If no buffer size is selected and all settings are disabled, this means a buffer size in use by the driver which does not match the values. %1 will still work with this setting but may have restricted performance. Gdy rozmiar bufora nie jest wybrany, a wszystkie ustawienia są zablokowane, oznacza to, że sterownik używa nieobsługiwanego rozmiaru bufora. %1 będzie działał z tymi ustawieniami ale jego fukcjonalność może być ograniczona. The actual buffer delay has influence on the connection, the current upload rate and the overall delay. The lower the buffer size, the higher the probability of a red light in the status indicator (drop outs) and the higher the upload rate and the lower the overall delay. Rzeczywiste opóźnienie bufora ma wpływ na status połączenia, bieżącą prędkość wysyłania i całkowite opóźnienie. Im mniejsza wielkość bufora, tym większe prawdopodobieństwo pojawienia się czerwonej kontrolki we wskaźniku statusu (drop-out) i tym większa szybkość wysyłania danych oraz tym mniejsze ogólne opóźnienie. 128 samples setting radio button przycisk wyboru 128-samplowego bufora 256 samples setting radio button przycisk wyboru 256-samplowego bufora Meter Style Styl miarki Select the meter style to be used for the level meters. The Narrow Bar and Small LEDs options only apply to the mixerboard. When Narrow Bar is selected, the input meters are set to Bar. When Small LEDs is selected, the input meters are set to Round LEDs. The remaining options apply to the mixerboard and input meters. Wybierz styl miarki używanej do poziomów. Opcje „Zwężony pasek” i „Mała dioda” mają zastosowanie tylko do miksera. Gdy zaznaczone jest „Zwęzony pasek” - wskaźniki wejścia są ustawione do paska. Zaznaczenie „Małej diody” spowoduje dopasowywanie wskaźników do diody. Pozostałe opcje mają zastosowanie zarówno do miksera jak i wskaźników wejścia. Meter Style combo box Lista wyboru stylu miarki Language Język Select the language to be used for the user interface. Wybierz język interfejsu użytkownika. Language combo box Lista wyboru języka Custom Directories Własne serwery If you need to add additional directories to the Connect dialog Directory drop down, you can enter the addresses here.<br>To remove a value, select it, delete the text in the input box, then move focus out of the control. Jeżeli potrzebujesz dodać dodatkowe serwery do listy w oknie połączeń, wpisz adresy tutaj.<br>Żeby usunąć wartość, zaznacz ją i skasuj, a następnie kliknij poza elementem listy. Custom Directories combo box Lista wyboru własnych serwerów Audio Upstream Rate Szybkość wysyłania audio Depends on the current audio packet size and compression setting. Make sure that the upstream rate is not higher than your available internet upload speed (check this with a service such as speedtest.net). Zależy od aktualnego rozmiaru bufora audio i wybranej jakości dźwięku. Upewnij się, że szybkość wysyłania nie jest wyższa niż dostępna u ciebie prędkość wychodząca (upload) połączenia internetowego (można to sprawdzić np. na speedtest.net). LEDs Diody Bar Pasek Narrow Bar Zawężony pasek Round LEDs Diody Small LEDs Małe diody None Brak Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country or region you are located in. Your city and skill level playing your instrument may also be added. Wpisz swoje imię lub przezwisko, żeby inni muzycy, z którymi chesz grać wiedzieli kim jesteś. Możesz także dodać ikonę instrumentu, na którym grasz oraz flagę kraju/regionu i miasto, z którego pochodzisz, a także poziom umiejętności. What you set here will appear at your fader on the mixer board when you are connected to a %1 server. This tag will also be shown at each client which is connected to the same server as you. To co zostanie tu wpisane pojawi się na suwaku miksera podczas połączenia z serwerem %1. Ta etykieta będzie także wyświetlana u innych muzyków podłączonych do tego samego serwera. Country/region flag button Przycisk wyboru flagi kraju/regionu Center Środek R P ASIO setup push button Przycisk ustawień ASIO Fancy Fantazyjna Compact Kompaktowa Audio Channels Kanały Audio Audio Device Urządzenie dźwiękowe Under the Windows operating system the ASIO driver (sound card) can be selected using %1. If the selected ASIO driver is not valid an error message is shown and the previous valid driver is selected. Under macOS the input and output hardware can be selected. W systemie operacyjnym Windows. można wybrać sterownik ASIO (kartę dźwiękową) używając %1-a. Jeśli wybrany sterownik ASIO nie jest prawidłowy, wyświetlany jest komunikat o błędzie i wybierany jest poprzedni prawidłowy sterownik. W systemie MacOS/Linux nie ma możliwości wyboru karty dźwiękowej przez Jamulus-a. For each %1 input/output channel (left and right channel) a different actual sound card channel can be selected. Może być wybrany inny kanał aktualnej karty dźwiękowej dla każdego wejściowego i wyjściowego strumienia programu %1 (prawy i lewy kanał). Enables support for very small network audio packets. These network packets are only actually used if the sound card buffer delay is smaller than %1 samples. The smaller the network buffers, the lower the audio latency. But at the same time the network load and the probability of audio dropouts or sound artifacts increases. Włącza obsługę bardzo małych pakietów internetowych z danymi audio. Właściwie to te małe pakiety są używane tylko jeżeli opóźnienie bufora jest mniejsze niż %1 sampli. Im mniejsze bufory sieciowe tym niższe opóźnienie audio ale jednocześnie zwiększa się obciążenie sieci i prawdopodobieństwo występowania przerw i zniekształceń dźwięku. Three buffer sizes can be selected Można wybrać spośród trzech różnych rozmairów bufora 64 samples: Provides the lowest latency but does not work with all sound cards. 64 sample: daje najmniejsze opóźnienie ale nie działa ze wszystkimi kartami dźwiękowymi. 256 samples: Should only be used when 64 or 128 samples is causing issues. 256 sample: używać tylko gdy 64 lub 128 powoduje problemy. Some sound card drivers do not allow the buffer delay to be changed from within %1. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. On Windows, use the ASIO Device Settings button to open the driver settings panel. On Linux, use the JACK configuration tool to change the buffer size. Niektóre sterowniki kart dźwiękowych nie pozwalają na zmianę bufora opoóźnień z poziomu %1-a. W takim przypadku te ustawienia są zablokowane i mogą być zmieniane tylko z poziomu sterownika karty dźwiękowej. W systemie Windows użyj przycisku ustawień ASIO aby otworzyć odpowiednie okno. W systemie Linux użyj programu do konfiguracji serwera JACK. If no buffer size is selected and all settings are disabled, this means an unsupported buffer size is in use by the driver. %1 will still work with this setting but may have restricted performance. Gdy rozmiar bufora nie jest wybrany, a wszystkie ustawienia są zablokowane, oznacza to, że sterownik używa nieobsługiwanego rozmiaru bufora. %1 będzie działał z tymi ustawieniami ale jego fukcjonalność może być ograniczona. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within %1. On Windows, press the ASIO Device Settings button to open the driver settings panel. On Linux, use the JACK configuration tool to change the buffer size. Jeżeli ustawienia opóźnienia bufora są zablokowane oznacza to, że sterownik audio nie pozwala na ich zmianę z poziomu %1-a. Aby otworzyć okno ustawień sterownika w systemie Windows - naciśnij przycisk ustawienia ASIO. W systemie Linux do zmiany bufora opóźnień użyj programu do konfiguracji serwera JACK. Some sound card drivers do not allow the buffer delay to be changed from within %1. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. Use the appropriate tool for the interface in use to adjust this buffer size. For example, if using ASIO, use the "ASIO Device Settings" button to open the driver settings panel or if using JACK, use a tool such as QjackCtl to adjust the buffer size. Other interfaces, such as Pipewire, would require their appropriate tool being used. Please refer to the interface manual. Niektóre sterowniki kart dźwiękowych nie pozwalają na zmianę opóźnienia bufora z poziomu %1. W tym przypadku ustawienie opóźnienia bufora jest wyłączone i musi zostać zmienione za pomocą sterownika karty dźwiękowej. Aby dopasować rozmiar bufora, użyj odpowiedniego narzędzia dla swojego sterownika. Na przykład dla sterownika ASIO, naciśnij przycisk „Ustawienia ASIO” aby otworzyć panel ustawień tego sterownika. Gdy używany jest JACK, do zmiany rozmiaru bufora można wykorzystać program QjackCtl. Inne interfejsy, takie jak np. PipeWire będą wymagały odpowiednio innego narzędzia. Szczegóły proszę sprawdzić w ich dokomentacji. This opens the driver settings of your sound card. Some drivers allow you to change buffer settings, others like ASIO4ALL lets you choose input or outputs of your device(s). More information can be found on jamulus.io. Otwiera ustawienia sterownika karty dźwiękowej. Niktóre sterowniki pozwalają na zmianę ustawień bufora, a inne jak ASIO4ALL pozwalają wybrać wejścia i wyjścia. Więcej informacji można znaleść na stronie jamulus.io. Opens the driver settings. Note: %1 currently only supports devices with a sample rate of %2 Hz. You will not be able to select a driver/device which doesn't. For more help see jamulus.io. Otwiera ustawienia sterownika. Uwaga: aktualnie %1 obsługuje tylko urządzenia z częstotliwością próbkowania %2 Hz. Nie będzie można wybrać sterownika/urządzenia nieobsługującego tej częstotliwośći. Więcej informacji można znaleść na stronie jamulus.io. Select the meter style to be used for the level meters. The Bar (narrow) and LEDs (round, small) options only apply to the mixerboard. When Bar (narrow) is selected, the input meters are set to Bar (wide). When LEDs (round, small) is selected, the input meters are set to LEDs (round, big). The remaining options apply to the mixerboard and input meters. Wybierz styl miarki używanej do poziomów. Opcje „Pasek” (zwężony) i „Diody” (małe, zaokrąglone) mają zastosowanie tylko do miksera. Gdy zaznaczony jest „Pasek” (zwężony) - wskaźniki wejścia są ustawione do paska (szeroki). Zaznaczenie „Diody” (małe) spowoduje dopasowywanie wskaźników do dużych diod. Pozostałe opcje mają zastosowanie zarówno do miksera jak i wskaźników wejścia. and i mode will increase your stream's data rate. Make sure your upload rate does not exceed the available upload speed of your internet connection. tryb ten zwiększy szybkość przesyłania danych w strumieniu. Upewnij się, że prędkość przesyłania danych nie przekracza dostępnej prędkości przesyłania połączenia internetowego. Audio channels combo box Pole wyboru kanałów audio Audio Quality Jakość Audio Audio quality combo box Pole ustawień jakości audio New Client Level Poziom nowego klienta New client level edit box Pole edycji poziomu nowego klienta Audio Alerts Alarmy dźwiękowe Enable audio alert when receiving a chat message and when a new client joins the session. A second sound device may be required to hear the alerts. Stosuj sygnały dźwiękowe dla przychodzących wiadomości czatu oraz kiedy dołącza nowy uczestnik sesji. Może być wymagane dodatkowe urządzenie dźwiękowe by je słyszeć. Audio Alerts check box Pole wyboru dla alarmów dźwiękowych Bar (narrow) Pasek (zwężony) Bar (wide) Pasek (szeroki) LEDs (stripe) Diody (pasek) LEDs (round, small) Diody (małe, zaokrąglone) LEDs (round, big) Diody (zaokrąglone, duże) Current Connection Status Parameter Wskaźnik aktualnego stanu połączenia If the ASIO4ALL driver is used, please note that this driver usually introduces approx. 10-30 ms of additional audio delay. Using a sound card with a native ASIO driver is therefore recommended. Jeśli używany jest sterownik ASIO4ALL, należy pamiętać, że zazwyczaj wprowadza on ok. 10-30 ms dodatkowego opóźnienia dźwięku. Dlatego zaleca się używanie karty dźwiękowej z natywnym sterownikiem ASIO. &Close &Zamknij Local Audio Input Fader Suwak Lokalnego Wejścia Audio Controls the relative levels of the left and right local audio channels. For a mono signal it acts as a pan between the two channels. For example, if a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows Kontroluje względne poziomy lewego i prawego lokalnego kanału audio. Na przykład, jeśli mikrofon jest podłączony do prawego kanału wejściowego, a instrument jest podłączony do lewego kanału wejściowego, który jest znacznie głośniejszy od mikrofonu, należy przesunąć suwak audio w kierunku, w którym pokazuje etykieta nad suwakiem L L , where , gdzie is the current attenuation indicator. jest wskaźnik aktualnego tłumienia. Local audio input fader (left/right) Suwak lokalnego wejścia audio The ASIO driver (sound card) can be selected using %1 under the Windows operating system. Under macOS/Linux, no sound card selection is possible. If the selected ASIO driver is not valid an error message is shown and the previous valid driver is selected. Sterownik ASIO (karta dźwiękowa) może być wybrany w %1-ie w systemie Windows. W systemach MacOs/Linux wybór karty dźwiękowej nie jest możliwy. Jeżeli wybrany sterownik ASIO nie jest poprawny wtedy wyświetlany jest komunikat błędu i poprzednio działający sterownik zostaje przywrócony. If the selected sound card device offers more than one input or output channel, the Input Channel Mapping and Output Channel Mapping settings are visible. Jeśli wybrane urządzenie karty dźwiękowej oferuje więcej niż jeden kanał wejściowy lub wyjściowy, widoczne są ustawienia Mapowanie Kanału Wejścia i Mapowanie Kanału Wejścia. samples. The smaller the network buffers, the lower the audio latency. But at the same time the network load increases and the probability of audio dropouts also increases. sample. Im mniejsze są bufory sieciowe, tym mniejsze jest opóźnienie dźwięku. Ale jednocześnie zwiększa się obciążenie sieci i prawdopodobieństwo przerw w transmisji dźwięku. The actual buffer delay has influence on the connection status, the current upload rate and the overall delay. The lower the buffer size, the higher the probability of a red light in the status indicator (drop outs) and the higher the upload rate and the lower the overall delay. Rzeczywiste opóźnienie bufora ma wpływ na status połączenia, bieżącą prędkość wysyłania i całkowite opóźnienie. Im mniejsza wielkość bufora, tym większe prawdopodobieństwo pojawienia się czerwonej kontrolki we wskaźniku statusu (drop-out) i tym większa szybkość wysyłania danych oraz tym mniejsze jest ogólne opóźnienie. 64 samples setting radio button przycisk wyboru 64-samplowego bufora ASIO Device Settings push button Przycisk ustawień ASIO Custom Directory Server Address Własny adres serwera zbiorczego Audio Upstream Rate depends on the current audio packet size and compression setting. Make sure that the upstream rate is not higher than your available internet upload speed (check this with a service such as speedtest.net). Prędkość wychodzącego strumienia audio zależy od ustawionej kompresji i rozmiaru ramki (mono/stereo). Upewnij się, że ta prędkość nie jest większa niż wyjściowa prędkość połączenia internetowego (można to sprawdzić np. przez speedtest.net). If this LED indicator turns red, you will not have much fun using the Jeśli ta dioda zmieni kolor na czerwony, może być utrudnione używanie software. . ASIO Setup Ustawienia ASIO Mono Mono Mono-in/Stereo-out Mono-in/Stereo-out Stereo Stereo Controls the relative levels of the left and right local audio channels. For a mono signal it acts as a pan between the two channels. For example, if a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows %1, where %2 is the current attenuation indicator. Kontroluje względne poziomy lewego i prawego lokalnego kanału audio. Na przykład, jeśli mikrofon jest podłączony do prawego kanału wejściowego, a instrument jest podłączony do lewego kanału wejściowego, który jest znacznie głośniejszy od mikrofonu, należy przesunąć suwak audio w kierunku, w którym %1 pokazuje etykietę nad suwakiem, gdzie %2 jest właściwym wskaźnikiem tego cichszego. The jitter buffer compensates for network and sound card timing jitters. The size of the buffer therefore influences the quality of the audio stream (how many dropouts occur) and the overall delay (the longer the buffer, the higher the delay). Bufor odchyleń kompensuje opóźnienia sieci i karty dźwiękowej. Rozmiar bufora ma zatem wpływ na jakość strumienia audio (ilość zakłóceń) i ogólne opóźnienie (im większy bufor, tym większe opóźnienie). You can set the jitter buffer size manually for the local client and the remote server. For the local jitter buffer, dropouts in the audio stream are indicated by the light below the jitter buffer size faders. If the light turns to red, a buffer overrun/underrun has taken place and the audio stream is interrupted. Można ręcznie ustawić rozmiar bufora odchyleń dla klienta lokalnego i zdalnego serwera. W przypadku lokalnego bufora, przerwy w strumieniu audio są sygnalizowane przez diodę poniżej suwaków bufora odchylenia. Zmiana koloru na czerwony, oznacza przekroczenie/zaniżenie bufora i strumień audio zostanie przerwany. If the Auto setting is enabled, the jitter buffers of the local client and the remote server are set automatically based on measurements of the network and sound card timing jitter. If Auto is enabled, the jitter buffer size faders are disabled (they cannot be moved with the mouse). Jeśli opcja Auto jest włączona, bufory odchylenia lokalnego klienta i zdalnego serwera są ustawiane automatycznie na podstawie pomiarów czasu trwania odchyleń sieci i karty dźwiękowej. Jeśli opcja Auto jest włączona, bufory są wyłączone (nie można ich przesuwać za pomocą myszy). If the Auto setting is enabled, the network buffers of the local client and the remote server are set to a conservative value to minimize the audio dropout probability. To tweak the audio delay/latency it is recommended to disable the Auto setting and to lower the jitter buffer size manually by using the sliders until your personal acceptable amount of dropouts is reached. The LED indicator will display the audio dropouts of the local jitter buffer with a red light. Jeśli opcja Auto jest włączone, bufory sieciowe klienta lokalnego i zdalnego serwera są ustawione na wartość zachowawczą, aby zminimalizować prawdopodobieństwo przerwania odtwarzania dźwięku. W celu dostrojenia opóźnienia dźwięku zaleca się wyłączenie ustawienia Auto i ręczne zmniejszenie rozmiaru bufora odchyleń za pomocą suwaków do momentu osiągnięcia zadawalającego poziomu zakłóceń. Dioda będzie sygnalizować czerwoną lampką przerwanie odtwarzania dźwięku w lokalnym buforze lokalnym. The buffer delay setting is a fundamental setting of this software. This setting has an influence on many connection properties. Ustawienie opóźnienia bufora jest podstawowym ustawieniem tego programu. To ustawienie ma wpływ na wiele właściwości połączenia. 64 samples: The preferred setting. Provides the lowest latency but does not work with all sound cards. 64 sample: preferowane ustawienie. Oferuje najniższe opóźnienie ale nie jest obsługiwane przez wszystkie karty dźwiękowe. 128 samples: Should work for most available sound cards. 128 sampli: powinno działać na większości z dostępnych kart dźwiękowych. 256 samples: Should only be used on very slow computers or with a slow internet connection. 256 sampli: używać tylko na bardzo słabych komputerach lub przy wolnych połączeniach internetowych. Some sound card drivers do not allow the buffer delay to be changed from within the application. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. On Windows, press the ASIO Setup button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Niektóre sterowniki kart dźwiękowych nie pozwalają na zmianę opóźnienia bufora z poziomu aplikacji. W tym przypadku ustawienie opóźnienia bufora jest wyłączone i musi zostać zmienione za pomocą sterownika karty dźwiękowej. W systemie Windows, naciśnij przycisk ASIO Setup, aby otworzyć panel ustawień sterownika. W systemie Linux, użyj programu do konfiguracji serwera JACK i zmiany rozmiaru bufora. If no buffer size is selected and all settings are disabled, an unsupported buffer size is used by the driver. The application will still work with this setting but with restricted performance. Jeżeli nie jest wybrany żaden rozmiar bufora i te ustawienia nie są dostępne, oznacza to, że sterownik używa niewspieranego rozmiaru bufora. Aplikacja będzie nadal działać z tym ustawieniem, ale jej wydajność będzie ograniczona. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within the software. On Windows, press the ASIO Setup button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Jeśli ustawienia opóźnienia bufora są wyłączone, sterownik audio nie może modyfikować tego ustawienia z poziomu programu. W systemie Windows naciśnij przycisk ASIO Setup, aby otworzyć panel ustawień sterownika. W systemie Linux, użyj narzędzia konfiguracyjnego Jack do zmiany rozmiaru bufora. Skin Skórka Select the skin to be used for the main window. Wybierz skórkę dla głównego okna aplikacji. Skin combo box Lista wyboru skórki Selects the number of audio channels to be used for communication between client and server. There are three modes available: Wybiera liczbę kanałów audio, które mają być używane do komunikacji między klientem a serwerem. Dostępne są trzy tryby: and i These modes use one and two audio channels respectively. Tryby te wykorzystują odpowiednio jeden i dwa kanały audio. Mono in/Stereo-out wejście mono/wyjście stereo The audio signal sent to the server is mono but the return signal is stereo. This is useful if the sound card has the instrument on one input channel and the microphone on the other. In that case the two input signals can be mixed to one mono channel but the server mix is heard in stereo. Sygnał audio wysyłany do serwera jest mono, ale sygnał zwrotny jest stereo. Jest to przydatne, jeśli karta dźwiękowa ma instrument na jednym kanale wejściowym i mikrofon na drugim. W tym przypadku dwa sygnały wejściowe mogą być miksowane do jednego kanału mono, ale miks serwera jest słyszalny w trybie stereo. Enabling Włączanie In stereo streaming mode, no audio channel selection for the reverb effect will be available on the main window since the effect is applied to both channels in this case. W trybie strumieniowania stereo w oknie głównym nie będzie dostępny wybór kanału audio dla efektu pogłosu, ponieważ w tym przypadku efekt jest stosowany do obu kanałów. The higher the audio quality, the higher your audio stream's data rate. Make sure your upload rate does not exceed the available bandwidth of your internet connection. Im wyższa jakość dźwięku, tym większa szybkość transmisji danych strumienia audio. Upewnij się, że prędkość przesyłania danych nie przekracza dostępnej przepustowości połączenia internetowego. This setting defines the fader level of a newly connected client in percent. If a new client connects to the current server, they will get the specified initial fader level if no other fader level from a previous connection of that client was already stored. To ustawienie definiuje poziom sygnału nowo podłączonego klienta w procentach. Jeśli nowy klient połączy się z aktualnym serwerem, otrzyma ten początkowy poziom sygnału, o ile żaden inny poziom z poprzedniego połączenia tego klienta nie był wcześniej zapisany. Input Boost Wzmocnienie Wejścia This setting allows you to increase your input signal level by factors up to 10 (+20dB). If your sound is too quiet, first try to increase the level by getting closer to the microphone, adjusting your sound equipment or increasing levels in your operating system's input settings. Only if this fails, set a factor here. If your sound is too loud, sounds distorted and is clipping, this option will not help. Do not use it. The distortion will still be there. Instead, decrease your input level by getting farther away from your microphone, adjusting your sound equipment or by decreasing your operating system's input settings. Ta opcja pozwala na stopniowe zwiększenie poziomu twojego sygnału wejściowego aż do 10 (+20dB). Kiedy twój dźwięk jest zbyt cichy, najpierw spróbuj zwiększyć głośność zbliżając się do mikrofonu, ustawiając lepiej sprzęt audio lub zwiększając poziomy w ustawieniach wejścia dźwięku w swoim systemie operacyjnym. Dopiero gdy wszystko powyższe zawiedzie, ustaw to wzmocnienie tutaj. Jednak gdy twój dźwięk jest zbyt głośny, zniekształcony lub urywany, ta opcja nie pomoże. Wtedy jej nie używaj. Zniekształcenia i tak pozostaną. Zamiast tego obniż poziom sygnału wejściowego odsuwając się od mikrofonu, zmieniając ustawienia twoich urządzeń dźwiękowych lub ściszając poziomy wejścia w swoim systemie. Input Boost combo box Kontrolka Wzmocnienia Wejścia Leave this blank unless you need to enter the address of a directory server other than the default. Należy pozostawić to pole puste, chyba że konieczne jest wprowadzenie adresu serwera innego niż domyślny. Directory server address combo box Lista wyboru serwera zbiorczego The Ping Time is the time required for the audio stream to travel from the client to the server and back again. This delay is introduced by the network and should be about 20-30 ms. If this delay is higher than about 50 ms, your distance to the server is too large or your internet connection is not sufficient. Czas Ping Time to czas potrzebny do przejścia strumienia audio z klienta do serwera i z powrotem. Opóźnienie to jest wprowadzane przez sieć i powinno wynosić około 20-30 ms. Jeśli opóźnienie to jest większe niż około 50 ms, odległość do serwera jest zbyt duża lub połączenie internetowe nie jest wystarczające. Overall Delay is calculated from the current Ping Time and the delay introduced by the current buffer settings. Całkowite opóźnienie jest obliczane na podstawie bieżącego czasu ping i opóźnienia wprowadzonego przez bieżące ustawienia bufora. Number of Mixer Panel Rows Liczba rzędów panelu miksera Adjust the number of rows used to arrange the mixer panel. Dostosuj liczbę rzędów w panelu miksera. Number of Mixer Panel Rows spin box Pole wyboru liczby rzędów panelu miksera Feedback Protection Ochrona przed sprzęganiem Enable feedback protection to detect acoustic feedback between microphone and speakers. Wykrywaj sprzężenia akustyczne między miktofonem a głośnikami. Feedback Protection check box Pole wyboru wykrywania sprzężeń ASIO Device Settings Ustawienia urządzeń ASIO Low Niska Normal Standardowa High Wysoka Custom Własny All Genres Wszystkie style Any Genre 2 Każdy styl 2 Any Genre 3 Każdy styl 3 Genre Rock Rock Genre Jazz Jazz Genre Classical/Folk Klasyka/folk Genre Choral/Barbershop Chór/zespół wokalny Any Genre 1 Każdy styl 1 Genre Classical/Folk/Choral Klasyka/Folk/Chór Default Domyślny preferred preferowany Musician Profile Profil muzyka Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country you are located in. Your city and skill level playing your instrument may also be added. Wpisz swoje imię lub przezwisko, żeby inni muzycy, z którymi chesz grać wiedzieli kim jesteś. Możesz także dodać ikinę instrumentu na którym grasz oraz flagę kraju i miasto, z którego pochodzisz, a także poziom umiejętności. What you set here will appear at your fader on the mixer board when you are connected to a Jamulus server. This tag will also be shown at each client which is connected to the same server as you. Podane tutaj informacje pojawią się przy twoim suwaku na mikserze w czasie połączenia z serwerem Jamulus-a. Taka etykieta pokaże się także u każdego uczestnika podłączonego do tego samego serwera. Alias or name edit box Pole edycji nazwy lub pseudonimu Instrument picture button Przycisk wyboru instrumentu Country flag button Przycisk wyboru flagi City edit box Pole edycji miasta Skill level combo box Lista wyboru poziomu umiejętności Beginner Początkujący Intermediate Średniozaawansowany Expert Ekspert Size: Rozmiar: Buffer Delay Opóźnienie bufora Buffer Delay: Opóźnienie bufora: The selected audio device could not be used because of the following error: Wybrane urządzenie audio nie mogło być użyte z powodu następującego błędu: The previous driver will be selected. Został wybrany poprzedni sterownik. Ok Ok Drum Set Zestaw perkusyjny Djembe Djembe Electric Guitar Gitara elektryczna Acoustic Guitar Gitara akustyczna Bass Guitar Gitara basowa Keyboard Klawisze Synthesizer Syntezator Grand Piano Fortepian Accordion Akordeon Vocal Śpiew Microphone Mikrofon Harmonica Harmonijka ustna Trumpet Trąbka Trombone Puzon French Horn Waltornia Tuba Tuba Saxophone Saksofon Clarinet Klarnet Flute Flet Violin Skrzypce Cello Wiolonczela Double Bass Kontrabas Recorder Rejestrator Streamer Streamer Listener Słuchacz Guitar+Vocal Gitara+Śpiew Keyboard+Vocal Keyboard+Śpiew Bodhran Bodhran Bassoon Fagot Oboe Obój Harp Harfa Viola Altówka Congas Kongi Bongo Bongo Vocal Bass Bas Vocal Tenor Tenor Vocal Alto Alt Vocal Soprano Sopran Banjo Banjo Mandolin Mandolina Ukulele Ukulele Bass Ukulele Ukulele basowe Vocal Baritone Baryton Vocal Lead Wokal prowadzący Mountain Dulcimer Cymbały górskie Scratching Scratch Rapping Rapowanie Vibraphone Wibrafon Conductor Dyrygent CClientSettingsDlgBase Settings Ustawienia Soundcard Karta dźwiękowa Device Urządzenie Input Channel Mapping Mapowanie kanału wejścia L L R P Output Channel Mapping Mapowanie kanału wyjścia Enable Small Network Buffers Zezwalaj na małe bufory sieciowe Buffer Delay Opóźnienie bufora Country/Region Kraj/Region (preferred) (preferowane) (default) (domyślne) (safe) (bezpieczne) Driver Setup Konfiguracja sterownika My Profile Mój profil Musician's Profile Profil muzyka Alias/Name Imię/przezwisko Instrument Instrument Country Kraj City Miasto Skill Umiejętności User Interface Interfejs użytkownika Meter Style Styl miarki Mixer Rows Rzędy miksera Audio Alerts Alarmy dźwiękowe Audio/Network Setup Ustawienia dźwięku/sieci Audio Device Urządzenie dźwiękowe Jitter Buffer Bufor odchyleń Auto Automatyczny Local Lokalny Server Serwer Size Rozmiar kbps kbps Custom Directories: Serwery zbiorcze: Input Boost Wzmocnienie wejścia Feedback Protection Ochrona przed sprzęganiem Enable Zastosuj Input Balance Balans wejściowy Pan Panorama Center Środek Misc Różne Audio Channels Kanały audio Audio Quality Jakość audio Measurements Miara Advanced Setup Ustawienia zaawansowane Custom Central Server Address: Własny Adres Serwera Zbiorczego: New Client Level Poziom dołączającego się uczestnika Skin Skórka Language Język % % Custom Directory Server Address: Własny adres serwera centralnego: Audio Stream Rate Prędkość strumienia audio val wartość Ping Time Czas odpowiedzi Overall Delay Opóźnienie całkowite Local Jitter Buffer Lokalny bufor odchyleń CConnectDlg Directory Serwer Shows the servers listed by the selected directory. You can add custom directories in Advanced Settings. Wyświetla serwery z wybranego katalogu. Można dodać własne katalogi w „Ustawieniach zaawansowanych”. Directory combo box Lista wyboru katalogu Filters the server list by the given text. Note that the filter is case insensitive. A single # character will filter for those servers with at least one person connected. Tekst filtrujący listę serwerów. Filtr rozróżnia wielkość znaków. Pojedynczy znak # będzie filtrował serwery z podłączoną co najmniej jedną osobą. Uncheck to collapse the server list to show just the server details. Check to show everyone on the servers. Odznacz aby lista pokazywała tylko szczcegóły serwera. Zaznzcz, żeby wyświetlić wszystkich na serwerze. Server List Lissta serwerów The Connection Setup window lists the available servers registered with the selected directory. Use the Directory dropdown to change the directory, find the server you want to join in the server list, click on it, and then click the Connect button to connect. Alternatively, double click on the server name to connect. Okno ustawień połączenia wyświetla dostępne serwery zarejstrowane w wybranym katalogu. Użyj listy wyboru katalogu serwerów, znajdź serwer do którego chcesz się dołączyć, kliknij wybrany serwer na liście, a potem kliknij przycisk „Połącz” aby połączyć. Ewentualnie kliknij podwójnie w serwer na liście żeby połączyć się od razu. Permanent servers (those that have been listed for longer than 48 hours) are shown in bold. Stałe serwery (te które są na liście od ponad 48 godzin) wypisane są pogrubionym tekstem. You can add custom directories in Advanced Settings. Możesz dodać własne katalogi serwerów w zaawansowanych ustawieniach. Server list view Podgląd listy serwerów Server Address Adres serwera If you know the server address, you can connect to it using the Server name/Address field. An optional port number can be added after the server address using a colon as a separator, e.g. %1. The field will also show a list of the most recently used server addresses. Jeżeli znasz adres serwera możesz podłączyć się do niego podając te dane w polu nazwa/adres serwera. Dodatkowo może być podany numer portu - po dwukropku za adresem/numerem IP, np. %1. To pole tekstowe będzie także wyświetlać listę ostatnio używanych adresów. Holds the current server address. It also stores old addresses in the combo box list. Zatrzymuje aktualny adres serwera. Przechowuje również stare adresy na liście. The Connection Setup window shows a list of available servers. Server operators can optionally list their servers by music genre. Use the List dropdown to select a genre, click on the server you want to join and press the Connect button to connect to it. Alternatively, double click on on the server name. Permanent servers (those that have been listed for longer than 48 hours) are shown in bold. *nie jestem pewna Okno ustawień połączenia pokazuje listę dostępnych serwerów. Operatorzy serwerów mogą opcjonalnie wyświetlać swoje serwery według gatunków muzycznych. Użyj listy wyboru, aby wybrać gatunek, wybierz serwer, do którego chcesz się połączyć i wciśnij przycisk Połącz. Ewentualnie, podwójne kliknij na nazwę serwera. Stałe serwery (te, które są na liście od ponad 48 godzin) są zaznaczone pogrubioną czcionką. If you know the IP address or URL of a server, you can connect to it using the Server name/Address field. An optional port number can be added after the IP address or URL using a colon as a separator, e.g. example.org: Jeżeli znasz adres IP lub URL serwera, możesz się połączyć używając pola Nazwa/Adres Serwera. Opcjonalny numer portu może być dodany po adresie IP lub adresie URL za pomocą dwukropka jako separatora, np. example.org: . The field will also show a list of the most recently used server addresses. . Pole pokazuje również listę niedawno używanych serwerów. Server address edit box Pole edycji adresu serwera Holds the current server IP address or URL. It also stores old URLs in the combo box list. *nie jestem pewna Zatrzymuje aktualny adres IP lub adres URL serwera. Przechowuje również stare adresy URL na liście. Server List Selection *nie jestem pewna Wybór listy serwerów Selects the server list to be shown. *nie jestem pewna Wybierz listę serwerów, aby rozwinąć. Server list selection combo box *nie jestem pewna (server list selection ma podobne tłumaczenie) Pole wyboru listy serwerów Filter Filtr The server list is filtered by the given text. Note that the filter is case insensitive. Będą wyświetlane tylko serwery, których nazwy zawierają wprowadzony tekst. Uwaga: filtrowanie nie rozróżnia wielkości liter. Filter edit box Pole edycji filtra Show All Musicians Pokaż wsztystkich muzyków Pokaż wszystkich muzyków If you check this check box, the musicians of all servers are shown. If you uncheck the check box, all list view items are collapsed. Jeśli zaznaczysz to pole wyboru, zostaną pokazani muzycy wszystkich serwerów. Jeśli odznaczysz to pole wyboru, wszystkie elementy widoku listy zostaną zwinięte. Show all musicians check box *nie jestem pewna Pokaż wszystkim muzykom pole wyboru If you know the IP address or URL of a server, you can connect to it using the Server name/Address field. An optional port number can be added after the IP address or URL using a colon as a separator, e.g. %1. The field will also show a list of the most recently used server addresses. Jeżeli znasz adres IP lub URL serwera możesz podłączyć się do niego podając te dane w polu nazwa/adres serwera. Dodatkowo może być podany numer portu - po dwukropku za adresem/numerem IP, np. %1. To pole tekstowe będzie także wyświetlać listę ostatnio używanych adresów. Filter text, or # for occupied servers Tekst filtra lub # żeby widzieć używane serwery Type # for occupied servers Wpisz # żeby widzieć zajęte serwery CConnectDlgBase Connection Setup Konfiguracja połączenia List Lista Directory Serwer Filter Filtr Show All Musicians Pokazuj wszystkich muzyków Server Name Nazwa serwera Ping Time Czas odpowiedzi Musicians Muzycy Location Lokalizacja Server Address Adres serwera C&ancel &Anuluj &Connect &Połącz CHelpMenu &Help P&omoc Getting &Started... &Zaczynajmy... Software &Manual... &Instrukcja programu... What's &This &Co to jest &About Jamulus... &O programie Jamulus... About &Qt... O &Qt... &About... &O programie... About Qt O Qt CLanguageComboBox Restart Required Wymagany restart Please restart the application for the language change to take effect. Aby wprowadzić zmianę języka, proszę uruchomić program ponownie. CLicenceDlg This server requires you accept conditions before you can join. Please read these in the chat window. Zanim dołączysz, ten serwer wymaga akceptacji warunków korzystania. Proszę je przeczytać w oknie czatu. I have read the conditions and &agree. Zapoznałem się z zasadami i &akceptuję. Accept Zgadzam się Decline Odrzucam CMultiColorLED Red Czerwony Yellow Żółty Green Zielony CMusProfDlg Musician Profile Profil muzyka Alias/Name Nick/Imię Instrument Instrument Country Kraj City Miasto Skill Umiejętności &Close &Zamknij None Żaden Beginner Początkujący Intermediate Średniozaawansowany Expert Ekspert Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country you are located in. Your city and skill level playing your instrument may also be added. Wpisz swoje imię lub przezwisko, żeby inni muzycy, z którymi chesz grać wiedzieli kto to. Także możesz dodać obrazek instrumentu na którym grasz i flagę kraju i miasto, z którego pochodzisz, a także poziom umiejętności. What you set here will appear at your fader on the mixer board when you are connected to a Jamulus server. This tag will also be shown at each client which is connected to the same server as you. Podane tutaj informacje pojawią się przy twoim suwaku na mikserze w czasie połączenia z serwerem Jamulus-a. Taka etykieta pokaże się także u każdego uczestnika podłączonego do tego samego serwera. Alias or name edit box Pole edycji nazwy lub pseudonimu Instrument picture button Przycisk wyboru instrumentu Country flag button Przycisk wyboru flagi City edit box Pole edycji miasta Skill level combo box Lista wyboru poziomu umiejętności Drum Set Zestaw perkusyjny Djembe Djembe Electric Guitar Gitara elektryczna Acoustic Guitar Gitara akustyczna Bass Guitar Gitara basowa Keyboard Keyboard Synthesizer Syntezator Grand Piano Fortepian Accordion Akordeon Vocal Wokal Microphone Mikrofon Harmonica Harmonijka ustna Trumpet Trąbka Trombone Puzon French Horn Waltornia Tuba Tuba Saxophone Saksofon Clarinet Klarnet Flute Flet Violin Skrzypce Cello Wiolonczela Double Bass Kontrabas Recorder Flet prosty Streamer Streamer Listener Słuchacz Guitar+Vocal Gitara+Wokal Keyboard+Vocal Keyboard+Wokal Bodhran Bodhran Bassoon Fagot Oboe Obój Harp Harfa Viola Altówka Congas Kongi Bongo Bongo Vocal Bass Bas Vocal Tenor Tenor Vocal Alto Alt Vocal Soprano Sopran Banjo Banjo Mandolin Mandolina Ukulele Ukulele Bass Ukulele Ukulele basowe Vocal Baritone Baryton Vocal Lead Wokal prowadzący Mountain Dulcimer Cymbały górskie Scratching Scratch Rapping Rapowanie No Name Brak nazwy CServerDlg Client List Lista użytkowników The client list shows all clients which are currently connected to this server. Some information about the clients like the IP address and name are given for each connected client. Lista użytkowników wyświetla wszystkich użytkowników obecnie połączonych z tym serwerem. Informacje takie jak IP użytkownika oraz nazwa są wyświetlane dla każdego połączonego użytkownika. Connected clients list view Widok listy podłączonych użytkowników Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user %1 is running as). Kliknij przycisk aby otworzyć okno dialogowe wyboru głownego katalogu nagrywania. Wybrana ścieżka musi istnieć i mieć ustawione prawo do zapisu i tworzenia podkatalogów przez użytkownika uruchamiającego %1. The current value of the main recording directory. The chosen value must exist and be writeable (allow creation of sub-directories by the user %1 is running as). Click the button to open the dialog that allows the main recording directory to be selected. Aktualny głowny katalog nagrywania. Wybrana ścieżka musi istnieć i mieć ustawione prawo do zapisu i tworzenia podkatalogów przez użytkownika uruchamiającego %1. Kliknij przycisk aby otworzyć okno dialogowe wyboru głownego katalogu nagrywania. Custom Directory address Własny adres serwera zbiorczego The Custom Directory address is the address of the directory holding the server list to which this server should be added. Własny adres serwera zbiorczego to adres serwera, na którym zarządzana jest lista serwerów w oknie dialogowym połączenia. Server List Filename dialog push button Przycisk dla nazwy pliku z listą serwerów Server List Filename Nazwa pliku z listą serwerów Click the button to open the dialog that allows the server list persistence file name to be set. The user %1 is running as needs to be able to create the file name specified although it may already exist (it will get overwritten on save). Otwiera okno dialogowe wyboru nazwy pliku z listą serwerów. Użytkownik uruchamiający %1-a musi mieć prawo do tworzenia plików (gdy plik już istnieje, zostanie nadpisany). Server List Filename text box (read-only) Pole tekstowe z nazwą pliku listy serwerów (tylko do odczytu) The current value of server list persistence file name. The user %1 is running as needs to be able to create the file name specified although it may already exist (it will get overwritten on save). Click the button to open the dialog that allows the server list persistence file name to be set. Obecna nazwa pliku z listą serwerów. Użytkownik uruchamiający %1-a musi mieć prawo do tworzenia plików (gdy plik już istnieje, zostanie nadpisany). Naciśnij przycisk aby otwierzyć okno dialogowe wyboru nazwy pliku z listą serwerów. Clear the server list file name button Przycisk kasowania nazwy pliku z listą serwerów Clear Server List Filename Wyczyść nazwę pliku z listą serwerów Click the button to clear the currently selected server list persistence file name. This will prevent persisting the server list until a new value is selected. Naciśnij aby wyczyść nazwę pliku z listą serwerów. Lista serwerów nie będzie isnieć dopóki nie zostanie podana nowa nazwa. Start Minimized on Operating System Start Uruchom w tle przy włączeniu systemu operacyjnego Make My Server Public Ustaw serwer jako publiczny Register Server Status Zarejetruj status serwera If the Make My Server Public check box is checked, this will show whether registration with the directory server is successful. If the registration failed, please choose another server list. Jeśli pole wyboru Ustaw serwer jako publiczny jest zaznaczone, pokazuje, czy rejestracja na zbiorczcym serwerze zakończyła się sukcesem. Jeśli rejestracja nie powiodła się, wybierz inny serwer z listy. Custom Directory Server Address Własny adres serwera zbiorczego The custom directory server address is the IP address or URL of the directory server at which the server list of the connection dialog is managed. Niestandardowy adres serwera zbiorczego to adres IP lub adres URL serwera, na którym zarządzana jest lista serwerów w oknie dialogowym połączenia. Directory server address line edit Linia edycji adresu serwera zbiorczego Server List Selection Wybór listy serwerów Selects the server list (i.e. directory server address) in which your server will be added. Wybiera adres serwera (np. adres serwera zbiorczego), na listę którego zostanie dodany nasz serwer. Server list selection combo box Pole wyboru listy serwerów Server Name Nazwa serwera Server name line edit Pole edycji nazwy serwera Location City Lokalizacja serwera - miasto The city in which this server is located can be set here. If a city name is entered, it will be shown in the connect dialog server list at the clients. W tym okne można ustawić nazwę miasta, w którym znajduje się serwer. Jeżeli nazwa miasta jest wprowadzona, zostanie wyświetlona w oknie dialogowym połączenia, na liście dostępnych serwerów. City where the server is located line edit Pole wyboru miasta, w którym zlokalizowany jest serwer Location country Lokalizacja serwera - kraj The country in which this server is located can be set here. If a country is entered, it will be shown in the connect dialog server list at the clients. W tym okne można ustawić nazwę kraju, w którym znajduje się serwer. Jeżeli nazwa kraju jest wprowadzona, zostanie wyświetlona na liście serwerów dialogowych połączeń u klientów. Country where the server is located combo box Pole wyboru kraju, w którym zlokalizowany jest serwer Display dialog to select recording directory button Wyświetla okno wyboru katalogu nagrywania Main Recording Directory Główny katalog nagrywania Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user Jamulus is running as). Kliknij przycisk aby otworzyć okno dialogowe wyboru głownego katalogu nagrywania. Wybrana ścieżka musi istnieć i mieć ustawione prawo do zapisu i tworzenia podkatalogów przez użytkownika uruchamiającego Jamulus-a. Main recording directory text box (read-only) Pole tekstowe katalogu nagrywania (tylko do odczytu) The current value of the main recording directory. The chosen value must exist and be writeable (allow creation of sub-directories by the user Jamulus is running as). Click the button to open the dialog that allows the main recording directory to be selected. Aktualny głowny katalog nagrywania. Wybrana ścieżka musi istnieć i mieć ustawione prawo do zapisu i tworzenia podkatalogów przez użytkownika uruchamiającego Jamulus-a. Kliknij przycisk aby otworzyć okno dialogowe wyboru głownego katalogu nagrywania. Clear the recording directory button Przycisk czyszczenia katalogu nagrywania Clear Recording Directory Wyczyść katalog nagrywania Click the button to clear the currently selected recording directory. This will prevent recording until a new value is selected. Naciśnij przycisk aby wyczyścić wybraną ścieżkę katalogu. Nagrywanie będzie niemożliwe dopóki nowa ścieżka nie zostanie podana. Checkbox to turn on or off server recording Pole wyboru do włączania lub wyłączania nagrywania na serwerze If the Register Server check box is checked, this will show whether registration with the directory server is successful. If the registration failed, please choose another server list. Jeżeli pole wyboru „Rejestruj serwer” jest zaznaczone, wyświetli się komunikat o powowdzeniu rejestracji na serwerze. Gdy rejestracja się nie uda, proszę wybrać inny katalog serwerów. Enable Recorder Nagrywanie włączone Checked when the recorder is enabled, otherwise unchecked. The recorder will run when a session is in progress, if (set up correctly and) enabled. Zaznaczone kiedy nagrywanie jest możliwe. Nagrywanie rozpocznie się razem z sesją, jeżeli jest ustawione prawidłowo i dostępne. Current session directory text box (read-only) Pole tekstowe aktualnego katalogu sesji (tylko do odczytu) Current Session Directory Katalog sesji bieżących Enabled during recording and holds the current recording session directory. Disabled after recording or when the recorder is not enabled. Dostępne podczas nagrywania, przechowuje ścieżkę do aktualnego katalogu nagrywania. Wyłączone po nagraniu lub gdy rejestrator nie jest włączony. Recorder status label Etykieta statusu nagrywania Directory Type combo box Lista wyboru typu serwera Directory Serwer Select '%1' not to register your server with a directory. Zaznacz „%1” żeby nie rejestrować twojego serwera w katalogu zbiorczym. Select one of the genres to register with that directory. Wybierz który ze stylów zostanie zajejstrowany z tym serwerem. Or select '%1' and specify a Custom Directory address on the Options tab to register with a custom directory. Lub zaznacz „%1” i podaj adres własnego serwera zbiorczego na karcie Opcje żeby zarejstrować razem z nim. For any value except '%1', this server registers with a directory so that a %2 user can select this server in the client connect dialog server list when they choose that directory. Ten serwer zostanie zarejstrowany w katalogu zbiorczym dla każdego wpisu oprócz „%1”, więc użytkonik %2-a będzie mógł go zaznaczyć w oknie połączenia kiedy wybierze ten katalog zbiorczy. The registration of the server is renewed periodically to make sure that all servers in the connect dialog server list are actually available. Rejestracja serwerów jest odnawiana okresowo żeby mieć pweność, że wszystkie serwery na liście są dostępne. When a value other than "%1" is chosen for Directory, this will show whether registration is successful. If the registration failed, please choose a different directory. Kiedy podana nazwa jest różna niż „%1” zostanie wyświetlone czy rejestracja się powiodła. Gdy się nie powiedzie, proszę wybrać inny katalog serwerów. Recorder Status Status nagrywania No recording directory has been set or the value is not useable. Check the value in the Options tab. Nie wybrano katalogu nagrywania lub nie da się go używać. Proszę sprawdzić na karcie Opcje. Recording has been switched off by the UI checkbox. Nagrywanie zostało wyłączone przez użytkownika. Recording has been switched off, either by the UI checkbox or SIGUSR2 being received. Nagrywanie zostało wyłączone przez użytkownika lub otrzymano komunikat SIGUSR2. If the recording directory is not useable, the problem will be displayed in place of the session directory. Gdy nie da się używać katalogu nagrywania, zostanie to wyświetlone w miejscu katalogu sesji. Language Język Select the language to be used for the user interface. Wybierz język interfejsu użytkownika. Language combo box Lista wyboru języka Now a directory Bieżący serwer Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user Jamulus is running as). Kliknij przycisk aby otworzyć okno dialogowe wyboru głownego katalogu nagrywania. Wybrana ścieżka musi istnieć i mieć ustawione prawo do zapisu i tworzenia podkatalogów przez użytkownika uruchamiającego Jamulus-a. Custom Directory Własny katalog serwerów The custom directory is the IP address or URL of the directory server at which the server list of the connection dialog is managed. Niestandardowy adres serwera zbiorczego to adres IP lub adres URL serwera, na którym zarządzana jest lista serwerów w oknie dialogowym połączenia. Custom Directory line edit Pole edycji własnych serwerów &Hide %1 server &Ukryj serwer %1 &Show %1 server &Pokaż serwer %1 %1 server %1 is the name of the main application serwer %1-a %1 Server %1 is the name of the main application Serwer %1-a Recorder failed to start. Please check available disk space and permissions and try again. Error: Nie dało się nagrywać. Sprawdź dostępne miejsce na dysku i prawa dostępu i spróbuj ponownie. Błąd: Select Main Recording Directory Wybierz katalog nagrywania ERROR BŁĄD Request new recording button Nowy przycisk nagrywania New Recording Nowe nagranie During a recording session, the button can be used to start a new recording. Podczas sesji nagraniowej można użyć przycisku w celu rozpoczęcia nowego nagrania. E&xit &Wyjdź &Hide &Zminimalizuj server serwer &Open &Otwórz Recording Nagrywanie włączone Not recording Nagrywanie wyłączone Not initialised Nie rozpoczęte Not enabled Niedostępny Server Serwer If the start minimized on operating system start check box is checked, the server will be started when the operating system starts up and is automatically minimized to a system task bar icon. Jeśli pole wyboru start zminimalizowany na starcie systemu operacyjnego jest zaznaczone, serwer zostanie uruchomiony po uruchomieniu systemu operacyjnego i zostanie automatycznie zminimalizowany do ikony paska zadań systemowych. If the Make My Server Public check box is checked, this server registers itself at the directory server so that all users of the application can see the server in the connect dialog server list and connect to it. The registration of the server is renewed periodically to make sure that all servers in the connect dialog server list are actually available. Jeśli pole wyboru „Ustaw serwer jako publiczny” jest zaznaczone, serwer ten rejestruje się na serwerze zbiorczym, tak aby wszyscy użytkownicy aplikacji mogli zobaczyć go na liście i połączyć się z nim. Rejestracja serwera jest okresowo odnawiana, aby upewnić się, że wszystkie serwery na liście są rzeczywiście dostępne. The server name identifies your server in the connect dialog server list at the clients. Nazwa serwera identyfikuje twój serwer w oknie dialogowym połączenia na liście dostępnych serwerów. Country/Region Kraj/Region Set the country or region where the server is running. Clients will show this location in their connect dialog's server list. Ustaw kraj lub region gdzie znajduje się serwer. Inni będą widzieć tą nazwę lokalizacji w oknie z listą serwerów. Combo box for location of this server Lista rozwijana położenia tego serwera Displays the current status of the recorder. The following values are possible: Wyświetla aktualny stan nagrywania. Możliwe są następujące wartości: No recording directory has been set or the value is not useable. Nie wybrano katalogu nagrywania lub nie da się go używać. Recording has been switched off Nagrywanie zostało wyłączone by the UI checkbox w polu wyboru ustawień , either by the UI checkbox or SIGUSR2 being received , albo przez pole wyboru lub sygnał SIGUSR2 There is no one connected to the server to record. Nikt nie jest podłączony do serwera żeby nagrywać. The performers are being recorded to the specified session directory. Wykonawcy są nagrywani do wybranego katalogu. NOTE UWAGA If the recording directory is not useable, the problem will be displayed in place of the directory. Jeżeli nie da się korzystać z katalogu nagrywania, problem będzie wyświetlony zamiast ściżki. Server welcome message edit box Pole edycji tekstu powitania na serwerze Server Welcome Message Tekst powitania na serwerze A server welcome message text is displayed in the chat window if a musician enters the server. If no message is set, the server welcome is disabled. Tekst powitania pojawi się w oknie czatu kidy muzyk połaczy sie z serwerem. Jeżli tekst nie jest podany okno czatu nie zostanie wyświetlone po połączeniu. Type a message here. If no message is set, the server welcome is disabled. Wpisz tutaj tekst. Jeżli tekst nie jest podany okno czatu nie zostanie wyświetlone po połączeniu. software upgrade available dostępna aktualizacja oprogramowania &Window &Okno Unregistered Niezarejstrowany None Brak Not registered Nie zarejstrowany Bad address Błędny adres Registration requested Wymagana rejestracja Registration failed Rejestraca nie powiodła się Check server version Sprawdź wersję serwera Registered Zarejestrowany Directory server list full Serwer zbiorczy jest zapełniony Directory Server full Serwer zbiorczy zapełniony Your server version is too old Wersja twojego serwera jest przestarzała Requirements not fulfilled Niespełniono wymagań Unknown value %1 Nieznana wartość %1 Unknown value Nieznana wartość CServerDlgBase Client IP:Port IP użytkownika:port Name Nazwa Jitter Buffer Size Rozmiar bufora odchyleń Channels Kanały Server Setup Ustawienia serwera Genre Styl Directory Serwer Enable Jam Recorder Zezwalaj na nagrywanie sesji New Recording Nowe nagranie Session Sesja Chat Window Welcome (HTML/CSS Supported) Powitanie w oknie czatu (obsługiwane HTML/CSS) Options Opcje Language Consider add "(Lang)" as a suffix to ensure that users who selected the wrong language find the correct button Język Recording Directory Katalog nagrywania Custom Directory address Adres własnego serwera zbiorczego Server List Filename Nazwa pliku z listą serwerów Start Minimized on Windows Start Uruchom w tle przy starcie systemu Windows Enable delay panning Opóźnienie panoramy Update check Sprawdź uaktualnienia Make My Server Public (Register My Server in the Server List) Ustaw mój serwer jako publiczny (zarejestruj na liście) List Lista STATUS STATUS Location: Region Położenie: Region Custom Directory Server Address: Własny Adres Serwera Zbiorczego: My Server Info Informacje o tym serwerze Location: City Lokalizacja: Miasto Location: Country Lokalizacja: Kraj CServerListManager Could not write to '%1' Nie da się zapisywać do „%1” CSound The Jack server is not running. This software requires a Jack server to run. Normally if the Jack server is not running this software will automatically start the Jack server. It seems that this auto start has not worked. Try to start the Jack server manually. Serwer JACK nie jest uruchomiony. Do poprawnego działania, ten program wymaga serwera JACK. Normalnie, jeśli JACK nie jest uruchomiony, Jamulus uruchomi go automatycznie, jednak wygląda na to, że automatyczny start nie działa. Spróbuj uruchomić serwer JACK ręcznie. The Jack server sample rate is different from the required one. The required sample rate is: Częstotliwość próbkowania serwera JACK jest inna niż wymagana. Wymagana częstotliwość próbkowania wynosi: You can use a tool like <i><a href="https://qjackctl.sourceforge.io">QJackCtl</a></i> to adjust the Jack server sample rate. Możesz użyć programu <i><a href="https://qjackctl.sourceforge.io">QJackCtl</a></i> aby ustawić częstotliwość próbkowania JACK-a. Make sure to set the Frames/Period to a low value like Upewnij się, że ramki/okres są ustawione na niską wartość taką jak to achieve a low delay. aby uzyskać najniższe opóźnienie. The Jack port registering failed. Rejestracja portu JACK-a nie powiodła się. Cannot activate the Jack client. Nie może aktywować klienta JACK-a. The Jack server was shut down. This software requires a Jack server to run. Try to restart the software to solve the issue. Serwer JACK został wyłączony. Ten program wymaga serwera JACK do działania. Spróbuj zrestartować oprogramowanie, aby rozwiązać problem. CoreAudio input AudioHardwareGetProperty call failed. It seems that no sound card is available in the system. CoreAudio wywołanie wejścia AudioHardwareGetProperty nie powiodło się. Wydaje się, że karta dźwiękowa nie jest dostępna w systemie. CoreAudio output AudioHardwareGetProperty call failed. It seems that no sound card is available in the system. CoreAudio wywołanie wyjścia AudioHardwareGetProperty nie powiodło się. Wydaje się, że karta dźwiękowa nie jest dostępna w systemie. Current system audio input device sample rate of %1 Hz is not supported. Please open the Audio-MIDI-Setup in Applications->Utilities and try to set a sample rate of %2 Hz. Aktualna systemowa częstotliwość próbkowania urządzenia wejściowego audio %1 Hz nie jest obsługiwana. Proszę otworzyć Audio-MIDI-Setup w Applications->Utilities i spróbować ustawić częstotliwość próbkowania %2 Hz. The current selected audio device is no longer present in the system. Aktualnie zaznaczonego urządzenia dźwiękowego nie ma obecnie w systemie. The audio input device is no longer available. Wejściowe urządzenie dźwiękowe już nie jest dostępne. The audio output device is no longer available. Wyjściowe urządzenie dźwiękowe już nie jest dostępne. Current system audio output device sample rate of %1 Hz is not supported. Please open the Audio-MIDI-Setup in Applications->Utilities and try to set a sample rate of %2 Hz. Aktualna systemowa częstotliwość próbkowania urządzenia wyjściowego audio %1 Hz nie jest obsługiwana. Proszę otworzyć Audio-MIDI-Setup w Applications->Utilities i spróbować ustawić częstotliwość próbkowania %2 Hz. The audio input stream format for this audio device is not compatible with this software. Format strumienia wejściowego audio dla tego urządzenia audio nie jest kompatybilny z tym oprogramowaniem. The audio output stream format for this audio device is not compatible with this software. Format strumienia wyjściowego audio dla tego urządzenia audio nie jest kompatybilny z tym oprogramowaniem. The buffer sizes of the current input and output audio device cannot be set to a common value. Please choose other input/output audio devices in your system settings. Rozmiary bufora bieżącego wejściowego i wyjściowego urządzenia audio nie mogą być ustawione na wspólną wartość. Proszę wybrać inne wejściowe/wyjściowe urządzenia audio w ustawieniach systemowych. The audio driver could not be initialized. Sterownik audio nie może zostać zainicjalizowany. The audio device does not support the required sample rate. The required sample rate is: Urządzenie audio nie obsługuje wymaganej częstotliwości próbkowania. Wymagana częstotliwość próbkowania wynosi: The audio device does not support setting the required sampling rate. This error can happen if you have an audio interface like the Roland UA-25EX where you set the sample rate with a hardware switch on the audio device. If this is the case, please change the sample rate to Urządzenie audio nie obsługuje ustawiania wymaganej częstotliwości próbkowania. Błąd ten może się zdarzyć, jeśli posiadasz interfejs audio taki jak Roland UA-25EX, w którym ustawiasz częstotliwość próbkowania za pomocą przełącznika sprzętowego na urządzeniu audio. W takim przypadku należy zmienić częstotliwość próbkowania na Hz on the device and restart the Hz na urządzeniu i ponownie uruchom program software. program. The audio device does not support the required number of channels. The required number of channels for input and output is: Urządzenie audio nie obsługuje wymaganej liczby kanałów. Wymagana liczba kanałów dla wejścia i wyjścia wynosi: Required audio sample format not available. Wymagany format próbkowania audio nie jest dostępny. The selected audio device is no longer present in the system. Please check your audio device. Wybrane urządzenie dźwiękowe nie jest już dostępne w systemie. Proszę sprawdzić je sprawdzić. Couldn't initialise the audio driver. Check if your audio hardware is plugged in and verify your driver settings. Nie da się włączyć sterownika audio. Sprawdź czy twój sprzęt audio jest podłączony i zweryfikuj ustawienia sterownika. The selected audio device is incompatible since it doesn't support a sample rate of %1 Hz. Please select another device. Wybrane urządzenie dźwiękowe jest niekompatybilne bo nie obsługuje próbkowania %1 Hz. Proszę wybrać inne. The current audio device configuration is incompatible because the sample rate couldn't be set to %2 Hz. Please check for a hardware switch or driver setting to set the sample rate manually and restart %1. Aktualne urządzenie dźwiękowe jest niekompatybilne bo nie da się ustawić próbkowania %2 Hz. Proszę sprawdzić przełączniki na urządzeniu lub ustawienia jego sterownika żeby ustawić tą częstotliwość ręcznie i uruchomić %1 ponownie. The selected audio device is incompatible since it doesn't support %1 in/out channels. Please select another device or configuration. Wybrane urządzenie dźwiękowe jest niekompatybilne bo nie obsługuje %1 kanałów wej/wyj. Proszę wybrać inne urządzenie lub zmienić jego konfigurację. The selected audio device is incompatible since the required audio sample format isn't available. Please use another device. Wybrane urządzenie dźwiękowe jest niekompatybilne bo nie obsługuje wymaganego formatu próbek audio. Proszę wybrać inne. No ASIO audio device driver found. Nie znaleziono urządzenia ASIO. Please install an ASIO driver before running %1. If you own a device with ASIO support, install its official ASIO driver. If not, you'll need to install a universal driver like ASIO4ALL. Proszę zainstalować sterownik ASIO przed uruchomieniem %1-a. Jeżeli twoje urządzenie posiada wsparcie dla ASIO, zainstaluj oficjalny sterownik dla niego, jeżeli nie, trzeba zainstalować uniwersalny sterownik taki jak ASIO4ALL. Please install an ASIO driver before running %1. If you own a device with ASIO support, install its official ASIO driver. If not, you'll need to download and install a universal driver like ASIO4ALL. Proszę zainstalować sterownik ASIO przed uruchomieniem %1. Jeżeli posiadasz urządzenie wspierające ASIO, zainstaluj oficjalny sterownik do niego, jeżeli nie, potrzeba będzie zainstalować uniwersalny sterownik, taki jak ASIO4ALL. No ASIO audio device (driver) found. Urządzenie (sterownik) ASIO nie został znaleziony. software requires the low latency audio interface ASIO to work properly. This is not a standard Windows audio interface and therefore a special audio driver is required. Either your sound card has a native ASIO driver (which is recommended) or you might want to use alternative drivers like the ASIO4All driver. program wymaga do poprawnego działania interfejsu audio ASIO o niskim opóźnieniu. Nie jest to standardowy interfejs systemu Windows i dlatego wymagany jest specjalny sterownik audio. Albo twoja karta dźwiękowa posiada natywny sterownik ASIO (co jest zalecane) lub możesz użyć alternatywnych sterowników, takich jak ASIO4All. Error requesting stream stop: $s Błąd podczas zamykania strumienia: $s Error closing stream: $s Błąd podczas zamykania strumienia: $s JACK couldn't be started automatically. Please start JACK manually and check for error messages. JACK nie mógł być uruchomiony automatycznie. Proszę go uruchomić ręcznie i sprawdzić komunikaty błędów. JACK isn't running at a sample rate of <b>%1 Hz</b>. Please use a tool like <i><a href="https://qjackctl.sourceforge.io">QjackCtl</a></i> to set the the JACK sample rate to %1 Hz. JACK nie jest uruchomiony z częstotliwością próbkowania <b>%1 Hz</b>. Proszę użyć programu takiego jak <i><a href="https://qjackctl.sourceforge.io">QjackCtl</a></i> aby ustawić próbkowanie JACK-a na %1. The JACK port registration failed. This is probably an error with JACK. Please stop %1 and JACK. Afterwards check if another program at a sample rate of %2 Hz can connect to JACK. Nie powiodła się rejestracja portu na serwerze JACK. Prawdopodobnie to jego błąd. Proszę zamknąć %1-a i JACK-a i sprawdzić czy jakiś inny program wykorzystujący próbkowanie %2 Hz może się podłączyć do JACK-a. The JACK port registration failed. This is probably an error with JACK. Please stop %1 and JACK. Afterwards, check if another MIDI program can connect to JACK. Nie powiodła się rejestracja portu na serwerze JACK. Prawdopodobnie to jego błąd. Proszę zamknąć %1-a i JACK-a i sprawdzić czy jakiś inny program MIDI może się podłączyć do JACK-a. Can't activate the JACK client. This is probably an error with JACK. Please check the JACK output. Nie da się uruchomić klienta JACK. Prawdopodobnie to błąd JACK-a. Proszę sprawdzić jego komunikaty. JACK was shut down. %1 requires JACK to run. Please restart %1 to start JACK again. JACK został zatrzymany. %1 wymaga serwera JACK. Proszę zrestartować %1-a aby uruchomić JACK-a jeszcze raz. No sound card is available in your system. CoreAudio input AudioHardwareGetProperty call failed. W twoim systemie nie ma karty dźwiękowej. Wywołanie CoreAudio input AudioHardwareGetProperty nie powiodło się. No sound card is available in the system. CoreAudio output AudioHardwareGetProperty call failed. W twoim systemie nie ma karty dźwiękowej. Wywołanie CoreAudio output AudioHardwareGetProperty nie powiodło się. The currently selected audio device is no longer present. Please check your audio device. Brakuje aktualnie zaznaczonego urządzenia dźwiękowego. Proszę sprawdzić urządenia dźwiękowe. The audio input device is no longer available. Please check if your input device is connected correctly. Wejściowe urządzenie dźwiękowe nie jest już dostępne. Proszę sprawdzić czy jest właściwie podłączone. The sample rate on the current input device isn't %1 Hz and is therefore incompatible. Please select another device or try setting the sample rate to %1 Hz manually via Audio-MIDI-Setup (in Applications->Utilities). Częstotliwość próbkowania aktualnego urządzenia wejściowego to nie %1 Hz więc jest niekompatybilna. Proszę wybrać inne urządzenie lub spróbować zmienić próbkowanie na %1 Hz ręcznie - poprzez ustawienia Dźwięk-MIDI (w Programy->Narzędzia). The audio output device is no longer available. Please check if your output device is connected correctly. Wyjściowe urządzenie dźwiękowe nie jest już dostępne. Proszę sprawdzić czy jest właściwie podłączone. The sample rate on the current output device isn't %1 Hz and is therefore incompatible. Please select another device or try setting the sample rate to %1 Hz manually via Audio-MIDI-Setup (in Applications->Utilities). Częstotliwość próbkowania aktualnego urządzenia wejściowego to nie %1 Hz więc jest niekompatybilna. Proszę wybrać inne urządzenie lub spróbować zmienić próbkowanie na %1 Hz ręcznie - poprzez ustawienia Dźwięk-MIDI (w Programy->Narzędzia). The stream format on the current input device isn't compatible with this software. Please select another device. Format strumienia dźwiękowego aktualnego urządzenia wejściowego nie jest kompatybilny z tym oprogramowaniem. Proszę wybrać inne urządzenie. The stream format on the current output device isn't compatible with %1. Please select another device. Format strumienia dźwiękowego aktualnego urządzenia wyjściowego nie jest kompatybilny z %1-em. Proszę wybrać inne urządzenie. The buffer sizes of the current input and output audio device can't be set to a common value. Please select different input/output devices in your system settings. Rozmiary buforów aktualnych urządzeń wejściowych i wejściowych nie mogą być ustawione na jednakową wartość. Proszę wybrać inne urządzenia w ustawieniach systemowych. CSoundBase Invalid device selection. Wybrano niepoprawne urządzenie. The audio driver properties have changed to a state which is incompatible with this software. The selected audio device could not be used because of the following error: Właściwości sterownika audio zmieniły i są niekompatybilne z Jamulus-em. Wybrane urządzenie audio nie mogło zostać użyte z powodu następującego błędu: Please restart the software. Uruchom program ponownie. Close Zamknij The selected audio device could not be used because of the following error: Wybrane urządzenie audio nie mogło być użyte z powodu następującego błędu: The previous driver will be selected. Zostanie wybrany poprzedni sterownik. The previously selected audio device is no longer available or the audio driver properties have changed to a state which is incompatible with this software. We now try to find a valid audio device. This new audio device might cause audio feedback. So, before connecting to a server, please check the audio device setting. Poprzednio wybrane urządzenie dźwiękowe nie jest już dostępne lub parametry sterownika audio zostały tak zmienione, że są niekompatybilne z tym programem. Próbujmy teraz znaleźć właściwe urządzenie dźwiękowe. To nowe urządzenie może powodować sprzężenia, dlatego przed podłączeniem do serwera proszę sprawdzić jego ustawienia. No usable Nieużywany audio device (driver) found. znaleziono urządzenie dźwiękowe (sterownik). In the following there is a list of all available drivers with the associated error message: Poniżej znajduje się lista wszystkich dostępnych sterowników wraz z powiązanymi komunikatami błędów: Do you want to open the ASIO driver setups? Czy chcesz otworzyć konfigurację sterownika ASIO? could not be started because of audio interface issues. nie mógł być uruchomiony z powodu problemów z interfejsem audio. Can't use the selected audio device because of the following error: %1 The previous driver will be selected. Nie można używać wybranego urządzenia dźwiękowego z powodu błędu %1. Poprzedni sterownik zostanie wybrany. The previously selected audio device is no longer available or the driver has changed to an incompatible state. We'll attempt to find a valid audio device, but this new audio device may cause feedback. Before connecting to a server, please check your audio device settings. Poprzednio wybrane urządzenie dźwiękowe nie jest już dostępne lub jego ustawienia nie są już kompatybilne. Spróbuję znaleźć odpowiednie urządzenie dźwiękowe ale może ono powodować sprzężenia. Przed podłączeniem do serwera proszę sprawdzić swoje ustawienia audio. <b>%1 couldn't find a usable %2 audio device.</b><br><br> <b>%1 nie znalazł działającego %2 urządzenia dźwiękowego.</b><br><br> You may be able to fix errors in the driver settings. Do you want to open these settings now? Można spróbować naprawić błędy w ustawieniach sterownika. Otworzyć je teraz? No usable %1 audio device found. Nie znaleziono działającego użądzenia dźwiękowego %1. These are all the available drivers with error messages: Wszystkie te dostępne sterowniki mają błędy: Do you want to open the ASIO driver setup to try changing your configuration to a working state? Czy chcesz otworzyć ustawienia sterownika ASIO żeby spróbować ustawić konfigurację dźwięku? Can't start %1. Please restart %1 and check/reconfigure your audio settings. Nie udało się uruchomić %1-a. Proszę sprawdzić/zmienić ustawienia dźwięku i uruchomić %1-a ponownie. QCoreApplication %1, Version %2 %1, Wersja %2 Internet Jam Session Software Program do sesji dźwiękowych przez internet %1, Version %2 %1 is app name, %2 is version number %1, Wersja %2 Released under the GNU General Public License version 2 or later (GPLv2) Wydane na zasadach licencji GNU General Public License wersja 2 lub następne (GPLv2) This program is free software; you can redistribute it and/or modify it under Ten program jest wolnym oprogramowaniem; możesz go rozprowadzać dalej i/lub modyfikować na warunkach the terms of the GNU General Public License as published by the Free Software Powszechnej Licencji Publicznej GNU, wydanej przez Fundację Wolnego Oprogramowania Foundation; either version 2 of the License, or (at your option) any later version. - według wersji 2 tej Licencji lub (według twojego wyboru) którejś z późniejszych wersji. There is NO WARRANTY, to the extent permitted by law. Nie ma ŻADNEJ GWARANCJI, w zakresie dozwolonym przez prawo. Using the following libraries, resources or code snippets: Używając niżej podanych bibliotek, zasobów lub kawałków kodu: Qt framework Szablony Qt Opus Interactive Audio Codec Kodek Opus Audio Audio reverberation code by Perry R. Cook and Gary P. Scavone Kod algorytmu pogłosu: Perry R. Cook i Gary P Scavone Some pixmaps are from the Open Clip Art Library (OCAL) Niektóre obrazki są z Open Clip Art Library (OCAL) Flag icons by Mark James Ikony flag: Mark James Copyright (C) 2005-2022 The Jamulus Development Team Copyright (C) 2005-2022 Zespół programistów Jamulus-a Released under the GNU General Public License (GPL) Wydane na zasadach licencji GNU General Public License (GPL) global A %1 upgrade is available: <a style='color:red;' href='https://jamulus.io/upgrade?progversion=%2'>go to details and downloads</a> Dostępna jest aktualizacja %1-a: <a style='color:red;' href='https://jamulus.io/upgrade?progversion=%2'>zobacz szczegóły i pobierz</a> For more information use the "What's This" help (help menu, right mouse button or Shift+F1) Aby uzyskać więcej informacji użyj „Co to jest” (z menu Pomoc lub prawy przycisk myszy lub Shift+F1) jamulus-3.9.1+dfsg/src/translation/translation_sk_SK.ts0000644000175000017500000056756414340334543022330 0ustar vimervimer CAboutDlg Qt cross-platform application framework Qt multiplatformový aplikačný framework Audio reverberation code by Perry R. Cook and Gary P. Scavone Kód pre ozvenu (reverb): Perry R. Cook a Gary P. Scavone Some pixmaps are from the Niektoré ikony sú z This app enables musicians to perform real-time jam sessions over the internet. Táto aplikácia umožňuje hudobníkom v reálnom čase džemovať cez internet. There is a server which collects the audio data from each client, mixes the audio data and sends the mix back to each client. Úlohou servera je zbierať zvukové dáta od každého klienta, zmiešať ich a poslať ich každému klientovi naspäť. This app uses the following libraries, resources or code snippets: Tento program používa nasledujúce knižnice, zdrojové dáta alebo úryvky kódu: Country flag icons by Mark James Vlajky krajín: Mark James For details on the contributions check out the Podrobnosti o prispievateľoch nájdete na Flag icons by Mark James Ikony vlajok: Mark James Some sound samples are from Zopár zvukových samplov je z For details on the contributions check out the %1 Podrobnosti o prispievateľoch nájdete na %1 Github Contributors list Zoznam prispievateľov na Githube Spanish španielčina French francúzština Portuguese portugalčina Dutch holandčina Italian taliančina German nemčina Polish poľština Swedish švédčina Korean Slovak slovenčina Simplified Chinese zjednodušená čínština Norwegian Bokmål About %1 O programe %1 About O programe CAboutDlgBase About O programe TextLabelVersion TextLabelVersion Copyright (C) 2005-2022 Volker Fischer and others Autorské práva (C) 2005-2020 Volker Fischer a iní Copyright (C) 2005-2022 The Jamulus Development Team Autorské práva (C) 2005-2021 The Jamulus Development Team A&bout O pro&grame &Libraries &Knižnice &Contributors &Prispievatelia &Translation P&reklad &OK &OK CAnalyzerConsole Analyzer Console Konzola analyzátora Error Rate of Each Buffer Size Frekvencia chýb podľa veľkosti vyr. pamäte CAudioMixerBoard Personal Mix at the Server Osobný mix servera When connected to a server, the controls here allow you to set your local mix without affecting what others hear from you. The title shows the server name and, when known, whether it is actively recording. Po pripojení sa na server vám tieto ovládacie prvky umožnia lokálne mixovať zvuk bez toho, aby ste tým ovplyvnili to, čo od vás budú počuť ostatní. Nadpis okna zobrazuje názov servera a v prípade, ak je táto informácia k dispozícii, či je aktívne nahrávanie. Server Server T R Y I N G T O C O N N E C T P O K U S O P R I P O J E N I E RECORDING ACTIVE NAHRÁVANIE AKTÍVNE Personal Mix at: %1 Osobný mix na: %1 CChannelFader Pan Posúvanie Mute Stíšiť Solo Sólo Channel Level Úroveň kanála Input level of the current audio channel at the server Vstupná úroveň aktuálneho audio kanála na serveri Mixer Fader Prelínač mixéra Local mix level setting of the current audio channel at the server Nastavenie úrovne miestneho mixu aktuálneho audio kanála na serveri Status Indicator Stavový indikátor Shows a status indication about the client which is assigned to this channel. Supported indicators are: Zobrazuje indikáciu stavu klienta, ktorý je priradený k tomuto kanálu. Podporované indikátory sú: Status indicator label Menovka stavového indikátora Panning Posúvanie Local panning position of the current audio channel at the server Miesto posúvanie pozície aktuálneho zvukového kanála na serveri With the Mute checkbox, the audio channel can be muted. Audio kanál môžete vypnúť pomocou zaškrtávacieho políčka Stíšiť. Mute button Tlačidlo Stíšenia Solo button Tlačidlo Sóla Fader Tag Značka prelínača Displays the pre-fader audio level of this channel. All clients connected to the server will be assigned an audio level, the same value for every client. Zobrazuje počiatočnú úroveň zvuku pre tento kanál. Každému klientovi pripájajúcemu sa k tomuto serveru bude priradená táto úroveň, pre každého klienta sa použije rovnaká hodnota. &No grouping &Bez zoskupovania Assign to group Priradiť do skupiny Adjusts the audio level of this channel. All clients connected to the server will be assigned an audio fader, displayed at each client, to adjust the local mix. Upravuje úroveň zvuku pre tento kanál. Všetkým klientom pripojeným k serveru bude priradený zvukový prelínač a umožní vám ich lokálne mixovanie. Speaker with cancellation stroke: Indicates that another client has muted you. Prečiarknutý reproduktor: Zobrazí sa vtedy, ak vás iný klient stíšil. Sets the pan from Left to Right of the channel. Works only in stereo or preferably mono in/stereo out mode. Nastavuje posun z ľavého do pravého kanála. Funguje iba v režime stereo, prípadne (lepšie) v režie mono dnu/stereo von. With the Solo checkbox, the audio channel can be set to solo which means that all other channels except the soloed channel are muted. It is possible to set more than one channel to solo. Pomocou zaškrtávacieho políčka Sólo môžete zvukový kanál nastaviť ako sólo, čo znamená, že zvyšné kanály (okrem sólo kanálov) budú stíšené. Je možné takto označiť viac kanálov. Group Zoskupiť With the Grp checkbox, a group of audio channels can be defined. All channel faders in a group are moved in proportional synchronization if any one of the group faders are moved. Pomocou zaškrtávacieho políčka Skp môžete definovať skupinu zvukových kanálov. Pri zmene hlasitosti kanála sú príslušným spôsobom menené hlasitosti ostatných kanálov v tej istej skupine. Group button Tlačidlo Zoskupiť The fader tag identifies the connected client. The tag name, a picture of your instrument and the flag of your country can be set in the main window. Značka prelínača identifikuje pripojeného klienta. Názov značky, obrázok vášho nástroja a vlajku vašej krajiny môžete nastaviť v hlavnom okne. Mixer channel instrument picture Obrázok hud. nástroja kanála mixéra Mixer channel label (fader tag) Menovka kanála mixéra (značka prelínača) Mixer channel country flag Vlajka krajiny na kanáli mixéra PAN PAN MUTE STÍŠIŤ SOLO SÓLO GRP SKP M M S S G G Grp Skp Alias/Name Prez/Meno Instrument Hud. nástroj Location Miesto Skill Level Úroveň hrania Alias Prezývka Beginner Začiatočník The fader tag identifies the connected client. The tag name, a picture of your instrument and the flag of your location can be set in the main window. Značka prelínača identifikuje pripojeného klienta. Názov značky, obrázok vášho nástroja a vlajku vašej polohy môžete nastaviť v hlavnom okne. Mixer channel country/region flag Vlajka krajiny/regiónu na kanáli mixéra Intermediate Pokročilý Expert Expert Musician Profile Profil hudobníka CChatDlg Chat Window Okno chatu The chat window shows a history of all chat messages. Okno chatu zobrazuje históriu všetkých správ chatu. Chat history História chatu Input Message Text Vstupná správa chatu Enter the chat message text in the edit box and press enter to send the message to the server which distributes the message to all connected clients. Your message will then show up in the chat window. Zadajte text správy chatu do poľa a stlačte enter pre poslanie správy na server, ktorý ju rozpošle všetkým pripojeným klientom. Vaša správa sa potom objaví v okne chatu. New chat text edit box Pole úprav nového textu správy Type a message here Sem napíšte správu &Edit &Upraviť Cl&ear Chat History &Vyčistiť históriu chatu &Close &Zavrieť Do you want to open the link '%1' in your browser? Chcete otvoriť prepojenie '%1' vo vašom prehliadači? Do you want to open the link Chcete otvoriť prepojenie in an external browser? v externom prehliadači? CChatDlgBase Chat Chat &Send &Poslať CClientDlg Input Level Meter Indikátor úrovne vstupu Make sure not to clip the input signal to avoid distortions of the audio signal. Zabezpečte, aby nedochádzalo k orezávaniu (clipping) vstupného signálu, aby ste zamedzili jeho skresleniu. Input level meter Indikátor úrovne vstupu Simulates an analog LED level meter. Simuluje analógový LED indikátor úrovne vstupu. Connect/Disconnect Button Tlačidlo Pripojiť/Odpojiť Connect and disconnect toggle button Tlačidlo Pripojiť/Odpojiť Local Audio Input Fader Miestny prelínač zvukového vstupu L Ľ , where , kde is the current attenuation indicator. je indikátor aktuálneho útlmu. Local audio input fader (left/right) Miestny prelínač zvukového vstupu (ľavý/pravý) Delay Status LED Dióda stavu oneskorenia Delay status LED indicator LED indikátor stavu oneskorenia Buffers Status LED Dióda stavu bufferov The network jitter buffer is not large enough for the current network/audio interface jitter. Vyrovnávacia pamäť sieťového chvenia nemá dostatočnú veľkosť vzhľadom na aktuálne chvenie siete/zvukového rozhrania. This shows the level of the two stereo channels for your audio input. Tu sa zobrazuje úroveň dvoch stereo kanálov vášho zvukového vstupu. If the application is connected to a server and you play your instrument/sing into the microphone, the VU meter should flicker. If this is not the case, you have probably selected the wrong input channel (e.g. 'line in' instead of the microphone input) or set the input gain too low in the (Windows) audio mixer. Ak je aplikácia pripojená k serveru a vy zahráte na hudobný nástroj alebo zaspievate do mikrofónu, ukazovateľ vstupného signálu by sa mal aktivovať. Ak sa tak nedeje, pravdepodobne ste vybrali nesprávny vstupný kanál (napr. 'line in' miesto mikrofónneho vstupu) alebo ste nastavili zosilnenie signálu (gain) na príliš nízku hodnotu v zmiešavači zvuku (Windows). For proper usage of the application, you should not hear your singing/instrument through the loudspeaker or your headphone when the software is not connected. This can be achieved by muting your input audio channel in the Playback mixer (not the Recording mixer!). Ak má táto aplikácia fungovať správne, nemali by ste počuť svoj spev/nástroj v reproduktoroch alebo slúchadlách vtedy, keď tento program nie je pripojený. To môžete docieliť stíšením vášho vstupného audio kanála v mixéri prehrávania (nie v nahrávacom mixeri!). Opens a dialog where you can select a server to connect to. If you are connected, pressing this button will end the session. Otvorí dialógové okno s výberom serveru, ku ktorému sa chcete pripojiť. Ak ste pripojený, stlačením tohto tlačidla ukončíte sedenie. Reverb effect Efekt ozveny (reverb) Reverb can be applied to one local mono audio channel or to both channels in stereo mode. The mono channel selection and the reverb level can be modified. For example, if a microphone signal is fed in to the right audio channel of the sound card and a reverb effect needs to be applied, set the channel selector to right and move the fader upwards until the desired reverb level is reached. Efekt ozveny môžete použiť na jeden miestny audio kanál alebo na oba kanály v režime sterea. Výber kanála v mono režime a úroveň ozveny je možné meniť. Príklad: ak je signál z mikrofónu privedený do pravého kanála zvukovej karty a chcete naň použiť efekt ozveny, zvoľte pravý kanál a prelínač nastavte tak, aby ste dosiahli požadovanú úroveň efektu. Reverb effect level setting Nastavenie sily efektu ozveny (reverb) Reverb Channel Selection Výber kanála pre reverb With these radio buttons the audio input channel on which the reverb effect is applied can be chosen. Either the left or right input channel can be selected. Pomocou týchto tlačidiel si môžete vybrať, na ktorý vstupný kanál bude použitý efekt ozveny (reverb). Môžete si vybrať ľavý alebo pravý kanál. Left channel selection for reverb Výber ľavého kanála pre reverb Right channel selection for reverb Výber pravého kanála pre reverb Shows the current audio delay status: Zobrazuje aktuálny stav oneskorenia zvuku: Green Zelená The delay is perfect for a jam session. Oneskorenie je perfektné pre džemovanie. Yellow Žltá A session is still possible but it may be harder to play. Džemovanie je stále možné, ale hranie môže byť sťažené. Red Červená The delay is too large for jamming. Oneskorenie je príliš veľké na džemovanie. If this LED indicator turns red, you will not have much fun using the application. Ak sa dióda zmení na červenú, veľa zábavy si s touto aplikáciou neužijete. The buffers status LED shows the current audio/streaming status. If the light is red, the audio stream is interrupted. This is caused by one of the following problems: Dióda stavu bufferov ukazuje aktuálny stav audio/streamovania. Ak je jej farba červená, zvukový stream je prerušený. Príčinou môže byť jeden z nasledujúcich problémov: The sound card's buffer delay (buffer size) is too small (see Settings window). Oneskorenie buffera (veľkosť buffera) zvukovej karty je príliš malé (pozrite Nastavenia). The upload or download stream rate is too high for your internet bandwidth. Rýchlosť uploadu alebo downloadu streamu je príliš vysoká vzhľadom na vašu rýchlosť internetového pripojenia. The CPU of the client or server is at 100%. Procesor na klientovi alebo serveri je vytažený na 100 %. Buffers status LED indicator LED indikátor stavu bufferov Current Connection Status Parameter Stav aktuálneho pripojenia The Ping Time is the time required for the audio stream to travel from the client to the server and back again. This delay is introduced by the network and should be about 20-30 ms. If this delay is higher than about 50 ms, your distance to the server is too large or your internet connection is not sufficient. Čas pingu je čas potrebný na to, aby prúd zvuku pricestoval od klienta na server a naspäť. Oneskorenie je spôsobené sieťou a malo by sa pohybovať medzi 20 a 30 ms. Ak je oneskorenie vyššie ako približne 50 ms, vaša vzdialenosť ku serveru je príliš veľká alebo vaše pripojenie k internetu nie je postačujúce. Overall Delay is calculated from the current Ping Time and the delay introduced by the current buffer settings. Celkové oneskorenie vychádza z času pingu a oneskorenia spôsobeného nastavením vyrovnávacej pamäte. If this LED indicator turns red, you will not have much fun using the Ak sa dióda zmení na červenú, veľa zábavy si s touto aplikáciou software. neužijete. C&onnect &Pripojiť software upgrade available dostupná aktualizácia softvéru &File &Súbor &View Pohľ&ad &Connection Setup... Nasta&venie pripojenia... My &Profile... Môj &profil... C&hat... &Chat... &Settings... N&astavenia... &Analyzer Console... &Konzola analyzátora... N&o User Sorting Netriediť &používateľov Sort Users by &City Triediť používateľov podľa mes&ta Clear &All Stored Solo and Mute Settings &Vypnúť všetky nastavenia sólo a stíšení If this LED indicator turns red, you will not have much fun using %1. Ak sa táto dióda zmení na červenú, veľa zábavy si aplikáciou %1 neužijete. If this LED indicator turns red, the audio stream is interrupted. Ak sa táto dióda zmení na červenú, prúd zvuku sa prerušil. Current Connection Status Aktuálny stav pripojenia Set All Faders to New Client &Level Nastaviť všetky prelínače na ú&roveň pre nových klientov Auto-Adjust all &Faders &Automaticky prispôsobiť všetky prelínače O&wn Fader First &Vlastný prelínač ako prvý Sett&ings Na&stavenia %1 Directory Adresár %1 Ok Ok E&xit U&končiť Local Jitter Buffer Status LED Stavová LEDka vyrovnávacej pamäte miestneho chvenia The local jitter buffer status LED shows the current audio/streaming status. If the light is red, the audio stream is interrupted. This is caused by one of the following problems: Stavová LEDka miestnej vyrovnávacej pamäte chvenia zobrazuje stav aktuálneho streamovania/zvuku. Ak svieti načerveno, prúd zvuku bol prerušený. Toto môže byť spôsobené: Local Jitter Buffer status LED indicator Stavová dióda vyrovnávacej pamäte miestneho chvenia If this LED indicator turns red, you will not have much fun using the %1 software. Ak sa dióda zmení na červenú, veľa zábavy si aplikáciou %1 neužijete. &Load Mixer Channels Setup... &Načítať nastavenia kanálov mixéra... &Save Mixer Channels Setup... &Uložiť nastavenia kanálov mixéra... &Settings &Nastavenia Audio/Network &Settings... Nastavenia zvuku/&siete... A&dvanced Settings... Pokročilé &nastavenia... &Edit Úp&ravy Sort Users by &Name Triediť používateľov kanálov podľa &mena Sort Users by &Instrument Triediť používateľov kanálov podľa &nástroja Sort Users by &Group Triediť používateľov kanálov podľa &skupiny None Żaden Center Stred R P Directory Server Adresárový server Select Channel Setup File Vyberte súbor s nastavením kanálov user používateľ users používatelia Connect Pripojiť sa Settings Nastavenia Chat Chat Enable feedback detection Zapnúť detekciu spätnej väzby Audio feedback or loud signal detected. We muted your channel and activated 'Mute Myself'. Please solve the feedback issue first and unmute yourself afterwards. Bola zistená prítomnosť spätnej väzby alebo silného signálu. Stíšili sme váš kanál a aktivovali nastavenia 'Stíšiť ma'. Prosím, vyriešte problém so spätnou väzbou a následne vypnite stíšenie. Your sound card is not working correctly. Please open the settings dialog and check the device selection and the driver settings. Vaša zvuková karta nefunguje správne. Prosím, otvorte okno s nastaveniami a skontrolujte výber zariadenia a nastavenia ovládača. &Disconnect O&dpojiť CClientDlgBase Delay Oneskorenie Buffers Buffery Input Vstup L Ľ R P Jitter Chvenie Ping Ping ms ms &Mute Myself S&tíšiť ma &Settings Nasta&venia &Chat &Chat C&onnect &Pripojiť Pan Posun Center Stred Reverb Ozvena (rev) Left Ľavý Right Pravý MUTED (Other people won't hear you) STÍŠENÉ (ostatní vás nepočujú) Set up your audio, connect to a server and start jamming! Nastavte zvuk, pripojte sa na server a začnite džemovať! Update check Kontrola aktualizácií CClientSettingsDlg Jitter Buffer Size Veľkosť vyrovnávacej pamäte chvenia The jitter buffer setting is therefore a trade-off between audio quality and overall delay. Nastavenie vyrovnávacej pamäte chvenia je preto kompromisom medzi kvalitou zvuku a celkovým oneskorením. Local jitter buffer slider control Posuvný ovládač vyr. pamäte miestneho chvenia Server jitter buffer slider control Posuvný ovládač vyr. pamäte chvenia na serveri Auto jitter buffer switch Automatický prepínač vyr. pamäte chvenia Sound Card Device Zariadenie zvukovej karty The ASIO driver (sound card) can be selected using Ovládač (zvukovej karty) ASIO môžete vybrať použitím If the driver is selected during an active connection, the connection is stopped, the driver is changed and the connection is started again automatically. Ak ovládač vyberiete počas aktívneho pripojenia, pripojenie je pozastavené, ovládač sa zmení a následne sa spojenie automaticky opäť obnoví. Sound card device selector combo box If you are using the kX ASIO driver, make sure to connect the ASIO inputs in the kX DSP settings panel. Sound Card Channel Mapping Mapovanie kanálov zvukovej karty For each Pre každý input/output channel (Left and Right channel) a different actual sound card channel can be selected. vstupný/výstupný kanál (ľavý a pravý kanál) môžete vybrať iný kanál zvukovej karty. Left input channel selection combo box Right input channel selection combo box Left output channel selection combo box Right output channel selection combo box Enable Small Network Buffers Povoliť malú vyrovnávaciu pamäť pre sieť Enable small network buffers check box Sound Card Buffer Delay Oneskorenie vyrovnávacej pamäte zvukovej karty Three buffer sizes are supported Sú podporované 3 veľkosti buffera The buffer setting is therefore a trade-off between audio quality and overall delay. Nastavenie vyrovnávacej pamäte je preto kompromisom medzi kvalitou zvuku a celkovým oneskorením. Sound card driver settings Nastavenia ovládača zvukovej karty Opens the driver settings. Note: Otvorí nastavenia ovládača. Poznámka: For each %1 input/output channel (left and right channel) a different actual sound card channel can be selected. Pre každý %1 vstupný/výstupný kanál (ľavý a pravý kanál) môžete vybrať iný kanál zvukovej karty. Enables support for very small network audio packets. These network packets are only actually used if the sound card buffer delay is smaller than %1 samples. The smaller the network buffers, the lower the audio latency. But at the same time the network load and the probability of audio dropouts or sound artifacts increases. Zapne podporu pre veľmi malé sieťové audio pakety. Takéto sieťové pakety sa v skutočnosti použijú iba vtedy, ak je veľkosť buffera zvukovej karty menšia ako %1 vzoriek. Čím je menšia vyrovnávacia pamäť siete, tým je nižšia latencia zvuku. Zároveň tým však rastie zaťaženie siete a pravdepodobnosť výpadkov zvuku a vzniku artefaktov. Some sound card drivers do not allow the buffer delay to be changed from within %1. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. On Windows, use the ASIO Device Settings button to open the driver settings panel. On Linux, use the JACK configuration tool to change the buffer size. Niektoré ovládače zvukových kariet nepovoľujú meniť oneskorenie vyrovnávacej pamäte z prostredia programu %1. V takom prípade nie je nastavenie oneskorenia povolené a musíte ho zmeniť použitím ovládača zvukovej karty. Vo Windows kliknite na tlačidlo Nastaviť ASIO a otvoríte ovládací panel ovládača. V Linuxe použite pre zmenu veľkosti ovládacej pamäte nástroj na konfiguráciu servera JACK. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within %1. On Windows, press the ASIO Device Settings button to open the driver settings panel. On Linux, use the JACK configuration tool to change the buffer size. Ak nastavenia oneskorenia vyrovnávacej pamäte nie je možné meniť, zvukový ovládač neumožňuje programu %1 meniť toto nastavenie. Vo Windows kliknite na tlačidlo Nastavenia zariadenia ASIO a otvorte panel s nastaveniami ovládača. Na Linuxe použite na zmenu veľkosti vyrovnávacej pamäte nástroj na konfiguráciu servera JACK. This opens the driver settings of your sound card. Some drivers allow you to change buffer settings, others like ASIO4ALL lets you choose input or outputs of your device(s). More information can be found on jamulus.io. Opens the driver settings. Note: %1 currently only supports devices with a sample rate of %2 Hz. You will not be able to select a driver/device which doesn't. For more help see jamulus.io. 128 samples setting radio button 256 samples setting radio button Select the meter style to be used for the level meters. The Bar (narrow) and LEDs (round, small) options only apply to the mixerboard. When Bar (narrow) is selected, the input meters are set to Bar (wide). When LEDs (round, small) is selected, the input meters are set to LEDs (round, big). The remaining options apply to the mixerboard and input meters. Language Jazyk Select the language to be used for the user interface. Vyberte jazyk, ktorý sa použije v používateľskom rozhraní. Language combo box and a Input Boost Zosilnenie vstupu This setting allows you to increase your input signal level by factors up to 10 (+20dB). If your sound is too quiet, first try to increase the level by getting closer to the microphone, adjusting your sound equipment or increasing levels in your operating system's input settings. Only if this fails, set a factor here. If your sound is too loud, sounds distorted and is clipping, this option will not help. Do not use it. The distortion will still be there. Instead, decrease your input level by getting farther away from your microphone, adjusting your sound equipment or by decreasing your operating system's input settings. Input Boost combo box Bar (narrow) Paličky (úzke) Bar (wide) Paličky (široké) LEDs (stripe) Diódy (pás) LEDs (round, small) Diódy (okrúhle, malé) LEDs (round, big) Diódy (okrúhle, veľké) Audio Device Zvukové zariadenie Under the Windows operating system the ASIO driver (sound card) can be selected using %1. If the selected ASIO driver is not valid an error message is shown and the previous valid driver is selected. Under macOS the input and output hardware can be selected. Three buffer sizes can be selected Môžete si vybrať medzi tromi nastaveniami veľkosti vyrovnávacej pamäte 64 samples: Provides the lowest latency but does not work with all sound cards. 64 vzoriek: Poskytuje najnižšiu latenciu, ale nefunguje so všetkými zvukovými kartami. 256 samples: Should only be used when 64 or 128 samples is causing issues. 256 vzoriek: Mali by ste použiť iba vtedy, ak vám vyrovnávacia pamäť o veľkosti 64 alebo 128 spôsobuje problémy. Some sound card drivers do not allow the buffer delay to be changed from within %1. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. Use the appropriate tool for the interface in use to adjust this buffer size. For example, if using ASIO, use the "ASIO Device Settings" button to open the driver settings panel or if using JACK, use a tool such as QjackCtl to adjust the buffer size. Other interfaces, such as Pipewire, would require their appropriate tool being used. Please refer to the interface manual. If no buffer size is selected and all settings are disabled, this means a buffer size in use by the driver which does not match the values. %1 will still work with this setting but may have restricted performance. Ak nie je vybraná žiadna veľkosť vyrovnávacej pamäte a všetky nastavenia sú neaktívne, znamená to, že veľkosť vyrovnávacej pamäte, ktorý používa ovládač nesedí s hodnotami. %1 bude s týmito nastavenia fungovať, ale výkon môže byť nižší. The actual buffer delay has influence on the connection, the current upload rate and the overall delay. The lower the buffer size, the higher the probability of a red light in the status indicator (drop outs) and the higher the upload rate and the lower the overall delay. Meter Style Štýl ukazovateľa Meter Style combo box Custom Directories Vlastné adresáre If you need to add additional directories to the Connect dialog Directory drop down, you can enter the addresses here.<br>To remove a value, select it, delete the text in the input box, then move focus out of the control. Custom Directories combo box Audio Upstream Rate Depends on the current audio packet size and compression setting. Make sure that the upstream rate is not higher than your available internet upload speed (check this with a service such as speedtest.net). Number of Mixer Panel Rows Počet riadkov panela s mixérom Adjust the number of rows used to arrange the mixer panel. Number of Mixer Panel Rows spin box Feedback Protection Ochrana pred spätnou väzbou Enable feedback protection to detect acoustic feedback between microphone and speakers. Zapnite ochranu pred spätnou väzbou na detekciu akustickej väzby medzi mikrofónom a reproduktormi. Feedback Protection check box Zaškrtávacie pole ochrany pred spätnou väzbou Audio Alerts Zvukové upozornenia Enable audio alert when receiving a chat message and when a new client joins the session. A second sound device may be required to hear the alerts. Povoľte zvukové upozornenie pri prijatí správy v chate a keď sa pripojí nový klient. Pre prehratie upozornenia možno budete potrebovať ďalšie zariadenie zvuku. Audio Alerts check box Fancy Efektný Compact Kompaktný LEDs LEDky Bar Paličky Narrow Bar Úzke paličky Round LEDs Okrúhle LEDky Small LEDs Malé LEDky None Nenastavené Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country or region you are located in. Your city and skill level playing your instrument may also be added. Sem napíšte vaše meno alebo prezývku, aby ostatní hudobníci vedeli, s kým majú tú česť. Rovnako môžete pridať obrázok hudobného nástroja, na ktorý hráte a vlajku krajiny alebo regiónu, v ktorej/om sa nachádzate. Je možné pridať aj mesto a úroveň vašej hry na hudobný nástroj. What you set here will appear at your fader on the mixer board when you are connected to a %1 server. This tag will also be shown at each client which is connected to the same server as you. To, čo sem napíšete sa zobrazí pri vašom prelínači na mixéri po tom, ako sa pripojíte k serveru %1. Táto menovka sa rovnako zobrazí každému klientovi, ktorý sa pripojí k tomu istému serveru ako vy. Country/region flag button Tlačidlo s vlajkou krajiny/regiónu Center Stred R P Display Channel Levels Zobraziť úrovne kanálov Audio Channels Zvukové kanály mode will increase your stream's data rate. Make sure your upload rate does not exceed the available upload speed of your internet connection. Audio channels combo box Audio Quality Kvalita zvuku Audio quality combo box New Client Level Úroveň pre nových klientov New client level edit box If the ASIO4ALL driver is used, please note that this driver usually introduces approx. 10-30 ms of additional audio delay. Using a sound card with a native ASIO driver is therefore recommended. &Close &Zavrieť Local Audio Input Fader Miestny prelínač zvukového vstupu L L , where , kde is the current attenuation indicator. je indikátor aktuálneho útlmu. Local audio input fader (left/right) Miestny prelínač zvukového vstupu (ľavý/pravý) If the selected sound card device offers more than one input or output channel, the Input Channel Mapping and Output Channel Mapping settings are visible. The buffer delay setting is a fundamental setting of %1. This setting has an influence on many connection properties. 64 samples setting radio button ASIO Device Settings push button Custom Directory Server Address Adresa vlastného adresárového servera If this LED indicator turns red, you will not have much fun using the Ak sa dióda zmení na červenú, veľa zábavy si s touto aplikáciou software. neužijete. ASIO Setup Nastavenie ASIO Mono Mono-in/Stereo-out Mono-dnu/Stereo-von Stereo Stereo Controls the relative levels of the left and right local audio channels. For a mono signal it acts as a pan between the two channels. For example, if a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows %1, where %2 is the current attenuation indicator. The jitter buffer compensates for network and sound card timing jitters. The size of the buffer therefore influences the quality of the audio stream (how many dropouts occur) and the overall delay (the longer the buffer, the higher the delay). You can set the jitter buffer size manually for the local client and the remote server. For the local jitter buffer, dropouts in the audio stream are indicated by the light below the jitter buffer size faders. If the light turns to red, a buffer overrun/underrun has taken place and the audio stream is interrupted. If the Auto setting is enabled, the jitter buffers of the local client and the remote server are set automatically based on measurements of the network and sound card timing jitter. If Auto is enabled, the jitter buffer size faders are disabled (they cannot be moved with the mouse). If the Auto setting is enabled, the network buffers of the local client and the remote server are set to a conservative value to minimize the audio dropout probability. To tweak the audio delay/latency it is recommended to disable the Auto setting and to lower the jitter buffer size manually by using the sliders until your personal acceptable amount of dropouts is reached. The LED indicator will display the audio dropouts of the local jitter buffer with a red light. The buffer delay setting is a fundamental setting of this software. This setting has an influence on many connection properties. Nastavenie oneskorenia buffera je základným nastavením tohto programu. Toto nastavenie ovplyvňuje mnoho vlastností spojenia. 64 samples: The preferred setting. Provides the lowest latency but does not work with all sound cards. 64 vzoriek. Odporúčané nastavenie. Poskytuje najnižšiu latenciu, ale nefunguje pri všetkých zvukových kartách. 128 samples: Should work for most available sound cards. 128 vzoriek. Malo by fungovať pre väčšinu dostupných zvukových kariet. 256 samples: Should only be used on very slow computers or with a slow internet connection. 256 vzoriek: Toto nastavenie by ste mali použiť iba na veľmi pomalých počítačoch alebo pri pomalom internetovom pripojení. Some sound card drivers do not allow the buffer delay to be changed from within the application. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. On Windows, press the ASIO Setup button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Niektoré ovládače zvukových kariet nepovoľujú meniť oneskorenie buffera z prostredia aplikácie. V takom prípade je nastavenie oneskorenia buffera neaktívne a musíte ho zmeniť použitím ovládača zvukovej karty. Vo Windows kliknite na tlačidlo Nastaviť ASIO a otvoríte ovládací panel ovládača. V LInuxe použite pre zmenu veľkosti buffera konfiguračný nástroj Jack. Skin Vzhľad Select the skin to be used for the main window. Vyberte vzhľad, ktorý sa aplikuje na hlavné okno programu. Skin combo box Selects the number of audio channels to be used for communication between client and server. There are three modes available: These modes use one and two audio channels respectively. Mono in/Stereo-out Mono dnu/Stereo von The audio signal sent to the server is mono but the return signal is stereo. This is useful if the sound card has the instrument on one input channel and the microphone on the other. In that case the two input signals can be mixed to one mono channel but the server mix is heard in stereo. Enabling Zapnutím In stereo streaming mode, no audio channel selection for the reverb effect will be available on the main window since the effect is applied to both channels in this case. The higher the audio quality, the higher your audio stream's data rate. Make sure your upload rate does not exceed the available bandwidth of your internet connection. This setting defines the fader level of a newly connected client in percent. If a new client connects to the current server, they will get the specified initial fader level if no other fader level from a previous connection of that client was already stored. ASIO Device Settings Nastavenia zariadenia ASIO Low Nízka Normal Normálna High Vysoká Custom Vlastný All Genres Všetky žánre Any Genre 2 Ľubovoľný žáner 2 Any Genre 3 Ľubovoľný žáner 3 Genre Rock Žáner Rock Genre Jazz Žáner Jazz Genre Classical/Folk Žáner Klasika/Folk Genre Choral/Barbershop Žáner Zbor/Barbershop Any Genre 1 Ľubovoľný žáner 1 Genre Classical/Folk/Choral Žáner Klasika/Folk/Zbor Default Predvolený preferred preferované Musician Profile Profil hudobníka Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country you are located in. Your city and skill level playing your instrument may also be added. Sem napíšte vaše meno alebo prezývku, aby ostatní hudobníci vedeli, s kým majú tú česť. Rovnako môžete pridať obrázok hudobného nástroja, na ktorý hráte a vlajku krajiny, v ktorej sa nachádzate. Je možné pridať aj mesto a úroveň vašej hry na hudobný nástroj. What you set here will appear at your fader on the mixer board when you are connected to a Jamulus server. This tag will also be shown at each client which is connected to the same server as you. To, čo sem napíšete sa zobrazí pri vašom prelínači na mixéri po tom, ako sa pripojíte k Jamulus serveru. Táto menovka sa rovnako zobrazí každému klientovi, ktorý sa pripojí k tomu istému serveru ako vy. Alias or name edit box Instrument picture button Tlačidlo s obrázkom hud. nástroja Country flag button Tlačidlo s vlajkou krajiny City edit box Skill level combo box Beginner Začiatočník Intermediate Pokročilý Expert Expert Size: Veľkosť: Buffer Delay Oneskorenie vyr. pamäte Buffer Delay: Oneskorenie buffera: The selected audio device could not be used because of the following error: Vybrané audio zariadenie nie je možné použiť kvôli nasledujúcej chybe: The previous driver will be selected. Bude vybraný predchádzajúci ovládač. Ok Ok Drum Set Bicie Djembe Djembe Electric Guitar Elektrická gitara Acoustic Guitar Akustická gitara Bass Guitar Basová gitara Keyboard Keyboard Synthesizer Syntetizátor Grand Piano Koncertné krídlo Accordion Akordeón Vocal Vokály Microphone Mikrofón Harmonica Ústna harmonika Trumpet Trúbka Trombone Trombón French Horn Lesný roh Tuba Tuba Saxophone Saxofón Clarinet Klarinet Flute Flauta Violin Husle Cello Violončelo Double Bass Kontrabas Recorder Rekordér Streamer Streamovač Listener Poslucháč Guitar+Vocal Gitara+Vokály Keyboard+Vocal Klávesnica+Vokály Bodhran Bodhran Bassoon Fagot Oboe Hoboj Harp Harfa Viola Viola Congas Kongy Bongo Bongo Vocal Bass Basové vokály Vocal Tenor Tenorové vokály Vocal Alto Altové vokály Vocal Soprano Sopránové vokály Banjo Bendžo Mandolin Mandolína Ukulele Ukulele Bass Ukulele Basové ukulele Vocal Baritone Barytónové vokály Vocal Lead Hlavný spev Mountain Dulcimer Horský dulcimer Scratching Skrečing Rapping Repovanie Vibraphone Vibrafón Conductor Dirigent CClientSettingsDlgBase Settings Nastavenia Soundcard Zvuková karta Device Zariadenie Input Channel Mapping Mapovanie vstupného kanála L L R P Output Channel Mapping Mapovanie výstupného kanála Enable Small Network Buffers Povoliť malú vyr. pamäť siete Buffer Delay Oneskorenie buffera Country/Region Krajina/Región (preferred) (preferované) (default) (predvolené) (safe) (bezpečné) Driver Setup Konfigurácia ovládača My Profile Môj profil Musician's Profile Profil hudobníka Alias/Name Prezývka/Meno Instrument Hud. nástroj Country Krajina City Mesto Skill Úroveň hrania User Interface Používateľské rozhranie Meter Style Štýl ukazovateľa Mixer Rows Riadky mix. pultu Audio Alerts Zvukové upozornenia Audio/Network Setup Nastavenie zvuku/siete Audio Device Zvukové zariadenie Jitter Buffer Vyr. pamäť chvenia Auto Automaticky Local Lokálna Server Servera Size Veľkosť kbps kb/s Custom Directories: Vlastné adresáre: Input Boost Zosilnenie vstupu Feedback Protection Ochrana pred spätnou väzbou Enable Povoliť Input Balance Vyváženie vstupu Pan Posun Center Stred Misc Rôzne Audio Channels Zvukové kanály Audio Quality Kvalita zvuku Measurements Štatistiky Advanced Setup Pokročilé nastavenia Custom Central Server Address: Adresa vlastného adresárového servera: New Client Level Úroveň pre nových klientov Skin Vzhľad Language Jazyk % % Local Jitter Buffer Miestny jitter buffer Display Channel Levels Zobraziť úrovne kanálov Custom Directory Server Address: Adresa vlastného centrálneho servera: Audio Stream Rate Rýchlosť streamovania zvuku val hodn Ping Time Čas odpovede Overall Delay Celkové oneskorenie CConnectDlg Directory Adresár Shows the servers listed by the selected directory. You can add custom directories in Advanced Settings. Zobrazí servery uvedené vo vybranom adresári. V pokročilých nastaveniach môžete pridať vlastné adresáre. Directory combo box Filters the server list by the given text. Note that the filter is case insensitive. A single # character will filter for those servers with at least one person connected. Filtruje zoznam serverov podľa zadaného textu. Všimnite si, že filter neberie ohľad na veľkosť písmen. Samostatný znak # zobrazí iba servery, ku ktorému je pripojená aspoň jedna osoba. Uncheck to collapse the server list to show just the server details. Check to show everyone on the servers. Server List Zoznam serverov The Connection Setup window lists the available servers registered with the selected directory. Use the Directory dropdown to change the directory, find the server you want to join in the server list, click on it, and then click the Connect button to connect. Alternatively, double click on the server name to connect. Permanent servers (those that have been listed for longer than 48 hours) are shown in bold. Stále servery (tie, ktoré sú v zozname dlhšie ako 48 hodín) sú zobrazené tučným písmom. You can add custom directories in Advanced Settings. V pokročilých nastaveniach môžete pridať vlastné adresáre. Server list view Okno so zoznamom serverov Server Address Adresa servera If you know the server address, you can connect to it using the Server name/Address field. An optional port number can be added after the server address using a colon as a separator, e.g. %1. The field will also show a list of the most recently used server addresses. Holds the current server address. It also stores old addresses in the combo box list. The Connection Setup window shows a list of available servers. Server operators can optionally list their servers by music genre. Use the List dropdown to select a genre, click on the server you want to join and press the Connect button to connect to it. Alternatively, double click on on the server name. Permanent servers (those that have been listed for longer than 48 hours) are shown in bold. Okno Nastavenie pripojenia zobrazuje zoznam dostupných serverov. Prevádzkovatelia serverov môžu voliteľne zadať hudobný žáner. V rozbaľovacej ponuke vyberte žáner, kliknite na server, ku ktorému sa chcete pripojiť a kliknutím na tlačidlo Pripojiť sa pripojíte k serveru. Prípadne stačí dvakrát kliknúť na meno servera. Trvalé servery (také, ktoré sú v zozname viac ako 48 hodín) sú zobrazené tučným písmom. Server address edit box Server List Selection Výber zoznamu serverov Filter Filter The server list is filtered by the given text. Note that the filter is case insensitive. Zoznam serverov bude filtrovaný na základe zadaného textu. Všimnite si, že filter neberie ohľad na veľkosť písmen. Filter edit box Show All Musicians Zobraziť všetkých hudobníkov If you check this check box, the musicians of all servers are shown. If you uncheck the check box, all list view items are collapsed. Ak zaškrtnete toto políčko, budú zobrazení hudobníci na všetkých serverov. Ak ho necháte nezaškrtnuté, žiadne položky zoznamu nebudú rozbalené. Show all musicians check box Zaškrtávacie políčko Zobraziť všetkých hudobníkov If you know the IP address or URL of a server, you can connect to it using the Server name/Address field. An optional port number can be added after the IP address or URL using a colon as a separator, e.g. %1. The field will also show a list of the most recently used server addresses. Ak viete IP adresu alebo URL adresu servera, môžete sa naň pripojiť jej zadaním do políčka názov/adresa server. Voliteľne môžete pridať za IP adresu alebo URL adresu aj číslo portu s tým, že použijete dvojbodku ako oddeľujúci znak, napr. %1. Toto políčko zobrazí tiež zoznam naposledy použitých adries. Filter text, or # for occupied servers Filtrujte podľa textu alebo # pre obsadené servery Type # for occupied servers Zadajte # pre obsadené servery CConnectDlgBase Connection Setup Parametre pripojenia List Zoznam Directory Adresár Filter Filter Show All Musicians Zobraziť všetkých hudobníkov Server Name Meno servera Ping Time Čas odpovede Musicians Hudobníci Location Miesto Server Address Adresa servera Server Name/Address Meno servera/Adresa C&ancel &Zrušiť &Connect &Pripojiť CHelpMenu &Help Po&mocník Getting &Started... &Začíname... Software &Manual... &Manuál programu... What's &This Čo j&e toto &About Jamulus... &O programe Jamulus... About &Qt... O &Qt... &About... &O programe... About Qt O Qt CLanguageComboBox Restart Required Vyžadovaný reštart Please restart the application for the language change to take effect. Aby sa zmeny nastavenia jazyku prejavili, musíte reštartovať aplikáciu. CLicenceDlg I &agree to the above licence terms &Súhlasím s licenčnými podmienkami vyššie This server requires you accept conditions before you can join. Please read these in the chat window. Tento server od vás pred pripojením vyžaduje akceptovanie podmienok. Prosím, prečítajte si ich v okne chatu. I have read the conditions and &agree. Prečítal som si podmienky a &akceptujem ich. Accept Akceptovať Decline Odmietnuť By connecting to this server and agreeing to this notice, you agree to the following: Pripojením sa na tento server a prijatím tohto oznámenia, súhlasíte s nasledovným: Share Zdieľať ShareAlike ShareAlike No additional restrictions Žiadne ďalšie obmedzenia CMultiColorLED Red Červená Yellow Žltá Green Zelená CMusProfDlg Musician Profile Profil hudobníka Alias/Name Prezývka/Meno Instrument Hud. nástroj Country Krajina City Mesto Skill Úroveň hrania &Close &Zavrieť None Nenastavené Beginner Začiatočník Intermediate Pokročilý Expert Expert Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country you are located in. Your city and skill level playing your instrument may also be added. Sem napíšte vaše meno alebo prezývku, aby ostatní hudobníci vedeli, s kým majú tú česť. Rovnako môžete pridať obrázok hudobného nástroja, na ktorý hráte a vlajku krajiny, v ktorej sa nachádzate. Je možné pridať aj mesto a úroveň hry na hudobný nástroj. What you set here will appear at your fader on the mixer board when you are connected to a Jamulus server. This tag will also be shown at each client which is connected to the same server as you. To, čo sem napíšete sa zobrazí pri vašom prelínači na mixéri po tom, ako sa pripojíte k Jamulus serveru. Táto menovka sa rovnako zobrazí každému klientovi, ktorý sa pripojí k tomu istému serveru ako vy. Instrument picture button Tlačidlo s obrázkom hud. nástroja Country flag button Tlačidlo s vlajkou krajiny Drum Set Bicie Djembe Djembe Electric Guitar Elektrická gitara Acoustic Guitar Akustická gitara Bass Guitar Basová gitara Keyboard Keyboard Synthesizer Syntetizátor Grand Piano Koncertné krídlo Accordion Akordeón Vocal Vokály Microphone Mikrofón Harmonica Ústna harmonika Trumpet Trúbka Trombone Trombón French Horn Lesný roh Tuba Tuba Saxophone Saxofón Clarinet Klarinet Flute Flauta Violin Husle Cello Violončelo Double Bass Kontrabas Recorder Zobcová flauta Streamer Streamovač Listener Poslucháč Guitar+Vocal Gitara+Vokály Keyboard+Vocal Klávesnica+Vokály Bodhran Bodhran Bassoon Fagot Oboe Hoboj Harp Harfa Viola Viola Congas Kongy Bongo Bongo Vocal Bass Basové vokály Vocal Tenor Tenorové vokály Vocal Alto Altové vokály Vocal Soprano Sopránové vokály Banjo Bendžo Mandolin Mandolína Ukulele Ukulele Bass Ukulele Basové ukulele Vocal Baritone Barytónové vokály Vocal Lead Hlavný spev Rapping Repovanie No Name Bez názvu CServerDlg Client List Zoznam klientov The client list shows all clients which are currently connected to this server. Some information about the clients like the IP address and name are given for each connected client. Zoznam klientov zobrazuje všetkých klientov, ktorí su momentálne pripojení k serveru. Pri každom klientovi sú zobrazené dodatočné informácie, ako napr. IP adresa a meno. Connected clients list view Zoznam pripojených klientov Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user %1 is running as). The current value of the main recording directory. The chosen value must exist and be writeable (allow creation of sub-directories by the user %1 is running as). Click the button to open the dialog that allows the main recording directory to be selected. Custom Directory address Adresa vlastného adresára The Custom Directory address is the address of the directory holding the server list to which this server should be added. Adresa vlastného adresára je adresa, na ktorej sa nachádza adresár so zoznamom serverov, do ktorého sa má tento server pridať. Server List Filename dialog push button Server List Filename Meno súboru so zoznamom na serveri Click the button to open the dialog that allows the server list persistence file name to be set. The user %1 is running as needs to be able to create the file name specified although it may already exist (it will get overwritten on save). Server List Filename text box (read-only) The current value of server list persistence file name. The user %1 is running as needs to be able to create the file name specified although it may already exist (it will get overwritten on save). Click the button to open the dialog that allows the server list persistence file name to be set. Clear the server list file name button Clear Server List Filename Click the button to clear the currently selected server list persistence file name. This will prevent persisting the server list until a new value is selected. Start Minimized on Operating System Start Spustiť minimalizované pri štarte operačného systému Show Creative Commons Licence Dialog Zobraziť dialógové okno s licenciou Creative Commons License If enabled, a Creative Commons BY-NC-SA 4.0 Licence dialog is shown each time a new user connects the server. Ak je povolené vždy po pripojení na server sa klientom zobrazí dialógové okno s licenciou Creative Commons BY-NC-SA 4.0. Make My Server Public Nastaviť server ako verejný Register Server Status Stav registrácie servera If the Make My Server Public check box is checked, this will show whether registration with the directory server is successful. If the registration failed, please choose another server list. Ak je zapnutá voľba Nastaviť server ako verejný, tu sa zobrazí, či bola registrácia na adresárovom serveri úspešná. Ak registrácia zlyhala, prosím, vyberte iný zoznam serverov. Custom Directory Server Address Adresa vlastného adresárového servera The custom directory server address is the IP address or URL of the directory server at which the server list of the connection dialog is managed. Adresa vlastného adresárového servera je IP adresa alebo URL adresárového servera, kde je spravovaný zoznam serverov pre dialógové okno, ktoré je zobrazené klientom. Server List Selection Výber zoznamu serverov Selects the server list (i.e. directory server address) in which your server will be added. Vyberá zoznam serverov (t. j. adresu adresárového servera), do ktorého bude pridaný váš server. Server Name Názov servera Server name line edit Location City Umiestnenie/mesto The city in which this server is located can be set here. If a city name is entered, it will be shown in the connect dialog server list at the clients. Tu môžete nastaviť, v ktorom meste sa server nachádza. Ak je mesto zadané, zobrazí sa klientom v okne so zoznamom serverov. City where the server is located line edit Location country Umiestnenie/krajina Display dialog to select recording directory button Main Recording Directory Hlavný adresár na nahrávanie Main recording directory text box (read-only) Clear the recording directory button Clear Recording Directory Click the button to clear the currently selected recording directory. This will prevent recording until a new value is selected. Checkbox to turn on or off server recording Enable Recorder Povoliť nahrávanie Checked when the recorder is enabled, otherwise unchecked. The recorder will run when a session is in progress, if (set up correctly and) enabled. Current session directory text box (read-only) Current Session Directory Enabled during recording and holds the current recording session directory. Disabled after recording or when the recorder is not enabled. Recorder status label Directory Type combo box Directory Adresár Select '%1' not to register your server with a directory. Select one of the genres to register with that directory. Or select '%1' and specify a Custom Directory address on the Options tab to register with a custom directory. For any value except '%1', this server registers with a directory so that a %2 user can select this server in the client connect dialog server list when they choose that directory. The registration of the server is renewed periodically to make sure that all servers in the connect dialog server list are actually available. When a value other than "%1" is chosen for Directory, this will show whether registration is successful. If the registration failed, please choose a different directory. Recorder Status Stav nahrávania No recording directory has been set or the value is not useable. Check the value in the Options tab. Recording has been switched off by the UI checkbox. Nahrávanie bolo vypnuté pomocou začiarkavacieho políčka. Recording has been switched off, either by the UI checkbox or SIGUSR2 being received. Nahrávanie bolo vypnuté, buď prostredníctvom začiarkavacieho políčka alebo bol prijatý signál SIGUSR2. If the recording directory is not useable, the problem will be displayed in place of the session directory. Server welcome message edit box Server Welcome Message Uvítacia správa servera A server welcome message text is displayed in the chat window if a musician enters the server. If no message is set, the server welcome is disabled. Language Jazyk Select the language to be used for the user interface. Vyberte jazyk, ktorý sa použije v rozhraní aplikácie. Language combo box Now a directory Custom Directory Vlastný adresár Custom Directory line edit &Hide %1 server Sk&ryť %1 server &Show %1 server Z&obraziť %1 server %1 server %1 is the name of the main application %1 server Type a message here. If no message is set, the server welcome is disabled. Sem napíšte správu. Ak nie je nastavená žiadna správa, uvítacia správa servera bude vypnutá. software upgrade available dostupná aktualizácia softvéru Recorder failed to start. Please check available disk space and permissions and try again. Error: Nahrávanie sa nepodarilo spustiť. Skontrolujte, prosím, či je na disku dosť miesta a práva na zápis a skúste to znovu. Chyba: ERROR CHYBA Request new recording button New Recording Nová nahrávka During a recording session, the button can be used to start a new recording. Počas nahrávania sedenia môžete použiť toto tlačidlo na spustenie novej nahrávky. E&xit U&končiť &Hide &Skryť server server &Open &Otvoriť Select Main Recording Directory Vybrať hlavný adresár na nahrávanie Server Server If the start minimized on operating system start check box is checked, the server will be started when the operating system starts up and is automatically minimized to a system task bar icon. The server name identifies your server in the connect dialog server list at the clients. Country/Region Krajina/Región Set the country or region where the server is running. Clients will show this location in their connect dialog's server list. Combo box for location of this server Displays the current status of the recorder. The following values are possible: There is no one connected to the server to record. The performers are being recorded to the specified session directory. NOTE POZNÁMKA %1 Server %1 is the name of the main application %1 Server &Window &Okno Unregistered Neregistrovaný None Žiadny Not registered Neregistrovaný Bad address Zlá adresa Registration requested Vyžiadaná registrácia Registration failed Registrácia zlyhala Check server version Skontrolovať verziu servera Registered Registrovaný Directory server list full Zoznam adresárového servera je plný Directory Server full Adresárový server je plný Your server version is too old Verzia vášho servera je príliš stará Requirements not fulfilled Požiadavky nie sú splnené Unknown value %1 Neznáma hodnota %1 Unknown value Neznáma hodnota Not initialised Neinicializované Not enabled Nie je zapnuté Not recording Nenahráva sa Recording Nahráva sa CServerDlgBase Client IP:Port IP:Port klienta Name Meno Jitter Buffer Size Vyr. pamäť chvenia Channels Kanály Server Setup Nastavenie servera List Zoznam Location: Region Umiestnenie: Oblasť Session Sedenie Chat Window Welcome (HTML/CSS Supported) Uvítacia správa chatového okna (podporuje HTML/CSS) Options Nastavenia Custom Directory address Adresa vlastného adresára Server List Filename Meno súboru so zoznamom na serveri Start Minimized on Windows Start Spustiť minimalizované pri štarte Windows Enable delay panning Zapnúť posun oneskorenia Update check Kontrola aktualizácií Make My Server Public (Register My Server in the Server List) Nastaviť server ako verejný (zaregistrovať v zozname serverov) Genre Žáner STATUS STATUS Custom Directory Server Address: Adresa vlastného adresárového servera: My Server Info Informácie o serveri Location: City Umiestnenie: Mesto Location: Country Umiestnenie: Krajina Recording Directory Adresár pre nahrávanie Enable Jam Recorder Povoliť nahrávanie džemov Directory Adresár New Recording Nová nahrávka Language Consider add "(Lang)" as a suffix to ensure that users who selected the wrong language find the correct button Jazyk CServerListManager Could not write to '%1' Nepodarilo sa zapísať do '%1' CSound Error requesting stream stop: $s Chyba pri požiadavke na zastavenie streamu: $s Error closing stream: $s Chyba pri zatváraní streamu: $s The Jack server is not running. This software requires a Jack server to run. Normally if the Jack server is not running this software will automatically start the Jack server. It seems that this auto start has not worked. Try to start the Jack server manually. Server Jack nie je spustený. Tento softvér vyžaduje pre svoj beh server Jack. Za normálnych okolností, ak Jack nebeží, tento program sa ho pokúsi automaticky naštartovať. Vyzerá, že automatické spustenie zlyhalo. Pokúste sa spustiť server Jack ručne. The Jack server sample rate is different from the required one. The required sample rate is: Vzorkovacia frekvencia servera Jack sa líši od vyžadovanej. Vyžadovaná frekvencia vzorkovania je: You can use a tool like <i><a href="https://qjackctl.sourceforge.io">QJackCtl</a></i> to adjust the Jack server sample rate. Pre úpravu vzorkovacej frekvencie môžete použiť nástroj ako napr. <i><a href="https://qjackctl.sourceforge.io">QJackCtl</a></i>. Make sure to set the Frames/Period to a low value like Ubezpečte sa, že nastavenie Snímky/Perióda je nastavené na nízku hodnotu ako to achieve a low delay. , aby ste dosiahli nízke oneskorenie. The Jack port registering failed. Registrácia portu Jack zlyhala. Cannot activate the Jack client. Nepodarilo sa aktivovať klienta Jack. The Jack server was shut down. This software requires a Jack server to run. Try to restart the software to solve the issue. Server Jack bol vypnutý. Tento program vyžaduje, aby bol server Jack spustený. Pokúste sa reštartovať tento program a vyriešiť tak tento problém. The audio input device is no longer available. Vstupné zvukové zariadenie už nie je dostupné. The audio output device is no longer available. Výstupné zvukové zariadenie už nie je dostupné. The audio driver could not be initialized. Audio ovládač sa nepodarilo inicializovať. The audio device does not support the required sample rate. The required sample rate is: Zvukové zariadenie nepodporuje požadovanú vzorkovaciu frekvenciu. Požadovaná vzorkovacia frekvencia je: software. neužijete. The selected audio device is no longer present in the system. Please check your audio device. Vybrané zvukové zariadenie už nie je v systéme dostupné. Prosím, skontrolujte ho. Couldn't initialise the audio driver. Check if your audio hardware is plugged in and verify your driver settings. Nepodarilo sa inicializovať audio ovládač. Skontrolujte, či je váš zvukový hardvér zapojený a preverte nastavenia ovládača. The selected audio device is incompatible since it doesn't support a sample rate of %1 Hz. Please select another device. Vybrané zvukové zariadenie je nekompatibilné, pretože nepodporuje vzorkovaciu frekvenciu %1 Hz. Prosím, vyberte iné zariadenie. The current audio device configuration is incompatible because the sample rate couldn't be set to %2 Hz. Please check for a hardware switch or driver setting to set the sample rate manually and restart %1. Aktuálna konfigurácia zvukového zariadenia nie je kompatibilná, pretože nepodporuje vzorkovaciu frekvenciu %2 Hz. Prosím skontrolujte, či neexistuje hardvérový prepínač alebo nastavenie ovládača, ktoré umožní nastaviť vzorkovaciu frekvenciu manuálne a reštartujte %1. The selected audio device is incompatible since it doesn't support %1 in/out channels. Please select another device or configuration. Vybrané zvukové zariadenie nie je kompatibilné, pretože nepodporuje %1 vstupných/výstupných kanálov. Prosím, vyberte iné zariadenie alebo konfiguráciu. The selected audio device is incompatible since the required audio sample format isn't available. Please use another device. Vybrané zvukové zariadenie nie je kompatibilné, pretože vybraný formát vzorkovania nie je dostupný. Vyberte, prosím, iné zariadenie. No ASIO audio device driver found. Nebol nájdený zvukový ovládač ASIO. Please install an ASIO driver before running %1. If you own a device with ASIO support, install its official ASIO driver. If not, you'll need to install a universal driver like ASIO4ALL. JACK couldn't be started automatically. Please start JACK manually and check for error messages. Server JACK sa nepodarilo spustiť automaticky. Prosím, spustite JACK server ručne a skontrolujte chybové hlásenia. JACK isn't running at a sample rate of <b>%1 Hz</b>. Please use a tool like <i><a href="https://qjackctl.sourceforge.io">QjackCtl</a></i> to set the the JACK sample rate to %1 Hz. Server JACK nebeží na vzorkovacej frekvencii <b>%1 Hz</b>. Prosím, použite nástroj ako je <i><a href="https://qjackctl.sourceforge.io">QjackCtl</a></i> a nastavte v ňom vzorkovaciu frekvenciu servera JACK na %1 Hz. The JACK port registration failed. This is probably an error with JACK. Please stop %1 and JACK. Afterwards check if another program at a sample rate of %2 Hz can connect to JACK. Chyba pri registrovaní portu JACK. Pravdepodobne sa jedná o chybu servera JACK. Prosím, zastavte %1 a následne aj JACK server. Potom sa presvedčte, či sa k JACK server dokáže pripojiť iný program pri použití vzorkovacej frekvencie %2 Hz. The JACK port registration failed. This is probably an error with JACK. Please stop %1 and JACK. Afterwards, check if another MIDI program can connect to JACK. Chyba pri registrovaní portu JACK. Pravdepodobne sa jedná o chybu servera JACK. Prosím, zastavte %1 a následne aj JACK server. Potom sa presvedčte, či sa k JACK server dokáže pripojiť iný program MIDI. Can't activate the JACK client. This is probably an error with JACK. Please check the JACK output. Nie je možné aktivovať klienta JACK. Pravdepodobne sa jedná o chybu JACK. Skontrolujte, prosím, výstup servera JACK. JACK was shut down. %1 requires JACK to run. Please restart %1 to start JACK again. Server JACK bol vypnutý. %1 vyžaduje, aby bol JACK spustený. Prosím, reštartujte %1, aby sa JACK opäť spustil. No sound card is available in your system. CoreAudio input AudioHardwareGetProperty call failed. V systéme nie je žiadna dostupná zvuková karta. Volanie AudioHardwareGetProperty vstupu CoreAudio skončilo s chybou. No sound card is available in the system. CoreAudio output AudioHardwareGetProperty call failed. V systéme nie je žiadna dostupná zvuková karta. Volanie AudioHardwareGetProperty výstupu CoreAudio skončilo s chybou. The currently selected audio device is no longer present. Please check your audio device. Vybrané zvukové zariadenie už nie je v systéme dostupné. Prosím, skontrolujte ho. The audio input device is no longer available. Please check if your input device is connected correctly. Vybrané zvukové zariadenie pre vstup už nie je v systéme dostupné. Prosím, skontrolujte, či je vaše zariadenie správne pripojené. The sample rate on the current input device isn't %1 Hz and is therefore incompatible. Please select another device or try setting the sample rate to %1 Hz manually via Audio-MIDI-Setup (in Applications->Utilities). The audio output device is no longer available. Please check if your output device is connected correctly. Vybrané zvukové zariadenie pre výstup už nie je dostupné. Prosím, skontrolujte, či je vaše zariadenie správne pripojené. The sample rate on the current output device isn't %1 Hz and is therefore incompatible. Please select another device or try setting the sample rate to %1 Hz manually via Audio-MIDI-Setup (in Applications->Utilities). The stream format on the current input device isn't compatible with this software. Please select another device. The stream format on the current output device isn't compatible with %1. Please select another device. The buffer sizes of the current input and output audio device can't be set to a common value. Please select different input/output devices in your system settings. CSoundBase Invalid device selection. Neplatný výber zariadenia. Please restart the software. Prosím, reštartujte tento program. Close Zavrieť The selected audio device could not be used because of the following error: Vybrané audio zariadenie nie je možné použiť kvôli nasledujúcej chybe: The previous driver will be selected. Bude vybraný predchádzajúci ovládač. The previously selected audio device is no longer available or the audio driver properties have changed to a state which is incompatible with this software. We now try to find a valid audio device. This new audio device might cause audio feedback. So, before connecting to a server, please check the audio device setting. V minulosti vybrané zvukové zariadenia už nie je dostupné alebo sa zmenili vlastnosti ovládača zvuku tak, že už naďalej nie sú kompatibilné s týmto programom. Teraz sa pokúsim nájsť platné zvukové zariadenie. Pred pripojením sa k serveru preto skontrolujte nastavenia zvukového zariadenia. No usable Nebolo nájdené žiadne audio device (driver) found. použiteľné zvukové zariadenie (ovládač). could not be started because of audio interface issues. sa nepodarilo spustiť kvôli problému s rozhraním zvuku. Can't use the selected audio device because of the following error: %1 The previous driver will be selected. Nie je možé použiť vybrané zvukové zariadenie kvôli nasledujúcej chyba: %1 Bude vybraný predchádzajúci ovládač zvuku. The previously selected audio device is no longer available or the driver has changed to an incompatible state. We'll attempt to find a valid audio device, but this new audio device may cause feedback. Before connecting to a server, please check your audio device settings. V minulosti vybrané zvukové zariadenia už nie je dostupné alebo sa zmenili vlastnosti ovládača zvuku tak, že už nie sú kompatibilné. Teraz sa pokúsime nájsť platné zvukové zariadenie, ale toto nové zariadenie môže spôsobiť spätnú väzbu. Pred pripojením sa k serveru preto skontrolujte nastavenia zvukového zariadenia. <b>%1 couldn't find a usable %2 audio device.</b><br><br> <b>%1 nemohol nájsť použiteľné zariadenie zvuku %2.</b><br><br> You may be able to fix errors in the driver settings. Do you want to open these settings now? Možno budete vedieť opraviť chyby v nastaveniach ovládača. Chcete tieto nastavenia otvoriť teraz? No usable %1 audio device found. Nebolo nájdené žiadne použitelné zvukové zariadenie %1. These are all the available drivers with error messages: Toto sú všetky dostupné ovládače spolu s chybovými hláseniami: Can't start %1. Please restart %1 and check/reconfigure your audio settings. Nepodarilo sa spustiť %1. Prosím, znovu spustite %1 a skontrolujte/zmeňte nastavenia zvuku. QCoreApplication %1, Version %2 %1, Verzia %2 Internet Jam Session Software Softvér na džemovanie cez internet %1, Version %2 %1 is app name, %2 is version number %1, Verzia %2 Released under the GNU General Public License version 2 or later (GPLv2) Vydané pod licenciou GNU General Public License verzie 2 alebo novšej (GPLv2) This program is free software; you can redistribute it and/or modify it under Tento program je slobodný softvér: môžete ho šíriť a/alebo upravovať podľa the terms of the GNU General Public License as published by the Free Software podmienok GNU General Public License publikovanou Free Software Foundation; either version 2 of the License, or (at your option) any later version. Foundation a to buď verzie 2 tejto licencie alebo (podľa vlastného zváženia) ktorejkoľvek novšej verzie. There is NO WARRANTY, to the extent permitted by law. Neposkytuje sa ŽIADNA ZÁRUKA, v rozsahu povolenom zákonmi. Using the following libraries, resources or code snippets: Používa nasledujúce knižnice, zdroja alebo úryvky kódu: Qt framework Qt framework Opus Interactive Audio Codec zvukový kodek Opus Interactive Audio Codec Audio reverberation code by Perry R. Cook and Gary P. Scavone Kód pre ozvenu (reverb): Perry R. Cook a Gary P. Scavone Some pixmaps are from the Open Clip Art Library (OCAL) Niektoré obrázky pochádzajú z knižnice Open Clip Art (OCAL) Flag icons by Mark James Ikony vlajok: Mark James Copyright (C) 2005-2022 The Jamulus Development Team Autorské práva (C) 2005-2022 The Jamulus Development Team Released under the GNU General Public License (GPL) Vydané pod licenciou GNU General Public License (GPL) global A %1 upgrade is available: <a style='color:red;' href='https://jamulus.io/upgrade?progversion=%2'>go to details and downloads</a> Je dostupná aktualizácia %1: <a style='color:red;' href='https://jamulus.io/upgrade?progversion=%2'>prejsť na podrobnosti a preberania</a> For more information use the "What's This" help (help menu, right mouse button or Shift+F1) Pre získanie viac informácii, použite "Čo je toto?" (ponuka pomocníka, pravé tlačidlo myši alebo Shift+F1) jamulus-3.9.1+dfsg/src/translation/translation_fr_FR.ts0000644000175000017500000071347214340334543022303 0ustar vimervimer CAboutDlg Qt cross-platform application framework Cadriciel d'application multiplateforme Qt Audio reverberation code by Perry R. Cook and Gary P. Scavone Code de réverbération audio par Perry R. Cook et Gary P. Scavone Some pixmaps are from the Certaines images sont issues de This app enables musicians to perform real-time jam sessions over the internet. Cette application permet aux musiciens de faire des bœufs en temps réel sur internet. There is a server which collects the audio data from each client, mixes the audio data and sends the mix back to each client. Un serveur collecte les données audio de chaque client, les mixe et renvoie le résultat à chaque client. This app uses the following libraries, resources or code snippets: Cette application utilise les bibliothèques, ressources ou extraits de code suivants : Country flag icons by Mark James Icônes de drapeaux de pays par Mark James For details on the contributions check out the Pour plus de détails sur les contributions, consultez la Flag icons by Mark James Icônes de drapeaux par Mark James Some sound samples are from Certains échantillons sonores sont issus de For details on the contributions check out the %1 Pour plus de détails sur les contributions, consultez le site %1 Github Contributors list liste de contributeurs sur GitHub Spanish Espagnol French Français Portuguese Portugais Dutch Néerlandais Italian Italien German Allemand Polish Polonais Swedish Suédois Korean Coréen Slovak Slovaque Simplified Chinese Chinois simplifié Norwegian Bokmål About %1 À propos %1 About À propos CAboutDlgBase About À propos TextLabelVersion Version d'étiquette de texte Copyright (C) 2005-2022 The Jamulus Development Team Copyright (C) 2005-2022 L'équipe de développement de Jamulus A&bout À &propos &Libraries &Bibliothèques &Contributors &Contributeurs &Translation &Traduction &OK &OK CAnalyzerConsole Analyzer Console Console d'analyse Error Rate of Each Buffer Size Taux d'erreur de chaque taille de tampon CAudioMixerBoard Personal Mix at the Server Mixage personnel au serveur When connected to a server, the controls here allow you to set your local mix without affecting what others hear from you. The title shows the server name and, when known, whether it is actively recording. Lorsque vous êtes connecté à un serveur, les contrôles vous permettent de régler votre mixage local sans affecter ce que les autres entendent de vous. Le titre indique le nom du serveur et, lorsque c'est le cas, s'il est en train d'enregistrer. Server Serveur T R Y I N G T O C O N N E C T T E N T A T I V E D E C O N N E X I O N RECORDING ACTIVE ENREGISTREMENT ACTIF Personal Mix at: %1 Mixage personnel à : %1 CChannelFader Channel Level Niveau de canal Input level of the current audio channel at the server Niveau d'entrée du canal audio actuel sur le serveur Mixer Fader Chariot du mixeur Local mix level setting of the current audio channel at the server Réglage du niveau de mixage local du canal audio actuel sur le serveur Status Indicator Indicateur d'état Shows a status indication about the client which is assigned to this channel. Supported indicators are: Affiche une indication sur l'état du client qui est affecté à ce canal. Les indicateurs pris en charge sont : Status indicator label Étiquette d'indicateur d'état Panning Panoramique Local panning position of the current audio channel at the server Position panoramique locale du canal audio actuel sur le serveur With the Mute checkbox, the audio channel can be muted. En cochant la case Me silencer, le canal audio peut être mis en sourdine. Mute button Bouton de sourdine Solo button Bouton de solo Fader Tag Étiquette de chariot The fader tag identifies the connected client. The tag name, a picture of your instrument and the flag of your location can be set in the main window. L'étiquette de chariot identifie le client connecté. Votre nom, une image de votre instrument et le drapeau de votre emplacement peuvent être définis dans la fenêtre principale. Mixer channel country/region flag Drapeau de pays/région du canal de mixage Grp Grp Displays the pre-fader audio level of this channel. All clients connected to the server will be assigned an audio level, the same value for every client. Affiche le niveau audio pré-chariot de ce canal. Tous les clients connectés au serveur se verront attribuer un niveau audio, la même valeur pour chaque client. &No grouping &Pas de regroupement Assign to group Affecter au groupe Adjusts the audio level of this channel. All clients connected to the server will be assigned an audio fader, displayed at each client, to adjust the local mix. Ajuste le niveau audio de ce canal. Tous les clients connectés au serveur se verront attribuer un chariot audio, affiché sur chaque client, pour ajuster le mixage local. Speaker with cancellation stroke: Indicates that another client has muted you. Haut-parleur barré : indique qu'un autre client vous a mis en sourdine. Sets the pan from Left to Right of the channel. Works only in stereo or preferably mono in/stereo out mode. Règle le panoramique de gauche à droite du canal. Fonctionne uniquement en mode stéréo ou de préférence en mode entrée mono/sortie stéréo. With the Solo checkbox, the audio channel can be set to solo which means that all other channels except the soloed channel are muted. It is possible to set more than one channel to solo. En cochant la case Solo, le canal audio peut être réglé sur solo, ce qui signifie que tous les canaux qui ne sont pas cochés, sont en sourdine. Il est possible de mettre plus d'un canal en solo. Group Groupe With the Grp checkbox, a group of audio channels can be defined. All channel faders in a group are moved in proportional synchronization if any one of the group faders are moved. Avec la case à cocher Grp, un groupe de canaux audio peut être défini. Tous les chariots de canaux d'un groupe sont déplacés en synchronisation proportionnelle si l'un des chariots du groupe est déplacé. Group button Bouton de groupe The fader tag identifies the connected client. The tag name, a picture of your instrument and the flag of your country can be set in the main window. L'étiquette de chariot identifie le client connecté. Le nom de l'étiquette, une photo de votre instrument et le drapeau de votre pays peuvent être définis dans la fenêtre principale. Mixer channel instrument picture Image d'instrument de canal de mixeur Mixer channel label (fader tag) Label de canal de mixeur (étiquette de chariot) Mixer channel country flag Drapeau de pays de canal de mixeur PAN PAN MUTE MUET SOLO SOLO GRP GRP M M S S G G Alias/Name Pseudo/nom Instrument Instrument Location Localisation Skill Level Niveau de compétence Alias Alias Beginner Débutant Intermediate Intermédiaire Expert Expert Musician Profile Profil de musicien Mute Muet Pan Pan Solo Solo CChatDlg Chat Window Fenêtre de tchate The chat window shows a history of all chat messages. La fenêtre de tchate affiche un historique de tous les messages de tchate. Chat history Historique du tchate Input Message Text Saisie du texte du message Enter the chat message text in the edit box and press enter to send the message to the server which distributes the message to all connected clients. Your message will then show up in the chat window. Saisissez le texte du message de tchate dans la zone d'édition et appuyez sur la touche Entrée pour envoyer le message au serveur qui le distribue à tous les clients connectés. Votre message apparaîtra alors dans la fenêtre de tchate. New chat text edit box Nouvelle boite d'édition de texte de tchate Type a message here Écrivez un message ici &Edit &Editer Cl&ear Chat History &Vider l'historique du tchate &Close &Fermer Do you want to open the link '%1' in your browser? Souhaitez-vous ouvrir le lien '%1' dans votre navigateur ? Do you want to open the link Souhaitez-vous ouvrir le lien in an external browser? dans un navigateur externe ? CChatDlgBase Chat Tchate &Send En&voyer CClientDlg Input Level Meter Indicateur de niveau d'entrée Make sure not to clip the input signal to avoid distortions of the audio signal. Veillez à ne pas écrêter le signal d'entrée afin d'éviter les distorsions du signal audio. Input level meter Indicateur de niveau d'entrée Simulates an analog LED level meter. Simule un indicateur de niveau analogique à diode. Connect/Disconnect Button Bouton connecter/déconnecter Connect and disconnect toggle button Bouton à bascule de connexion/déconnexion Local Audio Input Fader Chariot d'entrée audio locale Local audio input fader (left/right) Chariot d'entrée audio locale (gauche/droite) This shows the level of the two stereo channels for your audio input. Ceci indique le niveau des deux canaux stéréo pour votre entrée audio. If the application is connected to a server and you play your instrument/sing into the microphone, the VU meter should flicker. If this is not the case, you have probably selected the wrong input channel (e.g. 'line in' instead of the microphone input) or set the input gain too low in the (Windows) audio mixer. Si l'application est connectée à un serveur et que vous jouez de votre instrument/chantez dans le microphone, le VU-mètre devrait clignoter. Si ce n'est pas le cas, vous avez probablement sélectionné le mauvais canal d'entrée (par exemple 'entrée ligne' au lieu de l'entrée microphone) ou réglé le gain d'entrée trop bas dans le mélangeur audio. For proper usage of the application, you should not hear your singing/instrument through the loudspeaker or your headphone when the software is not connected. This can be achieved by muting your input audio channel in the Playback mixer (not the Recording mixer!). Pour une bonne utilisation de l'application, vous ne devez pas entendre votre chant/instrument par le haut-parleur ou votre casque lorsque le logiciel n'est pas connecté. Ceci peut être réalisé en coupant votre canal audio d'entrée dans le mixeur de lecture (pas dans le mixeur d'enregistrement !). Controls the relative levels of the left and right local audio channels. For a mono signal it acts as a pan between the two channels. For example, if a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows Contrôle les niveaux relatifs des canaux audio locaux gauche et droit. Pour un signal mono, il agit comme un pan entre les deux canaux. Par exemple, si un microphone est connecté au canal d'entrée droit et qu'un instrument est connecté au canal d'entrée gauche qui est beaucoup plus fort que le microphone, déplacez le curseur audio dans une direction où l'étiquette au-dessus du curseur indique Reverb effect Effet Réverbe Reverb can be applied to one local mono audio channel or to both channels in stereo mode. The mono channel selection and the reverb level can be modified. For example, if a microphone signal is fed in to the right audio channel of the sound card and a reverb effect needs to be applied, set the channel selector to right and move the fader upwards until the desired reverb level is reached. La réverbération peut être appliquée à un canal audio mono local ou aux deux canaux en mode stéréo. La sélection du canal mono et le niveau de réverbération peuvent être modifiés. Par exemple, si un signal de microphone est envoyé sur le canal audio droit de la carte son et qu'un effet de réverbération doit être appliqué, réglez le sélecteur de canal à droite et déplacez le chariot vers le haut jusqu'à ce que le niveau de réverbération souhaité soit atteint. Reverb effect level setting Réglage du niveau de l'effet de réverbération Reverb Channel Selection Sélection du canal de réverbération With these radio buttons the audio input channel on which the reverb effect is applied can be chosen. Either the left or right input channel can be selected. Ces boutons radio permettent de choisir le canal d'entrée audio sur lequel l'effet de réverbération est appliqué. Il est possible de sélectionner le canal d'entrée gauche ou droit. Left channel selection for reverb Sélection du canal gauche pour la réverbération Right channel selection for reverb Sélection du canal droit pour la réverbération The Le logiciel Green Vert The delay is perfect for a jam session. Le délai est parfait pour une séance de bœufs. Yellow Jaune Red Rouge If this LED indicator turns red, you will not have much fun using %1. Si ce témoin lumineux devient rouge, vous n'aurez pas beaucoup de plaisir à utiliser %1. Delay status LED indicator Indicateur diode lumineuse d'état de délai Opens a dialog where you can select a server to connect to. If you are connected, pressing this button will end the session. Ouvre une fenêtre dans laquelle vous pouvez sélectionner un serveur auquel vous connecter. Si vous êtes connecté, le fait d'appuyer sur ce bouton mettra fin à la session. Shows the current audio delay status: Indique l'état actuel du retard audio : A session is still possible but it may be harder to play. Une session est toujours possible mais il sera probablement plus difficile de jouer. The delay is too large for jamming. Le délai est trop important pour bœuffer. If this LED indicator turns red, you will not have much fun using the application. Si cette diode lumineuse devient rouge, vous n'aurez pas beaucoup de plaisir à utiliser l'application. The buffers status LED shows the current audio/streaming status. If the light is red, the audio stream is interrupted. This is caused by one of the following problems: La LED d'état des tampons indique l'état actuel de l'audio/streaming. Si le voyant est rouge, le flux audio est interrompu. Cela est dû à l'un des problèmes suivants : The sound card's buffer delay (buffer size) is too small (see Settings window). Le délai du tampon de la carte son (taille du tampon) est trop petit (voir la fenêtre des paramètres). The upload or download stream rate is too high for your internet bandwidth. Le taux de flux montant ou descendant est trop élevé pour votre bande passante Internet. Buffers status LED indicator Indicateur LED d'état de tampon C&onnect Se c&onnecter software upgrade available mise à jour du logiciel disponible &File &Fichier &View &Vue &Connection Setup... &Paramètres de connexion... My &Profile... Mon &profil... C&hat... Tc&hate... &Settings... Paramètre&s... &Analyzer Console... Console d'a&nalyse... Use &Two Rows Mixer Panel U&tiliser un panneau de mixage à deux rangées Clear &All Stored Solo and Mute Settings &Effacer tous les paramètres Solo et Muet enregistrés %1 Directory %1 Répertoire Ok Ok E&xit &Quitter &Edit &Editer Center Centre R D L G , where , où is the current attenuation indicator. est l'indicateur d'atténuation actuel. Delay Status LED Voyant d'état de délai Buffers Status LED Voyant d'état de tampon The network jitter buffer is not large enough for the current network/audio interface jitter. Le tampon de gigue réseau n'est pas assez grand pour la gigue actuelle de l'interface réseau/audio. The CPU of the client or server is at 100%. Le processeur du client ou du serveur est à 100%. Current Connection Status Parameter Paramètre de l'état de la connexion actuelle The Ping Time is the time required for the audio stream to travel from the client to the server and back again. This delay is introduced by the network and should be about 20-30 ms. If this delay is higher than about 50 ms, your distance to the server is too large or your internet connection is not sufficient. Le temps de ping est le temps nécessaire au flux audio pour aller du client au serveur et revenir. Ce délai est introduit par le réseau et doit être d'environ 20 à 30 ms. Si ce délai est supérieur à environ 50 ms, la distance qui vous sépare du serveur est trop importante ou votre connexion internet n'est pas suffisante. Overall Delay is calculated from the current Ping Time and the delay introduced by the current buffer settings. Le délai global est calculé à partir du temps de ping actuel et du délai introduit par les paramètres actuels de la mémoire tampon. If this LED indicator turns red, you will not have much fun using the Si ce voyant devient rouge, vous n'aurez pas beaucoup de plaisir à utiliser le software. logiciel. &Load Mixer Channels Setup... &Charger la configuration des canaux du mixeur... &Save Mixer Channels Setup... &Sauvegarder la configuration des canaux du mixeur... Sett&ings &Paramètres Audio/Network &Settings... Audio/Réseau Paramètre&s... A&dvanced Settings... Paramètres &avancés... N&o User Sorting Pas de &tri des canaux If this LED indicator turns red, you will not have much fun using the %1 software. Si ce témoin lumineux devient rouge, vous n'aurez pas beaucoup de plaisir à utiliser le logiciel %1. O&wn Fader First &Chariot personnel en premier Sort Users by &Name Trier les utilisateurs par &nom Sort Users by &Instrument Trier les utilisateurs par &instrument Sort Users by &Group Trier les utilisateurs par &groupe Sort Users by &City Trier les utilisateurs par &ville Set All Faders to New Client &Level Régler tous &les chariots sur le niveau d'un nouveau client Local Jitter Buffer Status LED Voyant d'état du tampon de gigue local The local jitter buffer status LED shows the current audio/streaming status. If the light is red, the audio stream is interrupted. This is caused by one of the following problems: Le voyant d'état du tampon de gigue local indique l'état actuel du flux audio/de la diffusion. Si le voyant est rouge, le flux audio est interrompu. Cela est dû à l'un des problèmes suivants : If this LED indicator turns red, the audio stream is interrupted. Si ce voyant devient rouge, le flux audio est interrompu. Local Jitter Buffer status LED indicator Indicateur du voyant d'état du tampon de gigue local Current Connection Status État de la connexion actuelle Auto-Adjust all &Faders Auto-ajuster tous les &chariots &Settings Paramètre&s Directory Server Serveur annuaire Select Channel Setup File Sélectionnez le fichier de configuration des canaux user utilisateur users utilisateurs Connect Se connecter Settings Paramètres Chat Tchate Enable feedback detection Activer la détection de larsen Audio feedback or loud signal detected. We muted your channel and activated 'Mute Myself'. Please solve the feedback issue first and unmute yourself afterwards. Larsen audio ou signal fort détecté. Nous avons coupé votre canal et activé "Me silencer". Veuillez d'abord résoudre le problème de larsen et rétablir le son après. Your sound card is not working correctly. Please open the settings dialog and check the device selection and the driver settings. Votre carte son ne fonctionne pas correctement. Veuillez ouvrir la fenêtre paramètres et vérifier la sélection du périphérique et les paramètres du pilote. &Disconnect &Déconnecter CClientDlgBase Delay Délai Buffers Tampons Input Entrée L G R D Jitter Gigue Ping Ping ms ms &Mute Myself &Me silencer &Settings Paramètre&s &Chat &Tchate C&onnect Se &connecter Pan Pan Center Centre Reverb Réverbe Left Gauche Right Droite MUTED (Other people won't hear you) SILENCÉ (les autres personnes ne vous entendent pas) Set up your audio, connect to a server and start jamming! Configurez votre audio, connectez-vous à un serveur et commencez à bœuffer ! Update check Vérification de mise à jour CClientSettingsDlg Jitter Buffer Size Taille du tampon de gigue The jitter buffer setting is therefore a trade-off between audio quality and overall delay. Le réglage du tampon de gigue est donc un compromis entre la qualité audio et le délai global. Local jitter buffer slider control Chariot de contrôle de la mémoire tampon de la gigue locale Server jitter buffer slider control Chariot de contrôle de la mémoire tampon de la gigue du serveur Auto jitter buffer switch Commutateur de tampon de gigue automatique Jitter buffer status LED indicator Indicateur LED de l'état du tampon de gigue Sound Card Device Périphérique d'interface audio The ASIO driver (sound card) can be selected using Le pilote ASIO (interface audio) peut être sélectionné en utilisant under the Windows operating system. Under MacOS/Linux, no sound card selection is possible. If the selected ASIO driver is not valid an error message is shown and the previous valid driver is selected. sous le système d'exploitation Windows. Sous MacOS/Linux, aucune sélection de carte son n'est possible. Si le pilote ASIO sélectionné n'est pas valide, un message d'erreur s'affiche et le pilote valide précédent est sélectionné. If the driver is selected during an active connection, the connection is stopped, the driver is changed and the connection is started again automatically. Si le pilote est sélectionné pendant une connexion active, la connexion est interrompue, le pilote est modifié et la connexion est automatiquement relancée. Sound card device selector combo box Choix déroulant de sélecteur de périphérique d'interface audio If the ASIO4ALL driver is used, please note that this driver usually introduces approx. 10-30 ms of additional audio delay. Using a sound card with a native ASIO driver is therefore recommended. Si le pilote ASIO4ALL est utilisé, veuillez noter que ce pilote introduit généralement environ 10 à 30 ms de latence audio supplémentaire. Il est donc recommandé d'utiliser une carte son avec un pilote ASIO natif. If you are using the kX ASIO driver, make sure to connect the ASIO inputs in the kX DSP settings panel. Si vous utilisez le pilote ASIO kX, assurez-vous de connecter les entrées ASIO dans le panneau de configuration DSP kX. Sound Card Channel Mapping Cartographie des canaux de la carte son If the selected sound card device offers more than one input or output channel, the Input Channel Mapping and Output Channel Mapping settings are visible. Si la carte son sélectionnée offre plus d'un canal d'entrée ou de sortie, les paramètres de cartographie des canaux d'entrées et de sorties sont visibles. For each Pour chaque Left input channel selection combo box Choix déroulant de sélection de canal d'entrée gauche Right input channel selection combo box Choix déroulant de sélection de canal d'entrée droite Left output channel selection combo box Choix déroulant de sélection de canal de sortie gauche Right output channel selection combo box Choix déroulant de sélection de canal de sortie droite Enable Small Network Buffers Activer les petits tampons de réseau If enabled, the support for very small network audio packets is activated. Very small network packets are only actually used if the sound card buffer delay is smaller than Si activée, la prise en charge des très petits paquets audio de réseau est activée. Les très petits paquets réseau ne sont réellement utilisés que si le délai de la mémoire tampon de la carte son est inférieur à samples. The smaller the network buffers, the lower the audio latency. But at the same time the network load increases and the probability of audio dropouts also increases. échantillons. Plus la mémoire tampon du réseau est petite, plus la latence audio est faible. Mais en même temps, la charge du réseau augmente et la probabilité de décrochage audio augmente également. Enable small network buffers check box Case-à-cocher pour activer les petits tampons de réseau Sound Card Buffer Delay Délai de temporisation de l'interface audio The buffer delay setting is a fundamental setting of %1. This setting has an influence on many connection properties. Le paramètre de délai de mise en mémoire tampon est un paramètre fondamental de %1. Ce paramètre a une influence sur de nombreuses propriétés de la connexion. Three buffer sizes are supported Trois tailles de tampon sont prises en charge Some sound card drivers do not allow the buffer delay to be changed from within the application. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. On Windows, press the ASIO Device Settings button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Certains pilotes de carte son ne permettent pas de modifier le délai de la mémoire tampon depuis l'application. Dans ce cas, le réglage de délai de tampon est désactivé et doit être modifié à l'aide du pilote de la carte son. Sous windows, appuyez sur le bouton Paramètres du périphérique ASIO pour ouvrir le panneau des paramètres du pilote. Sous Linux, utilisez l'outil de configuration JACK pour modifier la taille de la mémoire tampon. The actual buffer delay has influence on the connection status, the current upload rate and the overall delay. The lower the buffer size, the higher the probability of a red light in the status indicator (drop outs) and the higher the upload rate and the lower the overall delay. Le délai actuel de la mémoire tampon a une influence sur l'état de la connexion, le taux de téléchargement actuel et le délai global. Plus la taille de la mémoire tampon est faible, plus la probabilité d'un voyant rouge dans l'indicateur d'état (désynchronisations) est élevée, plus le taux de téléchargement est élevé et plus le délai global est faible. The buffer setting is therefore a trade-off between audio quality and overall delay. Le réglage de la mémoire tampon est donc un compromis entre la qualité audio et le délai global. ASIO Device Settings push button Bouton-poussoir des paramètres du périphérique ASIO input/output channel (Left and Right channel) a different actual sound card channel can be selected. (canal gauche et canal droit), il est possible de sélectionner un autre canal réel de la carte son. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within the software. On Windows, press the ASIO Device Settings button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Si les paramètres de taille de la mémoire tampon sont désactivés, le pilote audio ne permet pas de modifier ce paramètre depuis le logiciel. Sous Windows, appuyez sur le bouton Paramètres du périphérique ASIO pour ouvrir le panneau des paramètres du pilote. Sous Linux, utilisez l'outil de configuration JACK pour modifier la taille de la mémoire tampon. Sound card driver settings Paramètres du pilote de la carte son This opens the driver settings of your sound card. Some drivers allow you to change buffer settings, others like ASIO4ALL let you choose input or outputs of your device(s). More information can be found on jamulus.io. Cela ouvre les paramètres du pilote de votre carte son. Certains pilotes vous permettent de modifier les paramètres de la mémoire tampon, d'autres comme ASIO4ALL vous laissent choisir l'entrée ou les sorties de votre (vos) périphérique(s). Plus d'informations peuvent être trouvées sur jamulus.io. Opens the driver settings. Note: Ouvre les paramètres du pilote. Note : currently only supports devices supporting a sample rate of prend actuellement en charge uniquement les périphériques supportant un taux d'échantillonnage de Hz. You will not be able to select a driver/device which doesn't. For more help see jamulus.io. Hz. Vous ne pourrez pas sélectionner un pilote/périphérique ne le supportant pas. Pour plus d'informations, consultez jamulus.io. 64 samples setting radio button Bouton de paramétrage à 64 échantillons 128 samples setting radio button Bouton de paramétrage à 128 échantillons 256 samples setting radio button Bouton de paramétrage à 256 échantillons ASIO setup push button Bouton-poussoir de paramétrage ASIO Audio Channels Canaux audio Audio channels combo box Choix déroulant de canaux audio Audio Quality Qualité audio Audio quality combo box Choix déroulant de qualité audio New Client Level Niveau de nouveau client New client level edit box Nouvelle boîte d'édition de niveau des nouveaux clients Custom Directory Server Address Adresse personnalisée du serveur annuaire Current Connection Status Parameter Paramètre de l'état de la connexion actuelle If this LED indicator turns red, you will not have much fun using the Si ce voyant devient rouge, vous n'aurez pas beaucoup de plaisir à utiliser le software. logiciel. Mono Mono mode will increase your stream's data rate. Make sure your upload rate does not exceed the available upload speed of your internet connection. mode augmentera le débit de données de votre flux. Assurez-vous que votre débit montant ne dépasse pas la vitesse de téléchargement disponible de votre connexion internet. Mono-in/Stereo-out Mono-entrée/stéréo-sortie Stereo Stéréo &Close &Fermer Local Audio Input Fader Chariot d'entrée audio locale Controls the relative levels of the left and right local audio channels. For a mono signal it acts as a pan between the two channels. For example, if a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows Contrôle les niveaux relatifs des canaux audio locaux gauche et droit. Pour un signal mono, il agit comme un panoramique entre les deux canaux. Par exemple, si un microphone est connecté au canal d'entrée droit et qu'un instrument est connecté au canal d'entrée gauche qui est beaucoup plus fort que le microphone, déplacez le curseur audio du côté de l'étiquette L G , where , où is the current attenuation indicator. est l'indicateur d'atténuation actuel. Local audio input fader (left/right) Chariot d'entrée audio locale (gauche/droite) The jitter buffer compensates for network and sound card timing jitters. The size of the buffer therefore influences the quality of the audio stream (how many dropouts occur) and the overall delay (the longer the buffer, the higher the delay). Le tampon de gigue compense les gigues de synchronisation du réseau et de la carte son. La taille de la mémoire tampon influence donc la qualité du flux audio (le nombre de désynchronisations) et le délai global (plus la mémoire tampon est grande, plus le délai est important). You can set the jitter buffer size manually for the local client and the remote server. For the local jitter buffer, dropouts in the audio stream are indicated by the light below the jitter buffer size faders. If the light turns to red, a buffer overrun/underrun has taken place and the audio stream is interrupted. Vous pouvez définir manuellement la taille du tampon de gigue pour le client local et le serveur distant. Pour la mémoire tampon de gigue locale, les désynchronisations dans le flux audio sont indiquées par le voyant situé sous les chariots de taille de la mémoire tampon de gigue. Si le voyant devient rouge, cela signifie qu'il y a eu un dépassement ou une sous-utilisation de la mémoire tampon et que le flux audio est interrompu. If the Auto setting is enabled, the jitter buffers of the local client and the remote server are set automatically based on measurements of the network and sound card timing jitter. If Auto is enabled, the jitter buffer size faders are disabled (they cannot be moved with the mouse). Si le paramètre Auto est activé, les tampons de gigue du client local et du serveur distant sont automatiquement réglés en fonction des mesures de la gigue de synchronisation du réseau et de la carte son. Si le paramètre Auto est activé, les chariots de la taille des tampons de gigue sont désactivés (ils ne peuvent pas être déplacés avec la souris). If the Auto setting is enabled, the network buffers of the local client and the remote server are set to a conservative value to minimize the audio dropout probability. To tweak the audio delay/latency it is recommended to disable the Auto setting and to lower the jitter buffer size manually by using the sliders until your personal acceptable amount of dropouts is reached. The LED indicator will display the audio dropouts of the local jitter buffer with a red light. Si le paramètre Auto est activé, les tampons réseau du client local et du serveur distant sont réglés sur une valeur prudente pour minimiser la probabilité d'interruption de l'audio. Pour régler le délai/latence audio, il est recommandé de désactiver le paramètre Auto et de réduire manuellement la taille du tampon de gigue en utilisant les chariots jusqu'à ce que le nombre d'interruptions soit acceptable. L'indicateur LED affichera les désynchronisations audio du tampon de gigue local avec un voyant rouge. The buffer delay setting is a fundamental setting of this software. This setting has an influence on many connection properties. Le réglage du délai de la mémoire tampon est un paramètre fondamental de ce logiciel. Ce réglage a une influence sur de nombreuses propriétés de la connexion. 64 samples: The preferred setting. Provides the lowest latency but does not work with all sound cards. 64 échantillons : le paramétrage préféré. Fournit la latence la plus faible mais ne fonctionne pas avec toutes les cartes son. 128 samples: Should work for most available sound cards. 128 échantillons : devrait fonctionner pour la plupart des cartes son disponibles. 256 samples: Should only be used on very slow computers or with a slow internet connection. 256 échantillons : ne devrait être utilisé que sur des ordinateurs très lents ou avec une connexion internet lente. If no buffer size is selected and all settings are disabled, an unsupported buffer size is used by the driver. The application will still work with this setting but with restricted performance. Si aucune taille de tampon n'est sélectionnée et que tous les paramètres sont désactivés, une taille de tampon non prise en charge est utilisée par le pilote. L'application fonctionnera toujours avec ce paramètre, mais avec des performances limitées. Skin thème graphique Select the skin to be used for the main window. Sélectionnez le thème graphique à utiliser pour la fenêtre principale. Skin combo box Choix déroulant de thème graphique Select the meter style to be used for the level meters. The Bar (narrow) and LEDs (round, small) options only apply to the mixerboard. When Bar (narrow) is selected, the input meters are set to Bar (wide). When LEDs (round, small) is selected, the input meters are set to LEDs (round, big). The remaining options apply to the mixerboard and input meters. Sélectionnez le style d'indicateur à utiliser pour les indicateurs de niveaux. Les options barres (étroites) et diodes lumineuses (rondes, petites) ne s'appliquent qu'au tableau de mixage. Lorsque l'option Barre (étroite) est sélectionnée, les indicateurs d'entrées sont réglés sur barres (larges). Lorsque l'option diodes lumineuses (rondes, petites) est sélectionnée, les indicateurs d'entrées sont réglés sur diodes lumineuses (rondes, grandes). Les autres options s'appliquent au tableau de mixage et aux indicateurs d'entrées. Language Langue Select the language to be used for the user interface. Sélectionnez la langue à utiliser pour l'interface utilisateur. Language combo box Choix déroulant langue Selects the number of audio channels to be used for communication between client and server. There are three modes available: Sélectionne le nombre de canaux audio à utiliser pour la communication entre le client et le serveur. Trois modes sont disponibles : and et These modes use one and two audio channels respectively. Ces modes utilisent respectivement un et deux canaux audio. Mono in/Stereo-out Entrée mono/sortie stéréo The audio signal sent to the server is mono but the return signal is stereo. This is useful if the sound card has the instrument on one input channel and the microphone on the other. In that case the two input signals can be mixed to one mono channel but the server mix is heard in stereo. Le signal audio envoyé au serveur est mono mais le signal de retour est stéréo. Ceci est utile si la carte son a l'instrument sur un canal d'entrée et le microphone sur l'autre. Dans ce cas, les deux signaux d'entrée peuvent être mélangés sur un canal mono mais le mixage du serveur est entendu en stéréo. Enabling Activer In stereo streaming mode, no audio channel selection for the reverb effect will be available on the main window since the effect is applied to both channels in this case. En mode de flux stéréo, aucune sélection de canal audio pour l'effet de réverbération ne sera disponible dans la fenêtre principale puisque l'effet est appliqué aux deux canaux dans ce cas. The higher the audio quality, the higher your audio stream's data rate. Make sure your upload rate does not exceed the available bandwidth of your internet connection. Plus la qualité audio est élevée, plus le débit de données de votre flux audio est élevé. Assurez-vous que votre débit montant ne dépasse pas la bande passante disponible de votre connexion internet. This setting defines the fader level of a newly connected client in percent. If a new client connects to the current server, they will get the specified initial fader level if no other fader level from a previous connection of that client was already stored. Ce paramètre définit le niveau du chariot d'un client nouvellement connecté en pourcentage. Si un nouveau client se connecte au serveur actuel, il obtiendra le niveau de chariot initial spécifié si aucun autre niveau de chariot provenant d'une connexion précédente de ce client n'a déjà été enregistré. Input Boost Amplification de l'entrée This setting allows you to increase your input signal level by factors up to 10 (+20dB). If your sound is too quiet, first try to increase the level by getting closer to the microphone, adjusting your sound equipment or increasing levels in your operating system's input settings. Only if this fails, set a factor here. If your sound is too loud, sounds distorted and is clipping, this option will not help. Do not use it. The distortion will still be there. Instead, decrease your input level by getting farther away from your microphone, adjusting your sound equipment or by decreasing your operating system's input settings. Ce paramètre vous permet d'augmenter le niveau de votre signal d'entrée par des facteurs allant jusqu'à 10 (+20dB). Si votre son est trop faible, essayez d'abord d'augmenter le niveau en vous rapprochant du microphone, en réglant votre équipement de sonorisation ou en augmentant les niveaux dans les paramètres d'entrée de votre système d'exploitation. Ce n'est qu'en cas d'échec que vous pouvez définir un facteur ici. Si votre son est trop fort, s'il est déformé et s'il y a de l'écrêtage, cette option ne vous aidera pas. Ne l'utilisez pas. La distorsion sera toujours présente. Diminuez plutôt votre niveau d'entrée en vous éloignant de votre microphone, en réglant votre équipement de sonorisation ou en diminuant les paramètres d'entrée de votre système d'exploitation. Input Boost combo box Choix déroulant d'amplification de l'entrée Leave this blank unless you need to enter the address of a directory server other than the default. Laissez ce champ vide, sauf si vous devez entrer l'adresse d'un serveur annuaire autre que celui par défaut. Directory server address combo box Boîte combo d'adresses du serveur annuaire The Ping Time is the time required for the audio stream to travel from the client to the server and back again. This delay is introduced by the network and should be about 20-30 ms. If this delay is higher than about 50 ms, your distance to the server is too large or your internet connection is not sufficient. Le temps de ping est le temps nécessaire au flux audio pour aller du client au serveur et revenir. Ce délai est introduit par le réseau et doit être d'environ 20 à 30 ms. Si ce délai est supérieur à environ 50 ms, la distance qui vous sépare du serveur est trop importante ou votre connexion internet n'est pas suffisante. Overall Delay is calculated from the current Ping Time and the delay introduced by the current buffer settings. Le délai global est calculé à partir du temps de ping actuel et du délai introduit par les paramètres actuels de la mémoire tampon. Audio Upstream Rate depends on the current audio packet size and compression setting. Make sure that the upstream rate is not higher than your available internet upload speed (check this with a service such as speedtest.net). Le débit montant audio dépend de la taille actuelle des paquets audio et du réglage de la compression. Assurez-vous que le débit montant n'est pas supérieur à votre vitesse de téléchargement Internet disponible (vérifiez cela avec un service tel que speedtest.net). The ASIO driver (sound card) can be selected using %1 under the Windows operating system. Under macOS/Linux, no sound card selection is possible. If the selected ASIO driver is not valid an error message is shown and the previous valid driver is selected. Le pilote ASIO (carte son) peut être sélectionné à l'aide de %1 sous le système d'exploitation Windows. Sous macOS/Linux, aucune sélection de carte son n'est possible. Si le pilote ASIO sélectionné n'est pas valide, un message d'erreur s'affiche et le pilote valide précédent est sélectionné. For each %1 input/output channel (left and right channel) a different actual sound card channel can be selected. Pour chaque canal d'entrée/sortie %1 (canal gauche et droit), un canal réel différent de la carte son peut être sélectionné. Enables support for very small network audio packets. These network packets are only actually used if the sound card buffer delay is smaller than %1 samples. The smaller the network buffers, the lower the audio latency. But at the same time the network load and the probability of audio dropouts or sound artifacts increases. Active la prise en charge de très petits paquets audio réseau. Ces paquets réseau ne sont réellement utilisés que si le délai du tampon de la carte son est inférieur à %1 échantillons. Plus les tampons réseau sont petits, plus la latence audio est faible. Mais en même temps, la charge du réseau et la probabilité de pertes audio ou d'artefacts sonores augmentent. Some sound card drivers do not allow the buffer delay to be changed from within %1. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. On Windows, use the ASIO Device Settings button to open the driver settings panel. On Linux, use the JACK configuration tool to change the buffer size. Certains pilotes de carte son ne permettent pas de modifier le délai de mise en mémoire tampon à partir de %1. Dans ce cas, le paramètre de délai de mise en mémoire tampon est désactivé et doit être modifié à l'aide du pilote de la carte son. Sous Windows, utilisez le bouton Paramètres du périphérique ASIO pour ouvrir le panneau des paramètres du pilote. Sous Linux, utilisez l'outil de configuration JACK pour modifier la taille de la mémoire tampon. If no buffer size is selected and all settings are disabled, this means an unsupported buffer size is in use by the driver. %1 will still work with this setting but may have restricted performance. Si aucune taille de tampon n'est sélectionnée et que tous les paramètres sont désactivés, cela signifie qu'une taille de tampon non prise en charge est utilisée par le pilote. %1 fonctionnera quand même avec ce paramètre, mais ses performances risquent d'être limitées. Controls the relative levels of the left and right local audio channels. For a mono signal it acts as a pan between the two channels. For example, if a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows %1, where %2 is the current attenuation indicator. Contrôle les niveaux relatifs des canaux audio locaux gauche et droit. Pour un signal mono, il agit comme un panoramique entre les deux canaux. Par exemple, si un microphone est connecté au canal d'entrée droit et qu'un instrument est connecté au canal d'entrée gauche est beaucoup plus fort que le microphone, déplacez le chariot audio dans une direction où l'étiquette au-dessus du chariot indique %1, où %2 est l'indicateur d'atténuation actuel. Audio Device Interface audio Under the Windows operating system the ASIO driver (sound card) can be selected using %1. If the selected ASIO driver is not valid an error message is shown and the previous valid driver is selected. Under macOS the input and output hardware can be selected. Sous le système d'exploitation Windows, le pilote ASIO (carte son) peut être sélectionné à l'aide de %1. Si le pilote ASIO sélectionné n'est pas valide, un message d'erreur s'affiche et le pilote valide précédent est sélectionné. Sous macOS, le matériel d'entrée et de sortie peut être sélectionné. Three buffer sizes can be selected Trois tailles de tampon peuvent être sélectionnées 64 samples: Provides the lowest latency but does not work with all sound cards. 64 échantillons : Fournit la latence la plus faible mais ne fonctionne pas avec toutes les cartes son. 256 samples: Should only be used when 64 or 128 samples is causing issues. 256 échantillons : Devrait être utilisé uniquement si le réglage 64 ou 128 échantillons provoque des dysfonctionnements. Some sound card drivers do not allow the buffer delay to be changed from within %1. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. Use the appropriate tool for the interface in use to adjust this buffer size. For example, if using ASIO, use the "ASIO Device Settings" button to open the driver settings panel or if using JACK, use a tool such as QjackCtl to adjust the buffer size. Other interfaces, such as Pipewire, would require their appropriate tool being used. Please refer to the interface manual. Certains pilotes de carte son ne permettent pas de modifier le délai de la mémoire tampon depuis %1. Dans ce cas, le réglage de délai de tampon est désactivé et doit être modifié à l'aide du pilote de la carte son. Utilisez l'outil approprié pour l'interface utilisée afin de régler la taille de la mémoire tampon. Par exemple, si vous utilisez ASIO, utilisez le bouton "Paramètres du périphérique ASIO" pour ouvrir le panneau des paramètres du pilote ou si vous utilisez JACK, utilisez un outil tel que QjackCtl pour ajuster la taille du tampon. D'autres interfaces, telles que PipeWire, nécessitent l'utilisation de leur propre outil. Veuillez vous référer au manuel de l'interface. If no buffer size is selected and all settings are disabled, this means a buffer size in use by the driver which does not match the values. %1 will still work with this setting but may have restricted performance. Si aucune taille de tampon n'est sélectionnée et que tous les paramètres sont désactivés, cela signifie que la taille de tampon utilisée par le pilote ne correspond pas aux valeurs. %1 fonctionnera toujours avec ce paramètre, mais ses performances seront peut-être limitées. The actual buffer delay has influence on the connection, the current upload rate and the overall delay. The lower the buffer size, the higher the probability of a red light in the status indicator (drop outs) and the higher the upload rate and the lower the overall delay. Le délai réel de la mémoire tampon a une influence sur la connexion, le débit de téléchargement actuel et le délai global. Plus la taille de la mémoire tampon est faible, plus la probabilité d'un voyant rouge dans l'indicateur d'état (désynchronisation) est élevée, plus le débit de téléchargement est élevé et plus le délai global est faible. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within %1. On Windows, press the ASIO Device Settings button to open the driver settings panel. On Linux, use the JACK configuration tool to change the buffer size. Si les paramètres de retard de la mémoire tampon sont désactivés, il est interdit par le pilote audio de modifier ce paramètre à partir de %1. Sous Windows, appuyez sur le bouton Paramètres du périphérique ASIO pour ouvrir le panneau des paramètres du pilote. Sous Linux, utilisez l'outil de configuration JACK pour modifier la taille de la mémoire tampon. This opens the driver settings of your sound card. Some drivers allow you to change buffer settings, others like ASIO4ALL lets you choose input or outputs of your device(s). More information can be found on jamulus.io. Cela ouvre les paramètres du pilote de votre carte son. Certains pilotes vous permettent de modifier les paramètres de la mémoire tampon, d'autres, comme ASIO4ALL, vous permettent de choisir les entrées ou les sorties de votre ou vos périphériques. Vous trouverez de plus amples informations sur jamulus.io. Opens the driver settings. Note: %1 currently only supports devices with a sample rate of %2 Hz. You will not be able to select a driver/device which doesn't. For more help see jamulus.io. Ouvre les paramètres du pilote. Remarque : %1 ne prend actuellement en charge que les périphériques dont la fréquence d'échantillonnage est de %2 Hz. Vous ne pourrez pas sélectionner un pilote/périphérique qui ne le fait pas. Pour plus d'aide, consultez jamulus.io. Meter Style Style d'indicateur Select the meter style to be used for the level meters. The Narrow Bar and Small LEDs options only apply to the mixerboard. When Narrow Bar is selected, the input meters are set to Bar. When Small LEDs is selected, the input meters are set to Round LEDs. The remaining options apply to the mixerboard and input meters. Sélectionnez le style d'indicateur à utiliser pour les indicateurs de niveau. Les options indicateur étroit et petites diodes lumineuses ne s'appliquent qu'au tableau de mixage. Lorsque l'option indicateur étroit est sélectionnée, les indicateurs d'entrée sont réglés sur indicateur. Lorsque l'option petites diodes lumineuses est sélectionnée, les indicateurs d'entrée sont réglés sur des diodes rondes. Les autres options s'appliquent au tableau de mixage et aux indicateurs d'entrée. Meter Style combo box Choix déroulant de style d'indicateur and et Custom Directories Adresse personnalisée de l'annuaire If you need to add additional directories to the Connect dialog Directory drop down, you can enter the addresses here.<br>To remove a value, select it, delete the text in the input box, then move focus out of the control. Si vous devez ajouter des annuaires supplémentaires à la liste déroulante Annuaire de la boîte de dialogue Connexion, vous pouvez saisir les adresses ici.<br>Pour supprimer une valeur, sélectionnez-la, supprimez le texte dans la zone de saisie, puis déplacez la curseur en dehors. Custom Directories combo box Choix déroulant adresse personnalisée de l'annuaire Audio Upstream Rate Débit ascendant du flux audio Depends on the current audio packet size and compression setting. Make sure that the upstream rate is not higher than your available internet upload speed (check this with a service such as speedtest.net). Cela dépend de la taille actuelle des paquets audio et du paramètre de compression. Assurez-vous que le débit en amont n'est pas supérieur à votre vitesse de téléchargement sur Internet (vérifiez-le avec un service tel que speedtest.net). Number of Mixer Panel Rows Nombre de rangées de panneaux de mixeurs Adjust the number of rows used to arrange the mixer panel. Ajustez le nombre de rangées utilisées dans le panneau du mixeur. Number of Mixer Panel Rows spin box Liste de choix du nombre de rangées de panneaux de mixeurs Feedback Protection Protection larsen Enable feedback protection to detect acoustic feedback between microphone and speakers. Active la protection larsen pour détecter le larsen acoustique entre le microphone et les enceintes. Feedback Protection check box Case à cocher protection larsen Audio Alerts Alertes audio Enable audio alert when receiving a chat message and when a new client joins the session. A second sound device may be required to hear the alerts. Activez l'alerte audio lors de la réception d'un message de chat et lorsqu'un nouveau client rejoint la session. Un deuxième périphérique sonore peut être nécessaire pour entendre les alertes. Audio Alerts check box Case-à-cocher alertes audio ASIO Device Settings Paramètres du périphérique ASIO Low Basse Normal Normal High Haute Fancy Fantaisie Compact Compacte Bar (narrow) Barres (étroites) Bar (wide) Barres (larges) LEDs (stripe) Diodes lumineuses (bandes) LEDs (round, small) Diodes lumineuses (rondes, petites) LEDs (round, big) Diodes lumineuses (rondes, grandes) LEDs Diodes lumineuses Bar Barre Narrow Bar Barre étroite Round LEDs Diodes lumineuses rondes Small LEDs Petites diodes lumineuses None Aucune Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country or region you are located in. Your city and skill level playing your instrument may also be added. Inscrivez ici votre nom ou un pseudonyme pour que les autres musiciens avec lesquels vous voulez jouer sachent qui vous êtes. Vous pouvez également ajouter une illustration de l'instrument dont vous jouez, un drapeau du pays ou de la région où vous vous trouvez ainsi que votre ville et votre niveau de compétence sur votre instrument. What you set here will appear at your fader on the mixer board when you are connected to a %1 server. This tag will also be shown at each client which is connected to the same server as you. Ce que vous définissez ici apparaîtra sur votre chariot sur la table de mixage lorsque vous êtes connecté à un serveur %1. Cette balise sera également affichée sur chaque client connecté au même serveur que vous. Country/region flag button Bouton de drapeau de pays/région Center Centre R D Custom Personnalisé Any Genre 2 Tout genre 2 Any Genre 3 Tout genre 3 Genre Rock Genre Rock Genre Jazz Genre Jazz Genre Classical/Folk Genre classique/folk Genre Choral/Barbershop Genre chorale/barbershop Any Genre 1 Tout genre 1 preferred préféré Musician Profile Profil de musicien Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country you are located in. Your city and skill level playing your instrument may also be added. Écrivez votre nom ou un pseudonyme ici pour que les autres musiciens avec lesquels vous voulez jouer sachent qui vous êtes. Vous pouvez également ajouter une image de l'instrument dont vous jouez et un drapeau du pays dans lequel vous vous trouvez. Vous pouvez également ajouter votre ville et votre niveau de compétence pour jouer de votre instrument. What you set here will appear at your fader on the mixer board when you are connected to a Jamulus server. This tag will also be shown at each client which is connected to the same server as you. Ce que vous réglez ici apparaîtra au niveau de votre chariot sur la table de mixage lorsque vous serez connecté à un serveur Jamulus. Cette étiquette sera également affichée dans chaque client qui est connecté au même serveur que vous. Alias or name edit box Boîte d'édition de pseudo ou de nom Instrument picture button Bouton d'image d'instrument Country flag button Bouton de drapeau de pays City edit box Boîte d'édition de ville Skill level combo box Choix déroulant de niveau de compétence Beginner Débutant Intermediate Intermédiaire Expert Expert Size: Taille : Buffer Delay Délai de temporisation Buffer Delay: Délai de temporisation : Drum Set Batterie Djembe Djembé Electric Guitar Guitare électrique Acoustic Guitar Guitare acoustique Bass Guitar Guitare basse Keyboard Clavier Synthesizer Synthétiseur Grand Piano Piano à queue Accordion Accordéon Vocal Voix Microphone Microphone Harmonica Harmonica Trumpet Trompette Trombone Trombone French Horn Cor d'harmonie Tuba Tuba Saxophone Saxophone Clarinet Clarinette Flute Flûte Violin Violon Cello Violoncelle Double Bass Contrebasse Recorder Enregistreur Streamer Diffuseur Listener Auditeur Guitar+Vocal Guitare+voix Keyboard+Vocal Clavier+voix Bodhran Bodhran Bassoon Basson Oboe Hautbois Harp Harpe Viola Alto Congas Congas Bongo Bongo Vocal Bass Voix basse Vocal Tenor Voix ténor Vocal Alto Voix alto Vocal Soprano Voix soprano Banjo Banjo Mandolin Mandoline Ukulele Ukulélé Bass Ukulele Ukulélé basse Vocal Baritone Voix baryton Vocal Lead Voix principale Mountain Dulcimer Dulcimer de montagne Scratching Scratch Rapping Rap Vibraphone Vibraphone Conductor Conducteur CClientSettingsDlgBase Settings Paramètres Soundcard Interface audio Device Périphérique Input Channel Mapping Mappage des canaux d'entrée L G R D Output Channel Mapping Mappage des canaux de sortie Enable Small Network Buffers Activer les petits tampons de réseau Buffer Delay Délai de temporisation Country/Region Pays/Région (preferred) (préféré) (default) (défaut) (safe) (sûr) Driver Setup Configuration du pilote My Profile Mon profil Musician's Profile Profil musicien Alias/Name Pseudo/nom Instrument Instrument Country Pays City Ville Skill Compétence User Interface Interface utilisateur Meter Style Style d'indicateur Mixer Rows Rangées de mixeurs Audio Alerts Alertes audio Audio/Network Setup Configuration audio/réseau Audio Device Interface audio Jitter Buffer Tampon de gigue Auto Auto Local Local Server Serveur Size Taille kbps kbps ms ms Input Boost Amplification de l'entrée Feedback Protection Protection larsen Enable Activer Input Balance Balance d'entrée Pan Panoramique Center Centre Misc Divers Audio Channels Canaux audio Audio Quality Qualité audio Measurements Mesures Advanced Setup Configuration avancée Custom Central Server Address: Adresse personnalisée du serveur annuaire : New Client Level Niveau des nouveaux clients Skin Thème graphique Language Langue Custom Directories: Adresse personnalisée de l'annuaire : % % Custom Directory Server Address: Adresse personnalisée du serveur annuaire : Audio Stream Rate Débit du flux audio val val Ping Time Temps de réponse Overall Delay Délai global Local Jitter Buffer Tampon de gigue local CConnectDlg Directory Annuaire Shows the servers listed by the selected directory. You can add custom directories in Advanced Settings. Affiche les serveurs répertoriés par l'annuaire sélectionné. Vous pouvez ajouter des annuaires personnalisés dans les paramètres avancés. Directory combo box Choix déroulant annuaire Filters the server list by the given text. Note that the filter is case insensitive. A single # character will filter for those servers with at least one person connected. Filtre la liste des serveurs en fonction du texte donné. Notez que le filtre n'est pas sensible à la casse. Un simple caractère # filtrera les serveurs avec au moins une personne connectée. Uncheck to collapse the server list to show just the server details. Check to show everyone on the servers. Décochez cette case pour réduire la liste des serveurs et n'afficher que les détails du serveur. Cochez la case pour afficher tous les serveurs. Server List Liste de serveurs The Connection Setup window lists the available servers registered with the selected directory. Use the Directory dropdown to change the directory, find the server you want to join in the server list, click on it, and then click the Connect button to connect. Alternatively, double click on the server name to connect. La fenêtre de configuration de la connexion répertorie les serveurs disponibles enregistrés dans l'annuaire sélectionné. Utilisez la liste déroulante Annuaires pour changer d'annuaire, trouvez le serveur que vous voulez rejoindre dans la liste, cliquez dessus, puis cliquez sur le bouton "se connecter" pour vous connecter. Vous pouvez également double-cliquer sur le nom du serveur pour vous connecter. Permanent servers (those that have been listed for longer than 48 hours) are shown in bold. Les serveurs permanents (ceux qui sont répertoriés depuis plus de 48 heures) sont indiqués en gras. You can add custom directories in Advanced Settings. Vous pouvez ajouter des serveurs annuaires personnalisés dans paramètres avancés. Server list view Vue de la liste de serveurs Server Address Adresse du serveur If you know the server address, you can connect to it using the Server name/Address field. An optional port number can be added after the server address using a colon as a separator, e.g. %1. The field will also show a list of the most recently used server addresses. Si vous connaissez l'adresse du serveur, vous pouvez vous y connecter à l'aide du champ nom/adresse du serveur. Un numéro de port facultatif peut être ajouté après l'adresse du serveur en utilisant les deux points comme séparateur, par exemple %1. Le champ affichera également une liste des adresses de serveurs les plus récemment utilisées. Holds the current server address. It also stores old addresses in the combo box list. Contient l'adresse du serveur actuel. Il stocke également les anciennes adresses dans la liste déroulante. The Connection Setup window shows a list of available servers. Server operators can optionally list their servers by music genre. Use the List dropdown to select a genre, click on the server you want to join and press the Connect button to connect to it. Alternatively, double click on on the server name. Permanent servers (those that have been listed for longer than 48 hours) are shown in bold. La fenêtre de configuration de la connexion affiche une liste des serveurs disponibles. Les opérateurs de serveurs peuvent, en option, lister leurs serveurs par genre musical. Utilisez le menu déroulant Liste pour sélectionner un genre, cliquez sur le serveur que vous souhaitez rejoindre et appuyez sur le bouton Connexion pour vous y connecter. Vous pouvez également double-cliquer sur le nom du serveur. Les serveurs permanents (ceux qui ont été listés pendant plus de 48 heures) sont indiqués en gras. If you know the IP address or URL of a server, you can connect to it using the Server name/Address field. An optional port number can be added after the IP address or URL using a colon as a separator, e.g. example.org: Si vous connaissez l'adresse IP ou l'URL d'un serveur, vous pouvez vous y connecter en utilisant le champ Nom/Adresse du serveur. Un numéro de port optionnel peut être ajouté après l'adresse IP ou l'URL en utilisant deux points comme séparateur, par exemple, example.org : . The field will also show a list of the most recently used server addresses. . Le champ affichera également une liste des adresses de serveurs les plus récemment utilisées. Server address edit box Boîte d'édition d'adresse de serveur Holds the current server IP address or URL. It also stores old URLs in the combo box list. Contient l'adresse IP ou l'URL du serveur actuel. Il stocke également les anciennes URL dans la liste déroulante. Server List Selection Sélection de la liste des serveurs Selects the server list to be shown. Sélectionne la liste de serveurs à afficher. Server list selection combo box Liste déroulante de sélection de la liste des serveurs Filter Filtre The server list is filtered by the given text. Note that the filter is case insensitive. La liste des serveurs est filtrée par le texte donné. Notez que le filtre n'est pas sensible à la casse. Filter edit box Boite d'édition de filtre Show All Musicians Afficher tous les musiciens If you check this check box, the musicians of all servers are shown. If you uncheck the check box, all list view items are collapsed. Si vous cochez cette case, les musiciens de tous les serveurs sont affichés. Si vous décochez la case, tous les éléments de la vue en liste sont regroupés. Show all musicians check box Case-à-cocher pour afficher tous les musiciens If you know the IP address or URL of a server, you can connect to it using the Server name/Address field. An optional port number can be added after the IP address or URL using a colon as a separator, e.g. %1. The field will also show a list of the most recently used server addresses. Si vous connaissez l'adresse IP ou l'URL d'un serveur, vous pouvez vous y connecter à l'aide du champ Nom/adresse du serveur. Un numéro de port facultatif peut être ajouté après l'adresse IP ou l'URL en utilisant les deux points comme séparateur, par exemple, %1. Le champ affichera également une liste des adresses de serveur les plus récemment utilisées. Filter text, or # for occupied servers Texte du filtre, ou # pour les serveurs occupés Type # for occupied servers Tapez # pour les serveurs occupés CConnectDlgBase Connection Setup Paramètres de connexion List Liste Directory Annuaire Filter Filtre Show All Musicians Afficher tous les musiciens Server Name Nom du serveur Ping Time Temps de réponse Musicians Musiciens Location Localisation Server Address Adresse du serveur C&ancel &Annuler &Connect Se &connecter CHelpMenu &Help &Aide Getting &Started... &Configuration... Software &Manual... &Manuel du logiciel... What's &This Qu'est-ce que c'es&t &About Jamulus... À &propos de Jamulus... About &Qt... À propos de &Qt... &About... &À propos... About Qt À propos de Qt CLanguageComboBox Restart Required Redémarrage nécessaire Please restart the application for the language change to take effect. Veuillez relancer l'application pour que le changement de langue prenne effet. CLicenceDlg This server requires you accept conditions before you can join. Please read these in the chat window. Ce serveur exige que vous acceptiez des conditions avant de pouvoir le rejoindre. Veuillez les lire dans la fenêtre de tchate. I have read the conditions and &agree. J'ai lu les conditions et les &accepte. Accept Accepter Decline Décliner CMultiColorLED Red Rouge Yellow Jaune Green Vert CMusProfDlg Alias or name edit box Dialogue d'édition de pseudo ou de nom Instrument picture button Bouton d'image d'instrument Country flag button Bouton de drapeau de pays City edit box Dialogue d'édition de ville Skill level combo box Choix déroulant de niveau de compétence None Aucune Musician Profile Profil de musicien Alias/Name Pseudo/nom Instrument Instrument Country Pays City Ville Skill Compétence &Close &Fermer Beginner Débutant Intermediate Intermédiaire Expert Expert Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country you are located in. Your city and skill level playing your instrument may also be added. Écrivez votre nom ou un pseudonyme ici pour que les autres musiciens avec lesquels vous voulez jouer sachent qui vous êtes. Vous pouvez également ajouter une photo de l'instrument dont vous jouez et un drapeau du pays dans lequel vous vous trouvez. Vous pouvez également ajouter votre ville et votre niveau de compétence pour jouer de votre instrument. What you set here will appear at your fader on the mixer board when you are connected to a Jamulus server. This tag will also be shown at each client which is connected to the same server as you. Ce que vous réglez ici apparaîtra au niveau de votre chariot sur la table de mixage lorsque vous serez connecté à un serveur Jamulus. Cette étiquette sera également affichée dans chaque client qui est connecté au même serveur que vous. Drum Set Batterie Djembe Djembé Electric Guitar Guitare électrique Acoustic Guitar Guitare accoustique Bass Guitar Guitare basse Keyboard Clavier Synthesizer Synthétiseur Grand Piano Piano à queue Accordion Accordéon Vocal Voix Microphone Microphone Harmonica Harmonica Trumpet Trompette Trombone Trombone French Horn Cor d'harmonie Tuba Tuba Saxophone Saxophone Clarinet Clarinette Flute Flute Violin Violon Cello Violoncelle Double Bass Contrebasse Recorder Enregistreur Streamer Diffuseur Listener Auditeur Guitar+Vocal Guitare+voix Keyboard+Vocal Clavier+voix Bodhran Bodhran Bassoon Basson Oboe Hautbois Harp Harpe Viola Alto Congas Congas Bongo Bongo Vocal Bass Voix basse Vocal Tenor Voix ténor Vocal Alto Voix alto Vocal Soprano Voix soprano Banjo Banjo Mandolin Mandoline Ukulele Ukulélé Bass Ukulele Ukulélé basse Vocal Baritone Voix baryton Vocal Lead Voix principale Mountain Dulcimer Dulcimer de montagne Scratching Scratch Rapping Rap No Name Sans nom CServerDlg Client List Liste des clients The client list shows all clients which are currently connected to this server. Some information about the clients like the IP address and name are given for each connected client. La liste des clients affiche tous les clients qui sont actuellement connectés à ce serveur. Certaines informations sur les clients, telles que les adresses IP et le nom, sont données pour chaque client connecté. Connected clients list view Vue de la liste des clients connectés Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user %1 is running as). Cliquez sur le bouton pour ouvrir la boîte de dialogue qui permet de sélectionner le répertoire principal d'enregistrement. La valeur choisie doit exister et être accessible en écriture (permettre la création de sous-répertoires par l'utilisateur sous lequel %1 est exécuté). The current value of the main recording directory. The chosen value must exist and be writeable (allow creation of sub-directories by the user %1 is running as). Click the button to open the dialog that allows the main recording directory to be selected. La valeur actuelle du répertoire principal d'enregistrement. La valeur choisie doit exister et être accessible en écriture (permettre la création de sous-répertoires par l'utilisateur sous lequel %1 est exécuté). Cliquez sur le bouton pour ouvrir la boîte de dialogue qui permet de sélectionner le répertoire d'enregistrement principal. Custom Directory address Adresse personnalisée de l'annuaire The Custom Directory address is the address of the directory holding the server list to which this server should be added. L'adresse personnalisée de l'annuaire est l'adresse de l'annuaire contenant la liste des serveurs à laquelle ce serveur doit être ajouté. Server List Filename dialog push button Bouton poussoir de la boîte de dialogue nom du fichier liste de serveurs Server List Filename Nom du fichier liste de serveurs Click the button to open the dialog that allows the server list persistence file name to be set. The user %1 is running as needs to be able to create the file name specified although it may already exist (it will get overwritten on save). Cliquez sur le bouton pour ouvrir la boîte de dialogue qui permet de définir le nom du fichier de persistance de la liste des serveurs. L'utilisateur %1 doit être en mesure de créer le nom de fichier spécifié, même s'il existe déjà (il sera écrasé lors de la sauvegarde). Server List Filename text box (read-only) Zone de texte du fichier de la liste de serveurs (en lecture seule) The current value of server list persistence file name. The user %1 is running as needs to be able to create the file name specified although it may already exist (it will get overwritten on save). Click the button to open the dialog that allows the server list persistence file name to be set. La valeur actuelle du nom du fichier de persistance de la liste des serveurs. L'utilisateur %1 doit être en mesure de créer le nom de fichier spécifié, même s'il existe déjà (il sera écrasé lors de la sauvegarde). Cliquez sur le bouton pour ouvrir la boîte de dialogue qui permet de définir le nom du fichier de persistance de la liste de serveurs. Clear the server list file name button Bouton d'effacement du nom du fichier de la liste de serveurs Clear Server List Filename Effacer le nom de fichier de la liste de serveurs Click the button to clear the currently selected server list persistence file name. This will prevent persisting the server list until a new value is selected. Cliquez sur le bouton pour effacer le nom du fichier de persistance de la liste de serveurs actuellement sélectionné. Cela empêchera la persistance de la liste de serveurs jusqu'à ce qu'une nouvelle valeur soit sélectionnée. Start Minimized on Operating System Start Démarrage minimisé au lancement du système d'exploitation Now a directory Maintenant un annuaire Make My Server Public Rendre mon serveur public Register Server Status Enregistrer l'état du serveur If the Make My Server Public check box is checked, this will show whether registration with the directory server is successful. If the registration failed, please choose another server list. Si la case Rendre mon serveur public est cochée, cela indiquera si l'enregistrement auprès du serveur annuaire est réussi. Si l'enregistrement a échoué, veuillez choisir une autre liste de serveurs. If the start minimized on operating system start check box is checked, the server will be started when the operating system starts up and is automatically minimized to a system task bar icon. Si la case "Démarrage minimisé au démarrage du système d'exploitation" est cochée, le serveur sera exécuter au démarrage du système d'exploitation et sera automatiquement réduit à une icône de la barre des tâches du système. If the Make My Server Public check box is checked, this server registers itself at the directory server so that all users of the application can see the server in the connect dialog server list and connect to it. The registration of the server is renewed periodically to make sure that all servers in the connect dialog server list are actually available. Si la case Rendre mon serveur public est cochée, ce serveur s'enregistre sur le serveur annuaire afin que tous les utilisateurs de l'application puissent le voir dans la liste des serveurs de la fenêtre de connexion et puissent s'y connecter. L'inscription du serveur est renouvelée périodiquement pour s'assurer que tous les serveurs de la liste des serveurs de la fenêtre de connexion sont effectivement disponibles. Custom Directory Server Address Adresse personnalisée du serveur annuaire The custom directory server address is the IP address or URL of the directory server at which the server list of the connection dialog is managed. L'adresse personnalisée du serveur annuaire est l'adresse IP ou l'URL du serveur annuaire sur lequel la liste des serveurs de la fenêtre de connexion est gérée. Directory server address line edit Ligne d'édition pour l'adresse du serveur annuaire Server List Selection Sélection de la liste des serveurs Selects the server list (i.e. directory server address) in which your server will be added. Sélectionne la liste de serveurs (c-à-d l'adresse du serveur annuiare) dans laquelle votre serveur sera ajouté. Server list selection combo box Liste déroulante de sélection de la liste des serveurs Server Name Nom du serveur The server name identifies your server in the connect dialog server list at the clients. Le nom du serveur identifie votre serveur dans la liste des serveurs de la fenêtre de connexion chez les clients. Server name line edit Ligne d'édition pour le nom du serveur Location City Ville de localisation The city in which this server is located can be set here. If a city name is entered, it will be shown in the connect dialog server list at the clients. La ville dans laquelle ce serveur est situé peut être définie ici. Si un nom de ville est saisi, il sera affiché dans la liste des serveurs du dialogue de connexion chez les clients. City where the server is located line edit Ligne d'édition pour la ville où est situé le serveur Location country Pays de localisation The country in which this server is located can be set here. If a country is entered, it will be shown in the connect dialog server list at the clients. Le pays dans lequel ce serveur est situé peut être défini ici. Si un pays est saisi, il sera affiché dans la liste des serveurs du dialogue de connexion chez les clients. Country where the server is located combo box Choix déroulant du pays où le serveur est situé Display dialog to select recording directory button Afficher le boite de dialogue pour sélectionner le bouton du répertoire d'enregistrement Main Recording Directory Répertoire principal des enregistrements Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user Jamulus is running as). Cliquez sur le bouton pour ouvrir la boîte de dialogue permettant de sélectionner le répertoire d'enregistrement principal. La valeur choisie doit exister et être inscriptible (permettre la création de sous-répertoires par l'utilisateur sous lequel Jamulus fonctionne). Main recording directory text box (read-only) Zone de texte du répertoire principal d'enregistrement (lecture seule) The current value of the main recording directory. The chosen value must exist and be writeable (allow creation of sub-directories by the user Jamulus is running as). Click the button to open the dialog that allows the main recording directory to be selected. La valeur actuelle du répertoire principal d'enregistrement. La valeur choisie doit exister et être inscriptible (permettre la création de sous-répertoires par l'utilisateur sous lequel Jamulus fonctionne). Cliquez sur le bouton pour ouvrir la boîte de dialogue permettant de sélectionner le répertoire d'enregistrement principal. Clear the recording directory button Effacer le bouton du répertoire d'enregistrement Clear Recording Directory Effacer le répertoire des enregistrements Click the button to clear the currently selected recording directory. This will prevent recording until a new value is selected. Cliquez sur le bouton pour effacer le répertoire d'enregistrement actuellement sélectionné. Cela empêchera l'enregistrement jusqu'à ce qu'une nouvelle valeur soit sélectionnée. Checkbox to turn on or off server recording Case à cocher pour activer ou désactiver l'enregistrement du serveur If the Register Server check box is checked, this will show whether registration with the directory server is successful. If the registration failed, please choose another server list. Si la case Enregistrer le serveur est cochée, cela indique si l'enregistrement avec le serveur d'annuaire a réussi. Si l'enregistrement a échoué, veuillez choisir une autre liste de serveurs. Enable Recorder Activer l'enregistreur Checked when the recorder is enabled, otherwise unchecked. The recorder will run when a session is in progress, if (set up correctly and) enabled. Coché lorsque l'enregistreur est activé, sinon décocher. L'enregistreur fonctionnera lorsqu'une session est en cours, si (configuré correctement et) activé. If the recording directory is not useable, the problem will be displayed in place of the session directory. Si le répertoire d'enregistrement n'est pas utilisable, le problème sera affiché à la place du répertoire de la session. Current session directory text box (read-only) Zone de texte du répertoire de la session en cours (en lecture seule) Current Session Directory Répertoire de la session en cours Enabled during recording and holds the current recording session directory. Disabled after recording or when the recorder is not enabled. Activé pendant l'enregistrement et contient le répertoire de la session d'enregistrement en cours. Désactivé après l'enregistrement ou lorsque l'enregistreur n'est pas activé. Recorder status label Étiquette de statut d'enregistreur Recorder Status Statut de l'enregistreur Displays the current status of the recorder. The following values are possible: Affiche l'état actuel de l'enregistreur. Les valeurs suivantes sont possibles : No recording directory has been set or the value is not useable. Aucun répertoire d'enregistrement n'a été défini ou la valeur n'est pas utilisable. Recording has been switched off L'enregistrement a été désactivé by the UI checkbox par la case à cocher de l'interface graphique , either by the UI checkbox or SIGUSR2 being received , soit en cochant la case de l'interface graphique ou en recevant SIGUSR2 There is no one connected to the server to record. Il n'y a personne connecté au serveur pour enregistrer. The performers are being recorded to the specified session directory. Les interprètes sont enregistrés dans le répertoire de session spécifié. NOTE NOTE If the recording directory is not useable, the problem will be displayed in place of the directory. Si le répertoire d'enregistrement n'est pas utilisable, le problème sera affiché à la place du répertoire. Server welcome message edit box Boite d'édition du message de bienvenue du serveur Server Welcome Message Message de bienvenue du serveur A server welcome message text is displayed in the chat window if a musician enters the server. If no message is set, the server welcome is disabled. Un message de bienvenue du serveur est affiché dans la fenêtre de tchate si un musicien entre sur le serveur. Si aucun message n'est défini, le message de bienvenue du serveur est désactivé. Language Langue Select the language to be used for the user interface. Sélectionnez la langue à utiliser pour l'interface utilisateur. Language combo box Choix déroulant langue Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user Jamulus is running as). Cliquez sur le bouton pour ouvrir la boîte de dialogue qui permet de sélectionner le répertoire d'enregistrement principal. La valeur choisie doit exister et être accessible en écriture (permettre la création de sous-répertoires par l'utilisateur sous lequel Jamulus est exécuté). Custom Directory Répertoire personnalisé The custom directory is the IP address or URL of the directory server at which the server list of the connection dialog is managed. L'annuaire personnalisé est l'adresse IP ou l'URL du serveur annuaire sur lequel la liste des serveurs de la boîte de dialogue de connexion est gérée. Custom Directory line edit Modification de la ligne de l'annuaire personnalisé &Hide %1 server Cac&her le serveur %1 &Show %1 server Afficher le &serveur %1 %1 server %1 is the name of the main application Serveur %1 Type a message here. If no message is set, the server welcome is disabled. Tapez un message ici. Si aucun message n'est défini, l'accueil du serveur est désactivé. software upgrade available mise à jour du logiciel disponible Recorder failed to start. Please check available disk space and permissions and try again. Error: L'enregistreur n'a pas réussi à démarrer. Veuillez vérifier l'espace disque disponible et les permissions et réessayer. Erreur : ERROR ERREUR Request new recording button Demander un nouveau bouton d'enregistrement Directory Type combo box Liste déroulante type d'annuaire Directory Annuaire Select '%1' not to register your server with a directory. Sélectionnez '%1' pour ne pas enregistrer votre serveur dans l'annuaire. Select one of the genres to register with that directory. Sélectionnez l'un des genres pour vous inscrire à cet annuaire. Or select '%1' and specify a Custom Directory address on the Options tab to register with a custom directory. Ou sélectionnez "%1" et indiquez une adresse d'annuaire personnalisée dans l'onglet Options pour vous inscrire dans un annuaire personnalisé. For any value except '%1', this server registers with a directory so that a %2 user can select this server in the client connect dialog server list when they choose that directory. Pour toute valeur autre que '%1', ce serveur s'enregistre auprès d'un annuaire afin qu'un utilisateur %2 puisse sélectionner ce serveur dans la liste de serveurs de la boîte de dialogue de connexion du client lorsqu'il choisit cet annuaire. The registration of the server is renewed periodically to make sure that all servers in the connect dialog server list are actually available. L'enregistrement du serveur est renouvelé périodiquement pour s'assurer que tous les serveurs de la liste de serveurs de la boîte de dialogue de connexion sont effectivement disponibles. When a value other than "%1" is chosen for Directory, this will show whether registration is successful. If the registration failed, please choose a different directory. Lorsqu'une valeur autre que "%1" est choisie pour le répertoire, cela indique si l'enregistrement a réussi. Si l'enregistrement a échoué, veuillez choisir un autre répertoire. Country/Region Pays/Région Set the country or region where the server is running. Clients will show this location in their connect dialog's server list. Définissez le pays ou la région où le serveur est exécuté. Les clients afficheront cet emplacement dans la liste des serveurs de leur boîte de dialogue de connexion. Combo box for location of this server Liste déroulante pour le pays où le serveur est situé No recording directory has been set or the value is not useable. Check the value in the Options tab. Aucun répertoire d'enregistrement n'a été défini ou la valeur n'est pas utilisable. Vérifiez la valeur dans l'onglet Options. Recording has been switched off by the UI checkbox. L'enregistrement a été désactivé par la case à cocher de l'interface utilisateur. Recording has been switched off, either by the UI checkbox or SIGUSR2 being received. L'enregistrement a été désactivé, soit par la case à cocher de l'interface utilisateur, soit par la réception de SIGUSR2. New Recording Nouvel enregistrement During a recording session, the button can be used to start a new recording. Pendant une session d'enregistrement, le bouton peut être utilisé pour démarrer un nouvel enregistrement. E&xit &Quitter &Hide Cac&hé server serveur &Open &Ouvrir %1 Server %1 is the name of the main application %1 serveur Select Main Recording Directory Sélectionner le répertoire principal des enregistrements Recording En cours d'enregistrement Not recording Non enregistré Not initialised Non initialisé Not enabled Non activé Server serveur &Window &Fenêtre Unregistered Non inscrit None Aucune Not registered Non inscrit Bad address Mauvaise adresse Registration requested Inscription demandée Registration failed Échec de l'inscription Check server version Vérifier la version du serveur Registered Inscrit Directory server list full Liste de serveurs de l'annuaire pleine Directory Server full Serveur annuaire plein Your server version is too old La version de votre serveur est trop vieille Requirements not fulfilled Exigences non satisfaites Unknown value %1 Valeur inconnue %1 Unknown value Valeur inconnue CServerDlgBase Client IP:Port IP Client:Port Name Nom Jitter Buffer Size Taille du tampon de gigue Channels Canaux Server Setup Paramètres du serveur List Liste Location: Region Emplacement : Région Session Session Chat Window Welcome (HTML/CSS Supported) Bienvenue dans la fenêtre de tchate (HTML/CSS pris en charge) Options Options Custom Directory address Adresse personnalisée de l'annuaire Server List Filename Nom du fichier liste de serveurs Start Minimized on Windows Start Démarrage minimisé au lancement de Windows Enable delay panning Activer le panoramique à retardement Update check Vérification de mise à jour Make My Server Public (Register My Server in the Server List) Rendre mon serveur public (inscrire mon serveur dans la liste des serveurs) Genre Genre STATUS ÉTAT Custom Directory Server Address: Adresse personnalisée du serveur annuaire : Recording Directory Répertoire des enregistrements Enable Jam Recorder Activer l'enregistreur de bœuf Directory Annuaire New Recording Nouvel enregistrement Language Consider add "(Lang)" as a suffix to ensure that users who selected the wrong language find the correct button Langue My Server Info Informations de mon serveur Location: City Emplacement : ville Location: Country Emplacement : pays CServerListManager Could not write to '%1' Impossible d'écrire dans '%1' CSound The Jack server is not running. This software requires a Jack server to run. Normally if the Jack server is not running this software will automatically start the Jack server. It seems that this auto start has not worked. Try to start the Jack server manually. Le serveur JACK n'est pas démarré. Ce logiciel nécessite un serveur JACK pour fonctionner. Normalement, si le serveurJACK n'est pas en cours d'exécution, ce logiciel démarrera automatiquement le serveur JACK. Il semble que ce démarrage automatique n'ait pas fonctionné. Essayez de démarrer le serveur JACK manuellement. The Jack server sample rate is different from the required one. The required sample rate is: Le taux d'échantillonnage du serveur JACK est différent de celui requis. Le taux d'échantillonnage requis est le suivant : You can use a tool like <i><a href="https://qjackctl.sourceforge.io">QJackCtl</a></i> to adjust the Jack server sample rate. Vous pouvez utiliser un outil comme <i><a href="https://qjackctl.sourceforge.io">QJackCtl</a></i> pour ajuster le taux d'échantillonnage du serveur Jack. Make sure to set the Frames/Period to a low value like Veillez à définir les trames/périodes à une valeur faible comme to achieve a low delay. pour obtenir une latence faible. The Jack port registering failed. L'enregistrement du port Jack a échoué. Cannot activate the Jack client. Impossible d'activer le client JACK. The Jack server was shut down. This software requires a Jack server to run. Try to restart the software to solve the issue. Le serveur JACK a été fermé. Ce logiciel nécessite un serveur JACK pour fonctionner. Essayez de redémarrer le logiciel pour résoudre le problème. CoreAudio input AudioHardwareGetProperty call failed. It seems that no sound card is available in the system. L'appel d'entrée AudioHardwareGetProperty CoreAudio a échoué failed. Il semble qu'aucune carte son ne soit disponible dans le système. CoreAudio output AudioHardwareGetProperty call failed. It seems that no sound card is available in the system. L'appel de sortie AudioHardwareGetProperty CoreAudio a échoué failed. Il semble qu'aucune carte son ne soit disponible dans le système. Current system audio input device sample rate of %1 Hz is not supported. Please open the Audio-MIDI-Setup in Applications->Utilities and try to set a sample rate of %2 Hz. Le taux d'échantillonnage de %1 Hz du périphérique d'entrée audio du système actuel n'est pas pris en charge. Veuillez ouvrir la configuration Audio-MIDI dans Applications->Utilitaires et essayer de définir un taux d'échantillonnage de %2 Hz. The current selected audio device is no longer present in the system. Le périphérique audio actuellement sélectionné n'est plus présent dans le système. The audio input device is no longer available. Le périphérique d'entrée audio n'est plus disponible. The audio output device is no longer available. Le périphérique de sortie audio n'est plus disponible. Current system audio output device sample rate of %1 Hz is not supported. Please open the Audio-MIDI-Setup in Applications->Utilities and try to set a sample rate of %2 Hz. Le taux d'échantillonnage de %1 Hz du périphérique de sortie audio du système actuel n'est pas pris en charge. Veuillez ouvrir la configuration Audio-MIDI dans Applications->Utilitaires et essayer de définir un taux d'échantillonnage de %2 Hz. The audio input stream format for this audio device is not compatible with this software. Le format du flux d'entrée audio pour ce périphérique audio n'est pas compatible avec ce logiciel. The audio output stream format for this audio device is not compatible with this software. Le format du flux de sortie audio pour ce périphérique audio n'est pas compatible avec ce logiciel. The buffer sizes of the current input and output audio device cannot be set to a common value. Please choose other input/output audio devices in your system settings. Les tailles de tampon du périphérique audio d'entrée et de sortie actuel ne peuvent pas être réglées à une valeur commune. Veuillez choisir d'autres périphériques audio d'entrée/sortie dans les paramètres de votre système. The audio driver could not be initialized. Le pilote audio n'a pas pu être initialisé. The audio device does not support the required sample rate. The required sample rate is: Le périphérique audio ne prend pas en charge la fréquence d'échantillonnage requise. La fréquence d'échantillonnage requise est : The audio device does not support setting the required sampling rate. This error can happen if you have an audio interface like the Roland UA-25EX where you set the sample rate with a hardware switch on the audio device. If this is the case, please change the sample rate to Le périphérique audio ne permet pas de régler la fréquence d'échantillonnage requise. Cette erreur peut se produire si vous avez une interface audio comme le Roland UA-25EX où vous réglez la fréquence d'échantillonnage avec un commutateur matériel sur le périphérique audio. Si c'est le cas, veuillez changer la fréquence d'échantillonnage à Hz on the device and restart the Hz sur le périphérique et redémarrer le software. logiciel. The audio device does not support the required number of channels. The required number of channels for input and output is: Le périphérique audio ne prend pas en charge le nombre de canaux requis. Le nombre de canaux requis pour l'entrée et la sortie est : Required audio sample format not available. Le format de l'échantillon audio requis n'est pas disponible. The selected audio device is no longer present in the system. Please check your audio device. Le périphérique audio sélectionné n'est plus présent dans le système. Veuillez vérifier votre appareil audio. Couldn't initialise the audio driver. Check if your audio hardware is plugged in and verify your driver settings. Impossible d'initialiser le pilote audio. Vérifiez si votre matériel audio est branché et vérifiez les paramètres de votre pilote. The selected audio device is incompatible since it doesn't support a sample rate of %1 Hz. Please select another device. Le périphérique audio sélectionné est incompatible car il ne prend pas en charge une fréquence d'échantillonnage de %1 Hz. Veuillez sélectionner un autre périphérique. The current audio device configuration is incompatible because the sample rate couldn't be set to %2 Hz. Please check for a hardware switch or driver setting to set the sample rate manually and restart %1. La configuration actuelle du périphérique audio est incompatible car la fréquence d'échantillonnage n'a pas pu être définie sur %2 Hz. Veuillez vérifier si un commutateur matériel ou un paramètre du pilote permet de définir manuellement la fréquence d'échantillonnage et redémarrer %1. The selected audio device is incompatible since it doesn't support %1 in/out channels. Please select another device or configuration. Le périphérique audio sélectionné est incompatible car il ne prend pas en charge les canaux d'entrée/sortie %1. Veuillez sélectionner un autre périphérique ou une autre configuration. The selected audio device is incompatible since the required audio sample format isn't available. Please use another device. Le périphérique audio sélectionné est incompatible car le format d'échantillon audio requis n'est pas disponible. Veuillez utiliser un autre appareil. No ASIO audio device driver found. Aucun pilote de périphérique audio ASIO trouvé. Please install an ASIO driver before running %1. If you own a device with ASIO support, install its official ASIO driver. If not, you'll need to install a universal driver like ASIO4ALL. Veuillez installer un pilote ASIO avant d'exécuter %1. Si vous possédez un périphérique avec un support ASIO, installez son pilote ASIO officiel. Sinon, vous devrez télécharger et installer un pilote universel comme ASIO4ALL. Please install an ASIO driver before running %1. If you own a device with ASIO support, install its official ASIO driver. If not, you'll need to download and install a universal driver like ASIO4ALL. Veuillez installer un pilote ASIO avant d'exécuter %1. Si vous possédez un périphérique avec un support ASIO, installez son pilote ASIO officiel. Sinon, vous devrez télécharger et installer un pilote universel comme ASIO4ALL. No ASIO audio device (driver) found. Aucun périphérique audio ASIO (pilote) trouvé. The Le logiciel software requires the low latency audio interface ASIO to work properly. This is not a standard Windows audio interface and therefore a special audio driver is required. Either your sound card has a native ASIO driver (which is recommended) or you might want to use alternative drivers like the ASIO4All driver. nécessite l'interface audio à faible latence ASIO pour fonctionner correctement. Il ne s'agit pas d'une interface audio Windows standard et un pilote audio spécial est donc nécessaire. Soit votre carte son dispose d'un pilote ASIO natif (ce qui est recommandé), soit vous pouvez utiliser d'autres pilotes comme le pilote ASIO4All. Error requesting stream stop: $s Erreur lors de la demande d'arrêt du flux : $s Error closing stream: $s Erreur de fermeture du flux : $s JACK couldn't be started automatically. Please start JACK manually and check for error messages. JACK n'a pas pu être lancé automatiquement. Veuillez lancer JACK manuellement et vérifier les messages d'erreur. JACK isn't running at a sample rate of <b>%1 Hz</b>. Please use a tool like <i><a href="https://qjackctl.sourceforge.io">QjackCtl</a></i> to set the the JACK sample rate to %1 Hz. JACK ne fonctionne pas à un taux d'échantillonnage de <b>%1 Hz</b>. Veuillez utiliser un outil comme <i><a href="https://qjackctl.sourceforge.io">QjackCtl</a></i> pour régler le taux d'échantillonnage de JACK à %1 Hz. The JACK port registration failed. This is probably an error with JACK. Please stop %1 and JACK. Afterwards check if another program at a sample rate of %2 Hz can connect to JACK. L'enregistrement du port JACK a échoué. Il s'agit probablement d'une erreur de JACK. Veuillez arrêter %1 et JACK. Ensuite, vérifiez si un autre programme avec un taux d'échantillonnage de %2 Hz peut se connecter à JACK. The JACK port registration failed. This is probably an error with JACK. Please stop %1 and JACK. Afterwards, check if another MIDI program can connect to JACK. L'enregistrement du port JACK a échoué. Il s'agit probablement d'une erreur de JACK. Veuillez arrêter %1 et JACK. Ensuite, vérifiez si un autre programme MIDI peut se connecter à JACK. Can't activate the JACK client. This is probably an error with JACK. Please check the JACK output. Impossible d'activer le client JACK. Il s'agit probablement d'une erreur de JACK. Veuillez vérifier la sortie JACK. JACK was shut down. %1 requires JACK to run. Please restart %1 to start JACK again. JACK a été arrêté. %1 a besoin de JACK pour fonctionner. Veuillez redémarrer %1 pour relancer JACK. No sound card is available in your system. CoreAudio input AudioHardwareGetProperty call failed. Aucune carte son n'est disponible dans votre système. L'appel à l'entrée AudioHardwareGetProperty de CoreAudio a échoué. No sound card is available in the system. CoreAudio output AudioHardwareGetProperty call failed. Aucune carte son n'est disponible dans le système. L'appel de la sortie CoreAudio AudioHardwareGetProperty a échoué. The currently selected audio device is no longer present. Please check your audio device. Le périphérique audio actuellement sélectionné n'est plus présent. Veuillez vérifier votre périphérique audio. The audio input device is no longer available. Please check if your input device is connected correctly. Le périphérique d'entrée audio n'est plus disponible. Veuillez vérifier si votre périphérique d'entrée est correctement connecté. The sample rate on the current input device isn't %1 Hz and is therefore incompatible. Please select another device or try setting the sample rate to %1 Hz manually via Audio-MIDI-Setup (in Applications->Utilities). La fréquence d'échantillonnage du périphérique d'entrée actuel n'est pas de %1 Hz et est donc incompatible. Veuillez sélectionner un autre périphérique ou essayer de régler manuellement la fréquence d'échantillonnage sur %1 Hz via Audio-MIDI-Setup (dans Applications->Utilitaires). The audio output device is no longer available. Please check if your output device is connected correctly. Le périphérique de sortie audio n'est plus disponible. Veuillez vérifier si votre périphérique de sortie est correctement connecté. The sample rate on the current output device isn't %1 Hz and is therefore incompatible. Please select another device or try setting the sample rate to %1 Hz manually via Audio-MIDI-Setup (in Applications->Utilities). La fréquence d'échantillonnage du périphérique de sortie actuel n'est pas %1 Hz et est donc incompatible. Veuillez sélectionner un autre périphérique ou essayer de régler manuellement la fréquence d'échantillonnage sur %1 Hz via Audio-MIDI-Setup (dans Applications->Utilitaires). The stream format on the current input device isn't compatible with this software. Please select another device. Le format de flux du périphérique d'entrée actuel n'est pas compatible avec ce logiciel. Veuillez sélectionner un autre périphérique. The stream format on the current output device isn't compatible with %1. Please select another device. Le format du flux sur le périphérique de sortie actuel n'est pas compatible avec %1. Veuillez sélectionner un autre périphérique. The buffer sizes of the current input and output audio device can't be set to a common value. Please select different input/output devices in your system settings. La taille de la mémoire tampon du périphérique audio d'entrée et de sortie actuel ne peut pas être définie sur une valeur commune. Veuillez sélectionner des périphériques d'entrée/sortie différents dans les paramètres de votre système. CSoundBase The selected audio device could not be used because of the following error: Le périphérique audio sélectionné n'a pas pu être utilisé en raison de l'erreur suivante : The previous driver will be selected. Le pilote précédent sera sélectionné. The previously selected audio device is no longer available or the audio driver properties have changed to a state which is incompatible with this software. We now try to find a valid audio device. This new audio device might cause audio feedback. So, before connecting to a server, please check the audio device setting. Le périphérique audio précédemment sélectionné n'est plus disponible ou les propriétés du pilote audio sont passées à un état incompatible avec ce logiciel. Nous essayons à présent de trouver un périphérique audio valide. Ce nouveau périphérique audio peut provoquer un retour audio. Aussi, avant de vous connecter à un serveur, veuillez vérifier le réglage du périphérique audio. No usable Pas de audio device (driver) found. périphérique audio (pilote) trouvé. In the following there is a list of all available drivers with the associated error message: Vous trouverez ci-dessous une liste de tous les pilotes disponibles avec le message d'erreur associé : Do you want to open the ASIO driver setups? Voulez-vous ouvrir les configurations des pilotes ASIO ? could not be started because of audio interface issues. n'a pas pu être lancé en raison de problèmes d'interface audio. Can't use the selected audio device because of the following error: %1 The previous driver will be selected. Impossible d'utiliser le périphérique audio sélectionné en raison de l'erreur suivante : %1 Le pilote précédent sera sélectionné. The previously selected audio device is no longer available or the driver has changed to an incompatible state. We'll attempt to find a valid audio device, but this new audio device may cause feedback. Before connecting to a server, please check your audio device settings. Le périphérique audio précédemment sélectionné n'est plus disponible ou le pilote est passé à un état incompatible. Nous allons essayer de trouver un périphérique audio valide, mais ce nouveau périphérique audio peut provoquer un effet larsen. Avant de vous connecter à un serveur, veuillez vérifier les paramètres de votre périphérique audio. <b>%1 couldn't find a usable %2 audio device.</b><br><br> <b>%1 n'a pas trouvé de périphérique audio utilisable %2.</b><br><br> You may be able to fix errors in the driver settings. Do you want to open these settings now? Vous pouvez peut-être corriger les erreurs dans les paramètres du pilote. Voulez-vous ouvrir ces paramètres maintenant ? No usable %1 audio device found. Aucun périphérique audio %1 utilisable n'a été trouvé. These are all the available drivers with error messages: Voici tous les pilotes disponibles avec les messages d'erreur : Do you want to open the ASIO driver setup to try changing your configuration to a working state? Voulez-vous ouvrir la configuration du pilote ASIO pour essayer de modifier votre configuration afin qu'elle fonctionne ? Can't start %1. Please restart %1 and check/reconfigure your audio settings. Impossible de démarrer %1. Veuillez redémarrer %1 et vérifier/reconfigurer vos paramètres audio. QCoreApplication %1, Version %2 %1, version %2 Internet Jam Session Software Logiciel de bœuf sur internet %1, Version %2 %1 is app name, %2 is version number %1, version %2 Released under the GNU General Public License version 2 or later (GPLv2) Publié sous la licence GNU General Public License version 2 ou ultérieure (GPLv2) This program is free software; you can redistribute it and/or modify it under Ce programme est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier dans les conditions suivantes the terms of the GNU General Public License as published by the Free Software les termes de la licence publique générale GNU (GNU General Public License), telle que publiée par l'association des logiciels libres (Free Software) Foundation; either version 2 of the License, or (at your option) any later version. Foundation ; soit la version 2 de la Licence, soit (à votre choix) toute version ultérieure. There is NO WARRANTY, to the extent permitted by law. Il n'y a AUCUNE GARANTIE, dans la mesure permise par la loi. Using the following libraries, resources or code snippets: Utilisation des bibliothèques, ressources ou extraits de code suivants : Qt framework Cadriciel de travail Qt Opus Interactive Audio Codec Codec audio interactif Opus Audio reverberation code by Perry R. Cook and Gary P. Scavone Code de réverbération audio par Perry R. Cook et Gary P. Scavone Some pixmaps are from the Open Clip Art Library (OCAL) Certains pixmaps proviennent de l'Open Clip Art Library (OCAL) Flag icons by Mark James Icônes de drapeaux par Mark James Copyright (C) 2005-2022 The Jamulus Development Team Copyright (C) 2005-2022 L'équipe de développement de Jamulus Released under the GNU General Public License (GPL) Publié sous la licence publique générale GNU (GPL) global A %1 upgrade is available: <a style='color:red;' href='https://jamulus.io/upgrade?progversion=%2'>go to details and downloads</a> A %1 une mise à jour est disponible : <a style='color:red;' href='https://jamulus.io/upgrade?progversion=%2'>rendez-vous dans détails et téléchargements</a> For more information use the "What's This" help (help menu, right mouse button or Shift+F1) Pour plus d'informations, utilisez l'aide "Qu'est-ce que c'est" (menu d'aide, bouton droit de la souris ou Maj+F1) jamulus-3.9.1+dfsg/src/translation/translation_pt_BR.ts0000644000175000017500000103606414340334543022307 0ustar vimervimer CAboutDlg The O software enables musicians to perform real-time jam sessions over the internet. There is a permite aos músicos realizar jam sessions em tempo real pela Internet. Existe um servidor software enables musicians to perform real-time jam sessions over the internet. permite aos músicos realizar jam sessions em tempo real pela Internet. server which collects the audio data from each que reúne os dados de áudio de cada cliente There is a Existe um servidor client, mixes the audio data and sends the mix back to each client. , que mistura os dados de áudio e envia a mistura de volta para cada cliente. uses the following libraries, resources or code snippets: utiliza as seguintes bibliotecas, recursos ou partes de código: Qt cross-platform application framework Estrutura de aplicações multiplataforma Qt Audio reverberation code by Perry R. Cook and Gary P. Scavone Código de reverberação de áudio por Perry R. Cook e Gary P. Scavone Some pixmaps are from the Alguns pixmaps são do Country flag icons from Mark James Ícones de bandeira do país de Mark James This app enables musicians to perform real-time jam sessions over the internet. Esta aplicação permite aos músicos realizar jam sessions em tempo real pela Internet. There is a server which collects the audio data from each client, mixes the audio data and sends the mix back to each client. Existe um servidor que reúne os dados de áudio de cada cliente, mixa e envia a mixagem de volta para cada cliente. This app uses the following libraries, resources or code snippets: Esta aplicação utiliza as seguintes bibliotecas, recursos ou partes de código: Country flag icons by Mark James Ícones das bandeiras dos países por Mark James For details on the contributions check out the Para detalhes sobre as contribuições, consulte a Flag icons by Mark James Ícones de bandeiras por Mark James Some sound samples are from Algumas amostras de som provenientes de For details on the contributions check out the %1 Para detalhes sobre as contribuições, consulte a %1 Github Contributors list lista de colaboradores do Github Spanish Espanhol French Francês Portuguese Português Dutch Holandês Italian Italiano German Alemão Polish Polonês Swedish Suíço Korean Coreano Slovak Eslovaco Simplified Chinese Chinês Simplificado Norwegian Bokmål About %1 Sobre %1 About Sobre o , Version , Versão Internet Jam Session Software Programa de Jam Sessions pela Internet Released under the GNU General Public License (GPL) Lançado sob a Licença Pública Geral GNU (GPL) Under the GNU General Public License (GPL) Sob a Licença Pública Geral GNU (GPL) CAboutDlgBase About Sobre TextLabelVersion TextLabelVersion Copyright (C) 2005-2022 Volker Fischer and others Copyright (C) 2005-2022 Volker Fischer e outros Copyright (C) 2005-2022 The Jamulus Development Team I'll keep it untranslated for the moment A&bout &Sobre &Libraries Should we keep the same shortcut key if possible? &Bibliotecas &Contributors &Colaboradores &Translation &Tradução Author: Volker Fischer Autor: Volker Fischer Copyright (C) 2005-2022 Copyright (C) 2005-2022 &OK &OK CAnalyzerConsole Analyzer Console Console de Análise Error Rate of Each Buffer Size Taxa de Erros de Cada Tamanho de Buffer CAudioMixerBoard Personal Mix at the Server Mixagem Pessoal no Servidor When connected to a server, the controls here allow you to set your local mix without affecting what others hear from you. The title shows the server name and, when known, whether it is actively recording. Quando conectado a um servidor, estes controles permite definir sua mixagem local sem afetar o que os outros ouvem de você. O título exibe o nome do servidor e, quando conhecido, se está ativamente gravando. Server Servidor T R Y I N G T O C O N N E C T T E N T A N D O C O N E C T A R RECORDING ACTIVE GRAVAÇÃO ATIVA Personal Mix at: %1 Mixagem Pessoal em: %1 CChannelFader Channel Level Nível do Canal Displays the pre-fader audio level of this channel. All connected clients at the server will be assigned an audio level, the same value for each client. Mostra o nível de áudio pré-fader deste canal. Todos os clientes ligados ao servidor terão atribuído um nível de áudio, o mesmo valor para cada cliente. Input level of the current audio channel at the server Nível de entrada deste canal de áudio no servidor Mixer Fader Fader do Mixer Adjusts the audio level of this channel. All connected clients at the server will be assigned an audio fader at each client, adjusting the local mix. Ajusta o nível de áudio deste canal. Por cada cliente ligado ao servidor será atribuído um fader de áudio em todos os clientes, podendo cada um ajustar a sua mistura local. Local mix level setting of the current audio channel at the server Configuração do nível de mixagem local deste canal de áudio no servidor Status Indicator Indicador de Estado Shows a status indication about the client which is assigned to this channel. Supported indicators are: Mostra uma indicação de estado do cliente que está atribuído a este canal. Os indicadores suportados são: Speaker with cancellation stroke: Indicates that the other client has muted you. Alti-falante com sinal de proibição: Indica que o cliente silenciou o teu canal. Status indicator label Etiqueta do indicador de estado Panning Panorâmica Sets the panning position from Left to Right of the channel. Works only in stereo or preferably mono in/stereo out mode. Define a posição de panorâmica da esquerda para a direita do canal. Funciona apenas no modo estéreo ou, de preferência, no modo Entrada Mono/Saída Estéreo. Local panning position of the current audio channel at the server Posição de panorâmica local deste canal de áudio no servidor With the Mute checkbox, the audio channel can be muted. Com a caixa de seleção Mute, o canal de áudio pode ser silenciado. Mute button Botão Mute With the Solo checkbox, the audio channel can be set to solo which means that all other channels except of the current channel are muted. It is possible to set more than one channel to solo. Com a caixa de seleção Solo, o canal de áudio pode ser definido como solo, o que significa que todos os outros canais, exceto o canal atual, serão silenciados. É possível definir mais que um canal no modo solo. Solo button Botão Solo Fader Tag Identificador do Fader The fader tag identifies the connected client. The tag name, the picture of your instrument and a flag of your country can be set in the main window. O Identificador do fader identifica o cliente ligado. O nome no identificador, a imagem do instrumento e a bandeira do país podem ser definidos no Meu Perfil. Grp Grp Displays the pre-fader audio level of this channel. All clients connected to the server will be assigned an audio level, the same value for every client. Mostra o nível de áudio pré-fader deste canal. A todos os clientes conectados ao servidor será atribuído um nível de áudio, o mesmo valor para cada cliente. &No grouping &Sem grupo Assign to group Atribuir ao grupo Adjusts the audio level of this channel. All clients connected to the server will be assigned an audio fader, displayed at each client, to adjust the local mix. Ajusta o nível de áudio deste canal. A todos os clientes ligados ao servidor será atribuído um fader de áudio,exibido em cada cliente, para ajustar a mixagem local. Speaker with cancellation stroke: Indicates that another client has muted you. Alto-falante com sinal de proibido: Indica que outro cliente silenciou o teu canal. Sets the pan from Left to Right of the channel. Works only in stereo or preferably mono in/stereo out mode. Define a posição de panorâmica da esquerda para a direita do canal. Funciona apenas no modo estéreo ou, de preferência, no modo Entrada Mono/Saída Estéreo. With the Solo checkbox, the audio channel can be set to solo which means that all other channels except the soloed channel are muted. It is possible to set more than one channel to solo. Com a caixa de seleção Solo, o canal de áudio pode ser definido como solo, o que significa que todos os outros canais, exceto o canal atual, serão silenciados. É possível definir mais que um canal no modo solo. Group Grupo With the Grp checkbox, a group of audio channels can be defined. All channel faders in a group are moved in proportional synchronization if any one of the group faders are moved. Com a caixa de seleção Grp, um grupo de canais de áudio pode ser definido. Todos os faders de canal de um grupo são movidos em sincronização proporcional se algum dos faders do grupo for movido. Group button Botão Grupo The fader tag identifies the connected client. The tag name, a picture of your instrument and the flag of your country can be set in the main window. O Identificador do fader identifica o cliente conectado. O nome no identificador, a imagem do instrumento e a bandeira do país podem ser definidos em Meu Perfil. Mixer channel instrument picture Imagem do instrumento do canal do mixer Mixer channel label (fader tag) Identificação do canal do mixer (identificador do fader) Mixer channel country flag Bandeira do país do canal do mixer PAN BAL MUTE MUTE SOLO SOLO GRP GRP M M S S G G Alias/Name Apelido/Nome Instrument Instrumento Location Localização Skill Level Nível de Habilidade Alias Apelido Beginner Principiante The fader tag identifies the connected client. The tag name, a picture of your instrument and the flag of your location can be set in the main window. A marcação do fader identifica o cliente conectado. O nome, a imagem de seu instrumento e a bandeira de sua localização podem ser definidos na janela principal. Mixer channel country/region flag Bandeira do país/região do canal do mixer Intermediate Intermediário Expert Avançado Musician Profile Perfil do músico Mute Mudo Pan Bal Solo Solo CChatDlg Chat Window Janela de Mensagens The chat window shows a history of all chat messages. A janela de mensagens mostra um histórico de todas as mensagens enviadas durante a sessão. Chat history Histórico de Mensagens Input Message Text Texto da Mensagem Enter the chat message text in the edit box and press enter to send the message to the server which distributes the message to all connected clients. Your message will then show up in the chat window. Digite o texto da mensagem no campo de digitação e pressione Enter para enviar a mensagem ao servidor, que distribui a mensagem a todos os clientes conectados. A sua mensagem será então exibida na janela de mensagens. New chat text edit box Campo de edição de texto da mensagem Type a message here Digite uma mensagem aqui &Edit E&ditar Cl&ear Chat History Didn't include "de Mensagens" in order to keep the menu a bit shorter. &Limpar Histórico &Close &Fechar Do you want to open the link '%1' in your browser? Deseja abrir o link '%1' em seu navegador? Do you want to open the link Você quer abrir o link in an external browser? em um navegador externo? CChatDlgBase Chat Mensagens &Send &Enviar Cl&ear &Limpar &Close &Fechar CClientDlg Input Level Meter Indicador do Nível de Entrada The input level indicators show the input level of the two stereo channels of the current selected audio input. Os indicadores do nível de entrada mostram o nível dos dois canais stereo da entrada de áudio selecionada. Make sure not to clip the input signal to avoid distortions of the audio signal. Certifique-se de não clipar o sinal de entrada para evitar distorções no sinal de áudio. If the Se o cliente software, you should not hear your singing/instrument in the loudspeaker or your headphone when the , não deve ouvir a sua voz/instrumento diretamente nas colunas ou nos headphones enquanto o cliente software is connected and you play your instrument/sing in the microphone, the LED level meter should flicker. If this is not the case, you have probably selected the wrong input channel (e.g. line in instead of the microphone input) or set the input gain too low in the (Windows) audio mixer. estiver ligado a um servidor e tocar o seu instrumento/cantar no microfone, os LEDs do medidor do nível de entrada devem piscar. Se tal não acontecer, provavelmente selecionou o canal de entrada errado (por exemplo, entrada de linha em vez da entrada do microfone) ou ajustou o ganho da entrada muito baixo no misturador de áudio (Windows) ou na placa de som. For a proper usage of the Para um uso adequado do cliente software is not connected. This can be achieved by muting your input audio channel in the Playback mixer (not the Recording mixer!). não estiver ligado a um servidor. Isso pode ser feito silenciando (mute) o canal da entrada de áudio no dispositivo de reprodução (não no dispositivo de captura!) Input level meter Medidor do nível de entrada Simulates an analog LED level meter. Simula um medidor de nível analógico LED. Connect/Disconnect Button Botão de Conectar/Desconectar Push this button to connect to a server. A dialog where you can select a server will open. If you are connected, pressing this button will end the session. Pressione este botão para se ligar a um servidor. Uma janela será aberta onde pode selecionar um servidor. Se já estiver ligado a um servidor, pressionar este botão encerrará a sessão. Connect and disconnect toggle button Botão de alternação entre ligar e desligar Clicking on this button changes the caption of the button from Connect to Disconnect, i.e., it implements a toggle functionality for connecting and disconnecting the Clicar nesse botão altera a legenda do botão de Ligar para Desligar, ou seja, implementa uma funcionalidade de alternação para conectar e desconectar o cliente software. . Local Audio Input Fader Fader da Entrada Local de Áudio Local audio input fader (left/right) Fader de entrada local de áudio (esquerdo/direito) Reverberation effect level setting Ajuste do nível do efeito de reverberação Left channel selection for reverberation Seleção do canal esquerdo para reverberação Right channel selection for reverberation Seleção do canal direito para reverberação If this LED indicator turns red, you will not have much fun using the Se este indicador LED ficar vermelho, não se vai divertir muito ao usar o This shows the level of the two stereo channels for your audio input. Isto mostra o nível dos dois canais estéreo para a sua entrada de áudio. If the application is connected to a server and you play your instrument/sing into the microphone, the VU meter should flicker. If this is not the case, you have probably selected the wrong input channel (e.g. 'line in' instead of the microphone input) or set the input gain too low in the (Windows) audio mixer. Se a aplicação estiver conectada a um servidor e você tocar o seu instrumento/cantar no microfone, os LEDs do medidor do nível de entrada devem piscar. Se isso não acontecer, você provavelmente selecionou o canal de entrada errado (Ex.: entrada de linha em vez da entrada do microfone) ou ajustou o ganho da entrada muito baixo no mixer de áudio (Windows) ou na placa de som. For proper usage of the application, you should not hear your singing/instrument through the loudspeaker or your headphone when the software is not connected. This can be achieved by muting your input audio channel in the Playback mixer (not the Recording mixer!). Para um uso adequado da aplicação, não deve ouvir a sua voz/instrumento diretamente nos alto-falantes ou nos fones enquanto a aplicação não estiver conectada a um servidor. Isso pode ser feito silenciando (mute) o canal da entrada de áudio no dispositivo de reprodução (não no dispositivo de captura!). Clicking on this button changes the caption of the button from Connect to Disconnect, i.e., it implements a toggle functionality for connecting and disconnecting the application. Clicar nesse botão altera a legenda do botão de Conectar para Desconectar, ou seja, implementa uma funcionalidade de alternação para conectar e desconectar a aplicação. Controls the relative levels of the left and right local audio channels. For a mono signal it acts as a pan between the two channels. For example, if a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows Controla os níveis relativos dos canais locais esquerdo e direito. Para um sinal mono, atua como uma panorâmica entre os dois canais. Por exemplo, se um microfone estiver ligado no canal direito e um instrumento estiver ligado no canal esquerdo, mais alto que o microfone, mova o fader de áudio numa direção em que a etiqueta acima do fader mostre Reverb effect Efeito de Reverberação Reverb can be applied to one local mono audio channel or to both channels in stereo mode. The mono channel selection and the reverb level can be modified. For example, if a microphone signal is fed in to the right audio channel of the sound card and a reverb effect needs to be applied, set the channel selector to right and move the fader upwards until the desired reverb level is reached. O efeito de reverberação pode ser aplicado a um canal local de áudio mono ou a ambos os canais no modo estéreo. A seleção do canal mono e o nível de reverberação podem ser modificados. Por exemplo, se o sinal do microfone for alimentado no canal de áudio direito da placa de som, e for necessário aplicar um efeito de reverberação, ajuste o seletor de canal para a direita e mova o fader para cima até que o nível de reverberação desejado seja atingido. Reverb effect level setting Ajuste do nível do efeito de reverberação Reverb Channel Selection Seleção do Canal de Reverberação With these radio buttons the audio input channel on which the reverb effect is applied can be chosen. Either the left or right input channel can be selected. Com estes botões de seleção, pode ser escolhido o canal de entrada de áudio no qual o efeito de reverberação é aplicado. Pode ser selecionado o canal de entrada esquerdo ou direito. Left channel selection for reverb Seleção do canal esquerdo para reverberação Right channel selection for reverb Seleção do canal direito para reverberação Green Verde The delay is perfect for a jam session. A latência é perfeita para uma jam session. Yellow Amarelo Red Vermelho If this LED indicator turns red, you will not have much fun using %1. Se este indicador LED ficar vermelho, você não irá divertir-se muito ao usar o %1. Delay status LED indicator Indicador LED do estado de latência Opens a dialog where you can select a server to connect to. If you are connected, pressing this button will end the session. Abre uma caixa de diálogo onde pode selecionar a que servidor conectar-se. Se estiver conectado, pressionar este botão vai terminar a sessão. Shows the current audio delay status: Mostra o estado atual da latência de áudio: A session is still possible but it may be harder to play. Ainda é possível fazer uma sessão, mas poderá ser mais difícil tocar no tempo. The delay is too large for jamming. A latência é demasiada para tocar no tempo. If this LED indicator turns red, you will not have much fun using the application. Se este indicador LED ficar vermelho, você não vai divertir-se muito ao usar a aplicação. The buffers status LED shows the current audio/streaming status. If the light is red, the audio stream is interrupted. This is caused by one of the following problems: O indicador LED do estado dos buffers mostra o estado atual do áudio/transmissão. Se a luz estiver vermelha, o fluxo de áudio é interrompido. Isto é causado por um dos seguintes problemas: The sound card's buffer delay (buffer size) is too small (see Settings window). O buffer (tamanho do buffer) da placa de som é demasiado pequeno (verificar janela das Definições). The upload or download stream rate is too high for your internet bandwidth. A taxa de upload ou download é muito elevada para a sua largura de banda da Internet. Buffers status LED indicator Indicador LED do estado dos buffers Current Connection Status Parameter Parâmetros do Estado da Conexão The Ping Time is the time required for the audio stream to travel from the client to the server and back again. This delay is introduced by the network and should be about 20-30 ms. If this delay is higher than about 50 ms, your distance to the server is too large or your internet connection is not sufficient. A latência da conexão é o tempo necessário para o fluxo de áudio viajar do cliente para o servidor e vice-versa. Esta latência é introduzida pela rede e deve ser cerca de 20-30 ms. Se esta latência for maior que 50 ms, a distância até ao servidor é muito grande ou sua conexão à Internet não é suficiente. Overall Delay is calculated from the current Ping Time and the delay introduced by the current buffer settings. A latência geral é calculada a partir da latência da conexão atual e do atraso introduzido pelas configurações de buffer. C&onnect C&onectar software upgrade available atualização de software disponível &File &Arquivo &View &Ver &Connection Setup... C&onectar a Servidor... My &Profile... Meu &Perfil... C&hat... &Mensagens... &Settings... &Definições... &Analyzer Console... Console de &Análise... Use &Two Rows Mixer Panel Usar Duas Fileiras para &Painel do Mixer Clear &All Stored Solo and Mute Settings Limpar Todas as Configurações de &Solo e Mute %1 Directory Diretório %1 Ok Ok E&xit S&air &Edit &Editar &Sort Users by Name Ordenar os Canais por &Nome... None Nenhum Center Centro R R L L With the audio fader, the relative levels of the left and right local audio channels can be changed. For a mono signal it acts like a panning between the two channels. If, e.g., a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows Com o fader de áudio, os níveis relativos dos canais locais esquerdo e direito podem ser alterados. Para um sinal mono, atua como uma panorâmica entre os dois canais. Se, por exemplo, um microfone estiver ligado no canal direito e um instrumento estiver ligado no canal esquerdo, mais alto que o microfone, mova o fader de áudio numa direção em que a etiqueta acima do fader mostre , where , onde is the current attenuation indicator. é o indicador de atenuação atual. Reverberation Level Nível de Reverberação A reverberation effect can be applied to one local mono audio channel or to both channels in stereo mode. The mono channel selection and the reverberation level can be modified. If, e.g., the microphone signal is fed into the right audio channel of the sound card and a reverberation effect shall be applied, set the channel selector to right and move the fader upwards until the desired reverberation level is reached. Um efeito de reverberação pode ser aplicado a um canal local de áudio mono ou a ambos os canais no modo estéreo. A seleção do canal mono e o nível de reverberação podem ser modificados. Se, por exemplo, o sinal do microfone for alimentado no canal de áudio direito da placa de som, e for aplicado um efeito de reverberação, ajuste o seletor de canal para a direita e mova o fader para cima até que o nível de reverberação desejado seja atingido. The reverberation effect requires significant CPU so it should only be used on fast PCs. If the reverberation level fader is set to minimum (which is the default setting), the reverberation effect is switched off and does not cause any additional CPU usage. O efeito de reverberação requer uma utilização do CPU significativa, de forma a que só deve ser usado em PCs rápidos. Se o atenuador do nível de reverberação estiver definido como mínimo (que é a configuração padrão), o efeito de reverberação será desativado e não causará nenhum uso adicional do CPU. Reverberation Channel Selection Seleção do Canal de Reverberação With these radio buttons the audio input channel on which the reverberation effect is applied can be chosen. Either the left or right input channel can be selected. Com estes botões de seleção, pode ser escolhido o canal de entrada de áudio no qual o efeito de reverberação é aplicado. Pode ser selecionado o canal de entrada esquerdo ou direito. Delay Status LED LED do Estado da Latência The delay status LED indicator shows the current audio delay status. If the light is green, the delay is perfect for a jam session. If the light is yellow, a session is still possible but it may be harder to play. If the light is red, the delay is too large for jamming. O indicador LED do estado da latência mostra o estado atual do atraso do áudio. Se a luz estiver verde, o atraso é perfeito para uma jam session. Se a luz estiver amarela, uma sessão ainda é possível, mas pode ser mais difícil tocar sincronizado. Se a luz estiver vermelha, o atraso é demasiado grande para uma sessão de jamming. Buffers Status LED LED do Estado dos Buffers The buffers status LED indicator shows the current audio/streaming status. If the light is green, there are no buffer overruns/underruns and the audio stream is not interrupted. If the light is red, the audio stream is interrupted caused by one of the following problems: O indicador LED do estado dos buffers mostra o estado atual do áudio/transmissão. Se a luz estiver verde, não haverá buffer em excesso/déficit e o fluxo de áudio não será interrompido. Se a luz estiver vermelha, o fluxo de áudio é interrompido devido a um dos seguintes problemas: The network jitter buffer is not large enough for the current network/audio interface jitter. O jitter buffer da rede não é grande o suficiente para o jitter atual da interface de rede/áudio. The sound card buffer delay (buffer size) is set to too small a value. O atraso do buffer da placa de som (buffer size) está definido para um valor demasiado baixo. The upload or download stream rate is too high for the current available internet bandwidth. A taxa de upload ou download é muito alta para a largura de banda disponível na ligação à Internet. The CPU of the client or server is at 100%. O CPU do cliente ou servidor está em 100%. If this LED indicator turns red, the audio stream is interrupted. Se este indicador LED ficar vermelho, o fluxo de áudio é interrompido. Current Connection Status Estado da Conexão Atual &Load Mixer Channels Setup... &Carregar Configuração de Canais do Mixer... &Save Mixer Channels Setup... &Salvar Configuração de Canais do Mixer... Sett&ings Def&inições Audio/Network &Settings... Definiçõe&s de Áudio/Rede... A&dvanced Settings... &Definições Avançadas... N&o User Sorting Sem &Ordenação de Canais Local Jitter Buffer Status LED LED de estado do jitter buffer local The local jitter buffer status LED shows the current audio/streaming status. If the light is red, the audio stream is interrupted. This is caused by one of the following problems: O indicador LED do estado do jitter buffer local mostra a situação atual do áudio/transmissão. Se a luz estiver vermelha, o fluxo de áudio é interrompido. Isto é causado por um dos seguintes problemas: Local Jitter Buffer status LED indicator Indicador LED de estado do jitter buffer local If this LED indicator turns red, you will not have much fun using the %1 software. Se este indicador LED ficar vermelho, você não irá divertir-se muito ao usar o software %1. O&wn Fader First P&róprio Fader Primeiro Sort Users by &Name Ordenar os Canais por &Nome Sort Users by &Instrument Ordenar os Canais por &Instrumento Sort Users by &Group Ordenar os Canais por &Grupo Sort Users by &City Ordenar os Canais por &Cidade Clear &All Stored Solo Settings &Limpar Todos Ajustes de Solo Armazenados Set All Faders to New Client &Level Todos os Faders para Nível de Novo C&liente Auto-Adjust all &Faders Auto-Ajuste todos &Faders &Settings &Definições Directory Server Servidor de Diretório Select Channel Setup File Selecione Arquivo de Configuraçao de Canal user usuário users usuários Connect Conectar Settings Definições Chat Mensagens Enable feedback detection Ativar detecção de microfonia Audio feedback or loud signal detected. We muted your channel and activated 'Mute Myself'. Please solve the feedback issue first and unmute yourself afterwards. Microfonia ou sinal alto detectado. Silenciamos seu canal e ativamos 'Silenciar-me'. Resolva o problema de microfonia primeiro e depois reative seu som. Your sound card is not working correctly. Please open the settings dialog and check the device selection and the driver settings. Sua placa de som não está funcionando corretamente. Por favor abra a janela de ajustes e verifique a seleção do dispositivo e as configurações de driver. &Disconnect &Desconectar CClientDlgBase Delay Latência Buffers Buffers Input Entrada L L R R Jitter Jitter Ping Ping ms ms &Mute Myself Silenciar-&me &Settings Definiçõe&s &Chat Me&nsagens C&onnect C&onectar Pan Pan Center Centro Reverb Reverb Left Esquerdo Right Direito MUTED (Other people won't hear you) SILENCIADO (As pessoas não te ouvirão) Set up your audio, connect to a server and start jamming! Configure seu áudio, conecte-se a um servidor e comece a tocar! Update check Verificação de atualização CClientSettingsDlg Jitter Buffer Size Tamanho do Jitter Buffer The jitter buffer compensates for network and sound card timing jitters. The size of this jitter buffer has therefore influence on the quality of the audio stream (how many dropouts occur) and the overall delay (the longer the buffer, the higher the delay). O jitter buffer (ou buffer de instabilidade) compensa os desvios de temporização da rede e da placa de som. O tamanho desse jitter buffer influencia, portanto, a qualidade do fluxo de áudio (quantas interrupções ocorrem) e a latência geral (quanto maior o buffer, maior a latência). The jitter buffer size can be manually chosen for the local client and the remote server. For the local jitter buffer, dropouts in the audio stream are indicated by the light below the jitter buffer size faders. If the light turns to red, a buffer overrun/underrun took place and the audio stream is interrupted. O tamanho do jitter buffer pode ser escolhido manualmente para o cliente local e o servidor remoto. Para o jitter buffer local, as interrupções no fluxo de áudio são indicadas pela luz na parte inferior dos faders do jitter buffer. Se a luz ficar vermelha, ocorreu um excesso/déficit do buffer e o fluxo de áudio é interrompido. The jitter buffer setting is therefore a trade-off between audio quality and overall delay. A configuração do jitter buffer é, portanto, uma troca entre a qualidade do áudio e o atraso geral. An auto setting of the jitter buffer size setting is available. If the check Auto is enabled, the jitter buffers of the local client and the remote server are set automatically based on measurements of the network and sound card timing jitter. If the Auto check is enabled, the jitter buffer size faders are disabled (they cannot be moved with the mouse). Está disponível uma configuração automática do tamanho do jitter buffer. Se a opção Auto estiver ativada, os jitter buffers do cliente local e do servidor remoto serão configurados automaticamente com base nas medições da instabilidade de sincronização da rede e da placa de som. Se a opção Auto estiver ativada, os faders do jitter buffer serão desativados (não poderão ser movidos manualmente). If the auto setting of the jitter buffer is enabled, the network buffers of the local client and the remote server are set to a conservative value to minimize the audio dropout probability. To tweak the audio delay/latency it is recommended to disable the auto setting functionality and to lower the jitter buffer size manually by using the sliders until your personal acceptable limit of the amount of dropouts is reached. The LED indicator will visualize the audio dropouts of the local jitter buffer with a red light. Caso a configuração automática do jitter buffer estiver ativada, os buffers de rede do cliente local e do servidor remoto são configurados com um valor conservador para minimizar a probabilidade de perda de áudio. Para ajustar o atraso/latência do áudio, é recomendável desativar a funcionalidade de configuração automática e diminuir o tamanho do jitter buffer manualmente usando os controles deslizantes até que a quantidade de perdas de áudio lhe sejam pessoalmente aceitáveis. O indicador LED representará as interrupções de áudio do jitter buffer local através de uma luz vermelha. Local jitter buffer slider control Controle deslizante do jitter buffer local Server jitter buffer slider control Controle deslizante do jitter buffer do servidor Auto jitter buffer switch Interruptor do jitter buffer automático Jitter buffer status LED indicator Indicador LED de estado do jitter buffer Sound Card Device Dispositivo de Som The ASIO driver (sound card) can be selected using O driver ASIO (placa de som) pode ser selecionado usando o under the Windows operating system. Under MacOS/Linux, no sound card selection is possible. If the selected ASIO driver is not valid an error message is shown and the previous valid driver is selected. no Windows. No MacOS/Linux, não é possível seleccionar a placa de som. Se o driver ASIO selecionado não for válido, uma mensagem de erro será exibida e o driver válido anterior será selecionado. If the driver is selected during an active connection, the connection is stopped, the driver is changed and the connection is started again automatically. Se o driver for selecionado durante uma sessão ativa, a conexão será interrompida, o driver será alterado e a conexão reiniciada automaticamente. Sound card device selector combo box Seletor de dispositivo de som If the ASIO4ALL driver is used, please note that this driver usually introduces approx. 10-30 ms of additional audio delay. Using a sound card with a native ASIO driver is therefore recommended. Caso o driver ASIO4ALL seja usado, note que esse driver geralmente introduz aprox. 10-30 ms de atraso de áudio adicional. Dado isto, é recomendável usar uma placa de som com um driver ASIO nativo. If you are using the kX ASIO driver, make sure to connect the ASIO inputs in the kX DSP settings panel. Se estiver utilizando o driver kX ASIO, certifique-se de conectar as entradas ASIO no painel de configurações do kX DSP. Sound Card Channel Mapping Mapeamento de Canais da Placa de Som If the selected sound card device offers more than one input or output channel, the Input Channel Mapping and Output Channel Mapping settings are visible. Caso o dispositivo selecionado da placa de som ofereça mais que um canal de entrada ou saída, as configurações de Mapeamento de canais de entrada e de saída estarão visíveis. For each Para cada canal de entrada/saída do input/output channel (Left and Right channel) a different actual sound card channel can be selected. (canal esquerdo e direito), um canal real da placa de som pode ser selecionado. Left input channel selection combo box Seletor de canal de entrada esquerdo Right input channel selection combo box Seletor de canal de entrada direito Left output channel selection combo box Seletor de canal de saída esquerdo Right output channel selection combo box Seletor de canal de saída direito Enable Small Network Buffers Habilitar Buffers de Rede Pequenos If enabled, the support for very small network audio packets is activated. Very small network packets are only actually used if the sound card buffer delay is smaller than Se habilitado, o suporte para pacotes de áudio de rede muito pequenos é ativado. Pacotes de rede muito pequenos serão apenas realmente usados se o atraso do buffer da placa de som for menor que samples. The smaller the network buffers, the lower the audio latency. But at the same time the network load increases and the probability of audio dropouts also increases. amostras. Quanto menor o buffer da rede, menor a latência do áudio. Mas, ao mesmo tempo, a carga da rede e a probabilidade de interrupção do áudio também aumentam. Enable small network buffers check box Caixa de ativação de buffers de rede pequenos Sound Card Buffer Delay Atraso do Buffer da Placa de Som Some sound card drivers do not allow the buffer delay to be changed from within the application. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. On Windows, press the ASIO Device Settings button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Alguns drivers da placa de som não permitem que o atraso do buffer seja alterado pela aplicação. Nesse caso, a configuração de atraso do buffer estará desativada e deve ser alterada no driver da placa de som. No Windows, pressione o botão Definições de Dispositivo ASIO para abrir o painel de configurações do driver. No Linux, use a ferramenta de configuração Jack para alterar o atraso do buffer. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within the software. On Windows, press the ASIO Device Settings button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Se as definições de atraso do buffer estiverem desativadas, está proibido pelo driver do áudio sua modificação a partir do programa. No Windows, pressione o botão Definições de Dispositivo ASIO para abrir o painel de configurações do driver. No Linux, use a ferramenta de configuração Jack para alterar o tamanho do buffer. Sound card driver settings Definições de driver da placa de som This opens the driver settings of your sound card. Some drivers allow you to change buffer settings, others like ASIO4ALL let you choose input or outputs of your device(s). More information can be found on jamulus.io. Abre definições de driver para sua placa de som. Alguns drivers permitem mudanças na configuração de buffer, outros como ASIO4ALL permitem escolher entradas e saídas do seu(s) dispositivo(s). Mais informações pode ser encontrada em jamulus.io. Opens the driver settings. Note: Abre definições do driver. Nota: currently only supports devices supporting a sample rate of atualmente suporta apenas dispositivos com suporte à taxa de amostra de Hz. You will not be able to select a driver/device which doesn't. For more help see jamulus.io. Hz. Não será possível selecion um driver/dispositivo que não suporta. Para mais ajuda veja jamulus.io. ASIO Device Settings push button Botão de Definições do Dispositivo ASIO Select the meter style to be used for the level meters. The Bar (narrow) and LEDs (round, small) options only apply to the mixerboard. When Bar (narrow) is selected, the input meters are set to Bar (wide). When LEDs (round, small) is selected, the input meters are set to LEDs (round, big). The remaining options apply to the mixerboard and input meters. Selecione o estilo a ser usado para os medidores de nível. As opções Barra (estreita) e LEDs (redondo, pequeno) aplicam-se apenas à mesa do mixer. Quando a Barra (estreita) é selecionada, os medidores de entrada são definidos como Barra (larga). Quando LEDs (redondo, pequeno) é selecionado, os medidores de entrada são definidos como LEDs (redondo, grande). As opções restantes aplicam-se à mesa do mixer e aos medidores de entrada. Language Idioma Select the language to be used for the user interface. Selecione o idioma para ser utilizado na interface do usuário. Language combo box Seletor de idioma and e Audio Upstream Rate Taxa de Transmissão de Áudio Depends on the current audio packet size and compression setting. Make sure that the upstream rate is not higher than your available internet upload speed (check this with a service such as speedtest.net). Depende do tamanho do pacote de áudio e da configuração de compactação de áudio. Certifique-se de que a taxa de transmissão não é maior que a taxa de upload de internet disponível (verifique isso em um serviço como o speedtest.net). LEDs LEDs Bar Barra Narrow Bar Barra Estreita Round LEDs LEDs Redondos Small LEDs LEDs Pequenos None Nenhum Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country or region you are located in. Your city and skill level playing your instrument may also be added. Escreva o seu nome ou um apelido aqui para que os outros músicos com quem quer tocar saibam quem você é. Além disso, pode também definir uma imagem do instrumento que toca e uma bandeira do país ou região onde vive. A cidade e o nível de habilidade com o seu instrumento também podem ser adicionados. What you set here will appear at your fader on the mixer board when you are connected to a %1 server. This tag will also be shown at each client which is connected to the same server as you. O que definir aqui aparecerá abaixo do seu fader no mixer quando estiver conectado a um servidor %1. Esta etiqueta também será exibida em cada cliente que estiver conectado ao mesmo servidor. Country/region flag button Botão da bandeira do país/região Center Centro R R The buffer delay setting is a fundamental setting of the A configuração do atraso do buffer (buffer delay) é uma configuração fundamental do cliente software. This setting has influence on many connection properties. . Esta configuração tem influência em muitas propriedades da ligação. Three buffer sizes are supported Três tamanhos de buffer são suportados 64 samples: This is the preferred setting since it provides the lowest latency but does not work with all sound cards. 64 amostras: esta é a configuração preferida, pois oferece menor latência, mas não funciona com todas as placas de som. 128 samples: This setting should work for most available sound cards. 128 amostras: esta configuração deve funcionar na maioria das placas de som disponíveis. 256 samples: This setting should only be used if only a very slow computer or a slow internet connection is available. 256 amostras: esta configuração deve ser usada se apenas estiver disponível um computador muito lento ou uma ligação lenta à Internet. Some sound card drivers do not allow the buffer delay to be changed from within the Alguns drivers da placa de som não permitem que o atraso do buffer seja alterado pelo cliente software. In this case the buffer delay setting is disabled. To change the actual buffer delay, this setting has to be changed in the sound card driver. On Windows, press the ASIO Setup button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. . Nesse caso, a configuração de atraso do buffer estará desativada. Para alterar o atraso do buffer, essa configuração deve ser alterada no driver da placa de som. No Windows, pressione o botão Configuração do Driver para abrir o painel de configurações do driver. No Linux, use a ferramenta de configuração Jack para alterar o atraso do buffer. If no buffer size is selected and all settings are disabled, an unsupported buffer size is used by the driver. The Se nenhum atraso do buffer estiver selecionado e todas as configurações estiverem desativadas, um atraso do buffer não suportado será usado pelo driver. O cliente software will still work with this setting but with restricted performance. ainda funcionará com essa configuração, mas com desempenho restrito. The actual buffer delay has influence on the connection status, the current upload rate and the overall delay. The lower the buffer size, the higher the probability of a red light in the status indicator (drop outs) and the higher the upload rate and the lower the overall delay. O atraso do buffer influencia o estado da conexão, a taxa de upload atual e a latência geral. Quanto menor o tamanho do buffer, maior a probabilidade de a luz vermelha no indicador de estado (interrupções), maior a taxa de upload e menor a latência geral. The buffer setting is therefore a trade-off between audio quality and overall delay. A configuração do buffer é, portanto, uma troca entre qualidade de áudio e latência geral. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within the Se as configurações de atraso do buffer estiverem desativadas, é porque o driver de áudio proibe modificar essa configuração a partir do cliente software. On Windows, press the ASIO Setup button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. . No Windows, pressione o botão <i>Configuração do Driver</i> para abrir o painel de configurações do driver. No Linux, use a ferramenta de configuração <i>Jack</i> para alterar o atraso do buffer. 64 samples setting radio button Botão de configuração de 64 amostras 128 samples setting radio button Botão de configuração de 128 amostras 256 samples setting radio button Botão de configuração de 256 amostras ASIO setup push button Botão de configuração do ASIO Fancy Skin Skin Sofisticada If enabled, a fancy skin will be applied to the main window. Se ativada, uma skin sofisticada será aplicada à janela principal. Fancy skin check box Caixa de ativação da skin sofisticada Display Channel Levels Mostrar Níveis de Canais If enabled, each client channel will display a pre-fader level bar. Se habilitado, cada canal de cliente exibirá uma barra de nível pré-fader. Display channel levels check box Caixa de ativação para exibir níveis de canais Audio Channels Canais de Áudio Select the number of audio channels to be used. There are three modes available. The mono and stereo modes use one and two audio channels respectively. In mono-in/stereo-out mode the audio signal which is sent to the server is mono but the return signal is stereo. This is useful if the sound card has the instrument on one input channel and the microphone on the other channel. In that case the two input signals can be mixed to one mono channel but the server mix can be heard in stereo. Selecione o número de canais de áudio a serem usados. Existem três modos disponíveis. Os modos mono e estéreo usam um e dois canais de áudio, respectivamente. No modo Entrada Mono/Saída Estéreo, o sinal de áudio enviado ao servidor é mono, mas o sinal de retorno é estéreo. Isso é útil quando a placa de som coloca o instrumento e o microfone em canais diferentes. Nesse caso, os dois sinais de entrada podem ser misturados num canal mono, mas a mistura do servidor pode ser ouvida em estéreo. Enabling the stereo streaming mode will increase the stream data rate. Make sure that the current upload rate does not exceed the available bandwidth of your internet connection. Ativar o modo de transmissão estéreo aumenta a taxa do fluxo de dados. Verifique que a taxa de transmissão não excede a largura de banda disponível da sua ligação à Internet. In stereo streaming mode, no audio channel selection for the reverberation effect will be available on the main window since the effect is applied on both channels in this case. No modo de transmissão estéreo, nenhuma seleção de canal de áudio para o efeito de reverberação estará disponível na janela principal, pois o efeito é aplicado em ambos os canais. Audio channels combo box Seletor de canais de áudio Audio Quality Qualidade de Áudio Select the desired audio quality. A low, normal or high audio quality can be selected. The higher the audio quality, the higher the audio stream data rate. Make sure that the current upload rate does not exceed the available bandwidth of your internet connection. Selecione a qualidade de áudio desejada. Pode ser selecionada uma qualidade de áudio baixa, normal ou alta. Quanto maior a qualidade do áudio, maior a taxa de dados do fluxo de áudio. Verifique que a taxa de transmissão não excede a largura de banda disponível da sua ligação à Internet. Audio quality combo box Seletor de qualidade áudio New Client Level Nível de Novo Cliente The new client level setting defines the fader level of a new connected client in percent. I.e. if a new client connects to the current server, it will get the specified initial fader level if no other fader level of a previous connection of that client was already stored. A configuração de nível de novo cliente define, em percentagem, o nível do fader de um novo cliente ligado. Por exemplo, se um cliente novo se ligar ao servidor atual, o seu canal terá o nível inicial do fader especificado, excepto quando um diferente nível do fader de uma ligação anterior desse mesmo cliente já tenha sido definido. New client level edit box Caixa de edição no nível de novo cliente Custom Directory Server Address Endereço de Servidor de Diretório Personalizado The custom directory server address is the IP address or URL of the directory server at which the server list of the connection dialog is managed. This address is only used if the custom server list is selected in the connection dialog. O endereço personalizado do servidor central é o endereço IP ou URL do servidor central no qual a lista de servidores da Configuração de Ligação é gerida. Este endereço é usado apenas se a lista de servidores personalizados estiver selecionada na Configuração de Ligação. Directory Server Address Endereço do servidor central The directory server address is the IP address or URL of the directory server at which the server list of the connection dialog is managed. With the directory server address type either the local region can be selected of the default directory servers or a manual address can be specified. O endereço do servidor central é o endereço IP ou URL do servidor central a partir do qual é gerida a lista de servidores do diálogo de ligação. Com a configuração do endereço do servidor central, é possível selecionar um dos servidores centrais padrão ou especificar um endereço manual. Default directory server type combo box Seletor de servidor central padrão Directory server address line edit Caixa de edição do endereço de servidor central Current Connection Status Parameter Parâmetros do Estado da Conexão The ping time is the time required for the audio stream to travel from the client to the server and back again. This delay is introduced by the network. This delay should be as low as 20-30 ms. If this delay is higher (e.g., 50-60 ms), your distance to the server is too large or your internet connection is not sufficient. A latência da ligação é o tempo necessário para o fluxo de áudio viajar do cliente para o servidor e vice-versa. Esta latência é introduzida pela rede. Esta latência deve ser tão baixa quanto 20-30 ms. Se esta latência for maior (por exemplo, 50-60 ms), a distância até ao servidor é muito grande ou sua ligação à Internet não é suficiente. The overall delay is calculated from the current ping time and the delay which is introduced by the current buffer settings. A latência geral é calculada a partir da latência da ligação atual e do atraso introduzido pelas configurações do buffer. The upstream rate depends on the current audio packet size and the audio compression setting. Make sure that the upstream rate is not higher than the available rate (check the upstream capabilities of your internet connection by, e.g., using speedtest.net). A taxa de transmissão depende do tamanho do pacote de áudio e da configuração de compactação de áudio. Verifique se a taxa de transmissão não é maior que a taxa disponível (verifique a taxa de upload da sua ligação à Internet usando, por exemplo, o speedtest.net). If this LED indicator turns red, you will not have much fun using the Se este indicador LED ficar vermelho, você não irá divertir-se muito ao usar o software. . ASIO Setup Configuração ASIO Mono Mono mode will increase your stream's data rate. Make sure your upload rate does not exceed the available upload speed of your internet connection. vai aumentar a quantidade de dados da transmissão. Verifique se a taxa de upload não ultrapassa a velocidade de upload disponível da sua conexão à Internet. Audio Upstream Rate depends on the current audio packet size and compression setting. Make sure that the upstream rate is not higher than your available internet upload speed (check this with a service such as speedtest.net). A taxa de transmissão do áudio depende do tamanho do pacote de áudio e da configuração de compactação de áudio. Verifique se a taxa de transmissão não é maior que a taxa disponível (verifique a taxa de upload da sua conexão à Internet usando, por exemplo, o speedtest.net). Mono-in/Stereo-out Entrada Mono/Saída Estéreo Stereo Estéreo &Close &Fechar Local Audio Input Fader Fader da Entrada Local de Áudio Controls the relative levels of the left and right local audio channels. For a mono signal it acts as a pan between the two channels. For example, if a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows Controla os níveis relativos dos canais locais esquerdo e direito. Para um sinal mono, atua como uma panorâmica entre os dois canais. Por exemplo, se um microfone estiver ligado no canal direito e um instrumento estiver ligado no canal esquerdo, mais alto que o microfone, mova o fader de áudio numa direção em que a etiqueta acima do fader mostra L L , where , onde is the current attenuation indicator. é o indicador de atenuação atual. Local audio input fader (left/right) Fader de entrada local de áudio (esquerdo/direito) The jitter buffer compensates for network and sound card timing jitters. The size of the buffer therefore influences the quality of the audio stream (how many dropouts occur) and the overall delay (the longer the buffer, the higher the delay). O jitter buffer (ou buffer de instabilidade) compensa os desvios de temporização da rede e da placa de som. O tamanho do buffer influencia, portanto, a qualidade do fluxo de áudio (quantas interrupções ocorrem) e a latência geral (quanto maior o buffer, maior a latência). You can set the jitter buffer size manually for the local client and the remote server. For the local jitter buffer, dropouts in the audio stream are indicated by the light below the jitter buffer size faders. If the light turns to red, a buffer overrun/underrun has taken place and the audio stream is interrupted. Pode escolher o tamanho do jitter buffer manualmente para o cliente local e o servidor remoto. Para o jitter buffer local, as interrupções no fluxo de áudio são indicadas pela luz na parte inferior dos faders do jitter buffer. Se a luz ficar vermelha, ocorreu um excesso/déficit do buffer e o fluxo de áudio é interrompido. If the Auto setting is enabled, the jitter buffers of the local client and the remote server are set automatically based on measurements of the network and sound card timing jitter. If Auto is enabled, the jitter buffer size faders are disabled (they cannot be moved with the mouse). Caso a configuração automática estiver ativada, os buffers de rede do cliente local e do servidor remoto são configurados automaticamente com um valor conservador para minimizar a probabilidade de perda de áudio. Se o modo automático estiver ligado, os controlos estarão desativados (não podem ser alterados pelo usuário). If the Auto setting is enabled, the network buffers of the local client and the remote server are set to a conservative value to minimize the audio dropout probability. To tweak the audio delay/latency it is recommended to disable the Auto setting and to lower the jitter buffer size manually by using the sliders until your personal acceptable amount of dropouts is reached. The LED indicator will display the audio dropouts of the local jitter buffer with a red light. Caso a configuração automática do jitter buffer estiver ativada, os buffers de rede do cliente local e do servidor remoto são configurados com um valor conservador para minimizar a probabilidade de perda de áudio. Para ajustar o atraso/latência do áudio, é recomendável desativar a funcionalidade de configuração automática e diminuir o tamanho do jitter buffer manualmente usando os controles deslizantes até que a quantidade de perdas de áudio lhe sejam pessoalmente aceitáveis. O indicador LED representará as interrupções de áudio do jitter buffer local através de uma luz vermelha. The ASIO driver (sound card) can be selected using %1 under the Windows operating system. Under macOS/Linux, no sound card selection is possible. If the selected ASIO driver is not valid an error message is shown and the previous valid driver is selected. O driver ASIO (placa de som) pode ser selecionado usando %1 no Windows. No macOS/Linux, não é possível selecionar a placa de som. Se o driver ASIO selecionado não for válido, uma mensagem de erro será exibida e o driver válido anterior será selecionado. For each %1 input/output channel (left and right channel) a different actual sound card channel can be selected. Para cada canal de entrada/saída do %1 (canal esquerdo e direito), um canal real da placa de som pode ser selecionado. Enables support for very small network audio packets. These network packets are only actually used if the sound card buffer delay is smaller than %1 samples. The smaller the network buffers, the lower the audio latency. But at the same time the network load and the probability of audio dropouts or sound artifacts increases. Habilita suporte para pacotes de áudio de rede muito pequenos. Esses pacotes de rede só são realmente usados se o buffer de atraso da placa de som for menor que %1 amostras. Quanto menores os buffers de rede, menor a latência do áudio. Mas, ao mesmo tempo, a carga da rede e a probabilidade de falhas de áudio ou artefatos de som aumentam. The buffer delay setting is a fundamental setting of %1. This setting has an influence on many connection properties. A configuração do atraso do buffer é uma configuração fundamental do %1. Esta configuração tem influência em muitas propriedades da conexão. Some sound card drivers do not allow the buffer delay to be changed from within %1. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. On Windows, use the ASIO Device Settings button to open the driver settings panel. On Linux, use the JACK configuration tool to change the buffer size. Alguns drivers da placa de som não permitem que o atraso do buffer seja alterado pela aplicação %1. Nesse caso, a configuração de atraso do buffer é desativada e deve ser alterada no driver da placa de som. No Windows, pressione o botão Definições de Dispositivo ASIO para abrir o painel de configurações do driver. No Linux, use a ferramenta de configuração JACK para alterar o tamanho do buffer. If no buffer size is selected and all settings are disabled, this means an unsupported buffer size is in use by the driver. %1 will still work with this setting but may have restricted performance. Usei limitado em vez de restrito Se nenhum tamanho de buffer estiver selecionado e todas as configurações estiverem desativadas, um atraso do buffer não suportado será usado pelo driver. A aplicação %1 ainda funcionará com essa configuração, mas com desempenho limitado. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within %1. On Windows, press the ASIO Device Settings button to open the driver settings panel. On Linux, use the JACK configuration tool to change the buffer size. Se as configurações de atraso do buffer estiverem desativadas, é porque o driver de áudio proibe modificar essa configuração a partir do %1. No Windows, pressione o botão Configuração do Driver para abrir o painel de configurações do driver. No Linux, use a ferramenta de configuração Jack para alterar o atraso do buffer. This opens the driver settings of your sound card. Some drivers allow you to change buffer settings, others like ASIO4ALL lets you choose input or outputs of your device(s). More information can be found on jamulus.io. Isto abre definições de driver para sua placa de som. Alguns drivers permitem mudanças na configuração de buffer, outros como ASIO4ALL permitem escolher entradas e saídas do(s) seu(s) dispositivo(s). Mais informações podem ser encontradas em jamulus.io. Opens the driver settings. Note: %1 currently only supports devices with a sample rate of %2 Hz. You will not be able to select a driver/device which doesn't. For more help see jamulus.io. Abre as definições de driver. Nota: %1 somente suporta dispositivos com uma taxa de amostras de %2 Hz. Você não poderá selecionar um driver/dispositivo que não suporte. Para obter mais ajuda, consulte jamulus.io. The buffer delay setting is a fundamental setting of this software. This setting has an influence on many connection properties. A configuração do atraso do buffer (buffer delay) é uma configuração fundamental da aplicação. Esta configuração tem influência em muitas propriedades da conexão. 64 samples: The preferred setting. Provides the lowest latency but does not work with all sound cards. 64 amostras: Configuração preferida. Fornece menor latência, mas não funciona com todas as placas de som. 128 samples: Should work for most available sound cards. 128 amostras: Deve funcionar na maioria das placas de som disponíveis. 256 samples: Should only be used on very slow computers or with a slow internet connection. 256 amostras: Deve apenas ser usada se tiver um computador muito lento ou uma ligação lenta à Internet. Some sound card drivers do not allow the buffer delay to be changed from within the application. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. On Windows, press the ASIO Setup button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Alguns drivers da placa de som não permitem que o atraso do buffer seja alterado pela aplicação. Nesse caso, a configuração de atraso do buffer estará desativada e deve ser alterada no driver da placa de som. No Windows, pressione o botão Configuração do Driver para abrir o painel de configurações do driver. No Linux, use a ferramenta de configuração Jack para alterar o atraso do buffer. If no buffer size is selected and all settings are disabled, an unsupported buffer size is used by the driver. The application will still work with this setting but with restricted performance. Se nenhum atraso do buffer estiver selecionado e todas as configurações estiverem desativadas, um atraso do buffer não suportado será usado pelo driver. A aplicação ainda funcionará com essa configuração, mas com desempenho restrito. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within the software. On Windows, press the ASIO Setup button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Se as configurações de atraso do buffer estiverem desativadas, é porque o driver de áudio proibe modificar essa configuração a partir da aplicação. No Windows, pressione o botão Configuração do Driver para abrir o painel de configurações do driver. No Linux, use a ferramenta de configuração Jack para alterar o atraso do buffer. Skin Aparência Select the skin to be used for the main window. Selecione a aparência para ser utilizada na janela principal. Skin combo box Seletor de aparência Selects the number of audio channels to be used for communication between client and server. There are three modes available: Seleciona o número de canais de áudio a serem usados para a comunicação entre cliente e servidor. Existem três modos disponíveis: and e These modes use one and two audio channels respectively. Estes modos usam um e dois canais de áudio, respectivamente. Mono in/Stereo-out Entrada Mono/Saída Estéreo The audio signal sent to the server is mono but the return signal is stereo. This is useful if the sound card has the instrument on one input channel and the microphone on the other. In that case the two input signals can be mixed to one mono channel but the server mix is heard in stereo. O sinal de áudio enviado ao servidor é mono, mas o sinal de retorno é estéreo. Isso é útil quando a placa de som coloca o instrumento e o microfone em canais diferentes. Nesse caso, os dois sinais de entrada podem ser misturados num canal mono, mas a mistura do servidor pode ser ouvida em estéreo. Enabling Habilitando o modo In stereo streaming mode, no audio channel selection for the reverb effect will be available on the main window since the effect is applied to both channels in this case. No modo de transmissão estéreo, nenhuma seleção de canal de áudio para o efeito de reverberação estará disponível na janela principal, pois o efeito é aplicado em ambos os canais. The higher the audio quality, the higher your audio stream's data rate. Make sure your upload rate does not exceed the available bandwidth of your internet connection. Quanto maior a qualidade de áudio, maior a quantidade de dados da transmissão. Verifique se a taxa de upload não ultrapassa a velocidade de upload disponível da sua conexão à Internet. This setting defines the fader level of a newly connected client in percent. If a new client connects to the current server, they will get the specified initial fader level if no other fader level from a previous connection of that client was already stored. Esta opção define o nível do fader de um cliente novo, em percentagem. Se um cliente novo conecta-se ao mesmo servidor, este irá ter o nível do fader específicado, exceto se já definiu o nível do fader desse cliente a partir de uma conexão anterior que tenha sido guardada. Input Boost Changed from Impulso to Reforço Reforço de Entrada This setting allows you to increase your input signal level by factors up to 10 (+20dB). If your sound is too quiet, first try to increase the level by getting closer to the microphone, adjusting your sound equipment or increasing levels in your operating system's input settings. Only if this fails, set a factor here. If your sound is too loud, sounds distorted and is clipping, this option will not help. Do not use it. The distortion will still be there. Instead, decrease your input level by getting farther away from your microphone, adjusting your sound equipment or by decreasing your operating system's input settings. Esta configuração permite que você aumente o nível do seu sinal de entrada em fatores de até 10 (+ 20dB). Se o seu som estiver muito baixo, primeiro tente aumentar o nível aproximando-se do microfone, ajustando seu equipamento de som ou aumentando os níveis de entrada nas configurações do sistema operacional. Somente se isso falhar, defina um fator aqui. Se o seu som estiver muito alto, distorcido e cortado, esta opção não ajudará. Não use isso. A distorção ainda estará lá. Em vez disso, diminua o nível de entrada ficando mais longe do microfone, ajustando o equipamento de som ou diminuindo as configurações de entrada do sistema operacional. Input Boost combo box Seletor do Reforço de Entrada Leave this blank unless you need to enter the address of a directory server other than the default. Deixe este campo em branco exceto se necessitar de introduzir um endereço alternativo de um servidor de diretório. Directory server address combo box Seletor do endereço do servidor de diretório The Ping Time is the time required for the audio stream to travel from the client to the server and back again. This delay is introduced by the network and should be about 20-30 ms. If this delay is higher than about 50 ms, your distance to the server is too large or your internet connection is not sufficient. A latência da conexão é o tempo necessário para o fluxo de áudio viajar do cliente para o servidor e vice-versa. Esta latência é introduzida pela rede e deve ser cerca de 20-30 ms. Se esta latência for maior que 50 ms, a distância até ao servidor é muito grande ou sua conexão à Internet não é suficiente. Overall Delay is calculated from the current Ping Time and the delay introduced by the current buffer settings. A latência geral é calculada a partir da latência da conexão atual e do atraso introduzido pelas configurações de buffer. Controls the relative levels of the left and right local audio channels. For a mono signal it acts as a pan between the two channels. For example, if a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows %1, where %2 is the current attenuation indicator. Controla os níveis relativos dos canais locais esquerdo e direito. Para um sinal mono, atua como uma panorâmica entre os dois canais. Por exemplo, se um microfone estiver ligado no canal de entrada direito e um instrumento estiver ligado no canal de entrada esquerdo, mais alto que o microfone, mova o fader de áudio numa direção em que o marcador acima do fader mostre %1, onde %2 é o indicador de atenuação. Audio Device Dispositivo de Áudio Under the Windows operating system the ASIO driver (sound card) can be selected using %1. If the selected ASIO driver is not valid an error message is shown and the previous valid driver is selected. Under macOS the input and output hardware can be selected. No sistema operacional Windows o driver ASIO (placa de som) pode ser selecionado usando %1. Se o driver ASIO selecionado não for válido, uma mensagem de erro será exibida e o driver válido anterior será selecionado. No macOS o hardware de entrada e saída pode ser selecionado. Three buffer sizes can be selected Três tamanhos de buffer podem ser selecionados 64 samples: Provides the lowest latency but does not work with all sound cards. 64 amostras: Fornece menor latência, mas não funciona com todas as placas de som. 256 samples: Should only be used when 64 or 128 samples is causing issues. 256 amostras: Deve apenas ser usado quando 64 ou 128 amostras estiver causando problemas. Some sound card drivers do not allow the buffer delay to be changed from within %1. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. Use the appropriate tool for the interface in use to adjust this buffer size. For example, if using ASIO, use the "ASIO Device Settings" button to open the driver settings panel or if using JACK, use a tool such as QjackCtl to adjust the buffer size. Other interfaces, such as Pipewire, would require their appropriate tool being used. Please refer to the interface manual. Alguns drivers de placa de som não permitem que o atraso do buffer seja alterado de dentro do %1. Nesse caso, a configuração de atraso do buffer está desabilitada e deve ser alterada usando o driver da placa de som. Use a ferramenta apropriada para a interface em uso para ajustar o tamanho do buffer. Por exemplo, se estiver usando ASIO, use o botão "Definições de Dispositivo ASIO" para abrir o painel de configurações do driver ou se estiver usando JACK, use uma ferramenta como QjackCtl para ajustar o tamanho do buffer. Outras interfaces, como o Pipewire, exigem o uso de sua ferramenta apropriada. Consulte o manual da interface. If no buffer size is selected and all settings are disabled, this means a buffer size in use by the driver which does not match the values. %1 will still work with this setting but may have restricted performance. Se nenhum tamanho de buffer estiver selecionado e todas as configurações estiverem desativadas, significa que um tamanho de buffer em uso pelo driver não combina os valores. %1 ainda funcionará com essa configuração, mas com desempenho limitado. The actual buffer delay has influence on the connection, the current upload rate and the overall delay. The lower the buffer size, the higher the probability of a red light in the status indicator (drop outs) and the higher the upload rate and the lower the overall delay. O atraso do buffer influencia a conexão, a taxa de upload e a latência geral. Quanto menor o tamanho do buffer, maior a probabilidade de a luz vermelha no indicador de estado (interrupções), maior a taxa de upload e menor a latência geral. Meter Style Estilo do Medidor Select the meter style to be used for the level meters. The Narrow Bar and Small LEDs options only apply to the mixerboard. When Narrow Bar is selected, the input meters are set to Bar. When Small LEDs is selected, the input meters are set to Round LEDs. The remaining options apply to the mixerboard and input meters. Selecione o estilo a ser usado para os medidores de nível. As opções Barra Estreita e LEDs Pequenos aplicam-se apenas à mesa do mixer. Quando a Barra Estreita é selecionada, os medidores de entrada são definidos como Barra. Quando LEDs Pequenos é selecionado, os medidores de entrada são definidos como LEDs redondos. As opções restantes aplicam-se à mesa do mixere aos medidores de entrada. Meter Style combo box Seletor do Estilo do Medidor Custom Directories Diretórios Personalizados If you need to add additional directories to the Connect dialog Directory drop down, you can enter the addresses here.<br>To remove a value, select it, delete the text in the input box, then move focus out of the control. Se você precisa acrescentar diretórios adicionais no menu suspenso Diretório da caixa de diálogo Conectar, insira os endereços aqui.<br>Para remover um valor, selecione-o, exclua o texto na caixa de entrada e mova o foco para fora do controle. Custom Directories combo box Seletor de Diretório Personalizado Number of Mixer Panel Rows Número de Linhas do Painel do Mixer Adjust the number of rows used to arrange the mixer panel. Ajusta o número de linhas usadas para organizar o painel do mixer. Number of Mixer Panel Rows spin box Spinner Número de Linhas do Painel do Mixer Feedback Protection Microfonia ou realimentação? TBD Proteção de Microfonia Enable feedback protection to detect acoustic feedback between microphone and speakers. Permite a proteção de microfonia detectar realimentação acústica entre microfone e falantes. Feedback Protection check box Caixa de seleção Proteção de Microfonia Audio Alerts Alertas de Áudio Enable audio alert when receiving a chat message and when a new client joins the session. A second sound device may be required to hear the alerts. Ative o alerta de áudio ao receber uma mensagem de bate-papo e quando um novo cliente ingressar na sessão. Um segundo dispositivo de som pode ser necessário para ouvir os alertas. Audio Alerts check box Caixa de seleção de Alertas de Áudio ASIO Device Settings Definições de Dispositivo ASIO Low Baixa Normal Normal High Alta Fancy Sofisticada Compact Compacta Bar (narrow) Barra (estreita) Bar (wide) Barra (larga) LEDs (stripe) LEDs (faixa) LEDs (round, small) LEDs (redondo, pequeno) LEDs (round, big) LEDs (redondo, grande) Manual Manual Custom Personalizado All Genres Servidor Geral Any Genre 2 Gênero Variado 2 Any Genre 3 Gênero Variado 3 Genre Rock Gênero Rock Genre Jazz Gênero Jazz Genre Classical/Folk Gênero Clássico/Folk Genre Choral/Barbershop Gênero Coral/Barbershop Any Genre 1 Gênero Variado 1 Genre Rock/Jazz Servidor Rock/Jazz Genre Classical/Folk/Choral Serv. Clássica/Folclore/Coro Default Servidor Padrão Default (North America) Servidor Padrão (America do Norte) preferred preferido Musician Profile Perfil do músico Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country you are located in. Your city and skill level playing your instrument may also be added. Escreva o seu nome ou um apelido aqui para que os outros músicos com quem quer tocar saibam quem você é. Além disso, pode também definir uma imagem do instrumento que toca e uma bandeira do país onde vive. A cidade onde vive e o nível de habilidade com o seu instrumento também podem ser adicionados. What you set here will appear at your fader on the mixer board when you are connected to a Jamulus server. This tag will also be shown at each client which is connected to the same server as you. O que definir aqui aparecerá abaixo do seu fader no mixer quando estiver conectado a um servidor Jamulus. Esta etiqueta também será exibida em cada cliente que estiver conectado ao mesmo servidor. Alias or name edit box Caixa de edição do nome ou apelido Instrument picture button Botão da imagem do instrumento Country flag button Botão da bandeira do país City edit box Caixa de edição da cidade Skill level combo box Seletor do nível de habilidade Beginner Principiante Intermediate Intermediário Expert Avançado Size: Tamanho: Buffer Delay Atraso do buffer Buffer Delay: Atraso do buffer: The selected audio device could not be used because of the following error: O dispositivo de áudio selecionado não pôde ser usado devido ao seguinte erro: The previous driver will be selected. O driver anterior será selecionado. Ok Ok Drum Set Bateria Djembe Djembê Electric Guitar Guitarra Elétrica Acoustic Guitar Violão Bass Guitar Baixo Keyboard Teclado Synthesizer Sintetizador Grand Piano Piano de Cauda Accordion Acordeão Vocal Voz Microphone Microfone Harmonica Gaita Trumpet Trompete Trombone Trombone French Horn Trompa Francesa Tuba Tuba Saxophone Saxofone Clarinet Clarinete Flute Flauta Violin Violino Cello Violoncelo Double Bass Contrabaixo Recorder Gravador Streamer Streamer Listener Ouvinte Guitar+Vocal Guitarra+Voz Keyboard+Vocal Teclado+Voz Bodhran Bodhrán Bassoon Fagote Oboe Oboé Harp Harpa Viola Viola de Arco Congas Congas Bongo Bongo Vocal Bass Voz Baixo Vocal Tenor Voz Tenor Vocal Alto Voz Alto Vocal Soprano Voz Soprano Banjo Banjo Mandolin Bandolim Ukulele Ukulele Bass Ukulele Ukulele Baixo Vocal Baritone Voz Barítono Vocal Lead Voz Principal Mountain Dulcimer Saltério dos Apalaches Scratching Scratching Rapping Rap Vibraphone Vibrafone Conductor Maestro CClientSettingsDlgBase Settings Definições Soundcard Placa de Som Device Dispositivo Input Channel Mapping Mapeamento do Canal de Entrada L L R R Output Channel Mapping Mapeamento do Canal de Saída Enable Small Network Buffers Habilitar Buffers de Rede Pequenos Buffer Delay Atraso do buffer Country/Region País/Região (preferred) (preferido) (default) (padrão) (safe) (seguro) Driver Setup Configuração do Driver My Profile Meu Perfil Musician's Profile Perfil do Músico Alias/Name Apelido/Nome Instrument Instrumento Country País City Cidade Skill Habilidade User Interface Interface do Usuário Meter Style Estilo do Medidor Mixer Rows Linhas do Mixer Audio Alerts Alertas de Áudio Audio/Network Setup Configuração de Áudio/Rede Audio Device Dispositivo de Áudio Jitter Buffer Jitter Buffer Auto Auto Local Local Server Servidor Size Tamanho kbps kbps Custom Directories: Diretórios Personalizados: Input Boost Reforço de Entrada Feedback Protection Proteção de Microfonia Enable Ativar Input Balance Equilíbrio de Entrada Pan Bal Center Centro Misc Outras Config Audio Channels Canais de Áudio Audio Quality Qualidade de Áudio Measurements Medições Advanced Setup Configuração Avançada Custom Central Server Address: Endereço do Servidor de Diretório Personalizado: New Client Level Nível de Novo Cliente Skin Aparência Language Idioma % % Local Jitter Buffer Jitter buffer local Fancy Skin Skin Sofisticada Display Channel Levels Mostrar Níveis de Canais Custom Directory Server Address: Endereço do Servidor de Diretório Personalizado: Directory Server Address: Endereço do Servidor Central: Audio Stream Rate Taxa de Transmissão de Áudio val val Ping Time Latência da Ligação Overall Delay Latência Geral CConnectDlg Server List Lista de servidores The server list shows a list of available servers which are registered at the directory server. Select a server from the list and press the connect button to connect to this server. Alternatively, double click a server from the list to connect to it. If a server is occupied, a list of the connected musicians is available by expanding the list item. Permanent servers are shown in bold font. A lista de servidores mostra a os servidores disponíveis registados no servidor central. Selecione um servidor da lista e pressione o botão Ligar para se ligar a este servidor. Como alternativa, clique duas vezes num servidor da lista para se ligar ao mesmo. Se um servidor estiver ocupado, uma lista dos músicos ligados estará disponível expandindo o item da lista. Os servidores permanentes são mostrados em negrito. Note that it may take some time to retrieve the server list from the directory server. If no valid directory server address is specified in the settings, no server list will be available. Observe que pode demorar algum tempo para obter a lista de servidores do servidor central. Se nenhum endereço de servidor central válido for especificado nas definições, nenhuma lista de servidores estará disponível. Directory Diretório Shows the servers listed by the selected directory. You can add custom directories in Advanced Settings. Exibe os servidores listados por diretório selecionado. Você pode adicionar diretórios personalizados em Configurações Avançadas. Directory combo box Seletor de Diretório Filters the server list by the given text. Note that the filter is case insensitive. A single # character will filter for those servers with at least one person connected. Filtra a lista de servidores pelo texto fornecido. Observe que o filtro não diferencia maiúsculas de minúsculas. Um único caractere # filtrará os servidores com pelo menos uma pessoa conectada. Uncheck to collapse the server list to show just the server details. Check to show everyone on the servers. Desmarque para recolher a lista de servidores e mostrar apenas os detalhes. The Connection Setup window lists the available servers registered with the selected directory. Use the Directory dropdown to change the directory, find the server you want to join in the server list, click on it, and then click the Connect button to connect. Alternatively, double click on the server name to connect. A janela de Configuração de Conexão lista os servidores disponíveis registrados no diretório selecionado. Use o menu suspenso Diretório para alterar o diretório, localize o servidor que deseja ingressar na lista de servidores, clique nele e, em seguida clique no botão Conectar para conectar-se. Como alternativa, clique duas vezes no nome do servidor para conectar-se. Permanent servers (those that have been listed for longer than 48 hours) are shown in bold. Servidores permanentes (aqueles que estão listados por mais de 48 horas) são mostrados em negrito. You can add custom directories in Advanced Settings. Você pode adicionar diretórios personalizados em Configurações Avançadas. Server list view Vista da lista de servidores Server Address Endereço do servidor If you know the server address, you can connect to it using the Server name/Address field. An optional port number can be added after the server address using a colon as a separator, e.g. %1. The field will also show a list of the most recently used server addresses. Se você souber o endereço do servidor, poderá conectar-se a ele usando o campo Nome/Endereço do servidor. Um número de porta opcional pode ser adicionado após o endereço do servidor usando dois pontos como separador, por exemplo %1. O campo também mostrará uma lista dos endereços de servidor usados mais recentemente. Holds the current server address. It also stores old addresses in the combo box list. Contém o endereço do servidor atual. Também armazena endereços antigos na lista do seletor. The IP address or URL of the server running the O endereço IP ou URL do servidor executando o servidor server software must be set here. An optional port number can be added after the IP address or URL using a colon as a separator, e.g. example.org: deve ser definido aqui. Um número de porta opcional pode ser adicionado após o endereço IP ou URL usando o caractere dois pontos como separador, por exemplo, example.org: . A list of the most recent used server IP addresses or URLs is available for selection. . Uma lista dos endereços IP ou URLs dos servidores usados recentemente está disponível para seleção. The Connection Setup window shows a list of available servers. Server operators can optionally list their servers by music genre. Use the List dropdown to select a genre, click on the server you want to join and press the Connect button to connect to it. Alternatively, double click on on the server name. Permanent servers (those that have been listed for longer than 48 hours) are shown in bold. A janela Configuração da conexão mostra uma lista de servidores disponíveis. Os operadores dos servidores podem registrar os seus servidores por gênero musical. Utilize o menu Lista para selecionar um gênero, clique no servidor ao qual se deseja ingressar e pressione o botão Conectar. Como alternativa, clique duas vezes no nome do servidor. Servidores permanentes (aqueles que estão registrados há mais de 48 horas) são mostrados em negrito. If you know the IP address or URL of a server, you can connect to it using the Server name/Address field. An optional port number can be added after the IP address or URL using a colon as a separator, e.g. example.org: Se souber o endereço IP ou URL de um servidor, pode conectar-se a este utilizando o campo Nome/Endereço do Servidor. Um número de porta opcional pode ser adicionado após o endereço IP ou URL usando o caractere dois pontos como separador, por exemplo, example.org: . The field will also show a list of the most recently used server addresses. . Este campo também irá mostrar uma lista dos endereços IP ou URLs dos servidores usados recentemente. Server address edit box Caixa de edição do endereço do servidor Holds the current server IP address or URL. It also stores old URLs in the combo box list. Contém o endereço IP ou URL do servidor atual. Também armazena URLs antigos na lista do seletor. Server List Selection Seleção da Lista de Servidores Selects the server list to be shown. Seleciona a lista de servidores a ser apresentada. Server list selection combo box Caixa de seleção de lista de servidores Filter Filtro The server list is filtered by the given text. Note that the filter is case insensitive. A lista de servidores é filtrada pelo texto fornecido. Note que o filtro não diferencia maiúsculas de minúsculas. Filter edit box Caixa de edição do filtro Show All Musicians Mostrar Todos os Músicos If you check this check box, the musicians of all servers are shown. If you uncheck the check box, all list view items are collapsed. Se marcar esta caixa de seleção, os músicos de todos os servidores serão mostrados. Se desmarcar a caixa de seleção, todos os itens em exibição na lista serão recolhidos. Show all musicians check box Caixa de seleção para mostrar músicos If you know the IP address or URL of a server, you can connect to it using the Server name/Address field. An optional port number can be added after the IP address or URL using a colon as a separator, e.g. %1. The field will also show a list of the most recently used server addresses. Se você souber o endereço IP ou URL de um servidor, poderá conectar-se a ele usando o campo Nome/Endereço de Servidor. Um número de porta opcional pode ser adicionado após o endereço IP ou URL usando dois pontos como separador, por exemplo, %1. O campo também mostrará uma lista de servidores usados mais recentemente. Filter text, or # for occupied servers Texto ou # para servidores ocupados Type # for occupied servers Digite # para servidores ocupados CConnectDlgBase Connection Setup Configuração de Conexão List Lista Directory Diretório Filter Filtro Show All Musicians Mostrar Todos os Músicos Server Name Nome do Servidor Ping Time Latência Musicians Músicos Location Localização Server Address Endereço do Servidor C&ancel C&ancelar &Connect &Conectar CHelpMenu &Help A&juda Getting &Started... Como Começa&r... Software &Manual... &Manual do Programa... What's &This O que é &isto &About Jamulus... &Sobre o Jamulus... About &Qt... Sobre o &Qt... &About... &Sobre... About Qt Sobre o Qt CLanguageComboBox Restart Required É necessário reiniciar Please restart the application for the language change to take effect. Reinicie a aplicação para que a alteração de idioma entre em vigor. CLicenceDlg I &agree to the above licence terms Eu &aceito os termos da licença acima This server requires you accept conditions before you can join. Please read these in the chat window. Este servidor requer que você aceite as condições antes de entrar. Por favor leia-as na janela de chat. I have read the conditions and &agree. Li as condições e &concordo. Accept Aceitar Decline Rejeitar By connecting to this server and agreeing to this notice, you agree to the following: Ao conectar-se a este servidor e concordar com este aviso, você concorda com o seguinte: You agree that all data, sounds, or other works transmitted to this server are owned and created by you or your licensors, and that you are making these data, sounds or other works available via the following Creative Commons License (for more information on this license, see Você concorda que todos os dados, sons ou outros trabalhos transmitidos para este servidor pertencem e são criados por você ou por seus licenciadores, e que você está disponibilizando esses dados, sons ou outros trabalhos através da seguinte licença Creative Commons (para obter mais informações sobre esta licença, consulte You are free to: Você tem o direito de: Share Compartilhar copy and redistribute the material in any medium or format copiar e redistribuir o material em qualquer suporte ou formato Adapt Adaptar remix, transform, and build upon the material remixar, transformar, e criar a partir do material The licensor cannot revoke these freedoms as long as you follow the license terms. O licenciante não pode revogar estes direitos desde que você respeite os termos da licença. Under the following terms: De acordo com os termos seguintes: Attribution Atribuição You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. Você deve atribuir o devido crédito, fornecer um link para a licença, e indicar se foram feitas alterações. Você pode fazê-lo de qualquer forma razoável, mas não de uma forma que sugira que o licenciante o apoia ou aprova o seu uso. NonCommercial NãoComercial You may not use the material for commercial purposes. Você não pode usar o material para fins comerciais. ShareAlike CompartilhaIgual If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original. Se você remixar, transformar, ou criar a partir do material, deve distribuir as suas contribuições sob a mesma licença que do original. No additional restrictions Sem restrições adicionais You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. Você não pode aplicar termos jurídicos ou medidas de caráter tecnológico que restrinjam legalmente outros de fazerem algo que a licença permita. CMultiColorLED Red Vermelho Yellow Amarelo Green Verde CMusProfDlg server. This tag will also show up at each client which is connected to the same server as you. If the name is left empty, the IP address is shown instead. . Esta identificação também será exibida em cada cliente ligado ao mesmo servidor que você. Se o nome estiver vazio, o endereço IP será mostrado. Alias or name edit box Caixa de edição do nome ou apelido Instrument picture button Botão da imagem do instrumento Country flag button Botão da bandeira do país City edit box Caixa de edição da cidade Skill level combo box Seletor do nível de habilidade None Nenhum Musician Profile Perfil do músico Alias/Name Apelido/Nome Instrument Instrumento Country País City Cidade Skill Habilidade &Close &Fechar Beginner Principiante Intermediate Intermediário Expert Avançado Set your name or an alias here so that the other musicians you want to play with know who you are. Additionally you may set an instrument picture of the instrument you play and a flag of the country you are living in. The city you live in and the skill level playing your instrument may also be added. Defina o seu nome ou um pseudônimo aqui para que os outros músicos com quem quer tocar saibam quem você é. Além disso, pode definir uma imagem do instrumento que toca e uma bandeira do país em que vive. A cidade em que vive e o nível de habilidade com o seu instrumento também podem ser adicionados. What you set here will appear at your fader on the mixer board when you are connected to a O que definir aqui aparecerá por baixo do seu fader na secção de mistura quando estiver ligado a um servidor Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country you are located in. Your city and skill level playing your instrument may also be added. Escreva o seu nome ou um apelido aqui para que os outros músicos com quem quer tocar saibam quem você é. Além disso, pode também definir uma imagem do instrumento que toca e uma bandeira do país onde vive. A cidade onde vive e o nível de habilidade com o seu instrumento também podem ser adicionados. What you set here will appear at your fader on the mixer board when you are connected to a Jamulus server. This tag will also be shown at each client which is connected to the same server as you. O que definir aqui aparecerá abaixo do seu fader no mixer quando estiver conectado a um servidor Jamulus. Esta etiqueta também será exibida em cada cliente que estiver conectado ao mesmo servidor. Drum Set Bateria Djembe Djembe Electric Guitar Guitarra Elétrica Acoustic Guitar Guitarra Acústica Bass Guitar Baixo Keyboard Teclado Synthesizer Sintetizador Grand Piano Piano de Cauda Accordion Acordeão Vocal Voz Microphone Microfone Harmonica Harmónica Trumpet Trompete Trombone Trombone French Horn Trompa Francesa Tuba Tuba Saxophone Saxofone Clarinet Clarinete Flute Flauta Violin Violino Cello Violoncelo Double Bass Contrabaixo Recorder Gravador Streamer Streamer Listener Ouvinte Guitar+Vocal Guitarra+Voz Keyboard+Vocal Teclado+Voz Bodhran Bodhrán Bassoon Fagote Oboe Oboé Harp Harpa Viola Viola de Arco Congas Congas Bongo Bongo Vocal Bass Voz Baixo Vocal Tenor Voz Tenor Vocal Alto Voz Alto Vocal Soprano Voz Soprano Banjo Banjo Mandolin Bandolim Ukulele Ukulele Bass Ukulele Ukulele Baixo Vocal Baritone Voz Barítono Vocal Lead Voz Principal Mountain Dulcimer Saltério dos Apalaches Scratching Scratching Rapping Rap No Name Sem Nome CServerDlg Client List Lista de Clientes The client list shows all clients which are currently connected to this server. Some information about the clients like the IP address and name are given for each connected client. A lista de clientes mostra todos os clientes que estão atualmente conectados neste servidor. Algumas informações sobre os clientes, como o endereço IP e o nome, são fornecidas para cada cliente ligado. Connected clients list view Lista de clientes conectados Directory Type combo box Seletor de Tipo de Diretório Directory Diretório Select '%1' not to register your server with a directory. Selecione '%1' para não registrar seu servidor com um diretório. Select one of the genres to register with that directory. Selecione um dos gêneros para registrar-se nesse diretório. Or select '%1' and specify a Custom Directory address on the Options tab to register with a custom directory. Ou selecione '%1' e especifique um endereço de Diretório Personalizado na guia Opções para registrar-se com um diretório personalizado. For any value except '%1', this server registers with a directory so that a %2 user can select this server in the client connect dialog server list when they choose that directory. Para qualquer valor, exceto '%1',este servidor registra-se em um diretório para que um usuário %2 possa selecioná-lo na lista de servidores da caixa de diálogo de conexão do cliente ao escolher esse diretório. The registration of the server is renewed periodically to make sure that all servers in the connect dialog server list are actually available. O registro do servidor é renovado periodicamente para garantir que todos os servidores na lista do diálogo de conexão estejam realmente acessíveis. When a value other than "%1" is chosen for Directory, this will show whether registration is successful. If the registration failed, please choose a different directory. Quando um valordirefente de "%1" for escolhido para Diretório, isso mostrará se o registro foi bem sucedido. Se o registro falhou, escolha um diretório diferente. No recording directory has been set or the value is not useable. Check the value in the Options tab. Nenhum diretório de gravação foi definido ou o valor não pode ser usado. Verifique o valor na guia Opções. If the recording directory is not useable, the problem will be displayed in place of the session directory. Se o diretório de gravação não for utilizável, o problema será exibido no lugar do diretório de sessão. Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user %1 is running as). Clique no botão para abrir a caixa de diálogo que permite selecionar o diretório de gravação principal. O valor escolhido deve existir e ser gravável (permitir a criação de subdiretórios pelo usuário com o qual %1 está sendo executado). The current value of the main recording directory. The chosen value must exist and be writeable (allow creation of sub-directories by the user %1 is running as). Click the button to open the dialog that allows the main recording directory to be selected. Valor atual do diretório principal de gravação. O valor escolhido deve existir e ser gravável (permite criação de subdiretórios pelo usuário com o qual %1 está sendo executado.). Clique no botão para abrir a caixa de diálogo que permite selecionar o diretório principal de gravação. Custom Directory address End. de Diretório Personalizado The Custom Directory address is the address of the directory holding the server list to which this server should be added. O endereço do Diretório Personalizado é o endereço do diretório que contém a lista de servidores ao qual esse servidor deve ser adicionado. Server List Filename dialog push button Botão de diálogo do arquivo da Lista de Servidores Server List Filename Arquivo da Lista de Servidores Click the button to open the dialog that allows the server list persistence file name to be set. The user %1 is running as needs to be able to create the file name specified although it may already exist (it will get overwritten on save). Clique no botão para abrir a caixa de diálogo que permite definir o nome do arquivo de persistência da lista de servidores. O usuário com o qual %1 está sendo executado necessita ser capaz de criar o nome do arquivo especificado, embora ele já exista (será substituído ao salvar). Server List Filename text box (read-only) Caixa de texto com o arquivo da Lista de Servidores (apenas leitura) The current value of server list persistence file name. The user %1 is running as needs to be able to create the file name specified although it may already exist (it will get overwritten on save). Click the button to open the dialog that allows the server list persistence file name to be set. O valor atual do nome do arquivo de persistência da lista de servidores. O usuário com o qual %1 está sendo executado precisa ser capaz de criar o nome do arquivo especificado, embora ele já exista (será substituído ao salvar). Clique no botão para abrir a caixa de diálogo que permite definir o nome do arquivo de persistência da lista de servidores. Clear the server list file name button Botão limpar arquivo da lista de servidores Clear Server List Filename Limpar Arquivo da Lista de Servidores Click the button to clear the currently selected server list persistence file name. This will prevent persisting the server list until a new value is selected. Clique no botão para limpar o nome do arquivo de persistência da lista de servidores atualmente selecionado. Isso impedirá a persistência da lista de servidores até que um novo valor seja selecionado. Start Minimized on Operating System Start Iniciar Minimizado com o Sistema Operacional Now a directory Agora um diretório If the start minimized on operating system start check box is checked, the Se a caixa de seleção Iniciar Minimizado com o Sistema Operativo estiver marcada, o servidor server will be started when the operating system starts up and is automatically minimized to a system task bar icon. será iniciado quando o sistema operativo for iniciado, e minimizado automaticamente para um ícone da barra de tarefas do sistema. Show Creative Commons Licence Dialog Mostrar Diálogo da Licença Creative Commons If enabled, a Creative Commons BY-NC-SA 4.0 Licence dialog is shown each time a new user connects the server. Se habilitada, uma caixa de diálogo Creative Commons BY-NC-SA 4.0 será exibida sempre que um novo utilizador se ligar ao servidor. Make My Server Public Tornar Meu Servidor Público If the Make My Server Public check box is checked, this server registers itself at the directory server so that all Se a caixa de seleção Tornar Servidor Público estiver marcada, esse servidor irá registar-se no servidor central para que todos os utilizadores do users can see the server in the connect dialog server list and connect to it. The registration of the server is renewed periodically to make sure that all servers in the connect dialog server list are actually available. possam ver o servidor na lista do diálogo de ligação e ligar-se a ele. O registo do servidor é renovado periodicamente para garantir que todos os servidores na lista de diálogo de ligação estejam realmente disponíveis. Register Server Status Estado de Registro do Servidor If the Make My Server Public check box is checked, this will show whether registration with the directory server is successful. Se a caixa de seleção Tornar Servidor Público estiver marcada, isto mostrará o sucesso ou insucesso do registo no servidor central. Directory Server Address Endereço do servidor central The Directory server address is the IP address or URL of the directory server at which this server is registered. With the directory server address type either the local region can be selected of the default directory servers or a manual address can be specified. O endereço do servidor central é o endereço IP ou o URL do servidor central no qual esse servidor será registado. Com o menu dos servidores centrais, é possível selecionar um dos servidores centrais padrão ou especificar um endereço manual. If the Make My Server Public check box is checked, this will show whether registration with the directory server is successful. If the registration failed, please choose another server list. Se a caixa de seleção Tornar Meu Servidor Público for selecionada, isto exibirá se o registro no servidor de diretório foi bem-sucedido. Se o registro falhar, escolha outra lista de servidores. Default directory server type combo box Seletor do servidor central padrão If the start minimized on operating system start check box is checked, the server will be started when the operating system starts up and is automatically minimized to a system task bar icon. Se a caixa de seleção Iniciar Minimizado com o Sistema Operacional estiver marcada, o servidor será iniciado quando o sistema operacional for iniciado, e minimizado automaticamente para um ícone da barra de tarefas do sistema. If the Make My Server Public check box is checked, this server registers itself at the directory server so that all users of the application can see the server in the connect dialog server list and connect to it. The registration of the server is renewed periodically to make sure that all servers in the connect dialog server list are actually available. Se a caixa de seleção Tornar Meu Servidor Público estiver marcada, este servidor irá registrar-se no servidor de diretóriol para que todos os usuários da aplicação possam vê-lo na lista de servidores e conectar-se a ele. O registro dos servidores é renovado periodicamente para garantir que todos os servidores na lista estão realmente disponíveis. Custom Directory Server Address Endereço do Servidor de Diretório Personalizado The custom directory server address is the IP address or URL of the directory server at which the server list of the connection dialog is managed. O endereço do servidor de diretório personalizado é o endereço IP ou URL do servidor de diretório no qual a lista de servidores da Configuração da Conexão é gerida. Directory server address line edit Caixa de edição do endereço do servidor de diretório Server List Selection Seleção da Lista de Servidores Selects the server list (i.e. directory server address) in which your server will be added. Seleciona a lista de servidores (ou seja, endereço do servidor de diretório) à qual seu servidor será adicionado. Server list selection combo box Seletor de lista de servidores Server Name Nome do Servidor The server name identifies your server in the connect dialog server list at the clients. If no name is given, the IP address is shown instead. O nome do servidor identifica o servidor na lista do diálogo de ligação exibido nos clientes. Se nenhum nome for fornecido, o endereço IP será mostrado. The server name identifies your server in the connect dialog server list at the clients. O nome do servidor identifica seu servidor na lista do diálogo de conexão exibido nos clientes. Server name line edit Caixa de edição do nome do servidor Location City Localização: Cidade The city in which this server is located can be set here. If a city name is entered, it will be shown in the connect dialog server list at the clients. A cidade onde este servidor está localizado pode ser definida aqui. Se um nome de cidade for inserido, este será mostrado na lista do diálogo de conexão dos clientes. City where the server is located line edit Caixa de edição da cidade onde o servidor se encontra Location country Localização: País The country in which this server is located can be set here. If a country is entered, it will be shown in the connect dialog server list at the clients. O país em que este servidor está localizado pode ser definido aqui. Se um país for inserido, ele será mostrado na lista do diálogo de conexão dos clientes. Country where the server is located combo box Seletor do país onde o servidor se encontra Country/Region País/Região Set the country or region where the server is running. Clients will show this location in their connect dialog's server list. Define o país ou região onde o servidor está sendo executado. Os clientes irão exibir essa localização na caixa de diálogo de conexão da lista de servidores. Combo box for location of this server Seletor para localização deste servidor Recording has been switched off by the UI checkbox. Gravação foi desligada pela caixa de seleção da IU. Recording has been switched off, either by the UI checkbox or SIGUSR2 being received. Gravação foi desligada pela caixa de seleção da IU ou SIGUSR2 recebido. Display dialog to select recording directory button Botão que mostra diálogo para selecionar diretório de gravação Main Recording Directory Diretório Principal de Gravação Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user Jamulus is running as). Clique no botão para abrir a caixa de diálogo que permite selecionar o diretório principal de gravação. O valor escolhido deve existir e ser gravável(permite a criação de subdiretórios pelo usuário que está executando Jamulus). Main recording directory text box (read-only) Caixa de texto com o diretório principal de gravação (apenas leitura) The current value of the main recording directory. The chosen value must exist and be writeable (allow creation of sub-directories by the user Jamulus is running as). Click the button to open the dialog that allows the main recording directory to be selected. Valor atual do diretório principal de gravação. O valor escolhido deve existir e ser gravável (permite criação de subdiretórios pelo usuário que está executando Jamulus). Clique no botão para abrir a caixa de diálogo que permite selecionar o diretório principal de gravação. Clear the recording directory button Botão para limpar o diretório de gravação Clear Recording Directory Limpar Diretório de Gravação Click the button to clear the currently selected recording directory. This will prevent recording until a new value is selected. Clique no botão para limpar o diretório de gravação atualmente selecionado. Isso impedirá a gravação até que um novo valor seja selecionado. Checkbox to turn on or off server recording Caixa de seleção para ligar ou desligar a gravação no servidor If the Register Server check box is checked, this will show whether registration with the directory server is successful. If the registration failed, please choose another server list. Se a caixa de seleção Registrar Servidor estiver marcada, isto exibirá se o registro no servidor de diretório foi bem-sucedido. Se o registro falhar, escolha outra lista de servidores. Enable Recorder Habilitar Gravador Checked when the recorder is enabled, otherwise unchecked. The recorder will run when a session is in progress, if (set up correctly and) enabled. Ativo quando o gravador estiver ligado, caso contrário inativo. O gravador irá rodar quando uma sessão estiver a decorrer, se (corretamente configurado e ) ativo. Current session directory text box (read-only) Caixa de texto com a pasta da gravação (apenas leitura) Current Session Directory Pasta da Sessão Atual Enabled during recording and holds the current recording session directory. Disabled after recording or when the recorder is not enabled. Ativo durante a gravação e exibe a pasta da gravação atual. Inativo depois de gravação ou quando o gravador não estiver habilitado. Recorder status label Etiqueta do estado do Gravador Recorder Status Estado do Gravador Displays the current status of the recorder. The following values are possible: Exibe o estado atual do gravador. Os seguintes valores são possíveis: No recording directory has been set or the value is not useable. Nenhum diretório de gravação definido ou o valor não é utilizável. Recording has been switched off Gravação foi desligada by the UI checkbox pela caixa de ativação da IU , either by the UI checkbox or SIGUSR2 being received , pela caixa de ativação da IU ou SIGUSR2 foi recebido There is no one connected to the server to record. Não há ninguém conectado ao servidor para gravar. The performers are being recorded to the specified session directory. Os artistas estão sendo gravados no diretório de sessão especificado. NOTE NOTA If the recording directory is not useable, the problem will be displayed in place of the directory. Se o diretório de gravação não é utilizável, o problema será exibido no lugar do diretório. Server welcome message edit box Caixa de edição da mensagem de boas-vindas do servidor Server Welcome Message Mensagem de Boas-vindas do Servidor A server welcome message text is displayed in the chat window if a musician enters the server. If no message is set, the server welcome is disabled. Uma mensagem de boas-vindas é exibida na janela de chat se um músico entra no servidor. Se nenhuma mensagem for definida, a mensagem de boas-vindas do servidor é desativada. Language Idioma Select the language to be used for the user interface. Selecione o idioma para ser utilizado na interface do usuário. Language combo box Seletor de idioma Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user Jamulus is running as). Clique no botão para abrir a caixa de diálogo que permite selecionar o diretório principal de gravação. O valor escolhido deve existir e ser gravável (permite a criação de subdiretórios pelo usuário que está executando Jamulus). Custom Directory Diretório Personalizado The custom directory is the IP address or URL of the directory server at which the server list of the connection dialog is managed. O diretório personalizado é o endereço IP ou URL do servidor de diretório na qual a lista de servidores do diálogo de conexão é gerida. Custom Directory line edit Edição de linha do Diretório Personalizado &Hide %1 server &Ocultar servidor %1 &Show %1 server Mostrar &servidor %1 %1 server %1 is the name of the main application Servidor %1 Type a message here. If no message is set, the server welcome is disabled. Digite uma mensagem de boas-vindas aqui. Se nenhuma mensagem for definida, a mensagem de boas-vindas do servidor será desativada. %1 Server %1 is the name of the main application Servidor %1 software upgrade available atualização de software disponível Recorder failed to start. Please check available disk space and permissions and try again. Error: O gravador falhou ao iniciar. Verifique o espaço em disco disponível e as permissões e tente novamente. Erro: ERROR ERRO Displays the current status of the recorder. Mostra o estado atual do gravador. Request new recording button Botão para começar nova gravação New Recording Nova Gravação During a recording session, the button can be used to start a new recording. Durante uma sessão de gravação, este botão pode ser usado para começar uma nova gravação. E&xit &Sair &Hide &Esconder servidor server &Open &Abrir servidor server Select Main Recording Directory Selecione Diretório Principal de Gravação Predefined Address Endereço Predefinido Recording Gravando Not recording Não gravando Not initialised Não inicializado Not enabled Desativado Manual Manual Default Servidor Padrão Default (North America) Servidor Padrão (America do Norte) Server - Servidor &Window &Janela Unregistered Não Registrado None Nenhum Not registered Não registrado Bad address Endereço incorreto Registration requested Registro solicitado Registration failed Falha no registro Check server version Verifique versão do servidor Registered Registrado Directory server list full where the "server list" is what holds registering servers and the Directory can take no more entries. Lista de servidores no diretório cheia Your server version is too old A versão do seu servidor está muito desatualizada Requirements not fulfilled Requisitos não atendidos Unknown value %1 Valor desconhecido %1 Unknown value Valor desconhecido CServerDlgBase Client IP:Port IP do Cliente:Porta Name Nome do Servidor Jitter Buffer Size Tamanho do Jitter Buffer Channels Canais Server Setup Configuração do Servidor List Lista Location: Region Localização: Região Session Sessão Chat Window Welcome (HTML/CSS Supported) Mensagem de Boas-vindas do Chat (Suporta HTML/CSS) Options Opções Custom Directory address End. de Diretório Personalizado Server List Filename Arquivo da Lista de Servidores Start Minimized on Windows Start Iniciar Minimizado com o Sistema Operacional Enable delay panning Ativar atraso panorâmico Show Creative Commons BY-NC-SA 4.0 Licence Dialog Mostrar Diálogo da Licença Creative Commons BY-NC-SA 4.0 Update check Verificação de atualização Make My Server Public (Register My Server in the Server List) Tornar Meu Servidor Público (Registrar na Lista de Servidores) Genre Gênero STATUS ESTADO Custom Directory Server Address: Endereço do Servidor de Diretório Personalizado: Recording Directory Diretório de Gravação Enable Jam Recorder Ativar Gravação da Jam Directory Diretório New Recording Nova Gravação Language Consider add "(Lang)" as a suffix to ensure that users who selected the wrong language find the correct button Idioma Directory Server Address: Endereço do Servidor Central: My Server Info Informação do Meu Servidor Location: City Localização: Cidade Location: Country Localização: País Enable jam recorder Habilitar gravação New recording Nova gravação Recordings folder Pasta de gravações TextLabelNameVersion TextLabelNameVersion CServerListManager Could not write to '%1' Não foi possível gravar em '%1' CSound The Jack server is not running. This software requires a Jack server to run. Normally if the Jack server is not running this software will automatically start the Jack server. It seems that this auto start has not worked. Try to start the Jack server manually. O servidor Jack não está em execução. Este programa requer um servidor Jack para ser executado. Normalmente, se o servidor Jack não estiver em execução, este programa iniciará automaticamente o servidor Jack. Parece que esse início automático não funcionou. Tente iniciar o servidor Jack manualmente. The Jack server sample rate is different from the required one. The required sample rate is: A taxa de amostragem (sample rate) do servidor Jack é diferente da necessária. A taxa de amostragem necessária é: You can use a tool like <i><a href="https://qjackctl.sourceforge.io">QJackCtl</a></i> to adjust the Jack server sample rate. Pode usar uma ferramenta como <i><a href="https://qjackctl.sourceforge.io">QJackCtl</a></i> para ajustar a taxa de amostragem do servidor Jack. Make sure to set the Frames/Period to a low value like Certifique-se de definir Quadros/Período para um valor baixo como to achieve a low delay. para obter uma latência baixa. The Jack port registering failed. O registro da porta Jack falhou. Cannot activate the Jack client. Não é possível ativar o cliente Jack. The Jack server was shut down. This software requires a Jack server to run. Try to restart the software to solve the issue. O servidor Jack foi desligado. Este programa requer um servidor Jack para ser executado. Tente reiniciar o programa para resolver o problema. CoreAudio input AudioHardwareGetProperty call failed. It seems that no sound card is available in the system. A entrada do CoreAudio falhou na chamada AudioHardwareGetProperty. Parece que nenhuma placa de som está disponível no sistema. CoreAudio output AudioHardwareGetProperty call failed. It seems that no sound card is available in the system. A saída do CoreAudio falhou na chamada AudioHardwareGetProperty. Parece que nenhuma placa de som está disponível no sistema. Current system audio input device sample rate of %1 Hz is not supported. Please open the Audio-MIDI-Setup in Applications->Utilities and try to set a sample rate of %2 Hz. A taxa de amostragem (sample rate) de %1 Hz do dispositivo de entrada de áudio atual não é suportada. Por favor, abra o Audio-MIDI-Setup em Aplicativos-> Utilitários e tente definir uma taxa de amostragem de %2 Hz. The current selected audio device is no longer present in the system. O dispositivo de áudio selecionado não está mais presente no sistema. The audio input device is no longer available. O dispositivo de entrada de áudio não está mais disponível. The audio output device is no longer available. O dispositivo de saída de áudio não está mais disponível. Current system audio output device sample rate of %1 Hz is not supported. Please open the Audio-MIDI-Setup in Applications->Utilities and try to set a sample rate of %2 Hz. A taxa de amostragem (sample rate) de %1 Hz do dispositivo de saída de áudio atual não é suportada. Por favor, abra o Audio-MIDI-Setup em Aplicativos-> Utilitários e tente definir uma taxa de amostragem de %2 Hz. The audio input stream format for this audio device is not compatible with this software. O formato do fluxo de entrada de áudio para este dispositivo de áudio não é compatível com este programa. The audio output stream format for this audio device is not compatible with this software. O formato do fluxo de saída de áudio para este dispositivo de áudio não é compatível com este programa. The buffer sizes of the current input and output audio device cannot be set to a common value. Please choose other input/output audio devices in your system settings. Os tamanhos de buffer do dispositivo de áudio de entrada e saída atual não podem ser definidos para um valor comum. Por favor, escolha outros dispositivos de áudio de entrada/saída nas configurações do seu sistema. The audio driver could not be initialized. O driver de áudio não pôde ser inicializado. The audio device does not support the required sample rate. The required sample rate is: O dispositivo de áudio não suporta a taxa de amostragem (sample rate) necessária. A taxa de amostragem necessária é: The audio device does not support setting the required sampling rate. This error can happen if you have an audio interface like the Roland UA-25EX where you set the sample rate with a hardware switch on the audio device. If this is the case, please change the sample rate to O dispositivo de áudio não suporta definir a taxa de amostragem (sample rate) necessária. Este erro pode ocorrer se você tiver uma interface de áudio como o Roland UA-25EX, onde se define a taxa de amostragem através de um interruptor de hardware no dispositivo de áudio. Se for esse o caso, altere a taxa de amostragem para Hz on the device and restart the Hz no dispositivo e reinicie o cliente software. . The audio device does not support the required number of channels. The required number of channels for input and output is: O dispositivo de áudio não suporta o número necessário de canais. O número necessário de canais para entrada e saída é: Required audio sample format not available. Formato de amostra de áudio necessário não disponível. The selected audio device is no longer present in the system. Please check your audio device. O dispositivo de áudio selecionado não está mais presente no sistema. Verifique seu dispositivo de áudio. Couldn't initialise the audio driver. Check if your audio hardware is plugged in and verify your driver settings. Não foi possível inicializar o driver de áudio. Confirme se seu equipamento de áudio está conectado e verifique suas configurações do driver. The selected audio device is incompatible since it doesn't support a sample rate of %1 Hz. Please select another device. O dispositivo de áudio selecionado é incompatível uma vez que não suporta uma taxa de amostras de %1 Hz. Por favor, selecione outro dispositivo. The current audio device configuration is incompatible because the sample rate couldn't be set to %2 Hz. Please check for a hardware switch or driver setting to set the sample rate manually and restart %1. A configuração do dispositivo de áudio atual é incompatível pois não foi possível definir a taxa de amostras em %2 Hz. Verifique se o equipamento possui alguma chave ou configuração de driver para definir manualmente a taxa de amostras e reiniciar o %1. The selected audio device is incompatible since it doesn't support %1 in/out channels. Please select another device or configuration. O dispositivo de áudio selecionado é incompatível uma vez que não suporta %1 canais de entrada/saída. Por favor, selecione outro dispositivo ou configuração. The selected audio device is incompatible since the required audio sample format isn't available. Please use another device. O dispositivo de áudio selecionado é incompatível uma vez que o formato de áudio requerido não está disponível. Por favor, selecione outro dispositivo. No ASIO audio device driver found. Nenhum driver de dispositivo de áudio ASIO encontrado. Please install an ASIO driver before running %1. If you own a device with ASIO support, install its official ASIO driver. If not, you'll need to install a universal driver like ASIO4ALL. Instale um driver ASIO antes de executar %1. Se você possui um dispositivo com suporte ASIO, instale o driver oficial. Caso contrário, você precisará instalar um driver universal como o ASIO4ALL. Please install an ASIO driver before running %1. If you own a device with ASIO support, install its official ASIO driver. If not, you'll need to download and install a universal driver like ASIO4ALL. Instaleum driver ASIO antes de executar %1. Se você possui um dispositivo com suporte ASIO, instale o driver oficial. Caso contrário, você precisará baixar e instalar um driver universal como o ASIO4ALL. No ASIO audio device (driver) found. Nenhum dispositivo de áudio ASIO (driver) encontrado. The O programa software requires the low latency audio interface ASIO to work properly. This is not a standard Windows audio interface and therefore a special audio driver is required. Either your sound card has a native ASIO driver (which is recommended) or you might want to use alternative drivers like the ASIO4All driver. requer que a interface de áudio de baixa latência ASIO funcione corretamente. Esta não é uma interface de áudio padrão do Windows e, portanto, é necessário um driver de áudio especial. Ou a sua placa de som possui um driver ASIO nativo (recomendado), ou pode usar drivers alternativos, como o driver ASIO4All. Error requesting stream stop: $s Erro ao requisitar parada do stream: $s Error closing stream: $s Erro ao fechar o stream: $s JACK couldn't be started automatically. Please start JACK manually and check for error messages. Não foi possível iniciar o JACK automaticamente. Inicie o JACK manualmente e verifique se há mensagens de erro. JACK isn't running at a sample rate of <b>%1 Hz</b>. Please use a tool like <i><a href="https://qjackctl.sourceforge.io">QjackCtl</a></i> to set the the JACK sample rate to %1 Hz. O JACK não está sendo executado com uma taxa de amostras de <b>%1 Hz</b>. Utilize uma ferramenta como <i><a=href="https://qjackctl.sourceforge.io">QjackCtl</a></i> para definir a taxa de amostras do JACK em %1 Hz. The JACK port registration failed. This is probably an error with JACK. Please stop %1 and JACK. Afterwards check if another program at a sample rate of %2 Hz can connect to JACK. O registro da porta JACK falhou. Provavelmente isso é um erro com JACK. Pare %1 e JACK. Depois, verifique se outro programa com uma taxa de amostragem de %2 Hz pode conectar-se ao JACK. The JACK port registration failed. This is probably an error with JACK. Please stop %1 and JACK. Afterwards, check if another MIDI program can connect to JACK. O registro da porta JACK falhou. Provavelmente isso é um erro com JACK. Pare %1 e JACK. Depois, verifique se outro programa MIDI pode conectar-se ao JACK. Can't activate the JACK client. This is probably an error with JACK. Please check the JACK output. Não é possível ativar o cliente JACK. Provavelmente isso é um erro com JACK. Verifique a saída JACK. JACK was shut down. %1 requires JACK to run. Please restart %1 to start JACK again. JACK foi encerrado. %1 requer JACK para ser executado. Reinicie %1 para iniciar JACK novamente. No sound card is available in your system. CoreAudio input AudioHardwareGetProperty call failed. Nenhuma placa de som está disponível em seu sistema. A entrada do CoreAudio falhou na chamada AudioHardwareGetProperty. No sound card is available in the system. CoreAudio output AudioHardwareGetProperty call failed. Nenhuma placa de som está disponível em seu sistema. A saída do CoreAudio falhou na chamada AudioHardwareGetProperty. The currently selected audio device is no longer present. Please check your audio device. O dispositivo de áudio selecionado não está mais presente. Verifique seu dispositivo de áudio. The audio input device is no longer available. Please check if your input device is connected correctly. O dispositivo de entrada de áudio não está mais disponível. Verifique se seu dispositivo de entrada está corretamente conectado. The sample rate on the current input device isn't %1 Hz and is therefore incompatible. Please select another device or try setting the sample rate to %1 Hz manually via Audio-MIDI-Setup (in Applications->Utilities). A taxa de amostragem no dispositivo de entrada atual não é %1 Hz e, portanto, é incompatível. Selecione outro dispositivo ou tente definir manualmente a taxa de amostragem para %1 Hz via Configuração de Áudio e MIDI (em Aplicativos->Utilitários). The audio output device is no longer available. Please check if your output device is connected correctly. O dispositivo de saída de áudio não está mais disponível. Verifique se seu dispositivo de saída está corretamente conectado. The sample rate on the current output device isn't %1 Hz and is therefore incompatible. Please select another device or try setting the sample rate to %1 Hz manually via Audio-MIDI-Setup (in Applications->Utilities). A taxa de amostragem no dispositivo de saída atual não é %1 Hz e, portanto, é incompatível. Selecione outro dispositivo ou tente definir manualmente a taxa de amostragem para %1 Hz via Configuração de Áudio e MIDI (em Aplicativos->Utilitários). The stream format on the current input device isn't compatible with this software. Please select another device. O formato do fluxo no dispositivo de entrada atual não é compatível com este software. Selecione outro dispositivo. The stream format on the current output device isn't compatible with %1. Please select another device. O formato do fluxo no dispositivo de saída atual não é compatível com %1. Selecione outro dispositivo. The buffer sizes of the current input and output audio device can't be set to a common value. Please select different input/output devices in your system settings. Os tamanhos de buffer do dispositivo de áudio de entrada e saída atual não podem ser definidos para um valor comum. Selecione diferentes dispositivos de entrada/saída nas suas configurações. CSoundBase Invalid device selection. Seleção de dispositivo inválida. The audio driver properties have changed to a state which is incompatible with this software. The selected audio device could not be used because of the following error: As propriedades do driver de áudio foram alteradas para um estado incompatível com este programa. O dispositivo de áudio selecionado não pôde ser usado devido ao seguinte erro: Please restart the software. Por favor reinicie o programa. Close Fechar The selected audio device could not be used because of the following error: O dispositivo de áudio selecionado não pôde ser usado devido ao seguinte erro: The previous driver will be selected. O driver anterior será selecionado. The previously selected audio device is no longer available or the audio driver properties have changed to a state which is incompatible with this software. We now try to find a valid audio device. This new audio device might cause audio feedback. So, before connecting to a server, please check the audio device setting. O dispositivo de áudio selecionado anteriormente não está mais disponível ou as propriedades do driver de áudio foram alteradas para um estado o qual é incompatível com este software. Tentaremos encontrar um dispositivo de áudio válido. Este novo dispositivo poderá causar realimentação de áudio. Portanto, antes de conectar-se a um servidor, confira as configurações do dispositivo. No usable Nenhum dispositivo de áudio (driver) audio device (driver) found. utilizável encontrado. In the following there is a list of all available drivers with the associated error message: Abaixo uma lista de todos os drivers disponíveis com a mensagem de erro associada: Do you want to open the ASIO driver setups? Deseja abrir as configurações do driver ASIO? could not be started because of audio interface issues. não pôde ser iniciado devido a problemas na interface de áudio. Can't use the selected audio device because of the following error: %1 The previous driver will be selected. Não é possível usar o dispositivo de áudio selecionado devido ao seguinte erro: %1. O driver anterior será selecionado. The previously selected audio device is no longer available or the driver has changed to an incompatible state. We'll attempt to find a valid audio device, but this new audio device may cause feedback. Before connecting to a server, please check your audio device settings. O dispositivo de áudio selecionado anteriormente não está mais disponível ou o driver mudou para um estado incompatível. Tentaremos encontrar um dispositivo de áudio válido, mas esse novo dispositivo pode causar microfonia. Antes de conectar-se a um servidor, verifique suas definições de dispositivo de áudio. <b>%1 couldn't find a usable %2 audio device.</b><br><br> <b>%1 não encontrou um dispositivo de áudio %2 utilizável </b><br><br> You may be able to fix errors in the driver settings. Do you want to open these settings now? Você pode corrigir erros nas configurações do driver. Deseja abrir essas configurações agora? No usable %1 audio device found. Nenhum dispositivo de áudio %1 utilizável foi encontrado. These are all the available drivers with error messages: Estes são todos os drivers disponíveis com mensagens de erro: Do you want to open the ASIO driver setup to try changing your configuration to a working state? Deseja abrir a configuração do driver ASIO para tentar alterar sua configuração para um estado de funcionamento? Can't start %1. Please restart %1 and check/reconfigure your audio settings. Não é possível iniciar %1. Reinicie %1 e verifique/reconfigure suas definições de áudio. QCoreApplication %1, Version %2 %1, Versão %2 Internet Jam Session Software Programa de Jam Sessions pela Internet %1, Version %2 %1 is app name, %2 is version number %1, Versão %2 Released under the GNU General Public License version 2 or later (GPLv2) Lançado sob a Licença Pública Geral GNU versão 2 (GPLv2) This program is free software; you can redistribute it and/or modify it under Este programa é um software livre; você pode redistribuí-lo e/ou modificá-lo sob the terms of the GNU General Public License as published by the Free Software os termos da Licença Pública Geral GNU, conforme publicado pela Free Software Foundation; either version 2 of the License, or (at your option) any later version. Foundation, seja a versão 2 da Licença ou (a seu critério) qualquer versão posterior. There is NO WARRANTY, to the extent permitted by law. NÃO HÁ GARANTIA, até o limite permitido por lei. Using the following libraries, resources or code snippets: Utilizando as seguintes bibliotecas, recursos ou partes de código: Qt framework Framework Qt Opus Interactive Audio Codec No need to translate name. Opus Interactive Audio Codec Audio reverberation code by Perry R. Cook and Gary P. Scavone Código de reverberação de áudio por Perry R. Cook e Gary P. Scavone Some pixmaps are from the Open Clip Art Library (OCAL) Alguns pixmaps são da Open Clip Art Library (OCAL) Flag icons by Mark James Ícones de bandeiras por Mark James Copyright (C) 2005-2022 The Jamulus Development Team Copyright (C) 2005-2022 Equipe de Desenvolvimento Jamulus Released under the GNU General Public License (GPL) Lançado sob a Licença Pública Geral GNU (GPL) global A %1 upgrade is available: <a style='color:red;' href='https://jamulus.io/upgrade?progversion=%2'>go to details and downloads</a> Uma melhoria %1 está disponível: <a style='color:red' href=https://jamulus.io/upgrade?progversion=%2'>vá para detalhes e downloads</a> For more information use the "What's This" help (help menu, right mouse button or Shift+F1) Para mais informações, use "O que é isto" (menu Ajuda, botão direito do mouse ou Shift + F1) jamulus-3.9.1+dfsg/src/translation/translation_sv_SE.ts0000644000175000017500000070566114340334543022325 0ustar vimervimer CAboutDlg This app enables musicians to perform real-time jam sessions over the internet. Applikationen gör det möjligt för musiker att spela tillsammans live över Internet. There is a server which collects the audio data from each client, mixes the audio data and sends the mix back to each client. Det finns en server som samlar ljud från varje klient, blandar ljudet och skickar mixen tillbaka till varje klient. This app uses the following libraries, resources or code snippets: Denna applikationen använder följande bibliotek, resurser eller kodavsnitt: Qt cross-platform application framework Qt cross-platform applikationsramverk Audio reverberation code by Perry R. Cook and Gary P. Scavone Ljudklangkod av Perry R. Cook och Gary P. Scavone Some pixmaps are from the Vissa pixmaps är från Country flag icons by Mark James Landsflaggsymboler gjorda av Mark James For details on the contributions check out the För detaljer om bidrag, kolla in Flag icons by Mark James Flaggikoner av Mark James Some sound samples are from Vissa ljudprover är från For details on the contributions check out the %1 För detaljer om bidragen kolla in %1 Github Contributors list Github's bidragsgivarlista Spanish Spanska French Franska Portuguese Portugisiska Dutch Holländska Italian Italienska German Tyska Polish Polska Swedish Svenska Korean Koreanska Slovak Slovakiska Simplified Chinese Förenklad kinesiska Norwegian Bokmål About %1 Om %1 About Om CAboutDlgBase About Om TextLabelVersion How to translate this? TextLabelVersion Copyright (C) 2005-2022 Volker Fischer and others Upphovsrätt (C) 2005-2020 Volker Fischer och andra Copyright (C) 2005-2022 The Jamulus Development Team Upphovsrätt (C) 2005-2021 The Jamulus Development Team A&bout &Om &Libraries &Bibliotek &Contributors Bidrags&givare &Translation &Översättningar &OK &Stäng CAnalyzerConsole Analyzer Console Analyskonsol Error Rate of Each Buffer Size Felhastighet för varje buffertstorlek CAudioMixerBoard Personal Mix at the Server Personlig mix på servern When connected to a server, the controls here allow you to set your local mix without affecting what others hear from you. The title shows the server name and, when known, whether it is actively recording. När du är ansluten till en server låter kontrollerna här ställa in din lokala mix utan att påverka vad andra hör från dig. Titeln visar servernamnet och, om det är känt, om den aktivt spelar in. Server Server T R Y I N G T O C O N N E C T F Ö R S Ö K E R A N S L U T A RECORDING ACTIVE INSPELNING AKTIV Personal Mix at: %1 Personlig mix på: %1 CChannelFader Pan Panorera Mute Tyst Solo Solo &No grouping &Ingen gruppering Assign to group Tilldela grupp Channel Level Kanalnivå Displays the pre-fader audio level of this channel. All clients connected to the server will be assigned an audio level, the same value for every client. Visar ljudnivån för fader på denna kanal. Alla klienter som är anslutna till servern tilldelas en ljudnivå och har samma värde för alla klienter. Input level of the current audio channel at the server Ingångsnivå för den aktuella ljudkanalen på servern Mixer Fader Mixer Adjusts the audio level of this channel. All clients connected to the server will be assigned an audio fader, displayed at each client, to adjust the local mix. Justerar ljudnivån på den här kanalen. Alla klienter som är anslutna till servern tilldelas en ljudfader som visas vid varje klient för att justera den lokala mixen. Local mix level setting of the current audio channel at the server Lokal mixernivåinställning för den aktuella ljudkanalen på servern Status Indicator Statusindikator Shows a status indication about the client which is assigned to this channel. Supported indicators are: Visar en statusindikering om klienten som tilldelas denna kanal. Stödjade indikatorer är: Speaker with cancellation stroke: Indicates that another client has muted you. Högtalare med streck över visar att en annan klient har stängt av ditt ljud. Status indicator label etikett för statusindikator Panning Panorering Sets the pan from Left to Right of the channel. Works only in stereo or preferably mono in/stereo out mode. Ställer in panorering från vänster till höger för kanalen. Fungerar endast i stereo eller helst mono in / stereo ut-läge. Local panning position of the current audio channel at the server Lokal panoreringsposition för den aktuella ljudkanalen på servern With the Mute checkbox, the audio channel can be muted. Med kryssrutan "Stäng av" kan ljudkanalen stängas av. Mute button Knapp för att stänga av With the Solo checkbox, the audio channel can be set to solo which means that all other channels except the soloed channel are muted. It is possible to set more than one channel to solo. Med kryssrutan Solo kan ljudkanalen ställas in på solo vilket innebär att alla andra kanaler utom solokanalen är avstängda. Det är möjligt att ställa in mer än en kanal för solo. Solo button Soloknapp Group Grupp With the Grp checkbox, a group of audio channels can be defined. All channel faders in a group are moved in proportional synchronization if any one of the group faders are moved. Med kryssrutan Grp kan en grupp ljudkanaler definieras. Alla kanalfadrar i en grupp flyttas i proportionell synkronisering om någon av gruppfadrarna flyttas. Group button Gruppknapp Fader Tag Panoreringstagg The fader tag identifies the connected client. The tag name, a picture of your instrument and the flag of your country can be set in the main window. Fadertaggen identifierar den anslutna klienten. Etikettnamnet, en bild av ditt instrument och ditt lands flagga kan ställas in i huvudfönstret. Mixer channel instrument picture Mixerkanalens instrumentbild Mixer channel label (fader tag) Mixerkanalens etikett (fader) Mixer channel country flag Mixerkanalens landsflagga PAN PANORERA MUTE TYST SOLO SOLO GRP GRUPP M T S S G G Grp Grp Alias/Name Alias/Namn Instrument Instrument Location Plats Skill Level Skicklighetsnivå Alias Alias Beginner Nybörjare The fader tag identifies the connected client. The tag name, a picture of your instrument and the flag of your location can be set in the main window. Fadertaggen identifierar den anslutna klienten. Etikettnamnet, en bild av ditt instrument och flaggan för din plats ställas in i huvudfönstret. Mixer channel country/region flag Mixerkanalens land/regionsflagga Intermediate Mellannivå Expert Expert Musician Profile Musikprofil CChatDlg Chat Window Chattfönster The chat window shows a history of all chat messages. Chattfönstret visar en historik över alla chattmeddelanden. Chat history Chatthistorik Input Message Text Skriv meddelandetext Enter the chat message text in the edit box and press enter to send the message to the server which distributes the message to all connected clients. Your message will then show up in the chat window. Ange chattmeddelandetexten i textrutan och tryck på enter för att skicka meddelandet till servern som distribuerar meddelandet till alla anslutna klienter. Ditt meddelande kommer synas i chattfönstret. New chat text edit box Ny redigeringsruta för chatt-text Type a message here Skriv ditt meddelande här &Edit &Redigera Cl&ear Chat History &Rensa chatthistorik &Close &Stäng Do you want to open the link '%1' in your browser? Vill du öppna länken '%1' i din webbläsare? Do you want to open the link Vill du öppna länken in an external browser? i en extern webbläsare? CChatDlgBase Chat Chatt &Send &Skicka Cl&ear R&ensa &Close &Stäng CClientDlg Input Level Meter Ingångsnivå This shows the level of the two stereo channels for your audio input. Detta visar nivån på de två stereokanalerna för din ljudingång. Make sure not to clip the input signal to avoid distortions of the audio signal. Se till att inte klippa insignalen för att undvika en snedvridning av ljudsignalen. If the application is connected to a server and you play your instrument/sing into the microphone, the VU meter should flicker. If this is not the case, you have probably selected the wrong input channel (e.g. 'line in' instead of the microphone input) or set the input gain too low in the (Windows) audio mixer. Om applikationen är ansluten till en server och du spelar ditt instrument/sjunger in i mikrofonen, bör VU-mätaren röra sig. Om detta inte sker har du antagligen valt fel inmatningskanal (t.ex. 'line in' i stället för mikrofoningången) eller ställt in ingångsförstärkningen för (Windows) för lågt. For proper usage of the application, you should not hear your singing/instrument through the loudspeaker or your headphone when the software is not connected. This can be achieved by muting your input audio channel in the Playback mixer (not the Recording mixer!). För korrekt användning av applikationen, bör du inte höra din sång/instrument via högtalaren eller hörlurarna när programvaran inte är ansluten. Det kan uppnås genom att stänga av din ingående ljudkanal i uppspelningsblandaren (inte inspelningsblandaren!). Input level meter Ingångsnivåmätare Simulates an analog LED level meter. Simulerar en analog LED-nivåmätare. Connect/Disconnect Button Knapp för att anslut eller koppla ifrån Opens a dialog where you can select a server to connect to. If you are connected, pressing this button will end the session. Öppnar en dialogruta där du kan välja en server att ansluta till. Om du är ansluten avslutar du sessionen genom att trycka på den här knappen. Connect and disconnect toggle button Knapp för att anslut och koppla bort Clicking on this button changes the caption of the button from Connect to Disconnect, i.e., it implements a toggle functionality for connecting and disconnecting the application. Om du klickar på den här knappen ändras bildtexten på knappen från Ansluten till Nedkopplad, dvs. den implementerar en växelfunktion för att ansluta och koppla bort applikationen. Local Audio Input Fader Lokal ljudingångsfader Controls the relative levels of the left and right local audio channels. For a mono signal it acts as a pan between the two channels. For example, if a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows Kontrollerar de relativa nivåerna för vänster och höger lokala ljudkanal. För en monosignal fungerar den som en panorering mellan de två kanalerna. Om exempelvis en mikrofon är ansluten till den högra ingångskanalen och ett instrument är anslutet till den vänstra ingångskanalen som är mycket högre än mikrofonen, flytta ljudfadern i en riktning som etiketten ovanför fadern visar L V , where , där is the current attenuation indicator. är den aktuella dämpningsindikatorn. Local audio input fader (left/right) Lokal ljudingångsfader (vänster/höger) Reverb effect Reverb effekt Reverb can be applied to one local mono audio channel or to both channels in stereo mode. The mono channel selection and the reverb level can be modified. For example, if a microphone signal is fed in to the right audio channel of the sound card and a reverb effect needs to be applied, set the channel selector to right and move the fader upwards until the desired reverb level is reached. Reverb kan tillämpas på en lokal monoljudkanal eller på båda kanalerna i stereoläge. Valet av monokanal och reverbnivån kan ändras. Om till exempel en mikrofonsignal matas in till höger ljudkanal på ljudkortet och en reverb-effekt måste appliceras, ställ in kanalväljaren till höger och flytta fadern uppåt tills önskad reverbnivå har uppnåtts. Reverb effect level setting Reverbeffektnivåinställning Reverb Channel Selection Reverbkanalval With these radio buttons the audio input channel on which the reverb effect is applied can be chosen. Either the left or right input channel can be selected. Med dessa tryckknappar kan du välja ljudingångskanalen på vilken reverbeffekten används. Antingen kan vänster eller höger ingångskanal väljas. Left channel selection for reverb Vänster kanal för reverb Right channel selection for reverb Höger kanal för reverb Delay Status LED Fördröjningsstatus-LED Shows the current audio delay status: Visar aktuell ljudfördröjningsstatus: Green Grön The delay is perfect for a jam session. Fördröjningen är perfekt för en jam-session. Yellow Gul A session is still possible but it may be harder to play. En session är fortfarande möjlig men det kan vara svårare att spela. Red Röd The delay is too large for jamming. Fördröjningen är troligtvis för stor för en jam-session. If this LED indicator turns red, you will not have much fun using the application. Om den här LED-indikatorn blir röd kommer du inte ha så kul med applikationen. Delay status LED indicator LED-indikator för fördröjningsstatus %1 Directory %1 Katalog Buffers Status LED Buffertstatus-LED The buffers status LED shows the current audio/streaming status. If the light is red, the audio stream is interrupted. This is caused by one of the following problems: Statuslampan för buffertar visar aktuell ljud-/strömningsstatus. Om lampan är röd avbryts ljudströmmen. Detta orsakas av ett av följande problem: The network jitter buffer is not large enough for the current network/audio interface jitter. Nätverksjitterbufferten är inte tillräckligt stor för det nuvarande nätverks-/ljudgränssnittsjitteret. The sound card's buffer delay (buffer size) is too small (see Settings window). Ljudkortets buffertfördröjning (buffertstorlek) är för liten (se Inställningsfönstret). The upload or download stream rate is too high for your internet bandwidth. Uppladdnings- eller nedladdningsströmmen är för hög för din internethastighet. The CPU of the client or server is at 100%. Klientens eller serverns CPU är 100%. Buffers status LED indicator LED-indikator för buffertstatus Current Connection Status Parameter Parameter för aktuell anslutningsstatus The Ping Time is the time required for the audio stream to travel from the client to the server and back again. This delay is introduced by the network and should be about 20-30 ms. If this delay is higher than about 50 ms, your distance to the server is too large or your internet connection is not sufficient. Ping-tiden är den tid som krävs för ljudströmmen att resa från klienten till servern och tillbaka igen. Denna fördröjning införs av nätverket och bör vara cirka 20-30 ms. Om denna fördröjning är högre än cirka 50 ms är ditt avstånd till servern för stort eller din internetanslutning är inte tillräcklig. Overall Delay is calculated from the current Ping Time and the delay introduced by the current buffer settings. Övergripande fördröjning beräknas utifrån den aktuella Ping-tiden och den fördröjning som införts av de aktuella buffertinställningarna. If this LED indicator turns red, you will not have much fun using the Om den här LED-indikatorn blir röd kommer du inte ha så kul med att använda software. applikationen. C&onnect A&nslut software upgrade available mjukvaruuppdatering tillgänglig &File &Arkiv &View &Visa &Connection Setup... &Anslutningsinställningar... My &Profile... Min &profil... C&hat... &Chatt... &Settings... &Inställningar... &Analyzer Console... Analys&konsol... N&o User Sorting Ingen kanals&ortering Sort Users by &City Sortera användarna efter S&tad Use &Two Rows Mixer Panel Dela upp &mixerpanelen i två rader Clear &All Stored Solo and Mute Settings &Rensa alla lagrade solo och tystade inställningar Auto-Adjust all &Faders Möjligtvis annat ordval skulle vara bättre. Justera alla &mixers automatiskt &Settings &Inställningar Connect Anslut Settings Inställningar Chat Chatt Enable feedback detection Aktivera återkopplingsdetektering Audio feedback or loud signal detected. We muted your channel and activated 'Mute Myself'. Please solve the feedback issue first and unmute yourself afterwards. Ljudåterkoppling eller hög signal har upptäcks. Vi stängde av din kanal och aktiverade 'Tysta mig själv'. Vänligen lös problemet med ljudåterkopplingen först och slå sedan på dittt ljud igen. Your sound card is not working correctly. Please open the settings dialog and check the device selection and the driver settings. Ditt ljudkort fungerar inte korrekt. Öppna inställningar och kontrollera enhetsvalet och drivrutinsinställningarna. Ok Okej Clear &All Stored Solo Settings &Rensa alla lagrade soloinställningar Set All Faders to New Client &Level &Ställ in alla mixers till ny klientnivå E&xit A&vsluta If this LED indicator turns red, you will not have much fun using %1. Om den här LED-indikatorn blir röd kommer du inte att ha mycket kul med %1. Local Jitter Buffer Status LED LED för lokal jitterbufferstatus The local jitter buffer status LED shows the current audio/streaming status. If the light is red, the audio stream is interrupted. This is caused by one of the following problems: Statuslampan för lokala jitterbuffert visar aktuell ljud-/strömningsstatus. Om lampan är röd avbryts ljudströmmen. Detta orsakas av ett av följande problem: If this LED indicator turns red, the audio stream is interrupted. Om denna LED-indikator blir röd avbryts ljudströmmen. Local Jitter Buffer status LED indicator LED-indikator för lokal jitterbufferstatus If this LED indicator turns red, you will not have much fun using the %1 software. Om den här LED-indikatorn blir röd kommer du inte ha så kul med att använda %1 applicationen. &Load Mixer Channels Setup... &Ladda in mixerkanalinställningarna... &Save Mixer Channels Setup... &Spara mixerkanalinställningarna... O&wn Fader First &Egen fader först Sett&ings &Inställningar Audio/Network &Settings... Ljud och nätverks&inställningar... A&dvanced Settings... A&vancerade inställningar... &Edit &Redigera Current Connection Status Aktuell anslutningsstatus Sort Users by &Name Sortera användarna efter &Namn Sort Users by &Instrument Sortera användarna efter &Instrument Sort Users by &Group Sortera användarna efter &Grupp None Ingen Center Mitten R H Directory Server Katalogserver Select Channel Setup File Välj kanalinställningsfil user användare users användare The soundcard device does not work correctly. Please check the device selection and the driver settings. Ljudkortet fungerar inte som det ska. Kontrollera enhetsvalet och drivrutinsinställningarna. &Disconnect Koppla &ner CClientDlgBase Delay Fördröjning Buffers Buffert Input Ingång L V R H Jitter Jitter Ping Ping ms ms &Mute Myself Tysta &mig själv &Settings In&ställningar &Chat &Chatt C&onnect &Koppla upp Pan Panorera Center Mitten Reverb Reverb Left Vänster Right Höger MUTED (Other people won't hear you) Du är tystad! (andra hör inte dig) Set up your audio, connect to a server and start jamming! Ställ in ditt ljud och anslut till en server. Sedan är det bara att börja jamma! Update check Uppdateringskontroll MUTED (You are not sending any audio to the server) TYSTAD (Du skickar inget ljud till servern) CClientSettingsDlg &Close &Stäng Local Audio Input Fader Lokal ljudingångsfader Controls the relative levels of the left and right local audio channels. For a mono signal it acts as a pan between the two channels. For example, if a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows Kontrollerar de relativa nivåerna för vänster och höger lokala ljudkanal. För en monosignal fungerar den som en panorering mellan de två kanalerna. Om exempelvis en mikrofon är ansluten till den högra ingångskanalen och ett instrument är anslutet till den vänstra ingångskanalen som är mycket högre än mikrofonen, flytta ljudfadern i en riktning som etiketten ovanför fadern visar L V , where , där is the current attenuation indicator. är den aktuella dämpningsindikatorn. Local audio input fader (left/right) Lokal ljudingångsfader (vänster/höger) Jitter Buffer Size Jitterbuffertstorlek The jitter buffer compensates for network and sound card timing jitters. The size of the buffer therefore influences the quality of the audio stream (how many dropouts occur) and the overall delay (the longer the buffer, the higher the delay). Jitterbufferten kompenserar för nätverks- och ljudkortstimning. Storleken på bufferten påverkar därför kvaliteten på ljudströmmen (hur många bortfall som inträffar) och den totala förseningen (ju längre bufferten är, desto högre fördröjning). You can set the jitter buffer size manually for the local client and the remote server. For the local jitter buffer, dropouts in the audio stream are indicated by the light below the jitter buffer size faders. If the light turns to red, a buffer overrun/underrun has taken place and the audio stream is interrupted. Jitterbufferten kompenserar för nätverks- och ljudkortets timeing. Storleken på bufferten påverkar därför kvaliteten på ljudströmmen (hur många bortfall som inträffar) och den totala förseningen (ju längre bufferten är, desto högre är fördröjningen). The jitter buffer setting is therefore a trade-off between audio quality and overall delay. Jitterbuffertinställningen är därför en avvägning mellan ljudkvalitet och total fördröjning. If the Auto setting is enabled, the jitter buffers of the local client and the remote server are set automatically based on measurements of the network and sound card timing jitter. If Auto is enabled, the jitter buffer size faders are disabled (they cannot be moved with the mouse). Om Auto-inställningen är aktiverad, ställs jitterbuffertarna för den lokala klienten och fjärrservern in automatiskt baserat på mätningar av nätverkets och ljudkortets timingjitter. Om Auto är aktiverat inaktiveras jitterbuffertstorleken (de kan inte justeras). If the Auto setting is enabled, the network buffers of the local client and the remote server are set to a conservative value to minimize the audio dropout probability. To tweak the audio delay/latency it is recommended to disable the Auto setting and to lower the jitter buffer size manually by using the sliders until your personal acceptable amount of dropouts is reached. The LED indicator will display the audio dropouts of the local jitter buffer with a red light. Om Auto-inställningen är aktiverad ställs nätverksbuffertarna för den lokala klienten och fjärrservern in på ett konservativt värde för att minimera sannorlikheten för ljudbortfall. För att justera ljudfördröjningen/latensen rekommenderas att du inaktiverar Auto-inställningen och att sänka jitterbuffertstorleken manuellt genom att använda reglagen tills din personliga acceptabla mängd bortfall uppnåtts. LED-indikatorn visar ljudavfallet från den lokala jitterbufferten med rött ljus. Local jitter buffer slider control Lokalt jitterbuffertreglage Server jitter buffer slider control Server jitter buffertreglage Auto jitter buffer switch Auto-jitterbuffert reglage For each %1 input/output channel (left and right channel) a different actual sound card channel can be selected. För varje %1 ingångs-/utgångskanal (vänster- och högerkanal) kan en annan faktisk ljudkortkanal väljas. Enables support for very small network audio packets. These network packets are only actually used if the sound card buffer delay is smaller than %1 samples. The smaller the network buffers, the lower the audio latency. But at the same time the network load and the probability of audio dropouts or sound artifacts increases. Möjliggör stöd för mycket små nätverksljudpaket. Dessa nätverkspaket används faktiskt bara om ljudkortets buffertfördröjning är mindre än %1 sampel. Ju mindre nätverksbuffertar, desto lägre ljudfördröjning. Men samtidigt ökar nätverksbelastningen och sannolikheten för ljudavbrott eller ljudartefakter. The buffer delay setting is a fundamental setting of %1. This setting has an influence on many connection properties. Inställningen för buffertfördröjning är en grundläggande inställning för %1. Denna inställning påverkar många anslutningsegenskaper. Some sound card drivers do not allow the buffer delay to be changed from within %1. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. On Windows, use the ASIO Device Settings button to open the driver settings panel. On Linux, use the JACK configuration tool to change the buffer size. Vissa ljudkortdrivrutiner tillåter inte att buffertfördröjningen ändras inifrån %1. I detta fall är inställningen för buffertfördröjning inaktiverad och måste ändras med hjälp av ljudkortdrivrutinen. På Windows trycker du på knappen ASIO enhetsinställningar för att öppna panelen för drivrutinsinställningar. På Linux använder du Jack-konfigurationsverktyget för att ändra buffertstorleken. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within %1. On Windows, press the ASIO Device Settings button to open the driver settings panel. On Linux, use the JACK configuration tool to change the buffer size. Om buffertfördröjningsinställningarna är inaktiverade är det förbjudet för ljuddrivrutinen att ändra denna inställning inifrån %1. På Windows trycker du på knappen ASIO enhetsinställningar för att öppna panelen för drivrutinsinställningar. På Linux använder du Jack-konfigurationsverktyget för att ändra buffertstorleken. This opens the driver settings of your sound card. Some drivers allow you to change buffer settings, others like ASIO4ALL lets you choose input or outputs of your device(s). More information can be found on jamulus.io. Detta öppnar drivrutinsinställningarna för ditt ljudkort. Vissa drivrutiner låter dig ändra buffertinställningar, andra som ASIO4ALL låter dig välja in- eller utgångar från din enhet(er). Mer information finns på jamulus.io. Opens the driver settings. Note: %1 currently only supports devices with a sample rate of %2 Hz. You will not be able to select a driver/device which doesn't. For more help see jamulus.io. Öppnar drivrutinsinställningarna. Obs! %1 stöder för närvarande bara enheter med en samplingsfrekvens på %2 Hz. Du kommer inte att kunna välja en drivrutin/enhet som inte gör det. För mer hjälp se jamulus.io. Jitter buffer status LED indicator LED-indikator för jitterbufferstatus Sound Card Device Ljudkortsenhet The ASIO driver (sound card) can be selected using ASIO-drivrutinen (ljudkort) kan väljas med under the Windows operating system. Under MacOS/Linux, no sound card selection is possible. If the selected ASIO driver is not valid an error message is shown and the previous valid driver is selected. under Windows. Under MacOS/Linux är inget ljudkortsval möjligt. Om den valda ASIO-drivrutinen inte är giltig visas ett felmeddelande och den tidigare giltiga drivrutinen väljs. If the driver is selected during an active connection, the connection is stopped, the driver is changed and the connection is started again automatically. Om drivrutinen väljs under en aktiv anslutning stoppas anslutningen, drivrutinen ändras och anslutningen startas automatiskt igen. Sound card device selector combo box Ljudkortsenhetens kombinationsruta If the ASIO4ALL driver is used, please note that this driver usually introduces approx. 10-30 ms of additional audio delay. Using a sound card with a native ASIO driver is therefore recommended. Om ASIO4ALL-drivrutinen används, observera att den här drivrutinen vanligtvis introducerar ca. 10-30 ms extra ljudfördröjning. Det rekommenderas därför att använda ett ljudkort med en inbyggd ASIO-drivrutin. If you are using the kX ASIO driver, make sure to connect the ASIO inputs in the kX DSP settings panel. Om du använder kX ASIO-drivrutinen, se till att ansluta ASIO-ingångarna på kX DSP-inställningspanelen. Sound Card Channel Mapping Ljudkortets kanalval If the selected sound card device offers more than one input or output channel, the Input Channel Mapping and Output Channel Mapping settings are visible. Om den valda ljudkortsenheten erbjuder mer än en ingångs- eller utgångskanal är inställningarna för inmatningskanalens mappning och utmatningskanal synliga. For each För varje input/output channel (Left and Right channel) a different actual sound card channel can be selected. ingångs-/utgångskanal (vänster- och högerkanal) kan en annan faktisk ljudkortkanal väljas. Left input channel selection combo box Vänster ingångskanalvalskombinationsruta Right input channel selection combo box Höger ingångskanalvalskombinationsruta Left output channel selection combo box Vänster utgångskanalvalskombinationsruta Right output channel selection combo box Höger utgångskanalvalskombinationsruta Enable Small Network Buffers Aktivera liten nätverksbuffert If enabled, the support for very small network audio packets is activated. Very small network packets are only actually used if the sound card buffer delay is smaller than Om det är aktiverat aktiveras stödet för mycket små nätverksljudpaket. Mycket små nätverkspaket används faktiskt bara om ljudkortsbuffertfördröjningen är mindre än samples. The smaller the network buffers, the lower the audio latency. But at the same time the network load increases and the probability of audio dropouts also increases. bitars buffert. Ju mindre nätbuffertarna är, desto lägre är ljudet. Men samtidigt ökar nätverksbelastningen och sannolikheten för ljudavbrott ökar också. Enable small network buffers check box Aktivera kryssrutan för små nätverksbuffertar Sound Card Buffer Delay Ljudkortets buffertfördröjning The buffer delay setting is a fundamental setting of this software. This setting has an influence on many connection properties. Inställningen för buffertfördröjning är en grundläggande inställning för denna applikation. Denna inställning påverkar många anslutningsegenskaper. Three buffer sizes are supported Tre buffertstorlekar stöds 64 samples: The preferred setting. Provides the lowest latency but does not work with all sound cards. 64 bitars buffert: Den rekommenderade inställningen. Den ger den lägsta latensen men fungerar inte med alla ljudkort. 128 samples: Should work for most available sound cards. 128 bitars buffert: Bör fungera för alla ljudkort. 256 samples: Should only be used on very slow computers or with a slow internet connection. 265 bitars buffert: Ska endast användas med långsamma datorer eller med långsam internetkoppling. Some sound card drivers do not allow the buffer delay to be changed from within the application. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. On Windows, press the ASIO Device Settings button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Vissa ljudkortdrivrutiner tillåter inte att buffertfördröjningen ändras inifrån programmet. I detta fall är inställningen för buffertfördröjning inaktiverad och måste ändras med hjälp av ljudkortdrivrutinen. På Windows trycker du på knappen ASIO enhetsinställningar för att öppna panelen för drivrutinsinställningar. På Linux använder du Jack-konfigurationsverktyget för att ändra buffertstorleken. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within the software. On Windows, press the ASIO Device Settings button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. ASIO enhetsinställningar Om buffertfördröjningsinställningarna är inaktiverade är det förbjudet för ljuddrivrutinen att ändra denna inställning inifrån programvaran. På Windows trycker du på knappen ASIO enhetsinställningar för att öppna panelen för drivrutinsinställningar. På Linux använder du Jack-konfigurationsverktyget för att ändra buffertstorleken. Sound card driver settings Ljudkortsinställningar This opens the driver settings of your sound card. Some drivers allow you to change buffer settings, others like ASIO4ALL let you choose input or outputs of your device(s). More information can be found on jamulus.io. Detta öppnar drivrutinsinställningarna för ditt ljudkort. Vissa drivrutiner låter dig ändra buffertinställningar, andra som ASIO4ALL låter dig välja in- eller utgångar från din enhet (er). Mer information finns på jamulus.io. Opens the driver settings. Note: Öppnardrivrutinsinställningarna. Notera: currently only supports devices supporting a sample rate of stöder för närvarande endast enheter som stöder en samplingsfrekvens på Hz. You will not be able to select a driver/device which doesn't. For more help see jamulus.io. Hz. Du kommer inte att kunna välja en drivrutin/enhet som inte gör det. För mer hjälp se jamulus.io. Controls the relative levels of the left and right local audio channels. For a mono signal it acts as a pan between the two channels. For example, if a microphone is connected to the right input channel and an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader in a direction where the label above the fader shows %1, where %2 is the current attenuation indicator. Kontrollerar de relativa nivåerna för vänster och höger lokala ljudkanal. För en monosignal fungerar den som en panorering mellan de två kanalerna. Om exempelvis en mikrofon är ansluten till den högra ingångskanalen och ett instrument är anslutet till den vänstra ingångskanalen som är mycket högre än mikrofonen, flytta ljudfadern i en riktning som etiketten ovanför fadern visar %1, där %2 är den aktuella dämpningsindikatorn. Audio Device Ljudenhet Under the Windows operating system the ASIO driver (sound card) can be selected using %1. If the selected ASIO driver is not valid an error message is shown and the previous valid driver is selected. Under macOS the input and output hardware can be selected. Under Windows operativsystem kan ASIO-drivrutinen (ljudkortet) väljas med %1. Om den valda ASIO-drivrutinen inte är giltig visas ett felmeddelande och den tidigare giltiga drivrutinen väljs. Under macOS är inget ljudkortsval möjligt. Three buffer sizes can be selected Tre buffertstorlekar kan väljas 64 samples: Provides the lowest latency but does not work with all sound cards. 64 bitars buffert: Den ger den lägsta latensen men fungerar inte med alla ljudkort. 256 samples: Should only be used when 64 or 128 samples is causing issues. 256 bitars buffert: Ska endast användas när 64 eller 128 bitars buffert orsakar problem. Some sound card drivers do not allow the buffer delay to be changed from within %1. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. Use the appropriate tool for the interface in use to adjust this buffer size. For example, if using ASIO, use the "ASIO Device Settings" button to open the driver settings panel or if using JACK, use a tool such as QjackCtl to adjust the buffer size. Other interfaces, such as Pipewire, would require their appropriate tool being used. Please refer to the interface manual. If no buffer size is selected and all settings are disabled, this means a buffer size in use by the driver which does not match the values. %1 will still work with this setting but may have restricted performance. Om ingen buffertstorlek är vald och alla inställningar är inaktiverade, betyder detta en buffertstorlek som används av drivrutinen och som inte matchar värdena. %1 fungerar fortfarande med den här inställningen men med begränsad prestanda. The actual buffer delay has influence on the connection, the current upload rate and the overall delay. The lower the buffer size, the higher the probability of a red light in the status indicator (drop outs) and the higher the upload rate and the lower the overall delay. Den faktiska buffertfördröjningen har påverkan på anslutning, den aktuella uppladdningshastigheten och den totala förseningen. Ju lägre buffertstorlek, desto högre är sannolikheten för rött ljus i statusindikatorn (drop outs) och desto högre uppladdningshastighet och desto lägre blir den totala fördröjningen. ASIO Device Settings push button ASIO enhetsinställningsknapp Meter Style Meterstil Select the meter style to be used for the level meters. The Bar (narrow) and LEDs (round, small) options only apply to the mixerboard. When Bar (narrow) is selected, the input meters are set to Bar (wide). When LEDs (round, small) is selected, the input meters are set to LEDs (round, big). The remaining options apply to the mixerboard and input meters. Välj den mätarstil som ska användas för nivåmätarna. Alternativen Bar (smal) och LEDs (rund, liten) gäller bara för mixerkortet. När Bar (smal) är vald ställs ingångsmätarna in på Bar (bred). När LEDs (rund, liten) är vald, är ingångsmätarna inställda på LEDs (rund, stor). De återstående alternativen gäller mixerboard och ingångsmätare. Meter Style combo box Kombineringsknapp för meterstil Language Språk Select the language to be used for the user interface. Välj det språk som ska användas för användargränssnittet. Language combo box Kombineringsknapp för språk and och Input Boost Ingångsförstärkning This setting allows you to increase your input signal level by factors up to 10 (+20dB). If your sound is too quiet, first try to increase the level by getting closer to the microphone, adjusting your sound equipment or increasing levels in your operating system's input settings. Only if this fails, set a factor here. If your sound is too loud, sounds distorted and is clipping, this option will not help. Do not use it. The distortion will still be there. Instead, decrease your input level by getting farther away from your microphone, adjusting your sound equipment or by decreasing your operating system's input settings. Denna inställning låter dig öka din insignalnivå med faktor upp till 10 (+ 20dB). Om ditt ljud är för tyst, försök först att höja nivån genom att komma närmare mikrofonen, justera din ljudutrustning eller öka nivåerna i din drift systemets ingångsinställningar. Endast om detta misslyckas, ställ in en faktor här. Om ditt ljud är för högt, låter förvrängt och klipper, hjälper det här alternativet inte. Använd då inte det då förvrängningen kommer fortfarande att finnas där. Sänk istället din ingångsnivå genom att komma längre bort från din mikrofon, justera din ljudutrustning eller genom att minska operativsystemets ingångsinställningar. Input Boost combo box Ingångsförstärknings knapp Custom Directories Anpassad kataloger If you need to add additional directories to the Connect dialog Directory drop down, you can enter the addresses here.<br>To remove a value, select it, delete the text in the input box, then move focus out of the control. Om du behöver lägga till ytterligare kataloger i rullgardinsmenyn Anslut dialogrutan Katalog kan du ange adresserna här.<br>För att ta bort ett värde, välj det, radera texten i inmatningsrutan och flytta sedan fokus från kontrollen. Custom Directories combo box Kombinationsruta för anpassad kataloger Audio Upstream Rate Ljud uppströmshastighet Depends on the current audio packet size and compression setting. Make sure that the upstream rate is not higher than your available internet upload speed (check this with a service such as speedtest.net). Beror på den aktuella ljudpaketstorleken och komprimeringsinställningen. Se till att uppströmshastigheten inte är högre än din tillgängliga internetuppladdningshastighet (kolla detta med en tjänst som exempelvis speedtest.net). Number of Mixer Panel Rows Antal mixerpanelrader Adjust the number of rows used to arrange the mixer panel. Justera antalet rader som används för att ordna mixerpanelen. Number of Mixer Panel Rows spin box Antal mixerpanelrader i rutan Feedback Protection Rundgångsskydd Enable feedback protection to detect acoustic feedback between microphone and speakers. Aktivera rundgångsskydd för att upptäcka rundgång mellan mikrofon och högtalare. Feedback Protection check box Rundgångsskyddsruta Audio Alerts Ljudvarningar Enable audio alert when receiving a chat message and when a new client joins the session. A second sound device may be required to hear the alerts. Audio Alerts check box ASIO Device Settings ASIO enhetsinställningar Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country or region you are located in. Your city and skill level playing your instrument may also be added. Skriv ditt namn eller ett alias här så att de andra musikerna du vill spela med vet vem du är. Du kan också lägga till en bild av instrumentet du spelar och en flagga för det land/region du befinner dig i. Din stad och din färdighetsnivå som spelar ditt instrument kan också läggas till. What you set here will appear at your fader on the mixer board when you are connected to a %1 server. This tag will also be shown at each client which is connected to the same server as you. Det du ställer in här visas på din fader på mixerkortet när du är ansluten till en %1-server. Den här taggen kommer också att visas vid varje klient som är ansluten till samma server som du. Country/region flag button Knapp för land/regionsflagga Center Mitten R H Some sound card drivers do not allow the buffer delay to be changed from within the application. In this case the buffer delay setting is disabled and has to be changed using the sound card driver. On Windows, press the ASIO Setup button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Vissa ljudkortdrivrutiner tillåter inte buffertfördröjningen att ändras från applikationen. I detta fall avbryts inställningen för buffertfördröjning och måste ändras med ljudkortsdrivrutinen. I Windows trycker du på ASIO-inställningsknappen för att öppna drivrutinsinställningspanelen. I Linux använder du Jack-konfigurationsverktyget för att ändra buffertstorleken. If no buffer size is selected and all settings are disabled, an unsupported buffer size is used by the driver. The application will still work with this setting but with restricted performance. Om ingen buffertstorlek är vald och alla inställningar är inaktiverade, används en icke-stödd buffertstorlek av drivrutinen. Applikationen fungerar fortfarande med den här inställningen men med begränsad prestanda. The actual buffer delay has influence on the connection status, the current upload rate and the overall delay. The lower the buffer size, the higher the probability of a red light in the status indicator (drop outs) and the higher the upload rate and the lower the overall delay. Den faktiska buffertfördröjningen har påverkan på anslutningsstatusen, den aktuella uppladdningshastigheten och den totala förseningen. Ju lägre buffertstorlek, desto högre är sannolikheten för rött ljus i statusindikatorn (drop outs) och desto högre uppladdningshastighet och desto lägre blir den totala fördröjningen. The buffer setting is therefore a trade-off between audio quality and overall delay. Buffertinställningen är därför en avvägning mellan ljudkvalitet och total fördröjning. If the buffer delay settings are disabled, it is prohibited by the audio driver to modify this setting from within the software. On Windows, press the ASIO Setup button to open the driver settings panel. On Linux, use the Jack configuration tool to change the buffer size. Om buffertfördröjningsinställningarna är inaktiverade är det ljuddrivrutinen som begränsar och det är inte möjligt att ändra denna inställning från applikationen. I Windows trycker du på ASIO-inställningsknappen för att öppna drivrutinsinställningspanelen. I Linux använder du Jack-konfigurationsverktyget för att ändra buffertstorleken. 64 samples setting radio button 64 bitars buffertknapp 128 samples setting radio button 128 bitars buffertknapp 256 samples setting radio button 256 bitars buffertknapp ASIO setup push button ASIO-inställningsknapp Skin Skal Select the skin to be used for the main window. Välj skal som ska användas för huvudfönstret. Skin combo box Kombineringsknapp för skal Directory server address combo box Kombinationsruta för katalogserveradress Display Channel Levels Visa kanalnivåer If enabled, each client channel will display a pre-fader level bar. Om detta är aktiverat kommer varje klientkanal att visa ett nivåfält före varje fader. Display channel levels check box Visa kryssrutan för visa kanalnivåer Audio Channels Ljudkanaler Selects the number of audio channels to be used for communication between client and server. There are three modes available: Väljer antalet ljudkanaler som ska användas för kommunikation mellan klient och server. Det finns tre lägen tillgängliga: Mono Mono and och Stereo Stereo These modes use one and two audio channels respectively. Dessa lägen använder respektive en och två ljudkanaler. Mono in/Stereo-out Mono in/Stereo-ut The audio signal sent to the server is mono but the return signal is stereo. This is useful if the sound card has the instrument on one input channel and the microphone on the other. In that case the two input signals can be mixed to one mono channel but the server mix is heard in stereo. Ljudsignalen som skickas till servern är mono men retursignalen är stereo. Detta är användbart om ljudkortet har instrumentet på en ingångskanal och mikrofonen på den andra. I så fall kan de två insignalerna blandas till en monokanal men servermixen hörs i stereo. Enabling Möjliggör mode will increase your stream's data rate. Make sure your upload rate does not exceed the available upload speed of your internet connection. kommer att öka dataströmmen. Se till att din uppladdningshastighet inte överstiger den tillgängliga uppladdningshastigheten för din internetanslutning. In stereo streaming mode, no audio channel selection for the reverb effect will be available on the main window since the effect is applied to both channels in this case. I stereo-strömningsläge kommer inget val av ljudkanal för reverb-effekten att finnas tillgängligt i huvudfönstret eftersom effekten tillämpas på båda kanalerna i detta fall. Audio channels combo box Kombineringsknapp för ljudkanalerna Audio Quality Ljudkvalitet The higher the audio quality, the higher your audio stream's data rate. Make sure your upload rate does not exceed the available bandwidth of your internet connection. Ju högre ljudkvalitet, desto högre datahastighet krävs. Se till att din uppladdningshastighet inte överstiger den tillgängliga bandbredden för din internetanslutning. Audio quality combo box Kombineringsknapp för ljudkvalitet New Client Level Ny klientnivå This setting defines the fader level of a newly connected client in percent. If a new client connects to the current server, they will get the specified initial fader level if no other fader level from a previous connection of that client was already stored. Denna inställning definierar fadernivån för en nyansluten klient i procent. Om en ny klient ansluter till den aktuella servern, kommer de att få den angivna initiala fader-nivån om ingen annan fader-nivå från en tidigare anslutning av den klienten redan lagrats. New client level edit box Redigeringsruta för en ny klient Custom Directory Server Address Anpassad katalogserveradress Leave this blank unless you need to enter the address of a directory server other than the default. Lämna detta tomt om du inte behöver ange adressen till en annan katalogserver än standard. Directory server address line edit Ändra centralserveradress Current Connection Status Parameter Parameter för aktuell anslutningsstatus The Ping Time is the time required for the audio stream to travel from the client to the server and back again. This delay is introduced by the network and should be about 20-30 ms. If this delay is higher than about 50 ms, your distance to the server is too large or your internet connection is not sufficient. Ping-tiden är den tid som krävs för ljudströmmen att resa från klienten till servern och tillbaka igen. Denna fördröjning införs av nätverket och bör vara cirka 20-30 ms. Om denna fördröjning är högre än cirka 50 ms är ditt avstånd till servern för stort eller din internetanslutning är inte tillräcklig. Overall Delay is calculated from the current Ping Time and the delay introduced by the current buffer settings. Övergripande fördröjning beräknas utifrån den aktuella Ping-tiden och den fördröjning som införts av de aktuella buffertinställningarna. Audio Upstream Rate depends on the current audio packet size and compression setting. Make sure that the upstream rate is not higher than your available internet upload speed (check this with a service such as speedtest.net). Uppströmsfrekvensen för ljudet beror på den aktuella ljudpaketstorleken och komprimeringsinställningen. Se till att uppströmshastigheten inte är högre än din tillgängliga internetuppladdningshastighet (kolla detta med en tjänst som exempelvis speedtest.net). If this LED indicator turns red, you will not have much fun using the Om den här LED-indikatorn blir röd kommer du inte ha så kul med att använda software. applikationen. ASIO Setup Inställningar för ASIO Mono-in/Stereo-out Mono-in/Stereo-ut Low Låg Normal Normal High Hög Fancy Fancy Compact Kompakt Bar (narrow) Bar (smal) Bar (wide) Bar (bred) LEDs (stripe) LEDs (bred) LEDs (round, small) LEDs (rund, liten) LEDs (round, big) LEDs (rund, stor) None Ingen preferred föredraget Musician Profile Musikprofil Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country you are located in. Your city and skill level playing your instrument may also be added. Skriv ditt namn eller ett alias här så att de andra musikerna du vill spela med vet vem du är. Du kan också lägga till en bild av instrumentet du spelar och en flagga för det land du befinner dig i. Din stad och din färdighetsnivå som spelar ditt instrument kan också läggas till. What you set here will appear at your fader on the mixer board when you are connected to a Jamulus server. This tag will also be shown at each client which is connected to the same server as you. Det du ställer in här visas på din fader på mixerkortet när du är ansluten till en Jamulus-server. Den här taggen kommer också att visas vid varje klient som är ansluten till samma server som du. Alias or name edit box Redigeringsruta för alias eller namn Instrument picture button Knapp för instrumentbild Country flag button Knapp för landsflagga City edit box Redigeringsruta för stad Skill level combo box Kombinationsruta för färdighetsnivå Beginner Nybörjare Intermediate Mellannivå Expert Expert Size: Storlek: Buffer Delay Buffertfördröjning Buffer Delay: Buffertfördröjning: The selected audio device could not be used because of the following error: Den valda ljudenheten kunde inte användas på grund av följande fel: The previous driver will be selected. Den föregående drivrutinen kommer att väljas. Ok Okej Custom Eget All Genres Alla genrer Any Genre 2 Alla genrer 2 Any Genre 3 Alla genrer 3 Genre Rock Genre Rock Genre Jazz Genre Jazz Genre Classical/Folk Genre Klassisk/Folkmusik Genre Choral/Barbershop Genre Choral/Barbershop Any Genre 1 Alla genrer 1 Genre Classical/Folk/Choral Genre Klassiskt/Folkmusik/Kör Default Standard Drum Set Trumset Djembe Djembe Electric Guitar Elgitarr Acoustic Guitar Akustisk gitarr Bass Guitar Basgitarr Keyboard Klaviatur Synthesizer Synthesizer Grand Piano Flygel Accordion Dragspel Vocal Sång Microphone Mikrofon Harmonica Munspel Trumpet Trumpet Trombone Trombon French Horn Valthorn Tuba Tuba Saxophone Saxofon Clarinet Klarinett Flute Flöjt Violin Fiol Cello Cello Double Bass Kontrabas Recorder Inspelningsapparat Streamer Streamer Listener Lyssnare Guitar+Vocal Gitarr+Sång Keyboard+Vocal Klaviatur+Sång Bodhran Bodhrán Bassoon Fagott Oboe Oboe Harp Harpa Viola Altfiol Congas Congas Bongo Bongo Vocal Bass Sång (bas) Vocal Tenor Sång (tenor) Vocal Alto Sång (alt) Vocal Soprano Sång (sopran) Banjo Banjo Mandolin Mandolin Ukulele Ukulele Bass Ukulele Ukulele (bas) Vocal Baritone Sång (baryton) Vocal Lead Sång (melodistämma) Mountain Dulcimer Mountain Dulcimer Scratching Scratching Rapping Rapp Vibraphone Vibrafon Conductor Dirigent CClientSettingsDlgBase Settings Inställningar Soundcard Ljudkort Device Enhet Input Channel Mapping Kanalval för ingång L V R H Output Channel Mapping Kanalval för utgång Enable Small Network Buffers Aktivera små nätverksbuffertar Buffer Delay Buffertfördröjning Country/Region Land/region (preferred) (förvald) (default) (standard) (safe) (säker) Driver Setup Drivrutinsinställningar My Profile Min profil Musician's Profile Musikprofil Alias/Name Alias/Namn Instrument Instrument Country Land City Stad Skill Färdighetsnivå User Interface Användargränssnitt Meter Style Meterstil Mixer Rows Mixerrader Audio Alerts Ljudvarningar Audio/Network Setup Ljud och nätverksinställningar Audio Device Ljudenhet Jitter Buffer Jitterbuffert Auto Automatiskt Local Lokalt Server Server Size Nivå kbps kbps Custom Directories: Anpassad kataloger: Input Boost Ingångsförstärkning Feedback Protection Rundgångsskydd Enable Aktivera Input Balance Ingångsbalans Pan Panorera Center Mitten Misc Blandade inställningar Audio Channels Ljudkanaler Audio Quality Ljudkvalitet Measurements Mätningar Advanced Setup Avancerade inställningar Custom Central Server Address: Anpassad katalogserveradress: New Client Level Ny klientnivå Skin Skal Language Språk % % Local Jitter Buffer Lokal jitterbuffert Display Channel Levels Visa kanalnivåer Custom Directory Server Address: Egen katalogserveradress: Audio Stream Rate Ljudströmshastighet val val Ping Time Pingtid Overall Delay Total fördröjning CConnectDlg Server List Serverlista The Connection Setup window shows a list of available servers. Server operators can optionally list their servers by music genre. Use the List dropdown to select a genre, click on the server you want to join and press the Connect button to connect to it. Alternatively, double click on on the server name. Permanent servers (those that have been listed for longer than 48 hours) are shown in bold. Inställningsfönstret visar en lista över tillgängliga servrar. Serveroperatörer kan valfritt lista sina servrar efter musikgenre. Använd rullgardinsmenyn Lista för att välja en genre, klicka på servern du vill gå med i och tryck på Anslutsknappen för att ansluta till den. Alternativt kan du dubbelklicka på servernamnet. Permanenta servrar (de som har listats längre än 48 timmar) visas med fet stil. Directory Katalog Shows the servers listed by the selected directory. You can add custom directories in Advanced Settings. Visar servrarna listade av den valda katalogen. Du kan lägga till anpassade kataloger i Avancerade inställningar. Directory combo box Kombineringsknapp för kataloger Filters the server list by the given text. Note that the filter is case insensitive. A single # character will filter for those servers with at least one person connected. Filtrerar serverlistan efter den givna texten. Observera att filtret är skiftlägesokänsligt. Ett enda # tecken kommer att filtrera för de servrar med minst en person ansluten. Uncheck to collapse the server list to show just the server details. Check to show everyone on the servers. Avmarkera för att komprimera serverlistan för att bara visa serverdetaljerna. Markera för att visa alla på servrarna. The Connection Setup window lists the available servers registered with the selected directory. Use the Directory dropdown to change the directory, find the server you want to join in the server list, click on it, and then click the Connect button to connect. Alternatively, double click on the server name to connect. Fönstret Connection Setup listar tillgängliga servrar som är registrerade med den valda katalogen. Använd rullgardinsmenyn Katalog för att ändra katalogen, hitta den server du vill ansluta till i serverlistan, klicka på den och klicka sedan på knappen Anslut för att ansluta. Alternativt kan du dubbelklicka på servernamnet för att ansluta. Permanent servers (those that have been listed for longer than 48 hours) are shown in bold. Permanenta servrar (de som har varit listade i mer än 48 timmar) visas i fet stil. You can add custom directories in Advanced Settings. Du kan lägga till anpassade kataloger i Avancerade inställningar. Server list view Serverlista Server Address Serveradress If you know the server address, you can connect to it using the Server name/Address field. An optional port number can be added after the server address using a colon as a separator, e.g. %1. The field will also show a list of the most recently used server addresses. Holds the current server address. It also stores old addresses in the combo box list. If you know the IP address or URL of a server, you can connect to it using the Server name/Address field. An optional port number can be added after the IP address or URL using a colon as a separator, e.g. example.org: Om du känner till en servers IP-adress eller URL kan du ansluta till den i fältet Servernamn/adress. Ett valfritt portnummer kan läggas till efter IP-adressen eller URL:en med ett kolon som separator, t.ex. exempel.org: . The field will also show a list of the most recently used server addresses. . Fältet visar också en lista över de senast använda serveradresserna. Server address edit box Serveradressens redigeringsruta Holds the current server IP address or URL. It also stores old URLs in the combo box list. Visar den aktuella serverns IP-adress eller URL. Det lagrar också gamla URL:er i listan med kombinationsrutor. Server List Selection Val av server Selects the server list to be shown. Väljer server som ska visas. Server list selection combo box Kombobox för val av serverlista Filter Filter The server list is filtered by the given text. Note that the filter is case insensitive. Serverlistan filtreras av den givna texten. Observera att filtret är känsligt för stora och små bokstäver. Filter edit box Redigeringsrutan för filtrering Show All Musicians Visa alla musiker If you check this check box, the musicians of all servers are shown. If you uncheck the check box, all list view items are collapsed. Om du markerar den här kryssrutan visas musikerna på alla servrar. Om du avmarkerar kryssrutan minimeras alla listvyer. Show all musicians check box Klickruta för att visa alla musiker If you know the IP address or URL of a server, you can connect to it using the Server name/Address field. An optional port number can be added after the IP address or URL using a colon as a separator, e.g. %1. The field will also show a list of the most recently used server addresses. Om du känner till en servers IP-adress eller URL kan du ansluta till den i fältet Servernamn/adress. Ett valfritt portnummer kan läggas till efter IP-adressen eller URL:en med ett kolon som separator, t.ex. %1. Fältet visar också en lista över de senast använda serveradresserna. Filter text, or # for occupied servers Filtrera text eller använd # för att se servrar med användare Type # for occupied servers Skriv # för upptagna servrar CConnectDlgBase Connection Setup Anslutningsinställning List Lista Directory Katalog Filter Filter Show All Musicians Visa alla musiker Server Name Servernamn Ping Time Pingtid Musicians Musiker Location Plats Server Address Serveradress Server Name/Address Servernamn/ipadress (:port) C&ancel Av&bryt &Connect &Anslut CHelpMenu &Help &Hjälp Getting &Started... Komma &igång... Software &Manual... &Manual... What's &This &Vad är detta &About Jamulus... &Om Jamulus... About &Qt... Om &Qt... &About... &Om... About Qt Om Qt CLanguageComboBox Restart Required Omstart krävs Please restart the application for the language change to take effect. Starta om applikationen för att språkändringen ska träda i kraft. CLicenceDlg I &agree to the above licence terms Jag &accepterar ovanstående licensvillkor This server requires you accept conditions before you can join. Please read these in the chat window. Denna server kräver att du accepterar villkoren innan du kan gå med. Läs dem i chattfönstret. I have read the conditions and &agree. Jag har &läst villkoren och håller med. Accept Acceptera Decline Neka By connecting to this server and agreeing to this notice, you agree to the following: Genom att ansluta till denna server och godkänna detta meddelande, samtycker du till följande: You agree that all data, sounds, or other works transmitted to this server are owned and created by you or your licensors, and that you are making these data, sounds or other works available via the following Creative Commons License (for more information on this license, see Du accepterar att all data, ljud eller andra verk som överförs till denna server ägs och skapas av dig eller dina licensgivare, och att du gör dessa data, ljud eller andra verk tillgängliga via följande Creative Commons-licens (för mer information om detta licens, se You are free to: Du är fri att: Share Dela copy and redistribute the material in any medium or format kopiera och omfördela materialet i vilket medium eller format som helst Adapt Anpssa remix, transform, and build upon the material remixa, transformera och bygga vidare på materialet The licensor cannot revoke these freedoms as long as you follow the license terms. Licensgivaren kan inte återkalla dessa friheter så länge du följer licensvillkoren. Under the following terms: Under följande villkor: Attribution Erkännande You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. Du måste ge lämplig kredit, ange en länk till licensen och ange om ändringar gjordes. Du kan göra det på något rimligt sätt, men inte på något sätt som antyder att licensgivaren godkänner dig eller din användning. NonCommercial Ickekommersiell You may not use the material for commercial purposes. Du får inte använda materialet för kommersiella ändamål. ShareAlike Dela lika If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original. Om du remixar, omvandlar eller bygger på materialet måste du distribuera dina bidrag under samma licens som originalet. No additional restrictions Inga ytterligare begränsningar You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. Du får inte tillämpa juridiska villkor eller tekniska åtgärder som lagligen begränsar andra från att göra något som licensen tillåter. CMultiColorLED Red Röd Yellow Gul Green Grön CMusProfDlg No Name Inget namn Musician Profile Musikprofil Alias/Name Alias/Namn Instrument Instrument Country Land City Stad Skill Färdighetsnivå &Close &Stäng None Ingen Beginner Nybörjare Intermediate Mellannivå Expert Expert Write your name or an alias here so the other musicians you want to play with know who you are. You may also add a picture of the instrument you play and a flag of the country you are located in. Your city and skill level playing your instrument may also be added. Skriv ditt namn eller ett alias här så att de andra musikerna du vill spela med vet vem du är. Du kan också lägga till en bild av instrumentet du spelar och en flagga för det land du befinner dig i. Din stad och din färdighetsnivå som spelar ditt instrument kan också läggas till. What you set here will appear at your fader on the mixer board when you are connected to a Jamulus server. This tag will also be shown at each client which is connected to the same server as you. Det du ställer in här visas på din fader på mixerkortet när du är ansluten till en Jamulus-server. Den här taggen kommer också att visas vid varje klient som är ansluten till samma server som du. Alias or name edit box Redigeringsruta för alias eller namn Instrument picture button Knapp för instrumentbild Country flag button Knapp för landsflagga City edit box Redigeringsruta för stad Skill level combo box Kombinationsruta för färdighetsnivå Drum Set Trumset Djembe Djembe Electric Guitar Elgitarr Acoustic Guitar Akustisk gitarr Bass Guitar Basgitarr Keyboard Klaviatur Synthesizer Synthesizer Grand Piano Flygel Accordion Dragspel Vocal Sång Microphone Mikrofon Harmonica Munspel Trumpet Trumpet Trombone Trombon French Horn Valthorn Tuba Tuba Saxophone Saxofon Clarinet Klarinett Flute Flöjt Violin Fiol Cello Cello Double Bass Kontrabas Recorder Inspelningsapparat Streamer Streamer Listener Lyssnare Guitar+Vocal Gitarr+Sång Keyboard+Vocal Klaviatur+Sång Bodhran Klaviatur+Sång Bassoon Fagott Oboe Oboe Harp Harpa Viola Altfiol Congas Congas Bongo Bongo Vocal Bass Sång (bas) Vocal Tenor Sång (tenor) Vocal Alto Sång (alt) Vocal Soprano Sång (sopran) Banjo Banjo Mandolin Mandolin Ukulele Ukulele Bass Ukulele Ukulele (bas) Vocal Baritone Sång (baryton) Vocal Lead Sång (melodistämma) Mountain Dulcimer Mountain Dulcimer Scratching Scratching Rapping Rapp CServerDlg Client List Klientlista The client list shows all clients which are currently connected to this server. Some information about the clients like the IP address and name are given for each connected client. Klientlistan visar alla klienter som för närvarande är anslutna till den här servern. Viss information om klienterna som IP-adressen och namnet ges för varje ansluten klient. Connected clients list view Lista över anslutna klienter Directory Type combo box Directory Katalog Select '%1' not to register your server with a directory. Select one of the genres to register with that directory. Or select '%1' and specify a Custom Directory address on the Options tab to register with a custom directory. For any value except '%1', this server registers with a directory so that a %2 user can select this server in the client connect dialog server list when they choose that directory. The registration of the server is renewed periodically to make sure that all servers in the connect dialog server list are actually available. When a value other than "%1" is chosen for Directory, this will show whether registration is successful. If the registration failed, please choose a different directory. No recording directory has been set or the value is not useable. Check the value in the Options tab. Recording has been switched off by the UI checkbox. Inspelningen har stängts av av kryssrutan UI. Recording has been switched off, either by the UI checkbox or SIGUSR2 being received. Inspelningen har stängts av, antingen genom att kryssrutan UI eller SIGUSR2 har tagits emot. If the recording directory is not useable, the problem will be displayed in place of the session directory. Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user %1 is running as). The current value of the main recording directory. The chosen value must exist and be writeable (allow creation of sub-directories by the user %1 is running as). Click the button to open the dialog that allows the main recording directory to be selected. Custom Directory address The Custom Directory address is the address of the directory holding the server list to which this server should be added. Server List Filename dialog push button Server List Filename Click the button to open the dialog that allows the server list persistence file name to be set. The user %1 is running as needs to be able to create the file name specified although it may already exist (it will get overwritten on save). Server List Filename text box (read-only) The current value of server list persistence file name. The user %1 is running as needs to be able to create the file name specified although it may already exist (it will get overwritten on save). Click the button to open the dialog that allows the server list persistence file name to be set. Clear the server list file name button Clear Server List Filename Click the button to clear the currently selected server list persistence file name. This will prevent persisting the server list until a new value is selected. Start Minimized on Operating System Start Starta Minimerad vid operativsystemets start If the start minimized on operating system start check box is checked, the server will be started when the operating system starts up and is automatically minimized to a system task bar icon. Om kryssrutan Starta minimerad på operativsystemets start är markerad kommer servern att startas när operativsystemet startar och minimeras automatiskt till en ikon för systemaktivitetsfält. Now a directory Show Creative Commons Licence Dialog Visa Creative Commons licensedialog If enabled, a Creative Commons BY-NC-SA 4.0 Licence dialog is shown each time a new user connects the server. Om den är aktiverad visas en Creative Commons BY-NC-SA 4.0 licensdialog varje gång en ny användare ansluter till servern. Make My Server Public Gör min server publik If the Make My Server Public check box is checked, this server registers itself at the directory server so that all users of the application can see the server in the connect dialog server list and connect to it. The registration of the server is renewed periodically to make sure that all servers in the connect dialog server list are actually available. Om kryssrutan Gör min server publik är markerad, registrerar den här servern sig själv på katalogservern så att alla användare av Jamulus kan se servern i anslutningsdialogens serverlista och ansluta till den. Registreringen av servern förnyas regelbundet för att se till att alla servrar i listan är tillgängliga. Register Server Status Serverstatus om servern är registrerad If the Make My Server Public check box is checked, this will show whether registration with the directory server is successful. If the registration failed, please choose another server list. Om kryssrutan Gör min server publik är markerad kommer detta att visa om registrering på katalogservern är gjord. Om registreringen misslyckades, välj en annan katalogserver. Custom Directory Server Address Anpassad katalogserveradress The custom directory server address is the IP address or URL of the directory server at which the server list of the connection dialog is managed. Den anpassade katalogserveradressen är IP-adressen eller URL:en för katalogservern där serverlistan hanteras. Directory server address line edit Ändra anpassad katalogserveradress Server List Selection Val av serverlista Selects the server list (i.e. directory server address) in which your server will be added. Väljer serverlistan dvs. den katalogserveradress där servern ska läggas till. Server list selection combo box Kombineringsknapp för val av serverlista Server Name Servernamn The server name identifies your server in the connect dialog server list at the clients. Servernamnet identifierar din server i anslutningsdialogens serverlista hos klienterna. Server name line edit Ändra servernamnet Location City Stad The city in which this server is located can be set here. If a city name is entered, it will be shown in the connect dialog server list at the clients. Här kan man visa serverns plats. Om en stad anges kommer det att visas i listan för anslutningsdialogserver på klienterna. City where the server is located line edit Ändra var servern befinner sig Location country Land The country in which this server is located can be set here. If a country is entered, it will be shown in the connect dialog server list at the clients. Landet där servern ligger kan skrivas in här. Om ett land anges kommer det att visas i listan för anslutningsdialogserver på klienterna. Country where the server is located combo box Kombineringsknapp för val av serverplacering Country/Region Land/region Set the country or region where the server is running. Clients will show this location in their connect dialog's server list. Ställ in det land eller den region där servern körs. Klienter kommer att visa denna plats i sin anslutningsdialogs serverlista. Combo box for location of this server Kombineringsknapp för val av serverplacering Display dialog to select recording directory button Knapp för att visa dialogruta för att välja inspelningskatalog Main Recording Directory Huvudinspelningskatalog Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user Jamulus is running as). Klicka på knappen för att öppna dialogrutan som gör det möjligt att välja den huvudsakliga inspelningskatalogen. Den valda platsen måste finnas och vara skrivbar (tillåta skapandet av underkataloger av den användare som Jamulus körs via.). Main recording directory text box (read-only) Textruta för huvudinspelningskatalog (skrivskyddad) The current value of the main recording directory. The chosen value must exist and be writeable (allow creation of sub-directories by the user Jamulus is running as). Click the button to open the dialog that allows the main recording directory to be selected. Det aktuella värdet för huvudinspelningskatalogen. Det valda värdet måste existera och vara skrivbart (tillåta skapandet av underkataloger av användaren som Jamulus körs av). Klicka på knappen för att öppna dialogrutan som gör det möjligt att välja huvudinspelningskatalogen. Clear the recording directory button Knappen för att rensa inspelningskatalogen Clear Recording Directory Rensa inspelningskatalogen Click the button to clear the currently selected recording directory. This will prevent recording until a new value is selected. Klicka på knappen för att rensa den valda inspelningskatalogen. Detta förhindrar inspelning tills ett ny plats valts. Checkbox to turn on or off server recording Knapp för att slå på eller av serverinspelning If the Register Server check box is checked, this will show whether registration with the directory server is successful. If the registration failed, please choose another server list. Om kryssrutan Registrera Server är markerad kommer detta att visa om registrering på katalogservern är gjord. Om registreringen misslyckades, välj en annan katalogserver. Enable Recorder Starta serverinspelning Checked when the recorder is enabled, otherwise unchecked. The recorder will run when a session is in progress, if (set up correctly and) enabled. Markerad när inspelaren är aktiverad, annars avmarkerad. Inspelaren kommer att köras när en session pågår, om (inställt korrekt och) aktiverat. Current session directory text box (read-only) Nuvarande inspelningskatalogtext (skrivskyddad) Current Session Directory Aktuell inspelningskatalog Enabled during recording and holds the current recording session directory. Disabled after recording or when the recorder is not enabled. Aktiverad under inspelning och har den aktuella inspelningskatalogen. Inaktiverad efter inspelning eller när inspelaren inte är aktiverad. Recorder status label Inspelningsstatusetikett Recorder Status Inspelningsstatus Displays the current status of the recorder. The following values are possible: Visar inspelarens aktuella status. Dessa värden är möjliga: No recording directory has been set or the value is not useable. Ingen inspelningskatalog har ställts in eller värdet kan inte användas. Recording has been switched off Inspelningen har stängts av by the UI checkbox genom kryssrutan , either by the UI checkbox or SIGUSR2 being received , antingen genom kryssrutan eller SIGUSR2 som tas emot There is no one connected to the server to record. Det är ingen ansluten till servern att spela in. The performers are being recorded to the specified session directory. Artisterna spelas in i den angivna sessionskatalogen. NOTE NOTERING If the recording directory is not useable, the problem will be displayed in place of the directory. Om inspelningskatalogen inte kan användas visas problemet istället för katalogen. Server welcome message edit box Serverns redigeringsruta för välkomstmeddelandet Server Welcome Message Serverns välkomstmeddelande A server welcome message text is displayed in the chat window if a musician enters the server. If no message is set, the server welcome is disabled. En välkomstmeddelandetext för servern visas i chattfönstret om en musiker kommer in på servern. Om inget meddelande är inställt är serverns välkomst inaktiverad. Language Språk Select the language to be used for the user interface. Välj det språk som ska användas för användargränssnittet. Language combo box Kombineringsknapp för språk Click the button to open the dialog that allows the main recording directory to be selected. The chosen value must exist and be writeable (allow creation of sub-directories by the user Jamulus is running as). Klicka på knappen för att öppna dialogrutan som gör det möjligt att välja den huvudsakliga inspelningskatalogen. Den valda platsen måste finnas och vara skrivbar (tillåta skapandet av underkataloger av den användare som Jamulus körs via). Custom Directory Anpassad katalog The custom directory is the IP address or URL of the directory server at which the server list of the connection dialog is managed. Den anpassade katalogen är IP-adressen eller URL:en för katalogservern där serverlistan hanteras. Custom Directory line edit Ändra anpassad katalog &Hide %1 server &Dölj %1-server &Show %1 server &Visa %1-server %1 server %1 is the name of the main application %1-server Type a message here. If no message is set, the server welcome is disabled. Skriv ett meddelande här. Om inget meddelande är inställt är serverns välkomst inaktiverad. %1 Server %1 is the name of the main application %1-server software upgrade available mjukvaruuppdatering tillgänglig Recorder failed to start. Please check available disk space and permissions and try again. Error: Inspelningen kunde inte starta. Kontrollera tillgängligt diskutrymme och behörigheter och försök igen. Fel: ERROR FEL Displays the current status of the recorder. Visar inspelarens aktuella status. Request new recording button Begär ny inspelningsknapp New Recording Ny inspelning During a recording session, the button can be used to start a new recording. Under en inspelningssession kan knappen användas för att starta en ny inspelning. E&xit &Avbryt &Hide &Göm server server &Open &Öppna server server Server Server &Window &Fönster Select Main Recording Directory Välj huvudinspelningskatalog Predefined Address Förvald adress Recording Inspelning Not recording Inspelning inte aktiv Not initialised Inte initierad Not enabled Inte aktiv Unregistered Oregistrerad None Ingen Not registered Bad address Felaktig adress Registration requested Registreringsförfrågan skickad Registration failed Registreringen misslyckades Check server version Kontrollera serverversionen Registered Registrerad Directory server list full Directory Server full Katalogservern är full Your server version is too old Din serverversion är för gammal Requirements not fulfilled Kraven uppfylls inte Unknown value %1 Unknown value Okänt värde CServerDlgBase Client IP:Port Klient IP:Port Name Namn Jitter Buffer Size Jitterbufferstorlek Channels Server Setup Serverinställningar List Lista Directory Katalog Location: Region Plats: Region Enable Jam Recorder Aktivera Jam-inspelning New Recording Ny inspelning Session Chat Window Welcome (HTML/CSS Supported) Välkomstmeddelande som visas i chattfönstret (HTML/CSS stöds) Options Alternativ Language Consider add "(Lang)" as a suffix to ensure that users who selected the wrong language find the correct button Språk Recording Directory Inspelningskatalog Custom Directory address Server List Filename Start Minimized on Windows Start Starta minimerad när Micosoft Windows startas Enable delay panning Aktivera fördröjningspanorering Show Creative Commons BY-NC-SA 4.0 Licence Dialog Visa Creative Commons BY-NC-SA 4.0 licensdialog Update check Uppdateringskontroll Make My Server Public (Register My Server in the Server List) Gör min server publik (registrera min server i serverlistan) Genre Genre STATUS STATUS Custom Directory Server Address: Anpassad katalogserveradress: My Server Info Min serverinformation Location: City Plats: Stad Location: Country Plats: Land Enable jam recorder Aktivera inspelning New recording Ny inspelning Recordings folder Inspelningsfolder TextLabelNameVersion TextLabelNameVersion CServerListManager Could not write to '%1' Kunde inte skriva till '%1' CSound Error requesting stream stop: $s Fel vid begäran av strömningsstopp: $s Error closing stream: $s Fel vid stängning av ström: $s The Jack server is not running. This software requires a Jack server to run. Normally if the Jack server is not running this software will automatically start the Jack server. It seems that this auto start has not worked. Try to start the Jack server manually. Jack-servern körs inte. Denna programvara kräver att en Jack-server körs. Normalt om Jack-servern inte kör startar programvaran automatiskt Jack-servern. Det verkar som om denna automatiska start inte har fungerat. Försök starta Jack-servern manuellt. The Jack server sample rate is different from the required one. The required sample rate is: Jackservers samplingsfrekvens skiljer sig från den önskade. Den nödvändiga bithastigheten är: You can use a tool like <i><a href="https://qjackctl.sourceforge.io">QJackCtl</a></i> to adjust the Jack server sample rate. Du kan använda ett verktyg som <i><a href="https://qjackctl.sourceforge.io">QJackCtl</a></i> för att justera Jack-serverns samplingsfrekvens. Make sure to set the Frames/Period to a low value like Se till att ställa in ramarna/perioden till ett så lågt värde som to achieve a low delay. för att uppnå en låg fördröjning. The Jack port registering failed. Registreringen av Jack-porten misslyckades. Cannot activate the Jack client. Kan inte aktivera Jack-klienten. The Jack server was shut down. This software requires a Jack server to run. Try to restart the software to solve the issue. Jack-servern stängdes av. Denna programvara kräver att en Jack-server körs. Försök starta om programvaran för att lösa problemet. CoreAudio input AudioHardwareGetProperty call failed. It seems that no sound card is available in the system. CoreAudio-ingång AudioHardwareGetProperty misslyckades. Det verkar som om det inte finns något ljudkort i systemet. CoreAudio output AudioHardwareGetProperty call failed. It seems that no sound card is available in the system. CoreAudio-utgång AudioHardwareGetProperty misslyckades. Det verkar som om det inte finns något ljudkort i systemet. The previously selected audio device is no longer available. The system default audio device will be selected instead. Den tidigare valda ljudenheten är inte längre tillgänglig. Systemets standardljudenhet har valts i stället. Current audio input device is no longer available. Nuvarande ljudingångsenhet är inte längre tillgänglig. Current system audio input device sample rate of %1 Hz is not supported. Please open the Audio-MIDI-Setup in Applications->Utilities and try to set a sample rate of %2 Hz. Nuvarande systemljudingångsenhetens samplingsfrekvens för %1 Hz stöds inte. Öppna Audio-MIDI-installationen i Applications->Utilities och försök att ställa in en samplingsfrekvens på %2 Hz. Current audio output device is no longer available. Nuvarande ljudutgångsenhet är inte längre tillgänglig. The current selected audio device is no longer present in the system. Vald ljudenhet är inte längre tillgänglig för programmet. The audio input device is no longer available. Vald ljudingång är inte längre tillgänglig. The audio output device is no longer available. Vald ljudutgång är inte längre tillgänglig. Current system audio output device sample rate of %1 Hz is not supported. Please open the Audio-MIDI-Setup in Applications->Utilities and try to set a sample rate of %2 Hz. Nuvarande systemljudutgångsenhetens samplingsfrekvens för %1 Hz stöds inte. Öppna Audio-MIDI-installationen i Applications->Utilities och försök att ställa in en samplingshastighet på %2 Hz. The audio input stream format for this audio device is not compatible with this software. Ljudingångsströmformatet för denna ljudenhet är inte kompatibelt med den här programvaran. The audio output stream format for this audio device is not compatible with this software. Ljudutmatningsströmformatet för denna ljudenhet är inte kompatibelt med den här programvaran. The buffer sizes of the current input and output audio device cannot be set to a common value. Please choose other input/output audio devices in your system settings. Buffertstorlekarna för den aktuella ingångs- och utgångsljudenheten kan inte ställas in på ett gemensamt värde. Välj andra input/output-ljudenheter i systeminställningarna. The audio driver could not be initialized. Ljuddrivrutinen kunde inte initialiseras. The audio device does not support the required sample rate. The required sample rate is: Ljudenheten stöder inte den valda samplingsfrekvensen. Den valda provhastigheten är: The audio device does not support setting the required sampling rate. This error can happen if you have an audio interface like the Roland UA-25EX where you set the sample rate with a hardware switch on the audio device. If this is the case, please change the sample rate to Ljudenheten stöder inte inställning av önskad samplingsfrekvens. Det här felet kan hända om du har ett ljudgränssnitt som Roland UA-25EX där du ställer in samtalstakten med en hårdvaruskontakt på ljudenheten. Om detta är fallet, ändra provhastigheten till Hz on the device and restart the Hz på enheten och starta om software. applikationen. The audio device does not support the required number of channels. The required number of channels for input and output is: Ljudenheten stöder inte det valda antalet kanaler. Det valda antalet kanaler för in- och utmatning är: Required audio sample format not available. Nödvändigt ljudformat är inte tillgängligt. The selected audio device is no longer present in the system. Please check your audio device. Den valda ljudenheten finns inte längre i systemet. Kontrollera din ljudenhet. Couldn't initialise the audio driver. Check if your audio hardware is plugged in and verify your driver settings. Det gick inte att initiera ljuddrivrutinen. Kontrollera om din ljudmaskinvara är ansluten och kontrollera dina drivrutinsinställningar. The selected audio device is incompatible since it doesn't support a sample rate of %1 Hz. Please select another device. Den valda ljudenheten är inkompatibel eftersom den inte stöder en samplingsfrekvens på %1 Hz. Välj en annan enhet. The current audio device configuration is incompatible because the sample rate couldn't be set to %2 Hz. Please check for a hardware switch or driver setting to set the sample rate manually and restart %1. Den aktuella ljudenhetskonfigurationen är inkompatibel eftersom samplingshastigheten inte kunde ställas in på %2 Hz. Kontrollera om det finns en hårdvarubrytare eller drivrutinsinställning för att ställa in samplingsfrekvensen manuellt och starta om %1. The selected audio device is incompatible since it doesn't support %1 in/out channels. Please select another device or configuration. Den valda ljudenheten är inkompatibel eftersom den inte stöder %1 in/ut-kanaler. Välj en annan enhet eller konfiguration. The selected audio device is incompatible since the required audio sample format isn't available. Please use another device. Den valda ljudenheten är inkompatibel eftersom det nödvändiga ljudsampelformatet inte är tillgängligt. Använd en annan enhet. No ASIO audio device driver found. Ingen ASIO-ljudenhetsdrivrutin hittades. Please install an ASIO driver before running %1. If you own a device with ASIO support, install its official ASIO driver. If not, you'll need to install a universal driver like ASIO4ALL. Installera en ASIO-drivrutin innan du kör %1. Om du äger en enhet med ASIO-stöd installerar du dess officiella ASIO-drivrutin. Om inte, måste du ladda ner och installera en universell drivrutin så som ASIO4ALL. Please install an ASIO driver before running %1. If you own a device with ASIO support, install its official ASIO driver. If not, you'll need to download and install a universal driver like ASIO4ALL. Installera en ASIO-drivrutin innan du kör %1. Om du äger en enhet med ASIO-stöd installerar du dess officiella ASIO-drivrutin. Om inte, måste du ladda ner och installera en universell drivrutin så som ASIO4ALL. No ASIO audio device (driver) found. Ingen ASIO-ljudenhet (drivrutin) hittades. The Programvaran software requires the low latency audio interface ASIO to work properly. This is not a standard Windows audio interface and therefore a special audio driver is required. Either your sound card has a native ASIO driver (which is recommended) or you might want to use alternative drivers like the ASIO4All driver. kräver det låga latentljudgränssnittet ASIO för att fungera korrekt. Detta är inte ett vanligt Windows ljudgränssnitt och därför krävs en speciell ljuddrivrutin. Antingen har ditt ljudkort en inbyggd ASIO-drivrutin (som rekommenderas) eller så kanske du vill använda alternativa drivrutiner som ASIO4All-drivrutinen. JACK couldn't be started automatically. Please start JACK manually and check for error messages. JACK kunde inte startas automatiskt. Starta JACK manuellt och leta efter felmeddelanden. JACK isn't running at a sample rate of <b>%1 Hz</b>. Please use a tool like <i><a href="https://qjackctl.sourceforge.io">QjackCtl</a></i> to set the the JACK sample rate to %1 Hz. JACK körs inte med en samplingshastighet på <b>%1 Hz</b>. Använd ett verktyg som <i><a href="https://qjackctl.sourceforge.io">QjackCtl</a></i> för att ställa in JACK-samplingsfrekvensen till %1 Hz. The JACK port registration failed. This is probably an error with JACK. Please stop %1 and JACK. Afterwards check if another program at a sample rate of %2 Hz can connect to JACK. JACK-portregistreringen misslyckades. Detta är förmodligen ett fel med JACK. Stoppa %1 och JACK. Kontrollera efteråt om ett annat program med en samplingshastighet på %2 Hz kan ansluta till JACK. The JACK port registration failed. This is probably an error with JACK. Please stop %1 and JACK. Afterwards, check if another MIDI program can connect to JACK. JACK-portregistreringen misslyckades. Detta är förmodligen ett fel med JACK. Stoppa %1 och JACK. Kontrollera efteråt om ett annat MIDI-program kan ansluta till JACK. Can't activate the JACK client. This is probably an error with JACK. Please check the JACK output. Det går inte att aktivera JACK-klienten. Detta är förmodligen ett fel med JACK. Kontrollera JACK-utgången. JACK was shut down. %1 requires JACK to run. Please restart %1 to start JACK again. JACK stängdes av. %1 kräver att JACK körs. Starta om %1 för att starta JACK igen. No sound card is available in your system. CoreAudio input AudioHardwareGetProperty call failed. Inget ljudkort är tillgängligt i ditt system. CoreAudio-ingång AudioHardwareGetProperty-anrop misslyckades. No sound card is available in the system. CoreAudio output AudioHardwareGetProperty call failed. Inget ljudkort finns tillgängligt i systemet. CoreAudio-ingång AudioHardwareGetProperty-anrop misslyckades. The currently selected audio device is no longer present. Please check your audio device. Den för närvarande valda ljudenheten finns inte längre. Kontrollera din ljudenhet. The audio input device is no longer available. Please check if your input device is connected correctly. Ljudinmatningsenheten är inte längre tillgänglig. Kontrollera om din ingångsenhet är korrekt ansluten. The sample rate on the current input device isn't %1 Hz and is therefore incompatible. Please select another device or try setting the sample rate to %1 Hz manually via Audio-MIDI-Setup (in Applications->Utilities). Samplingshastigheten på den aktuella inmatningsenheten är inte %1 Hz och är därför inkompatibel. Välj en annan enhet eller försök ställa in samplingsfrekvensen till %1 Hz manuellt via Audio-MIDI-inställning (i Program->Verktyg). The audio output device is no longer available. Please check if your output device is connected correctly. Ljudutgångsenheten är inte längre tillgänglig. Kontrollera om din utenhet är korrekt ansluten. The sample rate on the current output device isn't %1 Hz and is therefore incompatible. Please select another device or try setting the sample rate to %1 Hz manually via Audio-MIDI-Setup (in Applications->Utilities). Samplingshastigheten på den aktuella utenheten är inte %1 Hz och är därför inkompatibel. Välj en annan enhet eller försök ställa in samplingsfrekvensen till %1 Hz manuellt via Audio-MIDI-inställning (i Program->Verktyg). The stream format on the current input device isn't compatible with this software. Please select another device. Strömformatet på den aktuella inmatningsenheten är inte kompatibelt med denna programvara. Välj en annan enhet. The stream format on the current output device isn't compatible with %1. Please select another device. Strömformatet på den aktuella inmatningsenheten är inte kompatibelt med %1. Välj en annan enhet. The buffer sizes of the current input and output audio device can't be set to a common value. Please select different input/output devices in your system settings. Buffertstorlekarna för den aktuella in- och utgående ljudenheten kan inte ställas in på ett gemensamt värde. Välj olika in-/utgångsenheter i dina systeminställningar. CSoundBase Invalid device selection. Ogiltigt enhetsval. The audio driver properties have changed to a state which is incompatible with this software. The selected audio device could not be used because of the following error: Ljuddrivrutinens egenskaper har ändrats till ett tillstånd som inte är kompatibelt med den här programvaran. Den valda ljudenheten kunde inte användas på grund av följande fel: Please restart the software. Starta om programvaran. Close Stäng The selected audio device could not be used because of the following error: Den valda ljudenheten kunde inte användas på grund av följande fel: The previous driver will be selected. Den föregående drivrutinen kommer att väljas. The previously selected audio device is no longer available or the audio driver properties have changed to a state which is incompatible with this software. We now try to find a valid audio device. This new audio device might cause audio feedback. So, before connecting to a server, please check the audio device setting. Den tidigare valda ljudenheten är inte längre tillgänglig eller egenskaperna för ljuddrivrutinen har ändrats till ett tillstånd som inte fungerar med den här programvaran. Vi försöker nu hitta en giltig ljudenhet. Den här nya ljudenheten kan orsaka ljudåterkoppling så innan du ansluter till en server, kontrollera inställningen för ljudenheten. No usable Ingen användbar audio device (driver) found. ljudenhet (drivrutin) hittades. In the following there is a list of all available drivers with the associated error message: I det följande finns en lista över alla tillgängliga drivrutiner med tillhörande felmeddelande: Do you want to open the ASIO driver setups? Vill du öppna ASIO-drivrutinens inställningar? could not be started because of audio interface issues. kunde inte startas på grund av problem med ljudgränssnittet. Can't use the selected audio device because of the following error: %1 The previous driver will be selected. Kan inte använda den valda ljudenheten på grund av följande fel: %1 Den tidigare drivrutinen kommer att väljas. The previously selected audio device is no longer available or the driver has changed to an incompatible state. We'll attempt to find a valid audio device, but this new audio device may cause feedback. Before connecting to a server, please check your audio device settings. Den tidigare valda ljudenheten är inte längre tillgänglig eller så har drivrutinen ändrats till ett inkompatibelt tillstånd. Vi kommer att försöka hitta en giltig ljudenhet, men den här nya ljudenheten kan orsaka ljudåterkoppling. Kontrollera din ljudenhet innan du ansluter till en server inställningar. <b>%1 couldn't find a usable %2 audio device.</b><br><br> You may be able to fix errors in the driver settings. Do you want to open these settings now? No usable %1 audio device found. Ingen användbar %1 ljudenhet hittades. These are all the available drivers with error messages: Det här är alla tillgängliga drivrutiner med felmeddelanden: Do you want to open the ASIO driver setup to try changing your configuration to a working state? Vill du öppna ASIO-drivrutinen för att försöka ändra din konfiguration till ett fungerande tillstånd? Can't start %1. Please restart %1 and check/reconfigure your audio settings. Kan inte starta %1. Starta om %1 och kontrollera/konfigurera om dina ljudinställningar. QCoreApplication %1, Version %2 %1, Version %2 Internet Jam Session Software Internet Jam Session Software %1, Version %2 %1 is app name, %2 is version number %1, Version %2 Released under the GNU General Public License version 2 or later (GPLv2) Släppt under GNU General Public License version 2 eller senare (GPLv2) This program is free software; you can redistribute it and/or modify it under Detta program är fri programvara; du kan distribuera det och/eller modifiera det the terms of the GNU General Public License as published by the Free Software enligt villkoren i GNU General Public License som publicerats av Free Software Foundation; either version 2 of the License, or (at your option) any later version. Foundation; antingen version 2 av licensen eller (efter eget val) någon senare version. There is NO WARRANTY, to the extent permitted by law. Det finns INGEN GARANTI, i den utsträckning som lagen tillåter. Using the following libraries, resources or code snippets: Använda följande bibliotek, resurser eller kodavsnitt: Qt framework Qt framework Opus Interactive Audio Codec Opus Interactive Audio Codec Audio reverberation code by Perry R. Cook and Gary P. Scavone Ljudklangkod av Perry R. Cook och Gary P. Scavone Some pixmaps are from the Open Clip Art Library (OCAL) Vissa pixmaps är från Open Clip Art Library (OCAL) Flag icons by Mark James Flaggsymboler gjorda av Mark James Copyright (C) 2005-2022 The Jamulus Development Team Upphovsrätt (C) 2005-2021 The Jamulus Development Team Released under the GNU General Public License (GPL) Släppt under GNU General Public License (GPL) global A %1 upgrade is available: <a style='color:red;' href='https://jamulus.io/upgrade?progversion=%2'>go to details and downloads</a> En %1-uppgradering är tillgänglig: <a style='color:red;' href='https://jamulus.io/upgrade?progversion=%2'>gå till detaljer och nedladdningar</a> For more information use the "What's This" help (help menu, right mouse button or Shift+F1) För mer information använd hjälpen (hjälpmeny, höger musknapp eller Shift + F1) jamulus-3.9.1+dfsg/src/android/0000755000175000017500000000000014340334543015363 5ustar vimervimerjamulus-3.9.1+dfsg/src/android/androiddebug.cpp0000644000175000017500000000474214340334543020525 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2020-2022 * * Author(s): * Simon Tomlinson * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ const char* const applicationName = "Jamulus"; #ifdef ANDROIDDEBUG // Set in my myapp.pro file for android builds # include # include # include # include # include # include # include void myMessageHandler ( QtMsgType type, const QMessageLogContext& context, const QString& msg ) { QString report = msg; if ( context.file && !QString ( context.file ).isEmpty() ) { report += " in file "; report += QString ( context.file ); report += " line "; report += QString::number ( context.line ); } if ( context.function && !QString ( context.function ).isEmpty() ) { report += +" function "; report += QString ( context.function ); } const char* const local = report.toLocal8Bit().constData(); switch ( type ) { case QtDebugMsg: __android_log_write ( ANDROID_LOG_DEBUG, applicationName, local ); break; case QtInfoMsg: __android_log_write ( ANDROID_LOG_INFO, applicationName, local ); break; case QtWarningMsg: __android_log_write ( ANDROID_LOG_WARN, applicationName, local ); break; case QtCriticalMsg: __android_log_write ( ANDROID_LOG_ERROR, applicationName, local ); break; case QtFatalMsg: default: __android_log_write ( ANDROID_LOG_FATAL, applicationName, local ); abort(); break; } } #endif jamulus-3.9.1+dfsg/src/levelmeter.h0000644000175000017500000000663714340334543016274 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #include #include #include #include #include #include "util.h" #include "global.h" /* Definitions ****************************************************************/ #define NUM_LEDS_INCL_CLIP_LED ( NUM_STEPS_LED_BAR + 1 ) #define CLIP_IND_TIME_OUT_MS 20000 /* Classes ********************************************************************/ class CLevelMeter : public QWidget { Q_OBJECT public: enum ELevelMeterType { MT_BAR_NARROW, MT_BAR_WIDE, MT_LED_STRIPE, MT_LED_ROUND_SMALL, MT_LED_ROUND_BIG }; CLevelMeter ( QWidget* parent = nullptr ); virtual ~CLevelMeter(); void SetValue ( const double dValue ); void SetLevelMeterType ( const ELevelMeterType eNType ); protected: class cLED { public: enum ELightColor { RL_DISABLED, RL_BLACK, RL_GREEN, RL_YELLOW, RL_RED, RL_ROUND_SMALL_BLACK, RL_ROUND_SMALL_GREEN, RL_ROUND_SMALL_YELLOW, RL_ROUND_SMALL_RED, RL_ROUND_BIG_BLACK, RL_ROUND_BIG_GREEN, RL_ROUND_BIG_YELLOW, RL_ROUND_BIG_RED }; cLED ( QWidget* parent ); void SetColor ( const ELightColor eNewColor ); ELightColor GetColor() { return eCurLightColor; }; QLabel* GetLabelPointer() { return pLEDLabel; } protected: QPixmap BitmCubeLedBlack; QPixmap BitmCubeLedGreen; QPixmap BitmCubeLedYellow; QPixmap BitmCubeLedRed; QPixmap BitmCubeRoundSmallLedBlack; QPixmap BitmCubeRoundSmallLedGreen; QPixmap BitmCubeRoundSmallLedYellow; QPixmap BitmCubeRoundSmallLedRed; QPixmap BitmCubeRoundBigLedBlack; QPixmap BitmCubeRoundBigLedGreen; QPixmap BitmCubeRoundBigLedYellow; QPixmap BitmCubeRoundBigLedRed; ELightColor eCurLightColor; QLabel* pLEDLabel; }; virtual void mousePressEvent ( QMouseEvent* ) override { ClipReset(); } void SetBarMeterStyleAndClipStatus ( const ELevelMeterType eNType, const bool bIsClip ); CMinimumStackedLayout* pMinStackedLayout; ELevelMeterType eLevelMeterType; CVector vecpLEDs; QProgressBar* pBarMeter; QTimer TimerClip; public slots: void ClipReset(); }; jamulus-3.9.1+dfsg/src/serverrpc.cpp0000644000175000017500000002527714340334543016477 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2021-2022 * * Author(s): * dtinth * Christian Hoffmann * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include "serverrpc.h" CServerRpc::CServerRpc ( CServer* pServer, CRpcServer* pRpcServer, QObject* parent ) : QObject ( parent ) { // API doc already part of CClientRpc pRpcServer->HandleMethod ( "jamulus/getMode", [=] ( const QJsonObject& params, QJsonObject& response ) { QJsonObject result{ { "mode", "server" } }; response["result"] = result; Q_UNUSED ( params ); } ); /// @rpc_method jamulusserver/getRecorderStatus /// @brief Returns the recorder state. /// @param {object} params - No parameters (empty object). /// @result {boolean} result.initialised - True if the recorder is initialised. /// @result {string} result.errorMessage - The recorder error message, if any. /// @result {boolean} result.enabled - True if the recorder is enabled. /// @result {string} result.recordingDirectory - The recorder recording directory. pRpcServer->HandleMethod ( "jamulusserver/getRecorderStatus", [=] ( const QJsonObject& params, QJsonObject& response ) { QJsonObject result{ { "initialised", pServer->GetRecorderInitialised() }, { "errorMessage", pServer->GetRecorderErrMsg() }, { "enabled", pServer->GetRecordingEnabled() }, { "recordingDirectory", pServer->GetRecordingDir() }, }; response["result"] = result; Q_UNUSED ( params ); } ); /// @rpc_method jamulusserver/getClients /// @brief Returns the list of connected clients along with details about them. /// @param {object} params - No parameters (empty object). /// @result {array} result.clients - The list of connected clients. /// @result {number} result.clients[*].id - The client’s channel id. /// @result {string} result.clients[*].address - The client’s address (ip:port). /// @result {string} result.clients[*].name - The client’s name. /// @result {number} result.clients[*].jitterBufferSize - The client’s jitter buffer size. /// @result {number} result.clients[*].channels - The number of audio channels of the client. pRpcServer->HandleMethod ( "jamulusserver/getClients", [=] ( const QJsonObject& params, QJsonObject& response ) { QJsonArray clients; CVector vecHostAddresses; CVector vecsName; CVector veciJitBufNumFrames; CVector veciNetwFrameSizeFact; pServer->GetConCliParam ( vecHostAddresses, vecsName, veciJitBufNumFrames, veciNetwFrameSizeFact ); // we assume that all vectors have the same length const int iNumChannels = vecHostAddresses.Size(); // fill list with connected clients for ( int i = 0; i < iNumChannels; i++ ) { if ( vecHostAddresses[i].InetAddr == QHostAddress ( static_cast ( 0 ) ) ) { continue; } QJsonObject client{ { "id", i }, { "address", vecHostAddresses[i].toString ( CHostAddress::SM_IP_PORT ) }, { "name", vecsName[i] }, { "jitterBufferSize", veciJitBufNumFrames[i] }, { "channels", pServer->GetClientNumAudioChannels ( i ) }, }; clients.append ( client ); } // create result object QJsonObject result{ { "clients", clients }, }; response["result"] = result; Q_UNUSED ( params ); } ); /// @rpc_method jamulusserver/getServerProfile /// @brief Returns the server registration profile and status. /// @param {object} params - No parameters (empty object). /// @result {string} result.name - The server name. /// @result {string} result.city - The server city. /// @result {number} result.countryId - The server country ID (see QLocale::Country). /// @result {string} result.welcomeMessage - The server welcome message. /// @result {string} result.directoryServer - The directory server to which this server requested registration, or blank if none. /// @result {string} result.registrationStatus - The server registration status as string (see ESvrRegStatus and SerializeRegistrationStatus). pRpcServer->HandleMethod ( "jamulusserver/getServerProfile", [=] ( const QJsonObject& params, QJsonObject& response ) { QString dsName = ""; if ( AT_NONE != pServer->GetDirectoryType() ) dsName = NetworkUtil::GetDirectoryAddress ( pServer->GetDirectoryType(), pServer->GetDirectoryAddress() ); QJsonObject result{ { "name", pServer->GetServerName() }, { "city", pServer->GetServerCity() }, { "countryId", pServer->GetServerCountry() }, { "welcomeMessage", pServer->GetWelcomeMessage() }, { "directoryServer", dsName }, { "registrationStatus", SerializeRegistrationStatus ( pServer->GetSvrRegStatus() ) }, }; response["result"] = result; Q_UNUSED ( params ); } ); /// @rpc_method jamulusserver/setServerName /// @brief Sets the server name. /// @param {string} params.serverName - The new server name. /// @result {string} result - Always "ok". pRpcServer->HandleMethod ( "jamulusserver/setServerName", [=] ( const QJsonObject& params, QJsonObject& response ) { auto jsonServerName = params["serverName"]; if ( !jsonServerName.isString() ) { response["error"] = CRpcServer::CreateJsonRpcError ( CRpcServer::iErrInvalidParams, "Invalid params: serverName is not a string" ); return; } pServer->SetServerName ( jsonServerName.toString() ); response["result"] = "ok"; } ); /// @rpc_method jamulusserver/setWelcomeMessage /// @brief Sets the server welcome message. /// @param {string} params.welcomeMessage - The new welcome message. /// @result {string} result - Always "ok". pRpcServer->HandleMethod ( "jamulusserver/setWelcomeMessage", [=] ( const QJsonObject& params, QJsonObject& response ) { auto jsonWelcomeMessage = params["welcomeMessage"]; if ( !jsonWelcomeMessage.isString() ) { response["error"] = CRpcServer::CreateJsonRpcError ( CRpcServer::iErrInvalidParams, "Invalid params: welcomeMessage is not a string" ); return; } pServer->SetWelcomeMessage ( jsonWelcomeMessage.toString() ); response["result"] = "ok"; } ); /// @rpc_method jamulusserver/setRecordingDirectory /// @brief Sets the server recording directory. /// @param {string} params.recordingDirectory - The new recording directory. /// @result {string} result - Always "acknowledged". /// To check if the directory was changed, call `jamulusserver/getRecorderStatus` again. pRpcServer->HandleMethod ( "jamulusserver/setRecordingDirectory", [=] ( const QJsonObject& params, QJsonObject& response ) { auto jsonRecordingDirectory = params["recordingDirectory"]; if ( !jsonRecordingDirectory.isString() ) { response["error"] = CRpcServer::CreateJsonRpcError ( CRpcServer::iErrInvalidParams, "Invalid params: recordingDirectory is not a string" ); return; } pServer->SetRecordingDir ( jsonRecordingDirectory.toString() ); response["result"] = "acknowledged"; } ); /// @rpc_method jamulusserver/startRecording /// @brief Starts the server recording. /// @param {object} params - No parameters (empty object). /// @result {string} result - Always "acknowledged". /// To check if the recording was enabled, call `jamulusserver/getRecorderStatus` again. pRpcServer->HandleMethod ( "jamulusserver/startRecording", [=] ( const QJsonObject& params, QJsonObject& response ) { pServer->SetEnableRecording ( true ); response["result"] = "acknowledged"; Q_UNUSED ( params ); } ); /// @rpc_method jamulusserver/stopRecording /// @brief Stops the server recording. /// @param {object} params - No parameters (empty object). /// @result {string} result - Always "acknowledged". /// To check if the recording was disabled, call `jamulusserver/getRecorderStatus` again. pRpcServer->HandleMethod ( "jamulusserver/stopRecording", [=] ( const QJsonObject& params, QJsonObject& response ) { pServer->SetEnableRecording ( false ); response["result"] = "acknowledged"; Q_UNUSED ( params ); } ); /// @rpc_method jamulusserver/restartRecording /// @brief Restarts the recording into a new directory. /// @param {object} params - No parameters (empty object). /// @result {string} result - Always "acknowledged". /// To check if the recording was restarted or if there is any error, call `jamulusserver/getRecorderStatus` again. pRpcServer->HandleMethod ( "jamulusserver/restartRecording", [=] ( const QJsonObject& params, QJsonObject& response ) { pServer->RequestNewRecording(); response["result"] = "acknowledged"; Q_UNUSED ( params ); } ); } QJsonValue CServerRpc::SerializeRegistrationStatus ( ESvrRegStatus eSvrRegStatus ) { switch ( eSvrRegStatus ) { case SRS_NOT_REGISTERED: return "not_registered"; case SRS_BAD_ADDRESS: return "bad_address"; case SRS_REQUESTED: return "requested"; case SRS_TIME_OUT: return "time_out"; case SRS_UNKNOWN_RESP: return "unknown_resp"; case SRS_REGISTERED: return "registered"; case SRS_SERVER_LIST_FULL: return "directory_server_full"; case SRS_VERSION_TOO_OLD: return "server_version_too_old"; case SRS_NOT_FULFILL_REQUIREMENTS: return "requirements_not_fulfilled"; } return QString ( "unknown(%1)" ).arg ( eSvrRegStatus ); } jamulus-3.9.1+dfsg/src/chatdlg.h0000644000175000017500000000350414340334543015524 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "util.h" #include "ui_chatdlgbase.h" /* Classes ********************************************************************/ class CChatDlg : public CBaseDlg, private Ui_CChatDlgBase { Q_OBJECT public: CChatDlg ( QWidget* parent = nullptr ); void AddChatText ( QString strChatText ); public slots: void OnSendText(); void OnLocalInputTextTextChanged ( const QString& strNewText ); void OnClearChatHistory(); void OnAnchorClicked ( const QUrl& Url ); signals: void NewLocalInputText ( QString strNewText ); }; jamulus-3.9.1+dfsg/src/main.cpp0000644000175000017500000013665714340334543015415 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include #include #include #include "global.h" #ifndef HEADLESS # include # include # include "serverdlg.h" # ifndef SERVER_ONLY # include "clientdlg.h" # endif #endif #include "settings.h" #ifndef SERVER_ONLY # include "testbench.h" #endif #include "util.h" #ifdef ANDROID # include #endif #if defined( Q_OS_MACX ) # include "mac/activity.h" extern void qt_set_sequence_auto_mnemonic ( bool bEnable ); #endif #include #ifndef NO_JSON_RPC # include "rpcserver.h" # include "serverrpc.h" # ifndef SERVER_ONLY # include "clientrpc.h" # endif #endif // Implementation ************************************************************** int main ( int argc, char** argv ) { #if defined( Q_OS_MACX ) // Mnemonic keys are default disabled in Qt for MacOS. The following function enables them. // Qt will not show these with underline characters in the GUI on MacOS. (#1873) qt_set_sequence_auto_mnemonic ( true ); #endif QString strArgument; double rDbleArgument; QList CommandLineOptions; QList ServerOnlyOptions; QList ClientOnlyOptions; // initialize all flags and string which might be changed by command line // arguments #if ( defined( SERVER_BUNDLE ) && defined( Q_OS_MACX ) ) || defined( SERVER_ONLY ) // if we are on MacOS and we are building a server bundle or requested build with serveronly, start Jamulus in server mode bool bIsClient = false; qInfo() << "- Starting in server mode by default (due to compile time option)"; #else bool bIsClient = true; #endif bool bUseGUI = true; bool bStartMinimized = false; bool bShowComplRegConnList = false; bool bDisconnectAllClientsOnQuit = false; bool bUseDoubleSystemFrameSize = true; // default is 128 samples frame size bool bUseMultithreading = false; bool bShowAnalyzerConsole = false; bool bMuteStream = false; bool bMuteMeInPersonalMix = false; bool bDisableRecording = false; bool bDelayPan = false; bool bNoAutoJackConnect = false; bool bUseTranslation = true; bool bCustomPortNumberGiven = false; bool bEnableIPv6 = false; int iNumServerChannels = DEFAULT_USED_NUM_CHANNELS; quint16 iPortNumber = DEFAULT_PORT_NUMBER; int iJsonRpcPortNumber = INVALID_PORT; quint16 iQosNumber = DEFAULT_QOS_NUMBER; ELicenceType eLicenceType = LT_NO_LICENCE; QString strMIDISetup = ""; QString strConnOnStartupAddress = ""; QString strIniFileName = ""; QString strHTMLStatusFileName = ""; QString strLoggingFileName = ""; QString strRecordingDirName = ""; QString strDirectoryServer = ""; QString strServerListFileName = ""; QString strServerInfo = ""; QString strServerPublicIP = ""; QString strServerBindIP = ""; QString strServerListFilter = ""; QString strWelcomeMessage = ""; QString strClientName = ""; QString strJsonRpcSecretFileName = ""; #if defined( HEADLESS ) || defined( SERVER_ONLY ) Q_UNUSED ( bStartMinimized ) Q_UNUSED ( bUseTranslation ) Q_UNUSED ( bShowComplRegConnList ) Q_UNUSED ( bShowAnalyzerConsole ) Q_UNUSED ( bMuteStream ) #endif #if defined( SERVER_ONLY ) Q_UNUSED ( bMuteMeInPersonalMix ) Q_UNUSED ( bNoAutoJackConnect ) Q_UNUSED ( bCustomPortNumberGiven ) #endif #if !defined( HEADLESS ) && defined( _WIN32 ) if ( AttachConsole ( ATTACH_PARENT_PROCESS ) ) { freopen ( "CONOUT$", "w", stdout ); freopen ( "CONOUT$", "w", stderr ); } #endif // When adding new options, follow the same order as --help output // QT docu: argv()[0] is the program name, argv()[1] is the first // argument and argv()[argc()-1] is the last argument. // Start with first argument, therefore "i = 1" for ( int i = 1; i < argc; i++ ) { // Help (usage) flag --------------------------------------------------- if ( ( !strcmp ( argv[i], "--help" ) ) || ( !strcmp ( argv[i], "-h" ) ) || ( !strcmp ( argv[i], "-?" ) ) ) { const QString strHelp = UsageArguments ( argv ); std::cout << qUtf8Printable ( strHelp ); exit ( 0 ); } // Version number ------------------------------------------------------ if ( ( !strcmp ( argv[i], "--version" ) ) || ( !strcmp ( argv[i], "-v" ) ) ) { std::cout << qUtf8Printable ( GetVersionAndNameStr ( false ) ); exit ( 0 ); } // Common options: // Initialization file ------------------------------------------------- if ( GetStringArgument ( argc, argv, i, "-i", "--inifile", strArgument ) ) { strIniFileName = strArgument; qInfo() << qUtf8Printable ( QString ( "- initialization file name: %1" ).arg ( strIniFileName ) ); CommandLineOptions << "--inifile"; continue; } // Disable GUI flag ---------------------------------------------------- if ( GetFlagArgument ( argv, i, "-n", "--nogui" ) ) { bUseGUI = false; qInfo() << "- no GUI mode chosen"; CommandLineOptions << "--nogui"; continue; } // Port number --------------------------------------------------------- if ( GetNumericArgument ( argc, argv, i, "-p", "--port", 0, 65535, rDbleArgument ) ) { iPortNumber = static_cast ( rDbleArgument ); bCustomPortNumberGiven = true; qInfo() << qUtf8Printable ( QString ( "- selected port number: %1" ).arg ( iPortNumber ) ); CommandLineOptions << "--port"; continue; } // JSON-RPC port number ------------------------------------------------ if ( GetNumericArgument ( argc, argv, i, "--jsonrpcport", "--jsonrpcport", 0, 65535, rDbleArgument ) ) { iJsonRpcPortNumber = static_cast ( rDbleArgument ); qInfo() << qUtf8Printable ( QString ( "- JSON-RPC port number: %1" ).arg ( iJsonRpcPortNumber ) ); CommandLineOptions << "--jsonrpcport"; continue; } // JSON-RPC secret file name ------------------------------------------- if ( GetStringArgument ( argc, argv, i, "--jsonrpcsecretfile", "--jsonrpcsecretfile", strArgument ) ) { strJsonRpcSecretFileName = strArgument; qInfo() << qUtf8Printable ( QString ( "- JSON-RPC secret file: %1" ).arg ( strJsonRpcSecretFileName ) ); CommandLineOptions << "--jsonrpcsecretfile"; continue; } // Quality of Service -------------------------------------------------- if ( GetNumericArgument ( argc, argv, i, "-Q", "--qos", 0, 255, rDbleArgument ) ) { iQosNumber = static_cast ( rDbleArgument ); qInfo() << qUtf8Printable ( QString ( "- selected QoS value: %1" ).arg ( iQosNumber ) ); CommandLineOptions << "--qos"; continue; } // Disable translations ------------------------------------------------ if ( GetFlagArgument ( argv, i, "-t", "--notranslation" ) ) { bUseTranslation = false; qInfo() << "- translations disabled"; CommandLineOptions << "--notranslation"; continue; } // Enable IPv6 --------------------------------------------------------- if ( GetFlagArgument ( argv, i, "-6", "--enableipv6" ) ) { bEnableIPv6 = true; qInfo() << "- IPv6 enabled"; CommandLineOptions << "--enableipv6"; continue; } // Server only: // Disconnect all clients on quit -------------------------------------- if ( GetFlagArgument ( argv, i, "-d", "--discononquit" ) ) { bDisconnectAllClientsOnQuit = true; qInfo() << "- disconnect all clients on quit"; CommandLineOptions << "--discononquit"; ServerOnlyOptions << "--discononquit"; continue; } // Directory server ---------------------------------------------------- if ( GetStringArgument ( argc, argv, i, "-e", "--directoryserver", strArgument ) ) { strDirectoryServer = strArgument; qInfo() << qUtf8Printable ( QString ( "- directory server: %1" ).arg ( strDirectoryServer ) ); CommandLineOptions << "--directoryserver"; ServerOnlyOptions << "--directoryserver"; continue; } // Central server ** D E P R E C A T E D ** ---------------------------- if ( GetStringArgument ( argc, argv, i, "--centralserver", // no short form "--centralserver", strArgument ) ) { strDirectoryServer = strArgument; qInfo() << qUtf8Printable ( QString ( "- directory server: %1" ).arg ( strDirectoryServer ) ); CommandLineOptions << "--directoryserver"; ServerOnlyOptions << "--directoryserver"; continue; } // Directory file ------------------------------------------------------ if ( GetStringArgument ( argc, argv, i, "--directoryfile", // no short form "--directoryfile", strArgument ) ) { strServerListFileName = strArgument; qInfo() << qUtf8Printable ( QString ( "- directory server persistence file: %1" ).arg ( strServerListFileName ) ); CommandLineOptions << "--directoryfile"; ServerOnlyOptions << "--directoryfile"; continue; } // Server list filter -------------------------------------------------- if ( GetStringArgument ( argc, argv, i, "-f", "--listfilter", strArgument ) ) { strServerListFilter = strArgument; qInfo() << qUtf8Printable ( QString ( "- server list filter: %1" ).arg ( strServerListFilter ) ); CommandLineOptions << "--listfilter"; ServerOnlyOptions << "--listfilter"; continue; } // Use 64 samples frame size mode -------------------------------------- if ( GetFlagArgument ( argv, i, "-F", "--fastupdate" ) ) { bUseDoubleSystemFrameSize = false; // 64 samples frame size qInfo() << qUtf8Printable ( QString ( "- using %1 samples frame size mode" ).arg ( SYSTEM_FRAME_SIZE_SAMPLES ) ); CommandLineOptions << "--fastupdate"; ServerOnlyOptions << "--fastupdate"; continue; } // Use logging --------------------------------------------------------- if ( GetStringArgument ( argc, argv, i, "-l", "--log", strArgument ) ) { strLoggingFileName = strArgument; qInfo() << qUtf8Printable ( QString ( "- logging file name: %1" ).arg ( strLoggingFileName ) ); CommandLineOptions << "--log"; ServerOnlyOptions << "--log"; continue; } // Use licence flag ---------------------------------------------------- if ( GetFlagArgument ( argv, i, "-L", "--licence" ) ) { // LT_CREATIVECOMMONS is now used just to enable the pop up eLicenceType = LT_CREATIVECOMMONS; qInfo() << "- licence required"; CommandLineOptions << "--licence"; ServerOnlyOptions << "--licence"; continue; } // HTML status file ---------------------------------------------------- if ( GetStringArgument ( argc, argv, i, "-m", "--htmlstatus", strArgument ) ) { strHTMLStatusFileName = strArgument; qInfo() << qUtf8Printable ( QString ( "- HTML status file name: %1" ).arg ( strHTMLStatusFileName ) ); CommandLineOptions << "--htmlstatus"; ServerOnlyOptions << "--htmlstatus"; continue; } // Server info --------------------------------------------------------- if ( GetStringArgument ( argc, argv, i, "-o", "--serverinfo", strArgument ) ) { strServerInfo = strArgument; qInfo() << qUtf8Printable ( QString ( "- server info: %1" ).arg ( strServerInfo ) ); CommandLineOptions << "--serverinfo"; ServerOnlyOptions << "--serverinfo"; continue; } // Server Public IP ---------------------------------------------------- if ( GetStringArgument ( argc, argv, i, "--serverpublicip", // no short form "--serverpublicip", strArgument ) ) { strServerPublicIP = strArgument; qInfo() << qUtf8Printable ( QString ( "- server public IP: %1" ).arg ( strServerPublicIP ) ); CommandLineOptions << "--serverpublicip"; ServerOnlyOptions << "--serverpublicip"; continue; } // Enable delay panning on startup ------------------------------------- if ( GetFlagArgument ( argv, i, "-P", "--delaypan" ) ) { bDelayPan = true; qInfo() << "- starting with delay panning"; CommandLineOptions << "--delaypan"; ServerOnlyOptions << "--delaypan"; continue; } // Recording directory ------------------------------------------------- if ( GetStringArgument ( argc, argv, i, "-R", "--recording", strArgument ) ) { strRecordingDirName = strArgument; qInfo() << qUtf8Printable ( QString ( "- recording directory name: %1" ).arg ( strRecordingDirName ) ); CommandLineOptions << "--recording"; ServerOnlyOptions << "--recording"; continue; } // Disable recording on startup ---------------------------------------- if ( GetFlagArgument ( argv, i, "--norecord", // no short form "--norecord" ) ) { bDisableRecording = true; qInfo() << "- recording will not take place until enabled"; CommandLineOptions << "--norecord"; ServerOnlyOptions << "--norecord"; continue; } // Server mode flag ---------------------------------------------------- if ( GetFlagArgument ( argv, i, "-s", "--server" ) ) { bIsClient = false; qInfo() << "- server mode chosen"; CommandLineOptions << "--server"; ServerOnlyOptions << "--server"; continue; } // Server Bind IP -------------------------------------------------- if ( GetStringArgument ( argc, argv, i, "--serverbindip", // no short form "--serverbindip", strArgument ) ) { strServerBindIP = strArgument; qInfo() << qUtf8Printable ( QString ( "- server bind IP: %1" ).arg ( strServerBindIP ) ); CommandLineOptions << "--serverbindip"; ServerOnlyOptions << "--serverbindip"; continue; } // Use multithreading -------------------------------------------------- if ( GetFlagArgument ( argv, i, "-T", "--multithreading" ) ) { bUseMultithreading = true; qInfo() << "- using multithreading"; CommandLineOptions << "--multithreading"; ServerOnlyOptions << "--multithreading"; continue; } // Maximum number of channels ------------------------------------------ if ( GetNumericArgument ( argc, argv, i, "-u", "--numchannels", 1, MAX_NUM_CHANNELS, rDbleArgument ) ) { iNumServerChannels = static_cast ( rDbleArgument ); qInfo() << qUtf8Printable ( QString ( "- maximum number of channels: %1" ).arg ( iNumServerChannels ) ); CommandLineOptions << "--numchannels"; ServerOnlyOptions << "--numchannels"; continue; } // Server welcome message ---------------------------------------------- if ( GetStringArgument ( argc, argv, i, "-w", "--welcomemessage", strArgument ) ) { strWelcomeMessage = strArgument; qInfo() << qUtf8Printable ( QString ( "- welcome message: %1" ).arg ( strWelcomeMessage ) ); CommandLineOptions << "--welcomemessage"; ServerOnlyOptions << "--welcomemessage"; continue; } // Start minimized ----------------------------------------------------- if ( GetFlagArgument ( argv, i, "-z", "--startminimized" ) ) { bStartMinimized = true; qInfo() << "- start minimized enabled"; CommandLineOptions << "--startminimized"; ServerOnlyOptions << "--startminimized"; continue; } // Client only: // Connect on startup -------------------------------------------------- if ( GetStringArgument ( argc, argv, i, "-c", "--connect", strArgument ) ) { strConnOnStartupAddress = NetworkUtil::FixAddress ( strArgument ); qInfo() << qUtf8Printable ( QString ( "- connect on startup to address: %1" ).arg ( strConnOnStartupAddress ) ); CommandLineOptions << "--connect"; ClientOnlyOptions << "--connect"; continue; } // Disabling auto Jack connections ------------------------------------- if ( GetFlagArgument ( argv, i, "-j", "--nojackconnect" ) ) { bNoAutoJackConnect = true; qInfo() << "- disable auto Jack connections"; CommandLineOptions << "--nojackconnect"; ClientOnlyOptions << "--nojackconnect"; continue; } // Mute stream on startup ---------------------------------------------- if ( GetFlagArgument ( argv, i, "-M", "--mutestream" ) ) { bMuteStream = true; qInfo() << "- others on a server will not hear you (mutestream active)"; CommandLineOptions << "--mutestream"; ClientOnlyOptions << "--mutestream"; continue; } // For headless client mute my own signal in personal mix -------------- if ( GetFlagArgument ( argv, i, "--mutemyown", // no short form "--mutemyown" ) ) { bMuteMeInPersonalMix = true; qInfo() << "- you will not hear yourself in the server mix (mutemyown active)"; CommandLineOptions << "--mutemyown"; ClientOnlyOptions << "--mutemyown"; continue; } // Client Name --------------------------------------------------------- if ( GetStringArgument ( argc, argv, i, "--clientname", // no short form "--clientname", strArgument ) ) { strClientName = strArgument; qInfo() << qUtf8Printable ( QString ( "- client name: %1" ).arg ( strClientName ) ); CommandLineOptions << "--clientname"; ClientOnlyOptions << "--clientname"; continue; } // Controller MIDI channel --------------------------------------------- if ( GetStringArgument ( argc, argv, i, "--ctrlmidich", // no short form "--ctrlmidich", strArgument ) ) { strMIDISetup = strArgument; qInfo() << qUtf8Printable ( QString ( "- MIDI controller settings: %1" ).arg ( strMIDISetup ) ); CommandLineOptions << "--ctrlmidich"; ClientOnlyOptions << "--ctrlmidich"; continue; } // Undocumented: // Show all registered servers in the server list ---------------------- // Undocumented debugging command line argument: Show all registered // servers in the server list regardless if a ping to the server is // possible or not. if ( GetFlagArgument ( argv, i, "--showallservers", // no short form "--showallservers" ) ) { bShowComplRegConnList = true; qInfo() << "- show all registered servers in server list"; CommandLineOptions << "--showallservers"; ClientOnlyOptions << "--showallservers"; continue; } // Show analyzer console ----------------------------------------------- // Undocumented debugging command line argument: Show the analyzer // console to debug network buffer properties. if ( GetFlagArgument ( argv, i, "--showanalyzerconsole", // no short form "--showanalyzerconsole" ) ) { bShowAnalyzerConsole = true; qInfo() << "- show analyzer console"; CommandLineOptions << "--showanalyzerconsole"; ClientOnlyOptions << "--showanalyzerconsole"; continue; } // Clean up legacy fader settings -------------------------------------- // Undocumented temporary command line argument: Clean up fader settings // corrupted by bug #2680. Only needs to be used once (per file). if ( GetFlagArgument ( argv, i, "--cleanuplegacyfadersettings", // no short form "--cleanuplegacyfadersettings" ) ) { qInfo() << "- will clean up legacy fader settings on load"; CommandLineOptions << "--cleanuplegacyfadersettings"; ClientOnlyOptions << "--cleanuplegacyfadersettings"; continue; } // Unknown option ------------------------------------------------------ qCritical() << qUtf8Printable ( QString ( "%1: Unknown option '%2' -- use '--help' for help" ).arg ( argv[0] ).arg ( argv[i] ) ); // clicking on the Mac application bundle, the actual application // is called with weird command line args -> do not exit on these #if !( defined( Q_OS_MACX ) ) exit ( 1 ); #endif } // Dependencies ------------------------------------------------------------ #ifdef HEADLESS if ( bUseGUI ) { bUseGUI = false; qWarning() << "No GUI support compiled. Running in headless mode."; } #endif if ( bIsClient ) #ifdef SERVER_ONLY { qCritical() << "Only --server mode is supported in this build."; exit ( 1 ); } #else // TODO create settings in default state, if loading from file do that next, then come back here to // override from command line options, then create client or server, letting them do the validation { if ( ServerOnlyOptions.size() != 0 ) { qCritical() << qUtf8Printable ( QString ( "%1: Server only option(s) '%2' used. Did you omit '--server'?" ) .arg ( argv[0] ) .arg ( ServerOnlyOptions.join ( ", " ) ) ); exit ( 1 ); } // mute my own signal in personal mix is only supported for headless mode if ( bUseGUI && bMuteMeInPersonalMix ) { bMuteMeInPersonalMix = false; qWarning() << "Mute my own signal in my personal mix is only supported in headless mode."; } // adjust default port number for client: use different default port than the server since // if the client is started before the server, the server would get a socket bind error if ( !bCustomPortNumberGiven ) { iPortNumber += 10; // increment by 10 qInfo() << qUtf8Printable ( QString ( "- allocated port number: %1" ).arg ( iPortNumber ) ); } } else #endif { if ( ClientOnlyOptions.size() != 0 ) { qCritical() << qUtf8Printable ( QString ( "%1: Client only option(s) '%2' used. See '--help' for help" ).arg ( argv[0] ).arg ( ClientOnlyOptions.join ( ", " ) ) ); exit ( 1 ); } #ifndef HEADLESS if ( bUseGUI ) { // by definition, when running with the GUI we always default to registering somewhere but // until the settings are loaded we do not know where, so we cannot be prescriptive here if ( !strServerListFileName.isEmpty() ) { qInfo() << "Note:" << "Server list persistence file will only take effect when running as a directory server."; } if ( !strServerListFilter.isEmpty() ) { qInfo() << "Note:" << "Server list filter will only take effect when running as a directory server."; } } else #endif { // the inifile is not supported for the headless server mode if ( !strIniFileName.isEmpty() ) { qWarning() << "No initialization file support in headless server mode."; strIniFileName = ""; } // therefore we know everything based on command line options if ( strDirectoryServer.compare ( "localhost", Qt::CaseInsensitive ) == 0 || strDirectoryServer.compare ( "127.0.0.1" ) == 0 ) { if ( !strServerListFileName.isEmpty() ) { QFileInfo serverListFileInfo ( strServerListFileName ); if ( !serverListFileInfo.exists() ) { QFile strServerListFile ( strServerListFileName ); if ( !strServerListFile.open ( QFile::OpenModeFlag::ReadWrite ) ) { qWarning() << qUtf8Printable ( QString ( "Cannot create %1 for reading and writing. Please check permissions." ).arg ( strServerListFileName ) ); strServerListFileName = ""; } } else if ( !serverListFileInfo.isFile() ) { qWarning() << qUtf8Printable ( QString ( "Server list file %1 must be a plain file. Please check the name." ).arg ( strServerListFileName ) ); strServerListFileName = ""; } else if ( !serverListFileInfo.isReadable() || !serverListFileInfo.isWritable() ) { qWarning() << qUtf8Printable ( QString ( "Server list file %1 must be readable and writeable. Please check the permissions." ) .arg ( strServerListFileName ) ); strServerListFileName = ""; } } if ( !strServerListFilter.isEmpty() ) { QStringList slWhitelistAddresses = strServerListFilter.split ( ";" ); for ( int iIdx = 0; iIdx < slWhitelistAddresses.size(); iIdx++ ) { // check for special case: [version] if ( ( slWhitelistAddresses.at ( iIdx ).length() > 2 ) && ( slWhitelistAddresses.at ( iIdx ).left ( 1 ) == "[" ) && ( slWhitelistAddresses.at ( iIdx ).right ( 1 ) == "]" ) ) { // Good case - it seems QVersionNumber isn't fussy } else if ( slWhitelistAddresses.at ( iIdx ).isEmpty() ) { qWarning() << "There is empty entry in the server list filter that will be ignored"; } else { QHostAddress InetAddr; if ( !InetAddr.setAddress ( slWhitelistAddresses.at ( iIdx ) ) ) { qWarning() << qUtf8Printable ( QString ( "%1 is not a valid server list filter entry. Only plain IP addresses are supported" ) .arg ( slWhitelistAddresses.at ( iIdx ) ) ); } } } } } else { if ( !strServerListFileName.isEmpty() ) { qWarning() << "Server list persistence file will only take effect when running as a directory server."; strServerListFileName = ""; } if ( !strServerListFilter.isEmpty() ) { qWarning() << "Server list filter will only take effect when running as a directory server."; strServerListFileName = ""; } } if ( strDirectoryServer.isEmpty() ) { if ( !strServerPublicIP.isEmpty() ) { qWarning() << "Server Public IP will only take effect when registering a server with a directory server."; strServerPublicIP = ""; } } else { if ( !strServerPublicIP.isEmpty() ) { QHostAddress InetAddr; if ( !InetAddr.setAddress ( strServerPublicIP ) ) { qWarning() << "Server Public IP is invalid. Only plain IP addresses are supported."; strServerPublicIP = ""; } } } } if ( !strServerBindIP.isEmpty() ) { QHostAddress InetAddr; if ( !InetAddr.setAddress ( strServerBindIP ) ) { qWarning() << "Server Bind IP is invalid. Only plain IP addresses are supported."; strServerBindIP = ""; } } } // Application/GUI setup --------------------------------------------------- // Application object #ifdef HEADLESS QCoreApplication* pApp = new QCoreApplication ( argc, argv ); #else # if defined( Q_OS_IOS ) bUseGUI = true; bIsClient = true; // Client only - TODO: maybe a switch in interface to change to server? // bUseMultithreading = true; QApplication* pApp = new QApplication ( argc, argv ); # else QCoreApplication* pApp = bUseGUI ? new QApplication ( argc, argv ) : new QCoreApplication ( argc, argv ); # endif #endif #ifdef ANDROID // special Android coded needed for record audio permission handling auto result = QtAndroid::checkPermission ( QString ( "android.permission.RECORD_AUDIO" ) ); if ( result == QtAndroid::PermissionResult::Denied ) { QtAndroid::PermissionResultMap resultHash = QtAndroid::requestPermissionsSync ( QStringList ( { "android.permission.RECORD_AUDIO" } ) ); if ( resultHash["android.permission.RECORD_AUDIO"] == QtAndroid::PermissionResult::Denied ) { return 0; } } #endif #ifdef _WIN32 // set application priority class -> high priority SetPriorityClass ( GetCurrentProcess(), HIGH_PRIORITY_CLASS ); // For accessible support we need to add a plugin to qt. The plugin has to // be located in the install directory of the software by the installer. // Here, we set the path to our application path. QDir ApplDir ( QApplication::applicationDirPath() ); pApp->addLibraryPath ( QString ( ApplDir.absolutePath() ) ); #endif #if defined( Q_OS_MACX ) // On OSX we need to declare an activity to ensure the process doesn't get // throttled by OS level Nap, Sleep, and Thread Priority systems. CActivity activity; activity.BeginActivity(); #endif // init resources Q_INIT_RESOURCE ( resources ); #ifndef SERVER_ONLY //### TEST: BEGIN ###// // activate the following line to activate the test bench, // CTestbench Testbench ( "127.0.0.1", DEFAULT_PORT_NUMBER ); //### TEST: END ###// #endif #ifdef NO_JSON_RPC if ( iJsonRpcPortNumber != INVALID_PORT || !strJsonRpcSecretFileName.isEmpty() ) { qWarning() << "No JSON-RPC support in this build."; } #else CRpcServer* pRpcServer = nullptr; if ( iJsonRpcPortNumber != INVALID_PORT ) { if ( strJsonRpcSecretFileName.isEmpty() ) { qCritical() << qUtf8Printable ( QString ( "- JSON-RPC: --jsonrpcsecretfile is required. Exiting." ) ); exit ( 1 ); } QFile qfJsonRpcSecretFile ( strJsonRpcSecretFileName ); if ( !qfJsonRpcSecretFile.open ( QFile::OpenModeFlag::ReadOnly ) ) { qCritical() << qUtf8Printable ( QString ( "- JSON-RPC: Unable to open secret file %1. Exiting." ).arg ( strJsonRpcSecretFileName ) ); exit ( 1 ); } QTextStream qtsJsonRpcSecretStream ( &qfJsonRpcSecretFile ); QString strJsonRpcSecret = qtsJsonRpcSecretStream.readLine(); if ( strJsonRpcSecret.length() < JSON_RPC_MINIMUM_SECRET_LENGTH ) { qCritical() << qUtf8Printable ( QString ( "JSON-RPC: Refusing to run with secret of length %1 (required: %2). Exiting." ) .arg ( strJsonRpcSecret.length() ) .arg ( JSON_RPC_MINIMUM_SECRET_LENGTH ) ); exit ( 1 ); } qWarning() << "- JSON-RPC: This interface is experimental and is subject to breaking changes even on patch versions " "(not subject to semantic versioning) during the initial phase."; pRpcServer = new CRpcServer ( pApp, iJsonRpcPortNumber, strJsonRpcSecret ); if ( !pRpcServer->Start() ) { qCritical() << qUtf8Printable ( QString ( "- JSON-RPC: Server failed to start. Exiting." ) ); exit ( 1 ); } } #endif try { #ifndef SERVER_ONLY if ( bIsClient ) { // Client: // actual client object CClient Client ( iPortNumber, iQosNumber, strConnOnStartupAddress, strMIDISetup, bNoAutoJackConnect, strClientName, bEnableIPv6, bMuteMeInPersonalMix ); // load settings from init-file (command line options override) CClientSettings Settings ( &Client, strIniFileName ); Settings.Load ( CommandLineOptions ); // load translation if ( bUseGUI && bUseTranslation ) { CLocale::LoadTranslation ( Settings.strLanguage, pApp ); CInstPictures::UpdateTableOnLanguageChange(); } # ifndef NO_JSON_RPC if ( pRpcServer ) { new CClientRpc ( &Client, pRpcServer, pRpcServer ); } # endif # ifndef HEADLESS if ( bUseGUI ) { // GUI object CClientDlg ClientDlg ( &Client, &Settings, strConnOnStartupAddress, strMIDISetup, bShowComplRegConnList, bShowAnalyzerConsole, bMuteStream, bEnableIPv6, nullptr ); // show dialog ClientDlg.show(); pApp->exec(); } else # endif { // only start application without using the GUI qInfo() << qUtf8Printable ( GetVersionAndNameStr ( false ) ); pApp->exec(); } } else #endif { // Server: // actual server object CServer Server ( iNumServerChannels, strLoggingFileName, strServerBindIP, iPortNumber, iQosNumber, strHTMLStatusFileName, strDirectoryServer, strServerListFileName, strServerInfo, strServerPublicIP, strServerListFilter, strWelcomeMessage, strRecordingDirName, bDisconnectAllClientsOnQuit, bUseDoubleSystemFrameSize, bUseMultithreading, bDisableRecording, bDelayPan, bEnableIPv6, eLicenceType ); #ifndef NO_JSON_RPC if ( pRpcServer ) { new CServerRpc ( &Server, pRpcServer, pRpcServer ); } #endif #ifndef HEADLESS if ( bUseGUI ) { // load settings from init-file (command line options override) CServerSettings Settings ( &Server, strIniFileName ); Settings.Load ( CommandLineOptions ); // load translation if ( bUseGUI && bUseTranslation ) { CLocale::LoadTranslation ( Settings.strLanguage, pApp ); } // GUI object for the server CServerDlg ServerDlg ( &Server, &Settings, bStartMinimized, nullptr ); // show dialog (if not the minimized flag is set) if ( !bStartMinimized ) { ServerDlg.show(); } pApp->exec(); } else #endif { // only start application without using the GUI qInfo() << qUtf8Printable ( GetVersionAndNameStr ( false ) ); // CServerListManager defaults to AT_NONE, so need to switch if // strDirectoryServer is wanted if ( !strDirectoryServer.isEmpty() ) { Server.SetDirectoryType ( AT_CUSTOM ); } pApp->exec(); } } } catch ( const CGenErr& generr ) { // show generic error #ifndef HEADLESS if ( bUseGUI ) { QMessageBox::critical ( nullptr, APP_NAME, generr.GetErrorText(), "Quit", nullptr ); } else #endif { qCritical() << qUtf8Printable ( QString ( "%1: %2" ).arg ( APP_NAME ).arg ( generr.GetErrorText() ) ); exit ( 1 ); } } #if defined( Q_OS_MACX ) activity.EndActivity(); #endif return 0; } /******************************************************************************\ * Command Line Argument Parsing * \******************************************************************************/ QString UsageArguments ( char** argv ) { // clang-format off return QString ( "\n" "Usage: %1 [option] [option argument] ...\n" "\n" " -h, -?, --help display this help text and exit\n" " -v, --version display version information and exit\n" "\n" "Common options:\n" " -i, --inifile initialization file name\n" " (not supported for headless Server mode)\n" " -n, --nogui disable GUI (\"headless\")\n" " -p, --port set the local port number\n" " --jsonrpcport enable JSON-RPC server, set TCP port number\n" " (EXPERIMENTAL, APIs might still change;\n" " only accessible from localhost)\n" " --jsonrpcsecretfile\n" " path to a single-line file which contains a freely\n" " chosen secret to authenticate JSON-RPC users.\n" " -Q, --qos set the QoS value. Default is 128. Disable with 0\n" " (see the Jamulus website to enable QoS on Windows)\n" " -t, --notranslation disable translation (use English language)\n" " -6, --enableipv6 enable IPv6 addressing (IPv4 is always enabled)\n" "\n" "Server only:\n" " -d, --discononquit disconnect all Clients on quit\n" " -e, --directoryserver address of the directory Server with which to register\n" " (or 'localhost' to host a server list on this Server)\n" " --directoryfile Remember registered Servers even if the Directory is restarted. Directory Servers only.\n" " -f, --listfilter Server list whitelist filter. Format:\n" " [IP address 1];[IP address 2];[IP address 3]; ...\n" " -F, --fastupdate use 64 samples frame size mode\n" " -l, --log enable logging, set file name\n" " -L, --licence show an agreement window before users can connect\n" " -m, --htmlstatus enable HTML status file, set file name\n" " -o, --serverinfo registration info for this Server. Format:\n" " [name];[city];[country as two-letter ISO country code or Qt5 QLocale ID]\n" " --serverpublicip public IP address for this Server. Needed when\n" " registering with a server list hosted\n" " behind the same NAT\n" " -P, --delaypan start with delay panning enabled\n" " -R, --recording set server recording directory; server will record when a session is active by default\n" " --norecord set server not to record by default when recording is configured\n" " -s, --server start Server\n" " --serverbindip IP address the Server will bind to (rather than all)\n" " -T, --multithreading use multithreading to make better use of\n" " multi-core CPUs and support more Clients\n" " -u, --numchannels maximum number of channels\n" " -w, --welcomemessage welcome message to display on connect\n" " (string or filename, HTML supported)\n" " -z, --startminimized start minimizied\n" "\n" "Client only:\n" " -c, --connect connect to given Server address on startup\n" " -j, --nojackconnect disable auto JACK connections\n" " -M, --mutestream prevent others on a server from hearing what I play\n" " --mutemyown prevent me from hearing what I play in the server mix (headless only)\n" " --clientname Client name (window title and JACK client name)\n" " --ctrlmidich MIDI controller channel to listen\n" "\n" "Example: %1 -s --inifile myinifile.ini\n" "\n" "For more information and localized help see:\n" "https://jamulus.io/wiki/Command-Line-Options\n" ).arg( argv[0] ); // clang-format on } bool GetFlagArgument ( char** argv, int& i, QString strShortOpt, QString strLongOpt ) { if ( ( !strShortOpt.compare ( argv[i] ) ) || ( !strLongOpt.compare ( argv[i] ) ) ) { return true; } else { return false; } } bool GetStringArgument ( int argc, char** argv, int& i, QString strShortOpt, QString strLongOpt, QString& strArg ) { if ( ( !strShortOpt.compare ( argv[i] ) ) || ( !strLongOpt.compare ( argv[i] ) ) ) { if ( ++i >= argc ) { qCritical() << qUtf8Printable ( QString ( "%1: '%2' needs a string argument." ).arg ( argv[0] ).arg ( argv[i - 1] ) ); exit ( 1 ); } strArg = argv[i]; return true; } else { return false; } } bool GetNumericArgument ( int argc, char** argv, int& i, QString strShortOpt, QString strLongOpt, double rRangeStart, double rRangeStop, double& rValue ) { if ( ( !strShortOpt.compare ( argv[i] ) ) || ( !strLongOpt.compare ( argv[i] ) ) ) { QString errmsg = "%1: '%2' needs a numeric argument from '%3' to '%4'."; if ( ++i >= argc ) { qCritical() << qUtf8Printable ( errmsg.arg ( argv[0] ).arg ( argv[i - 1] ).arg ( rRangeStart ).arg ( rRangeStop ) ); exit ( 1 ); } char* p; rValue = strtod ( argv[i], &p ); if ( *p || ( rValue < rRangeStart ) || ( rValue > rRangeStop ) ) { qCritical() << qUtf8Printable ( errmsg.arg ( argv[0] ).arg ( argv[i - 1] ).arg ( rRangeStart ).arg ( rRangeStop ) ); exit ( 1 ); } return true; } else { return false; } } jamulus-3.9.1+dfsg/src/serverlogging.cpp0000644000175000017500000000537614340334543017337 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include "serverlogging.h" // Server logging -------------------------------------------------------------- CServerLogging::~CServerLogging() { // close logging file of open if ( File.isOpen() ) { File.close(); } } void CServerLogging::Start ( const QString& strLoggingFileName ) { // open file File.setFileName ( strLoggingFileName ); if ( File.open ( QIODevice::Append | QIODevice::Text ) ) { bDoLogging = true; } } void CServerLogging::AddNewConnection ( const QHostAddress& ClientInetAddr, const int iNumberOfConnectedClients ) { // logging of new connected channel const QString strLogStr = CurTimeDatetoLogString() + ", " + ClientInetAddr.toString() + ", connected (" + QString::number ( iNumberOfConnectedClients ) + ")"; qInfo() << qUtf8Printable ( strLogStr ); // on console *this << strLogStr; // in log file } void CServerLogging::AddServerStopped() { const QString strLogStr = CurTimeDatetoLogString() + ",, server idling " "-------------------------------------"; qInfo() << qUtf8Printable ( strLogStr ); // on console *this << strLogStr; // in log file } void CServerLogging::operator<< ( const QString& sNewStr ) { if ( bDoLogging ) { // append new line in logging file QTextStream out ( &File ); out << sNewStr << '\n'; out.flush(); } } QString CServerLogging::CurTimeDatetoLogString() { // time and date to string conversion const QDateTime curDateTime = QDateTime::currentDateTime(); // format date and time output according to "2006-09-30 11:38:08" return curDateTime.toString ( "yyyy-MM-dd HH:mm:ss" ); } jamulus-3.9.1+dfsg/src/chatdlgbase.ui0000644000175000017500000000375014340334543016550 0ustar vimervimer CChatDlgBase 0 0 435 405 0 0 Chat :/png/main/res/fronticon.png:/png/main/res/fronticon.png true false Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse false false &Send true true txvChatWindow jamulus-3.9.1+dfsg/src/chatdlg.cpp0000644000175000017500000001507514340334543016065 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include "chatdlg.h" /* Implementation *************************************************************/ CChatDlg::CChatDlg ( QWidget* parent ) : CBaseDlg ( parent, Qt::Window ) // use Qt::Window to get min/max window buttons { setupUi ( this ); // Add help text to controls ----------------------------------------------- // chat window txvChatWindow->setWhatsThis ( "" + tr ( "Chat Window" ) + ": " + tr ( "The chat window shows a history of all chat messages." ) ); txvChatWindow->setAccessibleName ( tr ( "Chat history" ) ); // input message text edtLocalInputText->setWhatsThis ( "" + tr ( "Input Message Text" ) + ": " + tr ( "Enter the chat message text in the edit box and press enter to send the " "message to the server which distributes the message to all connected " "clients. Your message will then show up in the chat window." ) ); edtLocalInputText->setAccessibleName ( tr ( "New chat text edit box" ) ); // clear chat window and edit line txvChatWindow->clear(); edtLocalInputText->clear(); // we do not want to show a cursor in the chat history txvChatWindow->setCursorWidth ( 0 ); // set a placeholder text to make sure where to type the message in (#384) edtLocalInputText->setPlaceholderText ( tr ( "Type a message here" ) ); // Menu ------------------------------------------------------------------- QMenuBar* pMenu = new QMenuBar ( this ); QMenu* pEditMenu = new QMenu ( tr ( "&Edit" ), this ); pEditMenu->addAction ( tr ( "Cl&ear Chat History" ), this, SLOT ( OnClearChatHistory() ), QKeySequence ( Qt::CTRL + Qt::Key_E ) ); pMenu->addMenu ( pEditMenu ); #if defined( Q_OS_IOS ) QAction* action = pMenu->addAction ( tr ( "&Close" ) ); connect ( action, SIGNAL ( triggered() ), this, SLOT ( close() ) ); #endif #if defined( ANDROID ) || defined( Q_OS_ANDROID ) pEditMenu->addAction ( tr ( "&Close" ), this, SLOT ( close() ), QKeySequence ( Qt::CTRL + Qt::Key_W ) ); #endif // Now tell the layout about the menu layout()->setMenuBar ( pMenu ); // Connections ------------------------------------------------------------- QObject::connect ( edtLocalInputText, &QLineEdit::textChanged, this, &CChatDlg::OnLocalInputTextTextChanged ); QObject::connect ( butSend, &QPushButton::clicked, this, &CChatDlg::OnSendText ); QObject::connect ( txvChatWindow, &QTextBrowser::anchorClicked, this, &CChatDlg::OnAnchorClicked ); } void CChatDlg::OnLocalInputTextTextChanged ( const QString& strNewText ) { // check and correct length if ( strNewText.length() > MAX_LEN_CHAT_TEXT ) { // text is too long, update control with shortened text edtLocalInputText->setText ( strNewText.left ( MAX_LEN_CHAT_TEXT ) ); } } void CChatDlg::OnSendText() { // send new text and clear line afterwards, do not send an empty message if ( !edtLocalInputText->text().isEmpty() ) { emit NewLocalInputText ( edtLocalInputText->text() ); edtLocalInputText->clear(); } } void CChatDlg::OnClearChatHistory() { // clear chat window txvChatWindow->clear(); } void CChatDlg::AddChatText ( QString strChatText ) { // notify accessibility plugin that text has changed QAccessible::updateAccessibility ( new QAccessibleValueChangeEvent ( txvChatWindow, strChatText ) ); // analyze strChatText to check if hyperlink (limit ourselves to http(s)://) but do not // replace the hyperlinks if any HTML code for a hyperlink was found (the user has done the HTML // coding hisself and we should not mess with that) if ( !strChatText.contains ( QRegularExpression ( "href\\s*=|src\\s*=" ) ) ) { // searches for all occurrences of http(s) and cuts until a space (\S matches any non-white-space // character and the + means that matches the previous element one or more times.) // This regex now contains three parts: // - https?://\\S+ matches as much non-whitespace as possible after the http:// or https://, // subject to the next two parts, which exclude terminating punctuation // - (??\\[\\]{}]) is a negative look-behind assertion that disallows the match // from ending with one of the characters !"'()+,.:;<=>?[]{} // - (??\\[\\]{}]) is a negative look-behind assertion that disallows the match // from ending with a ? followed by one of the characters !"'()+,.:;<=>?[]{} // These last two parts must be separate, as a look-behind assertion must be fixed length. #define PUNCT_NOEND_URL "[!\"'()+,.:;<=>?\\[\\]{}]" strChatText.replace ( QRegularExpression ( "(https?://\\S+(?\\1" ); } // add new text in chat window txvChatWindow->append ( strChatText ); } void CChatDlg::OnAnchorClicked ( const QUrl& Url ) { // only allow http(s) URLs to be opened in an external browser if ( Url.scheme() == QLatin1String ( "https" ) || Url.scheme() == QLatin1String ( "http" ) ) { if ( QMessageBox::question ( this, APP_NAME, tr ( "Do you want to open the link '%1' in your browser?" ).arg ( "" + Url.toString() + "" ), QMessageBox::Yes | QMessageBox::No ) == QMessageBox::Yes ) { QDesktopServices::openUrl ( Url ); } } } jamulus-3.9.1+dfsg/src/util.cpp0000644000175000017500000021353614340334543015436 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include "util.h" /* Implementation *************************************************************/ // Input level meter implementation -------------------------------------------- void CStereoSignalLevelMeter::Update ( const CVector& vecsAudio, const int iMonoBlockSizeSam, const bool bIsStereoIn ) { // Get maximum of current block // // Speed optimization: // - we only make use of the negative values and ignore the positive ones (since // int16 has range {-32768, 32767}) -> we do not need to call the fabs() function // - we only evaluate every third sample // // With these speed optimizations we might loose some information in // special cases but for the average music signals the following code // should give good results. short sMinLOrMono = 0; short sMinR = 0; if ( bIsStereoIn ) { // stereo in for ( int i = 0; i < 2 * iMonoBlockSizeSam; i += 6 ) // 2 * 3 = 6 -> stereo { // left (or mono) and right channel sMinLOrMono = std::min ( sMinLOrMono, vecsAudio[i] ); sMinR = std::min ( sMinR, vecsAudio[i + 1] ); } // in case of mono out use minimum of both channels if ( !bIsStereoOut ) { sMinLOrMono = std::min ( sMinLOrMono, sMinR ); } } else { // mono in for ( int i = 0; i < iMonoBlockSizeSam; i += 3 ) { sMinLOrMono = std::min ( sMinLOrMono, vecsAudio[i] ); } } // apply smoothing, if in stereo out mode, do this for two channels dCurLevelLOrMono = UpdateCurLevel ( dCurLevelLOrMono, -sMinLOrMono ); if ( bIsStereoOut ) { dCurLevelR = UpdateCurLevel ( dCurLevelR, -sMinR ); } } double CStereoSignalLevelMeter::UpdateCurLevel ( double dCurLevel, const double dMax ) { // decrease max with time if ( dCurLevel >= METER_FLY_BACK ) { dCurLevel *= dSmoothingFactor; } else { dCurLevel = 0; } // update current level -> only use maximum if ( dMax > dCurLevel ) { return dMax; } else { return dCurLevel; } } double CStereoSignalLevelMeter::CalcLogResultForMeter ( const double& dLinearLevel ) { const double dNormLevel = dLinearLevel / _MAXSHORT; // logarithmic measure double dLevelForMeterdB = -100000.0; // large negative value if ( dNormLevel > 0 ) { dLevelForMeterdB = 20.0 * log10 ( dNormLevel ); } // map to signal level meter (linear transformation of the input // level range to the level meter range) dLevelForMeterdB -= LOW_BOUND_SIG_METER; dLevelForMeterdB *= NUM_STEPS_LED_BAR / ( UPPER_BOUND_SIG_METER - LOW_BOUND_SIG_METER ); if ( dLevelForMeterdB < 0 ) { dLevelForMeterdB = 0; } return dLevelForMeterdB; } // CRC ------------------------------------------------------------------------- void CCRC::Reset() { // init state shift-register with ones. Set all registers to "1" with // bit-wise not operation iStateShiftReg = ~uint32_t ( 0 ); } void CCRC::AddByte ( const uint8_t byNewInput ) { for ( int i = 0; i < 8; i++ ) { // shift bits in shift-register for transition iStateShiftReg <<= 1; // take bit, which was shifted out of the register-size and place it // at the beginning (LSB) // (If condition is not satisfied, implicitly a "0" is added) if ( ( iStateShiftReg & iBitOutMask ) > 0 ) { iStateShiftReg |= 1; } // add new data bit to the LSB if ( ( byNewInput & ( 1 << ( 8 - i - 1 ) ) ) > 0 ) { iStateShiftReg ^= 1; } // add mask to shift-register if first bit is true if ( iStateShiftReg & 1 ) { iStateShiftReg ^= iPoly; } } } uint32_t CCRC::GetCRC() { // return inverted shift-register (1's complement) iStateShiftReg = ~iStateShiftReg; // remove bit which where shifted out of the shift-register frame return iStateShiftReg & ( iBitOutMask - 1 ); } /******************************************************************************\ * Audio Reverberation * \******************************************************************************/ /* The following code is based on "JCRev: John Chowning's reverberator class" by Perry R. Cook and Gary P. Scavone, 1995 - 2004 which is in "The Synthesis ToolKit in C++ (STK)" http://ccrma.stanford.edu/software/stk Original description: This class is derived from the CLM JCRev function, which is based on the use of networks of simple allpass and comb delay filters. This class implements three series allpass units, followed by four parallel comb filters, and two decorrelation delay lines in parallel at the output. */ void CAudioReverb::Init ( const EAudChanConf eNAudioChannelConf, const int iNStereoBlockSizeSam, const int iSampleRate, const float fT60 ) { // store parameters eAudioChannelConf = eNAudioChannelConf; iStereoBlockSizeSam = iNStereoBlockSizeSam; // delay lengths for 44100 Hz sample rate int lengths[9] = { 1116, 1356, 1422, 1617, 225, 341, 441, 211, 179 }; const float scaler = static_cast ( iSampleRate ) / 44100.0f; if ( scaler != 1.0f ) { for ( int i = 0; i < 9; i++ ) { int delay = static_cast ( floorf ( scaler * lengths[i] ) ); if ( ( delay & 1 ) == 0 ) { delay++; } while ( !isPrime ( delay ) ) { delay += 2; } lengths[i] = delay; } } for ( int i = 0; i < 3; i++ ) { allpassDelays[i].Init ( lengths[i + 4] ); } for ( int i = 0; i < 4; i++ ) { combDelays[i].Init ( lengths[i] ); combFilters[i].setPole ( 0.2f ); } setT60 ( fT60, iSampleRate ); outLeftDelay.Init ( lengths[7] ); outRightDelay.Init ( lengths[8] ); allpassCoefficient = 0.7f; Clear(); } bool CAudioReverb::isPrime ( const int number ) { /* Returns true if argument value is prime. Taken from "class Effect" in "STK abstract effects parent class". */ if ( number == 2 ) { return true; } if ( number & 1 ) { for ( int i = 3; i < static_cast ( sqrtf ( static_cast ( number ) ) ) + 1; i += 2 ) { if ( ( number % i ) == 0 ) { return false; } } return true; // prime } else { return false; // even } } void CAudioReverb::Clear() { // reset and clear all internal state allpassDelays[0].Reset ( 0 ); allpassDelays[1].Reset ( 0 ); allpassDelays[2].Reset ( 0 ); combDelays[0].Reset ( 0 ); combDelays[1].Reset ( 0 ); combDelays[2].Reset ( 0 ); combDelays[3].Reset ( 0 ); combFilters[0].Reset(); combFilters[1].Reset(); combFilters[2].Reset(); combFilters[3].Reset(); outRightDelay.Reset ( 0 ); outLeftDelay.Reset ( 0 ); } void CAudioReverb::setT60 ( const float fT60, const int iSampleRate ) { // set the reverberation T60 decay time for ( int i = 0; i < 4; i++ ) { combCoefficient[i] = powf ( 10.0f, static_cast ( -3.0f * combDelays[i].Size() / ( fT60 * iSampleRate ) ) ); } } void CAudioReverb::COnePole::setPole ( const float fPole ) { // calculate IIR filter coefficients based on the pole value fA = -fPole; fB = 1.0f - fPole; } float CAudioReverb::COnePole::Calc ( const float fIn ) { // calculate IIR filter fLastSample = fB * fIn - fA * fLastSample; return fLastSample; } void CAudioReverb::Process ( CVector& vecsStereoInOut, const bool bReverbOnLeftChan, const float fAttenuation ) { float fMixedInput, temp, temp0, temp1, temp2; for ( int i = 0; i < iStereoBlockSizeSam; i += 2 ) { // we sum up the stereo input channels (in case mono input is used, a zero // shall be input for the right channel) if ( eAudioChannelConf == CC_STEREO ) { fMixedInput = 0.5f * ( vecsStereoInOut[i] + vecsStereoInOut[i + 1] ); } else { if ( bReverbOnLeftChan ) { fMixedInput = vecsStereoInOut[i]; } else { fMixedInput = vecsStereoInOut[i + 1]; } } temp = allpassDelays[0].Get(); temp0 = allpassCoefficient * temp; temp0 += fMixedInput; allpassDelays[0].Add ( temp0 ); temp0 = -( allpassCoefficient * temp0 ) + temp; temp = allpassDelays[1].Get(); temp1 = allpassCoefficient * temp; temp1 += temp0; allpassDelays[1].Add ( temp1 ); temp1 = -( allpassCoefficient * temp1 ) + temp; temp = allpassDelays[2].Get(); temp2 = allpassCoefficient * temp; temp2 += temp1; allpassDelays[2].Add ( temp2 ); temp2 = -( allpassCoefficient * temp2 ) + temp; const float temp3 = temp2 + combFilters[0].Calc ( combCoefficient[0] * combDelays[0].Get() ); const float temp4 = temp2 + combFilters[1].Calc ( combCoefficient[1] * combDelays[1].Get() ); const float temp5 = temp2 + combFilters[2].Calc ( combCoefficient[2] * combDelays[2].Get() ); const float temp6 = temp2 + combFilters[3].Calc ( combCoefficient[3] * combDelays[3].Get() ); combDelays[0].Add ( temp3 ); combDelays[1].Add ( temp4 ); combDelays[2].Add ( temp5 ); combDelays[3].Add ( temp6 ); const float filtout = temp3 + temp4 + temp5 + temp6; outLeftDelay.Add ( filtout ); outRightDelay.Add ( filtout ); // inplace apply the attenuated reverb signal (for stereo always apply // reverberation effect on both channels) if ( ( eAudioChannelConf == CC_STEREO ) || bReverbOnLeftChan ) { vecsStereoInOut[i] = Float2Short ( ( 1.0f - fAttenuation ) * vecsStereoInOut[i] + 0.5f * fAttenuation * outLeftDelay.Get() ); } if ( ( eAudioChannelConf == CC_STEREO ) || !bReverbOnLeftChan ) { vecsStereoInOut[i + 1] = Float2Short ( ( 1.0f - fAttenuation ) * vecsStereoInOut[i + 1] + 0.5f * fAttenuation * outRightDelay.Get() ); } } } // CHighPrecisionTimer implementation ****************************************** #ifdef _WIN32 CHighPrecisionTimer::CHighPrecisionTimer ( const bool bNewUseDoubleSystemFrameSize ) : bUseDoubleSystemFrameSize ( bNewUseDoubleSystemFrameSize ) { // add some error checking, the high precision timer implementation only // supports 64 and 128 samples frame size at 48 kHz sampling rate # if ( SYSTEM_FRAME_SIZE_SAMPLES != 64 ) && ( DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES != 128 ) # error "Only system frame size of 64 and 128 samples is supported by this module" # endif # if ( SYSTEM_SAMPLE_RATE_HZ != 48000 ) # error "Only a system sample rate of 48 kHz is supported by this module" # endif // Since QT only supports a minimum timer resolution of 1 ms but for our // server we require a timer interval of 2.333 ms for 128 samples // frame size at 48 kHz sampling rate. // To support this interval, we use a timer with 2 ms resolution for 128 // samples frame size and 1 ms resolution for 64 samples frame size. // Then we fire the actual frame timer if the error to the actual // required interval is minimum. veciTimeOutIntervals.Init ( 3 ); // for 128 sample frame size at 48 kHz sampling rate with 2 ms timer resolution: // actual intervals: 0.0 2.666 5.333 8.0 // quantized to 2 ms: 0 2 6 8 (0) // for 64 sample frame size at 48 kHz sampling rate with 1 ms timer resolution: // actual intervals: 0.0 1.333 2.666 4.0 // quantized to 2 ms: 0 1 3 4 (0) veciTimeOutIntervals[0] = 0; veciTimeOutIntervals[1] = 1; veciTimeOutIntervals[2] = 0; Timer.setTimerType ( Qt::PreciseTimer ); // connect timer timeout signal QObject::connect ( &Timer, &QTimer::timeout, this, &CHighPrecisionTimer::OnTimer ); } void CHighPrecisionTimer::Start() { // reset position pointer and counter iCurPosInVector = 0; iIntervalCounter = 0; if ( bUseDoubleSystemFrameSize ) { // start internal timer with 2 ms resolution for 128 samples frame size Timer.start ( 2 ); } else { // start internal timer with 1 ms resolution for 64 samples frame size Timer.start ( 1 ); } } void CHighPrecisionTimer::Stop() { // stop timer Timer.stop(); } void CHighPrecisionTimer::OnTimer() { // check if maximum number of high precision timer intervals are // finished if ( veciTimeOutIntervals[iCurPosInVector] == iIntervalCounter ) { // reset interval counter iIntervalCounter = 0; // go to next position in vector, take care of wrap around iCurPosInVector++; if ( iCurPosInVector == veciTimeOutIntervals.Size() ) { iCurPosInVector = 0; } // minimum time error to actual required timer interval is reached, // emit signal for server emit timeout(); } else { // next high precision timer interval iIntervalCounter++; } } #else // Mac and Linux CHighPrecisionTimer::CHighPrecisionTimer ( const bool bUseDoubleSystemFrameSize ) : bRun ( false ) { // calculate delay in ns uint64_t iNsDelay; if ( bUseDoubleSystemFrameSize ) { iNsDelay = ( (uint64_t) DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES * 1000000000 ) / (uint64_t) SYSTEM_SAMPLE_RATE_HZ; // in ns } else { iNsDelay = ( (uint64_t) SYSTEM_FRAME_SIZE_SAMPLES * 1000000000 ) / (uint64_t) SYSTEM_SAMPLE_RATE_HZ; // in ns } # if defined( __APPLE__ ) || defined( __MACOSX ) // calculate delay in mach absolute time struct mach_timebase_info timeBaseInfo; mach_timebase_info ( &timeBaseInfo ); Delay = ( iNsDelay * (uint64_t) timeBaseInfo.denom ) / (uint64_t) timeBaseInfo.numer; # else // set delay Delay = iNsDelay; # endif } void CHighPrecisionTimer::Start() { // only start if not already running if ( !bRun ) { // set run flag bRun = true; // set initial end time # if defined( __APPLE__ ) || defined( __MACOSX ) NextEnd = mach_absolute_time() + Delay; # else clock_gettime ( CLOCK_MONOTONIC, &NextEnd ); NextEnd.tv_nsec += Delay; if ( NextEnd.tv_nsec >= 1000000000L ) { NextEnd.tv_sec++; NextEnd.tv_nsec -= 1000000000L; } # endif // start thread QThread::start ( QThread::TimeCriticalPriority ); } } void CHighPrecisionTimer::Stop() { // set flag so that thread can leave the main loop bRun = false; // give thread some time to terminate wait ( 5000 ); } void CHighPrecisionTimer::run() { // loop until the thread shall be terminated while ( bRun ) { // call processing routine by fireing signal //### TODO: BEGIN ###// // by emit a signal we leave the high priority thread -> maybe use some // other connection type to have something like a true callback, e.g. // "Qt::DirectConnection" -> Can this work? emit timeout(); //### TODO: END ###// // now wait until the next buffer shall be processed (we // use the "increment method" to make sure we do not introduce // a timing drift) # if defined( __APPLE__ ) || defined( __MACOSX ) mach_wait_until ( NextEnd ); NextEnd += Delay; # else clock_nanosleep ( CLOCK_MONOTONIC, TIMER_ABSTIME, &NextEnd, NULL ); NextEnd.tv_nsec += Delay; if ( NextEnd.tv_nsec >= 1000000000L ) { NextEnd.tv_sec++; NextEnd.tv_nsec -= 1000000000L; } # endif } } #endif /******************************************************************************\ * GUI Utilities * \******************************************************************************/ // About dialog ---------------------------------------------------------------- #ifndef HEADLESS CAboutDlg::CAboutDlg ( QWidget* parent ) : CBaseDlg ( parent ) { setupUi ( this ); // general description of software txvAbout->setText ( "

" + tr ( "This app enables musicians to perform real-time jam sessions " "over the internet." ) + "
" + tr ( "There is a server which collects " " the audio data from each client, mixes the audio data and sends the mix " " back to each client." ) + "

" "

" // GPL header text "This program is free software; you can redistribute it and/or modify " "it under the terms of the GNU General Public License as published by " "the Free Software Foundation; either version 2 of the License, or " "(at your option) any later version.
This program is distributed in " "the hope that it will be useful, but WITHOUT ANY WARRANTY; without " "even the implied warranty of MERCHANTABILITY or FITNESS FOR A " "PARTICULAR PURPOSE. See the GNU General Public License for more " "details.
You should have received a copy of the GNU General Public " "License along with his program; if not, write to the Free Software " "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 " "USA" "

" ); // libraries used by this compilation txvLibraries->setText ( tr ( "This app uses the following libraries, resources or code snippets:" ) + "

" + tr ( "Qt cross-platform application framework" ) + ", https://www.qt.io

" "

Opus Interactive Audio Codec" ", https://www.opus-codec.org

" # if defined( _WIN32 ) && !defined( WITH_JACK ) "

ASIO (Audio Stream I/O) SDK" ", https://www.steinberg.net/developers
" + "ASIO is a trademark and software of Steinberg Media Technologies GmbH

" # endif "

" + tr ( "Audio reverberation code by Perry R. Cook and Gary P. Scavone" ) + ", 1995 - 2021, " "The Synthesis ToolKit in C++ (STK)

" "

" + tr ( "Some pixmaps are from the" ) + " Open Clip Art Library (OCAL), " "https://openclipart.org

" "

" + tr ( "Flag icons by Mark James" ) + ", http://www.famfamfam.com

" + "

" + tr ( "Some sound samples are from" ) + " Freesound, " + "https://freesound.org

" ); // contributors list txvContributors->setText ( "

Volker Fischer (corrados)

" "

Peter L. Jones (pljones)

" "

Jonathan Baker-Bates (gilgongo)

" "

ann0see (ann0see)

" "

Daniele Masato (doloopuntil)

" "

Martin Schilde (geheimerEichkater)

" "

Simon Tomlinson (sthenos)

" "

Marc jr. Landolt (braindef)

" "

Olivier Humbert (trebmuh)

" "

Tarmo Johannes (tarmoj)

" "

mirabilos (mirabilos)

" "

Hector Martin (marcan)

" "

newlaurent62 (newlaurent62)

" "

AronVietti (AronVietti)

" "

Emlyn Bolton (emlynmac)

" "

Jos van den Oever (vandenoever)

" "

Tormod Volden (tormodvolden)

" "

Alberstein8 (Alberstein8)

" "

Gauthier Fleutot Östervall (fleutot)

" "

Tony Mountifield (softins)

" "

HPS (hselasky)

" "

Stanislas Michalak (stanislas-m)

" "

JP Cimalando (jpcima)

" "

Adam Sampson (atsampson)

" "

Jakob Jarmar (jarmar)

" "

Stefan Weil (stweil)

" "

Nils Brederlow (dingodoppelt)

" "

Sebastian Krzyszkowiak (dos1)

" "

Bryan Flamig (bflamig)

" "

Kris Raney (kraney)

" "

dszgit (dszgit)

" "

nefarius2001 (nefarius2001)

" "

jc-Rosichini (jc-Rosichini)

" "

Julian Santander (j-santander)

" "

chigkim (chigkim)

" "

Bodo (bomm)

" "

Christian Hoffmann (hoffie)

" "

jp8 (jp8)

" "

James (jdrage)

" "

ranfdev (ranfdev)

" "

bspeer (bspeer)

" "

Martin Passing (passing)

" "

DonC (dcorson-ticino-com)

" "

David Kastrup (dakhubgit)

" "

Jordan Lum (mulyaj)

" "

Noam Postavsky (npostavs)

" "

David Savinkoff (DavidSavinkoff)

" "

Johannes Brauers (JohannesBrx)

" "

Henk De Groot (henkdegroot)

" "

Ferenc Wágner (wferi)

" "

Martin Kaistra (djfun)

" "

Burkhard Volkemer (buv)

" "

Magnus Groß (vimpostor)

" "

Julien Taverna (jujudusud)

" "

Detlef Hennings (DetlefHennings)

" "

drummer1154 (drummer1154)

" "

helgeerbe (helgeerbe)

" "

Hk1020 (Hk1020)

" "

Jeroen van Veldhuizen (jeroenvv)

" "

Reinhard (reinhardwh)

" "

Stefan Menzel (menzels)

" "

Dau Huy Ngoc (ngocdh)

" "

Jiri Popek (jardous)

" "

Gary Wang (BLumia)

" "

RobyDati (RobyDati)

" "

Rob-NY (Rob-NY)

" "

Thai Pangsakulyanont (dtinth)

" "

Peter Goderie (pgScorpio)

" "
" + tr ( "For details on the contributions check out the %1" ) .arg ( "" + tr ( "Github Contributors list" ) + "." ) ); // translators txvTranslation->setText ( "

" + tr ( "Spanish" ) + "

" "

Daryl Hanlon (ignotus666)

" "

" + tr ( "French" ) + "

" "

Olivier Humbert (trebmuh)

" "

Julien Taverna (jujudusud)

" "

" + tr ( "Portuguese" ) + "

" "

Miguel de Matos (Snayler)

" "

Melcon Moraes (melcon)

" "

Manuela Silva (mansil)

" "

gbonaspetti (gbonaspetti)

" "

" + tr ( "Dutch" ) + "

" "

Jeroen Geertzen (jerogee)

" "

Henk De Groot (henkdegroot)

" "

" + tr ( "Italian" ) + "

" "

Giuseppe Sapienza (dzpex)

" "

" + tr ( "German" ) + "

" "

Volker Fischer (corrados)

" "

Roland Moschel (rolamos)

" "

" + tr ( "Polish" ) + "

" "

Martyna Danysz (Martyna27)

" "

Tomasz Bojczuk (SeeLook)

" "

" + tr ( "Swedish" ) + "

" "

Daniel (genesisproject2020)

" "

tygyh (tygyh)

" "

Allan Nordhøy (kingu)

" "

" + tr ( "Korean" ) + "

" "

Jung-Kyu Park (bagjunggyu)

" "

이정희 (MarongHappy)

" "

" + tr ( "Slovak" ) + "

" "

Jose Riha (jose1711)

" + "

" + tr ( "Simplified Chinese" ) + "

" "

Gary Wang (BLumia)

" + "

" + tr ( "Norwegian Bokmål" ) + "

" "

Allan Nordhøy (kingu)

" ); // set version number in about dialog lblVersion->setText ( GetVersionAndNameStr() ); // set window title setWindowTitle ( tr ( "About %1" ).arg ( APP_NAME ) ); } // Licence dialog -------------------------------------------------------------- CLicenceDlg::CLicenceDlg ( QWidget* parent ) : CBaseDlg ( parent ) { /* The licence dialog is structured as follows: - text box with the licence text on the top - check box: I &agree to the above licence terms - Accept button (disabled if check box not checked) - Decline button */ setWindowIcon ( QIcon ( QString::fromUtf8 ( ":/png/main/res/fronticon.png" ) ) ); QVBoxLayout* pLayout = new QVBoxLayout ( this ); QHBoxLayout* pSubLayout = new QHBoxLayout; QLabel* lblLicence = new QLabel ( tr ( "This server requires you accept conditions before you can join. Please read these in the chat window." ), this ); QCheckBox* chbAgree = new QCheckBox ( tr ( "I have read the conditions and &agree." ), this ); butAccept = new QPushButton ( tr ( "Accept" ), this ); QPushButton* butDecline = new QPushButton ( tr ( "Decline" ), this ); pSubLayout->addStretch(); pSubLayout->addWidget ( chbAgree ); pSubLayout->addWidget ( butAccept ); pSubLayout->addWidget ( butDecline ); pLayout->addWidget ( lblLicence ); pLayout->addLayout ( pSubLayout ); // set some properties butAccept->setEnabled ( false ); butAccept->setDefault ( true ); QObject::connect ( chbAgree, &QCheckBox::stateChanged, this, &CLicenceDlg::OnAgreeStateChanged ); QObject::connect ( butAccept, &QPushButton::clicked, this, &CLicenceDlg::accept ); QObject::connect ( butDecline, &QPushButton::clicked, this, &CLicenceDlg::reject ); } // Help menu ------------------------------------------------------------------- CHelpMenu::CHelpMenu ( const bool bIsClient, QWidget* parent ) : QMenu ( tr ( "&Help" ), parent ) { QAction* pAction; // standard help menu consists of about and what's this help if ( bIsClient ) { addAction ( tr ( "Getting &Started..." ), this, SLOT ( OnHelpClientGetStarted() ) ); addAction ( tr ( "Software &Manual..." ), this, SLOT ( OnHelpSoftwareMan() ) ); } else { addAction ( tr ( "Getting &Started..." ), this, SLOT ( OnHelpServerGetStarted() ) ); } addSeparator(); addAction ( tr ( "What's &This" ), this, SLOT ( OnHelpWhatsThis() ), QKeySequence ( Qt::SHIFT + Qt::Key_F1 ) ); addSeparator(); pAction = addAction ( tr ( "&About Jamulus..." ), this, SLOT ( OnHelpAbout() ) ); pAction->setMenuRole ( QAction::AboutRole ); // required for Mac pAction = addAction ( tr ( "About &Qt..." ), this, SLOT ( OnHelpAboutQt() ) ); pAction->setMenuRole ( QAction::AboutQtRole ); // required for Mac } // Language combo box ---------------------------------------------------------- CLanguageComboBox::CLanguageComboBox ( QWidget* parent ) : QComboBox ( parent ), iIdxSelectedLanguage ( INVALID_INDEX ) { QObject::connect ( this, static_cast ( &QComboBox::activated ), this, &CLanguageComboBox::OnLanguageActivated ); } void CLanguageComboBox::Init ( QString& strSelLanguage ) { // load available translations const QMap TranslMap = CLocale::GetAvailableTranslations(); QMapIterator MapIter ( TranslMap ); // add translations to the combobox list clear(); int iCnt = 0; int iIdxOfEnglishLanguage = 0; iIdxSelectedLanguage = INVALID_INDEX; while ( MapIter.hasNext() ) { MapIter.next(); addItem ( QLocale ( MapIter.key() ).nativeLanguageName() + " (" + MapIter.key() + ")", MapIter.key() ); // store the combo box index of the default english language if ( MapIter.key().compare ( "en" ) == 0 ) { iIdxOfEnglishLanguage = iCnt; } // if the selected language is found, store the combo box index if ( MapIter.key().compare ( strSelLanguage ) == 0 ) { iIdxSelectedLanguage = iCnt; } iCnt++; } // if the selected language was not found, use the english language if ( iIdxSelectedLanguage == INVALID_INDEX ) { strSelLanguage = "en"; iIdxSelectedLanguage = iIdxOfEnglishLanguage; } setCurrentIndex ( iIdxSelectedLanguage ); } void CLanguageComboBox::OnLanguageActivated ( int iLanguageIdx ) { // only update if the language selection is different from the current selected language if ( iIdxSelectedLanguage != iLanguageIdx ) { QMessageBox::information ( this, tr ( "Restart Required" ), tr ( "Please restart the application for the language change to take effect." ) ); emit LanguageChanged ( itemData ( iLanguageIdx ).toString() ); } } QSize CMinimumStackedLayout::sizeHint() const { // always use the size of the currently visible widget: if ( currentWidget() ) { return currentWidget()->sizeHint(); } return QStackedLayout::sizeHint(); } #endif /******************************************************************************\ * Other Classes * \******************************************************************************/ // Network utility functions --------------------------------------------------- bool NetworkUtil::ParseNetworkAddress ( QString strAddress, CHostAddress& HostAddress, bool bEnableIPv6 ) { QHostAddress InetAddr; unsigned int iNetPort = DEFAULT_PORT_NUMBER; // qInfo() << qUtf8Printable ( QString ( "Parsing network address %1" ).arg ( strAddress ) ); // init requested host address with invalid address first HostAddress = CHostAddress(); // Allow the following address formats: // [addr4or6] // [addr4or6]:port // addr4 // addr4:port // hostname // hostname:port // (where addr4or6 is a literal IPv4 or IPv6 address, and addr4 is a literal IPv4 address bool bLiteralAddr = false; QRegularExpression rx1 ( "^\\[([^]]*)\\](?::(\\d+))?$" ); // [addr4or6] or [addr4or6]:port QRegularExpression rx2 ( "^([^:]*)(?::(\\d+))?$" ); // addr4 or addr4:port or host or host:port QString strPort; QRegularExpressionMatch rx1match = rx1.match ( strAddress ); QRegularExpressionMatch rx2match = rx2.match ( strAddress ); // parse input address with rx1 and rx2 in turn, capturing address/host and port if ( rx1match.capturedStart() == 0 ) { // literal address within [] strAddress = rx1match.captured ( 1 ); strPort = rx1match.captured ( 2 ); bLiteralAddr = true; // don't allow hostname within [] } else if ( rx2match.capturedStart() == 0 ) { // hostname or IPv4 address strAddress = rx2match.captured ( 1 ); strPort = rx2match.captured ( 2 ); } else { // invalid format // qInfo() << qUtf8Printable ( QString ( "Invalid address format" ) ); return false; } if ( !strPort.isEmpty() ) { // a port number was given: extract port number iNetPort = strPort.toInt(); if ( iNetPort >= 65536 ) { // invalid port number // qInfo() << qUtf8Printable ( QString ( "Invalid port number specified" ) ); return false; } } // first try if this is an IP number an can directly applied to QHostAddress if ( InetAddr.setAddress ( strAddress ) ) { if ( !bEnableIPv6 && InetAddr.protocol() == QAbstractSocket::IPv6Protocol ) { // do not allow IPv6 addresses if not enabled // qInfo() << qUtf8Printable ( QString ( "IPv6 addresses disabled" ) ); return false; } } else { // it was no valid IP address. If literal required, return as invalid if ( bLiteralAddr ) { // qInfo() << qUtf8Printable ( QString ( "Invalid literal IP address" ) ); return false; // invalid address } // try to get host by name, assuming // that the string contains a valid host name string const QHostInfo HostInfo = QHostInfo::fromName ( strAddress ); if ( HostInfo.error() != QHostInfo::NoError ) { // qInfo() << qUtf8Printable ( QString ( "Invalid hostname" ) ); return false; // invalid address } bool bFoundAddr = false; foreach ( const QHostAddress HostAddr, HostInfo.addresses() ) { // qInfo() << qUtf8Printable ( QString ( "Resolved network address to %1 for proto %2" ) .arg ( HostAddr.toString() ) .arg ( // HostAddr.protocol() ) ); if ( HostAddr.protocol() == QAbstractSocket::IPv4Protocol || ( bEnableIPv6 && HostAddr.protocol() == QAbstractSocket::IPv6Protocol ) ) { InetAddr = HostAddr; bFoundAddr = true; break; } } if ( !bFoundAddr ) { // no valid address found // qInfo() << qUtf8Printable ( QString ( "No IP address found for hostname" ) ); return false; } } // qInfo() << qUtf8Printable ( QString ( "Parsed network address %1" ).arg ( InetAddr.toString() ) ); HostAddress = CHostAddress ( InetAddr, iNetPort ); return true; } CHostAddress NetworkUtil::GetLocalAddress() { QUdpSocket socket; // As we are using UDP, the connectToHost() does not generate any traffic at all. // We just require a socket which is pointed towards the Internet in // order to find out the IP of our own external interface: socket.connectToHost ( WELL_KNOWN_HOST, WELL_KNOWN_PORT ); if ( socket.waitForConnected ( IP_LOOKUP_TIMEOUT ) ) { return CHostAddress ( socket.localAddress(), 0 ); } else { qWarning() << "could not determine local IPv4 address:" << socket.errorString() << "- using localhost"; return CHostAddress ( QHostAddress::LocalHost, 0 ); } } CHostAddress NetworkUtil::GetLocalAddress6() { QUdpSocket socket; // As we are using UDP, the connectToHost() does not generate any traffic at all. // We just require a socket which is pointed towards the Internet in // order to find out the IP of our own external interface: socket.connectToHost ( WELL_KNOWN_HOST6, WELL_KNOWN_PORT ); if ( socket.waitForConnected ( IP_LOOKUP_TIMEOUT ) ) { return CHostAddress ( socket.localAddress(), 0 ); } else { qWarning() << "could not determine local IPv6 address:" << socket.errorString() << "- using localhost"; return CHostAddress ( QHostAddress::LocalHostIPv6, 0 ); } } QString NetworkUtil::GetDirectoryAddress ( const EDirectoryType eDirectoryType, const QString& strDirectoryAddress ) { switch ( eDirectoryType ) { case AT_CUSTOM: return strDirectoryAddress; case AT_ANY_GENRE2: return CENTSERV_ANY_GENRE2; case AT_ANY_GENRE3: return CENTSERV_ANY_GENRE3; case AT_GENRE_ROCK: return CENTSERV_GENRE_ROCK; case AT_GENRE_JAZZ: return CENTSERV_GENRE_JAZZ; case AT_GENRE_CLASSICAL_FOLK: return CENTSERV_GENRE_CLASSICAL_FOLK; case AT_GENRE_CHORAL: return CENTSERV_GENRE_CHORAL; default: return DEFAULT_SERVER_ADDRESS; // AT_DEFAULT } } QString NetworkUtil::FixAddress ( const QString& strAddress ) { // remove all spaces from the address string return strAddress.simplified().replace ( " ", "" ); } // Return whether the given HostAdress is within a private IP range // as per RFC 1918 & RFC 5735. bool NetworkUtil::IsPrivateNetworkIP ( const QHostAddress& qhAddr ) { // https://www.rfc-editor.org/rfc/rfc1918 // https://www.rfc-editor.org/rfc/rfc5735 static QList> addresses = { QPair ( QHostAddress ( "10.0.0.0" ), 8 ), QPair ( QHostAddress ( "127.0.0.0" ), 8 ), QPair ( QHostAddress ( "172.16.0.0" ), 12 ), QPair ( QHostAddress ( "192.168.0.0" ), 16 ), }; foreach ( auto item, addresses ) { if ( qhAddr.isInSubnet ( item ) ) { return true; } } return false; } // CHostAddress methods // Compare() - compare two CHostAddress objects, and return an ordering between them: // 0 - they are equal // <0 - this comes before other // >0 - this comes after other // The order is not important, so long as it is consistent, for use in a binary search. int CHostAddress::Compare ( const CHostAddress& other ) const { // compare port first, as it is cheap, and clients will often use random ports if ( iPort != other.iPort ) { return (int) iPort - (int) other.iPort; } // compare protocols before addresses QAbstractSocket::NetworkLayerProtocol thisProto = InetAddr.protocol(); QAbstractSocket::NetworkLayerProtocol otherProto = other.InetAddr.protocol(); if ( thisProto != otherProto ) { return (int) thisProto - (int) otherProto; } // now we know both addresses are the same protocol if ( thisProto == QAbstractSocket::IPv6Protocol ) { // compare IPv6 addresses Q_IPV6ADDR thisAddr = InetAddr.toIPv6Address(); Q_IPV6ADDR otherAddr = other.InetAddr.toIPv6Address(); return memcmp ( &thisAddr, &otherAddr, sizeof ( Q_IPV6ADDR ) ); } // compare IPv4 addresses quint32 thisAddr = InetAddr.toIPv4Address(); quint32 otherAddr = other.InetAddr.toIPv4Address(); return thisAddr < otherAddr ? -1 : thisAddr > otherAddr ? 1 : 0; } QString CHostAddress::toString ( const EStringMode eStringMode ) const { QString strReturn = InetAddr.toString(); // special case: for local host address, we do not replace the last byte if ( ( ( eStringMode == SM_IP_NO_LAST_BYTE ) || ( eStringMode == SM_IP_NO_LAST_BYTE_PORT ) ) && ( InetAddr != QHostAddress ( QHostAddress::LocalHost ) ) && ( InetAddr != QHostAddress ( QHostAddress::LocalHostIPv6 ) ) ) { // replace last part by an "x" if ( strReturn.contains ( "." ) ) { // IPv4 or IPv4-mapped: strReturn = strReturn.section ( ".", 0, -2 ) + ".x"; } else { // IPv6 strReturn = strReturn.section ( ":", 0, -2 ) + ":x"; } } if ( ( eStringMode == SM_IP_PORT ) || ( eStringMode == SM_IP_NO_LAST_BYTE_PORT ) ) { // add port number after a colon if ( strReturn.contains ( "." ) ) { strReturn += ":" + QString().setNum ( iPort ); } else { // enclose pure IPv6 address in [ ] before adding port, to avoid ambiguity strReturn = "[" + strReturn + "]:" + QString().setNum ( iPort ); } } return strReturn; } // Instrument picture data base ------------------------------------------------ CVector& CInstPictures::GetTable ( const bool bReGenerateTable ) { // make sure we generate the table only once static bool TableIsInitialized = false; static CVector vecDataBase; if ( !TableIsInitialized || bReGenerateTable ) { // instrument picture data base initialization // NOTE: Do not change the order of any instrument in the future! // NOTE: The very first entry is the "not used" element per definition. vecDataBase.Init ( 0 ); // first clear all existing data since we create the list be adding entries vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "None" ), ":/png/instr/res/instruments/none.png", IC_OTHER_INSTRUMENT ) ); // special first element vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Drum Set" ), ":/png/instr/res/instruments/drumset.png", IC_PERCUSSION_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Djembe" ), ":/png/instr/res/instruments/djembe.png", IC_PERCUSSION_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Electric Guitar" ), ":/png/instr/res/instruments/eguitar.png", IC_PLUCKING_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Acoustic Guitar" ), ":/png/instr/res/instruments/aguitar.png", IC_PLUCKING_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Bass Guitar" ), ":/png/instr/res/instruments/bassguitar.png", IC_PLUCKING_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Keyboard" ), ":/png/instr/res/instruments/keyboard.png", IC_KEYBOARD_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Synthesizer" ), ":/png/instr/res/instruments/synthesizer.png", IC_KEYBOARD_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Grand Piano" ), ":/png/instr/res/instruments/grandpiano.png", IC_KEYBOARD_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Accordion" ), ":/png/instr/res/instruments/accordeon.png", IC_KEYBOARD_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Vocal" ), ":/png/instr/res/instruments/vocal.png", IC_OTHER_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Microphone" ), ":/png/instr/res/instruments/microphone.png", IC_OTHER_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Harmonica" ), ":/png/instr/res/instruments/harmonica.png", IC_WIND_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Trumpet" ), ":/png/instr/res/instruments/trumpet.png", IC_WIND_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Trombone" ), ":/png/instr/res/instruments/trombone.png", IC_WIND_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "French Horn" ), ":/png/instr/res/instruments/frenchhorn.png", IC_WIND_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Tuba" ), ":/png/instr/res/instruments/tuba.png", IC_WIND_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Saxophone" ), ":/png/instr/res/instruments/saxophone.png", IC_WIND_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Clarinet" ), ":/png/instr/res/instruments/clarinet.png", IC_WIND_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Flute" ), ":/png/instr/res/instruments/flute.png", IC_WIND_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Violin" ), ":/png/instr/res/instruments/violin.png", IC_STRING_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Cello" ), ":/png/instr/res/instruments/cello.png", IC_STRING_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Double Bass" ), ":/png/instr/res/instruments/doublebass.png", IC_STRING_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Recorder" ), ":/png/instr/res/instruments/recorder.png", IC_OTHER_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Streamer" ), ":/png/instr/res/instruments/streamer.png", IC_OTHER_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Listener" ), ":/png/instr/res/instruments/listener.png", IC_OTHER_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Guitar+Vocal" ), ":/png/instr/res/instruments/guitarvocal.png", IC_MULTIPLE_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Keyboard+Vocal" ), ":/png/instr/res/instruments/keyboardvocal.png", IC_MULTIPLE_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Bodhran" ), ":/png/instr/res/instruments/bodhran.png", IC_PERCUSSION_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Bassoon" ), ":/png/instr/res/instruments/bassoon.png", IC_WIND_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Oboe" ), ":/png/instr/res/instruments/oboe.png", IC_WIND_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Harp" ), ":/png/instr/res/instruments/harp.png", IC_STRING_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Viola" ), ":/png/instr/res/instruments/viola.png", IC_STRING_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Congas" ), ":/png/instr/res/instruments/congas.png", IC_PERCUSSION_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Bongo" ), ":/png/instr/res/instruments/bongo.png", IC_PERCUSSION_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Vocal Bass" ), ":/png/instr/res/instruments/vocalbass.png", IC_OTHER_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Vocal Tenor" ), ":/png/instr/res/instruments/vocaltenor.png", IC_OTHER_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Vocal Alto" ), ":/png/instr/res/instruments/vocalalto.png", IC_OTHER_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Vocal Soprano" ), ":/png/instr/res/instruments/vocalsoprano.png", IC_OTHER_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Banjo" ), ":/png/instr/res/instruments/banjo.png", IC_PLUCKING_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Mandolin" ), ":/png/instr/res/instruments/mandolin.png", IC_PLUCKING_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Ukulele" ), ":/png/instr/res/instruments/ukulele.png", IC_PLUCKING_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Bass Ukulele" ), ":/png/instr/res/instruments/bassukulele.png", IC_PLUCKING_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Vocal Baritone" ), ":/png/instr/res/instruments/vocalbaritone.png", IC_OTHER_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Vocal Lead" ), ":/png/instr/res/instruments/vocallead.png", IC_OTHER_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Mountain Dulcimer" ), ":/png/instr/res/instruments/mountaindulcimer.png", IC_STRING_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Scratching" ), ":/png/instr/res/instruments/scratching.png", IC_OTHER_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Rapping" ), ":/png/instr/res/instruments/rapping.png", IC_OTHER_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Vibraphone" ), ":/png/instr/res/instruments/vibraphone.png", IC_PERCUSSION_INSTRUMENT ) ); vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CClientSettingsDlg", "Conductor" ), ":/png/instr/res/instruments/conductor.png", IC_OTHER_INSTRUMENT ) ); // now the table is initialized TableIsInitialized = true; } return vecDataBase; } bool CInstPictures::IsInstIndexInRange ( const int iIdx ) { // check if index is in valid range return ( iIdx >= 0 ) && ( iIdx < GetTable().Size() ); } QString CInstPictures::GetResourceReference ( const int iInstrument ) { // range check if ( IsInstIndexInRange ( iInstrument ) ) { // return the string of the resource reference for accessing the picture return GetTable()[iInstrument].strResourceReference; } else { return ""; } } QString CInstPictures::GetName ( const int iInstrument ) { // range check if ( IsInstIndexInRange ( iInstrument ) ) { // return the name of the instrument return GetTable()[iInstrument].strName; } else { return ""; } } CInstPictures::EInstCategory CInstPictures::GetCategory ( const int iInstrument ) { // range check if ( IsInstIndexInRange ( iInstrument ) ) { // return the name of the instrument return GetTable()[iInstrument].eInstCategory; } else { return IC_OTHER_INSTRUMENT; } } // Locale management class ----------------------------------------------------- QLocale::Country CLocale::WireFormatCountryCodeToQtCountry ( unsigned short iCountryCode ) { #if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) // The Jamulus protocol wire format gives us Qt5 country IDs. // Qt6 changed those IDs, so we have to convert back: return (QLocale::Country) wireFormatToQt6Table[iCountryCode]; #else return (QLocale::Country) iCountryCode; #endif } unsigned short CLocale::QtCountryToWireFormatCountryCode ( const QLocale::Country eCountry ) { #if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) // The Jamulus protocol wire format expects Qt5 country IDs. // Qt6 changed those IDs, so we have to convert back: return qt6CountryToWireFormat[(unsigned short) eCountry]; #else return (unsigned short) eCountry; #endif } bool CLocale::IsCountryCodeSupported ( unsigned short iCountryCode ) { #if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) // On newer Qt versions there might be codes which do not have a Qt5 equivalent. // We have no way to support those sanely right now. // Before we can check that via an array lookup, we have to ensure that // we are within the boundaries of that array: if ( iCountryCode >= qt6CountryToWireFormatLen ) { return false; } return qt6CountryToWireFormat[iCountryCode] != -1; #else // All Qt5 codes are supported. return iCountryCode <= QLocale::LastCountry; #endif } QLocale::Country CLocale::GetCountryCodeByTwoLetterCode ( QString sTwoLetterCode ) { #if QT_VERSION >= QT_VERSION_CHECK( 6, 2, 0 ) return QLocale::codeToTerritory ( sTwoLetterCode ); #else QList vLocaleList = QLocale::matchingLocales ( QLocale::AnyLanguage, QLocale::AnyScript, QLocale::AnyCountry ); QStringList vstrLocParts; // Qt < 6.2 does not support lookups from two-letter iso codes to // QLocale::Country. Therefore, we have to loop over all supported // locales and perform the matching ourselves. // In the future, QLocale::codeToTerritory can be used. foreach ( const QLocale qLocale, vLocaleList ) { QStringList vstrLocParts = qLocale.name().split ( "_" ); if ( vstrLocParts.size() >= 2 && vstrLocParts.at ( 1 ).toLower() == sTwoLetterCode ) { return qLocale.country(); } } return QLocale::AnyCountry; #endif } QString CLocale::GetCountryFlagIconsResourceReference ( const QLocale::Country eCountry /* Qt-native value */ ) { QString strReturn = ""; // special flag for none if ( eCountry == QLocale::AnyCountry ) { return ":/png/flags/res/flags/flagnone.png"; } // There is no direct query of the country code in Qt, therefore we use a // workaround: Get the matching locales properties and split the name of // that since the second part is the country code QList vCurLocaleList = QLocale::matchingLocales ( QLocale::AnyLanguage, QLocale::AnyScript, eCountry ); // check if the matching locales query was successful if ( vCurLocaleList.size() < 1 ) { return ""; } QStringList vstrLocParts = vCurLocaleList.at ( 0 ).name().split ( "_" ); // the second split contains the name we need if ( vstrLocParts.size() <= 1 ) { return ""; } strReturn = ":/png/flags/res/flags/" + vstrLocParts.at ( 1 ).toLower() + ".png"; // check if file actually exists, if not then invalidate reference if ( !QFile::exists ( strReturn ) ) { return ""; } return strReturn; } QMap CLocale::GetAvailableTranslations() { QMap TranslMap; QDirIterator DirIter ( ":/translations" ); // add english language (default which is in the actual source code) TranslMap["en"] = ""; // empty file name means that the translation load fails and we get the default english language while ( DirIter.hasNext() ) { // get alias of translation file const QString strCurFileName = DirIter.next(); // extract only language code (must be at the end, separated with a "_") const QString strLoc = strCurFileName.right ( strCurFileName.length() - strCurFileName.indexOf ( "_" ) - 1 ); TranslMap[strLoc] = strCurFileName; } return TranslMap; } QPair CLocale::FindSysLangTransFileName ( const QMap& TranslMap ) { QPair PairSysLang ( "", "" ); QStringList slUiLang = QLocale().uiLanguages(); if ( !slUiLang.isEmpty() ) { QString strUiLang = QLocale().uiLanguages().at ( 0 ); strUiLang.replace ( "-", "_" ); // first try to find the complete language string if ( TranslMap.constFind ( strUiLang ) != TranslMap.constEnd() ) { PairSysLang.first = strUiLang; PairSysLang.second = TranslMap[PairSysLang.first]; } else { // only extract two first characters to identify language (ignoring // location for getting a simpler implementation -> if the language // is not correct, the user can change it in the GUI anyway) if ( strUiLang.length() >= 2 ) { PairSysLang.first = strUiLang.left ( 2 ); PairSysLang.second = TranslMap[PairSysLang.first]; } } } return PairSysLang; } void CLocale::LoadTranslation ( const QString strLanguage, QCoreApplication* pApp ) { // The translator objects must be static! static QTranslator myappTranslator; static QTranslator myqtTranslator; QMap TranslMap = CLocale::GetAvailableTranslations(); const QString strTranslationFileName = TranslMap[strLanguage]; if ( myappTranslator.load ( strTranslationFileName ) ) { pApp->installTranslator ( &myappTranslator ); } // allows the Qt messages to be translated in the application if ( myqtTranslator.load ( QLocale ( strLanguage ), "qt", "_", QLibraryInfo::location ( QLibraryInfo::TranslationsPath ) ) ) { pApp->installTranslator ( &myqtTranslator ); } } /******************************************************************************\ * Global Functions Implementation * \******************************************************************************/ QString GetVersionAndNameStr ( const bool bDisplayInGui ) { QString strVersionText = ""; // name, short description and GPL hint if ( bDisplayInGui ) { strVersionText += ""; } else { #ifdef _WIN32 // start with newline to print nice in windows command prompt strVersionText += "\n"; #endif strVersionText += " *** "; } strVersionText += QCoreApplication::tr ( "%1, Version %2", "%1 is app name, %2 is version number" ).arg ( APP_NAME ).arg ( VERSION ); if ( bDisplayInGui ) { strVersionText += "
"; } else { strVersionText += "\n *** "; } if ( !bDisplayInGui ) { strVersionText += "Internet Jam Session Software"; strVersionText += "\n *** "; } strVersionText += QCoreApplication::tr ( "Released under the GNU General Public License version 2 or later (GPLv2)" ); if ( !bDisplayInGui ) { // additional non-translated text to show in console output strVersionText += "\n *** "; strVersionText += "\n *** "; strVersionText += "\n *** This program is free software; you can redistribute it and/or modify it under"; strVersionText += "\n *** the terms of the GNU General Public License as published by the Free Software"; strVersionText += "\n *** Foundation; either version 2 of the License, or (at your option) any later version."; strVersionText += "\n *** There is NO WARRANTY, to the extent permitted by law."; strVersionText += "\n *** "; strVersionText += "\n *** Using the following libraries, resources or code snippets:"; strVersionText += "\n *** "; strVersionText += QString ( "\n *** Qt framework %1" ).arg ( QT_VERSION_STR ); strVersionText += "\n *** "; strVersionText += "\n *** "; strVersionText += "\n *** Opus Interactive Audio Codec"; strVersionText += "\n *** "; strVersionText += "\n *** "; #if defined( _WIN32 ) && !defined( WITH_JACK ) strVersionText += "\n *** ASIO (Audio Stream I/O) SDK"; strVersionText += "\n *** "; strVersionText += "\n *** "; #endif strVersionText += "\n *** Audio reverberation code by Perry R. Cook and Gary P. Scavone"; strVersionText += "\n *** "; strVersionText += "\n *** "; strVersionText += "\n *** Some pixmaps are from the Open Clip Art Library (OCAL)"; strVersionText += "\n *** "; strVersionText += "\n *** "; strVersionText += "\n *** Flag icons by Mark James"; strVersionText += "\n *** "; strVersionText += "\n *** "; strVersionText += "\n *** Some sound samples are from Freesound"; strVersionText += "\n *** "; strVersionText += "\n *** "; strVersionText += "\n *** Copyright (C) 2005-2022 The Jamulus Development Team"; strVersionText += "\n"; } return strVersionText; } QString MakeClientNameTitle ( QString win, QString client ) { QString sReturnString = win; if ( !client.isEmpty() ) { sReturnString += " - " + client; } return ( sReturnString ); } QString TruncateString ( QString str, int position ) { QTextBoundaryFinder tbfString ( QTextBoundaryFinder::Grapheme, str ); tbfString.setPosition ( position ); if ( !tbfString.isAtBoundary() ) { tbfString.toPreviousBoundary(); position = tbfString.position(); } return str.left ( position ); } jamulus-3.9.1+dfsg/src/connectdlg.h0000644000175000017500000001064714340334543016244 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #include #include #include #include #include #include #include #include #include "global.h" #include "util.h" #include "settings.h" #include "multicolorled.h" #include "ui_connectdlgbase.h" /* Definitions ****************************************************************/ // defines the time interval at which the request server list message is re- // transmitted until it is received #define SERV_LIST_REQ_UPDATE_TIME_MS 2000 // ms /* Classes ********************************************************************/ class CConnectDlg : public CBaseDlg, private Ui_CConnectDlgBase { Q_OBJECT public: CConnectDlg ( CClientSettings* pNSetP, const bool bNewShowCompleteRegList, const bool bNEnableIPv6, QWidget* parent = nullptr ); void SetShowAllMusicians ( const bool bState ) { ShowAllMusicians ( bState ); } bool GetShowAllMusicians() { return bShowAllMusicians; } void SetServerList ( const CHostAddress& InetAddr, const CVector& vecServerInfo, const bool bIsReducedServerList = false ); void SetConnClientsList ( const CHostAddress& InetAddr, const CVector& vecChanInfo ); void SetPingTimeAndNumClientsResult ( const CHostAddress& InetAddr, const int iPingTime, const int iNumClients ); bool GetServerListItemWasChosen() const { return bServerListItemWasChosen; } QString GetSelectedAddress() const { return strSelectedAddress; } QString GetSelectedServerName() const { return strSelectedServerName; } protected: virtual void showEvent ( QShowEvent* ); virtual void hideEvent ( QHideEvent* ); QTreeWidgetItem* FindListViewItem ( const CHostAddress& InetAddr ); QTreeWidgetItem* GetParentListViewItem ( QTreeWidgetItem* pItem ); void DeleteAllListViewItemChilds ( QTreeWidgetItem* pItem ); void UpdateListFilter(); void ShowAllMusicians ( const bool bState ); void RequestServerList(); void EmitCLServerListPingMes ( const CHostAddress& haServerAddress ); void UpdateDirectoryServerComboBox(); CClientSettings* pSettings; QTimer TimerPing; QTimer TimerReRequestServList; QTimer TimerInitialSort; CHostAddress haDirectoryAddress; QString strSelectedAddress; QString strSelectedServerName; bool bShowCompleteRegList; bool bServerListReceived; bool bReducedServerListReceived; bool bServerListItemWasChosen; bool bListFilterWasActive; bool bShowAllMusicians; bool bEnableIPv6; public slots: void OnServerListItemDoubleClicked ( QTreeWidgetItem* Item, int ); void OnServerAddrEditTextChanged ( const QString& ); void OnDirectoryServerChanged ( int iTypeIdx ); void OnFilterTextEdited ( const QString& ) { UpdateListFilter(); } void OnExpandAllStateChanged ( int value ) { ShowAllMusicians ( value == Qt::Checked ); } void OnCustomDirectoriesChanged(); void OnConnectClicked(); void OnTimerPing(); void OnTimerReRequestServList(); signals: void ReqServerListQuery ( CHostAddress InetAddr ); void CreateCLServerListPingMes ( CHostAddress InetAddr ); void CreateCLServerListReqVerAndOSMes ( CHostAddress InetAddr ); void CreateCLServerListReqConnClientsListMes ( CHostAddress InetAddr ); }; jamulus-3.9.1+dfsg/src/resources.qrc0000644000175000017500000003564114340334543016475 0ustar vimervimer translation/translation_de_DE.qm translation/translation_fr_FR.qm translation/translation_pt_PT.qm translation/translation_pt_BR.qm translation/translation_es_ES.qm translation/translation_nb_NO.qm translation/translation_nl_NL.qm translation/translation_it_IT.qm translation/translation_pl_PL.qm translation/translation_sk_SK.qm translation/translation_sv_SE.qm translation/translation_zh_CN.qm translation/translation_ko_KR.qm res/CLEDDisabled.png res/CLEDGrey.png res/CLEDGreenBig.png res/CLEDRedBig.png res/CLEDYellowBig.png res/CLEDBlackBig.png res/IndicatorGreen.png res/IndicatorYellow.png res/IndicatorRed.png res/HLEDGreen.png res/HLEDBlack.png res/HLEDRed.png res/HLEDYellow.png res/IndicatorRedFancy.png res/IndicatorYellowFancy.png res/CLEDGreenSmall.png res/CLEDBlackSmall.png res/CLEDRedSmall.png res/CLEDYellowSmall.png res/faderbackground.png res/faderhandle.png res/faderhandlesmall.png res/ledbuttonnotpressed.png res/ledbuttonpressed.png res/mixerboardbackground.png res/transparent1x1.png res/mutediconorange.png res/instruments/none.png res/instruments/bassguitar.png res/instruments/clarinet.png res/instruments/drumset.png res/instruments/eguitar.png res/instruments/saxophone.png res/instruments/scratching.png res/instruments/rapping.png res/instruments/trumpet.png res/instruments/microphone.png res/instruments/mountaindulcimer.png res/instruments/keyboard.png res/instruments/violin.png res/instruments/aguitar.png res/instruments/flute.png res/instruments/accordeon.png res/instruments/cello.png res/instruments/trombone.png res/instruments/frenchhorn.png res/instruments/tuba.png res/instruments/doublebass.png res/instruments/grandpiano.png res/instruments/synthesizer.png res/instruments/vocal.png res/instruments/djembe.png res/instruments/harmonica.png res/instruments/recorder.png res/instruments/listener.png res/instruments/streamer.png res/instruments/guitarvocal.png res/instruments/keyboardvocal.png res/instruments/bodhran.png res/instruments/bassoon.png res/instruments/oboe.png res/instruments/harp.png res/instruments/viola.png res/instruments/congas.png res/instruments/bongo.png res/instruments/vocalbass.png res/instruments/vocalbaritone.png res/instruments/vocallead.png res/instruments/vocaltenor.png res/instruments/vocalalto.png res/instruments/vocalsoprano.png res/instruments/banjo.png res/instruments/mandolin.png res/instruments/ukulele.png res/instruments/bassukulele.png res/instruments/vibraphone.png res/instruments/conductor.png res/fronticon.png res/fronticonserver.png res/servertrayiconactive.png res/servertrayiconinactive.png res/flags/flagnone.png res/flags/ad.png res/flags/ae.png res/flags/af.png res/flags/ag.png res/flags/ai.png res/flags/al.png res/flags/am.png res/flags/an.png res/flags/ao.png res/flags/ar.png res/flags/as.png res/flags/at.png res/flags/au.png res/flags/aw.png res/flags/ax.png res/flags/az.png res/flags/ba.png res/flags/bb.png res/flags/bd.png res/flags/be.png res/flags/bf.png res/flags/bg.png res/flags/bh.png res/flags/bi.png res/flags/bj.png res/flags/bm.png res/flags/bn.png res/flags/bo.png res/flags/br.png res/flags/bs.png res/flags/bt.png res/flags/bv.png res/flags/bw.png res/flags/by.png res/flags/bz.png res/flags/ca.png res/flags/cc.png res/flags/cd.png res/flags/cf.png res/flags/cg.png res/flags/ch.png res/flags/ci.png res/flags/ck.png res/flags/cl.png res/flags/cm.png res/flags/cn.png res/flags/co.png res/flags/cr.png res/flags/cs.png res/flags/cu.png res/flags/cv.png res/flags/cx.png res/flags/cy.png res/flags/cz.png res/flags/de.png res/flags/dj.png res/flags/dk.png res/flags/dm.png res/flags/do.png res/flags/dz.png res/flags/ec.png res/flags/ee.png res/flags/eg.png res/flags/eh.png res/flags/er.png res/flags/es.png res/flags/et.png res/flags/fam.png res/flags/fi.png res/flags/fj.png res/flags/fk.png res/flags/fm.png res/flags/fo.png res/flags/fr.png res/flags/ga.png res/flags/gb.png res/flags/gd.png res/flags/ge.png res/flags/gf.png res/flags/gh.png res/flags/gi.png res/flags/gl.png res/flags/gm.png res/flags/gn.png res/flags/gp.png res/flags/gq.png res/flags/gr.png res/flags/gs.png res/flags/gt.png res/flags/gu.png res/flags/gw.png res/flags/gy.png res/flags/hk.png res/flags/hm.png res/flags/hn.png res/flags/hr.png res/flags/ht.png res/flags/hu.png res/flags/id.png res/flags/ie.png res/flags/il.png res/flags/in.png res/flags/io.png res/flags/iq.png res/flags/ir.png res/flags/is.png res/flags/it.png res/flags/jm.png res/flags/jo.png res/flags/jp.png res/flags/ke.png res/flags/kg.png res/flags/kh.png res/flags/ki.png res/flags/km.png res/flags/kn.png res/flags/kp.png res/flags/kr.png res/flags/kw.png res/flags/ky.png res/flags/kz.png res/flags/la.png res/flags/lb.png res/flags/lc.png res/flags/li.png res/flags/lk.png res/flags/lr.png res/flags/ls.png res/flags/lt.png res/flags/lu.png res/flags/lv.png res/flags/ly.png res/flags/ma.png res/flags/mc.png res/flags/md.png res/flags/me.png res/flags/mg.png res/flags/mh.png res/flags/mk.png res/flags/ml.png res/flags/mm.png res/flags/mn.png res/flags/mo.png res/flags/mp.png res/flags/mq.png res/flags/mr.png res/flags/ms.png res/flags/mt.png res/flags/mu.png res/flags/mv.png res/flags/mw.png res/flags/mx.png res/flags/my.png res/flags/mz.png res/flags/na.png res/flags/nc.png res/flags/ne.png res/flags/nf.png res/flags/ng.png res/flags/ni.png res/flags/nl.png res/flags/no.png res/flags/np.png res/flags/nr.png res/flags/nu.png res/flags/nz.png res/flags/om.png res/flags/pa.png res/flags/pe.png res/flags/pf.png res/flags/pg.png res/flags/ph.png res/flags/pk.png res/flags/pl.png res/flags/pm.png res/flags/pn.png res/flags/pr.png res/flags/ps.png res/flags/pt.png res/flags/pw.png res/flags/py.png res/flags/qa.png res/flags/re.png res/flags/ro.png res/flags/rs.png res/flags/ru.png res/flags/rw.png res/flags/sa.png res/flags/sb.png res/flags/sc.png res/flags/sd.png res/flags/se.png res/flags/sg.png res/flags/sh.png res/flags/si.png res/flags/sj.png res/flags/sk.png res/flags/sl.png res/flags/sm.png res/flags/sn.png res/flags/so.png res/flags/sr.png res/flags/st.png res/flags/sv.png res/flags/sy.png res/flags/sz.png res/flags/tc.png res/flags/td.png res/flags/tf.png res/flags/tg.png res/flags/th.png res/flags/tj.png res/flags/tk.png res/flags/tl.png res/flags/tm.png res/flags/tn.png res/flags/to.png res/flags/tr.png res/flags/tt.png res/flags/tv.png res/flags/tw.png res/flags/tz.png res/flags/ua.png res/flags/ug.png res/flags/um.png res/flags/us.png res/flags/uy.png res/flags/uz.png res/flags/va.png res/flags/vc.png res/flags/ve.png res/flags/vg.png res/flags/vi.png res/flags/vn.png res/flags/vu.png res/flags/wf.png res/flags/ws.png res/flags/ye.png res/flags/yt.png res/flags/za.png res/flags/zm.png res/flags/zw.png res/sounds/new_user.wav res/sounds/new_message.wav jamulus-3.9.1+dfsg/src/audiomixerboard.cpp0000644000175000017500000020524214340334543017632 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include "audiomixerboard.h" /******************************************************************************\ * CChanneFader * \******************************************************************************/ CChannelFader::CChannelFader ( QWidget* pNW ) : eDesign ( GD_STANDARD ), BitmapMutedIcon ( QString::fromUtf8 ( ":/png/fader/res/mutediconorange.png" ) ), bMIDICtrlUsed ( false ) { // create new GUI control objects and store pointers to them (note that // QWidget takes the ownership of the pMainGrid so that this only has // to be created locally in this constructor) pFrame = new QFrame ( pNW ); pLevelsBox = new QWidget ( pFrame ); plbrChannelLevel = new CLevelMeter ( pLevelsBox ); pFader = new QSlider ( Qt::Vertical, pLevelsBox ); pPan = new QDial ( pLevelsBox ); pPanLabel = new QLabel ( tr ( "Pan" ), pLevelsBox ); pInfoLabel = new QLabel ( "", pLevelsBox ); pMuteSoloBox = new QWidget ( pFrame ); pcbMute = new QCheckBox ( tr ( "Mute" ), pMuteSoloBox ); pcbSolo = new QCheckBox ( tr ( "Solo" ), pMuteSoloBox ); pcbGroup = new QCheckBox ( "", pMuteSoloBox ); pLabelInstBox = new QGroupBox ( pFrame ); plblLabel = new QLabel ( "", pFrame ); plblInstrument = new QLabel ( pFrame ); plblCountryFlag = new QLabel ( pFrame ); QVBoxLayout* pMainGrid = new QVBoxLayout ( pFrame ); QHBoxLayout* pLevelsGrid = new QHBoxLayout ( pLevelsBox ); QVBoxLayout* pMuteSoloGrid = new QVBoxLayout ( pMuteSoloBox ); pLabelGrid = new QHBoxLayout ( pLabelInstBox ); pLabelPictGrid = new QVBoxLayout(); QVBoxLayout* pPanGrid = new QVBoxLayout(); QHBoxLayout* pPanInfoGrid = new QHBoxLayout(); // define the popup menu for the group checkbox pGroupPopupMenu = new QMenu ( "", pcbGroup ); pGroupPopupMenu->addAction ( tr ( "&No grouping" ), this, [=] { OnGroupMenuGrp ( INVALID_INDEX ); } ); for ( int iGrp = 0; iGrp < MAX_NUM_FADER_GROUPS; iGrp++ ) { pGroupPopupMenu->addAction ( tr ( "Assign to group" ) + ( QString ( " &%1" ).arg ( iGrp + 1 ) ), this, [=] { OnGroupMenuGrp ( iGrp ); } ); } #if ( MAX_NUM_FADER_GROUPS != 8 ) # error "MAX_NUM_FADER_GROUPS must be set to 8, see implementation in CChannelFader()" #endif // setup channel level plbrChannelLevel->setContentsMargins ( 0, 3, 2, 3 ); // setup slider pFader->setPageStep ( 1 ); pFader->setRange ( 0, AUD_MIX_FADER_MAX ); pFader->setTickInterval ( AUD_MIX_FADER_MAX / 9 ); // setup panning control and info label pPan->setRange ( 0, AUD_MIX_PAN_MAX ); pPan->setValue ( AUD_MIX_PAN_MAX / 2 ); pPan->setNotchesVisible ( true ); pInfoLabel->setMinimumHeight ( 14 ); // prevents jitter when muting/unmuting (#811) pInfoLabel->setAlignment ( Qt::AlignTop ); pPanInfoGrid->addWidget ( pPanLabel, 0, Qt::AlignLeft | Qt::AlignTop ); pPanInfoGrid->addWidget ( pInfoLabel, 0, Qt::AlignHCenter | Qt::AlignTop ); pPanGrid->addLayout ( pPanInfoGrid ); pPanGrid->addWidget ( pPan, 0, Qt::AlignHCenter ); // setup fader tag label (black bold text which is centered) plblLabel->setTextFormat ( Qt::PlainText ); plblLabel->setAlignment ( Qt::AlignHCenter | Qt::AlignVCenter ); // set margins of the layouts to zero to get maximum space for the controls pMainGrid->setContentsMargins ( 0, 0, 0, 0 ); pPanGrid->setContentsMargins ( 0, 0, 0, 0 ); pPanGrid->setSpacing ( 0 ); // only minimal space pLevelsGrid->setContentsMargins ( 0, 0, 0, 0 ); pLevelsGrid->setSpacing ( 0 ); // only minimal space pMuteSoloGrid->setContentsMargins ( 0, 0, 0, 0 ); pMuteSoloGrid->setSpacing ( 0 ); // only minimal space pLabelGrid->setContentsMargins ( 0, 0, 0, 0 ); pLabelGrid->setSpacing ( 2 ); // only minimal space between picture and text // add user controls to the grids pLabelPictGrid->addWidget ( plblCountryFlag, 0, Qt::AlignHCenter ); pLabelPictGrid->addWidget ( plblInstrument, 0, Qt::AlignHCenter ); pLabelGrid->addLayout ( pLabelPictGrid ); pLabelGrid->addWidget ( plblLabel, 0, Qt::AlignVCenter ); // note: just initial add, may be changed later pLevelsGrid->addWidget ( plbrChannelLevel, 0, Qt::AlignRight ); pLevelsGrid->addWidget ( pFader, 0, Qt::AlignLeft ); pMuteSoloGrid->addWidget ( pcbGroup, 0, Qt::AlignLeft ); pMuteSoloGrid->addWidget ( pcbMute, 0, Qt::AlignLeft ); pMuteSoloGrid->addWidget ( pcbSolo, 0, Qt::AlignLeft ); pMainGrid->addLayout ( pPanGrid ); pMainGrid->addWidget ( pLevelsBox, 0, Qt::AlignHCenter ); pMainGrid->addWidget ( pMuteSoloBox, 0, Qt::AlignHCenter ); pMainGrid->addWidget ( pLabelInstBox ); // reset current fader strGroupBaseText = "Grp"; // this will most probably overwritten by SetGUIDesign() iInstrPicMaxWidth = INVALID_INDEX; // this will most probably overwritten by SetGUIDesign() Reset(); // add help text to controls plbrChannelLevel->setWhatsThis ( "" + tr ( "Channel Level" ) + ": " + tr ( "Displays the pre-fader audio level of this channel. All clients connected to the " "server will be assigned an audio level, the same value for every client." ) ); plbrChannelLevel->setAccessibleName ( tr ( "Input level of the current audio " "channel at the server" ) ); pFader->setWhatsThis ( "" + tr ( "Mixer Fader" ) + ": " + tr ( "Adjusts the audio level of this channel. All clients connected to the server " "will be assigned an audio fader, displayed at each client, to adjust the local mix." ) ); pFader->setAccessibleName ( tr ( "Local mix level setting of the current audio " "channel at the server" ) ); pInfoLabel->setWhatsThis ( "" + tr ( "Status Indicator" ) + ": " + tr ( "Shows a status indication about the client which is assigned to this channel. " "Supported indicators are:" ) + "
  • " + tr ( "Speaker with cancellation stroke: Indicates that another client has muted you." ) + "
" ); pInfoLabel->setAccessibleName ( tr ( "Status indicator label" ) ); pPan->setWhatsThis ( "" + tr ( "Panning" ) + ": " + tr ( "Sets the pan from Left to Right of the channel. " "Works only in stereo or preferably mono in/stereo out mode." ) ); pPan->setAccessibleName ( tr ( "Local panning position of the current audio channel at the server" ) ); pcbMute->setWhatsThis ( "" + tr ( "Mute" ) + ": " + tr ( "With the Mute checkbox, the audio channel can be muted." ) ); pcbMute->setAccessibleName ( tr ( "Mute button" ) ); pcbSolo->setWhatsThis ( "" + tr ( "Solo" ) + ": " + tr ( "With the Solo checkbox, the " "audio channel can be set to solo which means that all other channels " "except the soloed channel are muted. It is possible to set more than " "one channel to solo." ) ); pcbSolo->setAccessibleName ( tr ( "Solo button" ) ); pcbGroup->setWhatsThis ( "" + tr ( "Group" ) + ": " + tr ( "With the Grp checkbox, a " "group of audio channels can be defined. All channel faders in a group are moved " "in proportional synchronization if any one of the group faders are moved." ) ); pcbGroup->setAccessibleName ( tr ( "Group button" ) ); QString strFaderText = "" + tr ( "Fader Tag" ) + ": " + tr ( "The fader tag " "identifies the connected client. The tag name, a picture of your " "instrument and the flag of your location can be set in the main window." ); plblInstrument->setWhatsThis ( strFaderText ); plblInstrument->setAccessibleName ( tr ( "Mixer channel instrument picture" ) ); plblLabel->setWhatsThis ( strFaderText ); plblLabel->setAccessibleName ( tr ( "Mixer channel label (fader tag)" ) ); plblCountryFlag->setWhatsThis ( strFaderText ); plblCountryFlag->setAccessibleName ( tr ( "Mixer channel country/region flag" ) ); // Connections ------------------------------------------------------------- QObject::connect ( pFader, &QSlider::valueChanged, this, &CChannelFader::OnLevelValueChanged ); QObject::connect ( pPan, &QDial::valueChanged, this, &CChannelFader::OnPanValueChanged ); QObject::connect ( pcbMute, &QCheckBox::stateChanged, this, &CChannelFader::OnMuteStateChanged ); QObject::connect ( pcbSolo, &QCheckBox::stateChanged, this, &CChannelFader::soloStateChanged ); QObject::connect ( pcbGroup, &QCheckBox::stateChanged, this, &CChannelFader::OnGroupStateChanged ); } void CChannelFader::SetGUIDesign ( const EGUIDesign eNewDesign ) { eDesign = eNewDesign; switch ( eNewDesign ) { case GD_ORIGINAL: pFader->setStyleSheet ( "QSlider { width: 45px;" " border-image: url(:/png/fader/res/faderbackground.png) repeat;" " border-top: 10px transparent;" " border-bottom: 10px transparent;" " border-left: 20px transparent;" " border-right: -25px transparent; }" "QSlider::groove { image: url(:/png/fader/res/transparent1x1.png);" " padding-left: -34px;" " padding-top: -10px;" " padding-bottom: -15px; }" "QSlider::handle { image: url(:/png/fader/res/faderhandle.png); }" ); pLabelGrid->addWidget ( plblLabel, 0, Qt::AlignVCenter ); // label next to icons pLabelInstBox->setMinimumHeight ( 52 ); // maximum height of the instrument+flag pictures pPan->setFixedSize ( 50, 50 ); pPanLabel->setText ( tr ( "PAN" ) ); pcbMute->setText ( tr ( "MUTE" ) ); pcbSolo->setText ( tr ( "SOLO" ) ); strGroupBaseText = tr ( "GRP" ); iInstrPicMaxWidth = INVALID_INDEX; // no instrument picture scaling break; case GD_SLIMFADER: pLabelPictGrid->addWidget ( plblLabel, 0, Qt::AlignHCenter ); // label below icons pLabelInstBox->setMinimumHeight ( 130 ); // maximum height of the instrument+flag+label pPan->setFixedSize ( 28, 28 ); pFader->setTickPosition ( QSlider::NoTicks ); pFader->setStyleSheet ( "" ); pPanLabel->setText ( tr ( "Pan" ) ); pcbMute->setText ( tr ( "M" ) ); pcbSolo->setText ( tr ( "S" ) ); strGroupBaseText = tr ( "G" ); iInstrPicMaxWidth = 18; // scale instrument picture to avoid enlarging the width by the picture break; default: // reset style sheet and set original parameters pFader->setTickPosition ( QSlider::TicksBothSides ); pFader->setStyleSheet ( "" ); pLabelGrid->addWidget ( plblLabel, 0, Qt::AlignVCenter ); // label next to icons pLabelInstBox->setMinimumHeight ( 52 ); // maximum height of the instrument+flag pictures pPan->setFixedSize ( 50, 50 ); pPanLabel->setText ( tr ( "Pan" ) ); pcbMute->setText ( tr ( "Mute" ) ); pcbSolo->setText ( tr ( "Solo" ) ); strGroupBaseText = tr ( "Grp" ); iInstrPicMaxWidth = INVALID_INDEX; // no instrument picture scaling break; } // we need to update since we changed the checkbox text UpdateGroupIDDependencies(); // the instrument picture might need scaling after a style change SetChannelInfos ( cReceivedChanInfo ); } void CChannelFader::SetMeterStyle ( const EMeterStyle eNewMeterStyle ) { eMeterStyle = eNewMeterStyle; switch ( eNewMeterStyle ) { case MT_BAR_NARROW: plbrChannelLevel->SetLevelMeterType ( CLevelMeter::MT_BAR_NARROW ); // Fader height controls the distribution of the LEDs, if the value is too small the fader might not be movable pFader->setMinimumHeight ( 85 ); break; case MT_BAR_WIDE: plbrChannelLevel->SetLevelMeterType ( CLevelMeter::MT_BAR_WIDE ); // Fader height controls the distribution of the LEDs, if the value is too small the fader might not be movable pFader->setMinimumHeight ( 120 ); break; case MT_LED_ROUND_SMALL: plbrChannelLevel->SetLevelMeterType ( CLevelMeter::MT_LED_ROUND_SMALL ); // Fader height controls the distribution of the LEDs, if the value is too small the fader might not be movable pFader->setMinimumHeight ( 85 ); break; case MT_LED_ROUND_BIG: plbrChannelLevel->SetLevelMeterType ( CLevelMeter::MT_LED_ROUND_BIG ); // Fader height controls the distribution of the LEDs, if the value is too small the fader might not be movable pFader->setMinimumHeight ( 162 ); break; default: // reset style sheet and set original parameters plbrChannelLevel->SetLevelMeterType ( CLevelMeter::MT_LED_STRIPE ); // Fader height controls the distribution of the LEDs, if the value is too small the fader might not be movable pFader->setMinimumHeight ( 120 ); break; } } void CChannelFader::SetDisplayChannelLevel ( const bool eNDCL ) { plbrChannelLevel->setHidden ( !eNDCL ); } bool CChannelFader::GetDisplayChannelLevel() { return !plbrChannelLevel->isHidden(); } void CChannelFader::SetDisplayPans ( const bool eNDP ) { pPanLabel->setHidden ( !eNDP ); pPan->setHidden ( !eNDP ); } void CChannelFader::SetupFaderTag ( const ESkillLevel eSkillLevel ) { // Should never happen here if ( iGroupID >= MAX_NUM_FADER_GROUPS ) { SetGroupID ( INVALID_INDEX ); } // the group ID defines the border color and style QString strBorderColor = "black"; QString strBorderStyle = "solid"; if ( iGroupID != INVALID_INDEX ) { switch ( iGroupID % 4 ) { case 0: strBorderColor = "#C43AC5"; break; case 1: strBorderColor = "#2B93D4"; break; case 2: strBorderColor = "#3BC53A"; break; case 3: strBorderColor = "#D46C2B"; break; default: break; } switch ( iGroupID / 4 ) { case 0: strBorderStyle = "solid"; break; case 1: strBorderStyle = "dashed"; break; case 2: strBorderStyle = "dotted"; break; case 3: strBorderStyle = "double"; break; default: break; } } // setup group box for label/instrument picture: set a thick black border // with nice round edges QString strStile = "QGroupBox { border: 2px " + strBorderStyle + " " + strBorderColor + ";" " border-radius: 4px;" " padding: 3px;"; // the background color depends on the skill level switch ( eSkillLevel ) { case SL_BEGINNER: strStile += QString ( "background-color: rgb(%1, %2, %3); }" ).arg ( RGBCOL_R_SL_BEGINNER ).arg ( RGBCOL_G_SL_BEGINNER ).arg ( RGBCOL_B_SL_BEGINNER ); break; case SL_INTERMEDIATE: strStile += QString ( "background-color: rgb(%1, %2, %3); }" ) .arg ( RGBCOL_R_SL_INTERMEDIATE ) .arg ( RGBCOL_G_SL_INTERMEDIATE ) .arg ( RGBCOL_B_SL_INTERMEDIATE ); break; case SL_PROFESSIONAL: strStile += QString ( "background-color: rgb(%1, %2, %3); }" ) .arg ( RGBCOL_R_SL_SL_PROFESSIONAL ) .arg ( RGBCOL_G_SL_SL_PROFESSIONAL ) .arg ( RGBCOL_B_SL_SL_PROFESSIONAL ); break; default: strStile += QString ( "background-color: rgb(%1, %2, %3); }" ).arg ( RGBCOL_R_SL_NOT_SET ).arg ( RGBCOL_G_SL_NOT_SET ).arg ( RGBCOL_B_SL_NOT_SET ); break; } pLabelInstBox->setStyleSheet ( strStile ); } void CChannelFader::Reset() { // it is important to reset the group index first (#611) iGroupID = INVALID_INDEX; // general initializations SetRemoteFaderIsMute ( false ); // init gain and pan value -> maximum value as definition according to server pFader->setValue ( AUD_MIX_FADER_MAX ); dPreviousFaderLevel = AUD_MIX_FADER_MAX; pPan->setValue ( AUD_MIX_PAN_MAX / 2 ); // reset mute/solo/group check boxes and level meter pcbMute->setChecked ( false ); pcbSolo->setChecked ( false ); plbrChannelLevel->SetValue ( 0 ); plbrChannelLevel->ClipReset(); // clear instrument picture, country flag, tool tips and label text plblLabel->setText ( "" ); plblLabel->setToolTip ( "" ); plblInstrument->setVisible ( false ); plblInstrument->setToolTip ( "" ); plblCountryFlag->setVisible ( false ); plblCountryFlag->setToolTip ( "" ); cReceivedChanInfo = CChannelInfo(); SetupFaderTag ( SL_NOT_SET ); // set a defined tool tip time out const int iToolTipDurMs = 30000; plblLabel->setToolTipDuration ( iToolTipDurMs ); plblInstrument->setToolTipDuration ( iToolTipDurMs ); plblCountryFlag->setToolTipDuration ( iToolTipDurMs ); bOtherChannelIsSolo = false; bIsMyOwnFader = false; bIsMutedAtServer = false; iRunningNewClientCnt = 0; UpdateGroupIDDependencies(); } void CChannelFader::SetFaderLevel ( const double dLevel, const bool bIsGroupUpdate ) { // first make a range check if ( dLevel >= 0 ) { // we set the new fader level in the GUI (slider control) and also tell the // server about the change (block the signal of the fader since we want to // call SendFaderLevelToServer with a special additional parameter) pFader->blockSignals ( true ); pFader->setValue ( std::min ( AUD_MIX_FADER_MAX, MathUtils::round ( dLevel ) ) ); pFader->blockSignals ( false ); SendFaderLevelToServer ( std::min ( static_cast ( AUD_MIX_FADER_MAX ), dLevel ), bIsGroupUpdate ); if ( dLevel > AUD_MIX_FADER_MAX ) { // If the level is above the maximum, we have to store it for the purpose // of group fader movement. If you move a fader which has lower volume than // this one and this clips at max, we want to retain the ratio between this // fader and the others in the group. dPreviousFaderLevel = dLevel; } } } void CChannelFader::SetPanValue ( const int iPan ) { // first make a range check if ( ( iPan >= 0 ) && ( iPan <= AUD_MIX_PAN_MAX ) ) { // we set the new fader level in the GUI (slider control) which then // emits to signal to tell the server about the change (implicitly) pPan->setValue ( iPan ); pPan->setAccessibleName ( QString::number ( iPan ) ); } } void CChannelFader::SetFaderIsSolo ( const bool bIsSolo ) { // changing the state automatically emits the signal, too pcbSolo->setChecked ( bIsSolo ); } void CChannelFader::SetFaderIsMute ( const bool bIsMute ) { // changing the state automatically emits the signal, too pcbMute->setChecked ( bIsMute ); } void CChannelFader::SetRemoteFaderIsMute ( const bool bIsMute ) { if ( bIsMute ) { // show muted icon orange pInfoLabel->setPixmap ( BitmapMutedIcon ); } else { pInfoLabel->setPixmap ( QPixmap() ); } } void CChannelFader::SendFaderLevelToServer ( const double dLevel, const bool bIsGroupUpdate ) { // if mute flag is set or other channel is on solo, do not apply the new // fader value to the server (exception: we are on solo, in that case we // ignore the "other channel is on solo" flag) const bool bSuppressServerUpdate = !( ( pcbMute->checkState() == Qt::Unchecked ) && ( !bOtherChannelIsSolo || IsSolo() ) ); // emit signal for new fader gain value emit gainValueChanged ( MathUtils::CalcFaderGain ( static_cast ( dLevel ) ), bIsMyOwnFader, bIsGroupUpdate, bSuppressServerUpdate, dLevel / dPreviousFaderLevel ); // update previous fader level since the level has changed, avoid to use // the zero value not to have division by zero and also to retain the ratio // after the fader is moved up again from the zero position if ( dLevel > 0 ) { dPreviousFaderLevel = dLevel; } } void CChannelFader::SendPanValueToServer ( const int iPan ) { emit panValueChanged ( static_cast ( iPan ) / AUD_MIX_PAN_MAX ); } void CChannelFader::OnPanValueChanged ( int value ) { // on shift-click the pan shall reset to 0 L/R (#707) if ( QGuiApplication::keyboardModifiers() == Qt::ShiftModifier ) { // correct the value to the center position value = AUD_MIX_PAN_MAX / 2; // set the GUI control in the center position while deactivating // the signals to avoid an infinite loop pPan->blockSignals ( true ); pPan->setValue ( value ); pPan->blockSignals ( false ); } pPan->setAccessibleName ( QString::number ( value ) ); SendPanValueToServer ( value ); } void CChannelFader::OnMuteStateChanged ( int value ) { // call muting function SetMute ( static_cast ( value ) == Qt::Checked ); } void CChannelFader::SetGroupID ( const int iNGroupID ) { iGroupID = iNGroupID; UpdateGroupIDDependencies(); } void CChannelFader::UpdateGroupIDDependencies() { // update the group checkbox according the current group ID setting pcbGroup->blockSignals ( true ); // make sure no signals are fired if ( iGroupID == INVALID_INDEX ) { pcbGroup->setCheckState ( Qt::Unchecked ); } else { pcbGroup->setCheckState ( Qt::Checked ); } pcbGroup->blockSignals ( false ); // update group checkbox text if ( iGroupID != INVALID_INDEX ) { pcbGroup->setText ( strGroupBaseText + QString::number ( iGroupID + 1 ) ); } else { pcbGroup->setText ( strGroupBaseText ); } // if the group is disable for this fader, reset the previous fader level if ( iGroupID == INVALID_INDEX ) { // for the special case that the fader is all the way down, use a small // value instead if ( GetFaderLevel() > 0 ) { dPreviousFaderLevel = GetFaderLevel(); } else { dPreviousFaderLevel = 1; // small value } } // the fader tag border color is set according to the selected group SetupFaderTag ( cReceivedChanInfo.eSkillLevel ); } void CChannelFader::OnGroupStateChanged ( int ) { // we want a popup menu shown if the user presses the group checkbox but // we want to make sure that the checkbox state represents the current group // setting and not the current click state since the user might not click // on the menu but at one other place and then the popup menu disappears but // the checkobx state would be on an invalid state UpdateGroupIDDependencies(); pGroupPopupMenu->popup ( QCursor::pos() ); } void CChannelFader::SetMute ( const bool bState ) { if ( bState ) { if ( !bIsMutedAtServer ) { // mute channel -> send gain of 0 emit gainValueChanged ( 0, bIsMyOwnFader, false, false, -1 ); // set level ratio to in invalid value bIsMutedAtServer = true; } } else { // only unmute if we are not solot but an other channel is on solo if ( ( !bOtherChannelIsSolo || IsSolo() ) && bIsMutedAtServer ) { // mute was unchecked, get current fader value and apply emit gainValueChanged ( MathUtils::CalcFaderGain ( GetFaderLevel() ), bIsMyOwnFader, false, false, -1 ); // set level ratio to in invalid value bIsMutedAtServer = false; } } } void CChannelFader::UpdateSoloState ( const bool bNewOtherSoloState ) { // store state (must be done before the SetMute() call!) bOtherChannelIsSolo = bNewOtherSoloState; // mute overwrites solo -> if mute is active, do not change anything if ( !pcbMute->isChecked() ) { // mute channel if we are not solo but another channel is solo SetMute ( bOtherChannelIsSolo && !IsSolo() ); } } void CChannelFader::SetChannelLevel ( const uint16_t iLevel ) { plbrChannelLevel->SetValue ( iLevel ); } void CChannelFader::SetChannelInfos ( const CChannelInfo& cChanInfo ) { // store received channel info cReceivedChanInfo = cChanInfo; // init properties for the tool tip int iTTInstrument = CInstPictures::GetNotUsedInstrument(); QLocale::Country eTTCountry = QLocale::AnyCountry; // Label text -------------------------------------------------------------- QString strModText = cChanInfo.strName; // show channel numbers if --ctrlmidich is used (#241, #95) if ( bMIDICtrlUsed ) { strModText.prepend ( QString().setNum ( cChanInfo.iChanID ) + ":" ); } QTextBoundaryFinder tbfName ( QTextBoundaryFinder::Grapheme, cChanInfo.strName ); int iBreakPos; // apply break position and font size depending on the selected design if ( eDesign == GD_SLIMFADER ) { // in slim mode use a non-bold font (smaller width font) plblLabel->setStyleSheet ( "QLabel { color: black; }" ); // break at every 4th character iBreakPos = 4; } else { // in normal mode use bold font plblLabel->setStyleSheet ( "QLabel { color: black; font: bold; }" ); // break text at predefined position iBreakPos = MAX_LEN_FADER_TAG / 2; } int iInsPos = iBreakPos; int iCount = 0; int iLineNumber = 0; while ( tbfName.toNextBoundary() != -1 ) { ++iCount; if ( iCount == iInsPos && tbfName.position() + iLineNumber < strModText.length() ) { strModText.insert ( tbfName.position() + iLineNumber, QString ( "\n" ) ); iLineNumber++; iInsPos += iBreakPos; } } plblLabel->setText ( strModText ); // Instrument picture ------------------------------------------------------ // get the resource reference string for this instrument const QString strCurResourceRef = CInstPictures::GetResourceReference ( cChanInfo.iInstrument ); // first check if instrument picture is used or not and if it is valid if ( CInstPictures::IsNotUsedInstrument ( cChanInfo.iInstrument ) || strCurResourceRef.isEmpty() ) { // disable instrument picture plblInstrument->setVisible ( false ); } else { // set correct picture QPixmap pixInstr ( strCurResourceRef ); if ( ( iInstrPicMaxWidth != INVALID_INDEX ) && ( pixInstr.width() > iInstrPicMaxWidth ) ) { // scale instrument picture on request (scale to the width with correct aspect ratio) plblInstrument->setPixmap ( pixInstr.scaledToWidth ( iInstrPicMaxWidth, Qt::SmoothTransformation ) ); } else { plblInstrument->setPixmap ( pixInstr ); } iTTInstrument = cChanInfo.iInstrument; // enable instrument picture plblInstrument->setVisible ( true ); } // Country flag icon ------------------------------------------------------- if ( cChanInfo.eCountry != QLocale::AnyCountry ) { // try to load the country flag icon QPixmap CountryFlagPixmap ( CLocale::GetCountryFlagIconsResourceReference ( cChanInfo.eCountry ) ); // first check if resource reference was valid if ( CountryFlagPixmap.isNull() ) { // disable country flag plblCountryFlag->setVisible ( false ); } else { // set correct picture plblCountryFlag->setPixmap ( CountryFlagPixmap ); eTTCountry = cChanInfo.eCountry; // enable country flag plblCountryFlag->setVisible ( true ); } } else { // disable country flag plblCountryFlag->setVisible ( false ); } // Skill level background color -------------------------------------------- SetupFaderTag ( cChanInfo.eSkillLevel ); // Tool tip ---------------------------------------------------------------- // complete musician profile in the tool tip QString strToolTip = ""; QString strAliasAccessible = ""; QString strInstrumentAccessible = ""; QString strLocationAccessible = ""; // alias/name if ( !cChanInfo.strName.isEmpty() ) { strToolTip += "

" + tr ( "Alias/Name" ) + "

" + cChanInfo.strName; strAliasAccessible += cChanInfo.strName; } // instrument if ( !CInstPictures::IsNotUsedInstrument ( iTTInstrument ) ) { strToolTip += "

" + tr ( "Instrument" ) + "

" + CInstPictures::GetName ( iTTInstrument ); strInstrumentAccessible += CInstPictures::GetName ( iTTInstrument ); } // location if ( ( eTTCountry != QLocale::AnyCountry ) || ( !cChanInfo.strCity.isEmpty() ) ) { strToolTip += "

" + tr ( "Location" ) + "

"; if ( !cChanInfo.strCity.isEmpty() ) { strToolTip += cChanInfo.strCity; strLocationAccessible += cChanInfo.strCity; if ( eTTCountry != QLocale::AnyCountry ) { strToolTip += ", "; strLocationAccessible += ", "; } } if ( eTTCountry != QLocale::AnyCountry ) { strToolTip += QLocale::countryToString ( eTTCountry ); strLocationAccessible += QLocale::countryToString ( eTTCountry ); } } // skill level QString strSkillLevel; switch ( cChanInfo.eSkillLevel ) { case SL_BEGINNER: strSkillLevel = tr ( "Beginner" ); strToolTip += "

" + tr ( "Skill Level" ) + "

" + strSkillLevel; strInstrumentAccessible += ", " + strSkillLevel; break; case SL_INTERMEDIATE: strSkillLevel = tr ( "Intermediate" ); strToolTip += "

" + tr ( "Skill Level" ) + "

" + strSkillLevel; strInstrumentAccessible += ", " + strSkillLevel; break; case SL_PROFESSIONAL: strSkillLevel = tr ( "Expert" ); strToolTip += "

" + tr ( "Skill Level" ) + "

" + strSkillLevel; strInstrumentAccessible += ", " + strSkillLevel; break; case SL_NOT_SET: // skill level not set, do not add this entry break; } // if no information is given, leave the tool tip empty, otherwise add header if ( !strToolTip.isEmpty() ) { strToolTip.prepend ( "

" + tr ( "Musician Profile" ) + "

" ); } plblCountryFlag->setToolTip ( strToolTip ); plblCountryFlag->setAccessibleDescription ( strLocationAccessible ); plblInstrument->setToolTip ( strToolTip ); plblInstrument->setAccessibleDescription ( strInstrumentAccessible ); plblLabel->setToolTip ( strToolTip ); plblLabel->setAccessibleName ( strAliasAccessible ); plblLabel->setAccessibleDescription ( tr ( "Alias" ) ); pcbMute->setAccessibleName ( "Mute " + strAliasAccessible + ", " + strInstrumentAccessible ); pcbSolo->setAccessibleName ( "Solo " + strAliasAccessible + ", " + strInstrumentAccessible ); pcbGroup->setAccessibleName ( "Group " + strAliasAccessible + ", " + strInstrumentAccessible ); dynamic_cast ( plblLabel->parent() ) ->setAccessibleName ( strAliasAccessible + ", " + strInstrumentAccessible + ", " + strLocationAccessible ); } /******************************************************************************\ * CAudioMixerBoard * \******************************************************************************/ CAudioMixerBoard::CAudioMixerBoard ( QWidget* parent ) : QGroupBox ( parent ), pSettings ( nullptr ), bDisplayPans ( false ), bIsPanSupported ( false ), bNoFaderVisible ( true ), iMyChannelID ( INVALID_INDEX ), iRunningNewClientCnt ( 0 ), iNumMixerPanelRows ( 1 ), // pSettings->iNumMixerPanelRows is not yet available strServerName ( "" ), eRecorderState ( RS_UNDEFINED ), eChSortType ( ST_NO_SORT ) { // add group box and hboxlayout QHBoxLayout* pGroupBoxLayout = new QHBoxLayout ( this ); QWidget* pMixerWidget = new QWidget(); // will be added to the scroll area which is then the parent pScrollArea = new CMixerBoardScrollArea ( this ); pMainLayout = new QGridLayout ( pMixerWidget ); setAccessibleName ( "Personal Mix at the Server groupbox" ); setWhatsThis ( "" + tr ( "Personal Mix at the Server" ) + ": " + tr ( "When connected to a server, the controls here allow you to set your " "local mix without affecting what others hear from you. The title shows " "the server name and, when known, whether it is actively recording." ) ); // set title text (default: no server given) SetServerName ( "" ); // create all mixer controls and make them invisible vecpChanFader.Init ( MAX_NUM_CHANNELS ); vecAvgLevels.Init ( MAX_NUM_CHANNELS, 0.0f ); for ( int i = 0; i < MAX_NUM_CHANNELS; i++ ) { vecpChanFader[i] = new CChannelFader ( this ); vecpChanFader[i]->Hide(); } // insert horizontal spacer (at position MAX_NUM_CHANNELS+1 which is index MAX_NUM_CHANNELS) pMainLayout->addItem ( new QSpacerItem ( 0, 0, QSizePolicy::Expanding ), 0, MAX_NUM_CHANNELS ); // set margins of the layout to zero to get maximum space for the controls pGroupBoxLayout->setContentsMargins ( 0, 0, 0, 1 ); // note: to avoid problems at the bottom, use a small margin for that // add the group box to the scroll area pScrollArea->setMinimumWidth ( 200 ); // at least two faders shall be visible pScrollArea->setWidget ( pMixerWidget ); pScrollArea->setWidgetResizable ( true ); // make sure it fills the entire scroll area pScrollArea->setFrameShape ( QFrame::NoFrame ); pGroupBoxLayout->addWidget ( pScrollArea ); // Connections ------------------------------------------------------------- connectFaderSignalsToMixerBoardSlots(); } CAudioMixerBoard::~CAudioMixerBoard() { for ( int i = 0; i < MAX_NUM_CHANNELS; i++ ) { delete vecpChanFader[i]; } } template inline void CAudioMixerBoard::connectFaderSignalsToMixerBoardSlots() { int iCurChanID = slotId - 1; void ( CAudioMixerBoard::*pGainValueChanged ) ( float, bool, bool, bool, double ) = &CAudioMixerBoardSlots::OnChGainValueChanged; void ( CAudioMixerBoard::*pPanValueChanged ) ( float ) = &CAudioMixerBoardSlots::OnChPanValueChanged; QObject::connect ( vecpChanFader[iCurChanID], &CChannelFader::soloStateChanged, this, &CAudioMixerBoard::UpdateSoloStates ); QObject::connect ( vecpChanFader[iCurChanID], &CChannelFader::gainValueChanged, this, pGainValueChanged ); QObject::connect ( vecpChanFader[iCurChanID], &CChannelFader::panValueChanged, this, pPanValueChanged ); connectFaderSignalsToMixerBoardSlots(); } template<> inline void CAudioMixerBoard::connectFaderSignalsToMixerBoardSlots<0>() {} void CAudioMixerBoard::SetServerName ( const QString& strNewServerName ) { // store the current server name strServerName = strNewServerName; if ( strServerName.isEmpty() ) { // no connection or connection was reset: show default title setTitle ( tr ( "Server" ) ); } else { // Do not set the server name directly but first show a label which indicates // that we are trying to connect the server. First if a connected client // list was received, the connection was successful and the title is updated // with the correct server name. Make sure to choose a "try to connect" title // which is most striking (we use filled blocks and upper case letters). setTitle ( u8"\u2588\u2588\u2588\u2588\u2588 " + tr ( "T R Y I N G T O C O N N E C T" ) + u8" \u2588\u2588\u2588\u2588\u2588" ); } } void CAudioMixerBoard::SetGUIDesign ( const EGUIDesign eNewDesign ) { // move the channels tighter together in slim fader mode if ( eNewDesign == GD_SLIMFADER ) { pMainLayout->setSpacing ( 2 ); } else { pMainLayout->setSpacing ( 6 ); // Qt default spacing value } // apply GUI design to child GUI controls for ( int i = 0; i < MAX_NUM_CHANNELS; i++ ) { vecpChanFader[i]->SetGUIDesign ( eNewDesign ); } } void CAudioMixerBoard::SetMeterStyle ( const EMeterStyle eNewMeterStyle ) { // apply GUI design to child GUI controls for ( int i = 0; i < MAX_NUM_CHANNELS; i++ ) { vecpChanFader[i]->SetMeterStyle ( eNewMeterStyle ); } } void CAudioMixerBoard::SetDisplayPans ( const bool eNDP ) { bDisplayPans = eNDP; for ( int i = 0; i < MAX_NUM_CHANNELS; i++ ) { vecpChanFader[i]->SetDisplayPans ( eNDP && bIsPanSupported ); } } void CAudioMixerBoard::SetPanIsSupported() { bIsPanSupported = true; SetDisplayPans ( bDisplayPans ); } void CAudioMixerBoard::HideAll() { // before hiding the faders, store their settings StoreAllFaderSettings(); // make all controls invisible for ( int i = 0; i < MAX_NUM_CHANNELS; i++ ) { vecpChanFader[i]->SetChannelLevel ( 0 ); vecpChanFader[i]->SetDisplayChannelLevel ( false ); vecpChanFader[i]->SetDisplayPans ( false ); vecpChanFader[i]->Hide(); } // initialize flags and other parameters bIsPanSupported = false; bNoFaderVisible = true; eRecorderState = RS_UNDEFINED; iMyChannelID = INVALID_INDEX; iRunningNewClientCnt = 0; // reset running counter on new server connection // use original order of channel (by server ID) ChangeFaderOrder ( ST_NO_SORT ); // Reset recording indication styleSheet setStyleSheet ( "" ); // emit status of connected clients emit NumClientsChanged ( 0 ); // -> no clients connected } void CAudioMixerBoard::SetNumMixerPanelRows ( const int iNNumMixerPanelRows ) { // store new value and immediately initiate the sorting iNumMixerPanelRows = iNNumMixerPanelRows; ChangeFaderOrder ( eChSortType ); } void CAudioMixerBoard::SetFaderSorting ( const EChSortType eNChSortType ) { // store new sort type and update the fader order eChSortType = eNChSortType; ChangeFaderOrder ( eNChSortType ); } void CAudioMixerBoard::ChangeFaderOrder ( const EChSortType eChSortType ) { QMutexLocker locker ( &Mutex ); // create a pair list of lower strings and fader ID for each channel QList> PairList; int iNumVisibleFaders = 0; int iMyFader = -1; for ( int i = 0; i < MAX_NUM_CHANNELS; i++ ) { if ( vecpChanFader[i]->GetIsMyOwnFader() ) { iMyFader = i; } if ( eChSortType == ST_BY_NAME ) { PairList << QPair ( vecpChanFader[i]->GetReceivedName().toLower(), i ); } else if ( eChSortType == ST_BY_CITY ) { PairList << QPair ( vecpChanFader[i]->GetReceivedCity().toLower(), i ); } else if ( eChSortType == ST_BY_INSTRUMENT ) { // sort first "by instrument" and second "by name" by adding the name after the instrument PairList << QPair ( CInstPictures::GetName ( vecpChanFader[i]->GetReceivedInstrument() ) + vecpChanFader[i]->GetReceivedName().toLower(), i ); } else if ( eChSortType == ST_BY_GROUPID ) { if ( vecpChanFader[i]->GetGroupID() == INVALID_INDEX ) { // put channels without a group at the end PairList << QPair ( "z", i ); // group IDs are numbers, use letter to put it at the end } else { PairList << QPair ( QString::number ( vecpChanFader[i]->GetGroupID() ), i ); } } else // ST_NO_SORT { // per definition for no sort: faders are sorted in the order they appeared (note that we // pad to a total of 11 characters with zeros to make sure the sorting is done correctly) PairList << QPair ( QString ( "%1" ).arg ( vecpChanFader[i]->GetRunningNewClientCnt(), 11, 10, QLatin1Char ( '0' ) ), i ); } // count the number of visible faders if ( vecpChanFader[i]->IsVisible() ) { iNumVisibleFaders++; } } // sort the channels according to the first of the pair std::stable_sort ( PairList.begin(), PairList.end() ); // move my fader to first position if ( pSettings->bOwnFaderFirst ) { for ( int i = 0; i < MAX_NUM_CHANNELS; i++ ) { if ( iMyFader == PairList[i].second ) { PairList.move ( i, 0 ); break; } } } // we want to distribute iNumVisibleFaders across the first row, then the next, etc // up to iNumMixerPanelRows. So row wants to start at 0 until we get to some number, // then increase, where "some number" means we get no more than iNumMixerPanelRows. const int iNumFadersFirstRow = ( iNumVisibleFaders + iNumMixerPanelRows - 1 ) / iNumMixerPanelRows; // add channels to the layout in the new order, note that it is not required to remove // the widget from the layout first but it is moved to the new position automatically int iVisibleFaderCnt = 0; for ( int i = 0; i < MAX_NUM_CHANNELS; i++ ) { const int iCurFaderID = PairList[i].second; if ( vecpChanFader[iCurFaderID]->IsVisible() ) { // channels are added row-first, up to iNumFadersFirstRow, then onto // the next row. pMainLayout->addWidget ( vecpChanFader[iCurFaderID]->GetMainWidget(), iVisibleFaderCnt / iNumFadersFirstRow, iVisibleFaderCnt % iNumFadersFirstRow ); iVisibleFaderCnt++; } } } void CAudioMixerBoard::UpdateTitle() { QString strTitlePrefix = ""; if ( eRecorderState == RS_RECORDING ) { strTitlePrefix = QString ( "[%1] " ).arg ( tr ( "RECORDING ACTIVE" ) ); } // replace & signs with && (See Qt documentation for QLabel) // if strServerName includes an "&" sign, this is interpreted as keyboard shortcut (#1886) // it might be possible to find a more elegant solution here? QString strEscServerName = strServerName; strEscServerName.replace ( "&", "&&" ); setTitle ( strTitlePrefix + tr ( "Personal Mix at: %1" ).arg ( strEscServerName ) ); setAccessibleName ( title() ); } void CAudioMixerBoard::SetRecorderState ( const ERecorderState newRecorderState ) { // store the new recorder state and update the title eRecorderState = newRecorderState; UpdateTitle(); } void CAudioMixerBoard::ApplyNewConClientList ( CVector& vecChanInfo ) { // get number of connected clients const int iNumConnectedClients = vecChanInfo.Size(); Mutex.lock(); { // we want to set the server name only if the very first faders appear // in the audio mixer board to show a "try to connect" before if ( bNoFaderVisible ) { UpdateTitle(); } // search for channels which are already present and preserve their gain // setting, for all other channels reset gain // get all channels which are in use/not in use. We use the array index of vecChanInfo // if the fader is in use, else INVALID_INDEX to specify it is not in use int iFaderNumber[MAX_NUM_CHANNELS]; for ( int iChanID = 0; iChanID < MAX_NUM_CHANNELS; iChanID++ ) { iFaderNumber[iChanID] = INVALID_INDEX; } for ( int iFader = 0; iFader < iNumConnectedClients; iFader++ ) { iFaderNumber[vecChanInfo[iFader].iChanID] = iFader; } // Hide all unused faders and initialize used ones for ( int iChanID = 0; iChanID < MAX_NUM_CHANNELS; iChanID++ ) { if ( iFaderNumber[iChanID] == INVALID_INDEX ) { // current fader is not used StoreFaderSettings ( vecpChanFader[iChanID] ); vecpChanFader[iChanID]->Hide(); continue; } // current fader is used if ( !vecpChanFader[iChanID]->IsVisible() ) { // the fader was not in use, // reset everything for new client vecpChanFader[iChanID]->Reset(); vecAvgLevels[iChanID] = 0.0f; if ( iChanID == iMyChannelID ) { // this is my own fader --> set fader property vecpChanFader[iChanID]->SetIsMyOwnFader(); } // keep track of each new client // for "no sorting" channel sort order new clients are added // to the right-hand side of the mixer (#673) vecpChanFader[iChanID]->SetRunningNewClientCnt ( iRunningNewClientCnt++ ); // show fader vecpChanFader[iChanID]->Show(); // Set the default initial fader level. Check first that // this is not the initialization (i.e. previously there // were no faders visible) to avoid that our own level is // adjusted. If we have received our own channel ID, then // we can adjust the level even if no fader was visible. // The fader level of 100 % is the default in the // server, in that case we do not have to do anything here. if ( ( !bNoFaderVisible || ( ( iMyChannelID != INVALID_INDEX ) && ( iMyChannelID != iChanID ) ) ) && ( pSettings->iNewClientFaderLevel != 100 ) ) { // the value is in percent -> convert range vecpChanFader[iChanID]->SetFaderLevel ( pSettings->iNewClientFaderLevel / 100.0 * AUD_MIX_FADER_MAX ); } } if ( vecpChanFader[iChanID]->GetReceivedName().compare ( vecChanInfo[iFaderNumber[iChanID]].strName ) ) { // the text has actually changed, search in the list of // stored settings if we have a matching entry int iStoredFaderLevel; int iStoredPanValue; bool bStoredFaderIsSolo; bool bStoredFaderIsMute; int iGroupID; if ( GetStoredFaderSettings ( vecChanInfo[iFaderNumber[iChanID]].strName, iStoredFaderLevel, iStoredPanValue, bStoredFaderIsSolo, bStoredFaderIsMute, iGroupID ) ) { vecpChanFader[iChanID]->SetFaderLevel ( iStoredFaderLevel, true ); // suppress group update vecpChanFader[iChanID]->SetPanValue ( iStoredPanValue ); vecpChanFader[iChanID]->SetFaderIsSolo ( bStoredFaderIsSolo ); vecpChanFader[iChanID]->SetFaderIsMute ( bStoredFaderIsMute ); vecpChanFader[iChanID]->SetGroupID ( iGroupID ); // Must be the last to be set in the fader! } } // set the channel infos vecpChanFader[iChanID]->SetChannelInfos ( vecChanInfo[iFaderNumber[iChanID]] ); } // update the solo states since if any channel was on solo and a new client // has just connected, the new channel must be muted UpdateSoloStates(); // update flag for "all faders are invisible" bNoFaderVisible = ( iNumConnectedClients == 0 ); } Mutex.unlock(); // release mutex // sort the channels according to the selected sorting type ChangeFaderOrder ( eChSortType ); // emit status of connected clients emit NumClientsChanged ( iNumConnectedClients ); } void CAudioMixerBoard::SetFaderLevel ( const int iChannelIdx, const int iValue ) { // only apply new fader level if channel index is valid and the fader is visible if ( ( iChannelIdx >= 0 ) && ( iChannelIdx < MAX_NUM_CHANNELS ) ) { if ( vecpChanFader[iChannelIdx]->IsVisible() ) { vecpChanFader[iChannelIdx]->SetFaderLevel ( iValue ); } } } void CAudioMixerBoard::SetPanValue ( const int iChannelIdx, const int iValue ) { // only apply new pan value if channel index is valid and the panner is visible if ( ( iChannelIdx >= 0 ) && ( iChannelIdx < MAX_NUM_CHANNELS ) && bDisplayPans ) { if ( vecpChanFader[iChannelIdx]->IsVisible() ) { vecpChanFader[iChannelIdx]->SetPanValue ( iValue ); } } } void CAudioMixerBoard::SetFaderIsSolo ( const int iChannelIdx, const bool bIsSolo ) { // only apply solo if channel index is valid and the fader is visible if ( ( iChannelIdx >= 0 ) && ( iChannelIdx < MAX_NUM_CHANNELS ) ) { if ( vecpChanFader[iChannelIdx]->IsVisible() ) { vecpChanFader[iChannelIdx]->SetFaderIsSolo ( bIsSolo ); } } } void CAudioMixerBoard::SetFaderIsMute ( const int iChannelIdx, const bool bIsMute ) { // only apply mute if channel index is valid and the fader is visible if ( ( iChannelIdx >= 0 ) && ( iChannelIdx < MAX_NUM_CHANNELS ) ) { if ( vecpChanFader[iChannelIdx]->IsVisible() ) { vecpChanFader[iChannelIdx]->SetFaderIsMute ( bIsMute ); } } } void CAudioMixerBoard::SetAllFaderLevelsToNewClientLevel() { QMutexLocker locker ( &Mutex ); for ( int i = 0; i < MAX_NUM_CHANNELS; i++ ) { // only apply to visible faders and not to my own channel fader if ( vecpChanFader[i]->IsVisible() && ( i != iMyChannelID ) ) { // the value is in percent -> convert range, also use the group // update flag to make sure the group values are all set to the // same fader level now vecpChanFader[i]->SetFaderLevel ( pSettings->iNewClientFaderLevel / 100.0 * AUD_MIX_FADER_MAX, true ); } } } void CAudioMixerBoard::AutoAdjustAllFaderLevels() { QMutexLocker locker ( &Mutex ); // initialize variables used for statistics float vecMaxLevel[MAX_NUM_FADER_GROUPS + 1]; int vecChannelsPerGroup[MAX_NUM_FADER_GROUPS + 1]; for ( int i = 0; i < MAX_NUM_FADER_GROUPS + 1; ++i ) { vecMaxLevel[i] = LOW_BOUND_SIG_METER; vecChannelsPerGroup[i] = 0; } CVector> levels; levels.resize ( MAX_NUM_FADER_GROUPS + 1 ); // compute min/max level per group and number of channels per group for ( int i = 0; i < MAX_NUM_CHANNELS; ++i ) { // only apply to visible faders (and not to my own channel fader) if ( vecpChanFader[i]->IsVisible() && ( i != iMyChannelID ) ) { // map averaged meter output level to decibels // (invert CStereoSignalLevelMeter::CalcLogResultForMeter) float leveldB = vecAvgLevels[i] * ( UPPER_BOUND_SIG_METER - LOW_BOUND_SIG_METER ) / NUM_STEPS_LED_BAR + LOW_BOUND_SIG_METER; int group = vecpChanFader[i]->GetGroupID(); if ( group == INVALID_INDEX ) { group = MAX_NUM_FADER_GROUPS; } if ( leveldB >= AUTO_FADER_NOISE_THRESHOLD_DB ) { vecMaxLevel[group] = fmax ( vecMaxLevel[group], leveldB ); levels[group].Add ( leveldB ); } ++vecChannelsPerGroup[group]; } } // sort levels for later median computation for ( int i = 0; i < MAX_NUM_FADER_GROUPS + 1; ++i ) { std::sort ( levels[i].begin(), levels[i].end() ); } // compute the number of active groups (at least one channel) int cntActiveGroups = 0; for ( int i = 0; i < MAX_NUM_FADER_GROUPS; ++i ) { cntActiveGroups += vecChannelsPerGroup[i] > 0; } // only my channel is active, nothing to do if ( cntActiveGroups == 0 && vecChannelsPerGroup[MAX_NUM_FADER_GROUPS] == 0 ) { return; } // compute target level for each group // (prevent clipping when each group contributes at maximum level) float targetLevelPerGroup = -20.0f * log10 ( std::max ( cntActiveGroups, 1 ) ); // compute target levels for the channels of each group individually float vecTargetChannelLevel[MAX_NUM_FADER_GROUPS + 1]; float levelOffset = 0.0f; float minFader = 0.0f; for ( int i = 0; i < MAX_NUM_FADER_GROUPS + 1; ++i ) { // compute the target level for each channel in the current group // (prevent clipping when each channel in this group contributes at // the maximum level) vecTargetChannelLevel[i] = vecChannelsPerGroup[i] > 0 ? targetLevelPerGroup - 20.0f * log10 ( vecChannelsPerGroup[i] ) : 0.0f; // get median level int cntChannels = levels[i].Size(); if ( cntChannels == 0 ) { continue; } float refLevel = levels[i][cntChannels / 2]; // since we can only attenuate channels but not amplify, we have to // check that the reference channel can be brought to the target // level if ( refLevel < vecTargetChannelLevel[i] ) { // otherwise, we adjust the level offset in such a way that // the level can be reached levelOffset = fmin ( levelOffset, refLevel - vecTargetChannelLevel[i] ); // compute the minimum necessary fader setting minFader = fmin ( minFader, -vecMaxLevel[i] + vecTargetChannelLevel[i] + levelOffset ); } } // take minimum fader value into account // very weak channels would actually require strong channels to be // attenuated to a large amount; however, the attenuation is limited by // the faders if ( minFader < -AUD_MIX_FADER_RANGE_DB ) { levelOffset += -AUD_MIX_FADER_RANGE_DB - minFader; } // adjust all levels for ( int i = 0; i < MAX_NUM_CHANNELS; ++i ) { // only apply to visible faders (and not to my own channel fader) if ( vecpChanFader[i]->IsVisible() && ( i != iMyChannelID ) ) { // map averaged meter output level to decibels // (invert CStereoSignalLevelMeter::CalcLogResultForMeter) float leveldB = vecAvgLevels[i] * ( UPPER_BOUND_SIG_METER - LOW_BOUND_SIG_METER ) / NUM_STEPS_LED_BAR + LOW_BOUND_SIG_METER; int group = vecpChanFader[i]->GetGroupID(); if ( group == INVALID_INDEX ) { if ( cntActiveGroups > 0 ) { // do not adjust the channels without group in group mode continue; } else { group = MAX_NUM_FADER_GROUPS; } } // do not adjust channels with almost zero level to full level since // the channel might simply be silent at the moment if ( leveldB >= AUTO_FADER_NOISE_THRESHOLD_DB ) { // compute new level float newdBLevel = -leveldB + vecTargetChannelLevel[group] + levelOffset; // map range from decibels to fader level // (this inverts MathUtils::CalcFaderGain) float newFaderLevel = ( newdBLevel / AUD_MIX_FADER_RANGE_DB + 1.0f ) * AUD_MIX_FADER_MAX; // limit fader newFaderLevel = fmin ( fmax ( newFaderLevel, 0.0f ), float ( AUD_MIX_FADER_MAX ) ); // set fader level vecpChanFader[i]->SetFaderLevel ( newFaderLevel, true ); } } } } void CAudioMixerBoard::SetMIDICtrlUsed ( const bool bMIDICtrlUsed ) { QMutexLocker locker ( &Mutex ); for ( int i = 0; i < MAX_NUM_CHANNELS; i++ ) { vecpChanFader[i]->SetMIDICtrlUsed ( bMIDICtrlUsed ); } } void CAudioMixerBoard::StoreAllFaderSettings() { QMutexLocker locker ( &Mutex ); for ( int i = 0; i < MAX_NUM_CHANNELS; i++ ) { StoreFaderSettings ( vecpChanFader[i] ); } } void CAudioMixerBoard::LoadAllFaderSettings() { QMutexLocker locker ( &Mutex ); int iStoredFaderLevel; int iStoredPanValue; bool bStoredFaderIsSolo; bool bStoredFaderIsMute; int iGroupID; for ( int i = 0; i < MAX_NUM_CHANNELS; i++ ) { if ( GetStoredFaderSettings ( vecpChanFader[i]->GetReceivedName(), iStoredFaderLevel, iStoredPanValue, bStoredFaderIsSolo, bStoredFaderIsMute, iGroupID ) ) { vecpChanFader[i]->SetFaderLevel ( iStoredFaderLevel, true ); // suppress group update vecpChanFader[i]->SetPanValue ( iStoredPanValue ); vecpChanFader[i]->SetFaderIsSolo ( bStoredFaderIsSolo ); vecpChanFader[i]->SetFaderIsMute ( bStoredFaderIsMute ); vecpChanFader[i]->SetGroupID ( iGroupID ); // Must be the last to be set in the fader! } } } void CAudioMixerBoard::SetRemoteFaderIsMute ( const int iChannelIdx, const bool bIsMute ) { // only apply remote mute state if channel index is valid and the fader is visible if ( ( iChannelIdx >= 0 ) && ( iChannelIdx < MAX_NUM_CHANNELS ) ) { if ( vecpChanFader[iChannelIdx]->IsVisible() ) { vecpChanFader[iChannelIdx]->SetRemoteFaderIsMute ( bIsMute ); } } } void CAudioMixerBoard::UpdateSoloStates() { // first check if any channel has a solo state active bool bAnyChannelIsSolo = false; for ( int i = 0; i < MAX_NUM_CHANNELS; i++ ) { // check if fader is in use and has solo state active if ( vecpChanFader[i]->IsVisible() && vecpChanFader[i]->IsSolo() ) { bAnyChannelIsSolo = true; continue; } } // now update the solo state of all active faders for ( int i = 0; i < MAX_NUM_CHANNELS; i++ ) { if ( vecpChanFader[i]->IsVisible() ) { vecpChanFader[i]->UpdateSoloState ( bAnyChannelIsSolo ); } } } void CAudioMixerBoard::UpdateGainValue ( const int iChannelIdx, const float fValue, const bool bIsMyOwnFader, const bool bIsGroupUpdate, const bool bSuppressServerUpdate, const double dLevelRatio ) { // update current gain if ( !bSuppressServerUpdate ) { emit ChangeChanGain ( iChannelIdx, fValue, bIsMyOwnFader ); } // if this fader is selected, all other in the group must be updated as // well (note that we do not have to update if this is already a group update // to avoid an infinite loop) if ( ( vecpChanFader[iChannelIdx]->GetGroupID() != INVALID_INDEX ) && !bIsGroupUpdate ) { for ( int i = 0; i < MAX_NUM_CHANNELS; i++ ) { // update rest of faders selected if ( vecpChanFader[i]->IsVisible() && ( vecpChanFader[i]->GetGroupID() == vecpChanFader[iChannelIdx]->GetGroupID() ) && ( i != iChannelIdx ) && ( dLevelRatio >= 0 ) ) { // synchronize faders with moving fader level (it is important // to set the group flag to avoid infinite looping) vecpChanFader[i]->SetFaderLevel ( vecpChanFader[i]->GetPreviousFaderLevel() * dLevelRatio, true ); } } } } void CAudioMixerBoard::UpdatePanValue ( const int iChannelIdx, const float fValue ) { emit ChangeChanPan ( iChannelIdx, fValue ); } void CAudioMixerBoard::StoreFaderSettings ( CChannelFader* pChanFader ) { // if the fader was visible and the name is not empty, we store the old gain if ( pChanFader->IsVisible() && !pChanFader->GetReceivedName().isEmpty() ) { CVector viOldStoredFaderLevels ( pSettings->vecStoredFaderLevels ); CVector viOldStoredPanValues ( pSettings->vecStoredPanValues ); CVector vbOldStoredFaderIsSolo ( pSettings->vecStoredFaderIsSolo ); CVector vbOldStoredFaderIsMute ( pSettings->vecStoredFaderIsMute ); CVector vbOldStoredFaderGroupID ( pSettings->vecStoredFaderGroupID ); // put new value on the top of the list const int iOldIdx = pSettings->vecStoredFaderTags.StringFiFoWithCompare ( pChanFader->GetReceivedName() ); // current fader level and solo state is at the top of the list pSettings->vecStoredFaderLevels[0] = pChanFader->GetFaderLevel(); pSettings->vecStoredPanValues[0] = pChanFader->GetPanValue(); pSettings->vecStoredFaderIsSolo[0] = pChanFader->IsSolo(); pSettings->vecStoredFaderIsMute[0] = pChanFader->IsMute(); pSettings->vecStoredFaderGroupID[0] = pChanFader->GetGroupID(); int iTempListCnt = 1; // current fader is on top, other faders index start at 1 for ( int iIdx = 0; iIdx < MAX_NUM_STORED_FADER_SETTINGS; iIdx++ ) { // first check if we still have space in our data storage if ( iTempListCnt < MAX_NUM_STORED_FADER_SETTINGS ) { // check for the old index of the current entry (this has to be // skipped), note that per definition: the old index is an illegal // index in case the entry was not present in the vector before if ( iIdx != iOldIdx ) { pSettings->vecStoredFaderLevels[iTempListCnt] = viOldStoredFaderLevels[iIdx]; pSettings->vecStoredPanValues[iTempListCnt] = viOldStoredPanValues[iIdx]; pSettings->vecStoredFaderIsSolo[iTempListCnt] = vbOldStoredFaderIsSolo[iIdx]; pSettings->vecStoredFaderIsMute[iTempListCnt] = vbOldStoredFaderIsMute[iIdx]; pSettings->vecStoredFaderGroupID[iTempListCnt] = vbOldStoredFaderGroupID[iIdx]; iTempListCnt++; } } } } } bool CAudioMixerBoard::GetStoredFaderSettings ( const QString& strName, int& iStoredFaderLevel, int& iStoredPanValue, bool& bStoredFaderIsSolo, bool& bStoredFaderIsMute, int& iGroupID ) { // only do the check if the name string is not empty if ( !strName.isEmpty() ) { for ( int iIdx = 0; iIdx < MAX_NUM_STORED_FADER_SETTINGS; iIdx++ ) { // check if fader text is already known in the list if ( !pSettings->vecStoredFaderTags[iIdx].compare ( strName ) ) { // copy stored settings values iStoredFaderLevel = pSettings->vecStoredFaderLevels[iIdx]; iStoredPanValue = pSettings->vecStoredPanValues[iIdx]; bStoredFaderIsSolo = pSettings->vecStoredFaderIsSolo[iIdx] != 0; bStoredFaderIsMute = pSettings->vecStoredFaderIsMute[iIdx] != 0; iGroupID = pSettings->vecStoredFaderGroupID[iIdx]; // values found and copied, return OK return true; } } } // return "not OK" since we did not find matching fader settings return false; } void CAudioMixerBoard::SetChannelLevels ( const CVector& vecChannelLevel ) { const int iNumChannelLevels = vecChannelLevel.Size(); int i = 0; for ( int iChId = 0; iChId < MAX_NUM_CHANNELS; iChId++ ) { if ( vecpChanFader[iChId]->IsVisible() && ( i < iNumChannelLevels ) ) { // compute exponential moving average vecAvgLevels[iChId] = ( 1.0f - AUTO_FADER_ADJUST_ALPHA ) * vecAvgLevels[iChId] + AUTO_FADER_ADJUST_ALPHA * vecChannelLevel[i]; vecpChanFader[iChId]->SetChannelLevel ( vecChannelLevel[i++] ); // show level only if we successfully received levels from the // server (if server does not support levels, do not show levels) if ( !vecpChanFader[iChId]->GetDisplayChannelLevel() ) { vecpChanFader[iChId]->SetDisplayChannelLevel ( true ); } } } } void CAudioMixerBoard::MuteMyChannel() { SetFaderIsMute ( iMyChannelID, true ); } jamulus-3.9.1+dfsg/src/channel.cpp0000644000175000017500000006220714340334543016066 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include "channel.h" // CChannel implementation ***************************************************** CChannel::CChannel ( const bool bNIsServer ) : vecfGains ( MAX_NUM_CHANNELS, 1.0f ), vecfPannings ( MAX_NUM_CHANNELS, 0.5f ), iCurSockBufNumFrames ( INVALID_INDEX ), bDoAutoSockBufSize ( true ), bUseSequenceNumber ( false ), // this is important since in the client we reset on Channel.SetEnable ( false ) iSendSequenceNumber ( 0 ), iFadeInCnt ( 0 ), iFadeInCntMax ( FADE_IN_NUM_FRAMES_DBLE_FRAMESIZE ), bIsEnabled ( false ), bIsServer ( bNIsServer ), bIsIdentified ( false ), iAudioFrameSizeSamples ( DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES ), SignalLevelMeter ( false, 0.5 ) // server mode with mono out and faster smoothing { // reset network transport properties ResetNetworkTransportProperties(); // initial value for connection time out counter, we calculate the total // number of samples here and subtract the number of samples of the block // which we take out of the buffer to be independent of block sizes iConTimeOutStartVal = CON_TIME_OUT_SEC_MAX * SYSTEM_SAMPLE_RATE_HZ; // init time-out for the buffer with zero -> no connection iConTimeOut = 0; // init the socket buffer SetSockBufNumFrames ( DEF_NET_BUF_SIZE_NUM_BL ); // initialize channel info ResetInfo(); // Connections ------------------------------------------------------------- //### TODO: BEGIN ###// // if we later do not fire vectors in the emits, we can remove this again qRegisterMetaType> ( "CVector" ); qRegisterMetaType ( "CHostAddress" ); //### TODO: END ###// QObject::connect ( &Protocol, &CProtocol::MessReadyForSending, this, &CChannel::OnSendProtMessage ); QObject::connect ( &Protocol, &CProtocol::ChangeJittBufSize, this, &CChannel::OnJittBufSizeChange ); QObject::connect ( &Protocol, &CProtocol::ReqJittBufSize, this, &CChannel::ReqJittBufSize ); QObject::connect ( &Protocol, &CProtocol::ReqChanInfo, this, &CChannel::ReqChanInfo ); QObject::connect ( &Protocol, &CProtocol::ReqConnClientsList, this, &CChannel::ReqConnClientsList ); QObject::connect ( &Protocol, &CProtocol::ConClientListMesReceived, this, &CChannel::ConClientListMesReceived ); QObject::connect ( &Protocol, &CProtocol::ChangeChanGain, this, &CChannel::OnChangeChanGain ); QObject::connect ( &Protocol, &CProtocol::ChangeChanPan, this, &CChannel::OnChangeChanPan ); QObject::connect ( &Protocol, &CProtocol::ClientIDReceived, this, &CChannel::ClientIDReceived ); QObject::connect ( &Protocol, &CProtocol::MuteStateHasChangedReceived, this, &CChannel::MuteStateHasChangedReceived ); QObject::connect ( &Protocol, &CProtocol::ChangeChanInfo, this, &CChannel::OnChangeChanInfo ); QObject::connect ( &Protocol, &CProtocol::ChatTextReceived, this, &CChannel::ChatTextReceived ); QObject::connect ( &Protocol, &CProtocol::NetTranspPropsReceived, this, &CChannel::OnNetTranspPropsReceived ); QObject::connect ( &Protocol, &CProtocol::ReqNetTranspProps, this, &CChannel::OnReqNetTranspProps ); QObject::connect ( &Protocol, &CProtocol::ReqSplitMessSupport, this, &CChannel::OnReqSplitMessSupport ); QObject::connect ( &Protocol, &CProtocol::SplitMessSupported, this, &CChannel::OnSplitMessSupported ); QObject::connect ( &Protocol, &CProtocol::LicenceRequired, this, &CChannel::LicenceRequired ); QObject::connect ( &Protocol, &CProtocol::VersionAndOSReceived, this, &CChannel::OnVersionAndOSReceived ); QObject::connect ( &Protocol, &CProtocol::RecorderStateReceived, this, &CChannel::RecorderStateReceived ); } bool CChannel::ProtocolIsEnabled() { // for the server, only enable protocol if the channel is connected, i.e., // successfully audio packets are received from a client // for the client, enable protocol if the channel is enabled, i.e., the // connection button was hit by the user if ( bIsServer ) { return IsConnected(); } else { return bIsEnabled; } } void CChannel::SetEnable ( const bool bNEnStat ) { QMutexLocker locker ( &Mutex ); // set internal parameter bIsEnabled = bNEnStat; // The support for the packet sequence number must be reset if the client // disconnects from a server since we do not yet know if the next server we // connect to will support the sequence number. We use the SetEnable call in // the client for this task since at every start/stop it will call this // function. NOTE that it is important to reset this parameter on SetEnable(false) // since the SetEnable(true) is set AFTER the Init() in the client -> we // simply set it regardless of the state which does not hurt. bUseSequenceNumber = false; // if channel is not enabled, reset time out count and protocol if ( !bNEnStat ) { iConTimeOut = 0; Protocol.Reset(); } } void CChannel::OnVersionAndOSReceived ( COSUtil::EOpSystemType eOSType, QString strVersion ) { // check if audio packet counter is supported by the server (minimum version is 3.6.0) #if QT_VERSION >= QT_VERSION_CHECK( 5, 6, 0 ) if ( QVersionNumber::compare ( QVersionNumber::fromString ( strVersion ), QVersionNumber ( 3, 6, 0 ) ) >= 0 ) { // activate sequence counter and update the audio stream properties (which // does all the initialization and tells the server about the change) bUseSequenceNumber = true; SetAudioStreamProperties ( eAudioCompressionType, iCeltNumCodedBytes, iNetwFrameSizeFact, iNumAudioChannels ); } #endif emit VersionAndOSReceived ( eOSType, strVersion ); } void CChannel::SetAudioStreamProperties ( const EAudComprType eNewAudComprType, const int iNewCeltNumCodedBytes, const int iNewNetwFrameSizeFact, const int iNewNumAudioChannels ) { /* this function is intended for the client (not the server) */ CNetworkTransportProps NetworkTransportProps; Mutex.lock(); { // store new values eAudioCompressionType = eNewAudComprType; iNumAudioChannels = iNewNumAudioChannels; iCeltNumCodedBytes = iNewCeltNumCodedBytes; iNetwFrameSizeFact = iNewNetwFrameSizeFact; // add the size of the optional packet counter if ( bUseSequenceNumber ) { iNetwFrameSize = iCeltNumCodedBytes + 1; // per definition 1 byte counter } else { iNetwFrameSize = iCeltNumCodedBytes; } // update audio frame size if ( eAudioCompressionType == CT_OPUS ) { iAudioFrameSizeSamples = DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES; } else { iAudioFrameSizeSamples = SYSTEM_FRAME_SIZE_SAMPLES; } MutexSocketBuf.lock(); { // init socket buffer SockBuf.SetUseDoubleSystemFrameSize ( eAudioCompressionType == CT_OPUS ); // NOTE must be set BEFORE the init() SockBuf.Init ( iCeltNumCodedBytes, iCurSockBufNumFrames, bUseSequenceNumber ); } MutexSocketBuf.unlock(); MutexConvBuf.lock(); { // init conversion buffer ConvBuf.Init ( iNetwFrameSize * iNetwFrameSizeFact, bUseSequenceNumber ); } MutexConvBuf.unlock(); // fill network transport properties struct NetworkTransportProps = GetNetworkTransportPropsFromCurrentSettings(); } Mutex.unlock(); // tell the server about the new network settings Protocol.CreateNetwTranspPropsMes ( NetworkTransportProps ); } bool CChannel::SetSockBufNumFrames ( const int iNewNumFrames, const bool bPreserve ) { bool ReturnValue = true; // init with error bool bCurDoAutoSockBufSize = false; // we have to init but init values does not matter // first check for valid input parameter range if ( ( iNewNumFrames >= MIN_NET_BUF_SIZE_NUM_BL ) && ( iNewNumFrames <= MAX_NET_BUF_SIZE_NUM_BL ) ) { // only apply parameter if new parameter is different from current one if ( iCurSockBufNumFrames != iNewNumFrames ) { MutexSocketBuf.lock(); { // store new value iCurSockBufNumFrames = iNewNumFrames; // the network block size is a multiple of the minimum network // block size SockBuf.Init ( iCeltNumCodedBytes, iNewNumFrames, bUseSequenceNumber, bPreserve ); // store current auto socket buffer size setting in the mutex // region since if we use the current parameter below in the // if condition, it may have been changed in between the time // when we have left the mutex region and entered the if // condition bCurDoAutoSockBufSize = bDoAutoSockBufSize; ReturnValue = false; // -> no error } MutexSocketBuf.unlock(); } } // only in case there is no error, we are the server and auto jitter buffer // setting is enabled, we have to report the current setting to the client if ( !ReturnValue && bIsServer && bCurDoAutoSockBufSize ) { // we cannot call the "CreateJitBufMes" function directly since // this would give us problems with different threads (e.g. the // timer thread) and the protocol mechanism (problem with // qRegisterMetaType(), etc.) emit ServerAutoSockBufSizeChange ( iNewNumFrames ); } return ReturnValue; // set error flag } void CChannel::SetGain ( const int iChanID, const float fNewGain ) { QMutexLocker locker ( &Mutex ); // set value (make sure channel ID is in range) if ( ( iChanID >= 0 ) && ( iChanID < MAX_NUM_CHANNELS ) ) { // signal mute change if ( ( vecfGains[iChanID] == 0 ) && ( fNewGain > 0 ) ) { emit MuteStateHasChanged ( iChanID, false ); } if ( ( vecfGains[iChanID] > 0 ) && ( fNewGain == 0 ) ) { emit MuteStateHasChanged ( iChanID, true ); } vecfGains[iChanID] = fNewGain; } } float CChannel::GetGain ( const int iChanID ) { QMutexLocker locker ( &Mutex ); // get value (make sure channel ID is in range) if ( ( iChanID >= 0 ) && ( iChanID < MAX_NUM_CHANNELS ) ) { return vecfGains[iChanID]; } else { return 0; } } void CChannel::SetPan ( const int iChanID, const float fNewPan ) { QMutexLocker locker ( &Mutex ); // set value (make sure channel ID is in range) if ( ( iChanID >= 0 ) && ( iChanID < MAX_NUM_CHANNELS ) ) { vecfPannings[iChanID] = fNewPan; } } float CChannel::GetPan ( const int iChanID ) { QMutexLocker locker ( &Mutex ); // get value (make sure channel ID is in range) if ( ( iChanID >= 0 ) && ( iChanID < MAX_NUM_CHANNELS ) ) { return vecfPannings[iChanID]; } else { return 0; } } void CChannel::SetChanInfo ( const CChannelCoreInfo& NChanInf ) { // apply value (if a new channel or different from previous one) if ( !bIsIdentified || ChannelInfo != NChanInf ) { bIsIdentified = true; // Indicate we have received channel info ChannelInfo = NChanInf; // fire message that the channel info has changed emit ChanInfoHasChanged(); } } QString CChannel::GetName() { // make sure the string is not written at the same time when it is // read here -> use mutex to secure access QMutexLocker locker ( &Mutex ); return ChannelInfo.strName; } void CChannel::OnSendProtMessage ( CVector vecMessage ) { // only send messages if protocol is enabled, otherwise delete complete // queue if ( ProtocolIsEnabled() ) { // emit message to actually send the data emit MessReadyForSending ( vecMessage ); } else { // delete send message queue Protocol.Reset(); } } void CChannel::OnJittBufSizeChange ( int iNewJitBufSize ) { // for server apply setting, for client emit message if ( bIsServer ) { // first check for special case: auto setting if ( iNewJitBufSize == AUTO_NET_BUF_SIZE_FOR_PROTOCOL ) { SetDoAutoSockBufSize ( true ); } else { // manual setting is received, turn OFF auto setting and apply new value SetDoAutoSockBufSize ( false ); SetSockBufNumFrames ( iNewJitBufSize, true ); } } else { emit JittBufSizeChanged ( iNewJitBufSize ); } } void CChannel::OnChangeChanGain ( int iChanID, float fNewGain ) { SetGain ( iChanID, fNewGain ); } void CChannel::OnChangeChanPan ( int iChanID, float fNewPan ) { SetPan ( iChanID, fNewPan ); } void CChannel::OnChangeChanInfo ( CChannelCoreInfo ChanInfo ) { SetChanInfo ( ChanInfo ); } void CChannel::OnNetTranspPropsReceived ( CNetworkTransportProps NetworkTransportProps ) { // only the server shall act on network transport properties message if ( bIsServer ) { // OPUS and OPUS64 codecs are the only supported codecs right now if ( ( NetworkTransportProps.eAudioCodingType != CT_OPUS ) && ( NetworkTransportProps.eAudioCodingType != CT_OPUS64 ) ) { Protocol.CreateOpusSupportedMes(); return; } Mutex.lock(); { // store received parameters eAudioCompressionType = NetworkTransportProps.eAudioCodingType; iNumAudioChannels = static_cast ( NetworkTransportProps.iNumAudioChannels ); iNetwFrameSizeFact = NetworkTransportProps.iBlockSizeFact; iNetwFrameSize = static_cast ( NetworkTransportProps.iBaseNetworkPacketSize ); bUseSequenceNumber = ( NetworkTransportProps.eFlags == NF_WITH_COUNTER ); if ( bUseSequenceNumber ) { iCeltNumCodedBytes = iNetwFrameSize - 1; // per definition 1 byte counter } else { iCeltNumCodedBytes = iNetwFrameSize; } // update maximum number of frames for fade in counter (only needed for server) // and audio frame size if ( eAudioCompressionType == CT_OPUS ) { iFadeInCntMax = FADE_IN_NUM_FRAMES_DBLE_FRAMESIZE / iNetwFrameSizeFact; iAudioFrameSizeSamples = DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES; } else { iFadeInCntMax = FADE_IN_NUM_FRAMES / iNetwFrameSizeFact; iAudioFrameSizeSamples = SYSTEM_FRAME_SIZE_SAMPLES; } // the fade-in counter maximum value may have changed, make sure the fade-in counter // is not larger than the allowed maximum value iFadeInCnt = std::min ( iFadeInCnt, iFadeInCntMax ); MutexSocketBuf.lock(); { // update socket buffer (the network block size is a multiple of the // minimum network frame size) SockBuf.SetUseDoubleSystemFrameSize ( eAudioCompressionType == CT_OPUS ); // NOTE must be set BEFORE the init() SockBuf.Init ( iCeltNumCodedBytes, iCurSockBufNumFrames, bUseSequenceNumber ); } MutexSocketBuf.unlock(); MutexConvBuf.lock(); { // init conversion buffer ConvBuf.Init ( iNetwFrameSize * iNetwFrameSizeFact, bUseSequenceNumber ); } MutexConvBuf.unlock(); } Mutex.unlock(); } } void CChannel::OnReqNetTranspProps() { // fill network transport properties struct from current settings and send it Protocol.CreateNetwTranspPropsMes ( GetNetworkTransportPropsFromCurrentSettings() ); } void CChannel::OnReqSplitMessSupport() { // activate split messages in our protocol (client) and return answer message to the server Protocol.SetSplitMessageSupported ( true ); Protocol.CreateSplitMessSupportedMes(); } CNetworkTransportProps CChannel::GetNetworkTransportPropsFromCurrentSettings() { // set network flags ENetwFlags eFlags = NF_NONE; if ( bUseSequenceNumber ) { eFlags = NF_WITH_COUNTER; } // use current stored settings of the channel to fill the network transport // properties structure return CNetworkTransportProps ( static_cast ( iNetwFrameSize ), static_cast ( iNetwFrameSizeFact ), static_cast ( iNumAudioChannels ), SYSTEM_SAMPLE_RATE_HZ, eAudioCompressionType, eFlags, 0 ); } void CChannel::Disconnect() { // we only have to disconnect the channel if it is actually connected if ( IsConnected() ) { // set time out counter to a small value > 0 so that the next time a // received audio block is queried, the disconnection is performed // (assuming that no audio packet is received in the meantime) iConTimeOut = 1; // a small number > 0 } } void CChannel::PutProtocolData ( const int iRecCounter, const int iRecID, const CVector& vecbyMesBodyData, const CHostAddress& RecHostAddr ) { // Only process protocol message if: // - for client only: the packet comes from the server we want to talk to // - the channel is enabled // - the protocol mechanism is enabled if ( ( bIsServer || ( GetAddress() == RecHostAddr ) ) && IsEnabled() && ProtocolIsEnabled() ) { // parse the message assuming this is a regular protocol message Protocol.ParseMessageBody ( vecbyMesBodyData, iRecCounter, iRecID ); } } EPutDataStat CChannel::PutAudioData ( const CVector& vecbyData, const int iNumBytes, CHostAddress RecHostAddr ) { // init return state EPutDataStat eRet = PS_GEN_ERROR; // Only process audio data if: // - for client only: the packet comes from the server we want to talk to // - the channel is enabled if ( ( bIsServer || ( GetAddress() == RecHostAddr ) ) && IsEnabled() ) { MutexSocketBuf.lock(); { // only process audio if packet has correct size if ( iNumBytes == ( iNetwFrameSize * iNetwFrameSizeFact ) ) { // store new packet in jitter buffer if ( SockBuf.Put ( vecbyData, iNumBytes ) ) { eRet = PS_AUDIO_OK; } else { eRet = PS_AUDIO_ERR; } // manage audio fade-in counter, after channel is identified if ( iFadeInCnt < iFadeInCntMax && bIsIdentified ) { iFadeInCnt++; } } else { // the protocol parsing failed and this was no audio block, // we treat this as protocol error (unknown packet) eRet = PS_PROT_ERR; } // All network packets except of valid protocol messages // regardless if they are valid or invalid audio packets lead to // a state change to a connected channel. // This is because protocol messages can only be sent on a // connected channel and the client has to inform the server // about the audio packet properties via the protocol. // check if channel was not connected, this is a new connection if ( !IsConnected() ) { // overwrite status eRet = PS_NEW_CONNECTION; // init audio fade-in counter iFadeInCnt = 0; // init level meter SignalLevelMeter.Reset(); } // reset time-out counter (note that this must be done after the // "IsConnected()" query above) ResetTimeOutCounter(); } MutexSocketBuf.unlock(); } else { eRet = PS_AUDIO_INVALID; } return eRet; } EGetDataStat CChannel::GetData ( CVector& vecbyData, const int iNumBytes ) { EGetDataStat eGetStatus; MutexSocketBuf.lock(); { // the socket access must be inside a mutex const bool bSockBufState = SockBuf.Get ( vecbyData, iNumBytes ); // decrease time-out counter if ( iConTimeOut > 0 ) { // subtract the number of samples of the current block since the // time out counter is based on samples not on blocks (definition: // always one atomic block is get by using the GetData() function // where the atomic block size is "iAudioFrameSizeSamples") iConTimeOut -= iAudioFrameSizeSamples; if ( iConTimeOut <= 0 ) { // channel is just disconnected eGetStatus = GS_CHAN_NOW_DISCONNECTED; iConTimeOut = 0; // make sure we do not have negative values // reset network transport properties ResetNetworkTransportProperties(); } else { if ( bSockBufState ) { // everything is ok eGetStatus = GS_BUFFER_OK; } else { // channel is not yet disconnected but no data in buffer eGetStatus = GS_BUFFER_UNDERRUN; } } } else { // channel is disconnected eGetStatus = GS_CHAN_NOT_CONNECTED; } } MutexSocketBuf.unlock(); // in case we are just disconnected, we have to fire a message if ( eGetStatus == GS_CHAN_NOW_DISCONNECTED ) { // reset the protocol Protocol.Reset(); // emit message emit Disconnected(); } return eGetStatus; } void CChannel::PrepAndSendPacket ( CHighPrioSocket* pSocket, const CVector& vecbyNPacket, const int iNPacketLen ) { // From v3.8.0 onwards, a server will not send audio to a client until that client has sent channel info. // This addresses #1243 but means that clients earlier than v3.3.0 (24 Feb 2013) will no longer be compatible. if ( bIsServer && !bIsIdentified ) { return; } QMutexLocker locker ( &MutexConvBuf ); // use conversion buffer to convert sound card block size in network // block size and take care of optional sequence number (note that // the sequence number wraps automatically) if ( ConvBuf.Put ( vecbyNPacket, iNPacketLen, iSendSequenceNumber++ ) ) { pSocket->SendPacket ( ConvBuf.GetAll(), GetAddress() ); } } double CChannel::UpdateAndGetLevelForMeterdB ( const CVector& vecsAudio, const int iInSize, const bool bIsStereoIn ) { // update the signal level meter and immediately return the current value SignalLevelMeter.Update ( vecsAudio, iInSize, bIsStereoIn ); return SignalLevelMeter.GetLevelForMeterdBLeftOrMono(); } int CChannel::GetUploadRateKbps() { const int iAudioSizeOut = iNetwFrameSizeFact * iAudioFrameSizeSamples; // we assume that the UDP packet which is transported via IP has an // additional header size of ("Network Music Performance (NMP) in narrow // band networks; Carot, Kraemer, Schuller; 2006") // 8 (UDP) + 20 (IP without optional fields) = 28 bytes // 2 (PPP) + 6 (PPPoE) + 18 (MAC) = 26 bytes // 5 (RFC1483B) + 8 (AAL) + 10 (ATM) = 23 bytes return ( iNetwFrameSize * iNetwFrameSizeFact + 28 + 26 + 23 /* header */ ) * 8 /* bits per byte */ * SYSTEM_SAMPLE_RATE_HZ / iAudioSizeOut / 1000; } void CChannel::UpdateSocketBufferSize() { // just update the socket buffer size if auto setting is enabled, otherwise // do nothing if ( bDoAutoSockBufSize ) { // use auto setting result from channel, make sure we preserve the // buffer memory since we just adjust the size here SetSockBufNumFrames ( SockBuf.GetAutoSetting(), true ); } } jamulus-3.9.1+dfsg/src/recorder/0000755000175000017500000000000014340334543015550 5ustar vimervimerjamulus-3.9.1+dfsg/src/recorder/jamrecorder.h0000644000175000017500000001427414340334543020226 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2020-2022 * * Author(s): * pljones * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #include #include #include #include #include "../util.h" #include "../channel.h" #include "creaperproject.h" #include "cwavestream.h" namespace recorder { class CJamClientConnection : public QObject { Q_OBJECT public: CJamClientConnection ( const int _numAudioChannels, const qint64 _startFrame, const qint64 _length, const QString _name, const QString _fileName ) : numAudioChannels ( _numAudioChannels ), startFrame ( _startFrame ), length ( _length ), name ( _name ), fileName ( _fileName ) {} int Format() { return numAudioChannels; } qint64 StartFrame() { return startFrame; } qint64 Length() { return length; } QString Name() { return name; } QString FileName() { return fileName; } private: const int numAudioChannels; const qint64 startFrame; const qint64 length; const QString name; const QString fileName; }; class CJamClient : public QObject { Q_OBJECT public: CJamClient ( const qint64 frame, const int numChannels, const QString name, const CHostAddress address, const QDir recordBaseDir ); void Frame ( const QString name, const CVector& pcm, int iServerFrameSizeSamples ); void Disconnect(); qint64 StartFrame() { return startFrame; } qint64 FrameCount() { return frameCount; } uint16_t NumAudioChannels() { return numChannels; } QString ClientName() { return TranslateChars ( name ) .leftJustified ( 4, '_', false ) .append ( "-" ) .append ( TranslateChars ( address.toString ( CHostAddress::EStringMode::SM_IP_NO_LAST_BYTE_PORT ) ) ); } CHostAddress ClientAddress() { return address; } QString FileName() { return filename; } private: QString TranslateChars ( const QString& input ) const; const qint64 startFrame; const uint16_t numChannels; QString name; const CHostAddress address; QString filename; QFile* wavFile; QDataStream* out; qint64 frameCount = 0; }; class CJamSession : public QObject { Q_OBJECT public: CJamSession ( QDir recordBaseDir ); virtual ~CJamSession(); void Frame ( const int iChID, const QString name, const CHostAddress address, const int numAudioChannels, const CVector data, int iServerFrameSizeSamples ); void End(); QVector Clients() { return vecptrJamClients; } QMap> Tracks(); QString Name() { return sessionDir.dirName(); } const QDir SessionDir() { return sessionDir; } void DisconnectClient ( int iChID ); static QMap> TracksFromSessionDir ( const QString& name, int iServerFrameSizeSamples ); private: CJamSession(); const QDir sessionDir; qint64 currentFrame; int chIdDisconnected; QVector vecptrJamClients; QList jamClientConnections; }; class CJamRecorder : public QObject { Q_OBJECT public: CJamRecorder ( const QString strRecordingBaseDir, const int iServerFrameSizeSamples ) : recordBaseDir ( strRecordingBaseDir ), iServerFrameSizeSamples ( iServerFrameSizeSamples ), isRecording ( false ), currentSession ( nullptr ) {} /** * @brief Create recording directory, if necessary, and connect signal handlers * @param server Server object emitting signals */ QString Init(); /** * @brief SessionDirToReaper Method that allows an RPP file to be recreated * @param strSessionDirName Where the session wave files are * @param serverFrameSizeSamples What the server frame size was for the session */ static void SessionDirToReaper ( QString& strSessionDirName, int serverFrameSizeSamples ); private: void Start(); void ReaperProjectFromCurrentSession(); void AudacityLofFromCurrentSession(); QDir recordBaseDir; int iServerFrameSizeSamples; bool isRecording; CJamSession* currentSession; QMutex ChIdMutex; signals: void RecordingSessionStarted ( QString sessionDir ); void RecordingFailed ( QString error ); public slots: /** * @brief Handle last client leaving the server, ends the recording. */ void OnEnd(); /** * @brief Handle request to end one session and start a new one. */ void OnTriggerSession(); /** * @brief Handle application stopping */ void OnAboutToQuit(); /** * @brief Handle an existing client leaving the server. * @param iChID channel number of client */ void OnDisconnected ( int iChID ); /** * @brief Handle a frame of data to process */ void OnFrame ( const int iChID, const QString name, const CHostAddress address, const int numAudioChannels, const CVector data ); }; } // namespace recorder jamulus-3.9.1+dfsg/src/recorder/creaperproject.cpp0000644000175000017500000001075114340334543021270 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2020-2022 * * Author(s): * pljones * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include "creaperproject.h" /** * @brief operator << Write details of the STrackItem to the QTextStream * @param os the QTextStream * @param trackItem the STrackItem * @return the QTextStream * * Note: unused? */ QTextStream& operator<< ( QTextStream& os, const recorder::STrackItem& trackItem ) { os << "_track( " << "numAudioChannels(" << trackItem.numAudioChannels << ")" << ", startFrame(" << trackItem.startFrame << ")" << ", frameCount(" << trackItem.frameCount << ")" << ", fileName(" << trackItem.fileName << ")" << " );"; return os; } /******************************************************************************\ * recorder methods * \******************************************************************************/ using namespace recorder; // Reaper Project writer ------------------------------------------------------- /** * @brief CReaperItem::CReaperItem Construct a Reaper RPP "" for a given RIFF WAVE file * @param name the item name * @param trackItem the details of where the item is in the track, along with the RIFF WAVE filename * @param iid the sequential item id */ CReaperItem::CReaperItem ( const QString& name, const STrackItem& trackItem, const qint32& iid, int frameSize ) { QString wavName = trackItem.fileName; // assume RPP in same location... QTextStream sOut ( &out ); sOut << " " << '\n' << " >"; sOut.flush(); } /** * @brief CReaperTrack::CReaperTrack Construct a Reaper RPP "" for a given list of track items * @param name the track name * @param iid the sequential track id * @param items the list of items in the track */ CReaperTrack::CReaperTrack ( QString name, qint32& iid, QList items, int frameSize ) { QTextStream sOut ( &out ); sOut << " "; sOut.flush(); } /** * @brief CReaperProject::CReaperProject Construct a Reaper RPP "" for a given list of tracks * @param tracks the list of tracks */ CReaperProject::CReaperProject ( QMap> tracks, int frameSize ) { QTextStream sOut ( &out ); sOut << ""; sOut.flush(); } jamulus-3.9.1+dfsg/src/recorder/cwavestream.cpp0000644000175000017500000001304514340334543020600 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2020-2022 * * Author(s): * pljones * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include "cwavestream.h" /******************************************************************************\ * Overrides in global namespace * \******************************************************************************/ /** * @brief operator << Emit a hdr_riff object to a QDataStream * @param os a QDataStream * @param obj a hdr_riff object * @return the QDataStream passed */ recorder::CWaveStream& operator<< ( recorder::CWaveStream& os, const recorder::HdrRiff& obj ) { (QDataStream&) os << obj.chunkId << obj.chunkSize << obj.format; return os; } /** * @brief operator << Emit a fmtSubChunk object to a QDataStream * @param os a QDataStream * @param obj a fmtSubChunk object * @return the QDataStream passed */ recorder::CWaveStream& operator<< ( recorder::CWaveStream& os, const recorder::FmtSubChunk& obj ) { (QDataStream&) os << obj.chunkId << obj.chunkSize << obj.audioFormat << obj.numChannels << obj.sampleRate << obj.byteRate << obj.blockAlign << obj.bitsPerSample; return os; } /** * @brief operator << Emit a dataSubChunkHdr object to a QDataStream * @param os a QDataStream * @param obj a dataSubChunkHdr object * @return the QDataStream passed */ recorder::CWaveStream& operator<< ( recorder::CWaveStream& os, const recorder::DataSubChunkHdr& obj ) { (QDataStream&) os << obj.chunkId << obj.chunkSize; return os; } /******************************************************************************\ * Implementations of recorder.CWaveStream methods * \******************************************************************************/ using namespace recorder; CWaveStream::CWaveStream ( const uint16_t numChannels ) : QDataStream(), numChannels ( numChannels ), initialPos ( device()->pos() ), initialByteOrder ( byteOrder() ) { waveStreamHeaders(); } CWaveStream::CWaveStream ( QIODevice* iod, const uint16_t numChannels ) : QDataStream ( iod ), numChannels ( numChannels ), initialPos ( device()->pos() ), initialByteOrder ( byteOrder() ) { waveStreamHeaders(); } CWaveStream::CWaveStream ( QByteArray* iod, QIODevice::OpenMode flags, const uint16_t numChannels ) : QDataStream ( iod, flags ), numChannels ( numChannels ), initialPos ( device()->pos() ), initialByteOrder ( byteOrder() ) { waveStreamHeaders(); } CWaveStream::CWaveStream ( const QByteArray& ba, const uint16_t numChannels ) : QDataStream ( ba ), numChannels ( numChannels ), initialPos ( device()->pos() ), initialByteOrder ( byteOrder() ) { waveStreamHeaders(); } void CWaveStream::waveStreamHeaders() { static const HdrRiff scHdrRiff; const FmtSubChunk cFmtSubChunk ( numChannels ); static const DataSubChunkHdr scDataSubChunkHdr; setByteOrder ( LittleEndian ); *this << scHdrRiff << cFmtSubChunk << scDataSubChunkHdr; } void CWaveStream::finalise() { static const uint64_t hdrRiffChunkSize = sizeof ( uint32_t ) + sizeof ( uint32_t ) + sizeof ( uint32_t ); static const uint64_t fmtSubChunkSize = sizeof ( uint32_t ) + sizeof ( uint32_t ) + sizeof ( uint16_t ) + sizeof ( uint16_t ) + sizeof ( uint32_t ) + sizeof ( uint32_t ) + sizeof ( uint16_t ) + sizeof ( uint16_t ); static const uint64_t hdrRiffChunkSizeOffset = sizeof ( uint32_t ); static const uint64_t dataSubChunkHdrChunkSizeOffset = hdrRiffChunkSize + fmtSubChunkSize + sizeof ( uint32_t ); const int64_t currentPos = this->device()->pos(); const uint64_t fileLengthRiff = static_cast ( currentPos - initialPos - ( hdrRiffChunkSizeOffset + sizeof ( uint32_t ) ) ); const uint64_t fileLengthData = static_cast ( currentPos - initialPos - ( dataSubChunkHdrChunkSizeOffset + sizeof ( uint32_t ) ) ); // check if lengths are within the range of the WAV file format if ( fileLengthRiff < 0x100000000ULL && fileLengthData < 0x100000000ULL ) { QDataStream& out = static_cast ( *this ); // Overwrite hdr_riff.chunkSize this->device()->seek ( initialPos + hdrRiffChunkSizeOffset ); out << static_cast ( fileLengthRiff ); // Overwrite dataSubChunkHdr.chunkSize this->device()->seek ( initialPos + dataSubChunkHdrChunkSizeOffset ); out << static_cast ( fileLengthData ); // And restore the position this->device()->seek ( currentPos ); } // restore the byte order setByteOrder ( initialByteOrder ); } jamulus-3.9.1+dfsg/src/recorder/cwavestream.h0000644000175000017500000000731614340334543020251 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2020-2022 * * Author(s): * pljones * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #include #include #include namespace recorder { inline QString secondsAt48K ( const qint64 frames, const int frameSize ) { return QString::number ( static_cast ( frames * frameSize ) / 48000, 'f', 14 ); } struct STrackItem { STrackItem ( int numAudioChannels, qint64 startFrame, qint64 frameCount, QString fileName ) : numAudioChannels ( numAudioChannels ), startFrame ( startFrame ), frameCount ( frameCount ), fileName ( fileName ) {} int numAudioChannels; qint64 startFrame; qint64 frameCount; QString fileName; }; class HdrRiff { public: HdrRiff() {} static const uint32_t chunkId = 0x46464952; // RIFF static const uint32_t chunkSize = 0x00000000; // unknown static const uint32_t format = 0x45564157; // WAVE }; class FmtSubChunk { public: FmtSubChunk ( const uint16_t _numChannels ) : numChannels ( _numChannels ), byteRate ( sampleRate * numChannels * bitsPerSample / 8 ), blockAlign ( numChannels * bitsPerSample / 8 ) {} static const uint32_t chunkId = 0x20746d66; // "fmt " static const uint32_t chunkSize = 16; // bytes in fmtSubChunk after chunkSize static const uint16_t audioFormat = 1; // PCM const uint16_t numChannels; // 1 for mono, 2 for joy... uh, stereo static const uint32_t sampleRate = 48000; // because it's Jamulus const uint32_t byteRate; // sampleRate * numChannels * bitsPerSample/8 const uint16_t blockAlign; // numChannels * bitsPerSample/8 static const uint16_t bitsPerSample = 16; }; class DataSubChunkHdr { public: DataSubChunkHdr() {} static const uint32_t chunkId = 0x61746164; // "data" static const uint32_t chunkSize = 0x7ffff000; // magic for unspecified length }; class CWaveStream : public QDataStream { public: CWaveStream ( const uint16_t numChannels ); explicit CWaveStream ( QIODevice* iod, const uint16_t numChannels ); CWaveStream ( QByteArray* iod, QIODevice::OpenMode flags, const uint16_t numChannels ); CWaveStream ( const QByteArray& ba, const uint16_t numChannels ); void finalise(); private: void waveStreamHeaders(); const uint16_t numChannels; const int64_t initialPos; const ByteOrder initialByteOrder; }; } // namespace recorder recorder::CWaveStream& operator<< ( recorder::CWaveStream& out, recorder::HdrRiff& hdrRiff ); recorder::CWaveStream& operator<< ( recorder::CWaveStream& out, recorder::FmtSubChunk& fmtSubChunk ); recorder::CWaveStream& operator<< ( recorder::CWaveStream& out, recorder::DataSubChunkHdr& dataSubChunkHdr ); jamulus-3.9.1+dfsg/src/recorder/creaperproject.h0000644000175000017500000000367714340334543020746 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2020-2022 * * Author(s): * pljones * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #include #include #include #include "util.h" #include "cwavestream.h" namespace recorder { class CReaperItem : public QObject { Q_OBJECT public: CReaperItem ( const QString& name, const STrackItem& trackItem, const qint32& iid, int frameSize ); QString toString() { return out; } private: const QUuid iguid = QUuid::createUuid(); const QUuid guid = QUuid::createUuid(); QString out; }; class CReaperTrack : public QObject { Q_OBJECT public: CReaperTrack ( QString name, qint32& iid, QList items, int frameSize ); QString toString() { return out; } private: QUuid trackId = QUuid::createUuid(); QString out; }; class CReaperProject : public QObject { Q_OBJECT public: CReaperProject ( QMap> tracks, int frameSize ); QString toString() { return out; } private: QString out; }; } // namespace recorder jamulus-3.9.1+dfsg/src/recorder/jamcontroller.cpp0000644000175000017500000001466614340334543021144 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2020-2022 * * Author(s): * pljones * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include "jamcontroller.h" using namespace recorder; CJamController::CJamController ( CServer* pNServer ) : pServer ( pNServer ), bRecorderInitialised ( false ), bEnableRecording ( false ), strRecordingDir ( "" ), pthJamRecorder ( nullptr ), pJamRecorder ( nullptr ) {} void CJamController::RequestNewRecording() { if ( bRecorderInitialised && bEnableRecording ) { emit RestartRecorder(); } } void CJamController::SetEnableRecording ( bool bNewEnableRecording, bool isRunning ) { if ( bRecorderInitialised ) { // message only if the state appears to change if ( bEnableRecording != bNewEnableRecording ) { qInfo() << qUtf8Printable ( QString ( "Recording state: %1" ).arg ( bNewEnableRecording ? "enabled" : "disabled" ) ); } // note that this block executes regardless of whether // what appears to be a change is being applied, to ensure // the requested state is the result bEnableRecording = bNewEnableRecording; if ( !bEnableRecording ) { emit StopRecorder(); } else if ( !isRunning ) { // This dirty hack is for the GUI. It doesn't care. emit StopRecorder(); } } } void CJamController::SetRecordingDir ( QString newRecordingDir, int iServerFrameSizeSamples, bool bDisableRecording ) { if ( bRecorderInitialised && pthJamRecorder != nullptr ) { // We have a thread and we want to start a new one. // We only want one running. // This could take time, unfortunately. // Hopefully changing recording directory will NOT happen during a long jam... emit EndRecorderThread(); pthJamRecorder->wait(); delete pthJamRecorder; pthJamRecorder = nullptr; } if ( !newRecordingDir.isEmpty() ) { pJamRecorder = new recorder::CJamRecorder ( newRecordingDir, iServerFrameSizeSamples ); strRecorderErrMsg = pJamRecorder->Init(); bRecorderInitialised = ( strRecorderErrMsg == QString() ); bEnableRecording = bRecorderInitialised && !bDisableRecording; qInfo() << qUtf8Printable ( QString ( "Recording state: %1" ).arg ( bEnableRecording ? "enabled" : "disabled" ) ); } else { // This is the only time this is ever true - UI needs to handle it strRecorderErrMsg = QString(); bRecorderInitialised = false; bEnableRecording = false; qInfo() << "Recording state not initialised"; } if ( bRecorderInitialised ) { strRecordingDir = newRecordingDir; pthJamRecorder = new QThread(); pthJamRecorder->setObjectName ( "JamRecorder" ); pJamRecorder->moveToThread ( pthJamRecorder ); // QT signals QObject::connect ( pthJamRecorder, &QThread::finished, pJamRecorder, &QObject::deleteLater ); QObject::connect ( QCoreApplication::instance(), &QCoreApplication::aboutToQuit, pJamRecorder, &CJamRecorder::OnAboutToQuit, Qt::ConnectionType::BlockingQueuedConnection ); // from the controller to the recorder QObject::connect ( this, &CJamController::RestartRecorder, pJamRecorder, &CJamRecorder::OnTriggerSession ); QObject::connect ( this, &CJamController::StopRecorder, pJamRecorder, &CJamRecorder::OnEnd ); QObject::connect ( this, &CJamController::EndRecorderThread, pJamRecorder, &CJamRecorder::OnAboutToQuit, Qt::ConnectionType::BlockingQueuedConnection ); // from the server to the recorder QObject::connect ( this, &CJamController::Stopped, pJamRecorder, &CJamRecorder::OnEnd ); QObject::connect ( this, &CJamController::ClientDisconnected, pJamRecorder, &CJamRecorder::OnDisconnected ); qRegisterMetaType> ( "CVector" ); QObject::connect ( this, &CJamController::AudioFrame, pJamRecorder, &CJamRecorder::OnFrame ); // from the recorder to the server QObject::connect ( pJamRecorder, &CJamRecorder::RecordingSessionStarted, this, &CJamController::RecordingSessionStarted ); // from the recorder to the controller QObject::connect ( pJamRecorder, &CJamRecorder::RecordingFailed, this, &CJamController::OnRecordingFailed ); pthJamRecorder->start ( QThread::NormalPriority ); } else { strRecordingDir = ""; } } void CJamController::OnRecordingFailed ( QString error ) { if ( !bEnableRecording ) { // Recording has already been stopped, possibly // by a previous OnRecordingFailed call from another client/thread. return; } strRecorderErrMsg = error; qWarning() << "Could not start recording:" << error; // Turn off recording until it is manually re-enabled via UI or signals. // This needs to be done from the CServer side to cover all relevant // state. pServer->SetEnableRecording ( false ); } ERecorderState CJamController::GetRecorderState() { // return recorder state if ( bRecorderInitialised ) { if ( bEnableRecording ) { return RS_RECORDING; } else { return RS_NOT_ENABLED; } } else { return RS_NOT_INITIALISED; } } jamulus-3.9.1+dfsg/src/recorder/jamrecorder.cpp0000644000175000017500000005152514340334543020561 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2020-2022 * * Author(s): * pljones * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include "jamrecorder.h" using namespace recorder; /* ******************************************************************************************************** * CJamClient * ********************************************************************************************************/ /** * @brief CJamClient::CJamClient * @param frame Start frame of the client within the session * @param numChannels 1 for mono, 2 for stereo * @param name The client's current name * @param address IP and Port * @param recordBaseDir Session recording directory * * Creates a file for the raw PCM data and sets up a QDataStream to which to write received frames. * The data is stored Little Endian. */ CJamClient::CJamClient ( const qint64 frame, const int _numChannels, const QString name, const CHostAddress address, const QDir recordBaseDir ) : startFrame ( frame ), numChannels ( static_cast ( _numChannels ) ), name ( name ), address ( address ), out ( nullptr ) { // At this point we may not have much of a name QString fileName = ClientName() + "-" + QString::number ( frame ) + "-" + QString::number ( _numChannels ); QString affix = ""; while ( recordBaseDir.exists ( fileName + affix + ".wav" ) ) { affix = affix.length() == 0 ? "_1" : "_" + QString::number ( affix.remove ( 0, 1 ).toInt() + 1 ); } fileName = fileName + affix + ".wav"; wavFile = new QFile ( recordBaseDir.absoluteFilePath ( fileName ) ); if ( !wavFile->open ( QFile::OpenMode ( QIODevice::OpenModeFlag::ReadWrite ) ) ) // need to allow rewriting headers { throw CGenErr ( "Could not write to WAV file " + wavFile->fileName() ); } out = new CWaveStream ( wavFile, numChannels ); filename = wavFile->fileName(); } /** * @brief CJamClient::Frame Handle a frame of PCM data from a client connected to the server * @param _name The client's current name * @param pcm The PCM data */ void CJamClient::Frame ( const QString _name, const CVector& pcm, int iServerFrameSizeSamples ) { name = _name; for ( int i = 0; i < numChannels * iServerFrameSizeSamples; i++ ) { *out << pcm[i]; } frameCount++; } /** * @brief CJamClient::Disconnect Clean up after a disconnected client */ void CJamClient::Disconnect() { if ( out ) { static_cast ( out )->finalise(); delete out; out = nullptr; } wavFile->close(); delete wavFile; wavFile = nullptr; } /** * @brief CJamClient::TranslateChars Replace non-ASCII chars with nearest equivalent, if any, and change all punctuation to _ */ QString CJamClient::TranslateChars ( const QString& input ) const { // Allow letters and numbers // clang-format off static const char charmap[256] = { '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '_', '_', '_', '_', '_', '_', '_', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '_', '_', '_', '_', '_', '_', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', 'S', '_', 'O', '_', 'Z', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', 's', '_', 'o', '_', 'z', 'Y', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '2', '3', '_', 'u', '_', '_', '_', '1', '_', '_', '_', '_', '_', '_', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'C', 'E', 'E', 'E', 'E', 'I', 'I', 'I', 'I', 'D', 'N', 'O', 'O', 'O', 'O', 'O', 'x', 'O', 'U', 'U', 'U', 'U', 'Y', 'P', 'S', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'c', 'e', 'e', 'e', 'e', 'i', 'i', 'i', 'i', 'd', 'n', 'o', 'o', 'o', 'o', 'o', '_', 'o', 'u', 'u', 'u', 'u', 'y', 'p', 'y' }; // clang-format on QByteArray r = input.toLatin1(); for ( auto& c : r ) { unsigned char uc = c; c = charmap[uc]; } return QString::fromLatin1 ( r ); } /* ******************************************************************************************************** * CJamSession * ********************************************************************************************************/ /** * @brief CJamSession::CJamSession Construct a new jam recording session * @param recordBaseDir The recording base directory * * Each session is stored into its own subdirectory of the recording base directory. */ CJamSession::CJamSession ( QDir recordBaseDir ) : sessionDir ( QDir ( recordBaseDir.absoluteFilePath ( "Jam-" + QDateTime().currentDateTimeUtc().toString ( "yyyyMMdd-HHmmsszzz" ) ) ) ), currentFrame ( 0 ), chIdDisconnected ( -1 ), vecptrJamClients ( MAX_NUM_CHANNELS ), jamClientConnections() { QFileInfo fi ( sessionDir.absolutePath() ); fi.setCaching ( false ); if ( !fi.exists() && !QDir().mkpath ( sessionDir.absolutePath() ) ) { throw CGenErr ( sessionDir.absolutePath() + " does not exist and could not be created" ); } if ( !fi.isDir() ) { throw CGenErr ( sessionDir.absolutePath() + " exists but is not a directory" ); } if ( !fi.isWritable() ) { throw CGenErr ( sessionDir.absolutePath() + " is a directory but cannot be written to" ); } // Explicitly set all the pointers to "empty" vecptrJamClients.fill ( nullptr ); } /** * @brief CJamSession::~CJamSession */ CJamSession::~CJamSession() { // free up any active jamClientConnections for ( int i = 0; i < jamClientConnections.count(); i++ ) { if ( jamClientConnections[i] ) { delete jamClientConnections[i]; jamClientConnections[i] = nullptr; } } } /** * @brief CJamSession::DisconnectClient Capture details of the departing client's connection * @param iChID the channel id of the client that disconnected */ void CJamSession::DisconnectClient ( int iChID ) { vecptrJamClients[iChID]->Disconnect(); jamClientConnections.append ( new CJamClientConnection ( vecptrJamClients[iChID]->NumAudioChannels(), vecptrJamClients[iChID]->StartFrame(), vecptrJamClients[iChID]->FrameCount(), vecptrJamClients[iChID]->ClientName(), vecptrJamClients[iChID]->FileName() ) ); delete vecptrJamClients[iChID]; vecptrJamClients[iChID] = nullptr; chIdDisconnected = iChID; } /** * @brief CJamSession::Frame Process a frame emitted for a client by the server * @param iChID the client channel id * @param name the client name * @param address the client IP and port number * @param numAudioChannels the client number of audio channels * @param data the frame data * * Manages changes that affect how the recording is stored - i.e. if the number of audio channels changes, we need a new file. * Files are grouped by IP and port number, so if either of those change for a connection, we also start a new file. * * Also manages the overall current frame counter for the session. */ void CJamSession::Frame ( const int iChID, const QString name, const CHostAddress address, const int numAudioChannels, const CVector data, int iServerFrameSizeSamples ) { if ( iChID == chIdDisconnected ) { // DisconnectClient has just been called for this channel - this frame is "too late" chIdDisconnected = -1; return; } if ( vecptrJamClients[iChID] == nullptr ) { // then we have not seen this client this session vecptrJamClients[iChID] = new CJamClient ( currentFrame, numAudioChannels, name, address, sessionDir ); } else if ( numAudioChannels != vecptrJamClients[iChID]->NumAudioChannels() || address.InetAddr != vecptrJamClients[iChID]->ClientAddress().InetAddr || address.iPort != vecptrJamClients[iChID]->ClientAddress().iPort ) { DisconnectClient ( iChID ); if ( numAudioChannels == 0 ) { vecptrJamClients[iChID] = nullptr; } else { vecptrJamClients[iChID] = new CJamClient ( currentFrame, numAudioChannels, name, address, sessionDir ); } } if ( vecptrJamClients[iChID] == nullptr ) { // Frame allegedly from iChID but unable to establish client details return; } vecptrJamClients[iChID]->Frame ( name, data, iServerFrameSizeSamples ); // If _any_ connected client frame steps past currentFrame, increase currentFrame if ( vecptrJamClients[iChID]->StartFrame() + vecptrJamClients[iChID]->FrameCount() > currentFrame ) { currentFrame++; } } /** * @brief CJamSession::End Clean up any "hanging" clients when the server thinks they all left */ void CJamSession::End() { for ( int iChID = 0; iChID < vecptrJamClients.size(); iChID++ ) { if ( vecptrJamClients[iChID] != nullptr ) { DisconnectClient ( iChID ); vecptrJamClients[iChID] = nullptr; } } } /** * @brief CJamSession::Tracks Retrieve a map of (latest) client name to connection items * @return a map of (latest) client name to connection items */ QMap> CJamSession::Tracks() { QMap> tracks; for ( int i = 0; i < jamClientConnections.count(); i++ ) { STrackItem track ( jamClientConnections[i]->Format(), jamClientConnections[i]->StartFrame(), jamClientConnections[i]->Length(), jamClientConnections[i]->FileName() ); if ( !tracks.contains ( jamClientConnections[i]->Name() ) ) { tracks.insert ( jamClientConnections[i]->Name(), {} ); } tracks[jamClientConnections[i]->Name()].append ( track ); } return tracks; } /** * @brief CJamSession::TracksFromSessionDir Replica of CJamSession::Tracks but using the directory contents to construct the track item map * @param sessionDirName the directory name to scan * @return a map of (latest) client name to connection items */ QMap> CJamSession::TracksFromSessionDir ( const QString& sessionDirName, int iServerFrameSizeSamples ) { QMap> tracks; const QDir sessionDir ( sessionDirName ); foreach ( auto entry, sessionDir.entryList ( { "*.pcm" } ) ) { auto split = entry.split ( "." )[0].split ( "-" ); QString name = split[0]; QString hostPort = split[1]; QString frame = split[2]; QString tail = split[3]; // numChannels may have _nnn QString numChannels = tail.count ( "_" ) > 0 ? tail.split ( "_" )[0] : tail; QString trackName = name + "-" + hostPort; if ( !tracks.contains ( trackName ) ) { tracks.insert ( trackName, {} ); } QFileInfo fiEntry ( sessionDir.absoluteFilePath ( entry ) ); qint64 length = fiEntry.size() / numChannels.toInt() / iServerFrameSizeSamples; STrackItem track ( numChannels.toInt(), frame.toLongLong(), length, sessionDir.absoluteFilePath ( entry ) ); tracks[trackName].append ( track ); } return tracks; } /* ******************************************************************************************************** * CJamRecorder * ********************************************************************************************************/ /** * @brief CJamRecorder::Init Create recording directory, if necessary, and connect signal handlers * @param server Server object emitting signals * @return QString() on success else the failure reason */ QString CJamRecorder::Init() { QString errmsg = QString(); QFileInfo fi ( recordBaseDir.absolutePath() ); fi.setCaching ( false ); if ( !fi.exists() && !QDir().mkpath ( recordBaseDir.absolutePath() ) ) { errmsg = QString ( "'%1' does not exist but could not be created." ).arg ( recordBaseDir.absolutePath() ); qCritical() << qUtf8Printable ( errmsg ); return errmsg; } if ( !fi.isDir() ) { errmsg = QString ( "'%1' exists but is not a directory" ).arg ( recordBaseDir.absolutePath() ); qCritical() << qUtf8Printable ( errmsg ); return errmsg; } if ( !fi.isWritable() ) { errmsg = QString ( "'%1' is a directory but cannot be written to" ).arg ( recordBaseDir.absolutePath() ); qCritical() << qUtf8Printable ( errmsg ); return errmsg; } return errmsg; } /** * @brief CJamRecorder::Start Start up tasks for a new session */ void CJamRecorder::Start() { // Ensure any previous cleaning up has been done. OnEnd(); QString error; { // needs to be after OnEnd() as that also locks QMutexLocker mutexLocker ( &ChIdMutex ); try { currentSession = new CJamSession ( recordBaseDir ); isRecording = true; } catch ( const CGenErr& err ) { currentSession = nullptr; error = err.GetErrorText(); } } if ( !currentSession ) { emit RecordingFailed ( error ); return; } emit RecordingSessionStarted ( currentSession->SessionDir().path() ); } /** * @brief CJamRecorder::OnEnd Finalise the recording and write the Reaper RPP file */ void CJamRecorder::OnEnd() { QMutexLocker mutexLocker ( &ChIdMutex ); if ( isRecording ) { isRecording = false; currentSession->End(); ReaperProjectFromCurrentSession(); AudacityLofFromCurrentSession(); delete currentSession; currentSession = nullptr; } } /** * @brief CJamRecorder::OnTriggerSession End one session and start a new one */ void CJamRecorder::OnTriggerSession() { // This should magically get everything right... if ( isRecording ) { Start(); } } /** * @brief CJamRecorder::OnAboutToQuit End any recording and exit thread */ void CJamRecorder::OnAboutToQuit() { OnEnd(); QThread::currentThread()->exit(); } void CJamRecorder::ReaperProjectFromCurrentSession() { QString reaperProjectFileName = currentSession->SessionDir().filePath ( currentSession->Name().append ( ".rpp" ) ); const QFileInfo fi ( reaperProjectFileName ); if ( fi.exists() ) { qWarning() << "CJamRecorder::ReaperProjectFromCurrentSession():" << fi.absolutePath() << "exists and will not be overwritten."; } else { QFile outf ( reaperProjectFileName ); if ( outf.open ( QFile::WriteOnly ) ) { QTextStream out ( &outf ); out << CReaperProject ( currentSession->Tracks(), iServerFrameSizeSamples ).toString() << '\n'; qDebug() << "Session RPP:" << reaperProjectFileName; } else { qWarning() << "CJamRecorder::ReaperProjectFromCurrentSession():" << fi.absolutePath() << "could not be created, no RPP written."; } } } void CJamRecorder::AudacityLofFromCurrentSession() { QString audacityLofFileName = currentSession->SessionDir().filePath ( currentSession->Name().append ( ".lof" ) ); const QFileInfo fi ( audacityLofFileName ); if ( fi.exists() ) { qWarning() << "CJamRecorder::AudacityLofFromCurrentSession():" << fi.absolutePath() << "exists and will not be overwritten."; } else { QFile outf ( audacityLofFileName ); if ( outf.open ( QFile::WriteOnly ) ) { QTextStream sOut ( &outf ); foreach ( auto trackName, currentSession->Tracks().keys() ) { foreach ( auto item, currentSession->Tracks()[trackName] ) { QFileInfo fi ( item.fileName ); sOut << "file " << '"' << fi.fileName() << '"'; sOut << " offset " << secondsAt48K ( item.startFrame, iServerFrameSizeSamples ) << '\n'; } } sOut.flush(); qDebug() << "Session LOF:" << audacityLofFileName; } else { qWarning() << "CJamRecorder::AudacityLofFromCurrentSession():" << fi.absolutePath() << "could not be created, no LOF written."; } } } /** * @brief CJamRecorder::SessionDirToReaper Replica of CJamRecorder::OnEnd() but using the directory contents to construct the CReaperProject object * @param strSessionDirName * * This is used for testing and is not called from the regular Jamulus code. */ void CJamRecorder::SessionDirToReaper ( QString& strSessionDirName, int serverFrameSizeSamples ) { const QFileInfo fiSessionDir ( QDir::cleanPath ( strSessionDirName ) ); if ( !fiSessionDir.exists() || !fiSessionDir.isDir() ) { throw CGenErr ( fiSessionDir.absoluteFilePath() + " does not exist or is not a directory. Aborting." ); } const QDir dSessionDir ( fiSessionDir.absoluteFilePath() ); const QString reaperProjectFileName = dSessionDir.absoluteFilePath ( fiSessionDir.baseName().append ( ".rpp" ) ); const QFileInfo fiRPP ( reaperProjectFileName ); if ( fiRPP.exists() ) { throw CGenErr ( fiRPP.absoluteFilePath() + " exists and will not be overwritten. Aborting." ); } QFile outf ( fiRPP.absoluteFilePath() ); if ( !outf.open ( QFile::WriteOnly ) ) { throw CGenErr ( fiRPP.absoluteFilePath() + " could not be written. Aborting." ); } QTextStream out ( &outf ); out << CReaperProject ( CJamSession::TracksFromSessionDir ( fiSessionDir.absoluteFilePath(), serverFrameSizeSamples ), serverFrameSizeSamples ) .toString() << '\n'; qDebug() << "Session RPP:" << reaperProjectFileName; } /** * @brief CJamRecorder::OnDisconnected Handle disconnection of a client * @param iChID the client channel id */ void CJamRecorder::OnDisconnected ( int iChID ) { QMutexLocker mutexLocker ( &ChIdMutex ); if ( !isRecording ) { qWarning() << "CJamRecorder::OnDisconnected: channel" << iChID << "disconnected but not recording"; } if ( currentSession == nullptr ) { qWarning() << "CJamRecorder::OnDisconnected: channel" << iChID << "disconnected but no currentSession"; return; } currentSession->DisconnectClient ( iChID ); } /** * @brief CJamRecorder::OnFrame Handle a frame emitted for a client by the server * @param iChID the client channel id * @param name the client name * @param address the client IP and port number * @param numAudioChannels the client number of audio channels * @param data the frame data * * Ensures recording has started. */ void CJamRecorder::OnFrame ( const int iChID, const QString name, const CHostAddress address, const int numAudioChannels, const CVector data ) { // Make sure we are ready if ( !isRecording ) { Start(); } // Start() may have failed, so check again: if ( !isRecording ) { return; } // needs to be after Start() as that also locks { QMutexLocker mutexLocker ( &ChIdMutex ); currentSession->Frame ( iChID, name, address, numAudioChannels, data, iServerFrameSizeSamples ); } } jamulus-3.9.1+dfsg/src/recorder/jamcontroller.h0000644000175000017500000000543014340334543020576 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2020-2022 * * Author(s): * pljones * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #include #include "jamrecorder.h" namespace recorder { class CJamController : public QObject { Q_OBJECT public: explicit CJamController ( CServer* pNServer ); bool GetRecorderInitialised() { return bRecorderInitialised; } QString GetRecorderErrMsg() { return strRecorderErrMsg; } bool GetRecordingEnabled() { return bEnableRecording; } void RequestNewRecording(); void SetEnableRecording ( bool bNewEnableRecording, bool isRunning ); QString GetRecordingDir() { return strRecordingDir; } void SetRecordingDir ( QString newRecordingDir, int iServerFrameSizeSamples, bool bDisableRecording ); ERecorderState GetRecorderState(); private: void OnRecordingFailed ( QString error ); CServer* pServer; bool bRecorderInitialised; bool bEnableRecording; QString strRecordingDir; QThread* pthJamRecorder; CJamRecorder* pJamRecorder; QString strRecorderErrMsg; signals: void RestartRecorder(); void StopRecorder(); void RecordingSessionStarted ( QString sessionDir ); void EndRecorderThread(); void Stopped(); void ClientDisconnected ( int iChID ); void AudioFrame ( const int iChID, const QString stChName, const CHostAddress RecHostAddr, const int iNumAudChan, const CVector vecsData ); }; } // namespace recorder // This must be included AFTER the above definition of class CJamController, // because server.h defines CServer, which contains an instance of CJamController, // and therefore needs to know the its size. #include "../server.h" Q_DECLARE_METATYPE ( int16_t ) jamulus-3.9.1+dfsg/src/server.cpp0000644000175000017500000017436214340334543015772 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include "server.h" // CServer implementation ****************************************************** CServer::CServer ( const int iNewMaxNumChan, const QString& strLoggingFileName, const QString& strServerBindIP, const quint16 iPortNumber, const quint16 iQosNumber, const QString& strHTMLStatusFileName, const QString& strDirectoryServer, const QString& strServerListFileName, const QString& strServerInfo, const QString& strServerListFilter, const QString& strServerPublicIP, const QString& strNewWelcomeMessage, const QString& strRecordingDirName, const bool bNDisconnectAllClientsOnQuit, const bool bNUseDoubleSystemFrameSize, const bool bNUseMultithreading, const bool bDisableRecording, const bool bNDelayPan, const bool bNEnableIPv6, const ELicenceType eNLicenceType ) : bUseDoubleSystemFrameSize ( bNUseDoubleSystemFrameSize ), bUseMultithreading ( bNUseMultithreading ), iMaxNumChannels ( iNewMaxNumChan ), iCurNumChannels ( 0 ), Socket ( this, iPortNumber, iQosNumber, strServerBindIP, bNEnableIPv6 ), Logging(), iFrameCount ( 0 ), bWriteStatusHTMLFile ( false ), strServerHTMLFileListName ( strHTMLStatusFileName ), HighPrecisionTimer ( bNUseDoubleSystemFrameSize ), ServerListManager ( iPortNumber, strDirectoryServer, strServerListFileName, strServerInfo, strServerPublicIP, strServerListFilter, iNewMaxNumChan, bNEnableIPv6, &ConnLessProtocol ), JamController ( this ), bDisableRecording ( bDisableRecording ), bAutoRunMinimized ( false ), bDelayPan ( bNDelayPan ), bEnableIPv6 ( bNEnableIPv6 ), eLicenceType ( eNLicenceType ), bDisconnectAllClientsOnQuit ( bNDisconnectAllClientsOnQuit ), pSignalHandler ( CSignalHandler::getSingletonP() ) { int iOpusError; int i; // create OPUS encoder/decoder for each channel (must be done before // enabling the channels), create a mono and stereo encoder/decoder // for each channel for ( i = 0; i < iMaxNumChannels; i++ ) { // init OPUS ----------------------------------------------------------- OpusMode[i] = opus_custom_mode_create ( SYSTEM_SAMPLE_RATE_HZ, DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES, &iOpusError ); Opus64Mode[i] = opus_custom_mode_create ( SYSTEM_SAMPLE_RATE_HZ, SYSTEM_FRAME_SIZE_SAMPLES, &iOpusError ); // init audio encoders and decoders OpusEncoderMono[i] = opus_custom_encoder_create ( OpusMode[i], 1, &iOpusError ); // mono encoder legacy OpusDecoderMono[i] = opus_custom_decoder_create ( OpusMode[i], 1, &iOpusError ); // mono decoder legacy OpusEncoderStereo[i] = opus_custom_encoder_create ( OpusMode[i], 2, &iOpusError ); // stereo encoder legacy OpusDecoderStereo[i] = opus_custom_decoder_create ( OpusMode[i], 2, &iOpusError ); // stereo decoder legacy Opus64EncoderMono[i] = opus_custom_encoder_create ( Opus64Mode[i], 1, &iOpusError ); // mono encoder OPUS64 Opus64DecoderMono[i] = opus_custom_decoder_create ( Opus64Mode[i], 1, &iOpusError ); // mono decoder OPUS64 Opus64EncoderStereo[i] = opus_custom_encoder_create ( Opus64Mode[i], 2, &iOpusError ); // stereo encoder OPUS64 Opus64DecoderStereo[i] = opus_custom_decoder_create ( Opus64Mode[i], 2, &iOpusError ); // stereo decoder OPUS64 // we require a constant bit rate opus_custom_encoder_ctl ( OpusEncoderMono[i], OPUS_SET_VBR ( 0 ) ); opus_custom_encoder_ctl ( OpusEncoderStereo[i], OPUS_SET_VBR ( 0 ) ); opus_custom_encoder_ctl ( Opus64EncoderMono[i], OPUS_SET_VBR ( 0 ) ); opus_custom_encoder_ctl ( Opus64EncoderStereo[i], OPUS_SET_VBR ( 0 ) ); // for 64 samples frame size we have to adjust the PLC behavior to avoid loud artifacts opus_custom_encoder_ctl ( Opus64EncoderMono[i], OPUS_SET_PACKET_LOSS_PERC ( 35 ) ); opus_custom_encoder_ctl ( Opus64EncoderStereo[i], OPUS_SET_PACKET_LOSS_PERC ( 35 ) ); // we want as low delay as possible opus_custom_encoder_ctl ( OpusEncoderMono[i], OPUS_SET_APPLICATION ( OPUS_APPLICATION_RESTRICTED_LOWDELAY ) ); opus_custom_encoder_ctl ( OpusEncoderStereo[i], OPUS_SET_APPLICATION ( OPUS_APPLICATION_RESTRICTED_LOWDELAY ) ); opus_custom_encoder_ctl ( Opus64EncoderMono[i], OPUS_SET_APPLICATION ( OPUS_APPLICATION_RESTRICTED_LOWDELAY ) ); opus_custom_encoder_ctl ( Opus64EncoderStereo[i], OPUS_SET_APPLICATION ( OPUS_APPLICATION_RESTRICTED_LOWDELAY ) ); // set encoder low complexity for legacy 128 samples frame size opus_custom_encoder_ctl ( OpusEncoderMono[i], OPUS_SET_COMPLEXITY ( 1 ) ); opus_custom_encoder_ctl ( OpusEncoderStereo[i], OPUS_SET_COMPLEXITY ( 1 ) ); // init double-to-normal frame size conversion buffers ----------------- // use worst case memory initialization to avoid allocating memory in // the time-critical thread DoubleFrameSizeConvBufIn[i].Init ( 2 /* stereo */ * DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES /* worst case buffer size */ ); DoubleFrameSizeConvBufOut[i].Init ( 2 /* stereo */ * DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES /* worst case buffer size */ ); } // define colors for chat window identifiers vstrChatColors.Init ( 6 ); vstrChatColors[0] = "mediumblue"; vstrChatColors[1] = "red"; vstrChatColors[2] = "darkorchid"; vstrChatColors[3] = "green"; vstrChatColors[4] = "maroon"; vstrChatColors[5] = "coral"; // set the server frame size if ( bUseDoubleSystemFrameSize ) { iServerFrameSizeSamples = DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES; } else { iServerFrameSizeSamples = SYSTEM_FRAME_SIZE_SAMPLES; } // To avoid audio clitches, in the entire realtime timer audio processing // routine including the ProcessData no memory must be allocated. Since we // do not know the required sizes for the vectors, we allocate memory for // the worst case here: // allocate worst case memory for the temporary vectors vecChanIDsCurConChan.Init ( iMaxNumChannels ); vecvecfGains.Init ( iMaxNumChannels ); vecvecfPannings.Init ( iMaxNumChannels ); vecvecsData.Init ( iMaxNumChannels ); vecvecsData2.Init ( iMaxNumChannels ); vecvecsSendData.Init ( iMaxNumChannels ); vecvecfIntermediateProcBuf.Init ( iMaxNumChannels ); vecvecbyCodedData.Init ( iMaxNumChannels ); vecNumAudioChannels.Init ( iMaxNumChannels ); vecNumFrameSizeConvBlocks.Init ( iMaxNumChannels ); vecUseDoubleSysFraSizeConvBuf.Init ( iMaxNumChannels ); vecAudioComprType.Init ( iMaxNumChannels ); for ( i = 0; i < iMaxNumChannels; i++ ) { // init vectors storing information of all channels vecvecfGains[i].Init ( iMaxNumChannels ); vecvecfPannings[i].Init ( iMaxNumChannels ); // we always use stereo audio buffers (which is the worst case) vecvecsData[i].Init ( 2 /* stereo */ * DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES /* worst case buffer size */ ); vecvecsData2[i].Init ( 2 /* stereo */ * DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES /* worst case buffer size */ ); // (note that we only allocate iMaxNumChannels buffers for the send // and coded data because of the OMP implementation) vecvecsSendData[i].Init ( 2 /* stereo */ * DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES /* worst case buffer size */ ); // allocate worst case memory for intermediate processing buffers in float precision vecvecfIntermediateProcBuf[i].Init ( 2 /* stereo */ * DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES /* worst case buffer size */ ); // allocate worst case memory for the coded data vecvecbyCodedData[i].Init ( MAX_SIZE_BYTES_NETW_BUF ); } // allocate worst case memory for the channel levels vecChannelLevels.Init ( iMaxNumChannels ); // enable logging (if requested) if ( !strLoggingFileName.isEmpty() ) { Logging.Start ( strLoggingFileName ); } // HTML status file writing if ( !strServerHTMLFileListName.isEmpty() ) { // activate HTML file writing and write initial file bWriteStatusHTMLFile = true; WriteHTMLChannelList(); } // manage welcome message: if the welcome message is a valid link to a local // file, the content of that file is used as the welcome message (#361) SetWelcomeMessage ( strNewWelcomeMessage ); // first use given text, may be overwritten if ( QFileInfo ( strNewWelcomeMessage ).exists() ) { QFile file ( strNewWelcomeMessage ); if ( file.open ( QIODevice::ReadOnly | QIODevice::Text ) ) { // use entire file content for the welcome message SetWelcomeMessage ( file.readAll() ); } } // enable jam recording (if requested) - kicks off the thread (note // that jam recorder needs the frame size which is given to the jam // recorder in the SetRecordingDir() function) SetRecordingDir ( strRecordingDirName ); // enable all channels (for the server all channel must be enabled the // entire life time of the software) for ( i = 0; i < iMaxNumChannels; i++ ) { vecChannels[i].SetEnable ( true ); vecChannelOrder[i] = i; } int iAvailableCores = QThread::idealThreadCount(); // setup CThreadPool if multithreading is active and possible if ( bUseMultithreading ) { if ( iAvailableCores == 1 ) { qDebug() << "found only one core, disabling multithreading"; bUseMultithreading = false; } else { // set maximum thread count to available cores; other threads will share at random iMaxNumThreads = iAvailableCores; qDebug() << "multithreading enabled, setting thread count to" << iMaxNumThreads; pThreadPool = std::unique_ptr ( new CThreadPool{ static_cast ( iMaxNumThreads ) } ); Futures.reserve ( iMaxNumThreads ); } } // Connections ------------------------------------------------------------- // connect timer timeout signal QObject::connect ( &HighPrecisionTimer, &CHighPrecisionTimer::timeout, this, &CServer::OnTimer ); QObject::connect ( &ConnLessProtocol, &CProtocol::CLMessReadyForSending, this, &CServer::OnSendCLProtMessage ); QObject::connect ( &ConnLessProtocol, &CProtocol::CLPingReceived, this, &CServer::OnCLPingReceived ); QObject::connect ( &ConnLessProtocol, &CProtocol::CLPingWithNumClientsReceived, this, &CServer::OnCLPingWithNumClientsReceived ); QObject::connect ( &ConnLessProtocol, &CProtocol::CLRegisterServerReceived, this, &CServer::OnCLRegisterServerReceived ); QObject::connect ( &ConnLessProtocol, &CProtocol::CLRegisterServerExReceived, this, &CServer::OnCLRegisterServerExReceived ); QObject::connect ( &ConnLessProtocol, &CProtocol::CLUnregisterServerReceived, this, &CServer::OnCLUnregisterServerReceived ); QObject::connect ( &ConnLessProtocol, &CProtocol::CLReqServerList, this, &CServer::OnCLReqServerList ); QObject::connect ( &ConnLessProtocol, &CProtocol::CLRegisterServerResp, this, &CServer::OnCLRegisterServerResp ); QObject::connect ( &ConnLessProtocol, &CProtocol::CLSendEmptyMes, this, &CServer::OnCLSendEmptyMes ); QObject::connect ( &ConnLessProtocol, &CProtocol::CLDisconnection, this, &CServer::OnCLDisconnection ); QObject::connect ( &ConnLessProtocol, &CProtocol::CLReqVersionAndOS, this, &CServer::OnCLReqVersionAndOS ); QObject::connect ( &ConnLessProtocol, &CProtocol::CLVersionAndOSReceived, this, &CServer::CLVersionAndOSReceived ); QObject::connect ( &ConnLessProtocol, &CProtocol::CLReqConnClientsList, this, &CServer::OnCLReqConnClientsList ); QObject::connect ( &ServerListManager, &CServerListManager::SvrRegStatusChanged, this, &CServer::SvrRegStatusChanged ); QObject::connect ( &JamController, &recorder::CJamController::RestartRecorder, this, &CServer::RestartRecorder ); QObject::connect ( &JamController, &recorder::CJamController::StopRecorder, this, &CServer::StopRecorder ); QObject::connect ( &JamController, &recorder::CJamController::RecordingSessionStarted, this, &CServer::RecordingSessionStarted ); QObject::connect ( &JamController, &recorder::CJamController::EndRecorderThread, this, &CServer::EndRecorderThread ); QObject::connect ( this, &CServer::Stopped, &JamController, &recorder::CJamController::Stopped ); QObject::connect ( this, &CServer::ClientDisconnected, &JamController, &recorder::CJamController::ClientDisconnected ); qRegisterMetaType> ( "CVector" ); QObject::connect ( this, &CServer::AudioFrame, &JamController, &recorder::CJamController::AudioFrame ); QObject::connect ( QCoreApplication::instance(), &QCoreApplication::aboutToQuit, this, &CServer::OnAboutToQuit ); QObject::connect ( pSignalHandler, &CSignalHandler::HandledSignal, this, &CServer::OnHandledSignal ); connectChannelSignalsToServerSlots(); // start the socket (it is important to start the socket after all // initializations and connections) Socket.Start(); } template inline void CServer::connectChannelSignalsToServerSlots() { int iCurChanID = slotId - 1; void ( CServer::*pOnSendProtMessCh ) ( CVector ) = &CServerSlots::OnSendProtMessCh; void ( CServer::*pOnReqConnClientsListCh )() = &CServerSlots::OnReqConnClientsListCh; void ( CServer::*pOnChatTextReceivedCh ) ( QString ) = &CServerSlots::OnChatTextReceivedCh; void ( CServer::*pOnMuteStateHasChangedCh ) ( int, bool ) = &CServerSlots::OnMuteStateHasChangedCh; void ( CServer::*pOnServerAutoSockBufSizeChangeCh ) ( int ) = &CServerSlots::OnServerAutoSockBufSizeChangeCh; // send message QObject::connect ( &vecChannels[iCurChanID], &CChannel::MessReadyForSending, this, pOnSendProtMessCh ); // request connected clients list QObject::connect ( &vecChannels[iCurChanID], &CChannel::ReqConnClientsList, this, pOnReqConnClientsListCh ); // channel info has changed QObject::connect ( &vecChannels[iCurChanID], &CChannel::ChanInfoHasChanged, this, &CServer::CreateAndSendChanListForAllConChannels ); // chat text received QObject::connect ( &vecChannels[iCurChanID], &CChannel::ChatTextReceived, this, pOnChatTextReceivedCh ); // other mute state has changed QObject::connect ( &vecChannels[iCurChanID], &CChannel::MuteStateHasChanged, this, pOnMuteStateHasChangedCh ); // auto socket buffer size change QObject::connect ( &vecChannels[iCurChanID], &CChannel::ServerAutoSockBufSizeChange, this, pOnServerAutoSockBufSizeChangeCh ); connectChannelSignalsToServerSlots(); } template<> inline void CServer::connectChannelSignalsToServerSlots<0>() {} void CServer::CreateAndSendJitBufMessage ( const int iCurChanID, const int iNNumFra ) { vecChannels[iCurChanID].CreateJitBufMes ( iNNumFra ); } CServer::~CServer() { for ( int i = 0; i < iMaxNumChannels; i++ ) { // free audio encoders and decoders opus_custom_encoder_destroy ( OpusEncoderMono[i] ); opus_custom_decoder_destroy ( OpusDecoderMono[i] ); opus_custom_encoder_destroy ( OpusEncoderStereo[i] ); opus_custom_decoder_destroy ( OpusDecoderStereo[i] ); opus_custom_encoder_destroy ( Opus64EncoderMono[i] ); opus_custom_decoder_destroy ( Opus64DecoderMono[i] ); opus_custom_encoder_destroy ( Opus64EncoderStereo[i] ); opus_custom_decoder_destroy ( Opus64DecoderStereo[i] ); // free audio modes opus_custom_mode_destroy ( OpusMode[i] ); opus_custom_mode_destroy ( Opus64Mode[i] ); } } void CServer::SendProtMessage ( int iChID, CVector vecMessage ) { // the protocol queries me to call the function to send the message // send it through the network Socket.SendPacket ( vecMessage, vecChannels[iChID].GetAddress() ); } void CServer::OnNewConnection ( int iChID, int iTotChans, CHostAddress RecHostAddr ) { QMutexLocker locker ( &Mutex ); // inform the client about its own ID at the server (note that this // must be the first message to be sent for a new connection) vecChannels[iChID].CreateClientIDMes ( iChID ); // Send an empty channel list in order to force clients to reset their // audio mixer state. This is required to trigger clients to re-send their // gain levels upon reconnecting after server restarts. vecChannels[iChID].CreateConClientListMes ( CVector ( 0 ) ); // query support for split messages in the client vecChannels[iChID].CreateReqSplitMessSupportMes(); // on a new connection we query the network transport properties for the // audio packets (to use the correct network block size and audio // compression properties, etc.) vecChannels[iChID].CreateReqNetwTranspPropsMes(); // this is a new connection, query the jitter buffer size we shall use // for this client (note that at the same time on a new connection the // client sends the jitter buffer size by default but maybe we have // reached a state where this did not happen because of network trouble, // client or server thinks that the connection was still active, etc.) vecChannels[iChID].CreateReqJitBufMes(); // A new client connected to the server, the channel list // at all clients have to be updated. This is done by sending // a channel name request to the client which causes a channel // name message to be transmitted to the server. If the server // receives this message, the channel list will be automatically // updated (implicitly). // // Usually it is not required to send the channel list to the // client currently connecting since it automatically requests // the channel list on a new connection (as a result, he will // usually get the list twice which has no impact on functionality // but will only increase the network load a tiny little bit). But // in case the client thinks he is still connected but the server // was restartet, it is important that we send the channel list // at this place. vecChannels[iChID].CreateReqChanInfoMes(); // send welcome message (if enabled) { QMutexLocker locker ( &MutexWelcomeMessage ); if ( !strWelcomeMessage.isEmpty() ) { // create formatted server welcome message and send it just to // the client which just connected to the server const QString strWelcomeMessageFormated = WELCOME_MESSAGE_PREFIX + strWelcomeMessage; vecChannels[iChID].CreateChatTextMes ( strWelcomeMessageFormated ); } } // send licence request message (if enabled) if ( eLicenceType != LT_NO_LICENCE ) { vecChannels[iChID].CreateLicReqMes ( eLicenceType ); } // send version info (for, e.g., feature activation in the client) vecChannels[iChID].CreateVersionAndOSMes(); // send recording state message on connection vecChannels[iChID].CreateRecorderStateMes ( JamController.GetRecorderState() ); // reset the conversion buffers DoubleFrameSizeConvBufIn[iChID].Reset(); DoubleFrameSizeConvBufOut[iChID].Reset(); // logging of new connected channel Logging.AddNewConnection ( RecHostAddr.InetAddr, iTotChans ); } void CServer::OnServerFull ( CHostAddress RecHostAddr ) { // note: no mutex required here // inform the calling client that no channel is free ConnLessProtocol.CreateCLServerFullMes ( RecHostAddr ); } void CServer::OnSendCLProtMessage ( CHostAddress InetAddr, CVector vecMessage ) { // the protocol queries me to call the function to send the message // send it through the network Socket.SendPacket ( vecMessage, InetAddr ); } void CServer::OnCLDisconnection ( CHostAddress InetAddr ) { // check if the given address is actually a client which is connected to // this server, if yes, disconnect it const int iCurChanID = FindChannel ( InetAddr ); if ( iCurChanID != INVALID_CHANNEL_ID ) { vecChannels[iCurChanID].Disconnect(); } } void CServer::OnAboutToQuit() { // if enabled, disconnect all clients on quit if ( bDisconnectAllClientsOnQuit ) { QMutexLocker locker ( &Mutex ); for ( int i = 0; i < iMaxNumChannels; i++ ) { if ( vecChannels[i].IsConnected() ) { ConnLessProtocol.CreateCLDisconnection ( vecChannels[i].GetAddress() ); } } } Stop(); if ( bWriteStatusHTMLFile ) { WriteHTMLServerQuit(); } } void CServer::OnHandledSignal ( int sigNum ) { // show the signal number on the console (note that this may not work for Windows) qDebug() << qUtf8Printable ( QString ( "OnHandledSignal: %1" ).arg ( sigNum ) ); #ifdef _WIN32 // Windows does not actually get OnHandledSignal triggered QCoreApplication::instance()->exit(); Q_UNUSED ( sigNum ) #else switch ( sigNum ) { case SIGUSR1: RequestNewRecording(); break; case SIGUSR2: SetEnableRecording ( !JamController.GetRecordingEnabled() ); break; case SIGINT: case SIGTERM: // This should trigger OnAboutToQuit QCoreApplication::instance()->exit(); break; default: break; } #endif } void CServer::Start() { // only start if not already running if ( !IsRunning() ) { // start timer HighPrecisionTimer.Start(); // emit start signal emit Started(); } } void CServer::Stop() { // Under Mac we have the problem that the timer shutdown might // take some time and therefore we get a lot of "server stopped" // entries in the log. The following condition shall prevent this. // For the other OSs this should not hurt either. if ( IsRunning() ) { // stop timer HighPrecisionTimer.Stop(); // logging (add "server stopped" logging entry) Logging.AddServerStopped(); // emit stopped signal emit Stopped(); } } void CServer::OnTimer() { //### TEST: BEGIN ###// // uncomment next line to do a timer Jitter measurement // static CTimingMeas JitterMeas ( 1000, "test2.dat" ); JitterMeas.Measure(); //### TEST: END ###// // Get data from all connected clients ------------------------------------- // some inits int iNumClients = 0; // init connected client counter bool bUseMT = false; int iNumBlocks = 0; // init number of blocks for multithreading int iMTBlockSize = 0; // init block size for multithreading bChannelIsNowDisconnected = false; // note that the flag must be a member function since QtConcurrent::run can only take 5 params { // Make put and get calls thread safe. QMutexLocker locker ( &Mutex ); // first, get number and IDs of connected channels for ( int i = 0; i < iMaxNumChannels; i++ ) { if ( vecChannels[i].IsConnected() ) { // add ID and increment counter (note that the vector length is // according to the worst case scenario, if the number of // connected clients is less, only a subset of elements of this // vector are actually used and the others are dummy elements) vecChanIDsCurConChan[iNumClients] = i; iNumClients++; } } // use multithreading for any non-zero number of clients // (overhead is low and it is worth doing for all numbers) bUseMT = bUseMultithreading && iNumClients > 0; // prepare and decode connected channels if ( !bUseMT ) { // run the OPUS decoder for all data blocks DecodeReceiveDataBlocks ( this, 0, iNumClients - 1, iNumClients ); } else { // spread work equally among available threads iNumBlocks = std::min ( iNumClients, iMaxNumThreads ); iMTBlockSize = ( iNumClients - 1 ) / iNumBlocks + 1; // processing with multithreading for ( int iBlockCnt = 0; iBlockCnt < iNumBlocks; iBlockCnt++ ) { // The work for OPUS decoding is distributed over all available processor cores. // By using the future synchronizer we make sure that all // threads are done when we leave the timer callback function. const int iStartChanCnt = iBlockCnt * iMTBlockSize; const int iStopChanCnt = std::min ( ( iBlockCnt + 1 ) * iMTBlockSize - 1, iNumClients - 1 ); Futures.push_back ( pThreadPool->enqueue ( CServer::DecodeReceiveDataBlocks, this, iStartChanCnt, iStopChanCnt, iNumClients ) ); } // make sure all concurrent run threads have finished when we leave this function for ( auto& future : Futures ) { future.wait(); } Futures.clear(); } // a channel is now disconnected, take action on it if ( bChannelIsNowDisconnected ) { // update channel list for all currently connected clients CreateAndSendChanListForAllConChannels(); } } // Process data ------------------------------------------------------------ // Check if at least one client is connected. If not, stop server until // one client is connected. if ( iNumClients > 0 ) { // calculate levels for all connected clients const bool bSendChannelLevels = CreateLevelsForAllConChannels ( iNumClients, vecNumAudioChannels, vecvecsData, vecChannelLevels ); for ( int iChanCnt = 0; iChanCnt < iNumClients; iChanCnt++ ) { // get actual ID of current channel const int iCurChanID = vecChanIDsCurConChan[iChanCnt]; // update socket buffer size vecChannels[iCurChanID].UpdateSocketBufferSize(); // send channel levels if they are ready if ( bSendChannelLevels ) { ConnLessProtocol.CreateCLChannelLevelListMes ( vecChannels[iCurChanID].GetAddress(), vecChannelLevels, iNumClients ); } // export the audio data for recording purpose if ( JamController.GetRecordingEnabled() ) { emit AudioFrame ( iCurChanID, vecChannels[iCurChanID].GetName(), vecChannels[iCurChanID].GetAddress(), vecNumAudioChannels[iChanCnt], vecvecsData[iChanCnt] ); } // processing without multithreading if ( !bUseMT ) { // generate a separate mix for each channel, OPUS encode the // audio data and transmit the network packet MixEncodeTransmitData ( iChanCnt, iNumClients ); } } // processing with multithreading if ( bUseMT ) { for ( int iBlockCnt = 0; iBlockCnt < iNumBlocks; iBlockCnt++ ) { // Generate a separate mix for each channel, OPUS encode the // audio data and transmit the network packet. The work is // distributed over all available processor cores. // By using the future synchronizer we make sure that all // threads are done when we leave the timer callback function. const int iStartChanCnt = iBlockCnt * iMTBlockSize; const int iStopChanCnt = std::min ( ( iBlockCnt + 1 ) * iMTBlockSize - 1, iNumClients - 1 ); Futures.push_back ( pThreadPool->enqueue ( CServer::MixEncodeTransmitDataBlocks, this, iStartChanCnt, iStopChanCnt, iNumClients ) ); } // make sure all concurrent run threads have finished when we leave this function for ( auto& fFuture : Futures ) { fFuture.wait(); } Futures.clear(); } if ( bDelayPan ) { for ( int i = 0; i < iNumClients; i++ ) { for ( int j = 0; j < 2 * ( iServerFrameSizeSamples ); j++ ) { vecvecsData2[i][j] = vecvecsData[i][j]; } } } } else { // Disable server if no clients are connected. In this case the server // does not consume any significant CPU when no client is connected. Stop(); } } // This is a static method used as a callback, and does not inherit a "this" pointer, // so it is necessary for the server instance to be passed as a parameter. void CServer::DecodeReceiveDataBlocks ( CServer* pServer, const int iStartChanCnt, const int iStopChanCnt, const int iNumClients ) { // loop over all channels in the current block, needed for multithreading support for ( int iChanCnt = iStartChanCnt; iChanCnt <= iStopChanCnt; iChanCnt++ ) { pServer->DecodeReceiveData ( iChanCnt, iNumClients ); } } // This is a static method used as a callback, and does not inherit a "this" pointer, // so it is necessary for the server instance to be passed as a parameter. void CServer::MixEncodeTransmitDataBlocks ( CServer* pServer, const int iStartChanCnt, const int iStopChanCnt, const int iNumClients ) { // loop over all channels in the current block, needed for multithreading support for ( int iChanCnt = iStartChanCnt; iChanCnt <= iStopChanCnt; iChanCnt++ ) { pServer->MixEncodeTransmitData ( iChanCnt, iNumClients ); } } void CServer::DecodeReceiveData ( const int iChanCnt, const int iNumClients ) { int iUnused; int iClientFrameSizeSamples = 0; // initialize to avoid a compiler warning OpusCustomDecoder* CurOpusDecoder; unsigned char* pCurCodedData; // get actual ID of current channel const int iCurChanID = vecChanIDsCurConChan[iChanCnt]; // get and store number of audio channels and compression type vecNumAudioChannels[iChanCnt] = vecChannels[iCurChanID].GetNumAudioChannels(); vecAudioComprType[iChanCnt] = vecChannels[iCurChanID].GetAudioCompressionType(); // get info about required frame size conversion properties vecUseDoubleSysFraSizeConvBuf[iChanCnt] = ( !bUseDoubleSystemFrameSize && ( vecAudioComprType[iChanCnt] == CT_OPUS ) ); if ( bUseDoubleSystemFrameSize && ( vecAudioComprType[iChanCnt] == CT_OPUS64 ) ) { vecNumFrameSizeConvBlocks[iChanCnt] = 2; } else { vecNumFrameSizeConvBlocks[iChanCnt] = 1; } // update conversion buffer size (nothing will happen if the size stays the same) if ( vecUseDoubleSysFraSizeConvBuf[iChanCnt] ) { DoubleFrameSizeConvBufIn[iCurChanID].SetBufferSize ( DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES * vecNumAudioChannels[iChanCnt] ); DoubleFrameSizeConvBufOut[iCurChanID].SetBufferSize ( DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES * vecNumAudioChannels[iChanCnt] ); } // select the opus decoder and raw audio frame length if ( vecAudioComprType[iChanCnt] == CT_OPUS ) { iClientFrameSizeSamples = DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES; if ( vecNumAudioChannels[iChanCnt] == 1 ) { CurOpusDecoder = OpusDecoderMono[iCurChanID]; } else { CurOpusDecoder = OpusDecoderStereo[iCurChanID]; } } else if ( vecAudioComprType[iChanCnt] == CT_OPUS64 ) { iClientFrameSizeSamples = SYSTEM_FRAME_SIZE_SAMPLES; if ( vecNumAudioChannels[iChanCnt] == 1 ) { CurOpusDecoder = Opus64DecoderMono[iCurChanID]; } else { CurOpusDecoder = Opus64DecoderStereo[iCurChanID]; } } else { CurOpusDecoder = nullptr; } // get gains of all connected channels for ( int j = 0; j < iNumClients; j++ ) { // The second index of "vecvecdGains" does not represent // the channel ID! Therefore we have to use // "vecChanIDsCurConChan" to query the IDs of the currently // connected channels vecvecfGains[iChanCnt][j] = vecChannels[iCurChanID].GetGain ( vecChanIDsCurConChan[j] ); // consider audio fade-in vecvecfGains[iChanCnt][j] *= vecChannels[vecChanIDsCurConChan[j]].GetFadeInGain(); // use the fade in of the current channel for all other connected clients // as well to avoid the client volumes are at 100% when joining a server (#628) if ( j != iChanCnt ) { vecvecfGains[iChanCnt][j] *= vecChannels[iCurChanID].GetFadeInGain(); } // panning vecvecfPannings[iChanCnt][j] = vecChannels[iCurChanID].GetPan ( vecChanIDsCurConChan[j] ); } // If the server frame size is smaller than the received OPUS frame size, we need a conversion // buffer which stores the large buffer. // Note that we have a shortcut here. If the conversion buffer is not needed, the boolean flag // is false and the Get() function is not called at all. Therefore if the buffer is not needed // we do not spend any time in the function but go directly inside the if condition. if ( ( vecUseDoubleSysFraSizeConvBuf[iChanCnt] == 0 ) || !DoubleFrameSizeConvBufIn[iCurChanID].Get ( vecvecsData[iChanCnt], SYSTEM_FRAME_SIZE_SAMPLES * vecNumAudioChannels[iChanCnt] ) ) { // get current number of OPUS coded bytes const int iCeltNumCodedBytes = vecChannels[iCurChanID].GetCeltNumCodedBytes(); for ( int iB = 0; iB < vecNumFrameSizeConvBlocks[iChanCnt]; iB++ ) { // get data const EGetDataStat eGetStat = vecChannels[iCurChanID].GetData ( vecvecbyCodedData[iChanCnt], iCeltNumCodedBytes ); // if channel was just disconnected, set flag that connected // client list is sent to all other clients // and emit the client disconnected signal if ( eGetStat == GS_CHAN_NOW_DISCONNECTED ) { if ( JamController.GetRecordingEnabled() ) { emit ClientDisconnected ( iCurChanID ); // TODO do this outside the mutex lock? } FreeChannel ( iCurChanID ); // note that the channel is now not in use // note that no mutex is needed for this shared resource since it is not a // read-modify-write operation but an atomic write and also each thread can // only set it to true and never to false bChannelIsNowDisconnected = true; // since the channel is no longer in use, we should return return; } // get pointer to coded data if ( eGetStat == GS_BUFFER_OK ) { pCurCodedData = &vecvecbyCodedData[iChanCnt][0]; } else { // for lost packets use null pointer as coded input data pCurCodedData = nullptr; } // OPUS decode received data stream if ( CurOpusDecoder != nullptr ) { const int iOffset = iB * SYSTEM_FRAME_SIZE_SAMPLES * vecNumAudioChannels[iChanCnt]; iUnused = opus_custom_decode ( CurOpusDecoder, pCurCodedData, iCeltNumCodedBytes, &vecvecsData[iChanCnt][iOffset], iClientFrameSizeSamples ); } } // a new large frame is ready, if the conversion buffer is required, put it in the buffer // and read out the small frame size immediately for further processing if ( vecUseDoubleSysFraSizeConvBuf[iChanCnt] != 0 ) { DoubleFrameSizeConvBufIn[iCurChanID].PutAll ( vecvecsData[iChanCnt] ); DoubleFrameSizeConvBufIn[iCurChanID].Get ( vecvecsData[iChanCnt], SYSTEM_FRAME_SIZE_SAMPLES * vecNumAudioChannels[iChanCnt] ); } } Q_UNUSED ( iUnused ) } /// @brief Mix all audio data from all clients together, encode and transmit void CServer::MixEncodeTransmitData ( const int iChanCnt, const int iNumClients ) { int i, j, k, iUnused; CVector& vecfIntermProcBuf = vecvecfIntermediateProcBuf[iChanCnt]; // use reference for faster access CVector& vecsSendData = vecvecsSendData[iChanCnt]; // use reference for faster access // get actual ID of current channel const int iCurChanID = vecChanIDsCurConChan[iChanCnt]; // init intermediate processing vector with zeros since we mix all channels on that vector vecfIntermProcBuf.Reset ( 0 ); // distinguish between stereo and mono mode if ( vecNumAudioChannels[iChanCnt] == 1 ) { // Mono target channel ------------------------------------------------- for ( j = 0; j < iNumClients; j++ ) { // get a reference to the audio data and gain of the current client const CVector& vecsData = vecvecsData[j]; const float fGain = vecvecfGains[iChanCnt][j]; // if channel gain is 1, avoid multiplication for speed optimization if ( fGain == 1.0f ) { if ( vecNumAudioChannels[j] == 1 ) { // mono for ( i = 0; i < iServerFrameSizeSamples; i++ ) { vecfIntermProcBuf[i] += vecsData[i]; } } else { // stereo: apply stereo-to-mono attenuation for ( i = 0, k = 0; i < iServerFrameSizeSamples; i++, k += 2 ) { vecfIntermProcBuf[i] += ( static_cast ( vecsData[k] ) + vecsData[k + 1] ) / 2; } } } else { if ( vecNumAudioChannels[j] == 1 ) { // mono for ( i = 0; i < iServerFrameSizeSamples; i++ ) { vecfIntermProcBuf[i] += vecsData[i] * fGain; } } else { // stereo: apply stereo-to-mono attenuation for ( i = 0, k = 0; i < iServerFrameSizeSamples; i++, k += 2 ) { vecfIntermProcBuf[i] += fGain * ( static_cast ( vecsData[k] ) + vecsData[k + 1] ) / 2; } } } } // convert from double to short with clipping for ( i = 0; i < iServerFrameSizeSamples; i++ ) { vecsSendData[i] = Float2Short ( vecfIntermProcBuf[i] ); } } else { // Stereo target channel ----------------------------------------------- const int maxPanDelay = MAX_DELAY_PANNING_SAMPLES; int iPanDelL = 0, iPanDelR = 0, iPanDel; int iLpan, iRpan, iPan; for ( j = 0; j < iNumClients; j++ ) { // get a reference to the audio data and gain/pan of the current client const CVector& vecsData = vecvecsData[j]; const CVector& vecsData2 = vecvecsData2[j]; const float fGain = vecvecfGains[iChanCnt][j]; const float fPan = bDelayPan ? 0.5f : vecvecfPannings[iChanCnt][j]; // calculate combined gain/pan for each stereo channel where we define // the panning that center equals full gain for both channels const float fGainL = MathUtils::GetLeftPan ( fPan, false ) * fGain; const float fGainR = MathUtils::GetRightPan ( fPan, false ) * fGain; if ( bDelayPan ) { iPanDel = lround ( (float) ( 2 * maxPanDelay - 2 ) * ( vecvecfPannings[iChanCnt][j] - 0.5f ) ); iPanDelL = ( iPanDel > 0 ) ? iPanDel : 0; iPanDelR = ( iPanDel < 0 ) ? -iPanDel : 0; } if ( vecNumAudioChannels[j] == 1 ) { // mono: copy same mono data in both out stereo audio channels for ( i = 0, k = 0; i < iServerFrameSizeSamples; i++, k += 2 ) { // left/right channel if ( bDelayPan ) { // pan address shift // left channel iLpan = i - iPanDelL; if ( iLpan < 0 ) { // get from second iLpan = iLpan + iServerFrameSizeSamples; vecfIntermProcBuf[k] += vecsData2[iLpan] * fGainL; } else { vecfIntermProcBuf[k] += vecsData[iLpan] * fGainL; } // right channel iRpan = i - iPanDelR; if ( iRpan < 0 ) { // get from second iRpan = iRpan + iServerFrameSizeSamples; vecfIntermProcBuf[k + 1] += vecsData2[iRpan] * fGainR; } else { vecfIntermProcBuf[k + 1] += vecsData[iRpan] * fGainR; } } else { vecfIntermProcBuf[k] += vecsData[i] * fGainL; vecfIntermProcBuf[k + 1] += vecsData[i] * fGainR; } } } else { // stereo for ( i = 0; i < ( 2 * iServerFrameSizeSamples ); i++ ) { // left/right channel if ( bDelayPan ) { // pan address shift if ( ( i & 1 ) == 0 ) { iPan = i - 2 * iPanDelL; // if even : left channel } else { iPan = i - 2 * iPanDelR; // if odd : right channel } // interleaved channels if ( iPan < 0 ) { // get from second iPan = iPan + 2 * iServerFrameSizeSamples; vecfIntermProcBuf[i] += vecsData2[iPan] * fGain; } else { vecfIntermProcBuf[i] += vecsData[iPan] * fGain; } } else { if ( ( i & 1 ) == 0 ) { // if even : left channel vecfIntermProcBuf[i] += vecsData[i] * fGainL; } else { // if odd : right channel vecfIntermProcBuf[i] += vecsData[i] * fGainR; } } } } } // convert from double to short with clipping for ( i = 0; i < ( 2 * iServerFrameSizeSamples ); i++ ) { vecsSendData[i] = Float2Short ( vecfIntermProcBuf[i] ); } } int iClientFrameSizeSamples = 0; // initialize to avoid a compiler warning OpusCustomEncoder* pCurOpusEncoder = nullptr; // get current number of CELT coded bytes const int iCeltNumCodedBytes = vecChannels[iCurChanID].GetCeltNumCodedBytes(); // select the opus encoder and raw audio frame length if ( vecAudioComprType[iChanCnt] == CT_OPUS ) { iClientFrameSizeSamples = DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES; if ( vecNumAudioChannels[iChanCnt] == 1 ) { pCurOpusEncoder = OpusEncoderMono[iCurChanID]; } else { pCurOpusEncoder = OpusEncoderStereo[iCurChanID]; } } else if ( vecAudioComprType[iChanCnt] == CT_OPUS64 ) { iClientFrameSizeSamples = SYSTEM_FRAME_SIZE_SAMPLES; if ( vecNumAudioChannels[iChanCnt] == 1 ) { pCurOpusEncoder = Opus64EncoderMono[iCurChanID]; } else { pCurOpusEncoder = Opus64EncoderStereo[iCurChanID]; } } // If the server frame size is smaller than the received OPUS frame size, we need a conversion // buffer which stores the large buffer. // Note that we have a shortcut here. If the conversion buffer is not needed, the boolean flag // is false and the Get() function is not called at all. Therefore if the buffer is not needed // we do not spend any time in the function but go directly inside the if condition. if ( ( vecUseDoubleSysFraSizeConvBuf[iChanCnt] == 0 ) || DoubleFrameSizeConvBufOut[iCurChanID].Put ( vecsSendData, SYSTEM_FRAME_SIZE_SAMPLES * vecNumAudioChannels[iChanCnt] ) ) { if ( vecUseDoubleSysFraSizeConvBuf[iChanCnt] != 0 ) { // get the large frame from the conversion buffer DoubleFrameSizeConvBufOut[iCurChanID].GetAll ( vecsSendData, DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES * vecNumAudioChannels[iChanCnt] ); } // OPUS encoding if ( pCurOpusEncoder != nullptr ) { //### TODO: BEGIN ###// // find a better place than this: the setting does not change all the time so for speed // optimization it would be better to set it only if the network frame size is changed opus_custom_encoder_ctl ( pCurOpusEncoder, OPUS_SET_BITRATE ( CalcBitRateBitsPerSecFromCodedBytes ( iCeltNumCodedBytes, iClientFrameSizeSamples ) ) ); //### TODO: END ###// for ( int iB = 0; iB < vecNumFrameSizeConvBlocks[iChanCnt]; iB++ ) { const int iOffset = iB * SYSTEM_FRAME_SIZE_SAMPLES * vecNumAudioChannels[iChanCnt]; iUnused = opus_custom_encode ( pCurOpusEncoder, &vecsSendData[iOffset], iClientFrameSizeSamples, &vecvecbyCodedData[iChanCnt][0], iCeltNumCodedBytes ); // send separate mix to current clients vecChannels[iCurChanID].PrepAndSendPacket ( &Socket, vecvecbyCodedData[iChanCnt], iCeltNumCodedBytes ); } } } Q_UNUSED ( iUnused ) } CVector CServer::CreateChannelList() { CVector vecChanInfo ( 0 ); // look for free channels for ( int i = 0; i < iMaxNumChannels; i++ ) { if ( vecChannels[i].IsConnected() ) { vecChanInfo.Add ( CChannelInfo ( i, // ID vecChannels[i].GetChanInfo() ) ); } } return vecChanInfo; } void CServer::CreateAndSendChanListForAllConChannels() { // create channel list CVector vecChanInfo ( CreateChannelList() ); // now send connected channels list to all connected clients for ( int i = 0; i < iMaxNumChannels; i++ ) { if ( vecChannels[i].IsConnected() ) { // send message vecChannels[i].CreateConClientListMes ( vecChanInfo ); } } // create status HTML file if enabled if ( bWriteStatusHTMLFile ) { WriteHTMLChannelList(); } } void CServer::CreateAndSendChanListForThisChan ( const int iCurChanID ) { // create channel list CVector vecChanInfo ( CreateChannelList() ); // now send connected channels list to the channel with the ID "iCurChanID" vecChannels[iCurChanID].CreateConClientListMes ( vecChanInfo ); } void CServer::CreateAndSendChatTextForAllConChannels ( const int iCurChanID, const QString& strChatText ) { // Create message which is sent to all connected clients ------------------- // get client name QString ChanName = vecChannels[iCurChanID].GetName(); // add time and name of the client at the beginning of the message text and // use different colors QString sCurColor = vstrChatColors[iCurChanID % vstrChatColors.Size()]; const QString strActualMessageText = "(" + QTime::currentTime().toString ( "hh:mm:ss AP" ) + ") " + ChanName.toHtmlEscaped() + " " + strChatText.toHtmlEscaped(); // Send chat text to all connected clients --------------------------------- for ( int i = 0; i < iMaxNumChannels; i++ ) { if ( vecChannels[i].IsConnected() ) { // send message vecChannels[i].CreateChatTextMes ( strActualMessageText ); } } } void CServer::CreateAndSendRecorderStateForAllConChannels() { // get recorder state ERecorderState eRecorderState = JamController.GetRecorderState(); // now send recorder state to all connected clients for ( int i = 0; i < iMaxNumChannels; i++ ) { if ( vecChannels[i].IsConnected() ) { // send message vecChannels[i].CreateRecorderStateMes ( eRecorderState ); } } } void CServer::CreateOtherMuteStateChanged ( const int iCurChanID, const int iOtherChanID, const bool bIsMuted ) { if ( vecChannels[iOtherChanID].IsConnected() ) { // send message vecChannels[iOtherChanID].CreateMuteStateHasChangedMes ( iCurChanID, bIsMuted ); } } int CServer::GetNumberOfConnectedClients() { QMutexLocker locker ( &MutexChanOrder ); return iCurNumChannels; } // CServer::FindChannel() is called for every received audio packet or connected protocol // packet, to find the channel ID associated with the source IP address and port. // In order to search as efficiently as possible, a list of active channel IDs is stored // in vecChannelOrder[], sorted by IP and port (according to CHostAddress::Compare()), // and a binary search is used to find either the existing channel, or the position at // which a new channel should be inserted. int CServer::FindChannel ( const CHostAddress& CheckAddr, const bool bAllowNew ) { int iNewChanID = INVALID_CHANNEL_ID; QMutexLocker locker ( &MutexChanOrder ); int l = 0, r = iCurNumChannels, i; // use binary search to find the channel while ( r > l ) { int t = ( r + l ) / 2; int cmp = CheckAddr.Compare ( vecChannels[vecChannelOrder[t]].GetAddress() ); if ( cmp == 0 ) { // address and port match return vecChannelOrder[t]; } if ( cmp > 0 ) { l = t + 1; } else { r = t; } } // existing channel not found - return if we cannot create a new channel if ( !bAllowNew || iCurNumChannels >= iMaxNumChannels ) { return INVALID_CHANNEL_ID; } // allocate a new channel i = iCurNumChannels++; // save index of free channel and increment count iNewChanID = vecChannelOrder[i]; InitChannel ( iNewChanID, CheckAddr ); // now l == r == position in vecChannelOrder to insert iNewChanID // move channel IDs up by one starting at the top and working down while ( i > r ) { int j = i--; vecChannelOrder[j] = vecChannelOrder[i]; } // insert the new channel ID in the correct place vecChannelOrder[i] = iNewChanID; // DumpChannels ( __FUNCTION__ ); return iNewChanID; } void CServer::InitChannel ( const int iNewChanID, const CHostAddress& InetAddr ) { // initialize new channel by storing the calling host address vecChannels[iNewChanID].SetAddress ( InetAddr ); // reset channel info vecChannels[iNewChanID].ResetInfo(); // reset the channel gains/pans of current channel, at the same // time reset gains/pans of this channel ID for all other channels for ( int i = 0; i < iMaxNumChannels; i++ ) { vecChannels[iNewChanID].SetGain ( i, 1.0 ); vecChannels[iNewChanID].SetPan ( i, 0.5 ); // other channels (we do not distinguish the case if // i == iCurChanID for simplicity) vecChannels[i].SetGain ( iNewChanID, 1.0 ); vecChannels[i].SetPan ( iNewChanID, 0.5 ); } } // CServer::FreeChannel() is called to remove a channel from the list of active channels. // The remaining ordered IDs are moved down by one space, and the freed ID is moved to the // end, ready to be reused by the next new connection. void CServer::FreeChannel ( const int iCurChanID ) { QMutexLocker locker ( &MutexChanOrder ); for ( int i = 0; i < iCurNumChannels; i++ ) { if ( vecChannelOrder[i] == iCurChanID ) { --iCurNumChannels; // move channel IDs down by one starting at the freed channel and working up the active channels // and then the free channels until its position in the free list is reached while ( i < iCurNumChannels || ( i + 1 < iMaxNumChannels && vecChannelOrder[i + 1] < iCurChanID ) ) { int j = i++; vecChannelOrder[j] = vecChannelOrder[i]; } // put deleted channel in the vacated position ready for re-use vecChannelOrder[i] = iCurChanID; // DumpChannels ( __FUNCTION__ ); return; } } qWarning() << "FreeChannel() called with invalid channel ID"; } void CServer::DumpChannels ( const QString& title ) { qDebug() << qUtf8Printable ( title ); for ( int i = 0; i < iMaxNumChannels; i++ ) { int iChanID = vecChannelOrder[i]; if ( i == iCurNumChannels ) { qDebug() << "----------"; } qDebug() << qUtf8Printable ( QString ( "%1: [%2] %3" ).arg ( i, 3 ).arg ( iChanID ).arg ( vecChannels[iChanID].GetAddress().toString() ) ); } } void CServer::OnProtocolCLMessageReceived ( int iRecID, CVector vecbyMesBodyData, CHostAddress RecHostAddr ) { QMutexLocker locker ( &Mutex ); // connection less messages are always processed ConnLessProtocol.ParseConnectionLessMessageBody ( vecbyMesBodyData, iRecID, RecHostAddr ); } void CServer::OnProtocolMessageReceived ( int iRecCounter, int iRecID, CVector vecbyMesBodyData, CHostAddress RecHostAddr ) { QMutexLocker locker ( &Mutex ); // find the channel with the received address const int iCurChanID = FindChannel ( RecHostAddr ); // if the channel exists, apply the protocol message to the channel if ( iCurChanID != INVALID_CHANNEL_ID ) { vecChannels[iCurChanID].PutProtocolData ( iRecCounter, iRecID, vecbyMesBodyData, RecHostAddr ); } } bool CServer::PutAudioData ( const CVector& vecbyRecBuf, const int iNumBytesRead, const CHostAddress& HostAdr, int& iCurChanID ) { QMutexLocker locker ( &Mutex ); bool bNewConnection = false; // init return value // Get channel ID ------------------------------------------------------ // check address iCurChanID = FindChannel ( HostAdr, true /* allow new */ ); // If channel is valid or new, put received audio data in jitter buffer ---------------------------- if ( iCurChanID != INVALID_CHANNEL_ID ) { // put packet in socket buffer if ( vecChannels[iCurChanID].PutAudioData ( vecbyRecBuf, iNumBytesRead, HostAdr ) == PS_NEW_CONNECTION ) { // in case we have a new connection return this information bNewConnection = true; } } // return the state if a new connection was happening return bNewConnection; } void CServer::GetConCliParam ( CVector& vecHostAddresses, CVector& vecsName, CVector& veciJitBufNumFrames, CVector& veciNetwFrameSizeFact ) { // init return values vecHostAddresses.Init ( iMaxNumChannels ); vecsName.Init ( iMaxNumChannels ); veciJitBufNumFrames.Init ( iMaxNumChannels ); veciNetwFrameSizeFact.Init ( iMaxNumChannels ); // check all possible channels for ( int i = 0; i < iMaxNumChannels; i++ ) { if ( vecChannels[i].IsConnected() ) { // get requested data vecHostAddresses[i] = vecChannels[i].GetAddress(); vecsName[i] = vecChannels[i].GetName(); veciJitBufNumFrames[i] = vecChannels[i].GetSockBufNumFrames(); veciNetwFrameSizeFact[i] = vecChannels[i].GetNetwFrameSizeFact(); } } } void CServer::SetEnableRecording ( bool bNewEnableRecording ) { JamController.SetEnableRecording ( bNewEnableRecording, IsRunning() ); // not dependent upon JamController state bDisableRecording = !bNewEnableRecording; // the recording state may have changed, send recording state message CreateAndSendRecorderStateForAllConChannels(); } void CServer::SetWelcomeMessage ( const QString& strNWelcMess ) { // we need a mutex to secure access QMutexLocker locker ( &MutexWelcomeMessage ); strWelcomeMessage = strNWelcMess; // restrict welcome message to maximum allowed length strWelcomeMessage = strWelcomeMessage.left ( MAX_LEN_CHAT_TEXT ); } void CServer::WriteHTMLChannelList() { // prepare file and stream QFile serverFileListFile ( strServerHTMLFileListName ); if ( serverFileListFile.open ( QIODevice::WriteOnly | QIODevice::Text ) ) { QTextStream streamFileOut ( &serverFileListFile ); // depending on number of connected clients write list if ( GetNumberOfConnectedClients() == 0 ) { // no clients are connected -> empty server streamFileOut << " No client connected\n"; } else { streamFileOut << "
    \n"; // write entry for each connected client for ( int i = 0; i < iMaxNumChannels; i++ ) { if ( vecChannels[i].IsConnected() ) { streamFileOut << "
  • " << vecChannels[i].GetName().toHtmlEscaped() << "
  • \n"; } } streamFileOut << "
\n"; } } } void CServer::WriteHTMLServerQuit() { // prepare file and stream QFile serverFileListFile ( strServerHTMLFileListName ); if ( !serverFileListFile.open ( QIODevice::WriteOnly | QIODevice::Text ) ) { return; } QTextStream streamFileOut ( &serverFileListFile ); streamFileOut << " Server terminated\n"; serverFileListFile.close(); } void CServer::customEvent ( QEvent* pEvent ) { if ( pEvent->type() == QEvent::User + 11 ) { const int iMessType = ( (CCustomEvent*) pEvent )->iMessType; switch ( iMessType ) { case MS_PACKET_RECEIVED: // wake up the server if a packet was received // if the server is still running, the call to Start() will have // no effect Start(); break; } } } /// @brief Compute frame peak level for each client bool CServer::CreateLevelsForAllConChannels ( const int iNumClients, const CVector& vecNumAudioChannels, const CVector> vecvecsData, CVector& vecLevelsOut ) { bool bLevelsWereUpdated = false; // low frequency updates if ( iFrameCount > CHANNEL_LEVEL_UPDATE_INTERVAL ) { iFrameCount = 0; bLevelsWereUpdated = true; for ( int j = 0; j < iNumClients; j++ ) { // update and get signal level for meter in dB for each channel const double dCurSigLevelForMeterdB = vecChannels[vecChanIDsCurConChan[j]].UpdateAndGetLevelForMeterdB ( vecvecsData[j], iServerFrameSizeSamples, vecNumAudioChannels[j] > 1 ); // map value to integer for transmission via the protocol (4 bit available) vecLevelsOut[j] = static_cast ( std::ceil ( dCurSigLevelForMeterdB ) ); } } // increment the frame counter needed for low frequency update trigger iFrameCount++; if ( bUseDoubleSystemFrameSize ) { // additional increment needed for double frame size to get to the same time interval iFrameCount++; } return bLevelsWereUpdated; } jamulus-3.9.1+dfsg/src/protocol.cpp0000644000175000017500000030220514340334543016312 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ /* Protocol message definition --------------------------- - All messages received need to be acknowledged by an acknowledge packet (except of connection less messages) MAIN FRAME ---------- +-------------+------------+------------+------------------+ ... | 2 bytes TAG | 2 bytes ID | 1 byte cnt | 2 bytes length n | ... +-------------+------------+------------+------------------+ ... ... --------------+-------------+ ... n bytes data | 2 bytes CRC | ... --------------+-------------+ - TAG is an all zero bit word to identify protocol messages - message ID defined by the defines PROTMESSID_x - cnt: counter which is increment for each message and wraps around at 255 - length n in bytes of the data - actual data, dependent on message type - 16 bits CRC, calculated over the entire message and is transmitted inverted Generator polynom: G_16(x) = x^16 + x^12 + x^5 + 1, initial state: all ones SPLIT MESSAGE CONTAINER ----------------------- +------------+------------------------+------------------+--------------+ | 2 bytes ID | 1 byte number of parts | 1 byte split cnt | n bytes data | +------------+------------------------+------------------+--------------+ - ID is the message ID of the message being split - number of parts - total number of parts comprising the whole message - split cnt - number within number total for this part of the message - data - subset of the data part of the original message being split MESSAGES (with connection) -------------------------- - PROTMESSID_ACKN: Acknowledgement message +------------------------------------------+ | 2 bytes ID of message to be acknowledged | +------------------------------------------+ note: the cnt value is the same as of the message to be acknowledged - PROTMESSID_JITT_BUF_SIZE: Jitter buffer size +--------------------------+ | 2 bytes number of blocks | +--------------------------+ - PROTMESSID_REQ_JITT_BUF_SIZE: Request jitter buffer size note: does not have any data -> n = 0 - PROTMESSID_CLIENT_ID: Sends the current client ID to the client +---------------------------------+ | 1 byte channel ID of the client | +---------------------------------+ - PROTMESSID_CHANNEL_GAIN: Gain of channel +-------------------+--------------+ | 1 byte channel ID | 2 bytes gain | +-------------------+--------------+ - PROTMESSID_CHANNEL_PAN: Gain of channel +-------------------+-----------------+ | 1 byte channel ID | 2 bytes panning | +-------------------+-----------------+ - PROTMESSID_MUTE_STATE_CHANGED: Mute state of your signal at another client has changed +-------------------+-----------------+ | 1 byte channel ID | 1 byte is muted | +-------------------+-----------------+ - PROTMESSID_CONN_CLIENTS_LIST: Information about connected clients for each connected client append following data: +-------------------+-----------------+--------------------+ ... | 1 byte channel ID | 2 bytes country | 4 bytes instrument | ... +-------------------+-----------------+--------------------+ ... ... --------------------+--------------------------------------+ ... ... 1 byte skill level | 4 bytes zero (used to be IP address) | ... ... --------------------+--------------------------------------+ ... ... ------------------+---------------------------+ ... 2 bytes number n | n bytes UTF-8 string name | ... ------------------+---------------------------+ ... ------------------+---------------------------+ ... 2 bytes number n | n bytes UTF-8 string city | ... ------------------+---------------------------+ - PROTMESSID_REQ_CONN_CLIENTS_LIST: Request connected clients list note: does not have any data -> n = 0 - PROTMESSID_CHANNEL_INFOS: Information about the channel +-----------------+--------------------+ ... | 2 bytes country | 4 bytes instrument | ... +-----------------+--------------------+ ... ... --------------------+ ... ... 1 byte skill level | ... ... --------------------+ ... ... ------------------+---------------------------+ ... ... 2 bytes number n | n bytes UTF-8 string name | ... ... ------------------+---------------------------+ ... ... ------------------+---------------------------+ ... 2 bytes number n | n bytes UTF-8 string city | ... ------------------+---------------------------+ - PROTMESSID_REQ_CHANNEL_INFOS: Request infos of the channel note: does not have any data -> n = 0 - PROTMESSID_CHAT_TEXT: Chat text +------------------+----------------------+ | 2 bytes number n | n bytes UTF-8 string | +------------------+----------------------+ - "UTF-8 string": the chat message (plain text from client to server; HTML from server to client) - PROTMESSID_NETW_TRANSPORT_PROPS: Properties for network transport +------------------------+-------------------------+-----------------+ ... | 4 bytes base netw size | 2 bytes block size fact | 1 byte num chan | ... +------------------------+-------------------------+-----------------+ ... ... ------------------+-----------------------+ ... ... 4 bytes sam rate | 2 bytes audiocod type | ... ... ------------------+-----------------------+ ... ... ---------------+----------------------+ ... 2 bytes flags | 4 bytes audiocod arg | ... ---------------+----------------------+ - "base netw size": length of the base network packet (frame) in bytes - "block size fact": block size factor - "num chan": number of channels of the audio signal, e.g. "2" is stereo - "sam rate": sample rate of the audio stream - "audiocod type": audio coding type, the following types are supported: - 0: none, no audio coding applied - 1: CELT - 2: OPUS - 3: OPUS64 - "flags": flags indicating network properties: - 0: none - 1: WITH_COUNTER (a packet counter is added to the audio packet) - "audiocod arg": argument for the audio coder, if not used this value shall be set to 0 - PROTMESSID_REQ_NETW_TRANSPORT_PROPS: Request properties for network transport note: does not have any data -> n = 0 - PROTMESSID_REQ_SPLIT_MESS_SUPPORT: Request split message support note: does not have any data -> n = 0 - PROTMESSID_SPLIT_MESS_SUPPORTED: Split messages are supported note: does not have any data -> n = 0 - PROTMESSID_LICENCE_REQUIRED: Licence required to connect to the server +---------------------+ | 1 byte licence type | +---------------------+ - PROTMESSID_VERSION_AND_OS: Version number and operating system +-------------------------+------------------+------------------------------+ | 1 byte operating system | 2 bytes number n | n bytes UTF-8 string version | +-------------------------+------------------+------------------------------+ // #### COMPATIBILITY OLD VERSION, TO BE REMOVED #### - PROTMESSID_OPUS_SUPPORTED: Informs that OPUS codec is supported note: does not have any data -> n = 0 - PROTMESSID_RECORDER_STATE: notifies of changes in the server jam recorder state +--------------+ | 1 byte state | +--------------+ state is a value from the enum ERecorderState: - 0 undefined (not used by protocol messages) - tbc CONNECTION LESS MESSAGES ------------------------ - PROTMESSID_CLM_PING_MS: Connection less ping message (for measuring the ping time) +-----------------------------+ | 4 bytes transmit time in ms | +-----------------------------+ - PROTMESSID_CLM_PING_MS_WITHNUMCLIENTS: Connection less ping message (for measuring the ping time) with the info about the current number of connected clients +-----------------------------+---------------------------------+ | 4 bytes transmit time in ms | 1 byte number connected clients | +-----------------------------+---------------------------------+ - PROTMESSID_CLM_SERVER_FULL: Connection less server full message note: does not have any data -> n = 0 - PROTMESSID_CLM_REGISTER_SERVER: Register a server, providing server information +------------------------------+ ... | 2 bytes server internal port | ... +------------------------------+ ... ... -----------------+----------------------------------+ ... ... 2 bytes country | 1 byte maximum connected clients | ... ... -----------------+----------------------------------+ ... ... ---------------------+ ... ... 1 byte is permanent | ... ... ---------------------+ ... ... ------------------+----------------------------------+ ... ... 2 bytes number n | n bytes UTF-8 string server name | ... ... ------------------+----------------------------------+ ... ... ------------------+----------------------------------------------+ ... ... 2 bytes number n | n bytes UTF-8 string server internal address | ... ... ------------------+----------------------------------------------+ ... ... ------------------+---------------------------+ ... 2 bytes number n | n bytes UTF-8 string city | ... ------------------+---------------------------+ - "country" is according to "Common Locale Data Repository" which is used in the QLocale class - "maximum connected clients" is the maximum number of clients which can be connected to the server at the same time - "is permanent" is a flag which indicates if the server is permanent online or not. If this value is any value <> 0 indicates that the server is permanent online. - "server internal address" represents the IPv4 address as a dotted quad to be used by clients with the same external IP address as the server. NOTE: In the PROTMESSID_CLM_SERVER_LIST list, this field will be empty as only the initial IP address should be used by the client. Where necessary, that value will contain the server internal address. When running a directory server and a registered server behind the same NAT, this field is used the other way round: It will contain the public IP in this case which will be served to clients from the Internet. - PROTMESSID_CLM_REGISTER_SERVER_EX: Register a server, providing extended server information +--------------------------------+-------------------------------+ | PROTMESSID_CLM_REGISTER_SERVER | PROTMESSID_CLM_VERSION_AND_OS | +--------------------------------+-------------------------------+ - PROTMESSID_CLM_UNREGISTER_SERVER: Unregister a server note: does not have any data -> n = 0 - PROTMESSID_CLM_SERVER_LIST: Server list message for each registered server append following data: +--------------------+--------------------------------+ | 4 bytes IP address | PROTMESSID_CLM_REGISTER_SERVER | +--------------------+--------------------------------+ - "PROTMESSID_CLM_REGISTER_SERVER" means that exactly the same message body of the PROTMESSID_CLM_REGISTER_SERVER message is used - PROTMESSID_CLM_RED_SERVER_LIST: Reduced server list message (to have less UDP fragmentation) for each registered server append following data: +--------------------+------------------------------+ ... | 4 bytes IP address | 2 bytes server internal port | ... +--------------------+------------------------------+ ... ... -----------------+----------------------------------+ ... 1 byte number n | n bytes UTF-8 string server name | ... -----------------+----------------------------------+ - PROTMESSID_CLM_REQ_SERVER_LIST: Request server list note: does not have any data -> n = 0 - PROTMESSID_CLM_SEND_EMPTY_MESSAGE: Send "empty message" message +--------------------+--------------+ | 4 bytes IP address | 2 bytes port | +--------------------+--------------+ - PROTMESSID_CLM_DISCONNECTION: Disconnect message note: does not have any data -> n = 0 - PROTMESSID_CLM_VERSION_AND_OS: Version number and operating system +-------------------------+------------------+------------------------------+ | 1 byte operating system | 2 bytes number n | n bytes UTF-8 string version | +-------------------------+------------------+------------------------------+ - PROTMESSID_CLM_REQ_VERSION_AND_OS: Request version number and operating system note: does not have any data -> n = 0 - PROTMESSID_CLM_CONN_CLIENTS_LIST: Information about connected clients for each connected client append the PROTMESSID_CONN_CLIENTS_LIST: +------------------------------+------------------------------+ ... | PROTMESSID_CONN_CLIENTS_LIST | PROTMESSID_CONN_CLIENTS_LIST | ... +------------------------------+------------------------------+ ... - PROTMESSID_CLM_REQ_CONN_CLIENTS_LIST: Request the connected clients list note: does not have any data -> n = 0 - PROTMESSID_CLM_CHANNEL_LEVEL_LIST: The channel level list +----------------------------------+ | ( ( n + 1 ) / 2 ) * 4 bit values | +----------------------------------+ n is number of connected clients the values are the maximum channel levels for a client frame converted to the range of CLevelMeter in 4 bits, two entries per byte with the earlier channel in the lower half of the byte where an odd number of clients is connected, there will be four unused upper bits in the final byte, containing 0xF (which is out of range) the server may compute the message when any client has used PROTMESSID_CLM_REQ_CHANNEL_LEVEL_LIST to opt in the server should issue the message only to a client that has used PROTMESSID_CLM_REQ_CHANNEL_LEVEL_LIST to opt in - PROTMESSID_CLM_REGISTER_SERVER_RESP: result of registration request +---------------+ | 1 byte status | +---------------+ - "status": Values of ESvrRegResult: 0 - success 1 - failed due to directory server list being full 2 - your server version is too old 3 - registration requirements not fulfilled Note: the directory server may send this message in response to a PROTMESSID_CLM_REGISTER_SERVER request. Where not received, the registering server may only retry up to five times for one registration request at 500ms intervals. Beyond this, it should "ping" every 15 minutes (standard re-registration timeout). */ #include "protocol.h" /* Implementation *************************************************************/ CProtocol::CProtocol() { // allocate worst case memory for split part messages vecbySplitMessageStorage.Init ( MAX_SIZE_BYTES_NETW_BUF ); Reset(); // Connections ------------------------------------------------------------- QObject::connect ( &TimerSendMess, &QTimer::timeout, this, &CProtocol::OnTimerSendMess ); } void CProtocol::Reset() { QMutexLocker locker ( &Mutex ); // prepare internal variables for initial protocol transfer iCounter = 0; iOldRecID = PROTMESSID_ILLEGAL; iOldRecCnt = 0; iSplitMessageCnt = 0; iSplitMessageDataIndex = 0; bSplitMessageSupported = false; // compatilibity to old versions // delete complete "send message queue" SendMessQueue.clear(); } void CProtocol::EnqueueMessage ( CVector& vecMessage, const int iCnt, const int iID ) { bool bListWasEmpty; Mutex.lock(); { // check if list is empty so that we have to initiate a send process bListWasEmpty = SendMessQueue.empty(); // create send message object for the queue CSendMessage SendMessageObj ( vecMessage, iCnt, iID ); // we want to have a FIFO: we add at the end and take from the beginning SendMessQueue.push_back ( SendMessageObj ); } Mutex.unlock(); // if list was empty, initiate send process if ( bListWasEmpty ) { SendMessage(); } } void CProtocol::SendMessage() { CVector vecMessage; bool bSendMess = false; Mutex.lock(); { // we have to check that list is not empty, since in another thread the // last element of the list might have been erased if ( !SendMessQueue.empty() ) { vecMessage.Init ( SendMessQueue.front().vecMessage.Size() ); vecMessage = SendMessQueue.front().vecMessage; // start or restart the ack timeout TimerSendMess.start ( SEND_MESS_TIMEOUT_MS ); bSendMess = true; } else { // no message to send, stop timer TimerSendMess.stop(); } } Mutex.unlock(); if ( bSendMess ) { // send message emit MessReadyForSending ( vecMessage ); } } void CProtocol::CreateAndSendMessage ( const int iID, const CVector& vecData ) { CVector vecNewMessage; int iCurCounter; const int iDataLen = vecData.Size(); // check if message has to be split because it is too large if ( bSplitMessageSupported && ( iDataLen > MESS_SPLIT_PART_SIZE_BYTES ) ) { CVector vecNewSplitMessage; int iStartIndexInData = 0; // init index // calculate the number of split parts const int iNumParts = static_cast ( std::ceil ( static_cast ( iDataLen ) / MESS_SPLIT_PART_SIZE_BYTES ) ); for ( int iSplitCnt = 0; iSplitCnt < iNumParts; iSplitCnt++ ) { // the split part size may be smaller for the last part int iCurPartSize = MESS_SPLIT_PART_SIZE_BYTES; if ( iDataLen - iStartIndexInData < MESS_SPLIT_PART_SIZE_BYTES ) { iCurPartSize = iDataLen - iStartIndexInData; } GenSplitMessageContainer ( vecNewSplitMessage, iID, iNumParts, iSplitCnt, vecData, iStartIndexInData, iCurPartSize ); // increment the start index of the source data by the last part size iStartIndexInData += iCurPartSize; Mutex.lock(); { // store current counter value iCurCounter = iCounter; // increase counter (wraps around automatically) iCounter++; } Mutex.unlock(); // build complete message GenMessageFrame ( vecNewMessage, iCurCounter, PROTMESSID_SPECIAL_SPLIT_MESSAGE, vecNewSplitMessage ); // enqueue message EnqueueMessage ( vecNewMessage, iCurCounter, PROTMESSID_SPECIAL_SPLIT_MESSAGE ); } } else { Mutex.lock(); { // store current counter value iCurCounter = iCounter; // increase counter (wraps around automatically) iCounter++; } Mutex.unlock(); // build complete message GenMessageFrame ( vecNewMessage, iCurCounter, iID, vecData ); // enqueue message EnqueueMessage ( vecNewMessage, iCurCounter, iID ); } } void CProtocol::CreateAndImmSendAcknMess ( const int& iID, const int& iCnt ) { CVector vecAcknMessage; CVector vecData ( 2 ); // 2 bytes of data int iPos = 0; // init position pointer // build data vector PutValOnStream ( vecData, iPos, static_cast ( iID ), 2 ); // build complete message GenMessageFrame ( vecAcknMessage, iCnt, PROTMESSID_ACKN, vecData ); // immediately send acknowledge message emit MessReadyForSending ( vecAcknMessage ); } void CProtocol::CreateAndImmSendConLessMessage ( const int iID, const CVector& vecData, const CHostAddress& InetAddr ) { CVector vecNewMessage; // build complete message (counter per definition=0 for connection less // messages) GenMessageFrame ( vecNewMessage, 0, iID, vecData ); // immediately send message emit CLMessReadyForSending ( InetAddr, vecNewMessage ); } void CProtocol::ParseMessageBody ( const CVector& vecbyMesBodyData, const int iRecCounter, const int iRecID ) { //### TEST: BEGIN ###// // channel implementation: randomly delete protocol messages (50 % loss) // if ( rand() < ( RAND_MAX / 2 ) ) return false; //### TEST: END ###// // In case we received a message and returned an answer but our answer // did not make it to the receiver, he will resend his message. We check // here if the message is the same as the old one, and if this is the // case, just resend our old answer again if ( ( iOldRecID == iRecID ) && ( iOldRecCnt == iRecCounter ) ) { // acknowledgments are not acknowledged if ( iRecID != PROTMESSID_ACKN ) { // resend acknowledgement CreateAndImmSendAcknMess ( iRecID, iRecCounter ); } } else { // special treatment for acknowledge messages if ( iRecID == PROTMESSID_ACKN ) { // check size if ( vecbyMesBodyData.Size() != 2 ) { return; } // extract data from stream and emit signal for received value bool bSendNextMess = false; int iPos = 0; const int iData = static_cast ( GetValFromStream ( vecbyMesBodyData, iPos, 2 ) ); Mutex.lock(); { // check if this is the correct acknowledgment if ( !SendMessQueue.empty() ) { if ( ( SendMessQueue.front().iCnt == iRecCounter ) && ( SendMessQueue.front().iID == iData ) ) { // message acknowledged, remove from queue SendMessQueue.pop_front(); // send next message in queue bSendNextMess = true; } } } Mutex.unlock(); if ( bSendNextMess ) { SendMessage(); } } else { CVector vecbyMesBodyDataSplitMess; int iRecIDModified = iRecID; bool bEvaluateMessage = false; // check for special ID first if ( iRecID == PROTMESSID_SPECIAL_SPLIT_MESSAGE ) { // Split message management ------------------------------------ int iOriginalID; int iReceivedNumParts; int iReceivedSplitCnt; int iCurPartSize; if ( !ParseSplitMessageContainer ( vecbyMesBodyData, vecbySplitMessageStorage, iSplitMessageDataIndex, iOriginalID, iReceivedNumParts, iReceivedSplitCnt, iCurPartSize ) ) { // consistency checks if ( ( iSplitMessageCnt != iReceivedSplitCnt ) || ( iSplitMessageCnt >= iReceivedNumParts ) || ( iSplitMessageCnt >= MAX_NUM_MESS_SPLIT_PARTS ) ) { // in case of an error we reset the split message counter iSplitMessageCnt = 0; iSplitMessageDataIndex = 0; } else { // update counter and message data index since we have received a valid new part iSplitMessageCnt++; iSplitMessageDataIndex += iCurPartSize; // check if the split part messages was completely received if ( iSplitMessageCnt == iReceivedNumParts ) { // the split message is completely received, copy data for parsing vecbyMesBodyDataSplitMess.Init ( iSplitMessageDataIndex ); std::copy ( vecbySplitMessageStorage.begin(), vecbySplitMessageStorage.begin() + iSplitMessageDataIndex, vecbyMesBodyDataSplitMess.begin() ); // the received ID is still PROTMESSID_SPECIAL_SPLIT_MESSAGE, set it to // the ID of the original reconstructed split message now iRecIDModified = iOriginalID; // the complete split message was reconstructed, reset the counter for // the next split message iSplitMessageCnt = 0; iSplitMessageDataIndex = 0; bEvaluateMessage = true; } } } } else { // a non-split message was received, reset split message counter and directly evaluate message iSplitMessageCnt = 0; iSplitMessageDataIndex = 0; bEvaluateMessage = true; } if ( bEvaluateMessage ) { // use a reference to either the original data vector or the reconstructed // split message to avoid unnecessary copying const CVector& vecbyMesBodyDataRef = ( iRecID == PROTMESSID_SPECIAL_SPLIT_MESSAGE ) ? vecbyMesBodyDataSplitMess : vecbyMesBodyData; // check which type of message we received and do action switch ( iRecIDModified ) { case PROTMESSID_JITT_BUF_SIZE: EvaluateJitBufMes ( vecbyMesBodyDataRef ); break; case PROTMESSID_REQ_JITT_BUF_SIZE: EvaluateReqJitBufMes(); break; case PROTMESSID_CLIENT_ID: EvaluateClientIDMes ( vecbyMesBodyDataRef ); break; case PROTMESSID_CHANNEL_GAIN: EvaluateChanGainMes ( vecbyMesBodyDataRef ); break; case PROTMESSID_CHANNEL_PAN: EvaluateChanPanMes ( vecbyMesBodyDataRef ); break; case PROTMESSID_MUTE_STATE_CHANGED: EvaluateMuteStateHasChangedMes ( vecbyMesBodyDataRef ); break; case PROTMESSID_CONN_CLIENTS_LIST: EvaluateConClientListMes ( vecbyMesBodyDataRef ); break; case PROTMESSID_REQ_CONN_CLIENTS_LIST: EvaluateReqConnClientsList(); break; case PROTMESSID_CHANNEL_INFOS: EvaluateChanInfoMes ( vecbyMesBodyDataRef ); break; case PROTMESSID_REQ_CHANNEL_INFOS: EvaluateReqChanInfoMes(); break; case PROTMESSID_CHAT_TEXT: EvaluateChatTextMes ( vecbyMesBodyDataRef ); break; case PROTMESSID_NETW_TRANSPORT_PROPS: EvaluateNetwTranspPropsMes ( vecbyMesBodyDataRef ); break; case PROTMESSID_REQ_NETW_TRANSPORT_PROPS: EvaluateReqNetwTranspPropsMes(); break; case PROTMESSID_REQ_SPLIT_MESS_SUPPORT: EvaluateReqSplitMessSupportMes(); break; case PROTMESSID_SPLIT_MESS_SUPPORTED: EvaluateSplitMessSupportedMes(); break; case PROTMESSID_LICENCE_REQUIRED: EvaluateLicenceRequiredMes ( vecbyMesBodyDataRef ); break; case PROTMESSID_VERSION_AND_OS: EvaluateVersionAndOSMes ( vecbyMesBodyDataRef ); break; case PROTMESSID_RECORDER_STATE: EvaluateRecorderStateMes ( vecbyMesBodyDataRef ); break; } } // immediately send acknowledge message CreateAndImmSendAcknMess ( iRecID, iRecCounter ); // save current message ID and counter to find out if message // was resent iOldRecID = iRecID; iOldRecCnt = iRecCounter; } } } void CProtocol::ParseConnectionLessMessageBody ( const CVector& vecbyMesBodyData, const int iRecID, const CHostAddress& InetAddr ) { //### TEST: BEGIN ###// // Test channel implementation: randomly delete protocol messages (50 % loss) // if ( rand() < ( RAND_MAX / 2 ) ) return false; //### TEST: END ###// // check which type of message we received and do action switch ( iRecID ) { case PROTMESSID_CLM_PING_MS: EvaluateCLPingMes ( InetAddr, vecbyMesBodyData ); break; case PROTMESSID_CLM_PING_MS_WITHNUMCLIENTS: EvaluateCLPingWithNumClientsMes ( InetAddr, vecbyMesBodyData ); break; case PROTMESSID_CLM_SERVER_FULL: EvaluateCLServerFullMes(); break; case PROTMESSID_CLM_SERVER_LIST: EvaluateCLServerListMes ( InetAddr, vecbyMesBodyData ); break; case PROTMESSID_CLM_RED_SERVER_LIST: EvaluateCLRedServerListMes ( InetAddr, vecbyMesBodyData ); break; case PROTMESSID_CLM_REQ_SERVER_LIST: EvaluateCLReqServerListMes ( InetAddr ); break; case PROTMESSID_CLM_SEND_EMPTY_MESSAGE: EvaluateCLSendEmptyMesMes ( vecbyMesBodyData ); break; case PROTMESSID_CLM_REGISTER_SERVER: EvaluateCLRegisterServerMes ( InetAddr, vecbyMesBodyData ); break; case PROTMESSID_CLM_REGISTER_SERVER_EX: EvaluateCLRegisterServerExMes ( InetAddr, vecbyMesBodyData ); break; case PROTMESSID_CLM_UNREGISTER_SERVER: EvaluateCLUnregisterServerMes ( InetAddr ); break; case PROTMESSID_CLM_DISCONNECTION: EvaluateCLDisconnectionMes ( InetAddr ); break; case PROTMESSID_CLM_VERSION_AND_OS: EvaluateCLVersionAndOSMes ( InetAddr, vecbyMesBodyData ); break; case PROTMESSID_CLM_REQ_VERSION_AND_OS: EvaluateCLReqVersionAndOSMes ( InetAddr ); break; case PROTMESSID_CLM_CONN_CLIENTS_LIST: EvaluateCLConnClientsListMes ( InetAddr, vecbyMesBodyData ); break; case PROTMESSID_CLM_REQ_CONN_CLIENTS_LIST: EvaluateCLReqConnClientsListMes ( InetAddr ); break; case PROTMESSID_CLM_CHANNEL_LEVEL_LIST: EvaluateCLChannelLevelListMes ( InetAddr, vecbyMesBodyData ); break; case PROTMESSID_CLM_REGISTER_SERVER_RESP: EvaluateCLRegisterServerResp ( InetAddr, vecbyMesBodyData ); break; } } /******************************************************************************\ * Access functions for creating and parsing messages * \******************************************************************************/ void CProtocol::CreateJitBufMes ( const int iJitBufSize ) { CVector vecData ( 2 ); // 2 bytes of data int iPos = 0; // init position pointer // build data vector PutValOnStream ( vecData, iPos, static_cast ( iJitBufSize ), 2 ); CreateAndSendMessage ( PROTMESSID_JITT_BUF_SIZE, vecData ); } bool CProtocol::EvaluateJitBufMes ( const CVector& vecData ) { int iPos = 0; // init position pointer // check size if ( vecData.Size() != 2 ) { return true; // return error code } // extract jitter buffer size const int iData = static_cast ( GetValFromStream ( vecData, iPos, 2 ) ); if ( ( ( iData < MIN_NET_BUF_SIZE_NUM_BL ) || ( iData > MAX_NET_BUF_SIZE_NUM_BL ) ) && ( iData != AUTO_NET_BUF_SIZE_FOR_PROTOCOL ) ) { return true; // return error code } // invoke message action emit ChangeJittBufSize ( iData ); return false; // no error } void CProtocol::CreateReqJitBufMes() { CreateAndSendMessage ( PROTMESSID_REQ_JITT_BUF_SIZE, CVector ( 0 ) ); } bool CProtocol::EvaluateReqJitBufMes() { // invoke message action emit ReqJittBufSize(); return false; // no error } void CProtocol::CreateClientIDMes ( const int iChanID ) { CVector vecData ( 1 ); // 1 byte of data int iPos = 0; // init position pointer // build data vector // channel ID PutValOnStream ( vecData, iPos, static_cast ( iChanID ), 1 ); CreateAndSendMessage ( PROTMESSID_CLIENT_ID, vecData ); } bool CProtocol::EvaluateClientIDMes ( const CVector& vecData ) { int iPos = 0; // init position pointer // check size if ( vecData.Size() != 1 ) { return true; // return error code } // channel ID const int iCurID = static_cast ( GetValFromStream ( vecData, iPos, 1 ) ); // invoke message action emit ClientIDReceived ( iCurID ); return false; // no error } void CProtocol::CreateChanGainMes ( const int iChanID, const float fGain ) { CVector vecData ( 3 ); // 3 bytes of data int iPos = 0; // init position pointer // build data vector // channel ID PutValOnStream ( vecData, iPos, static_cast ( iChanID ), 1 ); // actual gain, we convert from double with range 0..1 to integer const int iCurGain = static_cast ( fGain * ( 1 << 15 ) ); PutValOnStream ( vecData, iPos, static_cast ( iCurGain ), 2 ); CreateAndSendMessage ( PROTMESSID_CHANNEL_GAIN, vecData ); } bool CProtocol::EvaluateChanGainMes ( const CVector& vecData ) { int iPos = 0; // init position pointer // check size if ( vecData.Size() != 3 ) { return true; // return error code } // channel ID const int iCurID = static_cast ( GetValFromStream ( vecData, iPos, 1 ) ); // gain (read integer value) const int iData = static_cast ( GetValFromStream ( vecData, iPos, 2 ) ); // we convert the gain from integer to double with range 0..1 const float fNewGain = static_cast ( iData ) / ( 1 << 15 ); // invoke message action emit ChangeChanGain ( iCurID, fNewGain ); return false; // no error } void CProtocol::CreateChanPanMes ( const int iChanID, const float fPan ) { CVector vecData ( 3 ); // 3 bytes of data int iPos = 0; // init position pointer // build data vector // channel ID PutValOnStream ( vecData, iPos, static_cast ( iChanID ), 1 ); // actual pan, we convert from double with range 0..1 to integer const int iCurPan = static_cast ( fPan * ( 1 << 15 ) ); PutValOnStream ( vecData, iPos, static_cast ( iCurPan ), 2 ); CreateAndSendMessage ( PROTMESSID_CHANNEL_PAN, vecData ); } bool CProtocol::EvaluateChanPanMes ( const CVector& vecData ) { int iPos = 0; // init position pointer // check size if ( vecData.Size() != 3 ) { return true; // return error code } // channel ID const int iCurID = static_cast ( GetValFromStream ( vecData, iPos, 1 ) ); // pan (read integer value) const int iData = static_cast ( GetValFromStream ( vecData, iPos, 2 ) ); // we convert the pan from integer to double with range 0..1 const float fNewPan = static_cast ( iData ) / ( 1 << 15 ); // invoke message action emit ChangeChanPan ( iCurID, fNewPan ); return false; // no error } void CProtocol::CreateMuteStateHasChangedMes ( const int iChanID, const bool bIsMuted ) { CVector vecData ( 2 ); // 2 bytes of data int iPos = 0; // init position pointer // build data vector // channel ID PutValOnStream ( vecData, iPos, static_cast ( iChanID ), 1 ); // mute state PutValOnStream ( vecData, iPos, static_cast ( bIsMuted ), 1 ); CreateAndSendMessage ( PROTMESSID_MUTE_STATE_CHANGED, vecData ); } bool CProtocol::EvaluateMuteStateHasChangedMes ( const CVector& vecData ) { int iPos = 0; // init position pointer // check size if ( vecData.Size() != 2 ) { return true; // return error code } // channel ID const int iCurID = static_cast ( GetValFromStream ( vecData, iPos, 1 ) ); // mute state const bool bIsMuted = static_cast ( GetValFromStream ( vecData, iPos, 1 ) ); // invoke message action emit MuteStateHasChangedReceived ( iCurID, bIsMuted ); return false; // no error } void CProtocol::CreateConClientListMes ( const CVector& vecChanInfo ) { const int iNumClients = vecChanInfo.Size(); // build data vector CVector vecData ( 0 ); int iPos = 0; // init position pointer for ( int i = 0; i < iNumClients; i++ ) { // convert strings to utf-8 const QByteArray strUTF8Name = vecChanInfo[i].strName.toUtf8(); const QByteArray strUTF8City = vecChanInfo[i].strCity.toUtf8(); // size of current list entry const int iCurListEntrLen = 1 + // chan ID 2 + // country 4 + // instrument 1 + // skill level 4 + // IP address 2 + strUTF8Name.size() + // utf-8 str. size / str. 2 + strUTF8City.size(); // utf-8 str. size / str. // make space for new data vecData.Enlarge ( iCurListEntrLen ); // channel ID (1 byte) PutValOnStream ( vecData, iPos, static_cast ( vecChanInfo[i].iChanID ), 1 ); // country (2 bytes) PutCountryOnStream ( vecData, iPos, vecChanInfo[i].eCountry ); // instrument (4 bytes) PutValOnStream ( vecData, iPos, static_cast ( vecChanInfo[i].iInstrument ), 4 ); // skill level (1 byte) PutValOnStream ( vecData, iPos, static_cast ( vecChanInfo[i].eSkillLevel ), 1 ); // used to be IP address before #316 (4 bytes) PutValOnStream ( vecData, iPos, 0, 4 ); // name PutStringUTF8OnStream ( vecData, iPos, strUTF8Name ); // city PutStringUTF8OnStream ( vecData, iPos, strUTF8City ); } CreateAndSendMessage ( PROTMESSID_CONN_CLIENTS_LIST, vecData ); } bool CProtocol::EvaluateConClientListMes ( const CVector& vecData ) { int iPos = 0; // init position pointer const int iDataLen = vecData.Size(); CVector vecChanInfo ( 0 ); while ( iPos < iDataLen ) { // check size (the next 12 bytes) if ( ( iDataLen - iPos ) < 12 ) { return true; // return error code } // channel ID (1 byte) const int iChanID = static_cast ( GetValFromStream ( vecData, iPos, 1 ) ); // country (2 bytes) const QLocale::Country eCountry = GetCountryFromStream ( vecData, iPos ); // instrument (4 bytes) const int iInstrument = static_cast ( GetValFromStream ( vecData, iPos, 4 ) ); // skill level (1 byte) const ESkillLevel eSkillLevel = static_cast ( GetValFromStream ( vecData, iPos, 1 ) ); // used to be IP address, zero since #316 (4 bytes) iPos += 4; // name QString strCurName; if ( GetStringFromStream ( vecData, iPos, MAX_LEN_FADER_TAG, strCurName ) ) { return true; // return error code } // city QString strCurCity; if ( GetStringFromStream ( vecData, iPos, MAX_LEN_SERVER_CITY, strCurCity ) ) { return true; // return error code } // add channel information to vector vecChanInfo.Add ( CChannelInfo ( iChanID, strCurName, eCountry, strCurCity, iInstrument, eSkillLevel ) ); } // check size: all data is read, the position must now be at the end if ( iPos != iDataLen ) { return true; // return error code } // invoke message action emit ConClientListMesReceived ( vecChanInfo ); return false; // no error } void CProtocol::CreateReqConnClientsList() { CreateAndSendMessage ( PROTMESSID_REQ_CONN_CLIENTS_LIST, CVector ( 0 ) ); } bool CProtocol::EvaluateReqConnClientsList() { // invoke message action emit ReqConnClientsList(); return false; // no error } void CProtocol::CreateChanInfoMes ( const CChannelCoreInfo ChanInfo ) { int iPos = 0; // init position pointer // convert strings to utf-8 const QByteArray strUTF8Name = ChanInfo.strName.toUtf8(); const QByteArray strUTF8City = ChanInfo.strCity.toUtf8(); // size of current list entry const int iEntrLen = 2 + // country 4 + // instrument 1 + // skill level 2 + strUTF8Name.size() + // utf-8 str. size / str. 2 + strUTF8City.size(); // utf-8 str. size / str. // build data vector CVector vecData ( iEntrLen ); // country (2 bytes) PutCountryOnStream ( vecData, iPos, ChanInfo.eCountry ); // instrument (4 bytes) PutValOnStream ( vecData, iPos, static_cast ( ChanInfo.iInstrument ), 4 ); // skill level (1 byte) PutValOnStream ( vecData, iPos, static_cast ( ChanInfo.eSkillLevel ), 1 ); // name PutStringUTF8OnStream ( vecData, iPos, strUTF8Name ); // city PutStringUTF8OnStream ( vecData, iPos, strUTF8City ); CreateAndSendMessage ( PROTMESSID_CHANNEL_INFOS, vecData ); } bool CProtocol::EvaluateChanInfoMes ( const CVector& vecData ) { int iPos = 0; // init position pointer const int iDataLen = vecData.Size(); CChannelCoreInfo ChanInfo; // check size (the first 7 bytes) if ( iDataLen < 7 ) { return true; // return error code } // country (2 bytes) ChanInfo.eCountry = GetCountryFromStream ( vecData, iPos ); // instrument (4 bytes) ChanInfo.iInstrument = static_cast ( GetValFromStream ( vecData, iPos, 4 ) ); // skill level (1 byte) ChanInfo.eSkillLevel = static_cast ( GetValFromStream ( vecData, iPos, 1 ) ); // name if ( GetStringFromStream ( vecData, iPos, MAX_LEN_FADER_TAG, ChanInfo.strName ) ) { return true; // return error code } // city if ( GetStringFromStream ( vecData, iPos, MAX_LEN_SERVER_CITY, ChanInfo.strCity ) ) { return true; // return error code } // check size: all data is read, the position must now be at the end if ( iPos != iDataLen ) { return true; // return error code } // invoke message action emit ChangeChanInfo ( ChanInfo ); return false; // no error } void CProtocol::CreateReqChanInfoMes() { CreateAndSendMessage ( PROTMESSID_REQ_CHANNEL_INFOS, CVector ( 0 ) ); } bool CProtocol::EvaluateReqChanInfoMes() { // invoke message action emit ReqChanInfo(); return false; // no error } void CProtocol::CreateChatTextMes ( const QString strChatText ) { int iPos = 0; // init position pointer // convert chat text string to utf-8 const QByteArray strUTF8ChatText = strChatText.toUtf8(); const int iStrUTF8Len = strUTF8ChatText.size(); // get utf-8 str. size / string // size of message body const int iEntrLen = 2 + iStrUTF8Len; // utf-8 str. size / string // build data vector CVector vecData ( iEntrLen ); // chat text PutStringUTF8OnStream ( vecData, iPos, strUTF8ChatText ); CreateAndSendMessage ( PROTMESSID_CHAT_TEXT, vecData ); } bool CProtocol::EvaluateChatTextMes ( const CVector& vecData ) { int iPos = 0; // init position pointer // chat text QString strChatText; if ( GetStringFromStream ( vecData, iPos, MAX_LEN_CHAT_TEXT_PLUS_HTML, strChatText ) ) { return true; // return error code } // check size: all data is read, the position must now be at the end if ( iPos != vecData.Size() ) { return true; // return error code } // invoke message action emit ChatTextReceived ( strChatText ); return false; // no error } void CProtocol::CreateNetwTranspPropsMes ( const CNetworkTransportProps& NetTrProps ) { int iPos = 0; // init position pointer // size of current message body const int iEntrLen = 4 + // netw size 2 + // block size fact 1 + // num chan 4 + // sam rate 2 + // audiocod type 2 + // version 4; // audiocod arg // build data vector CVector vecData ( iEntrLen ); // length of the base network packet (frame) in bytes (4 bytes) PutValOnStream ( vecData, iPos, static_cast ( NetTrProps.iBaseNetworkPacketSize ), 4 ); // block size factor (2 bytes) PutValOnStream ( vecData, iPos, static_cast ( NetTrProps.iBlockSizeFact ), 2 ); // number of channels of the audio signal, e.g. "2" is stereo (1 byte) PutValOnStream ( vecData, iPos, static_cast ( NetTrProps.iNumAudioChannels ), 1 ); // sample rate of the audio stream (4 bytes) PutValOnStream ( vecData, iPos, static_cast ( NetTrProps.iSampleRate ), 4 ); // audio coding type (2 bytes) PutValOnStream ( vecData, iPos, static_cast ( NetTrProps.eAudioCodingType ), 2 ); // flags (2 bytes) PutValOnStream ( vecData, iPos, static_cast ( NetTrProps.eFlags ), 2 ); // argument for the audio coder (4 bytes) PutValOnStream ( vecData, iPos, static_cast ( NetTrProps.iAudioCodingArg ), 4 ); CreateAndSendMessage ( PROTMESSID_NETW_TRANSPORT_PROPS, vecData ); } bool CProtocol::EvaluateNetwTranspPropsMes ( const CVector& vecData ) { int iPos = 0; // init position pointer CNetworkTransportProps ReceivedNetwTranspProps; // size of current message body const int iEntrLen = 4 + // netw size 2 + // block size fact 1 + // num chan 4 + // sam rate 2 + // audiocod type 2 + // flags 4; // audiocod arg // check size if ( vecData.Size() != iEntrLen ) { return true; // return error code } // length of the base network packet (frame) in bytes (4 bytes) ReceivedNetwTranspProps.iBaseNetworkPacketSize = static_cast ( GetValFromStream ( vecData, iPos, 4 ) ); // at least CELT_MINIMUM_NUM_BYTES bytes are required for the CELC codec if ( ( ReceivedNetwTranspProps.iBaseNetworkPacketSize < CELT_MINIMUM_NUM_BYTES ) || ( ReceivedNetwTranspProps.iBaseNetworkPacketSize > MAX_SIZE_BYTES_NETW_BUF ) ) { return true; // return error code } // block size factor (2 bytes) ReceivedNetwTranspProps.iBlockSizeFact = static_cast ( GetValFromStream ( vecData, iPos, 2 ) ); if ( ( ReceivedNetwTranspProps.iBlockSizeFact != FRAME_SIZE_FACTOR_PREFERRED ) && ( ReceivedNetwTranspProps.iBlockSizeFact != FRAME_SIZE_FACTOR_DEFAULT ) && ( ReceivedNetwTranspProps.iBlockSizeFact != FRAME_SIZE_FACTOR_SAFE ) ) { return true; // return error code } // number of channels of the audio signal, only mono (1 channel) or // stereo (2 channels) allowed (1 byte) ReceivedNetwTranspProps.iNumAudioChannels = static_cast ( GetValFromStream ( vecData, iPos, 1 ) ); if ( ( ReceivedNetwTranspProps.iNumAudioChannels != 1 ) && ( ReceivedNetwTranspProps.iNumAudioChannels != 2 ) ) { return true; // return error code } // sample rate of the audio stream (4 bytes) ReceivedNetwTranspProps.iSampleRate = static_cast ( GetValFromStream ( vecData, iPos, 4 ) ); // audio coding type (2 bytes) with error check const int iRecCodingType = static_cast ( GetValFromStream ( vecData, iPos, 2 ) ); // note that CT_NONE is not a valid setting but only used for server // initialization if ( ( iRecCodingType != CT_CELT ) && ( iRecCodingType != CT_OPUS ) && ( iRecCodingType != CT_OPUS64 ) ) { return true; } ReceivedNetwTranspProps.eAudioCodingType = static_cast ( iRecCodingType ); // flags (2 bytes) ReceivedNetwTranspProps.eFlags = static_cast ( GetValFromStream ( vecData, iPos, 2 ) ); // argument for the audio coder (4 bytes) ReceivedNetwTranspProps.iAudioCodingArg = static_cast ( GetValFromStream ( vecData, iPos, 4 ) ); // invoke message action emit NetTranspPropsReceived ( ReceivedNetwTranspProps ); return false; // no error } void CProtocol::CreateReqNetwTranspPropsMes() { CreateAndSendMessage ( PROTMESSID_REQ_NETW_TRANSPORT_PROPS, CVector ( 0 ) ); } bool CProtocol::EvaluateReqNetwTranspPropsMes() { // invoke message action emit ReqNetTranspProps(); return false; // no error } void CProtocol::CreateReqSplitMessSupportMes() { CreateAndSendMessage ( PROTMESSID_REQ_SPLIT_MESS_SUPPORT, CVector ( 0 ) ); } bool CProtocol::EvaluateReqSplitMessSupportMes() { // invoke message action emit ReqSplitMessSupport(); return false; // no error } void CProtocol::CreateSplitMessSupportedMes() { CreateAndSendMessage ( PROTMESSID_SPLIT_MESS_SUPPORTED, CVector ( 0 ) ); } bool CProtocol::EvaluateSplitMessSupportedMes() { // invoke message action emit SplitMessSupported(); return false; // no error } void CProtocol::CreateLicenceRequiredMes ( const ELicenceType eLicenceType ) { CVector vecData ( 1 ); // 1 bytes of data int iPos = 0; // init position pointer // build data vector PutValOnStream ( vecData, iPos, static_cast ( eLicenceType ), 1 ); CreateAndSendMessage ( PROTMESSID_LICENCE_REQUIRED, vecData ); } bool CProtocol::EvaluateLicenceRequiredMes ( const CVector& vecData ) { int iPos = 0; // init position pointer // check size if ( vecData.Size() != 1 ) { return true; // return error code } // extract licence type const ELicenceType eLicenceType = static_cast ( GetValFromStream ( vecData, iPos, 1 ) ); if ( ( eLicenceType != LT_CREATIVECOMMONS ) && ( eLicenceType != LT_NO_LICENCE ) ) { return true; // return error code } // invoke message action emit LicenceRequired ( eLicenceType ); return false; // no error } void CProtocol::CreateOpusSupportedMes() { CreateAndSendMessage ( PROTMESSID_OPUS_SUPPORTED, CVector ( 0 ) ); } // TODO needed for compatibility to old servers >= 3.4.6 and <= 3.5.12 void CProtocol::CreateReqChannelLevelListMes() { CVector vecData ( 1 ); // 1 byte of data int iPos = 0; // init position pointer PutValOnStream ( vecData, iPos, static_cast ( true ), 1 ); CreateAndSendMessage ( PROTMESSID_REQ_CHANNEL_LEVEL_LIST, vecData ); } void CProtocol::CreateVersionAndOSMes() { int iPos = 0; // init position pointer // get the version number string const QString strVerion = VERSION; // convert version string to utf-8 const QByteArray strUTF8Version = strVerion.toUtf8(); // size of current message body const int iEntrLen = 1 + // operating system 2 + strUTF8Version.size(); // version utf-8 str. size / string // build data vector CVector vecData ( iEntrLen ); // operating system (1 byte) PutValOnStream ( vecData, iPos, static_cast ( COSUtil::GetOperatingSystem() ), 1 ); // version PutStringUTF8OnStream ( vecData, iPos, strUTF8Version ); CreateAndSendMessage ( PROTMESSID_VERSION_AND_OS, vecData ); } bool CProtocol::EvaluateVersionAndOSMes ( const CVector& vecData ) { int iPos = 0; // init position pointer const int iDataLen = vecData.Size(); // check size (the first 1 byte) if ( iDataLen < 1 ) { return true; // return error code } // operating system (1 byte) const COSUtil::EOpSystemType eOSType = static_cast ( GetValFromStream ( vecData, iPos, 1 ) ); // version text QString strVersion; if ( GetStringFromStream ( vecData, iPos, MAX_LEN_VERSION_TEXT, strVersion ) ) { return true; // return error code } // check size: all data is read, the position must now be at the end if ( iPos != iDataLen ) { return true; // return error code } // invoke message action emit VersionAndOSReceived ( eOSType, strVersion ); return false; // no error } void CProtocol::CreateRecorderStateMes ( const ERecorderState eRecorderState ) { CVector vecData ( 1 ); // 1 byte of data int iPos = 0; // init position pointer // build data vector // server jam recorder state (1 byte) PutValOnStream ( vecData, iPos, static_cast ( eRecorderState ), 1 ); CreateAndSendMessage ( PROTMESSID_RECORDER_STATE, vecData ); } bool CProtocol::EvaluateRecorderStateMes ( const CVector& vecData ) { int iPos = 0; // init position pointer // check size if ( vecData.Size() != 1 ) { return true; // return error code } // server jam recorder state (1 byte) const int iRecorderState = static_cast ( GetValFromStream ( vecData, iPos, 1 ) ); // note that RS_UNDEFINED is only internally used if ( ( iRecorderState != RS_NOT_INITIALISED ) && ( iRecorderState != RS_NOT_ENABLED ) && ( iRecorderState != RS_RECORDING ) ) { return true; } // invoke message action emit RecorderStateReceived ( static_cast ( iRecorderState ) ); return false; // no error } // Connection less messages ---------------------------------------------------- void CProtocol::CreateCLPingMes ( const CHostAddress& InetAddr, const int iMs ) { int iPos = 0; // init position pointer // build data vector (4 bytes long) CVector vecData ( 4 ); // transmit time (4 bytes) PutValOnStream ( vecData, iPos, static_cast ( iMs ), 4 ); CreateAndImmSendConLessMessage ( PROTMESSID_CLM_PING_MS, vecData, InetAddr ); } bool CProtocol::EvaluateCLPingMes ( const CHostAddress& InetAddr, const CVector& vecData ) { int iPos = 0; // init position pointer // check size if ( vecData.Size() != 4 ) { return true; // return error code } // invoke message action emit CLPingReceived ( InetAddr, static_cast ( GetValFromStream ( vecData, iPos, 4 ) ) ); return false; // no error } void CProtocol::CreateCLPingWithNumClientsMes ( const CHostAddress& InetAddr, const int iMs, const int iNumClients ) { int iPos = 0; // init position pointer // build data vector (5 bytes long) CVector vecData ( 5 ); // transmit time (4 bytes) PutValOnStream ( vecData, iPos, static_cast ( iMs ), 4 ); // current number of connected clients (1 byte) PutValOnStream ( vecData, iPos, static_cast ( iNumClients ), 1 ); CreateAndImmSendConLessMessage ( PROTMESSID_CLM_PING_MS_WITHNUMCLIENTS, vecData, InetAddr ); } bool CProtocol::EvaluateCLPingWithNumClientsMes ( const CHostAddress& InetAddr, const CVector& vecData ) { int iPos = 0; // init position pointer // check size if ( vecData.Size() != 5 ) { return true; // return error code } // transmit time const int iCurMs = static_cast ( GetValFromStream ( vecData, iPos, 4 ) ); // current number of connected clients const int iCurNumClients = static_cast ( GetValFromStream ( vecData, iPos, 1 ) ); // invoke message action emit CLPingWithNumClientsReceived ( InetAddr, iCurMs, iCurNumClients ); return false; // no error } void CProtocol::CreateCLServerFullMes ( const CHostAddress& InetAddr ) { CreateAndImmSendConLessMessage ( PROTMESSID_CLM_SERVER_FULL, CVector ( 0 ), InetAddr ); } bool CProtocol::EvaluateCLServerFullMes() { // invoke message action emit ServerFullMesReceived(); return false; // no error } void CProtocol::CreateCLRegisterServerMes ( const CHostAddress& InetAddr, const CHostAddress& LInetAddr, const CServerCoreInfo& ServerInfo ) { int iPos = 0; // init position pointer // convert server info strings to utf-8 const QByteArray strUTF8LInetAddr = LInetAddr.InetAddr.toString().toUtf8(); const QByteArray strUTF8Name = ServerInfo.strName.toUtf8(); const QByteArray strUTF8City = ServerInfo.strCity.toUtf8(); // size of current message body const int iEntrLen = 2 + // server internal port number 2 + // country 1 + // maximum number of connected clients 1 + // is permanent flag 2 + strUTF8Name.size() + // name utf-8 str. size / str. 2 + strUTF8LInetAddr.size() + // server internal address utf-8 str. size / str. 2 + strUTF8City.size(); // city utf-8 str. size / str. // build data vector CVector vecData ( iEntrLen ); // port number (2 bytes) PutValOnStream ( vecData, iPos, static_cast ( LInetAddr.iPort ), 2 ); // country (2 bytes) PutCountryOnStream ( vecData, iPos, ServerInfo.eCountry ); // maximum number of connected clients (1 byte) PutValOnStream ( vecData, iPos, static_cast ( ServerInfo.iMaxNumClients ), 1 ); // "is permanent" flag (1 byte) PutValOnStream ( vecData, iPos, static_cast ( ServerInfo.bPermanentOnline ), 1 ); // name PutStringUTF8OnStream ( vecData, iPos, strUTF8Name ); // server internal address (formerly unused topic) PutStringUTF8OnStream ( vecData, iPos, strUTF8LInetAddr ); // city PutStringUTF8OnStream ( vecData, iPos, strUTF8City ); CreateAndImmSendConLessMessage ( PROTMESSID_CLM_REGISTER_SERVER, vecData, InetAddr ); } bool CProtocol::EvaluateCLRegisterServerMes ( const CHostAddress& InetAddr, const CVector& vecData ) { int iPos = 0; // init position pointer const int iDataLen = vecData.Size(); QString sLocHost; // temp string for server internal address CHostAddress LInetAddr; CServerCoreInfo RecServerInfo; // check size (the first 6 bytes) if ( iDataLen < 6 ) { return true; // return error code } // port number (2 bytes) LInetAddr.iPort = static_cast ( GetValFromStream ( vecData, iPos, 2 ) ); // country (2 bytes) RecServerInfo.eCountry = GetCountryFromStream ( vecData, iPos ); // maximum number of connected clients (1 byte) RecServerInfo.iMaxNumClients = static_cast ( GetValFromStream ( vecData, iPos, 1 ) ); // "is permanent" flag (1 byte) RecServerInfo.bPermanentOnline = static_cast ( GetValFromStream ( vecData, iPos, 1 ) ); // server name if ( GetStringFromStream ( vecData, iPos, MAX_LEN_SERVER_NAME, RecServerInfo.strName ) ) { return true; // return error code } // server internal address if ( GetStringFromStream ( vecData, iPos, MAX_LEN_IP_ADDRESS, sLocHost ) ) { return true; // return error code } if ( sLocHost.isEmpty() ) { // old server, empty "topic", register as local host LInetAddr.InetAddr.setAddress ( QHostAddress::LocalHost ); } else if ( !LInetAddr.InetAddr.setAddress ( sLocHost ) ) { return true; // return error code } // server city if ( GetStringFromStream ( vecData, iPos, MAX_LEN_SERVER_CITY, RecServerInfo.strCity ) ) { return true; // return error code } // check size: all data is read, the position must now be at the end if ( iPos != iDataLen ) { return true; // return error code } // invoke message action emit CLRegisterServerReceived ( InetAddr, LInetAddr, RecServerInfo ); return false; // no error } void CProtocol::CreateCLRegisterServerExMes ( const CHostAddress& InetAddr, const CHostAddress& LInetAddr, const CServerCoreInfo& ServerInfo ) { int iPos = 0; // init position pointer // convert server info strings to utf-8 const QByteArray strUTF8LInetAddr = LInetAddr.InetAddr.toString().toUtf8(); const QByteArray strUTF8Name = ServerInfo.strName.toUtf8(); const QByteArray strUTF8City = ServerInfo.strCity.toUtf8(); const QByteArray strUTF8Version = QString ( VERSION ).toUtf8(); // size of current message body const int iEntrLen = 2 + // server internal port number 2 + // country 1 + // maximum number of connected clients 1 + // is permanent flag 2 + strUTF8Name.size() + // name utf-8 str. size / str. 2 + strUTF8LInetAddr.size() + // server internal address utf-8 str. size / str. 2 + strUTF8City.size() + // city utf-8 str. size / str. 1 + // operating system 2 + strUTF8Version.size(); // version utf-8 str. size / str. // build data vector CVector vecData ( iEntrLen ); // port number (2 bytes) PutValOnStream ( vecData, iPos, static_cast ( LInetAddr.iPort ), 2 ); // country (2 bytes) PutCountryOnStream ( vecData, iPos, ServerInfo.eCountry ); // maximum number of connected clients (1 byte) PutValOnStream ( vecData, iPos, static_cast ( ServerInfo.iMaxNumClients ), 1 ); // "is permanent" flag (1 byte) PutValOnStream ( vecData, iPos, static_cast ( ServerInfo.bPermanentOnline ), 1 ); // name PutStringUTF8OnStream ( vecData, iPos, strUTF8Name ); // server internal address (formerly unused topic) PutStringUTF8OnStream ( vecData, iPos, strUTF8LInetAddr ); // city PutStringUTF8OnStream ( vecData, iPos, strUTF8City ); // operating system (1 byte) PutValOnStream ( vecData, iPos, static_cast ( COSUtil::GetOperatingSystem() ), 1 ); // version PutStringUTF8OnStream ( vecData, iPos, strUTF8Version ); CreateAndImmSendConLessMessage ( PROTMESSID_CLM_REGISTER_SERVER_EX, vecData, InetAddr ); } bool CProtocol::EvaluateCLRegisterServerExMes ( const CHostAddress& InetAddr, const CVector& vecData ) { int iPos = 0; // init position pointer const int iDataLen = vecData.Size(); QString sLocHost; // temp string for server internal address CHostAddress LInetAddr; CServerCoreInfo RecServerInfo; // check size (the first 6 bytes) if ( iDataLen < 6 ) { return true; // return error code } // port number (2 bytes) LInetAddr.iPort = static_cast ( GetValFromStream ( vecData, iPos, 2 ) ); // country (2 bytes) RecServerInfo.eCountry = GetCountryFromStream ( vecData, iPos ); // maximum number of connected clients (1 byte) RecServerInfo.iMaxNumClients = static_cast ( GetValFromStream ( vecData, iPos, 1 ) ); // "is permanent" flag (1 byte) RecServerInfo.bPermanentOnline = static_cast ( GetValFromStream ( vecData, iPos, 1 ) ); // server name if ( GetStringFromStream ( vecData, iPos, MAX_LEN_SERVER_NAME, RecServerInfo.strName ) ) { return true; // return error code } // server internal address if ( GetStringFromStream ( vecData, iPos, MAX_LEN_IP_ADDRESS, sLocHost ) ) { return true; // return error code } if ( sLocHost.isEmpty() ) { // old server, empty "topic", register as local host LInetAddr.InetAddr.setAddress ( QHostAddress::LocalHost ); } else if ( !LInetAddr.InetAddr.setAddress ( sLocHost ) ) { return true; // return error code } // server city if ( GetStringFromStream ( vecData, iPos, MAX_LEN_SERVER_CITY, RecServerInfo.strCity ) ) { return true; // return error code } // check size (the next 1 byte) if ( iDataLen < iPos + 1 ) { return true; // return error code } // operating system (1 byte) const COSUtil::EOpSystemType eOSType = static_cast ( GetValFromStream ( vecData, iPos, 1 ) ); // version text QString strVersion; if ( GetStringFromStream ( vecData, iPos, MAX_LEN_VERSION_TEXT, strVersion ) ) { return true; // return error code } // check size: all data is read, the position must now be at the end if ( iPos != iDataLen ) { return true; // return error code } // invoke message action emit CLRegisterServerExReceived ( InetAddr, LInetAddr, RecServerInfo, eOSType, strVersion ); return false; // no error } void CProtocol::CreateCLUnregisterServerMes ( const CHostAddress& InetAddr ) { CreateAndImmSendConLessMessage ( PROTMESSID_CLM_UNREGISTER_SERVER, CVector ( 0 ), InetAddr ); } bool CProtocol::EvaluateCLUnregisterServerMes ( const CHostAddress& InetAddr ) { // invoke message action emit CLUnregisterServerReceived ( InetAddr ); return false; // no error } void CProtocol::CreateCLServerListMes ( const CHostAddress& InetAddr, const CVector vecServerInfo ) { const int iNumServers = vecServerInfo.Size(); // build data vector CVector vecData ( 0 ); int iPos = 0; // init position pointer for ( int i = 0; i < iNumServers; i++ ) { // convert server list strings to utf-8 const QByteArray strUTF8Name = vecServerInfo[i].strName.toUtf8(); const QByteArray strUTF8Empty = QString ( "" ).toUtf8(); const QByteArray strUTF8City = vecServerInfo[i].strCity.toUtf8(); // size of current list entry const int iCurListEntrLen = 4 + // IP address 2 + // port number 2 + // country 1 + // maximum number of connected clients 1 + // is permanent flag 2 + strUTF8Name.size() + // name utf-8 str. size / str. 2 + // empty string 2 + strUTF8City.size(); // city utf-8 str. size / str. // make space for new data vecData.Enlarge ( iCurListEntrLen ); // IP address (4 bytes) // note the Server List manager has put the internal details in HostAddr where required PutValOnStream ( vecData, iPos, static_cast ( vecServerInfo[i].HostAddr.InetAddr.toIPv4Address() ), 4 ); // port number (2 bytes) // note the Server List manager has put the internal details in HostAddr where required PutValOnStream ( vecData, iPos, static_cast ( vecServerInfo[i].HostAddr.iPort ), 2 ); // country (2 bytes) PutCountryOnStream ( vecData, iPos, vecServerInfo[i].eCountry ); // maximum number of connected clients (1 byte) PutValOnStream ( vecData, iPos, static_cast ( vecServerInfo[i].iMaxNumClients ), 1 ); // "is permanent" flag (1 byte) PutValOnStream ( vecData, iPos, static_cast ( vecServerInfo[i].bPermanentOnline ), 1 ); // name PutStringUTF8OnStream ( vecData, iPos, strUTF8Name ); // empty string PutStringUTF8OnStream ( vecData, iPos, strUTF8Empty ); // city PutStringUTF8OnStream ( vecData, iPos, strUTF8City ); } CreateAndImmSendConLessMessage ( PROTMESSID_CLM_SERVER_LIST, vecData, InetAddr ); } bool CProtocol::EvaluateCLServerListMes ( const CHostAddress& InetAddr, const CVector& vecData ) { int iPos = 0; // init position pointer const int iDataLen = vecData.Size(); CVector vecServerInfo ( 0 ); while ( iPos < iDataLen ) { // check size (the next 10 bytes) if ( ( iDataLen - iPos ) < 10 ) { return true; // return error code } // IP address (4 bytes) const quint32 iIpAddr = static_cast ( GetValFromStream ( vecData, iPos, 4 ) ); // port number (2 bytes) const quint16 iPort = static_cast ( GetValFromStream ( vecData, iPos, 2 ) ); // country (2 bytes) const QLocale::Country eCountry = GetCountryFromStream ( vecData, iPos ); // maximum number of connected clients (1 byte) const int iMaxNumClients = static_cast ( GetValFromStream ( vecData, iPos, 1 ) ); // "is permanent" flag (1 byte) const bool bPermanentOnline = static_cast ( GetValFromStream ( vecData, iPos, 1 ) ); // server name QString strName; if ( GetStringFromStream ( vecData, iPos, MAX_LEN_SERVER_NAME, strName ) ) { return true; // return error code } // empty QString strEmpty; if ( GetStringFromStream ( vecData, iPos, MAX_LEN_IP_ADDRESS, strEmpty ) ) { return true; // return error code } // server city QString strCity; if ( GetStringFromStream ( vecData, iPos, MAX_LEN_SERVER_CITY, strCity ) ) { return true; // return error code } // add server information to vector vecServerInfo.Add ( CServerInfo ( CHostAddress ( QHostAddress ( iIpAddr ), iPort ), CHostAddress ( QHostAddress ( iIpAddr ), iPort ), strName, eCountry, strCity, iMaxNumClients, bPermanentOnline ) ); } // check size: all data is read, the position must now be at the end if ( iPos != iDataLen ) { return true; // return error code } // invoke message action emit CLServerListReceived ( InetAddr, vecServerInfo ); return false; // no error } void CProtocol::CreateCLRedServerListMes ( const CHostAddress& InetAddr, const CVector vecServerInfo ) { const int iNumServers = vecServerInfo.Size(); // build data vector CVector vecData ( 0 ); int iPos = 0; // init position pointer for ( int i = 0; i < iNumServers; i++ ) { // convert server list strings to utf-8 const QByteArray strUTF8Name = vecServerInfo[i].strName.toUtf8(); // size of current list entry const int iCurListEntrLen = 4 + // IP address 2 + // port number 1 + strUTF8Name.size(); // name utf-8 str. size / str. // make space for new data vecData.Enlarge ( iCurListEntrLen ); // IP address (4 bytes) // note the Server List manager has put the internal details in HostAddr where required PutValOnStream ( vecData, iPos, static_cast ( vecServerInfo[i].HostAddr.InetAddr.toIPv4Address() ), 4 ); // port number (2 bytes) // note the Server List manager has put the internal details in HostAddr where required PutValOnStream ( vecData, iPos, static_cast ( vecServerInfo[i].HostAddr.iPort ), 2 ); // name (note that the string length indicator is 1 in this special case) PutStringUTF8OnStream ( vecData, iPos, strUTF8Name, 1 ); } CreateAndImmSendConLessMessage ( PROTMESSID_CLM_RED_SERVER_LIST, vecData, InetAddr ); } bool CProtocol::EvaluateCLRedServerListMes ( const CHostAddress& InetAddr, const CVector& vecData ) { int iPos = 0; // init position pointer const int iDataLen = vecData.Size(); CVector vecServerInfo ( 0 ); while ( iPos < iDataLen ) { // check size (the next 6 bytes) if ( ( iDataLen - iPos ) < 6 ) { return true; // return error code } // IP address (4 bytes) const quint32 iIpAddr = static_cast ( GetValFromStream ( vecData, iPos, 4 ) ); // port number (2 bytes) const quint16 iPort = static_cast ( GetValFromStream ( vecData, iPos, 2 ) ); // server name (note that the string length indicator is 1 in this special case) QString strName; if ( GetStringFromStream ( vecData, iPos, MAX_LEN_SERVER_NAME, strName, 1 ) ) { return true; // return error code } // add server information to vector vecServerInfo.Add ( CServerInfo ( CHostAddress ( QHostAddress ( iIpAddr ), iPort ), CHostAddress ( QHostAddress ( iIpAddr ), iPort ), strName, QLocale::AnyCountry, // set to any country since the information is not transmitted "", // empty city name since the information is not transmitted 0, // per definition: if max. num. client is zero, we ignore the value in the server list false ) ); // assume not permanent since the information is not transmitted } // check size: all data is read, the position must now be at the end if ( iPos != iDataLen ) { return true; // return error code } // invoke message action emit CLRedServerListReceived ( InetAddr, vecServerInfo ); return false; // no error } void CProtocol::CreateCLReqServerListMes ( const CHostAddress& InetAddr ) { CreateAndImmSendConLessMessage ( PROTMESSID_CLM_REQ_SERVER_LIST, CVector ( 0 ), InetAddr ); } bool CProtocol::EvaluateCLReqServerListMes ( const CHostAddress& InetAddr ) { // invoke message action emit CLReqServerList ( InetAddr ); return false; // no error } void CProtocol::CreateCLSendEmptyMesMes ( const CHostAddress& InetAddr, const CHostAddress& TargetInetAddr ) { int iPos = 0; // init position pointer // build data vector (6 bytes long) CVector vecData ( 6 ); // IP address (4 bytes) PutValOnStream ( vecData, iPos, static_cast ( TargetInetAddr.InetAddr.toIPv4Address() ), 4 ); // port number (2 bytes) PutValOnStream ( vecData, iPos, static_cast ( TargetInetAddr.iPort ), 2 ); CreateAndImmSendConLessMessage ( PROTMESSID_CLM_SEND_EMPTY_MESSAGE, vecData, InetAddr ); } bool CProtocol::EvaluateCLSendEmptyMesMes ( const CVector& vecData ) { int iPos = 0; // init position pointer // check size if ( vecData.Size() != 6 ) { return true; // return error code } // IP address (4 bytes) const quint32 iIpAddr = static_cast ( GetValFromStream ( vecData, iPos, 4 ) ); // port number (2 bytes) const quint16 iPort = static_cast ( GetValFromStream ( vecData, iPos, 2 ) ); // invoke message action emit CLSendEmptyMes ( CHostAddress ( QHostAddress ( iIpAddr ), iPort ) ); return false; // no error } void CProtocol::CreateCLEmptyMes ( const CHostAddress& InetAddr ) { // special message: for this message there exist no Evaluate // function CreateAndImmSendConLessMessage ( PROTMESSID_CLM_EMPTY_MESSAGE, CVector ( 0 ), InetAddr ); } void CProtocol::CreateCLDisconnection ( const CHostAddress& InetAddr ) { CreateAndImmSendConLessMessage ( PROTMESSID_CLM_DISCONNECTION, CVector ( 0 ), InetAddr ); } bool CProtocol::EvaluateCLDisconnectionMes ( const CHostAddress& InetAddr ) { // invoke message action emit CLDisconnection ( InetAddr ); return false; // no error } void CProtocol::CreateCLVersionAndOSMes ( const CHostAddress& InetAddr ) { int iPos = 0; // init position pointer // get the version number string const QString strVerion = VERSION; // convert version string to utf-8 const QByteArray strUTF8Version = strVerion.toUtf8(); // size of current message body const int iEntrLen = 1 + // operating system 2 + strUTF8Version.size(); // version utf-8 str. size / str. // build data vector CVector vecData ( iEntrLen ); // operating system (1 byte) PutValOnStream ( vecData, iPos, static_cast ( COSUtil::GetOperatingSystem() ), 1 ); // version PutStringUTF8OnStream ( vecData, iPos, strUTF8Version ); CreateAndImmSendConLessMessage ( PROTMESSID_CLM_VERSION_AND_OS, vecData, InetAddr ); } bool CProtocol::EvaluateCLVersionAndOSMes ( const CHostAddress& InetAddr, const CVector& vecData ) { int iPos = 0; // init position pointer const int iDataLen = vecData.Size(); // check size (the first 1 byte) if ( iDataLen < 1 ) { return true; // return error code } // operating system (1 byte) const COSUtil::EOpSystemType eOSType = static_cast ( GetValFromStream ( vecData, iPos, 1 ) ); // version text QString strVersion; if ( GetStringFromStream ( vecData, iPos, MAX_LEN_VERSION_TEXT, strVersion ) ) { return true; // return error code } // check size: all data is read, the position must now be at the end if ( iPos != iDataLen ) { return true; // return error code } // invoke message action emit CLVersionAndOSReceived ( InetAddr, eOSType, strVersion ); return false; // no error } void CProtocol::CreateCLReqVersionAndOSMes ( const CHostAddress& InetAddr ) { CreateAndImmSendConLessMessage ( PROTMESSID_CLM_REQ_VERSION_AND_OS, CVector ( 0 ), InetAddr ); } bool CProtocol::EvaluateCLReqVersionAndOSMes ( const CHostAddress& InetAddr ) { // invoke message action emit CLReqVersionAndOS ( InetAddr ); return false; // no error } void CProtocol::CreateCLConnClientsListMes ( const CHostAddress& InetAddr, const CVector& vecChanInfo ) { const int iNumClients = vecChanInfo.Size(); // build data vector CVector vecData ( 0 ); int iPos = 0; // init position pointer for ( int i = 0; i < iNumClients; i++ ) { // convert strings to utf-8 const QByteArray strUTF8Name = vecChanInfo[i].strName.toUtf8(); const QByteArray strUTF8City = vecChanInfo[i].strCity.toUtf8(); // size of current list entry const int iCurListEntrLen = 1 + // chan ID 2 + // country 4 + // instrument 1 + // skill level 4 + // IP address 2 + strUTF8Name.size() + // utf-8 str. size / str. 2 + strUTF8City.size(); // utf-8 str. size / str. // make space for new data vecData.Enlarge ( iCurListEntrLen ); // channel ID (1 byte) PutValOnStream ( vecData, iPos, static_cast ( vecChanInfo[i].iChanID ), 1 ); // country (2 bytes) PutCountryOnStream ( vecData, iPos, vecChanInfo[i].eCountry ); // instrument (4 bytes) PutValOnStream ( vecData, iPos, static_cast ( vecChanInfo[i].iInstrument ), 4 ); // skill level (1 byte) PutValOnStream ( vecData, iPos, static_cast ( vecChanInfo[i].eSkillLevel ), 1 ); // used to be IP address before #316 (4 bytes) PutValOnStream ( vecData, iPos, 0, 4 ); // name PutStringUTF8OnStream ( vecData, iPos, strUTF8Name ); // city PutStringUTF8OnStream ( vecData, iPos, strUTF8City ); } CreateAndImmSendConLessMessage ( PROTMESSID_CLM_CONN_CLIENTS_LIST, vecData, InetAddr ); } bool CProtocol::EvaluateCLConnClientsListMes ( const CHostAddress& InetAddr, const CVector& vecData ) { int iPos = 0; // init position pointer const int iDataLen = vecData.Size(); CVector vecChanInfo ( 0 ); while ( iPos < iDataLen ) { // check size (the next 12 bytes) if ( ( iDataLen - iPos ) < 12 ) { return true; // return error code } // channel ID (1 byte) const int iChanID = static_cast ( GetValFromStream ( vecData, iPos, 1 ) ); // country (2 bytes) const QLocale::Country eCountry = GetCountryFromStream ( vecData, iPos ); // instrument (4 bytes) const int iInstrument = static_cast ( GetValFromStream ( vecData, iPos, 4 ) ); // skill level (1 byte) const ESkillLevel eSkillLevel = static_cast ( GetValFromStream ( vecData, iPos, 1 ) ); // used to be IP address, zero since #316 (4 bytes) iPos += 4; // name QString strCurName; if ( GetStringFromStream ( vecData, iPos, MAX_LEN_FADER_TAG, strCurName ) ) { return true; // return error code } // city QString strCurCity; if ( GetStringFromStream ( vecData, iPos, MAX_LEN_SERVER_CITY, strCurCity ) ) { return true; // return error code } // add channel information to vector vecChanInfo.Add ( CChannelInfo ( iChanID, strCurName, eCountry, strCurCity, iInstrument, eSkillLevel ) ); } // check size: all data is read, the position must now be at the end if ( iPos != iDataLen ) { return true; // return error code } // invoke message action emit CLConnClientsListMesReceived ( InetAddr, vecChanInfo ); return false; // no error } void CProtocol::CreateCLReqConnClientsListMes ( const CHostAddress& InetAddr ) { CreateAndImmSendConLessMessage ( PROTMESSID_CLM_REQ_CONN_CLIENTS_LIST, CVector ( 0 ), InetAddr ); } bool CProtocol::EvaluateCLReqConnClientsListMes ( const CHostAddress& InetAddr ) { // invoke message action emit CLReqConnClientsList ( InetAddr ); return false; // no error } void CProtocol::CreateCLChannelLevelListMes ( const CHostAddress& InetAddr, const CVector& vecLevelList, const int iNumClients ) { // This must be a multiple of bytes at four bits per client const int iNumBytes = ( iNumClients + 1 ) / 2; CVector vecData ( iNumBytes ); int iPos = 0; // init position pointer for ( int i = 0, j = 0; i < iNumClients; i += 2 /* pack two per byte */, j++ ) { uint16_t levelLo = vecLevelList[i] & 0x0F; uint16_t levelHi = ( i + 1 < iNumClients ) ? vecLevelList[i + 1] & 0x0F : 0x0F; uint8_t byte = static_cast ( levelLo | ( levelHi << 4 ) ); PutValOnStream ( vecData, iPos, static_cast ( byte ), 1 ); } CreateAndImmSendConLessMessage ( PROTMESSID_CLM_CHANNEL_LEVEL_LIST, vecData, InetAddr ); } bool CProtocol::EvaluateCLChannelLevelListMes ( const CHostAddress& InetAddr, const CVector& vecData ) { int iPos = 0; // init position pointer const int iDataLen = vecData.Size(); // four bits per channel, 2 channels per byte // may have one too many entries, last being 0xF int iVecLen = iDataLen * 2; // one ushort per channel if ( iVecLen > MAX_NUM_CHANNELS ) { return true; // return error code } CVector vecLevelList ( iVecLen ); for ( int i = 0, j = 0; i < iDataLen; i++, j += 2 ) { uint8_t byte = static_cast ( GetValFromStream ( vecData, iPos, 1 ) ); uint16_t levelLo = byte & 0x0F; uint16_t levelHi = ( byte >> 4 ) & 0x0F; vecLevelList[j] = levelLo; if ( levelHi != 0x0F ) { vecLevelList[j + 1] = levelHi; } else { vecLevelList.resize ( iVecLen - 1 ); break; } } // invoke message action emit CLChannelLevelListReceived ( InetAddr, vecLevelList ); return false; // no error } void CProtocol::CreateCLRegisterServerResp ( const CHostAddress& InetAddr, const ESvrRegResult eResult ) { int iPos = 0; // init position pointer CVector vecData ( 1 ); PutValOnStream ( vecData, iPos, static_cast ( eResult ), 1 ); CreateAndImmSendConLessMessage ( PROTMESSID_CLM_REGISTER_SERVER_RESP, vecData, InetAddr ); } bool CProtocol::EvaluateCLRegisterServerResp ( const CHostAddress& InetAddr, const CVector& vecData ) { int iPos = 0; // init position pointer const int iDataLen = vecData.Size(); if ( iDataLen != 1 ) { return true; } // server registration result (1 byte) const int iSvrRegResult = static_cast ( GetValFromStream ( vecData, iPos, 1 ) ); if ( ( iSvrRegResult != SRR_REGISTERED ) && ( iSvrRegResult != SRR_SERVER_LIST_FULL ) && ( iSvrRegResult != SRR_VERSION_TOO_OLD ) && ( iSvrRegResult != SRR_NOT_FULFILL_REQIREMENTS ) ) { return true; } // invoke message action emit CLRegisterServerResp ( InetAddr, static_cast ( iSvrRegResult ) ); return false; // no error } /******************************************************************************\ * Message generation and parsing * \******************************************************************************/ bool CProtocol::ParseMessageFrame ( const CVector& vecbyData, const int iNumBytesIn, CVector& vecbyMesBodyData, int& iCnt, int& iID ) { int i; int iCurPos; // vector must be at least "MESS_LEN_WITHOUT_DATA_BYTE" bytes long if ( iNumBytesIn < MESS_LEN_WITHOUT_DATA_BYTE ) { return true; // return error code } // Decode header ----------------------------------------------------------- iCurPos = 0; // start from beginning // 2 bytes TAG const int iTag = static_cast ( GetValFromStream ( vecbyData, iCurPos, 2 ) ); // check if tag is correct if ( iTag != 0 ) { return true; // return error code } // 2 bytes ID iID = static_cast ( GetValFromStream ( vecbyData, iCurPos, 2 ) ); // 1 byte cnt iCnt = static_cast ( GetValFromStream ( vecbyData, iCurPos, 1 ) ); // 2 bytes length const int iLenBy = static_cast ( GetValFromStream ( vecbyData, iCurPos, 2 ) ); // make sure the length is correct if ( iLenBy != iNumBytesIn - MESS_LEN_WITHOUT_DATA_BYTE ) { return true; // return error code } // Now check CRC ----------------------------------------------------------- CCRC CRCObj; const int iLenCRCCalc = MESS_HEADER_LENGTH_BYTE + iLenBy; iCurPos = 0; // start from the beginning for ( i = 0; i < iLenCRCCalc; i++ ) { CRCObj.AddByte ( static_cast ( GetValFromStream ( vecbyData, iCurPos, 1 ) ) ); } if ( CRCObj.GetCRC() != GetValFromStream ( vecbyData, iCurPos, 2 ) ) { return true; // return error code } // Extract actual data ----------------------------------------------------- //### TODO: BEGIN ###// // this memory allocation is done in the real time thread but should be // done in the low priority protocol management thread vecbyMesBodyData.Init ( iLenBy ); //### TODO: END ###// iCurPos = MESS_HEADER_LENGTH_BYTE; // start from beginning of data for ( i = 0; i < iLenBy; i++ ) { vecbyMesBodyData[i] = static_cast ( GetValFromStream ( vecbyData, iCurPos, 1 ) ); } return false; // no error } bool CProtocol::ParseSplitMessageContainer ( const CVector& vecbyData, CVector& vecbyMesBodyData, const int iSplitMessageDataIndex, int& iID, int& iNumParts, int& iSplitCnt, int& iCurPartSize ) { int iPos = 0; // init position pointer const int iDataLen = vecbyData.Size(); // check size (the first 4 bytes) if ( iDataLen < 4 ) { return true; // return error code } // 2 bytes ID iID = static_cast ( GetValFromStream ( vecbyData, iPos, 2 ) ); // 1 byte number of parts iNumParts = static_cast ( GetValFromStream ( vecbyData, iPos, 1 ) ); // 1 byte split cnt iSplitCnt = static_cast ( GetValFromStream ( vecbyData, iPos, 1 ) ); // Extract actual data ----------------------------------------------------- iCurPartSize = iDataLen - 4; // the memory must be allocated outside this function -> check the size if ( vecbyMesBodyData.Size() < iSplitMessageDataIndex + iCurPartSize ) { return true; // return error code } for ( int i = 0; i < iCurPartSize; i++ ) { vecbyMesBodyData[iSplitMessageDataIndex + i] = static_cast ( GetValFromStream ( vecbyData, iPos, 1 ) ); } return false; // no error } uint32_t CProtocol::GetValFromStream ( const CVector& vecIn, int& iPos, const int iNumOfBytes ) { /* note: iPos is automatically incremented in this function */ // 4 bytes maximum since we return uint32 Q_ASSERT ( ( iNumOfBytes > 0 ) && ( iNumOfBytes <= 4 ) ); Q_ASSERT ( vecIn.Size() >= iPos + iNumOfBytes ); uint32_t iRet = 0; for ( int i = 0; i < iNumOfBytes; i++ ) { iRet |= vecIn[iPos] << ( i * 8 /* size of byte */ ); iPos++; } return iRet; } bool CProtocol::GetStringFromStream ( const CVector& vecIn, int& iPos, const int iMaxStringLen, QString& strOut, const int iNumberOfBytsLen ) { /* note: iPos is automatically incremented in this function */ const int iInLen = vecIn.Size(); // check if at least iNumberOfBytsLen bytes are available if ( ( iInLen - iPos ) < iNumberOfBytsLen ) { return true; // return error code } // number of bytes for utf-8 string (1 or 2 bytes) const int iStrUTF8Len = static_cast ( GetValFromStream ( vecIn, iPos, iNumberOfBytsLen ) ); // (note that iPos was incremented by 2 in the above code!) if ( ( iInLen - iPos ) < iStrUTF8Len ) { return true; // return error code } // string (n bytes) QByteArray sStringUTF8; for ( int i = 0; i < iStrUTF8Len; i++ ) { // byte-by-byte copying of the string data sStringUTF8.append ( static_cast ( GetValFromStream ( vecIn, iPos, 1 ) ) ); } // convert utf-8 byte array in the return string strOut = QString::fromUtf8 ( sStringUTF8 ); // check length of actual string if ( strOut.size() > iMaxStringLen ) { return true; // return error code } return false; // no error } QLocale::Country CProtocol::GetCountryFromStream ( const CVector& vecIn, int& iPos ) { unsigned short iCountryCode = GetValFromStream ( vecIn, iPos, 2 ); return CLocale::WireFormatCountryCodeToQtCountry ( iCountryCode ); } void CProtocol::GenMessageFrame ( CVector& vecOut, const int iCnt, const int iID, const CVector& vecData ) { int i; // query length of data vector const int iDataLenByte = vecData.Size(); // total length of message const int iTotLenByte = MESS_LEN_WITHOUT_DATA_BYTE + iDataLenByte; // init message vector vecOut.Init ( iTotLenByte ); // Encode header ----------------------------------------------------------- int iCurPos = 0; // init position pointer // 2 bytes TAG (all zero bits) PutValOnStream ( vecOut, iCurPos, static_cast ( 0 ), 2 ); // 2 bytes ID PutValOnStream ( vecOut, iCurPos, static_cast ( iID ), 2 ); // 1 byte cnt PutValOnStream ( vecOut, iCurPos, static_cast ( iCnt ), 1 ); // 2 bytes length PutValOnStream ( vecOut, iCurPos, static_cast ( iDataLenByte ), 2 ); // encode data ----- for ( i = 0; i < iDataLenByte; i++ ) { PutValOnStream ( vecOut, iCurPos, static_cast ( vecData[i] ), 1 ); } // Encode CRC -------------------------------------------------------------- CCRC CRCObj; iCurPos = 0; // start from beginning const int iLenCRCCalc = MESS_HEADER_LENGTH_BYTE + iDataLenByte; for ( i = 0; i < iLenCRCCalc; i++ ) { CRCObj.AddByte ( static_cast ( GetValFromStream ( vecOut, iCurPos, 1 ) ) ); } PutValOnStream ( vecOut, iCurPos, static_cast ( CRCObj.GetCRC() ), 2 ); } void CProtocol::GenSplitMessageContainer ( CVector& vecOut, const int iID, const int iNumParts, const int iSplitCnt, const CVector& vecData, const int iStartIndexInData, const int iLengthOfDataPart ) { int iPos = 0; // init position pointer // total length of message const int iTotLenByte = 4 + iLengthOfDataPart; // init message vector vecOut.Init ( iTotLenByte ); // 2 bytes ID PutValOnStream ( vecOut, iPos, static_cast ( iID ), 2 ); // 1 byte number of parts PutValOnStream ( vecOut, iPos, static_cast ( iNumParts ), 1 ); // 1 byte split cnt PutValOnStream ( vecOut, iPos, static_cast ( iSplitCnt ), 1 ); // data for ( int i = 0; i < iLengthOfDataPart; i++ ) { PutValOnStream ( vecOut, iPos, static_cast ( vecData[iStartIndexInData + i] ), 1 ); } } void CProtocol::PutValOnStream ( CVector& vecIn, int& iPos, const uint32_t iVal, const int iNumOfBytes ) { /* note: iPos is automatically incremented in this function */ // 4 bytes maximum since we use uint32 Q_ASSERT ( ( iNumOfBytes > 0 ) && ( iNumOfBytes <= 4 ) ); Q_ASSERT ( vecIn.Size() >= iPos + iNumOfBytes ); for ( int i = 0; i < iNumOfBytes; i++ ) { vecIn[iPos] = ( iVal >> ( i * 8 /* size of byte */ ) ) & 255 /* 11111111 */; iPos++; } } void CProtocol::PutStringUTF8OnStream ( CVector& vecIn, int& iPos, const QByteArray& sStringUTF8, const int iNumberOfBytsLen ) { // get the utf-8 string size const int iStrUTF8Len = sStringUTF8.size(); // number of bytes for utf-8 string (iNumberOfBytsLen bytes) PutValOnStream ( vecIn, iPos, static_cast ( iStrUTF8Len ), iNumberOfBytsLen ); // actual utf-8 string (n bytes) for ( int j = 0; j < iStrUTF8Len; j++ ) { // byte-by-byte copying of the utf-8 string data PutValOnStream ( vecIn, iPos, static_cast ( sStringUTF8[j] ), 1 ); } } void CProtocol::PutCountryOnStream ( CVector& vecIn, int& iPos, QLocale::Country eCountry ) { unsigned short iCountryCode = CLocale::QtCountryToWireFormatCountryCode ( eCountry ); PutValOnStream ( vecIn, iPos, iCountryCode, 2 ); } jamulus-3.9.1+dfsg/src/buffer.cpp0000644000175000017500000006073614340334543015734 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * * Note: We are assuming here that put and get operations are secured by a mutex * and accessing does not occur at the same time. * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include "buffer.h" /* Network buffer implementation **********************************************/ void CNetBuf::Init ( const int iNewBlockSize, const int iNewNumBlocks, const bool bNUseSequenceNumber, const bool bPreserve ) { // store the sequence number activation flag bUseSequenceNumber = bNUseSequenceNumber; // in simulation mode the size is not changed during operation -> we do // not have to implement special code for this case // only enter the "preserve" branch, if object was already initialized // and the block sizes are the same if ( bPreserve && ( !bIsSimulation ) && bIsInitialized && ( iBlockSize == iNewBlockSize ) ) { // extract all data from buffer in temporary storage CVector> vecvecTempMemory = vecvecMemory; // allocate worst case memory by copying if ( !bNUseSequenceNumber ) { int iPreviousDataCnt = 0; while ( Get ( vecvecTempMemory[iPreviousDataCnt], iBlockSize ) ) { iPreviousDataCnt++; } // now resize the buffer to the new size (buffer is empty after this operation) Resize ( iNewNumBlocks, iNewBlockSize ); // copy the previous data back in the buffer (make sure we only copy as much // data back as the new buffer size can hold) int iDataCnt = 0; while ( ( iDataCnt < iPreviousDataCnt ) && Put ( vecvecTempMemory[iDataCnt], iBlockSize ) ) { iDataCnt++; } } else { // store current complete buffer state in temporary memory CVector veciTempBlockValid ( iNumBlocksMemory ); const uint8_t iOldSequenceNumberAtGetPos = iSequenceNumberAtGetPos; const int iOldNumBlocksMemory = iNumBlocksMemory; const int iOldBlockGetPos = iBlockGetPos; int iCurBlockPos = 0; while ( iBlockGetPos < iNumBlocksMemory ) { veciTempBlockValid[iCurBlockPos] = veciBlockValid[iBlockGetPos]; vecvecTempMemory[iCurBlockPos++] = vecvecMemory[iBlockGetPos++]; } for ( iBlockGetPos = 0; iBlockGetPos < iOldBlockGetPos; iBlockGetPos++ ) { veciTempBlockValid[iCurBlockPos] = veciBlockValid[iBlockGetPos]; vecvecTempMemory[iCurBlockPos++] = vecvecMemory[iBlockGetPos]; } // now resize the buffer to the new size Resize ( iNewNumBlocks, iNewBlockSize ); // write back the temporary data in new memory iSequenceNumberAtGetPos = iOldSequenceNumberAtGetPos; iBlockGetPos = 0; // per definition for ( int iCurPos = 0; iCurPos < std::min ( iNewNumBlocks, iOldNumBlocksMemory ); iCurPos++ ) { veciBlockValid[iCurPos] = veciTempBlockValid[iCurPos]; vecvecMemory[iCurPos] = vecvecTempMemory[iCurPos]; } } } else { Resize ( iNewNumBlocks, iNewBlockSize ); } // set initialized flag bIsInitialized = true; } void CNetBuf::Resize ( const int iNewNumBlocks, const int iNewBlockSize ) { // allocate memory for actual data buffer vecvecMemory.Init ( iNewNumBlocks ); veciBlockValid.Init ( iNewNumBlocks, 0 ); // initialize with zeros = invalid if ( !bIsSimulation ) { for ( int iBlock = 0; iBlock < iNewNumBlocks; iBlock++ ) { vecvecMemory[iBlock].Init ( iNewBlockSize ); } } // init buffer pointers and buffer state (empty buffer) and store buffer properties iBlockGetPos = 0; iBlockPutPos = 0; eBufState = BS_EMPTY; iBlockSize = iNewBlockSize; iNumBlocksMemory = iNewNumBlocks; } bool CNetBuf::Put ( const CVector& vecbyData, int iInSize ) { // if the sequence number is used, we need a complete different way of applying // the new network packet if ( bUseSequenceNumber ) { // check that the input size is a multiple of the block size if ( ( iInSize % ( iBlockSize + iNumBytesSeqNum ) ) != 0 ) { return false; } // to get the number of input blocks we assume that the number of bytes for // the sequence number is much smaller than the number of coded audio bytes const int iNumBlocks = /* floor */ ( iInSize / iBlockSize ); // copy new data in internal buffer for ( int iBlock = 0; iBlock < iNumBlocks; iBlock++ ) { // calculate the block offset once per loop instead of repeated multiplying const int iBlockOffset = iBlock * ( iBlockSize + iNumBytesSeqNum ); // extract sequence number of current received block (per definition // the sequence number is appended after the coded audio data) const int iCurrentSequenceNumber = vecbyData[iBlockOffset + iBlockSize]; // calculate the sequence number difference and take care of wrap int iSeqNumDiff = iCurrentSequenceNumber - static_cast ( iSequenceNumberAtGetPos ); if ( iSeqNumDiff < -128 ) { iSeqNumDiff += 256; } else if ( iSeqNumDiff >= 128 ) { iSeqNumDiff -= 256; } // The 1-byte sequence number wraps around at a count of 256. So, if a packet is delayed // further than this we cannot detect it. But it does not matter since such a packet is // more than 100 ms delayed so we have a bad network situation anyway. Therefore we // assume that the sequence number difference between the received and local counter is // correct. The idea of the following code is that we always move our "buffer window" so // that the received packet fits into the buffer. By doing this we are robust against // sample rate offsets between client/server or buffer glitches in the audio driver since // we adjust the window. The downside is that we never throw away single packets which arrive // too late so we throw away valid packets when we move the "buffer window" to the delayed // packet and then back to the correct place when the next normal packet is received. But // tests showed that the new buffer strategy does not perform worse than the old jitter // buffer which did not use any sequence number at all. if ( iSeqNumDiff < 0 ) { // the received packet comes too late so we shift the "buffer window" to the past // until the received packet is the very first packet in the buffer for ( int i = iSeqNumDiff; i < 0; i++ ) { // insert an invalid block at the shifted position veciBlockValid[iBlockGetPos] = 0; // invalidate // we decrease the local sequence number and get position and take care of wrap iSequenceNumberAtGetPos--; iBlockGetPos--; if ( iBlockGetPos < 0 ) { iBlockGetPos += iNumBlocksMemory; } } // insert the new packet at the beginning of the buffer since it was delayed iBlockPutPos = iBlockGetPos; } else if ( iSeqNumDiff >= iNumBlocksMemory ) { // the received packet comes too early so we move the "buffer window" in the // future until the received packet is the last packet in the buffer for ( int i = 0; i < iSeqNumDiff - iNumBlocksMemory + 1; i++ ) { // insert an invalid block at the shifted position veciBlockValid[iBlockGetPos] = 0; // invalidate // we increase the local sequence number and get position and take care of wrap iSequenceNumberAtGetPos++; iBlockGetPos++; if ( iBlockGetPos >= iNumBlocksMemory ) { iBlockGetPos -= iNumBlocksMemory; } } // insert the new packet at the end of the buffer since it is too early (since // we add an offset to the get position, we have to take care of wrapping) iBlockPutPos = iBlockGetPos + iNumBlocksMemory - 1; if ( iBlockPutPos >= iNumBlocksMemory ) { iBlockPutPos -= iNumBlocksMemory; } } else { // this is the regular case: the received packet fits into the buffer so // we will write it at the correct position based on the sequence number iBlockPutPos = iBlockGetPos + iSeqNumDiff; if ( iBlockPutPos >= iNumBlocksMemory ) { iBlockPutPos -= iNumBlocksMemory; } } // for simulation buffer only update pointer, no data copying if ( !bIsSimulation ) { // copy one block of data in buffer std::copy ( vecbyData.begin() + iBlockOffset, vecbyData.begin() + iBlockOffset + iBlockSize, vecvecMemory[iBlockPutPos].begin() ); } // valid packet added, set flag veciBlockValid[iBlockPutPos] = 1; } } else { // check if there is not enough space available and that the input size is a // multiple of the block size if ( ( GetAvailSpace() < iInSize ) || ( ( iInSize % iBlockSize ) != 0 ) ) { return false; } // copy new data in internal buffer const int iNumBlocks = iInSize / iBlockSize; for ( int iBlock = 0; iBlock < iNumBlocks; iBlock++ ) { // for simultion buffer only update pointer, no data copying if ( !bIsSimulation ) { // calculate the block offset once per loop instead of repeated multiplying const int iBlockOffset = iBlock * iBlockSize; // copy one block of data in buffer std::copy ( vecbyData.begin() + iBlockOffset, vecbyData.begin() + iBlockOffset + iBlockSize, vecvecMemory[iBlockPutPos].begin() ); } // set the put position one block further iBlockPutPos++; // take care about wrap around of put pointer if ( iBlockPutPos == iNumBlocksMemory ) { iBlockPutPos = 0; } } // set buffer state flag if ( iBlockPutPos == iBlockGetPos ) { eBufState = BS_FULL; } else { eBufState = BS_OK; } } return true; } bool CNetBuf::Get ( CVector& vecbyData, const int iOutSize ) { bool bReturn = true; // check requested output size and available buffer data if ( ( iOutSize == 0 ) || ( iOutSize != iBlockSize ) || ( GetAvailData() < iOutSize ) ) { return false; } // if using sequence numbers, we do not use the block put position // at all but only determine the state from the "valid block" indicator if ( bUseSequenceNumber ) { bReturn = ( veciBlockValid[iBlockGetPos] > 0 ); // invalidate the block we are now taking from the buffer veciBlockValid[iBlockGetPos] = 0; // zero means invalid } // for simultion buffer or invalid block only update pointer, no data copying if ( !bIsSimulation && bReturn ) { // copy data from internal buffer in output buffer std::copy ( vecvecMemory[iBlockGetPos].begin(), vecvecMemory[iBlockGetPos].begin() + iBlockSize, vecbyData.begin() ); } // set the get position and sequence number one block further iBlockGetPos++; iSequenceNumberAtGetPos++; // wraps around automatically // take care about wrap around of get pointer if ( iBlockGetPos == iNumBlocksMemory ) { iBlockGetPos = 0; } // set buffer state flag if ( iBlockPutPos == iBlockGetPos ) { eBufState = BS_EMPTY; } else { eBufState = BS_OK; } return bReturn; } int CNetBuf::GetAvailSpace() const { // calculate available space in buffer int iAvBlocks = iBlockGetPos - iBlockPutPos; // check for special case and wrap around if ( iAvBlocks < 0 ) { iAvBlocks += iNumBlocksMemory; // wrap around } else { if ( ( iAvBlocks == 0 ) && ( eBufState == BS_EMPTY ) ) { iAvBlocks = iNumBlocksMemory; } } return iAvBlocks * iBlockSize; } int CNetBuf::GetAvailData() const { // in case of using sequence numbers, we always return data from the // buffer per definition int iAvBlocks = iNumBlocksMemory; if ( !bUseSequenceNumber ) { // calculate available data in buffer iAvBlocks = iBlockPutPos - iBlockGetPos; // check for special case and wrap around if ( iAvBlocks < 0 ) { iAvBlocks += iNumBlocksMemory; // wrap around } else { if ( ( iAvBlocks == 0 ) && ( eBufState == BS_FULL ) ) { iAvBlocks = iNumBlocksMemory; } } } return iAvBlocks * iBlockSize; } /* Network buffer with statistic calculations implementation ******************/ CNetBufWithStats::CNetBufWithStats() : CNetBuf ( false ), // base class init: no simulation mode iMaxStatisticCount ( MAX_STATISTIC_COUNT ), bUseDoubleSystemFrameSize ( false ), dAutoFilt_WightUpNormal ( IIR_WEIGTH_UP_NORMAL ), dAutoFilt_WightDownNormal ( IIR_WEIGTH_DOWN_NORMAL ), dAutoFilt_WightUpFast ( IIR_WEIGTH_UP_FAST ), dAutoFilt_WightDownFast ( IIR_WEIGTH_DOWN_FAST ), dErrorRateBound ( ERROR_RATE_BOUND ), dUpMaxErrorBound ( UP_MAX_ERROR_BOUND ) { // Define the sizes of the simulation buffers, // must be NUM_STAT_SIMULATION_BUFFERS elements! // Avoid the buffer length 1 because we do not have a solution for a // sample rate offset correction. Caused by the jitter we usually get bad // performance with just one buffer. viBufSizesForSim[0] = 2; viBufSizesForSim[1] = 3; viBufSizesForSim[2] = 4; viBufSizesForSim[3] = 5; viBufSizesForSim[4] = 6; viBufSizesForSim[5] = 7; viBufSizesForSim[6] = 8; viBufSizesForSim[7] = 9; viBufSizesForSim[8] = 10; viBufSizesForSim[9] = 11; // set all simulation buffers in simulation mode for ( int i = 0; i < NUM_STAT_SIMULATION_BUFFERS; i++ ) { SimulationBuffer[i].SetIsSimulation ( true ); } } void CNetBufWithStats::GetErrorRates ( CVector& vecErrRates, double& dLimit, double& dMaxUpLimit ) { // get all the averages of the error statistic vecErrRates.Init ( NUM_STAT_SIMULATION_BUFFERS ); for ( int i = 0; i < NUM_STAT_SIMULATION_BUFFERS; i++ ) { vecErrRates[i] = ErrorRateStatistic[i].GetAverage(); } // get the limits for the decisions dLimit = dErrorRateBound; dMaxUpLimit = dUpMaxErrorBound; } void CNetBufWithStats::Init ( const int iNewBlockSize, const int iNewNumBlocks, const bool bNUseSequenceNumber, const bool bPreserve ) { // call base class Init CNetBuf::Init ( iNewBlockSize, iNewNumBlocks, bNUseSequenceNumber, bPreserve ); // inits for statistics calculation if ( !bPreserve ) { // set the auto filter weights and max statistic count if ( bUseDoubleSystemFrameSize ) { dAutoFilt_WightUpNormal = IIR_WEIGTH_UP_NORMAL_DOUBLE_FRAME_SIZE; dAutoFilt_WightDownNormal = IIR_WEIGTH_DOWN_NORMAL_DOUBLE_FRAME_SIZE; dAutoFilt_WightUpFast = IIR_WEIGTH_UP_FAST_DOUBLE_FRAME_SIZE; dAutoFilt_WightDownFast = IIR_WEIGTH_DOWN_FAST_DOUBLE_FRAME_SIZE; iMaxStatisticCount = MAX_STATISTIC_COUNT_DOUBLE_FRAME_SIZE; dErrorRateBound = ERROR_RATE_BOUND_DOUBLE_FRAME_SIZE; dUpMaxErrorBound = UP_MAX_ERROR_BOUND_DOUBLE_FRAME_SIZE; } else { dAutoFilt_WightUpNormal = IIR_WEIGTH_UP_NORMAL; dAutoFilt_WightDownNormal = IIR_WEIGTH_DOWN_NORMAL; dAutoFilt_WightUpFast = IIR_WEIGTH_UP_FAST; dAutoFilt_WightDownFast = IIR_WEIGTH_DOWN_FAST; iMaxStatisticCount = MAX_STATISTIC_COUNT; dErrorRateBound = ERROR_RATE_BOUND; dUpMaxErrorBound = UP_MAX_ERROR_BOUND; } for ( int i = 0; i < NUM_STAT_SIMULATION_BUFFERS; i++ ) { // init simulation buffers with the correct size SimulationBuffer[i].Init ( iNewBlockSize, viBufSizesForSim[i], bNUseSequenceNumber ); // init statistics ErrorRateStatistic[i].Init ( iMaxStatisticCount, true ); } // reset the initialization counter which controls the initialization // phase length ResetInitCounter(); // init auto buffer setting with a meaningful value, also init the // IIR parameter with this value iCurAutoBufferSizeSetting = 6; dCurIIRFilterResult = iCurAutoBufferSizeSetting; iCurDecidedResult = iCurAutoBufferSizeSetting; } } void CNetBufWithStats::ResetInitCounter() { // start initialization phase of IIR filtering, use a quarter the size // of the error rate statistic buffers which should be ok for a good // initialization value (initialization phase should be as short as // possible) iInitCounter = iMaxStatisticCount / 4; } bool CNetBufWithStats::Put ( const CVector& vecbyData, const int iInSize ) { // call base class Put const bool bPutOK = CNetBuf::Put ( vecbyData, iInSize ); // update statistics calculations for ( int i = 0; i < NUM_STAT_SIMULATION_BUFFERS; i++ ) { ErrorRateStatistic[i].Update ( !SimulationBuffer[i].Put ( vecbyData, iInSize ) ); } return bPutOK; } bool CNetBufWithStats::Get ( CVector& vecbyData, const int iOutSize ) { // call base class Get const bool bGetOK = CNetBuf::Get ( vecbyData, iOutSize ); // update statistics calculations for ( int i = 0; i < NUM_STAT_SIMULATION_BUFFERS; i++ ) { ErrorRateStatistic[i].Update ( !SimulationBuffer[i].Get ( vecbyData, iOutSize ) ); } // update auto setting UpdateAutoSetting(); return bGetOK; } void CNetBufWithStats::UpdateAutoSetting() { int iCurDecision = 0; // dummy initialization int iCurMaxUpDecision = 0; // dummy initialization bool bDecisionFound; // Get regular error rate decision ----------------------------------------- // Use a specified error bound to identify the best buffer size for the // current network situation. Start with the smallest buffer and // test for the error rate until the rate is below the bound. bDecisionFound = false; for ( int i = 0; i < NUM_STAT_SIMULATION_BUFFERS - 1; i++ ) { if ( ( !bDecisionFound ) && ( ErrorRateStatistic[i].GetAverage() <= dErrorRateBound ) ) { iCurDecision = viBufSizesForSim[i]; bDecisionFound = true; } } if ( !bDecisionFound ) { // in case no buffer is below bound, use largest buffer size iCurDecision = viBufSizesForSim[NUM_STAT_SIMULATION_BUFFERS - 1]; } // Get maximum upper error rate decision ----------------------------------- // Use a specified error bound to identify the maximum upper error rate // to identify if we have a too low buffer setting which gives a very // bad performance constantly. Start with the smallest buffer and // test for the error rate until the rate is below the bound. bDecisionFound = false; for ( int i = 0; i < NUM_STAT_SIMULATION_BUFFERS - 1; i++ ) { if ( ( !bDecisionFound ) && ( ErrorRateStatistic[i].GetAverage() <= dUpMaxErrorBound ) ) { iCurMaxUpDecision = viBufSizesForSim[i]; bDecisionFound = true; } } if ( !bDecisionFound ) { // in case no buffer is below bound, use largest buffer size iCurMaxUpDecision = viBufSizesForSim[NUM_STAT_SIMULATION_BUFFERS - 1]; // This is a worst case, something very bad had happened. Hopefully // this was just temporary so that we initiate a new initialization // phase to get quickly back to normal buffer sizes (hopefully). ResetInitCounter(); } // Post calculation (filtering) -------------------------------------------- // Define different weights for up and down direction. Up direction // filtering shall be slower than for down direction since we assume // that the lower value is the actual value which can be used for // the current network condition. If the current error rate estimation // is higher, it may be a temporary problem which should not change // the current jitter buffer size significantly. // For the initialization phase, use lower weight values to get faster // adaptation. double dWeightUp, dWeightDown; const double dHysteresisValue = FILTER_DECISION_HYSTERESIS; bool bUseFastAdaptation = false; // check for initialization phase if ( iInitCounter > 0 ) { // decrease init counter iInitCounter--; // use the fast adaptation bUseFastAdaptation = true; } // if the current detected buffer setting is below the maximum upper bound // decision, then we enable a booster to go up to the minimum required // number of buffer blocks (i.e. we use weights for fast adaptation) if ( iCurAutoBufferSizeSetting < iCurMaxUpDecision ) { bUseFastAdaptation = true; } if ( bUseFastAdaptation ) { dWeightUp = dAutoFilt_WightUpFast; dWeightDown = dAutoFilt_WightDownFast; } else { dWeightUp = dAutoFilt_WightUpNormal; dWeightDown = dAutoFilt_WightDownNormal; } // apply non-linear IIR filter MathUtils().UpDownIIR1 ( dCurIIRFilterResult, static_cast ( iCurDecision ), dWeightUp, dWeightDown ); //### TEST: BEGIN ###// // TEST store important detection parameters in file for debugging /* static FILE* pFile = fopen ( "test.dat", "w" ); static int icnt = 0; if ( icnt == 50 ) { fprintf ( pFile, "%d %e\n", iCurDecision, dCurIIRFilterResult ); fflush ( pFile ); icnt = 0; } else { icnt++; } */ //### TEST: END ###// // apply a hysteresis iCurAutoBufferSizeSetting = MathUtils().DecideWithHysteresis ( dCurIIRFilterResult, iCurDecidedResult, dHysteresisValue ); // Initialization phase check and correction ------------------------------- // sometimes in the very first period after a connection we get a bad error // rate result -> delete this from the initialization phase if ( iInitCounter == iMaxStatisticCount / 8 ) { // check error rate of the largest buffer as the indicator if ( ErrorRateStatistic[NUM_STAT_SIMULATION_BUFFERS - 1].GetAverage() > dErrorRateBound ) { for ( int i = 0; i < NUM_STAT_SIMULATION_BUFFERS; i++ ) { ErrorRateStatistic[i].Reset(); } } } } jamulus-3.9.1+dfsg/src/connectdlgbase.ui0000644000175000017500000000722014340334543017256 0ustar vimervimer CConnectDlgBase 0 0 521 493 Connection Setup :/png/main/res/fronticon.png:/png/main/res/fronticon.png true 0 Directory Filter Show All Musicians QAbstractItemView::NoEditTriggers true Server Name Ping Time Musicians Location Server Address Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter true Qt::Horizontal 351 25 C&ancel &Connect true jamulus-3.9.1+dfsg/src/clientsettingsdlg.cpp0000644000175000017500000016010514340334543020200 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #include "clientsettingsdlg.h" /* Implementation *************************************************************/ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, CClientSettings* pNSetP, QWidget* parent ) : CBaseDlg ( parent, Qt::Window ), // use Qt::Window to get min/max window buttons pClient ( pNCliP ), pSettings ( pNSetP ) { setupUi ( this ); #if defined( Q_OS_IOS ) // iOS needs menu to close QMenuBar* pMenu = new QMenuBar ( this ); QAction* action = pMenu->addAction ( tr ( "&Close" ) ); connect ( action, SIGNAL ( triggered() ), this, SLOT ( close() ) ); // Now tell the layout about the menu layout()->setMenuBar ( pMenu ); #endif #if defined( Q_OS_ANDROID ) || defined( ANDROID ) // Android too QMenuBar* pMenu = new QMenuBar ( this ); QMenu* pCloseMenu = new QMenu ( tr ( "&Close" ), this ); pCloseMenu->addAction ( tr ( "&Close" ), this, SLOT ( close() ) ); pMenu->addMenu ( pCloseMenu ); // Now tell the layout about the menu layout()->setMenuBar ( pMenu ); #endif // Add help text to controls ----------------------------------------------- // local audio input fader QString strAudFader = "" + tr ( "Local Audio Input Fader" ) + ": " + tr ( "Controls the relative levels of the left and right local audio " "channels. For a mono signal it acts as a pan between the two channels. " "For example, if a microphone is connected to " "the right input channel and an instrument is connected to the left " "input channel which is much louder than the microphone, move the " "audio fader in a direction where the label above the fader shows " "%1, where %2 is the current attenuation indicator." ) .arg ( "" + tr ( "L" ) + " -x", "x" ); lblAudioPan->setWhatsThis ( strAudFader ); lblAudioPanValue->setWhatsThis ( strAudFader ); sldAudioPan->setWhatsThis ( strAudFader ); sldAudioPan->setAccessibleName ( tr ( "Local audio input fader (left/right)" ) ); // jitter buffer QString strJitterBufferSize = "" + tr ( "Jitter Buffer Size" ) + ": " + tr ( "The jitter buffer compensates for network and sound card timing jitters. The " "size of the buffer therefore influences the quality of " "the audio stream (how many dropouts occur) and the overall delay " "(the longer the buffer, the higher the delay)." ) + "
" + tr ( "You can set the jitter buffer size manually for the local client " "and the remote server. For the local jitter buffer, dropouts in the " "audio stream are indicated by the light below the " "jitter buffer size faders. If the light turns to red, a buffer " "overrun/underrun has taken place and the audio stream is interrupted." ) + "
" + tr ( "The jitter buffer setting is therefore a trade-off between audio " "quality and overall delay." ) + "
" + tr ( "If the Auto setting is enabled, the jitter buffers of the local client and " "the remote server are set automatically " "based on measurements of the network and sound card timing jitter. If " "Auto is enabled, the jitter buffer size faders are " "disabled (they cannot be moved with the mouse)." ); QString strJitterBufferSizeTT = tr ( "If the Auto setting " "is enabled, the network buffers of the local client and " "the remote server are set to a conservative " "value to minimize the audio dropout probability. To tweak the " "audio delay/latency it is recommended to disable the Auto setting " "and to lower the jitter buffer size manually by " "using the sliders until your personal acceptable amount " "of dropouts is reached. The LED indicator will display the audio " "dropouts of the local jitter buffer with a red light." ) + TOOLTIP_COM_END_TEXT; lblNetBuf->setWhatsThis ( strJitterBufferSize ); lblNetBuf->setToolTip ( strJitterBufferSizeTT ); grbJitterBuffer->setWhatsThis ( strJitterBufferSize ); grbJitterBuffer->setToolTip ( strJitterBufferSizeTT ); sldNetBuf->setWhatsThis ( strJitterBufferSize ); sldNetBuf->setAccessibleName ( tr ( "Local jitter buffer slider control" ) ); sldNetBuf->setToolTip ( strJitterBufferSizeTT ); sldNetBufServer->setWhatsThis ( strJitterBufferSize ); sldNetBufServer->setAccessibleName ( tr ( "Server jitter buffer slider control" ) ); sldNetBufServer->setToolTip ( strJitterBufferSizeTT ); chbAutoJitBuf->setAccessibleName ( tr ( "Auto jitter buffer switch" ) ); chbAutoJitBuf->setToolTip ( strJitterBufferSizeTT ); #if !defined( WITH_JACK ) // sound card device lblSoundcardDevice->setWhatsThis ( "" + tr ( "Audio Device" ) + ": " + tr ( "Under the Windows operating system the ASIO driver (sound card) can be " "selected using %1. If the selected ASIO driver is not valid an error " "message is shown and the previous valid driver is selected. " "Under macOS the input and output hardware can be selected." ) .arg ( APP_NAME ) + "
" + tr ( "If the driver is selected during an active connection, the connection " "is stopped, the driver is changed and the connection is started again " "automatically." ) ); cbxSoundcard->setAccessibleName ( tr ( "Sound card device selector combo box" ) ); # if defined( _WIN32 ) // set Windows specific tool tip cbxSoundcard->setToolTip ( tr ( "If the ASIO4ALL driver is used, " "please note that this driver usually introduces approx. 10-30 ms of " "additional audio delay. Using a sound card with a native ASIO driver " "is therefore recommended." ) + "
" + tr ( "If you are using the kX ASIO " "driver, make sure to connect the ASIO inputs in the kX DSP settings " "panel." ) + TOOLTIP_COM_END_TEXT ); # endif // sound card input/output channel mapping QString strSndCrdChanMapp = "" + tr ( "Sound Card Channel Mapping" ) + ": " + tr ( "If the selected sound card device offers more than one " "input or output channel, the Input Channel Mapping and Output " "Channel Mapping settings are visible." ) + "
" + tr ( "For each %1 input/output channel (left and " "right channel) a different actual sound card channel can be " "selected." ) .arg ( APP_NAME ); lblInChannelMapping->setWhatsThis ( strSndCrdChanMapp ); lblOutChannelMapping->setWhatsThis ( strSndCrdChanMapp ); cbxLInChan->setWhatsThis ( strSndCrdChanMapp ); cbxLInChan->setAccessibleName ( tr ( "Left input channel selection combo box" ) ); cbxRInChan->setWhatsThis ( strSndCrdChanMapp ); cbxRInChan->setAccessibleName ( tr ( "Right input channel selection combo box" ) ); cbxLOutChan->setWhatsThis ( strSndCrdChanMapp ); cbxLOutChan->setAccessibleName ( tr ( "Left output channel selection combo box" ) ); cbxROutChan->setWhatsThis ( strSndCrdChanMapp ); cbxROutChan->setAccessibleName ( tr ( "Right output channel selection combo box" ) ); #endif // enable OPUS64 chbEnableOPUS64->setWhatsThis ( "" + tr ( "Enable Small Network Buffers" ) + ": " + tr ( "Enables support for very small network audio packets. These " "network packets are only actually used if the sound card buffer delay is smaller than %1 samples. The " "smaller the network buffers, the lower the audio latency. But at the same time " "the network load and the probability of audio dropouts or sound artifacts increases." ) .arg ( DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES ) ); chbEnableOPUS64->setAccessibleName ( tr ( "Enable small network buffers check box" ) ); // sound card buffer delay QString strSndCrdBufDelay = "" + tr ( "Sound Card Buffer Delay" ) + ": " + tr ( "The buffer delay setting is a fundamental setting of %1. " "This setting has an influence on many connection properties." ) .arg ( APP_NAME ) + "
" + tr ( "Three buffer sizes can be selected" ) + ":
    " "
  • " + tr ( "64 samples: Provides the lowest latency but does not work with all sound cards." ) + "
  • " "
  • " + tr ( "128 samples: Should work for most available sound cards." ) + "
  • " "
  • " + tr ( "256 samples: Should only be used when 64 or 128 samples " "is causing issues." ) + "
  • " "
" + tr ( "Some sound card drivers do not allow the buffer delay to be changed from within %1. " "In this case the buffer delay setting is disabled and has to be changed using the sound card driver. " "Use the appropriate tool for the interface in use to adjust this buffer size. " "For example, if using ASIO, use the \"ASIO Device Settings\" button to open the driver settings panel or if using JACK, use a tool " "such as QjackCtl to adjust the buffer size. " "Other interfaces, such as Pipewire, would require their appropriate tool being used. Please refer to the interface manual." ) .arg ( APP_NAME ) + "
" + tr ( "If no buffer size is selected and all settings are disabled, this means a " "buffer size in use by the driver which does not match the values. %1 " "will still work with this setting but may have restricted " "performance." ) .arg ( APP_NAME ) + "
" + tr ( "The actual buffer delay has influence on the connection, the " "current upload rate and the overall delay. The lower the buffer size, " "the higher the probability of a red light in the status indicator (drop " "outs) and the higher the upload rate and the lower the overall " "delay." ) + "
" + tr ( "The buffer setting is therefore a trade-off between audio quality and overall delay." ); QString strSndCrdBufDelayTT = tr ( "Some sound card drivers do not allow the buffer delay to be changed from within %1. " "In this case the buffer delay setting is disabled and has to be changed using the sound card driver. " "Use the appropriate tool for the interface in use to adjust this buffer size. " "For example, if using ASIO, use the \"ASIO Device Settings\" button to open the driver settings panel or if using JACK, use a tool " "such as QjackCtl to adjust the buffer size. " "Other interfaces, such as Pipewire, would require their appropriate tool being used. Please refer to the interface manual." ) .arg ( APP_NAME ) + TOOLTIP_COM_END_TEXT; #if defined( _WIN32 ) && !defined( WITH_JACK ) // Driver setup button QString strSndCardDriverSetup = "" + tr ( "Sound card driver settings" ) + ": " + tr ( "This opens the driver settings of your sound card. Some drivers " "allow you to change buffer settings, others like ASIO4ALL " "lets you choose input or outputs of your device(s). " "More information can be found on jamulus.io." ); QString strSndCardDriverSetupTT = tr ( "Opens the driver settings. Note: %1 currently only supports devices " "with a sample rate of %2 Hz. " "You will not be able to select a driver/device which doesn't. " "For more help see jamulus.io." ) .arg ( APP_NAME ) .arg ( SYSTEM_SAMPLE_RATE_HZ ) + TOOLTIP_COM_END_TEXT; #endif rbtBufferDelayPreferred->setWhatsThis ( strSndCrdBufDelay ); rbtBufferDelayPreferred->setAccessibleName ( tr ( "64 samples setting radio button" ) ); rbtBufferDelayPreferred->setToolTip ( strSndCrdBufDelayTT ); rbtBufferDelayDefault->setWhatsThis ( strSndCrdBufDelay ); rbtBufferDelayDefault->setAccessibleName ( tr ( "128 samples setting radio button" ) ); rbtBufferDelayDefault->setToolTip ( strSndCrdBufDelayTT ); rbtBufferDelaySafe->setWhatsThis ( strSndCrdBufDelay ); rbtBufferDelaySafe->setAccessibleName ( tr ( "256 samples setting radio button" ) ); rbtBufferDelaySafe->setToolTip ( strSndCrdBufDelayTT ); #if defined( _WIN32 ) && !defined( WITH_JACK ) butDriverSetup->setWhatsThis ( strSndCardDriverSetup ); butDriverSetup->setAccessibleName ( tr ( "ASIO Device Settings push button" ) ); butDriverSetup->setToolTip ( strSndCardDriverSetupTT ); #endif // fancy skin lblSkin->setWhatsThis ( "" + tr ( "Skin" ) + ": " + tr ( "Select the skin to be used for the main window." ) ); cbxSkin->setAccessibleName ( tr ( "Skin combo box" ) ); // MeterStyle lblMeterStyle->setWhatsThis ( "" + tr ( "Meter Style" ) + ": " + tr ( "Select the meter style to be used for the level meters. The " "Bar (narrow) and LEDs (round, small) options only apply to the mixerboard. When " "Bar (narrow) is selected, the input meters are set to Bar (wide). When " "LEDs (round, small) is selected, the input meters are set to LEDs (round, big). " "The remaining options apply to the mixerboard and input meters." ) ); cbxMeterStyle->setAccessibleName ( tr ( "Meter Style combo box" ) ); // Interface Language lblLanguage->setWhatsThis ( "" + tr ( "Language" ) + ": " + tr ( "Select the language to be used for the user interface." ) ); cbxLanguage->setAccessibleName ( tr ( "Language combo box" ) ); // audio channels QString strAudioChannels = "" + tr ( "Audio Channels" ) + ": " + tr ( "Selects the number of audio channels to be used for communication between " "client and server. There are three modes available:" ) + "
    " "
  • " "" + tr ( "Mono" ) + " " + tr ( "and" ) + " " + tr ( "Stereo" ) + ": " + tr ( "These modes use " "one and two audio channels respectively." ) + "
  • " "
  • " "" + tr ( "Mono in/Stereo-out" ) + ": " + tr ( "The audio signal sent to the server is mono but the " "return signal is stereo. This is useful if the " "sound card has the instrument on one input channel and the " "microphone on the other. In that case the two input signals " "can be mixed to one mono channel but the server mix is heard in " "stereo." ) + "
  • " "
  • " + tr ( "Enabling " ) + "" + tr ( "Stereo" ) + " " + tr ( " mode " "will increase your stream's data rate. Make sure your upload rate does not " "exceed the available upload speed of your internet connection." ) + "
  • " "
" + tr ( "In stereo streaming mode, no audio channel selection " "for the reverb effect will be available on the main window " "since the effect is applied to both channels in this case." ); lblAudioChannels->setWhatsThis ( strAudioChannels ); cbxAudioChannels->setWhatsThis ( strAudioChannels ); cbxAudioChannels->setAccessibleName ( tr ( "Audio channels combo box" ) ); // audio quality QString strAudioQuality = "" + tr ( "Audio Quality" ) + ": " + tr ( "The higher the audio quality, the higher your audio stream's " "data rate. Make sure your upload rate does not exceed the " "available bandwidth of your internet connection." ); lblAudioQuality->setWhatsThis ( strAudioQuality ); cbxAudioQuality->setWhatsThis ( strAudioQuality ); cbxAudioQuality->setAccessibleName ( tr ( "Audio quality combo box" ) ); // new client fader level QString strNewClientLevel = "" + tr ( "New Client Level" ) + ": " + tr ( "This setting defines the fader level of a newly " "connected client in percent. If a new client connects " "to the current server, they will get the specified initial " "fader level if no other fader level from a previous connection " "of that client was already stored." ); lblNewClientLevel->setWhatsThis ( strNewClientLevel ); edtNewClientLevel->setWhatsThis ( strNewClientLevel ); edtNewClientLevel->setAccessibleName ( tr ( "New client level edit box" ) ); // input boost QString strInputBoost = "" + tr ( "Input Boost" ) + ": " + tr ( "This setting allows you to increase your input signal level " "by factors up to 10 (+20dB). " "If your sound is too quiet, first try to increase the level by " "getting closer to the microphone, adjusting your sound equipment " "or increasing levels in your operating system's input settings. " "Only if this fails, set a factor here. " "If your sound is too loud, sounds distorted and is clipping, this " "option will not help. Do not use it. The distortion will still be " "there. Instead, decrease your input level by getting farther away " "from your microphone, adjusting your sound equipment " "or by decreasing your operating system's input settings." ); lblInputBoost->setWhatsThis ( strInputBoost ); cbxInputBoost->setWhatsThis ( strInputBoost ); cbxInputBoost->setAccessibleName ( tr ( "Input Boost combo box" ) ); // custom directories QString strCustomDirectories = "" + tr ( "Custom Directories" ) + ": " + tr ( "If you need to add additional directories to the Connect dialog Directory drop down, " "you can enter the addresses here.
" "To remove a value, select it, delete the text in the input box, " "then move focus out of the control." ); lblCustomDirectories->setWhatsThis ( strCustomDirectories ); cbxCustomDirectories->setWhatsThis ( strCustomDirectories ); cbxCustomDirectories->setAccessibleName ( tr ( "Custom Directories combo box" ) ); // current connection status parameter QString strConnStats = "" + tr ( "Audio Upstream Rate" ) + ": " + tr ( "Depends on the current audio packet size and " "compression setting. Make sure that the upstream rate is not " "higher than your available internet upload speed (check this with a " "service such as speedtest.net)." ); lblUpstreamValue->setWhatsThis ( strConnStats ); grbUpstreamValue->setWhatsThis ( strConnStats ); QString strNumMixerPanelRows = "" + tr ( "Number of Mixer Panel Rows" ) + ": " + tr ( "Adjust the number of rows used to arrange the mixer panel." ); lblMixerRows->setWhatsThis ( strNumMixerPanelRows ); spnMixerRows->setWhatsThis ( strNumMixerPanelRows ); spnMixerRows->setAccessibleName ( tr ( "Number of Mixer Panel Rows spin box" ) ); QString strDetectFeedback = "" + tr ( "Feedback Protection" ) + ": " + tr ( "Enable feedback protection to detect acoustic feedback between " "microphone and speakers." ); lblDetectFeedback->setWhatsThis ( strDetectFeedback ); chbDetectFeedback->setWhatsThis ( strDetectFeedback ); chbDetectFeedback->setAccessibleName ( tr ( "Feedback Protection check box" ) ); // audio alerts QString strAudioAlerts = "" + tr ( "Audio Alerts" ) + ": " + tr ( "Enable audio alert when receiving a chat message and when a new client joins the session. " "A second sound device may be required to hear the alerts." ); lblAudioAlerts->setWhatsThis ( strAudioAlerts ); chbAudioAlerts->setWhatsThis ( strAudioAlerts ); chbAudioAlerts->setAccessibleName ( tr ( "Audio Alerts check box" ) ); // init driver button #if defined( _WIN32 ) && !defined( WITH_JACK ) butDriverSetup->setText ( tr ( "ASIO Device Settings" ) ); #else // no use for this button for MacOS/Linux right now or when using JACK -> hide it butDriverSetup->hide(); #endif // init audio in fader sldAudioPan->setRange ( AUD_FADER_IN_MIN, AUD_FADER_IN_MAX ); sldAudioPan->setTickInterval ( AUD_FADER_IN_MAX / 5 ); UpdateAudioFaderSlider(); // init delay and other information controls lblUpstreamValue->setText ( "---" ); lblUpstreamUnit->setText ( "" ); edtNewClientLevel->setValidator ( new QIntValidator ( 0, 100, this ) ); // % range from 0-100 // init slider controls --- // network buffer sliders sldNetBuf->setRange ( MIN_NET_BUF_SIZE_NUM_BL, MAX_NET_BUF_SIZE_NUM_BL ); sldNetBufServer->setRange ( MIN_NET_BUF_SIZE_NUM_BL, MAX_NET_BUF_SIZE_NUM_BL ); UpdateJitterBufferFrame(); // init sound card channel selection frame UpdateSoundDeviceChannelSelectionFrame(); // Audio Channels combo box cbxAudioChannels->clear(); cbxAudioChannels->addItem ( tr ( "Mono" ) ); // CC_MONO cbxAudioChannels->addItem ( tr ( "Mono-in/Stereo-out" ) ); // CC_MONO_IN_STEREO_OUT cbxAudioChannels->addItem ( tr ( "Stereo" ) ); // CC_STEREO cbxAudioChannels->setCurrentIndex ( static_cast ( pClient->GetAudioChannels() ) ); // Audio Quality combo box cbxAudioQuality->clear(); cbxAudioQuality->addItem ( tr ( "Low" ) ); // AQ_LOW cbxAudioQuality->addItem ( tr ( "Normal" ) ); // AQ_NORMAL cbxAudioQuality->addItem ( tr ( "High" ) ); // AQ_HIGH cbxAudioQuality->setCurrentIndex ( static_cast ( pClient->GetAudioQuality() ) ); // GUI design (skin) combo box cbxSkin->clear(); cbxSkin->addItem ( tr ( "Normal" ) ); // GD_STANDARD cbxSkin->addItem ( tr ( "Fancy" ) ); // GD_ORIGINAL cbxSkin->addItem ( tr ( "Compact" ) ); // GD_SLIMFADER cbxSkin->setCurrentIndex ( static_cast ( pClient->GetGUIDesign() ) ); // MeterStyle combo box cbxMeterStyle->clear(); cbxMeterStyle->addItem ( tr ( "Bar (narrow)" ) ); // MT_BAR_NARROW cbxMeterStyle->addItem ( tr ( "Bar (wide)" ) ); // MT_BAR_WIDE cbxMeterStyle->addItem ( tr ( "LEDs (stripe)" ) ); // MT_LED_STRIPE cbxMeterStyle->addItem ( tr ( "LEDs (round, small)" ) ); // MT_LED_ROUND_SMALL cbxMeterStyle->addItem ( tr ( "LEDs (round, big)" ) ); // MT_LED_ROUND_BIG cbxMeterStyle->setCurrentIndex ( static_cast ( pClient->GetMeterStyle() ) ); // language combo box (corrects the setting if language not found) cbxLanguage->Init ( pSettings->strLanguage ); // init custom directories combo box (max MAX_NUM_SERVER_ADDR_ITEMS entries) cbxCustomDirectories->setMaxCount ( MAX_NUM_SERVER_ADDR_ITEMS ); cbxCustomDirectories->setInsertPolicy ( QComboBox::NoInsert ); // update new client fader level edit box edtNewClientLevel->setText ( QString::number ( pSettings->iNewClientFaderLevel ) ); // Input Boost combo box cbxInputBoost->clear(); cbxInputBoost->addItem ( tr ( "None" ) ); for ( int i = 2; i <= 10; i++ ) { cbxInputBoost->addItem ( QString ( "%1x" ).arg ( i ) ); } // factor is 1-based while index is 0-based: cbxInputBoost->setCurrentIndex ( pSettings->iInputBoost - 1 ); // init number of mixer rows spnMixerRows->setValue ( pSettings->iNumMixerPanelRows ); // init audio alerts chbAudioAlerts->setCheckState ( pSettings->bEnableAudioAlerts ? Qt::Checked : Qt::Unchecked ); // update feedback detection chbDetectFeedback->setCheckState ( pSettings->bEnableFeedbackDetection ? Qt::Checked : Qt::Unchecked ); // update enable small network buffers check box chbEnableOPUS64->setCheckState ( pClient->GetEnableOPUS64() ? Qt::Checked : Qt::Unchecked ); // set text for sound card buffer delay radio buttons rbtBufferDelayPreferred->setText ( GenSndCrdBufferDelayString ( FRAME_SIZE_FACTOR_PREFERRED * SYSTEM_FRAME_SIZE_SAMPLES ) ); rbtBufferDelayDefault->setText ( GenSndCrdBufferDelayString ( FRAME_SIZE_FACTOR_DEFAULT * SYSTEM_FRAME_SIZE_SAMPLES ) ); rbtBufferDelaySafe->setText ( GenSndCrdBufferDelayString ( FRAME_SIZE_FACTOR_SAFE * SYSTEM_FRAME_SIZE_SAMPLES ) ); // sound card buffer delay inits SndCrdBufferDelayButtonGroup.addButton ( rbtBufferDelayPreferred ); SndCrdBufferDelayButtonGroup.addButton ( rbtBufferDelayDefault ); SndCrdBufferDelayButtonGroup.addButton ( rbtBufferDelaySafe ); UpdateSoundCardFrame(); // Add help text to controls ----------------------------------------------- // Musician Profile QString strFaderTag = "" + tr ( "Musician Profile" ) + ": " + tr ( "Write your name or an alias here so the other musicians you want to " "play with know who you are. You may also add a picture of the instrument " "you play and a flag of the country or region you are located in. " "Your city and skill level playing your instrument may also be added." ) + "
" + tr ( "What you set here will appear at your fader on the mixer " "board when you are connected to a %1 server. This tag will " "also be shown at each client which is connected to the same server as " "you." ) .arg ( APP_NAME ); plblAlias->setWhatsThis ( strFaderTag ); pedtAlias->setAccessibleName ( tr ( "Alias or name edit box" ) ); plblInstrument->setWhatsThis ( strFaderTag ); pcbxInstrument->setAccessibleName ( tr ( "Instrument picture button" ) ); plblCountry->setWhatsThis ( strFaderTag ); pcbxCountry->setAccessibleName ( tr ( "Country/region flag button" ) ); plblCity->setWhatsThis ( strFaderTag ); pedtCity->setAccessibleName ( tr ( "City edit box" ) ); plblSkill->setWhatsThis ( strFaderTag ); pcbxSkill->setAccessibleName ( tr ( "Skill level combo box" ) ); // Instrument pictures combo box ------------------------------------------- // add an entry for all known instruments for ( int iCurInst = 0; iCurInst < CInstPictures::GetNumAvailableInst(); iCurInst++ ) { // create a combo box item with text, image and background color QColor InstrColor; pcbxInstrument->addItem ( QIcon ( CInstPictures::GetResourceReference ( iCurInst ) ), CInstPictures::GetName ( iCurInst ), iCurInst ); switch ( CInstPictures::GetCategory ( iCurInst ) ) { case CInstPictures::IC_OTHER_INSTRUMENT: InstrColor = QColor ( Qt::blue ); break; case CInstPictures::IC_WIND_INSTRUMENT: InstrColor = QColor ( Qt::green ); break; case CInstPictures::IC_STRING_INSTRUMENT: InstrColor = QColor ( Qt::red ); break; case CInstPictures::IC_PLUCKING_INSTRUMENT: InstrColor = QColor ( Qt::cyan ); break; case CInstPictures::IC_PERCUSSION_INSTRUMENT: InstrColor = QColor ( Qt::white ); break; case CInstPictures::IC_KEYBOARD_INSTRUMENT: InstrColor = QColor ( Qt::yellow ); break; case CInstPictures::IC_MULTIPLE_INSTRUMENT: InstrColor = QColor ( Qt::black ); break; } InstrColor.setAlpha ( 10 ); pcbxInstrument->setItemData ( iCurInst, InstrColor, Qt::BackgroundRole ); } // sort the items in alphabetical order pcbxInstrument->model()->sort ( 0 ); // Country flag icons combo box -------------------------------------------- // add an entry for all known country flags for ( int iCurCntry = static_cast ( QLocale::AnyCountry ); iCurCntry < static_cast ( QLocale::LastCountry ); iCurCntry++ ) { // exclude the "None" entry since it is added after the sorting if ( static_cast ( iCurCntry ) == QLocale::AnyCountry ) { continue; } if ( !CLocale::IsCountryCodeSupported ( iCurCntry ) ) { // The current Qt version which is the base for the loop may support // more country codes than our protocol does. Therefore, skip // the unsupported options to avoid surprises. continue; } // get current country enum QLocale::Country eCountry = static_cast ( iCurCntry ); // try to load icon from resource file name QIcon CurFlagIcon; CurFlagIcon.addFile ( CLocale::GetCountryFlagIconsResourceReference ( eCountry ) ); // only add the entry if a flag is available if ( !CurFlagIcon.isNull() ) { // create a combo box item with text and image pcbxCountry->addItem ( QIcon ( CurFlagIcon ), QLocale::countryToString ( eCountry ), iCurCntry ); } } // sort country combo box items in alphabetical order pcbxCountry->model()->sort ( 0, Qt::AscendingOrder ); // the "None" country gets a special icon and is the very first item QIcon FlagNoneIcon; FlagNoneIcon.addFile ( ":/png/flags/res/flags/flagnone.png" ); pcbxCountry->insertItem ( 0, FlagNoneIcon, tr ( "None" ), static_cast ( QLocale::AnyCountry ) ); // Skill level combo box --------------------------------------------------- // create a pixmap showing the skill level colors QPixmap SLPixmap ( 16, 11 ); // same size as the country flags SLPixmap.fill ( QColor::fromRgb ( RGBCOL_R_SL_NOT_SET, RGBCOL_G_SL_NOT_SET, RGBCOL_B_SL_NOT_SET ) ); pcbxSkill->addItem ( QIcon ( SLPixmap ), tr ( "None" ), SL_NOT_SET ); SLPixmap.fill ( QColor::fromRgb ( RGBCOL_R_SL_BEGINNER, RGBCOL_G_SL_BEGINNER, RGBCOL_B_SL_BEGINNER ) ); pcbxSkill->addItem ( QIcon ( SLPixmap ), tr ( "Beginner" ), SL_BEGINNER ); SLPixmap.fill ( QColor::fromRgb ( RGBCOL_R_SL_INTERMEDIATE, RGBCOL_G_SL_INTERMEDIATE, RGBCOL_B_SL_INTERMEDIATE ) ); pcbxSkill->addItem ( QIcon ( SLPixmap ), tr ( "Intermediate" ), SL_INTERMEDIATE ); SLPixmap.fill ( QColor::fromRgb ( RGBCOL_R_SL_SL_PROFESSIONAL, RGBCOL_G_SL_SL_PROFESSIONAL, RGBCOL_B_SL_SL_PROFESSIONAL ) ); pcbxSkill->addItem ( QIcon ( SLPixmap ), tr ( "Expert" ), SL_PROFESSIONAL ); // Connections ------------------------------------------------------------- // timers QObject::connect ( &TimerStatus, &QTimer::timeout, this, &CClientSettingsDlg::OnTimerStatus ); // slider controls QObject::connect ( sldNetBuf, &QSlider::valueChanged, this, &CClientSettingsDlg::OnNetBufValueChanged ); QObject::connect ( sldNetBufServer, &QSlider::valueChanged, this, &CClientSettingsDlg::OnNetBufServerValueChanged ); // check boxes QObject::connect ( chbAutoJitBuf, &QCheckBox::stateChanged, this, &CClientSettingsDlg::OnAutoJitBufStateChanged ); QObject::connect ( chbEnableOPUS64, &QCheckBox::stateChanged, this, &CClientSettingsDlg::OnEnableOPUS64StateChanged ); QObject::connect ( chbDetectFeedback, &QCheckBox::stateChanged, this, &CClientSettingsDlg::OnFeedbackDetectionChanged ); QObject::connect ( chbAudioAlerts, &QCheckBox::stateChanged, this, &CClientSettingsDlg::OnAudioAlertsChanged ); // line edits QObject::connect ( edtNewClientLevel, &QLineEdit::editingFinished, this, &CClientSettingsDlg::OnNewClientLevelEditingFinished ); // combo boxes QObject::connect ( cbxSoundcard, static_cast ( &QComboBox::activated ), this, &CClientSettingsDlg::OnSoundcardActivated ); QObject::connect ( cbxLInChan, static_cast ( &QComboBox::activated ), this, &CClientSettingsDlg::OnLInChanActivated ); QObject::connect ( cbxRInChan, static_cast ( &QComboBox::activated ), this, &CClientSettingsDlg::OnRInChanActivated ); QObject::connect ( cbxLOutChan, static_cast ( &QComboBox::activated ), this, &CClientSettingsDlg::OnLOutChanActivated ); QObject::connect ( cbxROutChan, static_cast ( &QComboBox::activated ), this, &CClientSettingsDlg::OnROutChanActivated ); QObject::connect ( cbxAudioChannels, static_cast ( &QComboBox::activated ), this, &CClientSettingsDlg::OnAudioChannelsActivated ); QObject::connect ( cbxAudioQuality, static_cast ( &QComboBox::activated ), this, &CClientSettingsDlg::OnAudioQualityActivated ); QObject::connect ( cbxSkin, static_cast ( &QComboBox::activated ), this, &CClientSettingsDlg::OnGUIDesignActivated ); QObject::connect ( cbxMeterStyle, static_cast ( &QComboBox::activated ), this, &CClientSettingsDlg::OnMeterStyleActivated ); QObject::connect ( cbxCustomDirectories->lineEdit(), &QLineEdit::editingFinished, this, &CClientSettingsDlg::OnCustomDirectoriesEditingFinished ); QObject::connect ( cbxCustomDirectories, static_cast ( &QComboBox::activated ), this, &CClientSettingsDlg::OnCustomDirectoriesEditingFinished ); QObject::connect ( cbxLanguage, &CLanguageComboBox::LanguageChanged, this, &CClientSettingsDlg::OnLanguageChanged ); QObject::connect ( cbxInputBoost, static_cast ( &QComboBox::activated ), this, &CClientSettingsDlg::OnInputBoostChanged ); // buttons #if defined( _WIN32 ) && !defined( WITH_JACK ) // Driver Setup button is only available for Windows when JACK is not used QObject::connect ( butDriverSetup, &QPushButton::clicked, this, &CClientSettingsDlg::OnDriverSetupClicked ); #endif // misc // sliders QObject::connect ( sldAudioPan, &QSlider::valueChanged, this, &CClientSettingsDlg::OnAudioPanValueChanged ); QObject::connect ( &SndCrdBufferDelayButtonGroup, static_cast ( &QButtonGroup::buttonClicked ), this, &CClientSettingsDlg::OnSndCrdBufferDelayButtonGroupClicked ); // spinners QObject::connect ( spnMixerRows, static_cast ( &QSpinBox::valueChanged ), this, &CClientSettingsDlg::NumMixerPanelRowsChanged ); // Musician Profile QObject::connect ( pedtAlias, &QLineEdit::textChanged, this, &CClientSettingsDlg::OnAliasTextChanged ); QObject::connect ( pcbxInstrument, static_cast ( &QComboBox::activated ), this, &CClientSettingsDlg::OnInstrumentActivated ); QObject::connect ( pcbxCountry, static_cast ( &QComboBox::activated ), this, &CClientSettingsDlg::OnCountryActivated ); QObject::connect ( pedtCity, &QLineEdit::textChanged, this, &CClientSettingsDlg::OnCityTextChanged ); QObject::connect ( pcbxSkill, static_cast ( &QComboBox::activated ), this, &CClientSettingsDlg::OnSkillActivated ); QObject::connect ( tabSettings, &QTabWidget::currentChanged, this, &CClientSettingsDlg::OnTabChanged ); tabSettings->setCurrentIndex ( pSettings->iSettingsTab ); // Timers ------------------------------------------------------------------ // start timer for status bar TimerStatus.start ( DISPLAY_UPDATE_TIME ); } void CClientSettingsDlg::showEvent ( QShowEvent* ) { UpdateDisplay(); UpdateDirectoryServerComboBox(); // set the name pedtAlias->setText ( pClient->ChannelInfo.strName ); // select current instrument pcbxInstrument->setCurrentIndex ( pcbxInstrument->findData ( pClient->ChannelInfo.iInstrument ) ); // select current country pcbxCountry->setCurrentIndex ( pcbxCountry->findData ( static_cast ( pClient->ChannelInfo.eCountry ) ) ); // set the city pedtCity->setText ( pClient->ChannelInfo.strCity ); // select the skill level pcbxSkill->setCurrentIndex ( pcbxSkill->findData ( static_cast ( pClient->ChannelInfo.eSkillLevel ) ) ); } void CClientSettingsDlg::UpdateJitterBufferFrame() { // update slider value and text const int iCurNumNetBuf = pClient->GetSockBufNumFrames(); sldNetBuf->setValue ( iCurNumNetBuf ); lblNetBuf->setText ( tr ( "Size: " ) + QString::number ( iCurNumNetBuf ) ); const int iCurNumNetBufServer = pClient->GetServerSockBufNumFrames(); sldNetBufServer->setValue ( iCurNumNetBufServer ); lblNetBufServer->setText ( tr ( "Size: " ) + QString::number ( iCurNumNetBufServer ) ); // if auto setting is enabled, disable slider control const bool bIsAutoSockBufSize = pClient->GetDoAutoSockBufSize(); chbAutoJitBuf->setChecked ( bIsAutoSockBufSize ); sldNetBuf->setEnabled ( !bIsAutoSockBufSize ); lblNetBuf->setEnabled ( !bIsAutoSockBufSize ); lblNetBufLabel->setEnabled ( !bIsAutoSockBufSize ); sldNetBufServer->setEnabled ( !bIsAutoSockBufSize ); lblNetBufServer->setEnabled ( !bIsAutoSockBufSize ); lblNetBufServerLabel->setEnabled ( !bIsAutoSockBufSize ); } QString CClientSettingsDlg::GenSndCrdBufferDelayString ( const int iFrameSize, const QString strAddText ) { // use two times the buffer delay for the entire delay since // we have input and output return QString().setNum ( static_cast ( iFrameSize ) * 2 * 1000 / SYSTEM_SAMPLE_RATE_HZ, 'f', 2 ) + " ms (" + QString().setNum ( iFrameSize ) + strAddText + ")"; } void CClientSettingsDlg::UpdateSoundCardFrame() { // get current actual buffer size value const int iCurActualBufSize = pClient->GetSndCrdActualMonoBlSize(); // check which predefined size is used (it is possible that none is used) const bool bPreferredChecked = ( iCurActualBufSize == SYSTEM_FRAME_SIZE_SAMPLES * FRAME_SIZE_FACTOR_PREFERRED ); const bool bDefaultChecked = ( iCurActualBufSize == SYSTEM_FRAME_SIZE_SAMPLES * FRAME_SIZE_FACTOR_DEFAULT ); const bool bSafeChecked = ( iCurActualBufSize == SYSTEM_FRAME_SIZE_SAMPLES * FRAME_SIZE_FACTOR_SAFE ); // Set radio buttons according to current value (To make it possible // to have all radio buttons unchecked, we have to disable the // exclusive check for the radio button group. We require all radio // buttons to be unchecked in the case when the sound card does not // support any of the buffer sizes and therefore all radio buttons // are disabeld and unchecked.). SndCrdBufferDelayButtonGroup.setExclusive ( false ); rbtBufferDelayPreferred->setChecked ( bPreferredChecked ); rbtBufferDelayDefault->setChecked ( bDefaultChecked ); rbtBufferDelaySafe->setChecked ( bSafeChecked ); SndCrdBufferDelayButtonGroup.setExclusive ( true ); // disable radio buttons which are not supported by audio interface rbtBufferDelayPreferred->setEnabled ( pClient->GetFraSiFactPrefSupported() ); rbtBufferDelayDefault->setEnabled ( pClient->GetFraSiFactDefSupported() ); rbtBufferDelaySafe->setEnabled ( pClient->GetFraSiFactSafeSupported() ); // If any of our predefined sizes is chosen, use the regular group box // title text. If not, show the actual buffer size. Otherwise the user // would not know which buffer size is actually used. if ( bPreferredChecked || bDefaultChecked || bSafeChecked ) { // default title text grbSoundCrdBufDelay->setTitle ( tr ( "Buffer Delay" ) ); } else { // special title text with buffer size information added grbSoundCrdBufDelay->setTitle ( tr ( "Buffer Delay: " ) + GenSndCrdBufferDelayString ( iCurActualBufSize ) ); } } void CClientSettingsDlg::UpdateSoundDeviceChannelSelectionFrame() { // update combo box containing all available sound cards in the system QStringList slSndCrdDevNames = pClient->GetSndCrdDevNames(); cbxSoundcard->clear(); foreach ( QString strDevName, slSndCrdDevNames ) { cbxSoundcard->addItem ( strDevName ); } cbxSoundcard->setCurrentText ( pClient->GetSndCrdDev() ); // update input/output channel selection #if defined( _WIN32 ) || defined( __APPLE__ ) || defined( __MACOSX ) // Definition: The channel selection frame shall only be visible, // if more than two input or output channels are available const int iNumInChannels = pClient->GetSndCrdNumInputChannels(); const int iNumOutChannels = pClient->GetSndCrdNumOutputChannels(); if ( ( iNumInChannels <= 2 ) && ( iNumOutChannels <= 2 ) ) { // as defined, make settings invisible FrameSoundcardChannelSelection->setVisible ( false ); } else { // update combo boxes FrameSoundcardChannelSelection->setVisible ( true ); // input cbxLInChan->clear(); cbxRInChan->clear(); for ( int iSndChanIdx = 0; iSndChanIdx < pClient->GetSndCrdNumInputChannels(); iSndChanIdx++ ) { cbxLInChan->addItem ( pClient->GetSndCrdInputChannelName ( iSndChanIdx ) ); cbxRInChan->addItem ( pClient->GetSndCrdInputChannelName ( iSndChanIdx ) ); } if ( pClient->GetSndCrdNumInputChannels() > 0 ) { cbxLInChan->setCurrentIndex ( pClient->GetSndCrdLeftInputChannel() ); cbxRInChan->setCurrentIndex ( pClient->GetSndCrdRightInputChannel() ); } // output cbxLOutChan->clear(); cbxROutChan->clear(); for ( int iSndChanIdx = 0; iSndChanIdx < pClient->GetSndCrdNumOutputChannels(); iSndChanIdx++ ) { cbxLOutChan->addItem ( pClient->GetSndCrdOutputChannelName ( iSndChanIdx ) ); cbxROutChan->addItem ( pClient->GetSndCrdOutputChannelName ( iSndChanIdx ) ); } if ( pClient->GetSndCrdNumOutputChannels() > 0 ) { cbxLOutChan->setCurrentIndex ( pClient->GetSndCrdLeftOutputChannel() ); cbxROutChan->setCurrentIndex ( pClient->GetSndCrdRightOutputChannel() ); } } #else // for other OS, no sound card channel selection is supported FrameSoundcardChannelSelection->setVisible ( false ); #endif } void CClientSettingsDlg::SetEnableFeedbackDetection ( bool enable ) { pSettings->bEnableFeedbackDetection = enable; chbDetectFeedback->setCheckState ( pSettings->bEnableFeedbackDetection ? Qt::Checked : Qt::Unchecked ); } #if defined( _WIN32 ) && !defined( WITH_JACK ) void CClientSettingsDlg::OnDriverSetupClicked() { pClient->OpenSndCrdDriverSetup(); } #endif void CClientSettingsDlg::OnNetBufValueChanged ( int value ) { pClient->SetSockBufNumFrames ( value, true ); UpdateJitterBufferFrame(); } void CClientSettingsDlg::OnNetBufServerValueChanged ( int value ) { pClient->SetServerSockBufNumFrames ( value ); UpdateJitterBufferFrame(); } void CClientSettingsDlg::OnSoundcardActivated ( int iSndDevIdx ) { pClient->SetSndCrdDev ( cbxSoundcard->itemText ( iSndDevIdx ) ); UpdateSoundDeviceChannelSelectionFrame(); UpdateDisplay(); } void CClientSettingsDlg::OnLInChanActivated ( int iChanIdx ) { pClient->SetSndCrdLeftInputChannel ( iChanIdx ); UpdateSoundDeviceChannelSelectionFrame(); } void CClientSettingsDlg::OnRInChanActivated ( int iChanIdx ) { pClient->SetSndCrdRightInputChannel ( iChanIdx ); UpdateSoundDeviceChannelSelectionFrame(); } void CClientSettingsDlg::OnLOutChanActivated ( int iChanIdx ) { pClient->SetSndCrdLeftOutputChannel ( iChanIdx ); UpdateSoundDeviceChannelSelectionFrame(); } void CClientSettingsDlg::OnROutChanActivated ( int iChanIdx ) { pClient->SetSndCrdRightOutputChannel ( iChanIdx ); UpdateSoundDeviceChannelSelectionFrame(); } void CClientSettingsDlg::OnAudioChannelsActivated ( int iChanIdx ) { pClient->SetAudioChannels ( static_cast ( iChanIdx ) ); emit AudioChannelsChanged(); UpdateDisplay(); // upload rate will be changed } void CClientSettingsDlg::OnAudioQualityActivated ( int iQualityIdx ) { pClient->SetAudioQuality ( static_cast ( iQualityIdx ) ); UpdateDisplay(); // upload rate will be changed } void CClientSettingsDlg::OnGUIDesignActivated ( int iDesignIdx ) { pClient->SetGUIDesign ( static_cast ( iDesignIdx ) ); emit GUIDesignChanged(); UpdateDisplay(); } void CClientSettingsDlg::OnMeterStyleActivated ( int iMeterStyleIdx ) { pClient->SetMeterStyle ( static_cast ( iMeterStyleIdx ) ); emit MeterStyleChanged(); UpdateDisplay(); } void CClientSettingsDlg::OnAudioAlertsChanged ( int value ) { pSettings->bEnableAudioAlerts = value == Qt::Checked; } void CClientSettingsDlg::OnAutoJitBufStateChanged ( int value ) { pClient->SetDoAutoSockBufSize ( value == Qt::Checked ); UpdateJitterBufferFrame(); } void CClientSettingsDlg::OnEnableOPUS64StateChanged ( int value ) { pClient->SetEnableOPUS64 ( value == Qt::Checked ); UpdateDisplay(); } void CClientSettingsDlg::OnFeedbackDetectionChanged ( int value ) { pSettings->bEnableFeedbackDetection = value == Qt::Checked; } void CClientSettingsDlg::OnCustomDirectoriesEditingFinished() { if ( cbxCustomDirectories->currentText().isEmpty() && cbxCustomDirectories->currentData().isValid() ) { // if the user has selected an entry in the combo box list and deleted the text in the input field, // and then focus moves off the control without selecting a new entry, // we delete the corresponding entry in the vector pSettings->vstrDirectoryAddress[cbxCustomDirectories->currentData().toInt()] = ""; } else if ( cbxCustomDirectories->currentData().isValid() && pSettings->vstrDirectoryAddress[cbxCustomDirectories->currentData().toInt()].compare ( NetworkUtil::FixAddress ( cbxCustomDirectories->currentText() ) ) == 0 ) { // if the user has selected another entry in the combo box list without changing anything, // there is no need to update any list return; } else { // store new address at the top of the list, if the list was already // full, the last element is thrown out pSettings->vstrDirectoryAddress.StringFiFoWithCompare ( NetworkUtil::FixAddress ( cbxCustomDirectories->currentText() ) ); } // update combo box list and inform connect dialog about the new address UpdateDirectoryServerComboBox(); emit CustomDirectoriesChanged(); } void CClientSettingsDlg::OnSndCrdBufferDelayButtonGroupClicked ( QAbstractButton* button ) { if ( button == rbtBufferDelayPreferred ) { pClient->SetSndCrdPrefFrameSizeFactor ( FRAME_SIZE_FACTOR_PREFERRED ); } if ( button == rbtBufferDelayDefault ) { pClient->SetSndCrdPrefFrameSizeFactor ( FRAME_SIZE_FACTOR_DEFAULT ); } if ( button == rbtBufferDelaySafe ) { pClient->SetSndCrdPrefFrameSizeFactor ( FRAME_SIZE_FACTOR_SAFE ); } UpdateDisplay(); } void CClientSettingsDlg::UpdateUploadRate() { // update upstream rate information label lblUpstreamValue->setText ( QString().setNum ( pClient->GetUploadRateKbps() ) ); lblUpstreamUnit->setText ( "kbps" ); } void CClientSettingsDlg::UpdateDisplay() { // update slider controls (settings might have been changed) UpdateJitterBufferFrame(); UpdateSoundCardFrame(); if ( !pClient->IsRunning() ) { // clear text labels with client parameters lblUpstreamValue->setText ( "---" ); lblUpstreamUnit->setText ( "" ); } } void CClientSettingsDlg::UpdateDirectoryServerComboBox() { cbxCustomDirectories->clear(); cbxCustomDirectories->clearEditText(); for ( int iLEIdx = 0; iLEIdx < MAX_NUM_SERVER_ADDR_ITEMS; iLEIdx++ ) { if ( !pSettings->vstrDirectoryAddress[iLEIdx].isEmpty() ) { // store the index as user data to the combo box item, too cbxCustomDirectories->addItem ( pSettings->vstrDirectoryAddress[iLEIdx], iLEIdx ); } } } void CClientSettingsDlg::OnInputBoostChanged() { // index is zero-based while boost factor must be 1-based: pSettings->iInputBoost = cbxInputBoost->currentIndex() + 1; pClient->SetInputBoost ( pSettings->iInputBoost ); } void CClientSettingsDlg::OnAliasTextChanged ( const QString& strNewName ) { // check length if ( strNewName.length() <= MAX_LEN_FADER_TAG ) { // refresh internal name parameter pClient->ChannelInfo.strName = strNewName; // update channel info at the server pClient->SetRemoteInfo(); } else { // text is too long, update control with shortened text pedtAlias->setText ( TruncateString ( strNewName, MAX_LEN_FADER_TAG ) ); } } void CClientSettingsDlg::OnInstrumentActivated ( int iCntryListItem ) { // set the new value in the data base pClient->ChannelInfo.iInstrument = pcbxInstrument->itemData ( iCntryListItem ).toInt(); // update channel info at the server pClient->SetRemoteInfo(); } void CClientSettingsDlg::OnCountryActivated ( int iCntryListItem ) { // set the new value in the data base pClient->ChannelInfo.eCountry = static_cast ( pcbxCountry->itemData ( iCntryListItem ).toInt() ); // update channel info at the server pClient->SetRemoteInfo(); } void CClientSettingsDlg::OnCityTextChanged ( const QString& strNewCity ) { // check length if ( strNewCity.length() <= MAX_LEN_SERVER_CITY ) { // refresh internal name parameter pClient->ChannelInfo.strCity = strNewCity; // update channel info at the server pClient->SetRemoteInfo(); } else { // text is too long, update control with shortened text pedtCity->setText ( strNewCity.left ( MAX_LEN_SERVER_CITY ) ); } } void CClientSettingsDlg::OnSkillActivated ( int iCntryListItem ) { // set the new value in the data base pClient->ChannelInfo.eSkillLevel = static_cast ( pcbxSkill->itemData ( iCntryListItem ).toInt() ); // update channel info at the server pClient->SetRemoteInfo(); } void CClientSettingsDlg::OnMakeTabChange ( int iTab ) { tabSettings->setCurrentIndex ( iTab ); pSettings->iSettingsTab = iTab; } void CClientSettingsDlg::OnTabChanged ( void ) { pSettings->iSettingsTab = tabSettings->currentIndex(); } void CClientSettingsDlg::UpdateAudioFaderSlider() { // update slider and label of audio fader const int iCurAudInFader = pClient->GetAudioInFader(); sldAudioPan->setValue ( iCurAudInFader ); // show in label the center position and what channel is // attenuated if ( iCurAudInFader == AUD_FADER_IN_MIDDLE ) { lblAudioPanValue->setText ( tr ( "Center" ) ); } else { if ( iCurAudInFader > AUD_FADER_IN_MIDDLE ) { // attenuation on right channel lblAudioPanValue->setText ( tr ( "L" ) + " -" + QString().setNum ( iCurAudInFader - AUD_FADER_IN_MIDDLE ) ); } else { // attenuation on left channel lblAudioPanValue->setText ( tr ( "R" ) + " -" + QString().setNum ( AUD_FADER_IN_MIDDLE - iCurAudInFader ) ); } } } void CClientSettingsDlg::OnAudioPanValueChanged ( int value ) { pClient->SetAudioInFader ( value ); UpdateAudioFaderSlider(); } jamulus-3.9.1+dfsg/src/res/0000755000175000017500000000000014340334543014534 5ustar vimervimerjamulus-3.9.1+dfsg/src/res/instruments/0000755000175000017500000000000014340334543017127 5ustar vimervimerjamulus-3.9.1+dfsg/src/res/instruments/mandolin.png0000644000175000017500000002674614340334543021455 0ustar vimervimerPNG  IHDRU&zTXtRaw profile type exifxY$9dq:8Xsy U""zgh:=\M@f,_ΖML斳b>x>=|s(;<?ϟ_yh'3Ϋ#qܬr# zg(wDfSpQn|ZYG O_{FO)9BFb!G2^+ig}wIS1rűgm<^_Rnr۸ZC{ 1xn>djh}5F?zo?\>퍏'c ~>?~to J c?}B\P K bT\n^)]2[p ]{O鿆xӽSZ.<'|#8uL!7^)iL<:a4UN~(Y ]3\~ _!qBg#r9? ? !ޓ43:^_C{7~GsܽCYyB}ï?Ovw]Y==_߄}46(#"Ϡ6R1m }=7\#?O6Hm Fs7 ||[o r(I&@y`k&be*ck@D]re;~xKzn{޼#ؾUoFߎ;wS{n~M}e>rC9"BI}~r|G; g|(ID=]ӺkixGdχ}FPXa1/K%Vxy][ʟʧXr{4c)k& wmx(tGU4|Xw=|Fd]k$2n|_vc?>ʼzGA{KwQL~n?޿܇gZ\Z*7D`6DH?I̿У~V?׿Dh͸$- >W{Oޙ7 o}'L5Ǵ7"6WA}NE慾m~=O>m;_|P^n]Ks+>R7MY}r{zk)Gu]mɮXBWwU{WS,k9}5J~cJroQUAխx ~s%fc~Z}_s{'}iӍwuqgiF굙M{Go|nV?K7ֿ}q'WsU|;2I}L=^^C{Uجf]兾__OES?}O7b(ii~ertka]dۅϱv7]T7s׾?=s~ڊq=0:ܯ_.Z[ v;sWp] g+G 5-:.3}qC}z7S~۟]$ CJCwv/~qDkTr年kYaVW8{^3Rp mSY`c׮Sܛ˕Ks vG>aU|l3eoU<͓c1' qji4V'kmf;LצuX>h]L|?Vw50I!REV>c=Xڨpy 5׵ nN=am%12I;]kiFoўDª҆ F7 I;fÜp5xqkUfvԕ>J#RҭE%KDBc(R&i q?pZ,grY3n3KA*Q[Utm'IJ1wM# :T'cC5mWjS3Jll&><M25؝;S:LwraBLMvrWoڎ{Qʞ.&(b.wŐr {am/'~o{ges O=zb}หP %r"|?,yr\K=20KۯO ̈oN==L,jU̱\&9dC=)BI1@FGT\,L ?scvz[{)$JNk  @&U', ml cQ̓)n̮S%.A! @`a:{GXdydm_;,JGX̣z*QР6`Rqavlvn$40Lɬ&TP'}qqD.֫W񟔵7N:B9椴 sӪ]`R+>JF1Ak*U ՜BF`>#y&憑 X#y.j4FS wѩ.l*eZf"+s¯-_iÜ5jM܆ꈭ8$?8Q Aj@̺%xxbtr]W?AX01sJ`)@"UQN$39jM6?2AlOQ ϒȥsRα3ZHp#LM)(Tku.7bz ”z /?ޖR/ O%9aX SǎDz1 JܫYG;6820"Ups7Kl|n,$+ f  OSjqt ٝKPJZ}[,OÛY0M` kmm&=(LP6rAA9uU]Kܙ4 DXwP'LOH`\;E$`'PQ/8$V; 2_K:(ywLL*=đ&$B ((gaهz"7hZ}B )c E1zh4XTR{9Vk@LK3 G0$I݊A.@[.W ` <4_D*1ȳ\ɸqh5|=hDtG~9ȹTb0PQ o1L*FWA8d%㓎뗂/Ƅ;xγ@ ̺FC5Mm?bTp>휽+!ݒsd Qy%IB? 4r :Da[㠖\`7M̉ZR K8+Sw@R6q 6+ThI錢WzV.)WRֵES%sExR gļY% 6g2}-YV:PK^ +uz$O*cˑ݂HRѻ<%C2㔮Hu\ A>U١VQƜ%qo20- #1+^ԣaW<ܾ B6u_ a,Zav-$`A˺JWojWK]]pBN Xs8w) =R}//k6$TҠj358|@iTQ@[[ 1auD\;uu- DMcOYӵ47ߩ<M:" + 5eVsICOqX!h׬z}AE9/yO9 H୙ :p.xe@'䈠d5Pm|ċKqisEB0nj{Ä'0suD\HQ31_p.a|ZAmMF6I(pD2Y$1yYH)9BUZp/`5+$͚ಥ'y&OV7‰6H%ㅺ$;LZ=~UMh$,pdFGj'vnkLŌv;-ᤡ0n5BKJ8tj̀ MO."Z:XwࡖMy+lU2[!WN1eZ,™vڒPw".i1d75x`A2WPZ6ʱ9ƀ0a;S"iЛRaE ]گ+'CRS^b^ NJQ H@:…FB䛥!g z: {ݙUru~:9P(!]yIl%]4 H3$άIE6U|दg`U*L pARD4"(ۂԥ&+q73kOP#b"7m@(~8w^m'#% lZ-Zb: {wI )gdxmwo9nTs1a 8m :NE CwЁ!;/Qc5ݥ)NMð #In(!VM` PwYt2Ԣ"^:@2Txzm8rln EjI;ӑ8V;  F"@I +H~>o".AT7Hvxv+6 +8 [4ܾZV5ս 4ݐu)j J ɨPl"Ei^!Q$(k'm@m18 oZ|ޅ̮mA7 SIӢ8ZIPM@k+v7AY @*ǻ_E-H.U ujJliA p-}P`![:KY\[uiUINW>x'bllוQ}Ypq}{PŽDZf nitm/9*#7]DPTiC[=.K)Arԉ| *#!Ы"밥((ĤGh[3Z9O-,텉gDu'Dx uGu \MŪFUl25-9@c 6(/ ,=8pdC:%YqL8Aᾅ6@5pZ*RkQI3<oQ>B 0l6>朩rq7% Ymfjsix1.5rSziΚ3Y,+BR,aV3V[_ks6EQZ@0R`Vlރ*Ӵѷw_R#Gk ;xDJ=!JK z7 HצV`Pth AD c3+O[p"4!i 7qe*%\2CZ!3ǥhhi~`'!=Д'ӳ%O5(XMUQE-t/K(uo jR"^IPbx$ӏ PaoIP+ D:Nuh|Ţ!j& I0- A#{gKhf>ĔR( ϙVr@t6mu֥ S.DzzTRPFծѴ8Ț-\VxZCKi{D)cƠfp "?Sl pkpwxχ,mxaᅴz4'D і^y7N-?Y-^&M1ōH05TWMNFŽEa`VD">G$uzSdOPlA٩g^yhC\Ҳv3M, eN-BaMCh\;IYHMOx%q +`5MG_'m Z\J4!VA:1=I(ebF] ?FHw[n2myZv-hZ8NdѴz٭WM'MmMgܠ[m_OIu`(֮j$4r K ώL5E8Zj5ɢaBN(c+3|&I <*?X/@c\thuҮA &@D2D^+jc6hP=XZ.ڽ7XxH *A {RKH-.C>-m2e{Vսj?C_ژ2}3L596O(!EniQ< #CH.ڱ Q"r L@YۄHVmIÛ#FSs)ڇʜz2f!8Qqk$cq Sat6˨܌wWTķ(tOМ憲M;w*k"9拉7U/!In}C0g@tKdVsCNM0*zڅjpMFNKY`@JP&^WbM|T4gE.3"(o !GrcHdE_cAKƴqDwZ|S'! zx9[[ЊVє[mm"0(TQB4H&vR'lr2D2+w$2c1R<&Iq;[n%l>Ũ  +=;Z7ls<=6 rO<ANZ jѾAߜ7Cғ(qFp?j"EJ:h'->"݂괾5+ɩ|wOAY6}P$m*)|r@eX6}zJ@FFjjI{?Hgn߂B(a}-yd.Hfԧ#(MjIcsu(Y|T gY&̤ZY>ʌJ,@};]5IvMݽ%jf)VLIԴzƤJ )*)r2EVsGE{HsXAZWU[o h $*"D)4ݵ PBN ؐϮ[SvbLiA#>[G6>V QKPC=Y-YmX\G[`̮n~2B4y^<+ i. }>jjLKb+ r ݺ P<$].y $h!u#h+1NSAa,2WZ3rBfCZ8MQ_m/`?}?0iCCPICC profilex}=H@_S"␡:Yq*BZu0 4$).kŪ "%/)=BTkP5H'b6*v"00L}.Js|׻>S&|", xxz9XIRω #e8xfȤCbf%C%"*FBegRc{2i#E,!2j( 1Z5RLi?8drȱ*TH~wk&'ܤ`н 4}l \im|^ok#nkptɐOS(30p qd pp){={d3rᚉbKGDC pHYs^tIME!_hA$>IDATHǕk63^I$6&[/Li&E-+ RjE~A惂RD[(Ezд&&{;þk{9?sy;bĘd0 F|oػےC֬Yɑ#<@pKngf#wzCL36mXO߿BtvD9L--W} {x]Ύ 8y֧ ,wwusMvd(宼xWRJ;2Xa:8*&ԥ 9ϝ-zƜ3P@n;yA/z- f 9Z\\V'F^ 4 kҊb0d[ '@yjn=Us)[xl +Š0.?su>o6Ƙ`!Vh ЀoV]rXYIXSI[ww<\Lx WCxh]"tu + oGc,=ƓϾT#rHW=If L" P[-c~n?r'KYN/ݿ64QBFe-pqu(sbuݦKn10v/6R+HPp*9qxt-6KXvcgrSԺd@iM[m_P9SվO4mPgbBNC/p݃W8F ]ܴ`-:'Ǩ-qADrӌVi@_ !Hؠ-t.87mq~qje>5Qv`C@I>Q)Y*}Q%Tf850޸! dga0p@M+MpSMS >qQn@|.qߢPLvEMgPgM*+^UףP$=vO㸂hZ~V)$$/`Q|ŔSԗoB!Ԃ]_ SZwۣZQaN.S =[ȁrf=<kN<ƍQ#c$yfIENDB`jamulus-3.9.1+dfsg/src/res/instruments/accordeon.png0000644000175000017500000000371414340334543021577 0ustar vimervimerPNG  IHDR#pdD7bKGD pHYs  tIME -WYIDATHǝkL;3̕Yg@ԅ:K+Z[*ҭ6mm6&Ԛb͢[4&5Vc*7% 2 s=0/7&=ɛI?sW%`6f[vyv}lbb“H$^*,,,ϟF@88[@y@RW5Vx} Y@|0б~l idR9իWeee ^Ob<== p8 H>T N}?Á f+@xA ~QTٳgO",9"N8!D8 )!DjllL466 mvh>[@Pw[ZosQ!; <&{`A?NSSxqyH^-[ N~#}z?3Ñs88h~ ?sIE@YYj8T*JF@kF_^Ȝ aVl6]v!R!%'9c[ػl߾˅lTUU199^)z{{!3̐_0zjkk1L @Q ,UfRDZMee%\."n!PT&P*$`.' r!'O0O //zN'dχFaժUHD~~>Ѩx Út܃0CXSNRC c6I$㮯_\ d6)ٌj6, ոnt 7,`UN)`|셩@Y9s %%%'NПL`XB`immERa0t "t: wy׮_GA}}=GeХ|\CjehhE-Ivv6Q_.|4Ȉ?wϞZ͎;@c(c:̺s"x2ʕ+XVn޼% R05 ː~5R^ׯSZZ j5J-QFd@h)/vZZZqFmI-ϧ <GҩlJ's^^"B@D%077Z @z+z0<1UȨT*rss1SjMD"\v YUr:N $V -[˗ (A؁sىEM4 Lo^6kN8e "2,xعs'>v ÁL)Rh4r)&''!Ja4jxXtN2*p>b{ fʍ *++ijj"Ld(3 8 pZjeݺuU{uT##g{=x%%&Xp8Lyy9P*gfPs0L*zg/::U>K@gɠ|0b1Z[[Ub"߽!ؑ5/j~.pO Z2 ..{Cv=RTT/,, [.ǐZYc_QUWg@TFϷ ,dݬ/:xx DMy? IY8IENDB`jamulus-3.9.1+dfsg/src/res/instruments/congas.png0000644000175000017500000000375514340334543021121 0ustar vimervimerPNG  IHDR"nbKGD pHYs B(xtIME+#zIDATHǝip]e{]lM(IZ,l -3~0##J-8eeG؊u)~H RtI If77swIE g{rOl窑.DhD)@_=_Xsq>MW0< ,"*AjpXۧqOa_=O_bOO1:7ߋZm[KE DfUmk֬ }t۶3R_IDﺵS]5 h4J>%Hg0Vwl^yׯ^?cj>fl ફn,~mE/GYӞ2iʟ[ާjFUgxf8R iLxCߺFc>a#W8*_^R#chBRS':;xYQ= EQ^i 5Af|k6_΍MIi)h1"Ǖ޵ XEU~νj#%TRzND d|4zg97m|crlScCoߛěJSc$Fi݇^se:3͒RLM;p{ma`!KS_; :\YUHpQZKwЌ{9dG\wi8/LW,i[„* ÀCUq"tGD ~u׻!ݣ}eY@mVni:ұ2q2岕 &878`]\!K*,H''kfD,SPx;D;V5">.)6C!'9Ӆ898ha.V@p4xff{sNB^,BN l^^tBF_tGa-B`wSx6UK%n(#NwOIDATHǕ[ef9nwvv[4CP!"ÅDL Bb 9Bp!֠ ;f׋SB|n?y>}Qv CJccCS/~fW A:%Jf'-_qpѢ_B}&lΝ<<cG҈B!B@EH!H39Rtd&aU[[׭X,6>622?߿y:ZMDHq`?"+MHtvRiDqGx \w߽YHB(EBWĭEowX[7FHL['$+/t(!4Ѳ[_[ɏ; <H5DL(:tXPžs$9i$1+Ag&N1cҙKa][E3{^NWmڴ%K,6SNW>o'Z\hE,Bo\BB7Lf<#Iɀ>)CQF][>p/O*pRp|T{\ =WT# pXZDDht,^JN&iOǑΜ )-Z-/21>&n%_(qs F{oNB. ޚ#+_~/J&SAW\*b~яQ*Nm3' xNSN߱}{ln(%@$,r*(rI=\tKK.-_J"k*\_jhA87O3e7)z\;pLp#7Xbjp{R$237xӪa۶m^rov@^ADR/GWdo Z3x*Sfli_k #!KNm;w:߰w<ܹF(8>1Uj|g70iP+I(RW]z}3OkNr͏xt =w _Gixn28ZTԧ !&SQ/N?cSz+]GIENDB`jamulus-3.9.1+dfsg/src/res/instruments/vocalalto.png0000644000175000017500000000413514340334543021624 0ustar vimervimerPNG  IHDR#6sRGBgAMA a pHYsodIDATHKW{\Usfξwnq۵4VEJb1b&*Q4&h[51c#FL#mT[n}}3Bm/;*(0'\%-hmnB" CX (B/)H'S*<DK q'~ϹYmq@U"B[HRB$X B<:}\yF:L >JC܍{?+_K FrD?97$($`;e" p}|! .R ~x-~z1ah#}2 sZPqm8B1OY1dyrDG@AY9qQPxErNAhW'kK1^93EdU$ʾ !f0yGnA֐؀Bը~(3sS)RxrՃnĐ \gf[Ͼ/`mmA`n`0tk/7?:򻡝PԂ0\|rk8xQl\[_Y }]B8uĨSο#9wr54FNjh`bGHƌ|@`?ď|DaR=p}uYY婯oJq\@}$<ڕ 4"W>ܶn4>jd7abs~Q<)f}>$^f`I,^B V>fauS76 b?Go{Ɔ6N|%P+6J e>/j”eumA^%Й WmFDQi*1O&).5z QD"d)BEb.nVpa,[ 졜EP-!hJR n쑄X`}ZfD4Las 5Ӕ$4xj%BuKQe}nOHзV-ύ=  rRlyf(1_A7Cu0{Ǥ3 <`~#jL?-ci HP"v[fJb 'Sa7Mb_Ub00]D皓:J/ Qe!e wDhYIXV$MsgpJECGMSfa o zZ,=)CdVtc\.t&[ؚ᳕}Ę]5@s>! ͙O;gA#{*gV6bt zm6⩯-M[jR&OZl'a| tf0] 婑y"w / .{jKp"& |v{)X _|-%~cyB~RMHdV>|V0jaqXr}4o7NA%h|ّJ;,9.nz_=k} $PJ1B+]0g JCITM~u'? 躳8u(m.*^k^Q@jŠ|Q}pf8tROhʈ1.MHl`3gSuj>661qEeqf-#IENDB`jamulus-3.9.1+dfsg/src/res/instruments/saxophone.png0000644000175000017500000000236414340334543021646 0ustar vimervimerPNG  IHDRbKGD pHYs  tIME  ,IDATHǭkPTesrY@Xt1\73J,MmNY:R͖c54i؍6Ę@S% *+ !.9aweݳ{elA~yC>߻yY:0'4q5Up\0&rQ sMZ$Uشk\rw#aF4vKgY,{ȫ&>-PY_+W+aΥ9?_0ENj(}UTAalxHVut::U$ iY<(HG*]'M_u!*Zv y}<ûǐG}a37Y=8t`_O"0,tn5E.R &v2r&p칟_HΟ:zzK3ng2Pp mVHYVTJ;c//< %Y-f(a5/ ,Yp}V]9)RRRF ǣ7M`b/*Nw1᧐⥭S;3R#:m (AD}2,0(>Ⱦ15a3*klT#Hl('"@wlDxg|u79~Uс [w/Lrzʉ>?X8fn=as%f70:[=-drQĬVg.Z(cyJ& PM>tus$&iC,2ŪTm#9ҙ{Lj ^w{o@7ÿ!Ͷܵ60 .YA9jݸsΊv;۬wV]h -`8d2MF莇ϼ2"䜔=ң%992-ĵ@*X <l{(;\NDX =-+5)&S]6_e@; ]7?HiP)UPx7&_P*Q4ɀ"efk$4eus_!=^CtD}BI0<㸨K wBVk<;H(~Ns2!;Nޓf䯁BGQ>Nn<؞&_  @]=쬀m(j`7G[yV5q6#}a|,K[n4WT o)X24IENDB`jamulus-3.9.1+dfsg/src/res/instruments/doublebass.png0000644000175000017500000000234214340334543021761 0ustar vimervimerPNG  IHDRbKGD pHYs  tIME 57oIDATHǥhe}w66N]cGfK]ٲhcjb gEKE4IVBr2B!KaR ӥ9&}?jxyf{s>ٌ1kc~(+޺zO 5u0uC;֖mOLJh'Jx HFF[1۶4?ס5X}z5lXzllؾyӦ˞p ~ݺkdE/hh-tv`7eֿ814¡qEWh~Oжi ; 9bf=h77՗G|oQ3~|Udp7w-8b8 p[M 'D ~G毛@omߟԕg2Xti,K1ȍXWdlǞe0!ްjP^='ӿϜYpuHU{ ٮ6#ݤ(YJ$ ;Yy?p{7giSkc X3YTSV0$(f?L*|A`ǎݲ1w,oޯi=LG\qU: ?EGPSƈ,^$;wȤȒ i~!"g 0F8B[0H[ey?{߹3 "|s}=(ܷC!40>1 \Krel|T: ᴠc(J1j nZ/xB ?CȟLBP~^f!cF3 X,j@08XC;7! Au[h0Kx,E |'7'ZG%W+Y򯮃p^ :Ξ{ Mw݉dml@\G&`he/LD8֋nE蝡ڵŶ+D޾޲Q,ЃK6M||F,ȏ_B6CH8X !."31f'P6aUkT'm?~\RZ*-{zX> ¼~k*y 4q\L6Hehf C4Nk B 3 ֮wNZNu&_Kz~6eyT_m"lвPd ʶ%>yk`"cT)ct1A jm(TfYޏZ9_io~ :l01~~R8l\ ـd(Vg6Y{ [Kvl[C11`nr|ؤ "*NOwܲ]!Gc90>" `~NlIdXwJGJ@蠜ķdkrWjg$Ac>/5(D Uإ9nAR:7 U)4&r7@.chC""lrda(",E{|~ec~=ok!jv5;>GyAυfC*2I=iQ3l/-#"BOxڵX\ 2<~|;a2"<*j۬Wނ9]oADUe>tB<\BR Ӆ%֡>{vĆ<}],;6RLLzVc&̗ -,ୃ߿buP0╹%$&g(L`t*xf$\ v@?^6#[G]>*gQ:!2}S(;?sa#a-B,|_1+?]ǼUC\+dۏ:cR1Q/*24uP?n~56cz )5ע[ ӓFZFKpu35si aǁH xG[}-^a} v~sh(YnmIENDB`jamulus-3.9.1+dfsg/src/res/instruments/bodhran.png0000644000175000017500000000202414340334543021250 0ustar vimervimerPNG  IHDR bKGD pHYs B(xtIME"IDAT8}MlTUy3Ô)+Aц`jbb%$tM.\ʆܳ$.D"n04V $bh;ҙ{ԛys=Gp @$D@rBN+[ܹ{7uׁ/g=UnZ,p>,dz(jya1e>N·ޟ_{.si*Jh-/ҐyU׹ꉱ^?;Jcʗ/_V~څyl3`*[o<>CѸ?11AV㌌|嵠1usogRvrwzquiGrǽwŦԼJQz[IT:ԥkxV z 8k}TڵK۳gZDc lYEQثEQłQ眨 O4YuR?QAD֪:}(i>LoIPuxoh OW @ģk5gŽA1KX`US%Q}3sn]@E PY^~!y0TlkFQO3)V]m3W^NMMh(Vuɘon7LeYRfP_..^k6\t ѽ ٖٝ>nKe vh`8==ͅ s)F  LX)ܝEPW,mHcG;AUcZr9V{,יY>rsΰ`dEFWzRm4q oٽ fGvpb}L|bd%}djV/r!_4Sl"yg^4@d9)?Ky_/uϗ q9n瞇wdyBW"Ҷ8;zȏqhw2 "&Bm$G`t1giREQ\ƖIAQbJ@0 rŝL!2 Q`J*^Li[׊FMh `LPKT^]H"$JKM9GSoLy>Pp6^XNLD/R g" 89CT뉣(8_yD`w̘#Q/nsF*  UOQ:T$"|z8'9VARTºXfUIa\&뢷p veos`r.&бAdbw*'z*\*Eb*TI J :Ԉh#qR'65I2h5ǒ*AaB6I Y=Q尩$`06Du/Y$jxL^F8n) t*" {UD R]g2c nŷF_׀M(*Mdjɑfgiqy+ԯ(U7lLs{T|4DdWD9雅2:/`҂uC{V! t'N%3.Vè5RZM\tfEnVLbCQT:dd3q2$&v@jۀ?b!ȟCj/}n:vZ;SL͙h8V^!E#D,)p!Q5%U.yj3@5|> yB6oVxBV;Ů ̲"hxY Ԛ\D*7h%ʪOG5xWW@)Ļ`6XL=OKͬQ ZV`Y5M9qDC 2&oK>R[=5O-Wm"70f IENDB`jamulus-3.9.1+dfsg/src/res/instruments/vocalsoprano.png0000644000175000017500000000422414340334543022345 0ustar vimervimerPNG  IHDR#6sRGBgAMA a pHYsod)IDATHKW lU9no{RB1Ș:(ḻ͙973mز]e:e&*-N7&S3ԲLX""Xju{_{s[ TC=U^޾-&UD\¼ZP}Ɇfv i 24\рL"DJ?xX(uXۍ[X+/X*xtRT\ S1ضuQ,Qm<®лkVy\// IA&J%خUEebZƉGr{Qwỏ\?": ղMXR\KƐ+"<`l.0U@&G)?3k/bQxNRT?W GC>>TD-C2?}0Z`Ll jamulus-3.9.1+dfsg/src/res/instruments/djembe.png0000644000175000017500000000177014340334543021070 0ustar vimervimerPNG  IHDRbKGD pHYs  tIME 5 IDAT8˅;oE3] A(rsi"QQPPO@4 H4B+ N^CsA8S͙9ϼG8ubJ<Ӳ:RVF7L'$l_Yݕ/Ni|rm^Z2r3&<^ÛGވC ePVSe\z|!0rE`P86'Q#JUX'1 B=,Hj&r{Pxã8^fb0TPt :y<5"WEdV W 0,=wM+ RKf Yְd!Q`PzPa+8\;.eeF;E5 r=rtyg|DtTW.`D7q,cR"`ua{T9,dž+³ǤV/h#=89\3Wwǟo'NJ4E*x6v'lt'ћ:M_+ Ks SÙsd[jQʥɧ7v#"c4"ґ!25fbZq{\}F~-"cN6A`ϰÏV5^gwչfXn&ڇUYjVi Ff@PAcyz=`0,=vVUk#(w1;T4azȴO)OM?iLNE$v*ۢSf}iN [Atqfn9MZԭZr=^IENDB`jamulus-3.9.1+dfsg/src/res/instruments/keyboard.png0000644000175000017500000000167314340334543021444 0ustar vimervimerPNG  IHDR#=<bKGD pHYs  tIME , `HIDATHǽMoEx1q!"$\J"=j7"8# P JTAc;ip8L'Z7`eS#_xc`[֗HD^c>ցwD90΀YM1=089eXZp?@GDN'S%"-Uſ?~ 7 F bַ͞OJPgZ&Z0:&,.߮7SVEd!ش`Q zƇɆ .tZ06 MT(vBW`]f5 SF7„N24< #"s :e$0u:a)p>LPL(]΅7o~ "84Ț>sSӲ,t'sm'^.`.nYaPdYt7qy'BmkK4q?UԹWp*4q'14/-I\ӯmJ0 5UA X.u9j88F˔=^r2bKGD pHYs B(xtIME tEXtCommentCreated with GIMPW?IDATHǕ[]k>g>grf.Ӏ-ƈRCQBlI /iA|m+Z6ę99Z}ؓLL&Ya}\zn E)D_9Zb_^*/ZTKJ,!" !n?9:հg<.[ms,D &r,՚A>|?4L9֯)F& > X1QCJ~O([XgK-eٖ'gb?xKSe[wmaK%%2vږ+ !fX۽H)SǏ涅C\S`I1ȧZc[JGV[p˱$Z>(l 7/pߟSo6Wn-c nzM) I5: )E>= -ݶΝ>J'2 aFkfv[SE޽˕Ϥ읚޸$L>3RYIGO_:_|͊oWpֻw7] \@gg>F?b.|gS)B 1d`~p~gI|'~:{cm7dByV./<,4C \,mOt~ޛk;c ~>iooX73uqR}ercE?~o@R>voulӨ:ܼSXet'? ~9۽SZ.,!|ό{9ZBףJ?YB7؟6 Hoyo6o{=uO/ 맩rt3 +\~_~  fׯwץ |&9[E+6ǀ+n ftn;zoE~\wTR}wiv~y 1 t}Kct"Oc(o_kn_?25L,3b{ƙgF)sogg8ۚ|/)u ] m.'xMطkϣj^s;"=u%_ %kbkϙ3?oŞM$IG/Dq)Hݵxt12^ѸyPg0TX`?RvHo{6ZߟT@?x(39*%;~cؔ(!فvx\b|zۄZ!1r(|G}(?8;)jW^u*H0^iۍ3eWtn$ahczmw;bRTcvFm_h-D/nF^u|¥ͨutmO_znϩ .곒Ao˷#y\WEpk$nnn2g Zb!ZXl \T̍v[R]?}pt;z:Nf 0}KQTL[Y`'B#_u1+뫱 NL\`3h#P|qCxVQp)$=(Mw_74\E+8+e9XN)%/R8&V}BǒJ.JĚjjo[jp޹ggΛ{5+Ï0H#2hOgƙfef_~WZ@&vi]̮~N<ӧvܛ kzJ+_^j)sjh& J#|fsm}&1<3>;/\ܗ.oWB d}P{H>6\|jqR^> J%]OMeW#nw#\3݊nL2XUDQ7iyN^Ai\S`&1{wsO]sn>0qgSA=nb&c c;4^`}pVO>v xNYewX$LB<B& : jrGڞ^$Jb޳y9쳓3UP{,.By^[r%`DJHwԊD2YMwo"A`s] nQ-M9c N$uK`;̮.2@x1| N #̶.13xxzcf&?آ>CV/3˞cHCMYNĊ%תsP0djXb^xaC!&G.ìw~uیH!a ViT:Iv tޖ4!lQN8썧L'v۩{pNs.wfKa %PCg6ȬZMw/J#Blbkή U oENLstT vmTk,1<[p&%Gs4iCo|$ ⛨z- "1ץbFw^+]R~QGӻrxd3E0'V O7i՘ q*ҦCH/b߀,=uM!e 4ԎHZ7f|PiZv(?Kty7$/,YA̝ĒO`9`~m$CmΏ&q4 7Hn s]"0AZY0G)$f|8d;WqT({5TsexS NJJ%ZÓԛ<>nl9dxI}|kHI7]2T!qȄRӍY`*Y3Cw=p %P`Hi ꐼ@Y{IQ pj 7t| Hfs{:Mo.sF*Hf [t+?3` y wCA mdTzp3œ]m`b`QSj4Qe'լNSi`˪}a|pScfo #|JfboܚY;"@V"zR#&$Z7$oBϪ p[O_r!7a"0`o*CߵOd2tfa)b nVӶVE& TvŢB+pT3{Љ{Gؘ&AC/?^QI`) ᨼZ;6Dks^ sz<G.X'FfAu0jQ'O!wƒ -yd2X?ᗼ (5X8D{=]),Ly NJOɂv3h;k1qghUVXt[iĀ@/Xa342DЖ5'5\$ a.7@с~'9S`1I;T: *2],hܰ*AJ_nJԌ6#2Ae$n뒛ZzqGGqCl09&D7UHjCj!9n N ꉜë'z8|h&*%raH'JVAufq9Ga&)Md,T>Qۂ١G\F4T~9a:ESK TkRC765˕r:dTE"dLm0ߘrVpdáq6Lq)ةAБ+[zP7 S"pIT  C`̃w T{aigTg!T$:%J TWT+*/G!@ZHpE'R *`9ʈ 2Ʊ"8#@y$_M+ K$s FG)PrU y=[l@x0\Hde)VT}0)jy&{K b2zx^*Ȅ\U+k =AGRYhnkڜ`WA/.3^b;E(tShhm0V;1/ =;G.IA-. 30 PDQOq^aI@rI*m%<@pQЖV#>p}x|p <&b8c 0BB4r? &\^^ECV)ud9-\z2QׄbNFG|,IO+=BR )DyP*.MBxȉh³X)44 S uPT-R wB0=I ٔ8솢fm3E~Sd 0JR,n.:T-cbY,T@|;_D *ځ@[\GF1jOk{D6 ^^d>@X F5,j[/52ծ[@C< FDT<r]`(jylFHdJ,AT@S TȂ_ݣ@1/PN= /2E0e @:UwKnsig:CNK*\PO%SaJfQ𵉇ȫv.XJ#7`vh#Hݔ~r#`BrWYrx>Ԉj/N"(2@ÁSY ;(7 !žąE,ۣP:{4_4X3'. r e :Y!MD=ž7\!gƱgD eJ6xsIJ<$ϐ7 LUoǑUBj1V)(;~  | [t [EJ}4 Y,(dŧzXM*17xz0T_`1@ȣZP$@`WCi?rXLꨋyNn(Ts|d!PIC5=DezmNM=tyx!}ҽAiB4$|,/(˻k 6=WAb,%5_`e±ik8X@Q|+&0㣮$")q}Śma$(I7U!X!*y=-[HHJׄqJg)aǏf T)l#ͮL\`=G$p_*#u"%_ ФiAj" $4{^/V)ވC? ߃_Aswrcu!30=+CM 3pOwo:&̖JLzh'Ӯ vc {TecANS E6K•Ucçpz|>}zu1ˏ&Qr̴ILkԥ-3^!ǣb!yP` 0ח}"D]< CKvY4 BѦVT#y I_koIIY6Ab큀WSuL%Z:,ꇺk F#HΕV= *wR=r%i w)'=ޜu rQŕI3Ie RJ>deF$ϓ*=ӻ%1 h5SB`*goEHXJwF=gy 7n#TעT^!qNLx"L2! #Y㪦& tuM&)W.x.7Q䢊P)\.t@ByڟV\%0ܑ4_`eEd((FD%vB=CeNEg^^5ԱŁ5Bq~OL)1X"1rTޛT J =eyTȁ`HM"-S!YXaWc"IW=k 2JhTbzL2+Ct HG']*r]l:w '͍Bfi)ҋK@*XPdXI7K?z8$މd3m ʏ>uDcNUvn]Ij 혅K6ƒͬ5i'ăX?(moI-S&9j0L;s#5o9Q5lYtM9c2J ʽ't隱7Pvt,T6E7!̜|AhBrBCӪ;' id]P]^R{P;gJDu@"22l3gnqќ@d94 ΤeRp ViCPL耄V מB92$DWuvK^8b*߅t4}Pb.x8NbxdDTR$qۈO7 Y)$Rf+kud"ғNxU'ʅIwS,A;ڗyZվBD !u$!Zn<:+=HFNRXIO~4PH6 w|gwQB"f:TQm؂|⧓!S%`%&Z6SF>\$)/ζ!2(C B0}Z鴶SUT4v%y@VQTup^m!$ GjR{KQktn54 kPrEש"?+G8T¤:ĩ$B-hw=7^sΙ`%NI^mjݨVTG#tfCp0p8ACCTure89qD=SCh@'P9)9.?>Dm/?@Ӫ~eM1xX=KBeHưHtNuVM_U #`4aVmpb@gp8NR*['-T&IL;d_}K|QYU @(48nߑM'H$ګQjSP+WؕQ׺h@,ՒTPU8ۘƑj"2mi= 9THF1p?u 5~]rɽ.~'ݦSdR@5$H!ddoC I봻Y]pn qVjթ˱لGH5Uv:1.RPR7z{c@W LuլZ+Ł(*w2hG5+FA[ XxCx@˂d?y >]}{/_Q{vGҧkzru!Gtգ'(a?ՓO j%"> (Cz1xwcd53c{l3â=͐~inn'vd ,j<]tck(:6d;vj@͞.5Ppf Pj:^D,ZAbgvFD@jݑ$JL>+KE'X2H1.'t.:F[\8}ihCmj`R@nA*rEpd;Yl;-un IAE<uQ'ϡ E.5Ov׆KeRo:eGWq56HE6pA%y5}+LjİMA{ہ1WԖkڿM_#հCeR:C <h D^ L:V!jHR[y>*?k[(iˡoCh3 : jeaT:uoV~ٹ (E(?CrR+]Ձ0Јi4(`"Rþj4R5+"Op:: Hn6@K=:bwCENԞtܖ&5UHӨȝqIЇtHх&lJ:CHշ޵Ó[$PttoeXTA{Ӿc OX:HTU-#rOشιK =E'W/#y8GKΉr<ޑxNLƁ{sza:nYPQ粯nvLn֡rb!0(noyM5 ;kڢ )R ]_]OYX6 Cy$aW5O}pHm0Z#X[\06Vӑ~Ԣ%ge&b2~=~w8T!ٸ i72Cu=^uxds޻f\\Wn胍wH㩇=1` ~|yA/iCCPICC profilex}=H@_S"␡:Yq*BZu0 4$).kŪ "%/)=BTkP5H'b6*v"00L}.Js|׻>S&|", xxz9XIRω #e8xfȤCbf%C%"*FBegRc{2i#E,!2j( 1Z5RLi?8drȱ*TH~wk&'ܤ`н 4}l \im|^ok#nkptɐOS(30p qd pp){={d3rᚉbKGDC pHYs  tIME-M}IDATHǝ[VWk}7af`=RR+DCm"-- 4>xi*/bBPb$H)-Pc XBr! a.w^>|119gZ`J0 ~Oy"Dx[XAO $EQ1[j/eV?M2w,-qcGBECG"<Ⱥc'Yj ,Z8/tgx[a5<#EQyO `)_'K5eW=[^&?!>=NkpZByCTpB98â-dɣUmv+w Ռ=wA8Q*UEŁzD""3a&-]|>6a}+/_Sj@ţQu>1@TD," 𽧖Of,Z`HKӢ{7> ?0LPyn//Moc%1P=B1KMΜ/-Cp7\U0z2ϣ3v:/^:_ɰjCbL|Qw5 ntIYA4@`upCSR.SXm3br]S}]ۨM~FQâj@C6DV!Ɛ؈V=X.GXT !IA!Vz8zm6tf,`1TS"ɻ Jw1HFh@wiji'#Dd"4idıl j)B \PKQMTjLCou2Zr1oh`Ԡ#GsBQ]CF`&Vq?'.uu h!D XA2NsW6f_ϜM&f’YTɎ/~ڵ̽%їĒ$g7Bיumʹ  %VB.> nXzqtUU O#:ýƍl)PMM eDDscy:H&iUp/ !;;EEp9TwâemO6(t>zNdbƊ'ruGۊ}, ZI,m>lύV,RUUUe1gaz/Ֆ`p7oB˂+MMa4WL0fϙP8cJ;JS t233ZVcAAW)Nf=; W"BSS۩ϩ/c c>njFg$95 5V? VTTP^^nu8b;W9G )hx8񝰫JAAbnVq㖜^Y$ʄQcJp&}>WG7UxzN]s ?ֵ+05[vzQQvwwt:]^O9f ޻#y87k #=r懖@Q8΍VtF{Pؒn۶mE|+IbCH؉N'R}=ΙNHHȚBDQ9_ nZ9ZsЁ酀qlbdwsk3M_zZv&0>6d3^  , 'jrrHc}`"H >o;i?>|xqӊw~?$ :ɟYNBF\-ձ,~ !H"2҇PGBJR0?)˶2oJ4(! \ fu;zsw:inn~4}Ңm3A4>~KL[JIENDB`jamulus-3.9.1+dfsg/src/res/instruments/viola.png0000644000175000017500000002111014340334543020742 0ustar vimervimerPNG  IHDRqߟJzTXtRaw profile type exifxڭirkvcf8h62 ?kR+R$u:Bw^G<'|~??{ᯯoD^J<ϯ~_7^\u&?]h7Bo}F)|nv{wΟgZSa+'wd+:x>~п)KJTzLП7oPx9/os s?{3+SIL=sKzUn++|wZbSG"[|0B$7p 7{a3-6c1xwRrÍ4)M9$^mǻ \,'o|^5TDY0Nc\>FF|&2X^;~ Gq |/@Aa0!_C*bt-Id1HK(%sJܛi}4y $%UIV΅iSCK)(U!lVZm6t=KG#A?>ƘN<\qWYuXsGλ{yI>>8ӂQJXf݆Kt-v_Y ߶Z|ۯjk? o@H.FsT3?"]Q",J bW\q͑9{)kg>K/CjC'k}>Ŕ skй\ֈzHYzf=Nj~57ZXZ m܃>35R;vpW}A#NB={mƕm+wsR;8yJŰK(=`hgv ~1@W^hlVAVeê$)|\v8-m7w0u:9ytqw"A[{jX-WKo%2Ϻc<90VDyݖV¶L f#jjXhvW:)m޼oQO( u*ݑ⨙3*(8G)U!F@tn+%Hpm|~_NTW%xڊw=4PxS|oלVpo(fSzNU}=Xf=9q+jF$NDP7'%m *ȹV@qf]%+d[`b:mRhHC V?h bs}'Ν{R.hH19 tZuWg{В24!˟ ^[/tZz,x&&t -a/ v {A;U Ho6flH0@'SpY,7U]qϧ +Ӂ|a҅ 7>ҹ.տf7ۂ10Aء7.6 !V\(Iλ$([ jNBvh4 mcP^^uӶ9:,5ߺ^e:VPQ_:4P L++o*桝\=vv%amDp lR3щr=T9Bx9e\&kW3‘Z%1hbDNڠSkaׁc_{RA;y@ړ 2 h~6m$BBQI5vŏF.iV!eOXGN^wV=sPv!$V"ΰ⇮> ‚!*No>ieƹjhlGʍ1GJ"}zQJXM۶h.% ^}[~b'S\{ no 1$HpGbXekMQ'[h{8CBZ\㥫NF0xjӡ鰘9$2 {H445O8]; ^FT˳D>D"Aٯ"h# jHYhnh ]>JptJ  +PY=zDB h8T#20M.* Qt.WPl E8T,fr}1(bKlC%;|*1n"ddh<Ѹ`f8'gBD BQ;gN >yШxwFMC5Nܾ0MOA`(s*:9bW ztCՄvjE#Wp'rW>R*m"Ȃl@OqS0flM=BE# ֆN~$P{+w 4 oLz{mqk?Zv\(1 NCm"nP` #qF^D+55 o,2MP -o;L ;~,<ҡ;2[-ǰ+]]|/D`ZYui.ȰiZQ.dI [@ I iοZQn%!bi8\ց$ڢ}HZـ\ fg\)Q'pZ /QOf'z"pd“(Y0ȋʍ iVKfw->m2 ZtTXsɸxﲌ;+3- F<b4w ,!aė|:mQ+ZX۳h^ E-Ɛ #&zhO ]F@m;\AWȤ_cŠCĜWgĝ)ykB-|rl[W@"[.?3(Ԅ04sA[Zmjdcc҈ IR˒C뒏$PƱ! N725 X 27 :d0 dzv-Fk9CP -|ڀs{F""] l('!S- X*ގ%Mz$% pM6bQ˴?0|D$Kj#3=Eƣab@ƍQk(@L,B݁N ,ԙUmH&*2 %HOj ф Q\3}K'Ң Q-Q=ɤ\q$—|Dq{إFpprP@Oo0(wBDWD ?fޮdڵ_ ڎb $Vdbɍ &[$rM#Bit 16Ѡ3g*L]a}<+RBTi]/ 63R\: ܀F/;^{ZLXStf:̑`[zgdGlˤd& ihd9M*f :%hg3ת '1tmvǎ 4Xemo}% C["p:Sopwo()H(ж%Я] Oy{FD]=t/c~R/q usf}0rU+7it!gAxʟRoô*O,]fdtYJH}ث&(=Ħ8K4>_)~[[m-I[?&wu(hi.î~HpiTLNCoG{b؀QU(SJW-y~ up.mZ6v>X)ocJG2yUGp Km y:I֛}h2{:!W?n|I!a"oȔ鳧UH pX7ӥ`*Na#'ߚpxMߏ},Y%߅= t?>d!CĐ+3')'@'\:DŽw?F7p1lQn ؜>ޯܔZfٲ5y:bUzҁz:aq!@<w~M2-}]~/6KcڼEWԨ㎠R!yUH!U*/Xwnrv\hFYvj ,>c*y/˒&\CǿauDꉗߝˎ-[^lda*=]Ci/,ҙ7F'?eTZc^oLfݷiZ߹釹@&w =%5: 4VLkՈlMGAp`d R=Y@ފc}>ZZn˶U4,0RXDM̅t:,IheQڢ3ey-_|x U֯'e wEQo7:,ģǓ4މ#f޲(#n* *SAk}ҹݴaO]4hnX}t8vg;vMˈH?N][|ӓv81:eK@1LYH єgg#"',ic?& ~^㳦$ͽOc&CH끯`1 # }QCO$YAeRБ=@'1ˬtlNA?,& ,"H n!򮶶؅7 o<;2V }1\n&@m]2xADŖ@RW yX%ixr̲V4լ#Z$ztt(BCCGAr }\%j$:5r}>9&(Ee+A)hiˉh/h!]ɻ#L&&yE]N^C@8{I Z]]My }4ߨz\p,om8Fj"WUjBѽ NNU:0.9)UΑ(w'oY7E7bKGD pHYs+tIME3cRtEXtCommentCreated with GIMPWZIDAT8˝TklU=kg ,-M *H&( &FIƈ@#"πQ4 01>Pl`@kPikw;vعh Z朜sw$Ϣ/ k)w,QWg7 >.53.ǫTP +fVj?wCDxTm4_w>Qa=69"z3鱋w#%5ښZ0545e,{{I;|Y|>coò]m "jm+FE,=#IIQRZ!ށn&v,߸[˅@CW칆?+Rlҍ[hƝ1%V.!✙fgnQ;5'b}-T֞ظkLXv =#[4EXE:kkG_&Y$f  fh0ULl=ϗv>H(s=T.bSAZrd,[?;n0\nPOobh Tv5C㈾:Xx13Ya,v Cw;e H^W8PC=o grZ(eR4KT ǶGVlW[_g5z K^1fw]A15QYDHpxSb8)勎YPh}x;oXU-V39\ ,x( F{~*VA`Z6L>59Âe1u@rS)d yZ;^s(cK9p3i )1t8&% ;d 'i>/Ҽ.F! 6A@0h!2sxfd%o 7bRAIENDB`jamulus-3.9.1+dfsg/src/res/instruments/eguitar.png0000644000175000017500000000217414340334543021301 0ustar vimervimerPNG  IHDR|߯bKGD pHYs  tIME oIA IDATHǝkL[eƟ@aA) r;]م`s drY Aph.23.YMM%hl2YڑAe+Kq~Hb|{'8g(^ط5û0 UڣutVq׾f-k1A1}CyG=(<^E

o|QZzma]%Qk8lt ^?jIENDB`jamulus-3.9.1+dfsg/src/res/instruments/vocal.png0000644000175000017500000000307514340334543020746 0ustar vimervimerPNG  IHDR#2bKGD pHYs  tIME  0%J3IDATHǭYl\W߹z}8'ͪibj j%'P"*@J AP "iV UU"I%'qk<سx{a8tFl|-W<.igS`W۟.WDR왉ڶsW&g4Xp{Hp' ;z^??u7w4wT.ʿn{6""ertgߣ#?y̾͝7 y*`oQ>2ǎ TE""қ"!vw0 C׎ }Z4?ƫ*s2 Wid{i  RdNkϭ=[kDpwom"rbe3 &- @o A_{fqv("i\[[C?sCݗ}+/i;qzH;-}""\Z^cH{C%13?xT+>>UјM420b)a&:͹sɇˑs.vhr\VPz9wv 5|8.e**9ҟK lٻczn|i@4Gps$K~51Du2,>+PEDK_FCC)TLMn >]Z*gZOt:} ղ܆Y; h ۶KAo =^[0,S@65TmۧJB{pR|1; w^C;^ko~5ڶ̯%oYMʥ>Su.-m-ƺ퉮$(Sg$ɵLӾL%W(?wzO^ڼi6=]I,mnnmHsfb.ēs#yc޲N|?yECsǎ =_Z_>nh#O61D;*WIENDB`jamulus-3.9.1+dfsg/src/res/instruments/microphone.png0000644000175000017500000000277314340334543022011 0ustar vimervimerPNG  IHDRqߟbKGD pHYs  tIME )2K,IDAT8e]Ug杙ٝٝn+lvT mFMhT.ԠQ4j$$raHSXm"~u?3~ 9^ݶ$'ɓ1!7{cWkܨӅ|jəf5c>0X@ׯK φZIlOx5=_Or7[6<߹(1[/\?R ۱Q""ξן6+T5AF!{1ƪTm}jddHDJn1ڻɉ mq2d{Rr=Yaqs e$RO<G)!Al^%4f )j2Ǜ׷#qiehKZ)TkJ !Nrj6`l*"JO޽LW'DT5?w0 IRH)RbƲ]u_R_sLE8cFkMp}ǵFml@ת+/d4;G["Agy`bj˲P*r$>ǾmA!"I<2Xnq3׊eٝ#ӝ0RضcXMc[A/Ia.,_!"m$^h /8x5e!7 456ؖ$Q,rӟCm SUJܾsl[n!pXR"Ε|u[A[HDضhOwQV1!zT$J44 aY6f(eUH*Վ+[Az35w БGؼ&V*c#?8ޞV pzjeׯB*09pl [1j%a` [ضﷰ,DOT"`;ZkSo4ofLY0 ~yyW/lsa`pR4U>xɱ 1A!#'͖ ޽[z=@o&u}<62bصٮd!C}e<|xSמʫ?JO,/.jLT(W饸jԩ/?ufP-Ukli*mI|^{SoٛABbE2ە,)-#hfjŵkuht|}GE}IDAT8˝YHTQ{ν^g@1"h̲$m#!k̥AVD,-,{0J* \ J([ut3n"AyʎdE w½CɤX,n˜F1&1,?tc0a_Givy;xXzȘnYчae`l" daqaCޯjBMm~Ψ Z&q Q*XS)&vޫ`UrNw^Q1'\xq¨YƉ}5𰽧Oy;O;Y1ps_$dEa2j~$E7pE`:~)+;PZ|C.`ϟZ)Pʂ  ``'&`}ܙaqm 6W49{s^XӻikCyz@>_y87yCˎ!+޷ǖAܙO_h>. ]ՂLm#91Xݠ8~h!֨>v'bU{mдuwYcx'Rڱۤkj@"89 3_iywܰn˟{C;9vh2iߍq_PY&g&/{6\>~5?K>ѣӟ綛8 ?{~p& l l}c3fs .p^M ]^D@Uo ?(qGo\[w/~Ϥm6ljR+GZTZ9VTCR|ʖ軰\n`/?MȮ=^k+kB)zWW&`!>9p|3'Wɿ!8s/}ok6?Zr#J!6&82Ŭ($6/l"{s2LO\3";?x7\k->sژR}RVU #x{|+_4))"A>5/X_y{d͕ԐĆBk86~z<4TcРO~o+GJ82D6Nn1}OW!MeRŨ"~=0K!J1g=s?/ÒUE+SK9Y(uKd('Đ HyBd('T SCd#RjH 9(cĠ |ҢZj%K)C)*AaDPD`B)IP)E$Ee}}e=XAD>:<{ryrs8q2.sN3tt8r3O'd[] EqU#V;`LFT ee4[V!Bd2<432i_6MGh=vVhkSͽ%,, d!ΊXt̖{~ D EAPt~ !-,+Z'IENDB`jamulus-3.9.1+dfsg/src/res/instruments/grandpiano.png0000644000175000017500000000305414340334543021761 0ustar vimervimerPNG  IHDRbkbKGD pHYs  tIME ;M.IDATHǭ_h;3]I;*ו#HjUWbi]B)BC()OM[BK^6Ocش6QRRbڵ3sӇ캲N 3;s{};vܱm {y|C2_(Ik]{0_|,Q{{$ׁ_)'ݻ\.׿'3AU=5R]DWt@ "w 9|0gϞ؏?|ofqn#Q (DH: %ҥ8X >i~߯gVf4Z#6(EBI @_yw x1Qgҳ7qWR(PJS _{6oֳ1j/I c-:"ZX5b1`"|rWk@#OkEulnޔ7%,Ljo#(FSǦ'/sr#ӞH_* ,]qJt7&RDۣѨxyt%&V*EtcOdl6Yk}zNZKѠT*,0"S$IX(ma:;Gp?0|) C(b``]v.S,Sz-RHPN޸ !qH$^=>>ʊZ ٽ{7A \~}ޚB0:BqX1x"2l299 s5d22229}4JUs]@uj͞?}\֭[9p,״ϕJr/&,TJ2:wuN:Z߷t={+WHto3k;q/٬;w.۷/>z=:5299??88(w+XJއ닋4<ӳlj+"Κ{8 Ϝ9'8>nvPX(,&&&f/O'?ARc Z]]-DQt"u]DZfI&/݇icXr% C6VZ-QJ] J$mS1f9 *U*?ax=q?c0XkiZNoרrE_MFcj)k#vDAFcnzk Z#"CjV;^0kyU`@Tr?A <9vD;#5iTXtXML:com.adobe.xmp 2 1 1 2 27 1 35 KIDATH W[lg>񮽾v48 %i /)T*j+EPJZHB*<"$T*i:Q4]_{wwfggXk,82'K(-L tZ*Nh`p!m ʥ"w½w≟^/ !Oe9ȐSf)a;īF^%%-{ӄ5ZH۽C$CK%/$aLK˜9~<{?Z"VǛWCUdXctdߋ[׮ƠJ%Q+`j +S@+РHpRK쎞 |g6a&7./ y-؇l0}eL )E=~VTz AHtXx7fg#LҀȥ L}<\,9 K ЛIB4,U۸9[=<&ߓ`!ssHS,,`J\?I ѱp~8@ٌ+5b6(z$\yhZƎ}ci_~)wndXy'D^x"{ Q׆mP765e dܚP'64?݃"nOenf6G⳷ {1,-6EJ@vUkH cw]3b+-]v|WUNtEj!|]JZѠ!v+!\?=d?>Z 18y-,%f^1#}¬$X5MfrXm2M5d*7^}sdf!Ҧ\6{?]|Ok *L0IdV/"? HM $C I^хc ֖DnAB96OlY 3<y&9 )$&{d$M>9\&zVl"8ۚș!C0B4J"/Pi#1ӎ tu%X|"WeF_aE"r=|sz2MOϨ!  MD^SAqs60DRW8~|߄pq ~8I4ww%Г7J*I\FX-VaJ.&/ w"V1aI F 5W#Q%^xuC{X>$Vs^Dh,ĊJ +EjSxc.IF2Y}eR+a;I!![*ʵ J˸yGygg`PU\[Pʼ-8";1oW'llT1t +;n`bG/zLDx #t} vD2_E\E:ej 2Z>g;O+11;GY*eG'F,CMeLP+9uS+UHg$jfyKKqy>GH FFU>Lզq5S1{b^!8 (.ǛO~|’``z!Vx> 41UaEEwTUAIJ"4\mɴ3r#Yf>a~fcI#Z<M vIENDB`jamulus-3.9.1+dfsg/src/res/instruments/aguitar.png0000644000175000017500000000165614340334543021301 0ustar vimervimerPNG  IHDRu4uIDAT8˝mLSgm-/5D05:ȇLq**)Rzk[`@_YD*`M1.aƉbLDdb|%S1Dw~R $7ܛ;}D y"F_07KO9V$_X!(x•L#>}=9\PoQUXy17mH_]Ȩ󐟣%zչm2`M6r31ُ]VGM>MHPnr 33OQݲVtuCjF,޵mcZq߾i^W>z,qHM01YU7m&z[CYk$Уc1R9;;sáJYΦ9`f֏nlE q=l(6!gݣy'eNϙD?a@ܤ[A4A~|ڶL`zN휞zBsF4C}7,#nmYM*-1Z`)nP|lJ&J…yǵt$,(אХ G-w"0qPe:iR>Gx(d*Y%xqpJS0b ZtQΡb^gpM^%IЙN!szܡg|.[qmN%Jl@&ke("篿n ORAxR÷k]c?(M2;.)lǯ59OaO:"n]__5&E aW@Ge%.(wK$胄iC7l,o͌:asyqtS`yIENDB`jamulus-3.9.1+dfsg/src/res/instruments/bassoon.svg0000644000175000017500000002702714340334543021324 0ustar vimervimer image/svg+xml jamulus-3.9.1+dfsg/src/res/instruments/violin.png0000644000175000017500000000245314340334543021141 0ustar vimervimerPNG  IHDRqߟbKGD pHYs+tIME /:iTXtCommentCreated with GIMPd.eIDAT8˝ilTU7of^ʹ:C7eHJKYBE b&* eQRYTB"K$ HaЖ@ DjL;33Lͻ~@eO{/7w_jU{hmqƮ?dcu{=hƳfW1`1GL+z)՟62ǰO)L$EnR+gsrF|DFo 򇤸C59eq3,;C̀(rRq_C&gBC6 ¯Ty)X¨*Ѝ},H5<\x&La&(G.cyka8{;@+ԝ&hB#D~5-ЖC1q6ײ<_5}FD3 image/svg+xml jamulus-3.9.1+dfsg/src/res/instruments/oboe.svg0000644000175000017500000005673114340334543020610 0ustar vimervimer image/svg+xml jamulus-3.9.1+dfsg/src/res/instruments/cello.png0000644000175000017500000000164114340334543020735 0ustar vimervimerPNG  IHDRu4bKGD pHYs  tIME *ȱ.IDAT8˝KhesLd.I:V &E *q!E)ZAŅ(n P J++vaj Iab\H_fr\L]}8|=_:;ܛ I|)Q'OW~]ѓSۀSvƌt[Fy6(. `H$B<dؑd˅0+Rk7z[=R 7119\%Kd\e}w;Sl.Sffm4~y9ʩ![&Hk2'fL"På7|L0R"F>-@06l1c|S#lRm^]醳Zҡh@\ hz`I:}-o03+>vu:/o ͸nwvGhdU6|tHGBtƳ=[-?\yT.[]Ca rV.ГB! `4ʐmB"BB47)%3˞*&-s7&"d7=/|U@iPc,b)$00m\3[fCJDQ*) ZfSo0*IENDB`jamulus-3.9.1+dfsg/src/res/instruments/listener.png0000644000175000017500000000252414340334543021465 0ustar vimervimerPNG  IHDRdbKGD pHYs  tIME g:kIDAT8ˍYh\ens3w&3L&MŦ"ZjMk)*U"QD탂KAADpEA_T[ADpE7EVEkiKiE%6IӚ,3sgLJb[}ϟwV?,T˝Ans-c]<>{ w@uӕR8$q\T#CʻVo}YIׄρ\(Vx֣K.Otn$^N]xLAɂi6d:pvG;7`Mzu_cr*Q|B$Ph55D!A﵄]`Nl~yqkvb/yx~ںۑ krAª8XGfIJ lyTR ZV0wn)N"Dft@NC8(hXǸV?{R|3J_Up\hm˂b+ &tro>C<q=O^g$:VZMiIfw6!V-IBŠ<DyV[kuOLtEXtSoftwarewww.inkscape.org<bIDATH]hUٙ4M14[$jb+("$n" Mi.e.JjAT1W/ZJQiMdOf/tln:q#͝K2ewC4=vw/9qU5,M_ڪ?w;Z8p65^U/UMUNda5{he8<Mm4 #jeY\kMۑ@wV XL@Ө3}"a&v%s֫.LL8]=!, ,n/Dv S>`\u }dpxEK)t zT5=NQ>;:%GO$$g{(+!|&3\Ib&dUӶ:P7 }' Ks`>² d 4'HywGZ@G"-;oxM Z Ӓ0;ۭ+U_ (dKX AĠ` 'U};ښjTö,%ǧ@p3)yT˩y8De3Tז- qd^,XX;piFzW08 2hۋJE a># E%wշ3"ː8{z| ="\| tf,24u- Jā.r:Ƙ**|bϏ`E@)DzSO^6O%Z\R[!"3W?՝~qpCX #@&){\4 i [QBq%VjS%W~sW-j| 1%# @W]]n' Ndd4IYC0q(., nژDX,*/>p(/**ԴyΜ9J` :9)cnbi@U1cG1r셒X:( pY$T9 Z @Lٌbtc aRE/ rNGFhDž]8x hfl}l6KWYkcf_{HDp9n]08v]3!ciiݿu}dc/rZ[[Waߪٲz+ &p1ۦ[[g4Q@yjʠdaczYg?[@?P:7]^zn}SE?Q/Yk;&` @ {>/%y>QU ƜRW^ª-*"9,a>n֞ʞ~zQU `v̨ǭ5NLqqsjAɍpT3,>~t:CDb"E n6ƴYkTE^'0';&q3Uq 嵓^2Q !=C.q]t=O}s\KK<*xIp_VxP>8fYdYy/{;h6Ue;pY'=+H29sL@v) d0' ;i 7%?N%ޯ8FV\2kId~7Gғpgɳ]l6UͫRk @0 S8JU'`6 2Cw5-Xc+/dFr"r?֑?v~`뺟~"x4T%k*J7EO?ƥ{_gcЉH99lYIy_kl#5'f#0  "2SՇDdwFGGؕ<\+jdh$;u49슲:7}~ uWMc;_=tܹsE 1qa"XU0T[Q[V]ݹaŲ'?lMc@gbp"23k""""r\DRƘԗ!QËXIENDB`jamulus-3.9.1+dfsg/src/res/instruments/oboe.png0000644000175000017500000000151014340334543020556 0ustar vimervimerPNG  IHDR!$hbKGD pHYs B(xtIME&+HtEXtCommentCreated with GIMPWIDATHǵ[HSqǿ],m6ڔMj^VdHކك$ET!E/>AO:ԼPZ65\iqfӓ>`g~7{p)Dp@}Lb-·sR!!ۋJ6]XLrw.Zzϛ YMޤ>0ΚRU>%qe(ѩ B]7 . #e7g'V|=nC#yyԲZ:{$rD/E}H4ny<'q,G+0ӲC$~ښ?}Z%7 $-.i%SO*ǏuɆDm%]k *Z:Ism0J`kU4&iLQ[IOy%sQ7b?k d7*=N3RTR Z_\,Q cJXŬlc3wt/U:sMأK U QrQX 7*eAfxx7?K.\,~Rtn$DYR%!#%ZfDA7*sMf H&8!G(>% kI#WexbJAnĘh&cڔ|F 5?u NIENDB`jamulus-3.9.1+dfsg/src/res/instruments/none.png0000644000175000017500000000232614340334543020577 0ustar vimervimerPNG  IHDR#\bKGD̿ pHYs  tIME #6~gIDAT8˕[lUfwf޶EjSl$ A #11>1!B 1}0&$jDӢ r A.RZAv;3LJEs^/_Yj,A4 K#\<|RAA.|ݵ{1; ,IRD-,sS>ngon \οSΤXOEG6nLjzs\W YSU5-$&KN,<Ra(<JFd@QcZ0HR֭ƢĸW2. Jjpf<=W#O:qڻB>ΛiG[گdb} 7(}Rr)KͲ#jU۳%[iVX6CEŇ08(WR]=c<#L?!\dN,%<SU%F.DEX] 33׼w6v>~ ="(( ?'܌G2k fcy06.O5#|ȗc›׷9OyRISI1/ʜJtHwt3+N<"rN_]D ͻiZʌeG'D.E:FStlG-4;On@1ˉC(($ t0<1w 2.TH)D׃:QK$D;X'zQΪXBIdw9Ñ۩veCɲ1Ԁg {,b> j PO:ؾY3/xeˀ_PI,̲#Mbk/LSO4W4WKi>* ]⚹Nov;IY=fH T?)DL5@֯QlJt>:^5@h:GWHdlC$ɟ/$۵zHB$fѥMFMj۲f)MP.Ivސ5t'8X]u|0o`}ۛ9ã|kSE17'쾚)Ê \Щ届,?wWJjSi]2 ^e:IENDB`jamulus-3.9.1+dfsg/src/res/instruments/flute.png0000644000175000017500000000165014340334543020756 0ustar vimervimerPNG  IHDRdbKGD pHYs  tIME ~75IDAT8˝OH[ƿN*Ph0'J.Z5MydjZjMRkF7 Fk*/2L&B$J=R(zR$(bkk+~ZT^$|CCC=ɬN`~~,"J)[V ō(^y>;7ᦦ&?)Jz~'QF$IPTtV+ "I|fEJX~ggB D)KfFŲ?jvvPSS3___QQQo04N. \{uuu===ٝ8a:_Z}!s4l!ØUTTXcWh&k#! kخjjױH)o9faeAϧ=;`2.z ECCb֯7N5*Htt4g'_=Y $?F4esf zAD$y褁}V9p?ci&2_ْ>Vv[4#t$GŠ0ۥܸB! Ȳ2%B9[x9.?>.6, 3BqQgwRtmŝRնz-TV%1-Lbf:Fq(k-F[P>->SczWex k1ze+OϪ)^[A0`^8+4~p a/*jv(_: BՒ3"RW8lkqHS7M6Jd VU`4qh 3)t蛣.Df2pG6leܠ#Ri(!L,Fݘ%@M?<@SKd&h_>[#"z O@My U|)Y4b9Q3·2,)xIENDB`jamulus-3.9.1+dfsg/src/res/instruments/harp.png0000644000175000017500000000222114340334543020564 0ustar vimervimerPNG  IHDRdbKGD pHYs B(xtIME #n.tEXtCommentCreated with GIMPWIDAT8ˍKh]U:[jAt""j( (`#(iE`ԉV Iu"ACj*ڛ$s^1G kk_cx"v9:N7G"K H?`8ւ(ͱAW0|8ŇSwmȦ3< -$;AœWY>n$eo\pJy[/$OL@߀ ^wzw+)%Uնh_c(дGA< !t%$x )cafwo#OҭWOJ^{:r2!0$DG{ҙDFNUUBt]׃EvK^F>1Nr@$c繩jr(z LϽJ@$ !tͬ)"˲0SUU?|ր%P"eReKD.u=8")BϾ!s hũc$]B:Ꭻt9X8 DH!#!of3 }-`Nqл(V@wz3[DN1\ԿD P(!N=q63GJ+X/ !2*&{Y-EȀ{ncЭy5\ݔ+ "!ߖ.HNNL,mD!jL7ؽ=_ՀgJĮ7ǵ D $=g" //_KlTD2>z鞓ǹn9vX¨۷`RdUB iaK#p1::5%71A }E]k kģw image/svg+xml jamulus-3.9.1+dfsg/src/res/instruments/drumset.png0000644000175000017500000000467714340334543021336 0ustar vimervimerPNG  IHDR#6bKGD pHYs  tIME 4 B LIDATHǵ{Pǿ .B cV At3mq:Nc'Ԧj4cLG 4 Xv]v߽ v&=Ν{sɱ_!j.QDFK+o#BJ}fm]F>x>Ǥ @҈0hȁ`TS{V.OIOm6X}p6 d (PeI:-q+TDE8A iH}3Clw6Rv&C[ "Ùwhn ! P&jxx=vu"v]i{NJp =Kn٨p`rx>wD Te*Vnv&G`^AZ:$V]LXUUJPLGdi (| KV߬oDFEs/2y8W<#%~d^FU% (B"..`?7Rs _4nnnKL^c߿{{Ma Φaz{zľNtuw`jr֥K7:DE (A@bR^ҶnX0x-=zƝNF)# #Ҧ jamulus-3.9.1+dfsg/src/res/instruments/recorder.png0000644000175000017500000000362614340334543021451 0ustar vimervimerPNG  IHDRUiCCPICC profile(}=H@_SR+ fqP,8J`Zu0 4$).kŪ "%/)=B4ktLƢR&*^+3ˈ8]gu>Ss|3Lxxf68(&]o . N4u|c^=*rmLbKGD pHYs B(xtIME '"IDATHǭmpTgF6}3on%BL,Yuq+FԙLa:SdwaNi _Z&YeԙJqPG%0%Nl$0憼~p!D}={y9+@9 o"o~`s$ioo'a6r|>555[~i똪T5<::BV@ED(,*{QX"z++IGGGӪڪίa~4Fee|8˲\w"ݡ8]5p|s3c"R֪{`( =w TZFrN/ IOD̓ hP(ĞUfEϑ  " m۷og*Y 0""O\4S+^YnODhTV&`CaV#Lq>,4=\o7|R%KO-7c;iOeNNTNuO {W;kh˖ ΣecI6[Ǝ5v4[Tjhc7(]]]OX۱0gqw\̩ '>|1(;9C4iv,"ܝ b1ڕtfI\">OeQ)U~Y߮btj~dea388P `i^μ<;b%:x<95͠y Oœ|ؖH$@nyjyg_v/۱8> szBQt gCeee$Ʈ1JK%Vip6qT ~*^;9s 6:x!8CƍIP˝s]h>o#$&&ip_wkRU\ħ&0rC&ڴ*DUoYl-gs{rnY2v?9 @k З/]ٸ4Ͷ^lD&WV}"r "/??/\/o4vpe^8r*"f_۶ml7#=-DM `֭} n}߿G,wu-IN]L0d޽#"馛zxgvfxxǽe<.廥5Cü~}.^8rd&fRWNUm1M3Ԥ=dI]VzيejfZUVt/tuuvtt000@"nSQQ磺zx3;nI΂6KW6(.,~FIENDB`jamulus-3.9.1+dfsg/src/res/instruments/guitarvocal.png0000644000175000017500000000272414340334543022162 0ustar vimervimerPNG  IHDRdbKGD pHYs  tIME"$6iTXtCommentCreated with GIMPd.e8IDAT8˕kPU݅w P"]F! G-ki43"iD E rYXX@ivy?sEhZ2n6cV"R Mz9Qf'kJ1NޓE2zs߰{#XSy!:gdn՗-"ju: zOsN ; 2^>2񮇷wsPBx ?UU߶ +dYFSc1V3?uvޫ4S]ϾZ ިOmߟyai}(O}BkԫkJL76t z]xӅ%K2FU73_(LIvY&SD o݌wV45ܻ>l}_rm:@|4(9CHA5B)ӊ)!yFPx]qU99n< F2O*6vTe9'Fݮ#oS껡6ر*gt>'`Vfp"(QP #ߝp~k 2V/o ]~Rw_w],}- 2<9 ݦs133uǮz~;w-!ᙑ OT*! mWNr=k`wB^ Z;\QAP**P/H۰$Ji?=P>ksIENDB`jamulus-3.9.1+dfsg/src/res/instruments/clarinet.png0000644000175000017500000000111314340334543021432 0ustar vimervimerPNG  IHDRbKGD pHYs  tIME *d"[fIDATHǭOQo1H: &FI5 aFPA/ jB- )x"]*V%AҥKDɃbt%y}C4}NK!_,sEQJ8*a.L&Kl6{{}u$IΡN4oz=R4[nT*Q0|U*A(^zvBi W3ljJd2HpZS;~mtSUZn;|>Viw_X,^BvӥkL&OYca`6= Alιh4:n44 LPRor9|>DHD$2Xi Q~ܷ<#<3?zy}nn[&ɲ#˲~x<{ 'VrIENDB`jamulus-3.9.1+dfsg/src/res/instruments/frenchhorn.png0000644000175000017500000000443114340334543021773 0ustar vimervimerPNG  IHDR#8bKGD pHYs  tIME ) IDATH͖iTSgǟ '%"XPwXѩ֎NѩKk3vZ Z[=k:R8,B䒄h=?<#xw!d< 0 bqYk~) ?c]+H嫤c[" F~Ju--Im+jh2œS*>j. |L|(e c4l fY2_˥}:Z A%rssT%"BEt$/gg'5{dVg0 B#-̴:b,rieȥ {HV͖_\0|ܰ)l[=7;s׆ 6TFKt`ӶY e7'Ś)d\i[>IӘ1 w{FJ ? Agi v|7s8X-VOkʘed s,'卒7oTV(9%<4e7(\ HPn6 sb~`<)@,ԏ>6^ wpTrnv|=Pfa:cM;< ]h)m:E+%fckKþ !.uoDKf! h&Rȸc%4_O}OO>}o.pϻom x %Փݽ'7Դi䪸Q藶FcprN覺Z3ӤL0DB_9X\b>zeU5ͫL;ۓԉmW/b!d2ɸ|IʧNsbMD,w$dڕ?@=Ykn a8ڋy%7wr.]h%0[VSeM\)Lwp+t\ -ջH;\2W\ն@ i1X"bc{nΔ鷚dyE+(0[%GK CBBQQ1Rf*m8au(R9_OjZ䜉ٓH!1 ox`!AH% Wl]DOU8C$>@z::=P1BzWनRHH\(((Xk2Ȕ!%M+ę ÛX(us(̟^;%"2e1{^.ػ]z&-3/4̐.ShX'/CAZ6eKT>qgFkhqx5_FFW /3J :~f^0x)>^ %K8i[(~Gg/Da7M*/N"q+O3fR?!G3YXI,ZTL7mk+?wL)%Fm铪Y@.`BX͵>윛r 2Y GsWH ^J*G XKw?{c~V# ٕ_&6Ǹ:3Xq8wIPw"NmvQTyfg/-+yq\HZ}Et9PTCQ$ @Oű@c# x'fj?r0U{{\>Z_I#±:"&<R r'b]ă#{!euu,foOzVk9Ry鴋ـxۓU/0[8BbɁ0_Aq3˓,+<_覰`bIFM@F`1U i7^!yeU@*SPSiz}vXЊMljHk$29 F5N$eyA Z[[YYί{=^!HE6Ӂi2Yb?FK4aXa }{9K|_"]v?L֤'Ej"eW=Ƿ.ƥbipcKVg('^YbJ[Exl 30Ӷ2 #km0D( Zid߼f}!(D2EQ@.\>F"ugǼibB|_@FVkzkl4]t''*aIENDB`jamulus-3.9.1+dfsg/src/res/instruments/harp.svg0000644000175000017500000026572314340334543020621 0ustar vimervimer image/svg+xml jamulus-3.9.1+dfsg/src/res/instruments/vocaltenor.png0000644000175000017500000000417614340334543022021 0ustar vimervimerPNG  IHDR#6sRGBgAMA a pHYsodIDATHKWilg~ٙ=<]v4ibMDs(&Iˡ*h" %"8D&DER"T ԊCi " nҐñczϙovmr5-voy=V9gG'O V16>qa&drݝlT: `$̢Jڻ >vPi,_CȯWGCP~lŌ)C*z:[P*jU[pWSL5X@)pNpOwNև @jKo D"N|ajN̓[qS@wYLD$lGlW\FAJCL@&R1oY|CTܵq:&cН#,\tH*T gNONW}M#73 s`(YdqvbҠx@lOE1zqvADh1uZo3DyyBB]!`0hI)D<N5o]_]4j4'ېǷsHZk?%+!)[p'NsU jvG 8˟#݅9n7 [7:|h(کTJ8|XS/>Iff7ɰf@*-a;#޽{/t"|ޏ3d}>uOfΘ+T0|  4 Ck޳K7~z[INԇ#%蚹"bPPж[y>bNE"n'@P1En˃Qݼ "GUBf|J~H$ oGYDB Ya 1J֤g!<n IlN@*6Qts})ߓy'Dk)j/! Ba5Nr`6P0|D-Ui4Ю`g^>az )|9ITmܼ#PzFlcQAyyŚ%8:Dz1;-׻J:qe{IObX~ T]b>K2p}8kVREk@"hCqvaƉŸzD%[QGlvd9GBO/+hVxLFXḂ2|J15dWZ&n.z ۇTQy5O1̼ͤJT}Hc Pq)A!:Ŷص}K.CYP;6B>fJmisWx۳`ܞ_+#C.!=vfL\aW/m&aFc|H3SZ˯\Tֱ#Mذu;>}?.cxzԇ[ ee޸tl ZnF)l#HB!ao;4 o_ 4'WK=yjcF˳*,[J"J-ɶ X2ZYLPʣݶmTeTEFZ'.c V{'_:R}y㮍?=)dȊ/uTE2A?SHowF򊋲8qw JO}#/[lsih[5jn ƃj=G9p4)<@)0":-o:G_/2s67 nz#A~jdttێ b+l^Ib*f~9zU>]lU鈞q1mH@_`aqfX ixS͈?':j#X{y| ,v| &ww'VȣDz|? =-TBIENDB`jamulus-3.9.1+dfsg/src/res/instruments/synthesizer.png0000644000175000017500000000270314340334543022226 0ustar vimervimerPNG  IHDR ǍbKGD pHYs  tIME ,ҿPIDATHŖ=lSYb{l1q͆c' AA !@$Jb %T a֣6vw@~x&Zϩ{sw~|۶m!QJ9 IPxNO?={aJDPJ-PX+",[p8_Z4kz 3==a4i"䃔R(p8i8>}ԔڻwwRJ,qN'R ]JJ) ccc9rϟ?fPJaY D^M tuuqm<ȃ388H"@)^KRDQ"tGGG^۷#"ekSMs{krn:$n]v زe BP(D{{;?~DͲ,^~M&ahh;v`Yd24MCi9\@ A 0W&&&x-7oݻwܻwx<ΡClb5D"l޼0p8v"Br44~OFA>VKK N`0"0::$D;wbYBÁ@uBx^beGb]D8̪i'jgg'^T*㡻CR!J:6CD|hFZexx+V`&]]]`Y +Wj*D!Ѩ&p4&TzkuiLٸq#^]iiiarrHOL&y!pO  ͒ѣG[˲hmmٳgq?WWʩSɓ'r9inn0K.ɍ7DDdӦM200 w@޿/;vL_.""O/333H:t:-""ׯD"!rph5CRA4JjJbP.{in/omm}~>VQ/ֽ֮oLxQ4M!rzFƽڷu)@mՏq$DB}Hjd, [l5M/6&@Z˗/BVkj Y4}}}߯]VaAG,^zE,vs 6l@oo/\.Μ9C6%IRA>ωnN<˗è6Œ${졹^$HP.9p`lݺYf ===r-=@m\eg2 B?/^s֭[|1Gŋdt._LXڵk?|>j(IENDB`jamulus-3.9.1+dfsg/src/res/instruments/vocallead.png0000644000175000017500000000512014340334543021565 0ustar vimervimerPNG  IHDR#6gAMA a cHRMz&u0`:pQ<eXIfMM*JR(iZ``#51$ pHYs+YiTXtXML:com.adobe.xmp 1 L'YIDATH W[lW>;޵׷ M '8 I[(<H)rQ@CE *U BjPӋ !uMqjǮz/s7q4̜9s׳_NX^_jafvNr =Y Fp|\>9 `dҨTX-1s?_y^o~г>o/KgN!m&>B ןxǎ:$xumtb 0Ҧ % 7O֠K|$LN,gOjg.NBUd$h^ݸ~\4C*EJSLt^A$p Bu7D,#oBiV#8w#"|݇FVgD. Si1zܕI4JCFʀ^md,* qh|bssa!4rЕ@B FN'i+n_ fcu~Byqik$ "Ӷ-Ll}PuBl).5b€d _Eh}CKO="20A$y3EE:tK6(74 |Gn$ʼ:c#qW[>|mGb+(F&!9Cb-+\ٳg[CkX}/EZZ ;U֐M` Pk2jDFNKLBL.r|a:a^<ϛnCĘ{!2ta08L I7 =HIHd@.:i "^? 4BxQ 6w7~rMGCj􂖃et+QEeL1c2E}b-%"&Ww酜@ ͯ EE\7aG &Ώ3'mV(5bq8qJٷ\\ĝwelECM1w-KM# H$0 9q$abN)ļ-kp8ڗrq87BW@j1-# ԊSm1/9$ image/svg+xml jamulus-3.9.1+dfsg/src/res/instruments/mountaindulcimer.png0000644000175000017500000000240614340334543023216 0ustar vimervimerPNG  IHDRUiCCPICC profile(}=H@ߦT "QGb,B&A$Qp-8XupqU@]B8}]YF*UAhaXbH/f9]gy9zH f?Iз \\5ytɐOK(3 ܾqdW7!0Zuw:oM?|}r{bKGDC pHYs.#.#x?vtIME ,*"0tEXtCommentCreated with GIMPWIDATH]HQ3wfvNYKAiC=dOaCPmH%=ThTDXPfڲ늻ݝ e ? ׿&2Ӏ ZtgIGa V.]$:֚grM "~ƦC%KL_[,E3[`KoP4MT,ЇUW*+wuAWP z̠  HÉرT5(*$,A f'_j &9Una$#;9iM^,Zxɻ/[T?.}wrxuT y6TEg% -s rzoaB\6պ(1o;ҳ-<㽙vxzmD%Bx$# .~"ϐ N5 i B,М2dЇPyS.k8TSE;ȓPoC)5Dݩ1Gz:Q#å@Q(^{޵X#V;CV{}$x0FiVd(7T \DπΨ'ީQ0Ӣd}uGl4*tFC5%Ov Gcgz#}iU~s, 6qIENDB`jamulus-3.9.1+dfsg/src/res/instruments/bassguitar.png0000644000175000017500000000164314340334543022005 0ustar vimervimerPNG  IHDRbKGD pHYs  tIME #0IDATHǥ]hU͛|4iM4]0o*2Av! e~̏pQv!l~BalKVuk6iҼIEm/yn9^H;aT/E;^Tz8 ( (Jk6A}QY;6OP#oS|B%g#}-z1-eϙ_Lmo C!Q,AN|ͬUŲd i#/r35O$0_L2>CPTz++ 3L>Q(b&a~o'&;VryPGJIEs `CC羒l!$RR0L fR TNţiP 43%?kc4c{IENDB`jamulus-3.9.1+dfsg/src/res/instruments/tuba.png0000644000175000017500000000320614340334543020571 0ustar vimervimerPNG  IHDRdbKGD pHYs  tIME 2S>bIDAT8˅{PTǿ{޽~\E`H Ԗ1&$fbMhEjlǦIľZ"#aDbbvYPYvaw˽#c&tz:3=fUEW?x&[1bnt/u<\(y,YlDO$ ~:=s4tl:PLI }z@4">X 6cI2' V'fNQAO'/nE^VK_G١ BV>eUq)Y ٷ3XĨLZz*6n޺.Ι6Q%8v`f]};XBrFj3fY/dWy0mhdsH3a+2cSvY~زܞ*~=LRxUI{̈_\zȖS)[Y;7D[|WGw© IGk̗529}Kc NJtze]f+NK|g[fj9%BEI"]noI..OsNGxv o\Ex<^*z,A&Q4;j?:v% (FNuN}@^%7'aP(`EkI-;`f/VlPsK|`jԼ׳7-Jrte& 6pa{Bqa2WeU s9^V4xgp"V+d?P9*?f Tś :d k2lYE2 67A_D ꛮt7o.RXJ$Uy*+z9[ͪ. Gt-8q.U\oqc͐8MҵWPi 1&sx%ZpMG]3;3A GȴҨV#& u׺y M= Z:J]u3ã26w ~^2 ĈsX`cS3'gTd&!"45\N;'Vjx|rJe;NVG՟>g$G뽁FGYĦ\EiC\ ʥWr _S/ ?1OEB f/gC^1V!Fz5KJ 5k-n%ݣQ{_Xa4ٓ/,KY:oWu Mrj#vQeI6]mEfu sU+h3laȎ7p&쮮}h3$-L!]zǬ? ˚06R>PFN#b]`*|zݒP疦loIy^D}a}\a_4A'ڴ?4^rF %)QMZ?'2ub;GegF |kxbgIENDB`jamulus-3.9.1+dfsg/src/res/CLEDBlackSrc.png0000644000175000017500000011753314340334543017370 0ustar vimervimerPNG  IHDRXXfsBIT|d pHYs~uɍtEXtSoftwarewww.inkscape.org< IDATxwx\ՙ?u[$.-ۀqU.2 %@ d)KK$ l6Kd! $X- ]܍12꽌ꌦhf̝{9wyyl˚sޙ{ι(B䐛+0fWP!{]~׽l#gVFmC:rrrH@ !d$q2H07&Nc&J9Ýl]P2''(FBFPEAnnn4SF[=l gNNN!| 0+f*]d~_'\. ø!*?seT&܉04\p E kix &]srrڙFE,B4"777 4(::d!`©(suB52wf'uu<''mHPE'rssu25>3Eセk$]999lC"`Lnnn*Pgp'[0]X` ܉Tn%999v `+~k`9p'[;PER-I-l#"dXq%PL[ȇ,B|te6JEO-2ݺ@Ho("D`9@"+>=''qOoܸ@QE$۱cG$Wf !86n:M`IvرYB! ƍwh%X+W {YB!*!%Xc;v'oc !J R eÆ aJȈvܙV2BX 6lb%XdH;w4=ˠE !~a`("ڹs40u,©SaÆYBC Ν;C3) B;7l`c %XdΝ;gx-c!6l8:JHXW0p!Dp46Ps;wLKXB!~ڰaC@;vvy7Bd!AX"YCء,ڹsgxu,D41&!z&ցuQ3 DֱBN\pvv)ցP"@1QrZ8_dgg;YCG =|ֱ'"N'ǰO~]\rMuaN QήfQ%X~.??f }}}l׼'-O|+$$AA4.Mggg:JT~~~ $X\.l6X(>b+88 @e!';c!|X,Zl6&QR ",,l`7YBE ϟ #Ic!p\X,$S.M6$k0j"kpwvvqցPGkr7p8`6a2`6aXU ,, ለ@xx8=Kau D`Poxu,V5 fcBHH5 Whh(;뭬!Kvڕ LơY, $T' Wdd$XD)WHG ڵk%f QDOOݍ>!!** QQQD@@됈ܷ~!PAv%Ђ~l1T=<<¨QXD__NC ڵ+Y7tPuwwSH``@VTTn~z3@(Ґ]v ,ֱy\.tvvJE|"¿~!K#vڕ@*Xo\.*(`0 $[єl֯__:22J4`׮]+<4u,D˅ntttPRETןl"**-mp ,ڵ!b7!DE]]]T. DGGcшyuu dh`q@2XBca4F)a̘1uUϯ[.C!pXgDQDWW:B1c ::Z}[o %X)(( # XBFf`4a4 !..!!!!)iݺu!_#| `2XDQDgg':B1c &&Zw u֕Qʼnv:28Á6Rkѕ ;cƌA` =oñ6֭[wu ,.VtfCKK F#= Ht`0 ..}/ ֭:>@pl6C!+ :: g֭cQPAA4W:;; "d$GLL PȵXn{+J)((?)9r`4v&[G\\]#J(((x(X=32QֆFN:!11cƌsDO]7JT  C(h4vu8`ZaX`6aX ٌ>8N88~ x]!<<FBXXPL8Jڵk_aP?UϲCDQD{{;+P&/2 05j?Lp1n8=-~vZZ~M%`?cѳjESǧ]D鯉jHH IWLL}<3R$ƲE~ ੵk_a`)?6_E:;;:f455hjjBkk+иc"11 HHH@bb,Sh)i",, ƍG֮]K),}ǁZ ɄZKFTss3L&4-""b JHH@JJ QF!%%b}vZ{R%X r.(RnG}}=i~N x<_Gjj*Ґ$G:=z%K`)ʘ@݂r\1z_j^L4 T?h0Zy[?5kP2 3A\%W@]]n\p\˗QVV&PUU*gbb"&MI&!55UwIBcc#F#i `$@ `l4z{{QSS˱C]]] Uyy>ͧ7!!!0a@:$EFF"99Fbb͚54(ݻiQ8աu(q:FYY:$xL4 'OFZZ_+..ǏG` u5kd2K&w~A6r3qN'._R|嗺n ugHHnfdeeaҤI&[r 1f$zj͚5 (ݻ\WV+:E9NTTT/^ĨaaaHJJBRR6T'aaa(lX,K d2 hkkl[nYYY0a*˩&"""f15k>GwרT&466Ӂ. (--_| `̘1 o- TV}}=pK aaa2e M ki~.A0n8$$$h*n rغf͚Xe``ݛ4bf3O8jhhٳgq5jLq!88u0 XU[[/ux7ԩSq#))u8 Cjj*MR,oY&u ZE Dw^`'}\eTrP__f֡j8s Y2uTdee m ѣN\p9JKKQZZa 7nL>/ڊGRRʱذf͚="J$ؽ{\uuu洪'| .03**d*==\d=tY]]tWPPp#--YrHMMETTpիWgPݻwOp="3ӉF֡ȦΝÙ3gڪz$RӦMCJJ %S*3L(--I5vXq1cLI?GnԸ6w^u ZB  G8`2XdBEE&ЀcǎT$0c ,^-ԩS)T{{;JJJPTT @VV͛X-Ő,e\0wմȫ(Paaa}ş8'QQVV#GRpB,Zϧ E(**Çggffb4iIo |CJXzUB  pXfCEEen::?GUev@vmXh/^oY:p>|Ūy[oEPP*uac9<<yUEՔ<,hhDuu"wjݵZ,:u 'NPfIzzRߺpYEt曱i&,Y&MR-& GEaa!٣L۰`fqx}ob(Faa &`yIgΜQ@qXh"##ޏ`!""u(`իW` 0 Q4bXMMM\z^9r'OTd@,Y[l%KH<^UUmۆ\& wމEq;pA@RRY/[zu)@xD =U*Xt CjűcpqE2e lق 6"˅Ǐ㣏>R 1$$59C|LL ҨP5\jRp(0K:xoJjEYYcD`q =zT5alٲrer.m۶)҅㮻zdȡZU*{:@eest(..u@,][lŋ鮙0Q]]m۶!// ŋcΜ9ڿ֡rVZEI`]eϞ=xuZ&":mmm[b֭Hrp!8{e;k֬M7$kJa`h.(gVzu={-.@yy9Yⱶ6˲~{49'|7|EEE;i$]cǎ\OII"##N`ͪU`سgO:3A"ٌ˗/+:/, pi\.Y?7jjlB+@AAlsҥKeT dffҍoܶjժ*q0kϞ=:2-QQ'|"R+V.iuuux뭷m۶'g}F5 ˖-waAX֡h٧Zjp%X{qhUccf淪Daa I=͛G}wy шwy#KX~=233e)OiƍCbb"0ϫV XugϞuZ$":[,ٳΝ+W>|.OO|*ɄolYfkz*..)))\iVZ?`E ֞={([8t:Q^^.EVZZݻw?ј{/'0BD[[x l۶[BBBb ̞=뮸 L8Q]*lʕցI ֯<:˗~R>waDFF֭[iBqK,Ó7rs@@222:-ʕ+bt`ݻCkZZZP]]:a;v iO?4ͼN O@@-[y1o~A1cƨ_wʕB-Iݛ3|wsi, oߎ2ʹ;`&D"Պ?x뭷|9yd>᧷Ip?n8$$$tuʕ|߱D ޽{~bp>P4^EaTSS\IJJOS^Zѯ&(|@ZZڈ+g䍄7NtOʳd`=%qhIMM |C9rEEEDŽGC=#$|xWK.`0`ҥe IDATX`I.űcbLְV\2 ޽{g8 VPUU D=9A"//Yb~,̈́(LE◿O-'NwߍpOZz|y+V8:%uwD:-E0)\]]\Kw5 ?( B|sE?˗%1an ֡ǾbŊXLۗ ~nNi{[Ç#//O*J@mm݋:~"󬷗\k߾}:rM__H!++ M}]򗿔(M0{/1Oꌬm˗/'4`߿٬co 7?ʕ+_$ďgAoo??W$&&#;`i%Wjll&_"9~o%WDV(ҋׂ ׿ i}}=zIl횦(thmmEUUux3/bӦM^WZ>NaE㦭 ?8 I֭[/K Nʷ~;x DGG+Q+7jnm۶W_ ;;3gT 2cɓ'S54#)˗/oaY o@ՠN'ʸI;"ϖqF< #rڲe Xx|f̟?_ָ&MB@@8[kڿz(7`߾}8}>x衇d7*++?gZjߑ{P/Mc,lٲ]G5:UUUI^^N. pႤ?w#oP^1A7{ZZ eeea0|{K(..)))>LYlMhPW@ՠHv;rssQYY)#UKJJ›oGyF_pV7n]$ш`~d@CciS|:c4%/7#'ł?Prs<2Gr>IE=-- ˖-=2-%X{`of3.^$ݍ>@B{/~i"j`cIne'rqh߲eVH8 `'8xp8pIsKbjO*sT-S~/0LʋÃ>< ɓ:p@0Lb ODQĥK?1ׇ{Orڵk /Г3D1,q_'|E0,Re˖m]3WVV> ^q𦾾^ҀNQm6IZbʕW]~c8x YYY%7#v;DQDdd"1hXc-X;Sb O:::peEdT -/z<?>SN?aӦMjSt8 `Ҳe˸_u!,WEEL&[|c߾}ޛ_W %ž?\|vHSN #;+++D_fCLL 8$%##ց [ueI ƍC\\j`0 <CIzۿaѢE2Gu@gg ctzRhAJJ N'Ο?/6 ʒmoXZ BYҏ@p_||zI7 &O,gx!^D\.y>}ZrɸML\ n&.$A7\d rӂUYY(|2l6ysgrj=S3g\rJGm.fϞb CwwwSL`PUPEX,=4Bu '-XLP ډ5tMxm.DMiCll,ƎcF^7xpss3B72͈䢫B322>fСC̜N'.]ۺ:H~LL 2FKD233ى2eTWW#& G斁UUUb[MuFᄇX,w)?!ƌ$ᰞ{goXoGyIII>՗^?$?䇂-b`:t(wX.(((<fϞy1EN ?0Ʉ;wx3\C~;Wr fC99{:y$*++%?44=%3D1om>c ,^EEE˨1w!GɛzDDDPW;x`Cnp4 hnnfRw}}=>Nfw#cTޡ6'J£>e[2>vX;%K|ŢrG?%W0hia3'Z+_.VذawE_|,u >ȧAAl#66Qŋ>3a{2EPLCLll,~!<:)`=xwm60 dɓ'#$$D9xZ5+eъ$t\@UUDQT}vł]v\Fb>>W/+&>z}HHHb(B]]r(CU^TT]N[[[ʤ|t5kn$~ .DMWoHJJBqqOev"++$0LVUUG^tR&j$= J:ԩS> j`<\]x?e̙7oGk'Nw)Sdkhh@TTuywjU@^UUUhkkSzkÖ-[dWhN<>w Ǻ}LƁqX5*S3:Oz{{$WV1DQiKDD֮]K/EDrAv\cIގ8wMLQ..(Vpݻ}իs9zmg^֭ݻwϽ=M&vڅo|ː'NT.=,U",**Z `u񪽽Ŕx>^S= _9h"Y*//ɓ'Url6S85KըHy'x{5?mp466*EQDss3nV`@DDrfbuuGΗF ֿCv\ عs KY ,@ll,]lC߇6'6leqY̚5K<҂ѣG#((Hz9"|8 7N~zo}W~zz>c@ĉq7=ŋ7r #Ѱ*Pp5Nى^UZ(**򩌫ӧ#==ݷ@T}M&>~z|Wս~dddx=נ/]]]\%Ý(Q =wŲ&uW7egee!-- HbCvZ1I܌UP(RdÇ?Pi"S޴Uѧ?oP[[bL4 999^(ldpHqikiiAJJ* Ot"$$DϫtLcZZw3{@,ATlމմ rk-ZD vBf͚HW΁JfDGG1^  W.Xb:ժjϟh̘1@R_;z0 aֆO?)f:]]dD+2 =Qe{5cp )S`ԨQL;~DMznvZѣG1uTUb-e*`vphfwډ?.lovݞ,2h"jSk馛d&Z8z(-[&[#ѣU3x Mr{fގZf@@fΜ)k 0Qo63gDII~駘1cd-w8---k+֦1 .l@`= X25U=U\\ Qe[nQF[ ưIznM2].<(k*.k w#'syrԤrFxovm &ߴEn«}ee%***9fof}O -*..^@4h4O\.*`0[o6|3f#Gd)jEEEȀδvMr撒 ,W,nonnVϣS {NCیvm$X3OJkk^,` ݴ~'1T'Wc1ȃPYMmҤI?Mĉ6mlFaNII,X` Z,Mv앯NΝvAx8eq57ڟ o7z{{qYy睲=6&Xp4Z\ =2)& &Inٳg鍊nBxx./zzGۜ(a̙$Xpi̜9!!!=ٌ^*C?ӝfUϞ=Hw$q]|h'NDDDfel6|'7oeiiiǑu%%% ,iCт Lr4EV+Ν;XtmmM ##̚5 aa\raUő0s|)DK݃j>9(Μ9>EẐ {](Bc|'''+`v:u - wqyP>9rHk ꌸHkk+\.נāui8헜Xټ Mx7Jɓ'tREr`4J} ;yWj>%X {PEքo2pEKII$|N5DMшPd>~Xq6;k ֑#Gb~PuYgt*ZGrr2]tzևd|WrpiZJ}YyȑKz͗ō6Zp+v|w =6rKE_D]݄PZZ ժx=U#p:EA͆~WR8EeǏA).DMCϟٳ pO<)7JJ9`jc\.>3IJJ*+C{7J;wnv tFy ގDҠG?SHm{5IEYfԥK zr>AH'b/YG2 IDATh_VKll,Y7j& _~%Lr)utt !!Aoy$O*z~zٔ=Xƥiַp593gd=wp:3r[9 @G8"֪Zx.O\J$|]\͓PQQx mmmAjjꐿ#nGGe+O#=z4x޼yvo$o!unGw\駟RObb" ]]h}'-Ӄ>R'}{&) &%WsU{{;jkkU^SÅ>!jxU*F튭_˱5P:A Tjn?wjurƬѾ?1}\5 ^%XGMp7Ѻn^uJfQVVJ] 9QPU/h"(s7N`E 䗽IVK G\.jF__._J]W.Bҏm<$cy/^ʢ===EQ݄'X˥J]eeeSyEH'bBAǖ~,a/rGo3#O~ѣرc L)$P.݃` 7jkii* ~Pg cǎu]5#-Xt:u^"immEkk"uGHH_\3Mns]҂+R՟d2iw_4Z[,"{PAtEY@oO4J95~?OjbRr-E݈ $X|E[(ʶں7 ,z&/B 繈 ͓c~ړ^l|u E!r[;@es:QDU__Ţx=A=CۜPfIjE]]RSSd2t" @81رciwuװxE֫.YNFT>#t"DMzX<~K.`ɤP= nEE6Aƭw݈<˗/cҥ @t 2_oxo_$/O,ڠV`]]ӃjjBŘmOܟ- qq6 555HOOW.ɤ1#F&Xǎ%[8Ln> @__]?t'jxu Tu5tbǏG͝;wna ̅Oj^OO*\.TUUI~\w VᲔEKFX=tr,]ԫR1&IO \{/hjkkX,`Ɍ&r/G/l6snGMM 233cǎU%X#s:0͒Arp4"&jfZYMFeX6]ð9Ґ ̑=N ~=!˅JY՟gV4h=msz*M(0͈R9~xܹsp-X3[VFs,ǜ7#wmõ`ܶ555&Xr"66V296htCu 򝴜spT[N/!YϠv]]]C?˞ulV։';tLd~bvFE*'ߖ#!,4q}k,ժJ=!w&:ydPfAD,r{"}?DMiZyp:hiiAbbժF&.ȋs=19޻566*`Se;'XBޜxWfzZȈ.|M)y<1sLTHa-XJ1j!w])))M`jOM1Jdt/tMu}5SV]]]㍡NDHNNV9Bŗ)MXmtvv2[Q%XPLv;\.8KP^ <%j 6ocܜC=Ǜ_/PE8)Z'MՋ5@{{*jƍc !$_>X0D͍B`jۭڧX,ZOѣ20H$\.U6ֺUWW`]y=D_=zzz4cO)zl6k] ZVq~{ OFۜ(9ӗ}] p_{CCCZ jM:BdąO=k|+/kԣ.B}7F tohk[OO:::X!Z V__*ik~[HDQl: ]Xwc`|OߓbSN$j$X]]]p:ףnB?'١^D(r ÓWMM 'N]]]؂5ӧOWZޝGI#cX3r߳VӸilI# Z-,3#ZI`3HjF2B# nnuWUVUkfD1DEVVV.w}>^2*{y}*ZD}gmBhb\tO%R)]߭K&o#Qj c[ aŇN5?֖pUY&%h=!,MOOi6Lka/ B) L`'2quޥ:_' +=X1*Ţ,{'9 '3!~YXX,s=1hlӨT*PAVB aU2P099ɻC=:{BZ籴_OY,I X8mK,&&&`6yBTv^藞ηY]>)~5e:zL X"`SO"޳%.azjIc3%gay~J%3; b|vi?c5!Vc!hOL&1xL&RNE0[~~/..T*kԸD7d'Q_uppU aS %:PT077ǻ M#yR K/(] ,~HӆL333P&K$ߓ=j\^^F.Ӹ>X qZ/3ժԞ4x]|].~bȍηUUh]{hpf> $=hrnfPŐ yA4`Kaj} roԿ4դ|>@O 'L""c#MioDu?;;帬h9,buרnݺoo )Xɇ>sRe@}O$%ObBPh"3yrHFy,|>w.CsGA Xp%΢Nw)ZC#jsIZX<˵4,SXB`?R.qMu] =WO4^;TU VsoERĽ%*j`ubH vvvhxL3o^R[xTB[A(ڮ/9˒oF(âDjr.S[z5=Dam\9Xj̿ғ|>i\rw) u "@N)jE&Q[xW,w&cr<_|"ubtɧR`jjJϞ2C,4VNN:VMMM oxK+в}ƶD" .X,GŢQhcii üKaO;1BYC 50Y߻PR,O.:9D"8R<3"# [7==-ŚW9ktIM&$v?FN.EMRxy:b" zv(?=ծrz #y&vAKtoDX ] ;1i[.M}D|vH筵%É׋P dxaUUT*ܸqC[uZ, GmEQRy'BiOWhO dl`fftZYM\>RJnܸ'x&w9D5B]]Tutk9Xhdr;5twܡU9BG{ jgoo -$:gXwk=فE?R$QC&-sbI]I$#`Hv3J'ZV| cVBP u,UX5謂\+xuj'~t?t!5B|*Jx"$Vk9Jr,+ lJ裏:]N@F=1xV{ʊkyffѻ}abbw)-1Z#JG眺2 fffT]#͘޳3,>`5|Zf!OM\.z2ΗhHXX۷i9X-c~?L?T6??ٌ.^(ԡ;Z*p-y:vCVwaD4"GjG듙n6fvv!C3r[nw)'-hD;k`] hبEl䎫V(! $9yeLMM!.E7 S??zyiFN >j!N333Y"t u[Rݻwdt&6Kf_#uP ",=V{.&''ɻP,Y>Y,ە=ޥhNr4`i(`U[bW*ܹs/_azlR`ffm>L}d䚃5#LrqȑϚ'uuT*,.. }[P-#e g;OݮߢDoK޽aV|s!'W(077' zb@z^T*E6FRU ʻ X|VfYuH$P(066$,BjDybpggkkk܎ot& 6ht^&`m6r9u1rppi2D"uTU! 5^09FA,5SY'n"`R(033ax^pk١QkORҒ ~iDԢ(b09qTA+t2ׇp8RUQk|}݋"VFX,3*5Dtבק!jV3'fX\\DTS)`Njb b+"appVw9Bic Obܔa!-z;N&Ǖm+ ~ )ٌr1<~IӘF?:;;ych D2X,N5CŖu(HZ_^};AfO.J~$@RtCw^WY%_~RjPmՉdĀ'DLmy +J-qޥHžͿf|*MmC+ XXX@8FWWq6esݳ*?kf?FKR1,˩Cݲy1"N_ȧ;A’HH4.ժ,!HOo,>;~]E~ueXp^+=x<=aMڣ' KΑbx./zlx|4]]#nܸ@qB!DJ%lnn"HKJA{ԜJx#LJ,F]d,|>&t# 0k|X%aww\0ҵ%{߯1,%Ex80`ȻM IDAT)ĥƴZUCӧJh4T*P(deڡ:[(Jb /@;?+`^R`h*z|~4GX,bssBnC2rx:KRA*B2:::N^#7FJ%R)R.gj"bT*}: pph~Fj'ޞl;`IiڂjSm%dBnQ(L&XʈF6WTF]yfw#fr,Һv:Rh4d2 ׫bFD8rRx]W,H4vZ/Y,<,yJ%l]N(t/"Lj>mFTt_E1+ ɤP(D%i@R L"JJ`ш|+ JX,fÚ&I\CnɄz#>\.n7S5!*Jd2HӇ+ :`ED(Slkp j~p8s:4d2d20͇aKUЁA}#?_VqppL&C780H4zd#X7фP(P A\.coo{{{lptwc;rd28888<dmg:xXWWH6@:T  4FX,"H Ltr2&^:4Uxpp@ %Vg`]z5{֭9XVC[4⤋8b\.vPǥO70b_#t޶UUdYd2Ib6,Ѡ(架iի;: `LadB n[s -A\>oZrʤIj|fԒ +wv]spR -Ÿb23 ioT 6 vCv!Թeyr9y42#H$ww:m<4,)%RMW(P(tv;-f1kZEP8 Uڭ!yX `7Y4<%͏( BChψHRA6=mZnQ*-ajjeVΗγFd4/3͆B6s7N&MN T*!N#NztlOP8 T_ƴj4žA-;=ࡀu-gQo.롡w- J R +X,ZZ̷cARAXDX<{z>=kɵ)[W\y"=Ž IVGGnܽ{WעK{FJ#"l|3T*(JX,\kF82Ϳ)SN X4]e`VhiQ;zG_w4tY,#]"uhRVzz;>^uVU-r3Y#XRUѺ1THms$RF?vtb=tll6z\tjJr0%RgM=jwRZ9/|Pi:::qDX"5F@:z>**2a:z]{Jϟ^?z{PsB++WħkZ X'ݪ˨ZR9}z:{(_:C;“:I"&=\4]kW\?Κl5oզnloo7휜^CO=ћzkѠu<|Ɂ =tQ;d L~jOKt-}qVz,֠D" ,NP᫝@DGZ_j?=xya6ei㼀k4 nr 4:6(Dr:ۡFVu%HKQW!Ɋ QFDBAV{t͓XVD"&נd+۷oJ4{j4PgfXYYi8AC]lg̊d/_>uV|, ӉSGƫI"lP=uhv 190zyǜ9% ۍl6q"l6ЫSFDM7͆&ǒl h3`@HvqL&z{{ZEԡunjZF:ՙ{o߾5ba2_Eؠ D$,{Vf3v;c ˗\s]] IPJ4?N8nh;VQB(j l6D"&b5z%е󾡑UJbF:n9p8[:ZC#" ]fۙlys'Q72H/!xއ(‚lD{ԡu=ivU=4tgрEH<L&cxx{"lP= D$<:%=Fр6 ۍ}͏샨Ԉ((IJA׼cIx{h05&''Wܹ3J[%a(֫_SuhD$tͳuU\.c bjrr Qrݪm|ܼy{FQY"V{ła9(25>עO,oZ, H;uhD$d٠^;XOȵrd=\̧i<.z&2`QuhD$tkg||{/ӃiԲPCX;w| FX<f3*dMQQP%|>A&2L2>=K.5]S㈊<Q)ۍ3sT0nܸXQeڡӱ!9AɀU%`5r"bjjJ^L\PB:lf6 etݻwl$sݰZ('5/vՊ~)ba,1AXVU^6l6x{ΥK[y9HXɱ&&&C Y5ŋyǣLwZ XˀxDx,Q=ЈHg>(`5eҬ.fZrdo||ܐh:46(\tٱN*lLӔߥK.޽%Ygg'E=,tݟ!`s^z^/]xZdvl63{o|| c遄4ԡuK.1{$2OZ X|GZy=R>xqmr9&# D N̎WߣW2%n[ H/^MOOjY2L۷Omԁr: ;)dh&&&(xbKO3)Hl6:::pppxØvѳP=:BZe6b0]tΖ|l'`},Պ!,,,09w KD422]+UӒŋ_=nX,J%&2 EA Y6odjhaQH< /^LNR$ XhN'Ţ ЈHo8# @g|]?MƨR#' ˹XD\6LQ%j3͚,,zZ{( ^o?cyk OQ2;fWW"H#gaԡҡk===L`2S UX~D}ew ^rhTD֡c5o2puǴX,pL)jF5 .Dggg?j(`0~BBDM(<8~}|>LLLD|A-h},610.Dp lu NN)Vn˗[VG'i`-vFZeZq%ܸq1y U;tʕe>OjEUdگ^z%088(cD%З_L Kuؽ*vq8iB bv/hB݌%EQ Tx~^xp%ܹsGr: Yrj97~kDs enn19בf-No|Qu iX"n*\lox/ia0MωRBC<oԡPe{uuwwŋ\d_P 0EX7??AOxgY |+_Xcr:x|A&{cccfy@$}!:QuuuqYfQ^H/BXS{븄+EQZe@%ԲS{UZܶ*܆ wwen! @B{ك)^0 !NP(0?v}>.c#tj".\k[V2չ j9s?ZȒZ>6Pկ~caQ%zp8ZwV8D"\nKEŐ?֋5g` 6DQR)U_ѓ3H_<ȨC#D.tͫOQMovkp"2+<-`'( * VWWQ*???i.矔C#._٭~6۴5:::6^:MQQuf24-jؠ KxhwUms}< : x"k6ok>s]6Uq\})lBģ( ~in, "T01::³Ľ7Yud2vZ&h>oG|ҌIz W=;\}z?p.7ߏx<ΥC&t!=r崳vC-Sp'DXXX_]~?,]baF@тBlww7{1nǷz܎/n.`VB.޵T*amm J2o"Hp9>!#r xrGC(D"}B`aa?wE:f6tob/"CO=x3jr! GFF~wu E=;;;'F;/"Ͷ:5"]Ӊgyi\' hHw!uB,X\\52AM\ЕN/rٔl6MofrkLK2p|"ɑZV#X'n(b ncMOOcqqk F"uHqe5ԷQO.4.6ejd2o7nfu6;"A8NM^[#{&XT$B,X\\|7]h8RTS?TV+`ww!}$_z񠳳k .,zX6L:/-lmmq_N2ZD ѓ@ z8'\k,B/(|Yu\.cccCEH[Q, ==O?4-pZL7<<78.,--}C4|EHptT0!K/'!Dr( ~?m|2S in,--}λ%I$S?9hr ZD"|˷| 9W~kxxx(,y"h4*I5>IDAT>BKKK@mޥ Bw{FmJĵX,kM&K/D|=DŽ5s;Nְ~\u!BZY*:s~\9_bI D>O>P#EUC~qhhy#,<ɻ%IR)e*xWhwB{,ߏ׽uBqzz7<544$$>`5/*P<8kU*kW}75@yPWW{1sBT ]H `yywbo͝uQU߉ڵkB^G7췇˻5)`#1X4E&i5n077G0!mR.\Rс`ml y,X^^~X6޵nwww% ܸqזYB:}QޥcrrR!Պp8 ̻=6BX2`S=Y(^ T*bBns6Q(W느Fl6\xݼK9W}Ļ=* Aڀ??CPX,bvvK!*ҳ^\pAn7- ڂ#SH~#-XXX,F}(.n'Cl6ۆ8o_]oY[[-L&b1ޥ6Q`0/r.a4]ޅkkkwxסwd鍢ybmi~]CԸ\.LLL  .)aj~# yעwlx\W[g---1_ց)l6 c``@L&N'R3~.{(`BmyעwbXLEI+X]]ʊj'VCCC"V`P7 g#(``mmyעwjX lw)M+JX]]fGb`ppX,iD0hVMޅ)֮x-}U6aT*aeeyJ<9uf `hhH m*xBV[BDD kkkgK"|>xG[p8000>M^?JQ~]ǥ EVGxb$R XLK"TU`eeEwr t?7f! v> (<Vxb4T {{{PE"+ӵFD 188ϻUx^tvv.È  XMX__x޵M>G,3SzL1I=klFWW s &kjS}}}qޅ&F#L?T*a{{HӼ!nD"}F5Oy'Z/4fH$ 7򳷷͖F:%V5~f~NբY}vY`jdҐ>rܤI1Z{xG4in7|>'䷂߹z{{V_"LP@<7잀a-Պp8V,7͆@ 뵹t୽]^QjƏЍTU#Jn>b]05FjV+B =( :;;x wD/ 3 X*x?@WJVH$E4BaݖZ,P 8& {{{i6QR;!:dNL&Z"-M'1BU@mDͻYC0 X* ͻeR)d2ino#q$ d2%\.~?o( \.:;; 9A_PE,mllCBD| ðee-&jW_v  HhnIl}U, lll|/C&H&WV; \F\nazҌRgX|0 XP< kI=dK1?,R {{{C*D & zzOܮ'2K>z{{) F666L E6rd(QVN7ۣuLiZ7z.1p߹ ͳ~~, mllX)(dqQU(x"l6=d2/zcr^/mr /3A|O9 X4F.TFlP,Nqppt:L&xdBGG\.n7:::vaZy&<ՊNg4\i jkdw(hZ"""!!Q^4p8p8t:t: V0wP1 X mnnd2HR>qRtP(X,X,T*X, ,(ZX,ZZl(!sX,tvvr.顥&-F*t:= ZJðUX,\.ZRgZ@2L0L|ҟf0@ÔbĈb񞞞ZD! Xlnn.tޞaou’l> VtUUC0Fwc&޵Zd24EH#V.8*~6nG? 螅@/;4nu.DV86L>>xB9Nx^ZJL?iޅȌ677E Tv&$!<(r*=, ,;ޅȎ Y!޵U*Ӿ~D:=L&6*(~w!P7xBNW_x3N#.8nZXUfyޅ X 7񮅜T*!N#NӨ1 M+;λr,mmm|IQ-G*zPw> 'gP֖ڊﴭΔJ%d2iZl6vrh>{#,mmmҥl6L&l6KO !( \֩B(`ַ+^޵'P"CUGGMXg@w["ky> X:u 򮅴2 r-B1HB(`v8Z:* -EQp8oњU D" !3.yBU[l\&ȓf88N U?D2 !C _[55Bp|>O l6nntj.~0,.loo;P[+mk!|ðQ,yD`Zn@%OH$B[B,9&eH\.? (l*̻,_"GxBA`BmQ^޵qTU  ?ijmL&XVl?m6IE@mxBCˀ#3k!b+JBRlHAj>h?Ҁ/xkWW6B(`Ύw-D_*""J_rY[l6bλB4%~޵B$tWW_.AKr;;;?] !4J9xO5ޅ~(`o9:!`8z%D5ȡQ[aw-3wx8~w!D 4ɝ0<9C!zPD|9Fȉvww('yB!w᛼ !,r{ S~@s9" jmSihkwww s)L8^],Ұݟk!b~))B>P"M!?̻Ba/3.,Ғk!Dh 5]ZsPoyBiY4?̹BQKPhw1D(`E+B~1 M.,h4~Z!I~9 B1:XD5~r!{YW)\5D4Bm N.P"‹bWQ[᭠[ȬZ@0ŻBBF,N&{9Cag !b1/ 8C*`0H]Et+Y_r hTCGS@ĻBZAB<3w.?U@ %. XP;1vBΗGmS!D-!n? 9Cy@ ŻBFZ<7vK2T9Ԟ| (sP"҈=~QQ"F>6yC tP~ӄh3V}1PgCBH- ;\\!FpG|"DyC/' Q\!z _] !"E1x܉ڄScѢDDzMX,z ,BΐH$\ݠC-TpaQ"AD P [OPBg~? HH(`҂D"C Akc)Bg~s=,BڔH$~ѭ7&}q]E 3n|+"LwPS/z1 Xh(H ~z37ߊҨR=9߿̹B !zja\[ϣBTAN jA@ߊ:|}> !(`"d29ZЪ]`Z]-_E-T=!EɤS^zBQv_ǽ0GR" XD24xs-hm p?P|K"4!:L&Avbϫ.ɠv&?}>_kUQ"`ɤ`GtV0#!ޟ >cB !H&NԖvϑ{_*3%P RS>/˱.B#!H&SLXxF,Bȹd 0Б?|l[@@@ޟ]+|>G9,Bju<9؎}o'}}t+A!jNIENDB`jamulus-3.9.1+dfsg/src/res/mutediconorange.png0000644000175000017500000000103014340334543020417 0ustar vimervimerPNG  IHDRH- pHYs.#.#x?vIDATx?H[qǿE"XdXXq2ԥ VMEMQPR".g[;PR;wqPکN5w~_QA}{18Q.:3EhgC1(X ݨǞñ-M!n_p/ F0mh$ /!B-g gq06/%Ӱ'49{ߟ‹g!*kڋ\xgQAƜ %a} @aJ4=2lƪE?P@eM= Rz*ޕ}9m<> }=x}TT\y" ޔ^ۈGg@/sdžN&o!r^8tխonJ rwjeld9B-EiaX c<%L)/$сQϸDxC R aeLIENDB`jamulus-3.9.1+dfsg/src/res/CLEDBlackBig.png0000644000175000017500000000123514340334543017331 0ustar vimervimerPNG  IHDRH-sRGBbKGD pHYs~uɍtIMEfŻIDAT(Sm;K+aq%K6- n:AVb`c`_cmXX.xE-`bvq4'AL5 ̼ü8<<,jMU7+WQY^~LLL`>@ш{yy[iE Z1fhr||\?==%c\@Ue0ȼql6Y]]펀f-S3ڍ^5+++ߏ5 s...H c˲4Miۄa_4Mɲ k휱.RK,P($RXk1Ƙ Q#XkHӔ4M< k핱֧  %&''MYDF0T(X[[X,Uu^:N,"{nt:|~~yJjJXTUSTG{xxEdO`x8}Uݞه^ve/j]Uw0=/ J0|5IENDB`jamulus-3.9.1+dfsg/src/res/mac-jamulus-server.icns0000644000175000017500000061526714340334543021155 0ustar vimervimericnsic12)PNG  IHDR@@iqsRGBDeXIfMM*i@@FQBIDATx[ t=kHXdQ HA@zA%Xx=JAZ=v=He9HA#Me)NYD $dd3Lb,o޻[&_itg\8_;2( AIb"D3xhԔba U @ ?%3/5Ejuʴ +]B= . yڑ4 gcKfY͎&Ixp>E4U~bbb=ܣTϞ=UNT&M,ro~(4ϼ N"Y^ khCM>]mذA8qB]~]vt:Pj׮]jѢE*99WT@?@N~РXBfo0ӬGe3Ott3fPeeetY5|uw[2ưJc[BhlD>Qfőcbl7o!`N  nQf͚ ݪHI޽ͨZ?YWľ Cy~ФV)[^*UP1PkKbftx1 `cUYn`=bӄѓKY}c8dÔR?$k×QJo([KG^#@S y(P~Գf.f 6 ɓf_I^/Lwix>9r8|<AJ4gzsJX{7=^/+3f=*1IKJ&S"?.ÆHhBsEHӦ5m+& V#dfXoڈ)aΝsci.lTQ1^*>1\z;ENwJnQ\"Q&HhHk$7g*.`rc>|pfJצ—_Uei*?̮?r>x= Ev1P-[XIkoתYf U,w St*V5 yQ\@XK^9Ex&SOzI~Ȑ!☹ΨBgw+̌BIbkl Qnr-GbEd UCeM^._oEaZ}'{ݟ(F֪FK.NUS-9 1F{wlG~x|ekZB;$eNG װv9hٌ#Cj9UV#d/}B8Hǃ eΜ9) ̿ FRxY]/O Kp9Ip[I+`pyf=6DCTn:u Ob\ΒYs$b|0_S.COzմ;v7pŌ @pƍs+\oLWp}Cڵo%wF %KE"2}3 رc,=^x.a}~a| S 5SʠA,-TeF?E$mυ~S}&<&)5|u~~qF ?PEm;SN ۾*y}J7Gy t~)7!:|p0 *}NUq@Pyd.65ypYu|!Pui־^u:E"_8fe>+)8z6Xcg] ̩O*4d?@LS7bSρM_t ;N_Bs<ǟ @gm<h L#~( v#IENDB`ic07 HPNG  IHDR>asRGBDeXIfMM*iHwIDATx]E>w2H$EE 䁢5,.]]\®Y1 W)E\(AD@\{wvua s￷©SNUܔ@.AچEn, r 88NkO:6+*"v``&U V |d I'"W]%AMb]J DJmgJ"M(bMlJ`> `FamM!p "|057)߀ 400wq<c`p:"Apif]\4&M$Qtgt{s\<PX1'z@ e be7Ni%/_y3} ⻡ꟕիWc^~=]L Ԙ1c=cȩVsm,! $ f!"͸3_2mW/"7/iڵF\=g7\#MN¯F1u1en6iD͜93=,Oj۶mŵbwn_(1q4x6l :~Wc̬%86ptˎ:9`W'^=裊ӱJSNU+Wv*7(/XR:\95pH%⎮ꐼ| (k׮ϟmWKsU UUO=5.]8w n{e %Z,͉p-!bkb f͚yr>\}צ[SS۸߻:*!MyݺuSOuSfԷp*Ljc`T!~$bs#J)0N*6=[9{kFrsчW{hon\@hMԞ/Rk׹吔c<̢gՔ^w̽&7p)% տPG0S2洋Mz|TБ V^]U\ٱ |5:vuqn,ޅ~\7i+Wt_5݂noyHE]80 ֯_@-rzЩL4>{w` UQ QxtΣН{uaRSS_rjsPGʱ)OJ :*dHO%{>גVZ믿.evxktDF8raEk8ʣЍdA&L . /?Ih6k') ٳP/aPndZby?hsW*zn:Bn:Q[-kJ h ; R?N4wQq5ѺwH]"e*Krwz0wգ3 u^0+ <䓆QFˋmh u =G֭[8r_te8,.~q)t E.S>yw}Ҽys{7%LXJɓ'Kr2'ITooE)p䴐9 4ʜgBNElR`bp4<+P+^1(y"=ű VU2n#*'[-)aCaJ[nOKhEm`^8\ 8P`2F^&JuEl,U* L@*3/R$GzF!ząƍt`ӟ$ y_9*KJYi넽zyϮ{q?uM8n 1+v :MtWaw*|dJ2ܓjג n+I z.WI-8{tiRgE#HE~z_[۩%m3gR]!Ǽ?9u&6$Ze͙'9IN6`` Y(hx1E3pOZ ^ DQs|%:upHʔ˘;Wp\Oy߭,r| y?l.Dh]8}8%PSM4D%`=/ JZѝ4>3Z3%mGƆir*sMg/H0)ծ) C^%9+?/%()te!h(؆l %0­c @](snCB`3D~Ȇ`Q9wB@;vJَDsd6 ߓOn3/@+\ ķr%7ʼnÁD@,-:~_":R/âbte ? J!%ڙ@$Y w*2.&ɧK1f;V t:t <-M*YϷ5>Bt縲:6f ɸignq?#=0IdGkS%UKICRMΞ~ar/-0,1W>R?Pq̨Y4۵kqT&6R,+g)&㾜ӯ\R'ޯ*̽NŧX$h??)crV>rD(Yf"/١' 'ZE־5 D&40G&*/~ >n-[VtmqqG\[cPNw {ق~w.ϙgHd"j?c?gh svǫ뼏KwjsWnRҠx]Qbe_Kʁol[ZA‡6Pg>ӳ%p{Qio?,~oqm9Qeiv K 钷)ehЂOhx9f`v~}Bf:X5=mmH޹z~IE=.}|àgXv ԫW`زe%ˑqw妧|Ec]!l'1~)Sg1z{=%íA?6zO-M>? '88b9zCKZS3̹MP>tqr+ϙ3.類T,wgeco~h2]hBou萡ɞ=G2#_}#X^4)Qm7Pý6dLN u ^+6'Mнi00|<=łO- ;Mr?0o-H8`Fl熹:Pv-ͳyV2dص㏖~eՑB-"J$cxSr ].dN,X {]ʚiÚ6n4ic!hARr:^6crJ6m] `+qUxXT64%?zL`Y'$t|]e~%d%lË `]˗˖-[삔-?Z.ؔ[;ƬL+qd4!.9v`ˉ ;N|ʌq8WRq$ *X<Ɨҁ(N:vot/ItStQKGUfp%~ Tv×8VXc` _:\Ο-\ei)l{vJx`=[R qN,uextbDx`iSSM_K={p0[uav ޺Pp/e6!ʆz09ǯx82w*OZ>d]渊&o 8rm8wjoj/%\^v]kq~h+|5նP+ ꫯ7܍Ծ'_c7 G7>RۿҥSѲȉSd+## NVZ۹td06lPuԱGjX5pj]"?=03(U6U_ pfΜ߬Ul"1<3= WRNϨ"@Hƕ˟JJ;DʃE&NhFHop0Хp+˜#܃ƯrJ`, v5sn,º{'7>\&P x]<:mSDtJf2<Q.=ջs _Q6(/!\C^o8Hbڴi~Y$TݻwmLZec9э˗ ¨%\Õȑ#/@\oMX޸@!aөp(hw<i`FSⰬ*}VSO'\`{>(ujppqDXۄw-L5-g4 ͿUưUL^yBq4 >N .94)P<—CiF/jfn27o,xeʕIG+iǠqpcá`E9shZ)a܈0Wp:ۼ*8< q*V&e'ܹ_}bWn3~dŋݲmy뮥,E34wSW\qym`rz}6N 3HjZ ?DO d SjҤIT`~,A-ޞj|yR.7rʧ hL>723E+X}Og n5S_T hBV&+3ѣ41&N٤L5krW͇DERXe9.8QAQ@%UDu_0^(Ln :/~\LҳgOcGo֭ F%+l>{/?pC+ZxàHllur.{r)~mzR2%="TbE9#&5k@4r^)"p=@kTu@c _Q)%iؙ^C*Y7xls؉A*V{<8[.] ' QWJu(ݯd*Ӂ3WlGr7]k9͒68aI$CS什o"I~xzsqwČA{'I[/1!}i, VFHcĎAX mrESkW/=_{DCɈd{[7#?ZQ!\ЛcUmФ.b )Wp[vg@4 zGYyp崏/RDćganĭQJ>2ex"i*E߷ xW(EYniI!3y=ۡAtdJEHaO"Ve(3j/,.YJqgd2E!Q ֺ|`W#S%7XTop sUV.D XK4X7GD r? SIENDB`ic13G{PNG  IHDR\rfsRGBDeXIfMM*igI@IDATx] O_wvQd I"I H4DRJӿy&JE$ BȐ)rMw>gM{},=gk묽Zk8PM*CIll l <  v?|.R'>%@ HSis xDgS|rSTf݂=h+Bb5r\Md u0&bu`p'p;R Pb[JW <X{Nuo;3'k<6}/p3pC@ rZ|ȷDRI18W mIS<As_ [1`,{:9@CwM/DÁ|;p-5-yu& U, M1~.d.RCX,F5]3u16 8PRZ*f`#`ӀT!!YhH!?0yוh u@Uz0Q-|HzDHz נq[y3ۢ\[ mu&pp->$k;4} &8n #7f6$#Ʃ@8x9-`7yぃÁÀ:^1۱>蜖QG2X j.j؅>m-ρC=T~~ lBg?mn^ۍ>f2P; 4"tĆ*I5 ȇjǁrs@ny Z '[y=(}]4z}g.(+q5ClpJ64% 5 jXBhr(B1/;;ۨZQvmC5;}X~}VZF*U Kpah@WXi/>̋@:`иB&4AcܷS@{@Ww>vJ`_&`"KFI&ҰaC$:u&tA2#ii=%%%RXXh={?m۶o&ׯ 6Ț5kM6ɮ]\l\zX.e+x)@3lo2!A6F*~ n=Iث#ǐO` |5yҾ}{СmV5k&u5'y؊oP8lٲK.ŋ ?W^-wsu;4DoVΡXN~s$cK`B#!r^} 2m|ȳp4xv{׮]cf2~g؈`\Ҙ)hu^~:A@9`^!iU)v*q׫W4h/V2JKKaG!??߀f`FϞ=M|C_S 88hSHCt2?AgC)ƥw_B58Lb@Վ:+|`222\Yf53O)-~zP w\>;iBkM\~=nݺDJ4r2oiigGK]9=0T~^;̞8cԨQuF޽{S'xI,g, C {RF.nև7L< 31?k(Y୷JfA5+­Ua|â8=h԰wi5 G]vU,֫qPp;񨣎g/~;|mEq7փ7ߋ *˘#PϓW~{5_ݼ<㡇2ϕSv"0,pviX xf_vZvTXڇrZ2dI;C}ڵkaÆR{NĬQkI!DWWJzs7ѣ[4ERٳgpwўKhRz+@ChĆm@hN!>* m.w-@-O> 5fd FW_}3QsC:K+WD6  ]d~iP9ڿMZT9sѴiSz? ?$.T_DN;*C -έNׄ-BmW^y^ տ)'sKbϤY}C7def7hBie\W8e˖`?'ov#33γWٱxl(qeЅDZp+4)]e`ۺ~E۷oi=ӍC9s\ Q#kD4Kq~Hߣv0 zuw[(|Fɯ;v "H~ѦM?H}PS̅ "Y5̉бɍ0H8Pr鴞~iJqGe^H R&1vC̔\IGGHVյ\Q^iܹsy:'X cW.u̴`\7wPͼ#C ecA+}eNI&I߾}[TU)|kE K0(xKzd4Dl68,,ep F:^ \\^ԦÏ2&.]ۈVxkR"s]Oud:)cѴ8j3+Xk.טء%j7Xi h)|KLE_:wɱQJw"F\ ^'YJ;UJ/i<")y=TDzzR 0qi r饗ĉR !+} | ؈x Tiw|URE.j;\ID!^iD:UTعS_IԨ}._$v哱m\p``gD6F[*oƗ.zI QǷ='* @%9|[qJV{][P. عK{&z@@>} I.N@5W#ÂE2t_E#Pqo@nW{TZ,}'{n{n],fOKӤS*g Z,bݻ]i~;РAA19`GC\G=PjEZ 'N=T=q)p ]U\B5T!jzoLuK(H=^vLTF:i(U)Ƥe˖IKlhܝ N': ׻~ kUM*V #P<+{?Q%hҤOo?!ŗO% _Z|IVMNkp2| NK[A<|3:T:Be-Pb$iyc4p*ڇyL6xؒ;\)^9b|X)s0`ߥj^f]YnT,X ?:l.goٟɏJ7opoxq[ ly;.r7~xiܸaEnvC& TC}Xꆅk1E9,xq|{?% &Mє)SsYq>3tNDHk^oKz&N 8qH$_ ~7'熫K 4Mh}}GxtcfB'wc͗lX(ec{Rd7ƌ_4Udx!/[rAWD#M/?4 X ҵL8z<|M[GroAp/[Fa^?J25 ?pBGR*3(x =`vΠRi03SOƞ=%Gt`p#p> _F1} +b@]s1 6Q>4x)#1lA'=!;ve0kлᆱ2:𗊕+`((#/9jԨZW@f'?Zc^9T}I 5  RT wcBD64đLdz2%.DyY%?֕T)oֻ ʕ+裏=Y Pׄq o.:t0vr<8%70x,:lAVViu?I;_#@%NIY5~Tx0 g%]{-ÇM]*B{l;%G_H˜yx VF .茱IP21 h2d1B:(/H6/x gΊmJVމ3$Y._sh,`xUHP~}s_r%NO_qc/},SN,f[v5k̓Gx13ej!iXa"N8AE+30._~:ؽGZ fΒO?/iKs6!^`N-U|8]W^mV)l2%X-A瓀/$iܻۥK.h^C(̜me폆8s'xR;R>d47=8Sފ/VO?o*rv鉺tR 5Atu3*Vh 48; [6{تvM*~!XoipGh(d9Δl{JќOe!hn}%ZtD&ŒڀQ*pJtG"p']L`;vPZ{ͥD4a+\[1bk$gGM3oEKJ_a:* +T|XCZ'(gDz*gSTJ>jRܺ6YGz6~i$k/3TOVo0qnM7`<hF*7Mh~7&iut 7NnDqL~L(>C?wŜx9{e.Q<i/3).i|٦] 05YNvb\a=j*4B .^dP?sriEgRG, %+~i/*~y"7ThGn)i 2 TUu^ }~ +}ĉ涇(ZM8?,x QPa/ZMFr@9gOyMSdR]3H }tF)S-ݯp>.Dm)S)@ Cq'.t %\^t=+ `@U:6_hN8;TI_N}ei/Da{aA٤wIב/Xs{Uq1 @" tSf/cn1q`c۠s [1Pa3h{eгA3jq]@Ep],+LW_8.]-s浹|f.yGh ܲ3 U ?% ժULWǠ'%)Z$btoz1s7óͷFx\ɪ`+Su},U,V)26ƗBr#YO!u [xӦ#GI=&hHƶRC?on^栃0T͚5$+]J/h [0 ̶I~o6kpƁg 3;0~ETg+˿ߧ#]3 aٯ &^~ Pf p?:n*W^yPhp|Km5-HQ]9OJmz;wIox-V$Jajl|ןq#VLup(1K`1% t1S]fv]gF";ܐC_G͛J% rJP^x!%Pbb%'V[S .*P֒Ѷ ~}̬=yg|6Y*]v lLNuvڵk/,u0&A`/cݱ0tYo*WiÙիdo<BL£ne2)}[sUUp~fv_We`zf_l{_FiT[s'v3 N! }#킁S+"~Xs!lVPFErPB?С}0bGNS>Fh&Ǟ"Iu\g9m'b9|ȁ_TEH @ R+E@7tG}_JH\ٳ;r B?بA>\( 1*7A`^HE `]Pt);T^<Ȁ)4?gʙ{DA7}ݭdu2 m>X"}쩲cmZdy{EQXeW0:*/ƍgZ_׋́>lV#7k. -۳ϔ[Iv$?hc柴JM0Z ,gdRDvc`y\U^zȑ:MZxh4$*~f;g0fS۞>ԻJ!fB3S7>kQK`eQ7(G 0<9Wl/Y239`Rl}$ _5H[MʰH-E7zhGb ,+qep&1GFHEthƅ5"y^ɉoa7 )j\3l*CJժU+3fL1I4v@ 7=ˬlu'%/+ȰbJW(X.>lذA͊CUz`WydlXc.O xƋ7PaOd? P3v?8Nݎtܴ$ﯔtgϞخH?;Sgxhv̉on 0 f mb_(h8MBJ:oV}XOcꪣ}`^~&=uNFU./4JJT~!oe֭*ehAPi_~rI'TuT8Z1jl@$w^֩'K?}b|Yz1kL~ 8~PXI# ^_2Fn17S{kYrݲ s~!A*>}پ]Lf}YJK&/5~w%KTY1`T#?r+MG71vc%%{Op? C{E|rmߪ [xz չ`2tj_63HpvPMD3?~nBOOېmŊ*oB%s g|뵿 < ی 1K`~٧"kg߼yʓ÷+s?]`Oj4qg}=~"v.[l'DW_~%|(P(w \yk͚5Z5hD?񌒡 ź?NѺIsQ@Phx7c5hDS!a4LGd(ݨ?.QQ Xk.<~ mw?MHR"_|jV0oa0+ nYZpߩva!鋚0'il; TlÛ1_WecOߌ@Ov0v7|W`&<)lC=lP X_~U-{̊ou yGO=yz7s 3nvV]88VrY.zdOɎ4(hP8])~ѷ/g}a4>3p<< նwE-Cm Ǡń{|i?o[ewˎ~gK!cS}d2 pH[z)~*'31m W_9s-Y&+07;x :/nB_] TtdYUud%jpoz< $g@[N87lؠJ?;y*m^/PX$-MFYD񗁖,LЎ_O?d.ZHCjp ;ފ[r K[;V"5a ak2g4bTcV_7nӞY'8ܺ&k@ hR>T}!\$pK/uXNOP F.iH^U83IN^sT{d듰ϗK.D~c ()P\d0c$@4X|$]O,5VjLhFts2)O N(D銝tāʕmp?~=}RyQ>ֻn^yyGv㴑@} jӅ@Cr~AsTi؅R}s"{|͚JK ֭tuٳU+J/+PHX\x>X{T}>'`=zA#56F@XS93$‪' |>\5g&+N:2c ۷o[*wBV v+F*Oo_5R}/8?Z-C pR*O<,]~[&# քkԩSeРAn{ G;ݼy_b~p ,cT>5SؠE]4P@xJVqG`V2q΁l."2"ngL4 rsϹ!mD'܎H@u at173 { *?$&  ҉ F#9 DYi$ xr+駟SEC}2` e3]r:6q#I^|E޽SFQY-tc~Ӥ@E {{w[;%^]?)J꾪W.&M͛;'c5`Pf>upy1^s8miՔ*w[1YN8S} R͙`>OwrgϞ6[;wJI"Ps[G%)Hi}wB: qSX*V: Hر]怑S/UMr-r\8tY/_.+V(F۳[BQѻ 4h ~ht~qaH̙9@ srDP=<+ \r;J8s=I^hH`o&<蠃97o?*֯(;XbAްa8d1 AՃnGs 8о}{uTO.3+ DoH{`NJ9+p)٬nKs i9%ίLAh:/׭(xej—_~iZ8?^o#yhxp[c`(@ h _w͔Р99L/NWae@p` jr+OZ`|Ss 8аaCU0hQN@Co:.HkI'5hhW `T '@zE*rܹse˖-a5w86-2[irwÀ;իUk3́/^%C4"q|1MN+N2tF-?`˳X:z-/As@s`xfW-EQ#  0 7nnݺI$<<2&uSwB 9޴ |'Nu] O[+BnVZMp裏V:G٩x &sDqM7H5C ~r\Q 8ldddW9oackGTz:t0`(1}t[aG]v@"H 72_} [;QR3Oi:tjժOsXK߽rﺹHxꩧ,.a-xetvҩ'u9;4HlpY4uf71P c0ڵ3'@ҥK ø! In0,Y4nݺՀ_*wx>T?%gycɓ<{hRJFɓ'oyF2p[51UgFf`75ae5=q_n|I"fܠ.](TA;# 'S5PsO{@a0sLcӦMZ1jea3EC'V"- p,K'Amy|B:u,=z,!1]xXp0N|YrJ8O~p0u08}vFBt*CBm۶r1ǘغukC3NvfK@ES w~=MZx o!-XN >,tW S"/4YM4͛ {)>`S[`fvv`OOo FQ zjsү] ޱcv=#r뮻Ny/h.pC0f0v¬J*+P;P(`5|HNźDNl쟛y/J c:uuY :ؐͰK.īgAH云B<K#LԼK_s[u T 3 9Czƌǹ6 aN1a„!.a`KFp-9½hݯ~t^A7Tm۶#Fų;ә_8]^b{S.$,3,8W)`>LOF͚5~؀Gd*̞| G{>:C(}_|ĤyD1 SIڵ~ҳgOae߀ħc,A*6aww,g,@3bI;n9,LҩS'r-LԂStэ%װ7S}7ftH 3Q,SԮ]ԨQ#iڴ L֒+XR`V۳g97olfegf_~żr Šx"HOKCħ 0!=%'GIDAT> M@2r5 j%M++6>jpYF[v?H3ٝOs %8@ߛ G ` 44Ƈ/D E99)G߄u=>j@sしmpsY^pẞ.01N @pv M(@j߾{.QRE#m'׏'p/h$h~~Pn䣯vdSL`Eoуqms?g7j x|mdƀUs;fD {o;F]h[CM@7O6V < h.D`:0pWX1lkƐXJ'Ӱ MPW~tDW} ?7x~ 0)?1~.r`]RFxw8xz[@#pKTxp h;n“h,xc2.v5n?Zh .f8܃1-dU6 `$WXO &Êc#0 Qk1_,qTcx'F`d8xbgM{},=gk묽Zk8PM*CIll l <  v?|.R'>%@ HSis xDgS|rSTf݂=h+Bb5r\Md u0&bu`p'p;R Pb[JW <X{Nuo;3'k<6}/p3pC@ rZ|ȷDRI18W mIS<As_ [1`,{:9@CwM/DÁ|;p-5-yu& U, M1~.d.RCX,F5]3u16 8PRZ*f`#`ӀT!!YhH!?0yוh u@Uz0Q-|HzDHz נq[y3ۢ\[ mu&pp->$k;4} &8n #7f6$#Ʃ@8x9-`7yぃÁÀ:^1۱>蜖QG2X j.j؅>m-ρC=T~~ lBg?mn^ۍ>f2P; 4"tĆ*I5 ȇjǁrs@ny Z '[y=(}]4z}g.(+q5ClpJ64% 5 jXBhr(B1/;;ۨZQvmC5;}X~}VZF*U Kpah@WXi/>̋@:`иB&4AcܷS@{@Ww>vJ`_&`"KFI&ҰaC$:u&tA2#ii=%%%RXXh={?m۶o&ׯ 6Ț5kM6ɮ]\l\zX.e+x)@3lo2!A6F*~ n=Iث#ǐO` |5yҾ}{СmV5k&u5'y؊oP8lٲK.ŋ ?W^-wsu;4DoVΡXN~s$cK`B#!r^} 2m|ȳp4xv{׮]cf2~g؈`\Ҙ)hu^~:A@9`^!iU)v*q׫W4h/V2JKKaG!??߀f`FϞ=M|C_S 88hSHCt2?AgC)ƥw_B58Lb@Վ:+|`222\Yf53O)-~zP w\>;iBkM\~=nݺDJ4r2oiigGK]9=0T~^;̞8cԨQuF޽{S'xI,g, C {RF.nև7L< 31?k(Y୷JfA5+­Ua|â8=h԰wi5 G]vU,֫qPp;񨣎g/~;|mEq7փ7ߋ *˘#PϓW~{5_ݼ<㡇2ϕSv"0,pviX xf_vZvTXڇrZ2dI;C}ڵkaÆR{NĬQkI!DWWJzs7ѣ[4ERٳgpwўKhRz+@ChĆm@hN!>* m.w-@-O> 5fd FW_}3QsC:K+WD6  ]d~iP9ڿMZT9sѴiSz? ?$.T_DN;*C -έNׄ-BmW^y^ տ)'sKbϤY}C7def7hBie\W8e˖`?'ov#33γWٱxl(qeЅDZp+4)]e`ۺ~E۷oi=ӍC9s\ Q#kD4Kq~Hߣv0 zuw[(|Fɯ;v "H~ѦM?H}PS̅ "Y5̉бɍ0H8Pr鴞~iJqGe^H R&1vC̔\IGGHVյ\Q^iܹsy:'X cW.u̴`\7wPͼ#C ecA+}eNI&I߾}[TU)|kE K0(xKzd4Dl68,,ep F:^ \\^ԦÏ2&.]ۈVxkR"s]Oud:)cѴ8j3+Xk.טء%j7Xi h)|KLE_:wɱQJw"F\ ^'YJ;UJ/i<")y=TDzzR 0qi r饗ĉR !+} | ؈x Tiw|URE.j;\ID!^iD:UTعS_IԨ}._$v哱m\p``gD6F[*oƗ.zI QǷ='* @%9|[qJV{][P. عK{&z@@>} I.N@5W#ÂE2t_E#Pqo@nW{TZ,}'{n{n],fOKӤS*g Z,bݻ]i~;РAA19`GC\G=PjEZ 'N=T=q)p ]U\B5T!jzoLuK(H=^vLTF:i(U)Ƥe˖IKlhܝ N': ׻~ kUM*V #P<+{?Q%hҤOo?!ŗO% _Z|IVMNkp2| NK[A<|3:T:Be-Pb$iyc4p*ڇyL6xؒ;\)^9b|X)s0`ߥj^f]YnT,X ?:l.goٟɏJ7opoxq[ ly;.r7~xiܸaEnvC& TC}Xꆅk1E9,xq|{?% &Mє)SsYq>3tNDHk^oKz&N 8qH$_ ~7'熫K 4Mh}}GxtcfB'wc͗lX(ec{Rd7ƌ_4Udx!/[rAWD#M/?4 X ҵL8z<|M[GroAp/[Fa^?J25 ?pBGR*3(x =`vΠRi03SOƞ=%Gt`p#p> _F1} +b@]s1 6Q>4x)#1lA'=!;ve0kлᆱ2:𗊕+`((#/9jԨZW@f'?Zc^9T}I 5  RT wcBD64đLdz2%.DyY%?֕T)oֻ ʕ+裏=Y Pׄq o.:t0vr<8%70x,:lAVViu?I;_#@%NIY5~Tx0 g%]{-ÇM]*B{l;%G_H˜yx VF .茱IP21 h2d1B:(/H6/x gΊmJVމ3$Y._sh,`xUHP~}s_r%NO_qc/},SN,f[v5k̓Gx13ej!iXa"N8AE+30._~:ؽGZ fΒO?/iKs6!^`N-U|8]W^mV)l2%X-A瓀/$iܻۥK.h^C(̜me폆8s'xR;R>d47=8Sފ/VO?o*rv鉺tR 5Atu3*Vh 48; [6{تvM*~!XoipGh(d9Δl{JќOe!hn}%ZtD&ŒڀQ*pJtG"p']L`;vPZ{ͥD4a+\[1bk$gGM3oEKJ_a:* +T|XCZ'(gDz*gSTJ>jRܺ6YGz6~i$k/3TOVo0qnM7`<hF*7Mh~7&iut 7NnDqL~L(>C?wŜx9{e.Q<i/3).i|٦] 05YNvb\a=j*4B .^dP?sriEgRG, %+~i/*~y"7ThGn)i 2 TUu^ }~ +}ĉ涇(ZM8?,x QPa/ZMFr@9gOyMSdR]3H }tF)S-ݯp>.Dm)S)@ Cq'.t %\^t=+ `@U:6_hN8;TI_N}ei/Da{aA٤wIב/Xs{Uq1 @" tSf/cn1q`c۠s [1Pa3h{eгA3jq]@Ep],+LW_8.]-s浹|f.yGh ܲ3 U ?% ժULWǠ'%)Z$btoz1s7óͷFx\ɪ`+Su},U,V)26ƗBr#YO!u [xӦ#GI=&hHƶRC?on^栃0T͚5$+]J/h [0 ̶I~o6kpƁg 3;0~ETg+˿ߧ#]3 aٯ &^~ Pf p?:n*W^yPhp|Km5-HQ]9OJmz;wIox-V$Jajl|ןq#VLup(1K`1% t1S]fv]gF";ܐC_G͛J% rJP^x!%Pbb%'V[S .*P֒Ѷ ~}̬=yg|6Y*]v lLNuvڵk/,u0&A`/cݱ0tYo*WiÙիdo<BL£ne2)}[sUUp~fv_We`zf_l{_FiT[s'v3 N! }#킁S+"~Xs!lVPFErPB?С}0bGNS>Fh&Ǟ"Iu\g9m'b9|ȁ_TEH @ R+E@7tG}_JH\ٳ;r B?بA>\( 1*7A`^HE `]Pt);T^<Ȁ)4?gʙ{DA7}ݭdu2 m>X"}쩲cmZdy{EQXeW0:*/ƍgZ_׋́>lV#7k. -۳ϔ[Iv$?hc柴JM0Z ,gdRDvc`y\U^zȑ:MZxh4$*~f;g0fS۞>ԻJ!fB3S7>kQK`eQ7(G 0<9Wl/Y239`Rl}$ _5H[MʰH-E7zhGb ,+qep&1GFHEthƅ5"y^ɉoa7 )j\3l*CJժU+3fL1I4v@ 7=ˬlu'%/+ȰbJW(X.>lذA͊CUz`WydlXc.O xƋ7PaOd? P3v?8Nݎtܴ$ﯔtgϞخH?;Sgxhv̉on 0 f mb_(h8MBJ:oV}XOcꪣ}`^~&=uNFU./4JJT~!oe֭*ehAPi_~rI'TuT8Z1jl@$w^֩'K?}b|Yz1kL~ 8~PXI# ^_2Fn17S{kYrݲ s~!A*>}پ]Lf}YJK&/5~w%KTY1`T#?r+MG71vc%%{Op? C{E|rmߪ [xz չ`2tj_63HpvPMD3?~nBOOېmŊ*oB%s g|뵿 < ی 1K`~٧"kg߼yʓ÷+s?]`Oj4qg}=~"v.[l'DW_~%|(P(w \yk͚5Z5hD?񌒡 ź?NѺIsQ@Phx7c5hDS!a4LGd(ݨ?.QQ Xk.<~ mw?MHR"_|jV0oa0+ nYZpߩva!鋚0'il; TlÛ1_WecOߌ@Ov0v7|W`&<)lC=lP X_~U-{̊ou yGO=yz7s 3nvV]88VrY.zdOɎ4(hP8])~ѷ/g}a4>3p<< նwE-Cm Ǡń{|i?o[ewˎ~gK!cS}d2 pH[z)~*'31m W_9s-Y&+07;x :/nB_] TtdYUud%jpoz< $g@[N87lؠJ?;y*m^/PX$-MFYD񗁖,LЎ_O?d.ZHCjp ;ފ[r K[;V"5a ak2g4bTcV_7nӞY'8ܺ&k@ hR>T}!\$pK/uXNOP F.iH^U83IN^sT{d듰ϗK.D~c ()P\d0c$@4X|$]O,5VjLhFts2)O N(D銝tāʕmp?~=}RyQ>ֻn^yyGv㴑@} jӅ@Cr~AsTi؅R}s"{|͚JK ֭tuٳU+J/+PHX\x>X{T}>'`=zA#56F@XS93$‪' |>\5g&+N:2c ۷o[*wBV v+F*Oo_5R}/8?Z-C pR*O<,]~[&# քkԩSeРAn{ G;ݼy_b~p ,cT>5SؠE]4P@xJVqG`V2q΁l."2"ngL4 rsϹ!mD'܎H@u at173 { *?$&  ҉ F#9 DYi$ xr+駟SEC}2` e3]r:6q#I^|E޽SFQY-tc~Ӥ@E {{w[;%^]?)J꾪W.&M͛;'c5`Pf>upy1^s8miՔ*w[1YN8S} R͙`>OwrgϞ6[;wJI"Ps[G%)Hi}wB: qSX*V: Hر]怑S/UMr-r\8tY/_.+V(F۳[BQѻ 4h ~ht~qaH̙9@ srDP=<+ \r;J8s=I^hH`o&<蠃97o?*֯(;XbAްa8d1 AՃnGs 8о}{uTO.3+ DoH{`NJ9+p)٬nKs i9%ίLAh:/׭(xej—_~iZ8?^o#yhxp[c`(@ h _w͔Р99L/NWae@p` jr+OZ`|Ss 8аaCU0hQN@Co:.HkI'5hhW `T '@zE*rܹse˖-a5w86-2[irwÀ;իUk3́/^%C4"q|1MN+N2tF-?`˳X:z-/As@s`xfW-EQ#  0 7nnݺI$<<2&uSwB 9޴ |'Nu] O[+BnVZMp裏V:G٩x &sDqM7H5C ~r\Q 8ldddW9oackGTz:t0`(1}t[aG]v@"H 72_} [;QR3Oi:tjժOsXK߽rﺹHxꩧ,.a-xetvҩ'u9;4HlpY4uf71P c0ڵ3'@ҥK ø! In0,Y4nݺՀ_*wx>T?%gycɓ<{hRJFɓ'oyF2p[51UgFf`75ae5=q_n|I"fܠ.](TA;# 'S5PsO{@a0sLcӦMZ1jea3EC'V"- p,K'Amy|B:u,=z,!1]xXp0N|YrJ8O~p0u08}vFBt*CBm۶r1ǘغukC3NvfK@ES w~=MZx o!-XN >,tW S"/4YM4͛ {)>`S[`fvv`OOo FQ zjsү] ޱcv=#r뮻Ny/h.pC0f0v¬J*+P;P(`5|HNźDNl쟛y/J c:uuY :ؐͰK.īgAH云B<K#LԼK_s[u T 3 9Czƌǹ6 aN1a„!.a`KFp-9½hݯ~t^A7Tm۶#Fų;ә_8]^b{S.$,3,8W)`>LOF͚5~؀Gd*̞| G{>:C(}_|ĤyD1 SIڵ~ҳgOae߀ħc,A*6aww,g,@3bI;n9,LҩS'r-LԂStэ%װ7S}7ftH 3Q,SԮ]ԨQ#iڴ L֒+XR`V۳g97olfegf_~żr Šx"HOKCħ 0!=%'GIDAT> M@2r5 j%M++6>jpYF[v?H3ٝOs %8@ߛ G ` 44Ƈ/D E99)G߄u=>j@sしmpsY^pẞ.01N @pv M(@j߾{.QRE#m'׏'p/h$h~~Pn䣯vdSL`Eoуqms?g7j x|mdƀUs;fD {o;F]h[CM@7O6V < h.D`:0pWX1lkƐXJ'Ӱ MPW~tDW} ?7x~ 0)?1~.r`]RFxw8xz[@#pKTxp h;n“h,xc2.v5n?Zh .f8܃1-dU6 `$WXO &Êc#0 Qk1_,qTcx'F`d8xb}*&1b b 9Ho㸰a'lvggݮ%E@P@*Q \ \\\\Tzpxx V76n")+)"8!r'uu0'|N `h*JJ 0* NUR" QU"D@:i >LL) @7`* (PP/|NFT]'U\E J='{96'*Q1;JW`Z 9(y n-95RKRxWS#ĕE܇o ʞ @ /JAr0-s߀$(G֨C-2E+ׂ%UWWۃ +#%{'/?C)!`>N=_qBT)d]E 1ન-/=yL  LBƌ@K\|1x ~*&(Bhx *CPh? h:9){$ VN8} [u.dVRE5R!3aTc|4'gJG~)|/7A4ҁ*J@!l:(Ve !Fϫgq_CI(D:^>Lsak0Cp/ڎל*Ô~// e<%gCp`p'pX)Xa8 {> B҉Z_x?{Fv*/x =dk@st| 0WWA/.o|/'Q'8g J@МKgN=Llq+G%o#@ WTWz&]`+cA&N|҂Y+)"Ohޚzع|̽F%o!ݹ`Sσִn1S_'%*J@p)c5͋ρg\)?6 f~dR"q_ fX@iNT @{ɔFN^':~sH^ ?&fA3yՍDV<{O{n@ǂ~贩@pgl:\@ʉr^>s pIyx hBODOa{޷'~~U I>= ։Ͽe}7MFPAu*3fvKPG9b9 KU_gZ`znn3i9x>x6x!{DT_Aa '`,N9\ >"eDQ"朒Ĩct{WмT6v[ +mt7n\cn+L"g`#[*M&ѯ#gP{c=C}ց? . LG49m/ØF<ݸ'*Sq&[t8s ~hrnNЃ4K{D0&4)-J2RM<?v@]#:)=6=xn ;0F:N ڽ=- TUCE%{'-M:ZIi=K`?7#M0)7)8шf `z黣}3;$Fсɾ{*)j8h0D̡?OZ}' k6pDTTRE*V(+W̴ըQCVZpS( 6֭[%99Y6o,Xv);vm۶ɖ-[$/,Jq  Ŗ x.F)p kԭ3p>1Ʒv+t &`Oy?[Ԯ][j֬)5qR~}xժUIB Nʒ]vY}Jʕ+eŊ¿kʺu묿<_)"Y7Oaw+93F-ZY,rB z9z_`/$0 c  fr+bZ:'MA$۷^sɟւ7-%`…`Yh^RhEPn ~L/h.L?D&b<N4xX8}7u%`8X$p"& +xY㡹Tp8pҤIԩtԩ#Փ=6m5kŋo[.]jYb3X~\&\88;`?;y] bPp" x0޹^&VZI.]GҮ];ke_Zb/K-Yf͚%/Be!#\s+,6b] =,rRЬ߆s=̓j+peD}%opBio۶K#x5Nt謸dk`ڴi2w\5h `!#:uZ,I}p3`cùd;yFKBmu2ڻv=>`޽ 42sů)>H+KAU_]8ώ-Ds ̽~;41y͗s/6:=v̾;v~0&0VSrD?_D{nbnLu%if=( Xp`'C4Bkwy/?~>qQ:J,Sئc^l:A.Ľ4{L6_ܹsn #\͍9Meƈ"ofO #`-Mm$U ZL52$^&/ ܦ'с~anߌr?~!?|gpFš +/|!D+;ntVоq\[q.1U_1^C?O0˺w4yBsmo_}=x l2]3fLzz67( sxp" =5f⿐[ I,K})~Hmo⻁9QFN}'[7믿>ܢE Px !\D*QC*f`Lq+ ]R>ئsacFs^"VAkߦODզr0v j~cbYV#}|icoC[1=2ݗ &?Nw}wej8?i !~뭷O??w9Dp='k:Ӥ ϝ w{u74E*b!'be_ont -t+߼nܸq_W{J@P2eJCͳ﬍^謼qꁫra_0Df r*fw*:>ߴx!M -̙3Ga ^%E VRSS㎓ӧ˓O>ip-s YIcWpj{"SCa1!_x-R>/Ljc<5v222Ǐ/\0Ş^͛- yec"{.VRD ,SEp1>/%ȱg̘Q؅ҥK~B Fq}']rfE}(-Jm5h/fB{ w1(3.Q[I&ɻ+{-Xf͚ | R=YE닋T 8AsxM <,X_&+rrW *رcJq,c O=ۿ_Et@8ZDLC0@YͯYq0`HyRVxHOOX )yjߔH5[ }cyߞrn{zwޑ=x Zh xפcǎ\{QE_*;1n1s1h5'#F̙3-%E 6LjmS!:] R`f6H7V ǹ}Pɤ6$.ח'/,tSR@jլm*KO.uï8C,i١ EO3jߖfϖ56b'|"^x843KHDtJ+Q7 :ہp)[; +{W^}U9"FOR@_|Q>d+woy-FdP}3޳:+nس{ݺuB.rk{#0rH7lA`Z9"U,ELG[]mW=7?PzdW`"дiS˧;d ͌5R.3l\T،vZb@ֺ8TQc}sJ458hM=?>ES"tx unf߈K_H/`Bv M dv| 4 Ʊ6C[Nhic5յkW+qlkSR@.{Mg#e#R7&foSa(B S8i&x1HzaL' ɟ)Lg4n̘1裏J*UlG`~7OrV~^(M7oYs :ΗPzWPZ6JJΒܶ*nwRJVh,`u]0v݇oa a1:An蘞GNh"KvK GWtcҗ$ ⽓~)Bˇ>F~ܬ=R҆KX'L#Sv t=Yvhj*+h^d3\ɐ<'p--;&av4fGjnPy 3kzyə6S7lP2)0pҷIJ%{7I3ZR%L;$h>F`r֭5 -hxyS#Eh|T<_W=7v%[$rZ?H{">M\h=IdL;$6lXB\t$#iGNfiq"I'$￀R, ;(G{AwVm>,u zIoݾmnc{q5Um'NO>xW]?$ٯL|8d1!3s7 dIW*\{%ۣL>]N?tYb `=P$-kr_?c7%z9>AU?=:Ыѯ;=ڷ*Nlv{ %'O<ك%yÞyE (ڵ$%/($J ,Y#woU`F-dt$i-t=FGGY-N'bFCԨnWɟGvr<7L^a@B4 ,7I=+}k#Wd*X-<u?sA%XnTYnq|U?eU 7nSP&keJLv9}k@rR%c%h{>Anx ,jo;pE`;WpatO&8S7B8F{G3O>{ޯes$烏 <:" e$g,UJ@:v(h+`.=EqN g;^&E ';ǣ99, x= FEPVv9@!a KL90R!>}#< w_$y(te5ZHr0W^)q^ x} N OSv2Z-N=K~ ?Y>uAVRyDIAFADÆ Jt@.h^v( 3rڄľAhȦ6:/lj/f L.0=mV9s+l _&%I~~ :󟅷lmg+9}z HOI5jW,=^{aT?7#Nx}{d\n4wA.C9##JK{G>&q10aR% e\?,F!,&2]/({`fhS&WvCW\抟,]J=!q0ҵ^+&0ߔ+$ R/',3[ 9ْگ7ZscG lҪ{%\%Ώs]۩p,\  ,)M x2vAnI" `*Cҙg)71#K~($ rAϠ*gX4qڱC$TXUTt"d֬YegC>p> 9p 4Ü4끃@x3Tp uA05{n9t:NK.+HM/_AV=[2JjABSR"зo_?d޼ynC j[qJ(2阫`1CF^E0I/{!B5c2475jHLb)}ԧFw0&ǠW %%K/$mIͧOv]믿t(vźd`t0{>P&.I"~72M@০"ZXgF3֟YڶmkDBޞZOǿSro('=Ar;,' @ᠾ‹4 +7yާ&W Mۺw\9}2p|";K'̣TߕLWВSOyan 7&\a>DKj4?\F4`ӵڲk$?wk3gTW)V`Zɚv z!~lt}|` 0 b#&&>b?M9#}'>޷[v|VWp!Z,<_dܴ䄱~Ȅ{Ȁ NCpޞ9ר&:T ̉6uxJ4L4ʝQ1/Q߿PJ )XhSRD7nl)ME5G\fAJv".lm v XPNva5.&̝_ c-_awy:(8tW,NVtXs@S= &*T& W@(Ut|\}n<|\uU2|Lf#Ҝ8 o \GQ;AhNxknZh1yMbnjMWL%2vkr ,!V@W:BCo֬]qNw H  w+Sp}9Lx[ o?(n<^B9~]iW#>b%s'Pݢ rs D__"N͈ܹ_0XyB# 6jSAA㎓q؅݋`;/|3an%OOC[D+5`? T{ze>cK F`%E$n6E%M H w9VdVicu8([Z֞KD=W\tEү{Q+H9_$GB8ԬYӪʚiQ Ps=:GX+덹xp?Ŝȿ%uIѤ @pS{TR` /O>R3|X݆ k3G9&9%k8}'y܎hGq}̗Jj?Ah[}8M3H ̯rBxP-C Naq^KpM۷v6e[mdb N?묳o [!yz'b5_yAfn{^ +|/\ WD?ӔnOF5=pkժ|nvOf) iC>T]-?AFAO9 Շ`[l[*ϼZpR|oGq69;9y? .jVkAXKiɵ1< }r]2ӣ*D<,z87t4iҤaSG@av @n'hQ}b9qSߺ5r"> [& 2DFbĢPX  $oJ@$0E "9Չs lۼO>rOnr0}*x)$6ӴqH(-آ)Qd7RzX]I th4u64DxL$ju;x8Fr='/JLO28ɟɁ`zsKT|1r''լ!P)pmX+)#LjsW$?`IƧgL^'Vs\l`>xU={ʘ1n@!P/[W@NRW~@/Wh4mN4 19M(nѕ|޹iz,A(H"w`nW\ >\kbnA/)g UvSx˕~}D ))"pgK۶t{2N\DS<~\ |4qR |ZFEL1hР@)$w -8ڈ_%:G`Ыr$Ko$#P'K;'bq/xAi8>2&PgAN``*'$V2쯤iIRұBIѣGKnl%˹HGLW(QM x4\;!wpOp%p zbB҆#IU`a74BრBXv}btc l/~ mM=4U>~gNppvvW4D>$7k"i `t^Aۋ{v;!_YhLγ!V: 0rHܙ}@]ϐPED&  }h؃@**Jrs"bo"PK)v~%V[Xu[I:y6YkpZL-G_R1b˺d^zQAI\ 28T7. CcZ.rH.eNZUDY1Ay]Gvk۷O/@VpURAVݻ;x٭RڷKP?ƟW?e^ptAJ :bVM*teFD,4̨UN݂+~zGwBժJYBUaMd7K!(qxÇK.nh%&G{A߂q`Hǘ0C;}qRTIr>QP&Y~HpȺO V|L:toY؂i7G*X}oپ۞kJ޶MrFB$6 0&Wz )e#ЬY3yW寿*D{?R0ED nC};?!pՒ6E>/AR{ "bCTFvr'G} 0,3FDlzlz%\⇮z0r% c܇޽[Rj#X7A@Ojp>5LʵG$Va/)#=e9]y~_*ٟLPZj-hxT Udm`gF)y=J+BBAp^s.do/9&1?c$L͛V 7nQ*?JX?,qT3}8fk |m OJ/5boKTlD(=m88DUJ3 COO9}*y-F\1_PBX SN9tw%(=c{+$Lp\ ԩcիWOiO0AQXd8m;yd#@(=bGbx s?K3ƙK8T4Rـ`D˥[n~/0pm0퉳1U[*y=4=3IqҼysiٲ4mTk*U(ŏ@eq'oRZaqJڂ3F^z%m?oXˢF_{o( Xʕ+KF A 4ZhaM| SrWH>22M{&*%j!iCKܢy4蹊p(p Z"{,#;]*=joժnZڵk'm۶&MXxew1߇eP_Fč OO~lǟzHWItZU>-[*-29NP"銶DX;Ȍ( ߧz`?hAY~Nٱj֬߹z}}_\e։>!LZ$^IEYRz~3d>@E Bq8pVڡ˭?uUJCfT߹G}$ EV/pVݻҧ=7$U1 d&=H*La{5% UCd 4"LQ>qDdΎϦglO*cϕ;fY|ɝ={X @G!g\ɝ љ/{}hTR!bYE͛gr!4dJ>&bɧ(>`ի0.'{=M %LC0'խ+iCۤ$joa ꂙv?R`?H= Θ W>?!׬?iӦai b%O7Α$a"=ї@6l{&`UlxjLHJ89>֧L|G׭3N?XG&:*E 'Ņ?PY~D:s`?HJ=<>3|C "tT?33ǣѮGfirr$gIªJ@b!T>}L*7;{_R`_|E `Vɓ'ā 8 @Q4o3֟N%V;vyVD;n;;$덷v+H$:֭[MA g/q,$s[by''tBnu%E8ӦKoK0"4DLFxÿ•"NA_}Ri!tT`X pY2 ܽ|qӹ+vz⎹Id~723$oo,;%%Oi I5kHZJJΒҭVO譧OӨT!BbHϽ> =z LH'~2W;ɝ5۬_n. =ϒއw" )HPVPˆε;%5k c%PeLvp~ DWNt]|?^|ŖW?H~-߶͜׬!tO)@53c6;8nnAlcKŪX|&-IKe{QMɼRI-% о}{aM!sݖBy 0`Bcfܸqr%HK=v$%f/_In,q᝻$]^%8m2rD<3rq7p+ΟE-gv^XZ!NDYO8_ 0:樤D@'H?aO*T%Q]`WY&~fȞ5Y x<끇D XD]Rq_vjR`QU`t9bM7$G}oϚk'I֣.x]&jDŽl#D_Rd%~]8gmMkC#L lXBy2&I𱅃5\#g}kTIzΛLLuaywi԰'+ܯlld:]+a^Uy"\p^I^7|@N:tE$W̆ySN &H()! e者.1vJb_~=Vc Q!K7%C<޸IvAÚ'QFҴiSYpK%v Lϳ׉wq :]+%J|4|3_^rf‹}\3fgOK.0_{TZU8 @}Gt0gPɘ} 1SO>݄(ʠ# F3^`ORn"4-[%7746(I>s}Z1Px'{V~? '#f7&HJ#@ Qy_dž=8YgY^Zϱg@.7tQ0Ҏa-_L>IH,(LYP T$5䮩mˠ5c9]`x* Ƥ>^x׺ 2p~5TIąp6J5•xH̓3k6LHΜ$Æ"&߶5IR=C*0|^z\05?+D |5b ߉'QG嵮i@?IΗ_uz-8acm,j/6A L~TV-)|ٲe ЊFN޽'-[Fs؂@o"kG srRڒ:xP-9z}ҥV 췐% у?&6h@Yggxm @#ϯ; ޟE{>#'ډSfafgeŸ$y2r-&ߕ/s`pkV@IDAT1cıܢygG&H) R2^;o7(7IR ?t3JUiF^$Reşgmʋ?,?b3W}2 h7 X?brEӃ>(zj c K˯Ii^vn7Dg]o1o/4ȡ~-9yIjbmҦ6b Zr{+8L\0 '78@7J?Y)iOd0`3o[ZEma}}MԳMּyھ'hhMtU(g> TqL-&yM7IE("ޱC1a`E?Gx?C_?䩉?6]j$m15WA15?7c_$ѣG5AxH/ u I?9Jδ?H> `M5ϘZjp2gkFB Rl&:^Uh|X(:t',?!ڬ"=zU8xesI'nq{ML3sY^qZ$iJ4@ҎW䠾"ȧA% 56㢾ʡ N:$ytw_m6v,Ͼ0rӇ}?J X^gyğDfJƅjܑ4dxQ;oܝ1cX+ÚW8,hyÒTwlJrf|V`~>L7?1F b4dgIq$ABʝ0Hͼ0ϣ`&)p܇{:~+% id?ɁIȁhQB?޹Sr̕췧J6MV(ğiy˾#p !JA)%wp+R=4Jȝ6yWKIG?)+0M~}m`4Q'xg=ERdFJM/)cg#ݻw2<"IWnڴK_Fr'-x?_MFn>Bp>M>,7W6'o^^x7`*ܯ5\''Ox.ɝd!U -c+Fb8QL h1*1߲e˒>cgFf<&2 +dM9\`v@0D=0/UM^y29+=~Di j֬i;tS0V>kfӭ%%7$ W?I-q[t7)eC}Q9WE5k*ϝaů{,:I*є_F Ug) .TpX\u.FYI:YYg޽ZKzZQNrpcr(lnTLQU1 ep /P.2AL=C쌥-+jXW^cCCVIj@2Ɵ)U^,"t4M K=1 幵]6vÆ b%E`zu 4\,%Z5IG҆ }$aPv\{cABЯd2υυe0!SZR~g%E-]&9OC?!@?*dJJz k]<^y?7?mIՂ?枉HrC v?4i4hnlE *ߙ**/=+}-7*X;DRv.qa~|J2U2/8W2b͉~i1MYl] DZ4#QGZ"&0񗝣=%of#31TRzh@7kZMD/bay_%EO̘)` &~#v`r%혁0֭"b~慂ʆ]aI{ d^JA@`FaR臑bttń-R쨾U<~^RJ#Pߨ9}05슻$`Q8+[O;YOσGZP[dפ`6/5jdX b^{MgLə6üe&ڶv;sRspo [v8U0ar!1mYp;fɶ-?BBT^?MaG>G Yw=xA (&)qg Ok?&P8,wR苻w[wpB?J_Ȟw.1_WijPʒֳf'#gΗWVݬetO?)TcK mtJZ<TebT !={i2q@$f [49{ Z 'F z' I/77mݺU_rZߛoYڴi=z"k&ďI6TY1%aXD? @I۵`gXn-<&Pdܸq(^G`%;{-=&~zé/n];j`F8ՁUV9tIfv'~aڱ$Nw)sXFr^82cyR%iÇI &4b1\1?Ǐú=\B6/19JܙJșn(N{ M{ 0Kҏ,)t{ YMrĜ/DYpvN&GQ(%{vC*!/景,_#_=uV#oÅ3w?f$v.ZED`ƶNuֵ*nVMciUY @SxnOr}W-n/g;UWC gwZwd-~  r GG)C5RB%K 1sb(هUzR=j/c,IgZqF<RzʪQ/C*n#PhTIRu`$IݳO.iT<=~EB`ӦM ̌%z^Q1{~G ju”&%=zcak0 GQ3/b䛇*:տa m [n-\pAb=):@#JG(j/[a<]Tc%iGaHsHKw St E>+VsnR6a@7Du]'L{M^1${*4W()];#/16 0? U4֟ O&,Zh7ء̖Ă={o4A w/w͗6B?I-KѦ;TR:u𷉿xֻ\Iex$+A`&8W8 1sbW*U^ )!|&آ&{Caժ;d(}xņ2or`eZxE hxa1Ǩs@Ǐ .2CQN{'P(Z6 4O\ի7 :fS`<a#&/\($*+GBu17oAݎ0yA(7ɮAÿ/\UtaԦGE 'W(#шÇ}]9,L*#ɠ7ʶO5k L:K&J* %oѯ+]:QX'U C&oo8BTcU*= yȔH@rRs/Ʊm၂ҥ 9ǟܢk`wX`?i_< &1o<kP` @o4`ްaä[n}׿@H=pdHhU-?R%q#IH2L' 3jqLYْqɒIJ @` &{LYi=sLUy)_}Qvnɞw*pP+&~:&&~+ ^G\:bɚ? ?kh +1,1Q0`yFe0E+$5i$~@rgO=/%/ޱapW,dX LA,V*]>?>Q)?NhP, P\ZE!$?lJ@#ҳTG#g\eQ WPʒܬz$mk|Ba_6LG?7 6ҩh&^wyt, E@93gIδp ![ bPjܱ8l\R9AX| Q^F`ra{43ϔ*UKbn$ V/r%o!? so0oVv`a>cĊCJF Yխ[W+C[)@?,}xUF¢E࣏>xϟ[hu,./LDcLOVz~teIEeE`˖-B AbˋT h=93W+",*cv i!k>P\v#Kkw%d8Hpn^`z!]t1%N(@ PXG Wݳ EqPJlfB P BڛPn L=S4*GHX'˭?8g&Ǧ;$(qa.vX$9?vE\-H+jI5B;7*Wye@49R~$ [dStGKÆ MS9"Pt_dWW9+P!_~)7n,4;?_`$ Q*tI%U)"pcF$C+blyU{'9'Ol+ Lò>&{{AIvLTY"` `|-+-[ ?c49p%W酊"P kwA_"ˆ  ߚKCf,JS3СCK~(@4-bO b4%E/b'~^lR˻S"D' DS=)7o|7-.,Ohi QgϞRF+"P.J/ RO(Nxdݦ|ù -I"X^?sE@"t4*3٥?uY[z5k[oes4Wء[jUڵb}E@pPHvNU_| ɂ?&-9hzoŊN(m7k%)!i޼Y*DPlFt=9z(,$欂?J_Yc#먞逸rcChv$s~He8GE AأmCѝ֡#eÏIx,sIÌ/oD?S3ҋ8O>v4m(X@[';oM7ZIi LsO$I'8=Dmg< @m\*ҋ=vښ/^zEmkc*T*)(Ptx87DE}Ac1OS`%^g@^sUW<6i#Vr+o]C)͡Khf͚uH3b?ڣ>w+O/px6XXфѠ纄+y0Ői*,C6BtVY*DPC #tpr+WJϙ_נJel4?v4m+q^*bw^3D@%E@%D=*bk o2~5PCXKĦvM|R\ B\gX7QܹA*ɒ%ntu =Uo-+4`驊@ s~(=M~Yv\zl}d>y`φ_(ͬKRz1D:X~L81³m=YŢ>s+ }Ej,؇/ (aѫ@<_zR'_XW`?1ܼY' ?,K.uc̟BXik#^׸qcW^"EɘvAT8|?͛J=Bm,_\DO@n̛pE&P~}u4QFΕI}1 N%0g5VOh%)d_@B&-1S@0B[kHU"D @aG,EXBV΂hW{`~-<r3ᅛhē4͵ڵt=WP<@R2oj OI(D [^wqlٲɿ 7\TB+PR` XC)9ҥkSFG}$oSc| lB2S) 4z"xS[Njqqu LWyE`Νr뭷"MEy**2 h,6j#mhu E T?%o(]L4I̙cWsѶCf cUyjժ @ܷMP@R%dOIHޞpnÕA_xvo\?np*LخkN:m%E@ՠ0(8S ,uMQ؆M+Q%mSlojX3R)@#-xwVs҂?l~(?|ںgT|85jq*@P # %#%c{ 8/#p뮻-?Bc R`pWfTR!/SgtUR pw}WїgaϩG*p/k&+)@HIP5?cZ'@CoGS. 'X{u/=_PBaƢJ;vXm۶V 0#Ն]*HJ" K_"y )\$aƌnDu\vI-=("A ^"[;Av^{G ٳg˝w]Aknߖ[f[S[JR d] U޶]v?l:Jv}[ "C^]v Vzvl Ѽ7nUΨ(A+$=]p\u}u=IK1Pu<#?_};D8*h.\hT SE fX@c­$17zV{衇vd'̳`'Ǥm+ih(!Biqɕuɒ=?j"gK/̈́?9\<o޼y. ~a{E  9T;@ܹ_s.m%9_NڵK."w\XB4!V(Lhf8Od)g.ܟ~N45޻KN@4 *uL**\T+ZP`$'W^{C#;^s'8G5 n()" CݓEHu}:蓛 sp E `cpE ̭(@ T=@y%{ #5t0, ]uV7n{Yzu&qMֶʺ"D%rj`x믿^fΜvo<#n&lTk _%wx(v @(:8sh2soF.r2 _|P[x}G&ƨ2EaUJe#A(Ko#;IV\vu}wC>\!Wj`.{] U@redWN)CQ<ܲ?^r%xM5nj OߤCn_*@(b #W@jC$%>_?u O^z%ڏa_|OuUؽ{L6Mo6F@.aԑ -駞$ʕJ>W:,;/unu|E ~B0|*Bn#ä/J+g;v]\n߻j`;?I&ǮE.UA|բ,IiF2L҆ Ijc;wҥKz#t#k׮լn؁ P/ yRɒvxlo=@@?.PL2.|E@DWKG90Z׎Q&^|Ehpxbu[!;_ȪUAnwE+@ *d&J HƥJcP/&K쇉`(coXhQR?"TH '?|T~{NL"?ׯBF'BG z/%;0) aaD**JAĀqMꮮauŰ**(( D1$)9g?``zNu|sknx|E@D z50drz̤׮u{20 6g!泹߂rV+رcu(2VXDӏndۤ-cQU<C3qhv>" ^9x(~Z3SWLG2jT@۶mͰaÜfl9tja;=Xıĕ]}vU(FD 26cžLgJ9d*r5T6mjjN:z2NUKUF%^ޚ%K:G%[ LpL9{]:;%oE<>%eߤI3bӸqcۊE +B<6m2=X,"`H+939/I?MTԮ]0\W`S*P9!h,@*.! kJq3/ &ACMVZ}E=Gv2`>,9'-$tp۴6eT*X}ǎm>tPYnfh#G4~ix*.gfC͚T3%t ={TcQ@*T eUWz.\hza2HG~4z/Vȝ=nIty. +nOH:\"HǪڵ 9 <pUKZK>)mܸљklـWT)4䎟`ҒEDž{\LŝMFDMׂQ,%-uPPR%;j76?`8mc*yMT441k*kt\@%"'4>]\%¨ y.4r@ Wx*=<: V%M1;\')?b2No,shn$s֮]kL~G΁S?=T\X>X*@ɿxL3YT7eqdtڴic-ZdfΜyqb14-Y/B$#T~)Y)?-9iGeSD^m ,lgas=׆:>B$eI˂*$ԆFS+W ($@9\Sfz[F 8piذE)(_(l4{=3`H6Tac:yi2@*U'ׁSdh T}] RMK )?۝z3/^4jȼ X{騈m%v @ :VGd!ۖ-[̒%KLn0)R" nfuDj `WLF60%.jJr`LE^zFeE8;BD[nCbA͝;הCXЖ-[*]C3Xתig}1ՂTs%7oݫs-#0w6vxVثpf„ 7@D9FuNs6x2;6?cI#k=7A/۴i̚5k,`+7mz#~CX\[ׯ 6>XW&j[|Yn 1%-$2Tػz9xٻu)ƒÔzo&^y'jԨFL//& 0 _ȫ?faEz;2)zm8>čq6t={lݺyw4)g\Obuf8癑ώ4o7)0?9sfZLCFv8h `… A[D @$Wv9rss8>@&a @`Rlt:[^?&*+ois=g8 Z&A"믿ig׬Z*HXT8|!{SnS&c`P%F?M̈#\bVZO"3lzw Kd3.MGse"Tf2?LcI0MJfY803wqY ,D_~Ws}9Kd?SI=! IDAT2.%x֭[^mfFHNc{1]w GL{yH7_|Ѽ+fҥDJJT"?CO6ͫ"p^dw2»` qWPW" 4F֭3?馛 2eY-*O>gŸ\H[7h2jr%LKku~,˔)rJVl%z뭷[uTV;vSNPzu mcuRUȋ *V~W8+soxg>5Y\C`{v# C]UG` \^I/nq*߁l hݺԩi۶[~w١?5棏>r^l iʘ-Yԇ@Af ~6*燁y?̜9ͅ7mW_9+hjoX+LnNQ֌vg83 c[jհcIIϩC_~3oʔ)f2%+H;qubs1p IKasVSO=՜vis1؁䜚۷;'OlkW6' LǎKHG@ZJ5kVRs7 /$KH]7Z5r&q't3 dG&|~ҤI?#b'XtB;;\\W_Mn.j =Rl /_i`܁ :t>P'~ 7{  N%W(/tMfϞ=^ds68(PK'@nݺ|m&f+A^KAr #8 k|_p:>ϙ3Y`PN :<䓆Qd"j YT6lHuqg30ЗPmHl`p76]J*NAR9s[c_<98.]j-Z'|\q!,N g0qrmqȌq_{FN;<ꨣ-\ˀBٲet)p"Ӂs222LQ1:yts.XoBi5kj(2c8q#DmlcͲ }Qŵ@Hg4oNɋׂ1`aÆ9cjw_t%;Ou\1 K" >%УGgc D (`75 )A&" s*T`7oo2:.DƎkwj/F] dѠ<z#G:k30`P^ԁ%7e%8d 2?r`8 /믛޽{;X˯Qa|T1vQUT A}³Ecl~\_v6ұk`yC D |sΆ˹M~tMo߾~  WUx3zx pH.Tzus)ě1~7|p"^OA` Bl (LD\?۷o7Z:Ĵ-S9#0tPsUW:!0ڧ7Op\ @b8CӾ&MdN=TSRV{qct`'B Ԛd" "  .t>QF* 1W_}}:l ]3/2dTuK=t^@f͜s]vRJ d>}1n8/O>pz,jbϡ:d" "J5k4_|tӴiS(h6s*ĉ7DE͡w zLDkh޼aE]d=d lذywͨQ̯Zp}u8cစ&x< ?p)@ `9ӝ3w}D]/ /ɒBn) k~D@DSt1 8;P,@l23uT3bg)f~r_+hzDCA&" 6`7'Bxg;5j0Jx afѢEfN͊+JSl(^awȃk LD@l#PdIgO.tC\0Iu%@DADFUV5u1jr)WaA LٲeS}k6mL[zsܹs :O\O BY9 <|pމ0@JLŊUVւ;x4VCλ߱c3۶m3+Wtٔ~yͅ%l@58rH1ngdܬw" "<t WLafV>D|J +d.gc"[[E@D@Dj ? +VLf86wom |-8R Ng 2 F{:$_(H'/}+ C,dr"\I3$' :^KD@D;o"k>Ѹ8NX6gUZd5-jC  2k lDފtarX"}] $ MEN54d" " #5buTdTb}hh'/NmYўI'" "f{P硈a# R$@л ::ReMD@D@J`21n;_PZZO@|@pG}' !<+$Ro?dWD@D@F)'?gsG/VB&" " !%0>k sx~" )#9rF娌D |8͟tٓ}hfkD@!oq _'z+7ێ΄d" % -7Y?7%sDis#MD6O` *])f5LP#mELl'@lcP$㵽 0?MD .+quPa߻ .3T}c,?@KUeP@:bk 9~N1x$G /vލ]4WԹ#B l=,bԳj3*G >Q@X \>>w.0]t; *[!瓎yPxޝMAgA2y]]ed:68 ,hH͡_ /Y8q!h$B`ྗ$TȱaPȏA 6@JpW}")f,PX%ljA )\Md6l@@s܌+MƕOf3aXOhBPw.80ڇAAS-:Ǐ6K[,V=E`?Yxe gnUDat?xF%bF!߯7 ՃNZA :2(lbT7{醏bltHAAH`ҺJ͟e V P;BqtJhZbKAS TblPF◛7zξ~1J` >ք@ D@RyoJkof~ 8oae@ .t~-=V fχ%F`xIbIhg*ȇ7_fIEr`|Bt - @}>ږ6so|eS=o M1ܖ %!^縛Rr;U hONnyh#񈴍NAF D76~C|͜dp5ľD"b 9?$'Pّ =t. AzQЙe[jЕ  ΰXu'<>Yu=A3RHNA&zg?nDfs?))!h&JImDO Pw@̴wm5Ȝq "nМVGss6:+9W+H&"P8:Ig^Dμo>̘]8*>0LDhհ((][2 6|f55 7YhNC0p |3Q-|L`?}!O9 ѳE'Oed" >Cus%,A"xAY "fw yxa% A zD@#χzb.H6LtAk_@E ~up'P~CTԝݸ! Aa{PI@ AQ(cʺGX{Id2J*oPHv ɕ%eyd" v81ڛ~cTW{|F}?C~ ?lf?ƨ'n|L8cw"f-1;a[DF(@6p/JHP O&"oG %Bϔb^@MPa r4 cUIN<p6wn3t-ąd'~1_/ED@K-!/~kg9x}lτd!#nw 0+W@xpOhZ8 t90(H_ ޟ=@K xZ~ R~B-h-Psc*AGCl΋4Xoo/kL@3 F @Aձ|Jgd>\Cc @ @A<(O aA7At^&" F3ćuBi;A8  0@#"$g0:L/Y$P@ `tszPHJϧ/o,$8 qt6tD((,Ƨ9ds;gH"9.U" "as:g@ABtb|_?,đw%K9)lD@D ql]8in^`+ ΠZ} 3A#r<lE@D AWԇJV2i[Fhb gCˠ<d`PQD@D 89PjA@lI`rtQ8ݎg05.xgN $ Y>cIENDB`ic09PNG  IHDRxsRGBDeXIfMM*i @IDATx]|3ET|bDsNτ>}*&1b b 9Ho㸰a'lvggݮ%E@P@*Q \ \\\\Tzpxx V76n")+)"8!r'uu0'|N `h*JJ 0* NUR" QU"D@:i >LL) @7`* (PP/|NFT]'U\E J='{96'*Q1;JW`Z 9(y n-95RKRxWS#ĕE܇o ʞ @ /JAr0-s߀$(G֨C-2E+ׂ%UWWۃ +#%{'/?C)!`>N=_qBT)d]E 1ન-/=yL  LBƌ@K\|1x ~*&(Bhx *CPh? h:9){$ VN8} [u.dVRE5R!3aTc|4'gJG~)|/7A4ҁ*J@!l:(Ve !Fϫgq_CI(D:^>Lsak0Cp/ڎל*Ô~// e<%gCp`p'pX)Xa8 {> B҉Z_x?{Fv*/x =dk@st| 0WWA/.o|/'Q'8g J@МKgN=Llq+G%o#@ WTWz&]`+cA&N|҂Y+)"Ohޚzع|̽F%o!ݹ`Sσִn1S_'%*J@p)c5͋ρg\)?6 f~dR"q_ fX@iNT @{ɔFN^':~sH^ ?&fA3yՍDV<{O{n@ǂ~贩@pgl:\@ʉr^>s pIyx hBODOa{޷'~~U I>= ։Ͽe}7MFPAu*3fvKPG9b9 KU_gZ`znn3i9x>x6x!{DT_Aa '`,N9\ >"eDQ"朒Ĩct{WмT6v[ +mt7n\cn+L"g`#[*M&ѯ#gP{c=C}ց? . LG49m/ØF<ݸ'*Sq&[t8s ~hrnNЃ4K{D0&4)-J2RM<?v@]#:)=6=xn ;0F:N ڽ=- TUCE%{'-M:ZIi=K`?7#M0)7)8шf `z黣}3;$Fсɾ{*)j8h0D̡?OZ}' k6pDTTRE*V(+W̴ըQCVZpS( 6֭[%99Y6o,Xv);vm۶ɖ-[$/,Jq  Ŗ x.F)p kԭ3p>1Ʒv+t &`Oy?[Ԯ][j֬)5qR~}xժUIB Nʒ]vY}Jʕ+eŊ¿kʺu묿<_)"Y7Oaw+93F-ZY,rB z9z_`/$0 c  fr+bZ:'MA$۷^sɟւ7-%`…`Yh^RhEPn ~L/h.L?D&b<N4xX8}7u%`8X$p"& +xY㡹Tp8pҤIԩtԩ#Փ=6m5kŋo[.]jYb3X~\&\88;`?;y] bPp" x0޹^&VZI.]GҮ];ke_Zb/K-Yf͚%/Be!#\s+,6b] =,rRЬ߆s=̓j+peD}%opBio۶K#x5Nt謸dk`ڴi2w\5h `!#:uZ,I}p3`cùd;yFKBmu2ڻv=>`޽ 42sů)>H+KAU_]8ώ-Ds ̽~;41y͗s/6:=v̾;v~0&0VSrD?_D{nbnLu%if=( Xp`'C4Bkwy/?~>qQ:J,Sئc^l:A.Ľ4{L6_ܹsn #\͍9Meƈ"ofO #`-Mm$U ZL52$^&/ ܦ'с~anߌr?~!?|gpFš +/|!D+;ntVоq\[q.1U_1^C?O0˺w4yBsmo_}=x l2]3fLzz67( sxp" =5f⿐[ I,K})~Hmo⻁9QFN}'[7믿>ܢE Px !\D*QC*f`Lq+ ]R>ئsacFs^"VAkߦODզr0v j~cbYV#}|icoC[1=2ݗ &?Nw}wej8?i !~뭷O??w9Dp='k:Ӥ ϝ w{u74E*b!'be_ont -t+߼nܸq_W{J@P2eJCͳ﬍^謼qꁫra_0Df r*fw*:>ߴx!M -̙3Ga ^%E VRSS㎓ӧ˓O>ip-s YIcWpj{"SCa1!_x-R>/Ljc<5v222Ǐ/\0Ş^͛- yec"{.VRD ,SEp1>/%ȱg̘Q؅ҥK~B Fq}']rfE}(-Jm5h/fB{ w1(3.Q[I&ɻ+{-Xf͚ | R=YE닋T 8AsxM <,X_&+rrW *رcJq,c O=ۿ_Et@8ZDLC0@YͯYq0`HyRVxHOOX )yjߔH5[ }cyߞrn{zwޑ=x Zh xפcǎ\{QE_*;1n1s1h5'#F̙3-%E 6LjmS!:] R`f6H7V ǹ}Pɤ6$.ח'/,tSR@jլm*KO.uï8C,i١ EO3jߖfϖ56b'|"^x843KHDtJ+Q7 :ہp)[; +{W^}U9"FOR@_|Q>d+woy-FdP}3޳:+nس{ݺuB.rk{#0rH7lA`Z9"U,ELG[]mW=7?PzdW`"дiS˧;d ͌5R.3l\T،vZb@ֺ8TQc}sJ458hM=?>ES"tx unf߈K_H/`Bv M dv| 4 Ʊ6C[Nhic5յkW+qlkSR@.{Mg#e#R7&foSa(B S8i&x1HzaL' ɟ)Lg4n̘1裏J*UlG`~7OrV~^(M7oYs :ΗPzWPZ6JJΒܶ*nwRJVh,`u]0v݇oa a1:An蘞GNh"KvK GWtcҗ$ ⽓~)Bˇ>F~ܬ=R҆KX'L#Sv t=Yvhj*+h^d3\ɐ<'p--;&av4fGjnPy 3kzyə6S7lP2)0pҷIJ%{7I3ZR%L;$h>F`r֭5 -hxyS#Eh|T<_W=7v%[$rZ?H{">M\h=IdL;$6lXB\t$#iGNfiq"I'$￀R, ;(G{AwVm>,u zIoݾmnc{q5Um'NO>xW]?$ٯL|8d1!3s7 dIW*\{%ۣL>]N?tYb `=P$-kr_?c7%z9>AU?=:Ыѯ;=ڷ*Nlv{ %'O<ك%yÞyE (ڵ$%/($J ,Y#woU`F-dt$i-t=FGGY-N'bFCԨnWɟGvr<7L^a@B4 ,7I=+}k#Wd*X-<u?sA%XnTYnq|U?eU 7nSP&keJLv9}k@rR%c%h{>Anx ,jo;pE`;WpatO&8S7B8F{G3O>{ޯes$烏 <:" e$g,UJ@:v(h+`.=EqN g;^&E ';ǣ99, x= FEPVv9@!a KL90R!>}#< w_$y(te5ZHr0W^)q^ x} N OSv2Z-N=K~ ?Y>uAVRyDIAFADÆ Jt@.h^v( 3rڄľAhȦ6:/lj/f L.0=mV9s+l _&%I~~ :󟅷lmg+9}z HOI5jW,=^{aT?7#Nx}{d\n4wA.C9##JK{G>&q10aR% e\?,F!,&2]/({`fhS&WvCW\抟,]J=!q0ҵ^+&0ߔ+$ R/',3[ 9ْگ7ZscG lҪ{%\%Ώs]۩p,\  ,)M x2vAnI" `*Cҙg)71#K~($ rAϠ*gX4qڱC$TXUTt"d֬YegC>p> 9p 4Ü4끃@x3Tp uA05{n9t:NK.+HM/_AV=[2JjABSR"зo_?d޼ynC j[qJ(2阫`1CF^E0I/{!B5c2475jHLb)}ԧFw0&ǠW %%K/$mIͧOv]믿t(vźd`t0{>P&.I"~72M@০"ZXgF3֟YڶmkDBޞZOǿSro('=Ar;,' @ᠾ‹4 +7yާ&W Mۺw\9}2p|";K'̣TߕLWВSOyan 7&\a>DKj4?\F4`ӵڲk$?wk3gTW)V`Zɚv z!~lt}|` 0 b#&&>b?M9#}'>޷[v|VWp!Z,<_dܴ䄱~Ȅ{Ȁ NCpޞ9ר&:T ̉6uxJ4L4ʝQ1/Q߿PJ )XhSRD7nl)ME5G\fAJv".lm v XPNva5.&̝_ c-_awy:(8tW,NVtXs@S= &*T& W@(Ut|\}n<|\uU2|Lf#Ҝ8 o \GQ;AhNxknZh1yMbnjMWL%2vkr ,!V@W:BCo֬]qNw H  w+Sp}9Lx[ o?(n<^B9~]iW#>b%s'Pݢ rs D__"N͈ܹ_0XyB# 6jSAA㎓q؅݋`;/|3an%OOC[D+5`? T{ze>cK F`%E$n6E%M H w9VdVicu8([Z֞KD=W\tEү{Q+H9_$GB8ԬYӪʚiQ Ps=:GX+덹xp?Ŝȿ%uIѤ @pS{TR` /O>R3|X݆ k3G9&9%k8}'y܎hGq}̗Jj?Ah[}8M3H ̯rBxP-C Naq^KpM۷v6e[mdb N?묳o [!yz'b5_yAfn{^ +|/\ WD?ӔnOF5=pkժ|nvOf) iC>T]-?AFAO9 Շ`[l[*ϼZpR|oGq69;9y? .jVkAXKiɵ1< }r]2ӣ*D<,z87t4iҤaSG@av @n'hQ}b9qSߺ5r"> [& 2DFbĢPX  $oJ@$0E "9Չs lۼO>rOnr0}*x)$6ӴqH(-آ)Qd7RzX]I th4u64DxL$ju;x8Fr='/JLO28ɟɁ`zsKT|1r''լ!P)pmX+)#LjsW$?`IƧgL^'Vs\l`>xU={ʘ1n@!P/[W@NRW~@/Wh4mN4 19M(nѕ|޹iz,A(H"w`nW\ >\kbnA/)g UvSx˕~}D ))"pgK۶t{2N\DS<~\ |4qR |ZFEL1hР@)$w -8ڈ_%:G`Ыr$Ko$#P'K;'bq/xAi8>2&PgAN``*'$V2쯤iIRұBIѣGKnl%˹HGLW(QM x4\;!wpOp%p zbB҆#IU`a74BრBXv}btc l/~ mM=4U>~gNppvvW4D>$7k"i `t^Aۋ{v;!_YhLγ!V: 0rHܙ}@]ϐPED&  }h؃@**Jrs"bo"PK)v~%V[Xu[I:y6YkpZL-G_R1b˺d^zQAI\ 28T7. CcZ.rH.eNZUDY1Ay]Gvk۷O/@VpURAVݻ;x٭RڷKP?ƟW?e^ptAJ :bVM*teFD,4̨UN݂+~zGwBժJYBUaMd7K!(qxÇK.nh%&G{A߂q`Hǘ0C;}qRTIr>QP&Y~HpȺO V|L:toY؂i7G*X}oپ۞kJ޶MrFB$6 0&Wz )e#ЬY3yW寿*D{?R0ED nC};?!pՒ6E>/AR{ "bCTFvr'G} 0,3FDlzlz%\⇮z0r% c܇޽[Rj#X7A@Ojp>5LʵG$Va/)#=e9]y~_*ٟLPZj-hxT Udm`gF)y=J+BBAp^s.do/9&1?c$L͛V 7nQ*?JX?,qT3}8fk |m OJ/5boKTlD(=m88DUJ3 COO9}*y-F\1_PBX SN9tw%(=c{+$Lp\ ԩcիWOiO0AQXd8m;yd#@(=bGbx s?K3ƙK8T4Rـ`D˥[n~/0pm0퉳1U[*y=4=3IqҼysiٲ4mTk*U(ŏ@eq'oRZaqJڂ3F^z%m?oXˢF_{o( Xʕ+KF A 4ZhaM| SrWH>22M{&*%j!iCKܢy4蹊p(p Z"{,#;]*=joժnZڵk'm۶&MXxew1߇eP_Fč OO~lǟzHWItZU>-[*-29NP"銶DX;Ȍ( ߧz`?hAY~Nٱj֬߹z}}_\e։>!LZ$^IEYRz~3d>@E Bq8pVڡ˭?uUJCfT߹G}$ EV/pVݻҧ=7$U1 d&=H*La{5% UCd 4"LQ>qDdΎϦglO*cϕ;fY|ɝ={X @G!g\ɝ љ/{}hTR!bYE͛gr!4dJ>&bɧ(>`ի0.'{=M %LC0'խ+iCۤ$joa ꂙv?R`?H= Θ W>?!׬?iӦai b%O7Α$a"=ї@6l{&`UlxjLHJ89>֧L|G׭3N?XG&:*E 'Ņ?PY~D:s`?HJ=<>3|C "tT?33ǣѮGfirr$gIªJ@b!T>}L*7;{_R`_|E `Vɓ'ā 8 @Q4o3֟N%V;vyVD;n;;$덷v+H$:֭[MA g/q,$s[by''tBnu%E8ӦKoK0"4DLFxÿ•"NA_}Ri!tT`X pY2 ܽ|qӹ+vz⎹Id~723$oo,;%%Oi I5kHZJJΒҭVO譧OӨT!BbHϽ> =z LH'~2W;ɝ5۬_n. =ϒއw" )HPVPˆε;%5k c%PeLvp~ DWNt]|?^|ŖW?H~-߶͜׬!tO)@53c6;8nnAlcKŪX|&-IKe{QMɼRI-% о}{aM!sݖBy 0`Bcfܸqr%HK=v$%f/_In,q᝻$]^%8m2rD<3rq7p+ΟE-gv^XZ!NDYO8_ 0:樤D@'H?aO*T%Q]`WY&~fȞ5Y x<끇D XD]Rq_vjR`QU`t9bM7$G}oϚk'I֣.x]&jDŽl#D_Rd%~]8gmMkC#L lXBy2&I𱅃5\#g}kTIzΛLLuaywi԰'+ܯlld:]+a^Uy"\p^I^7|@N:tE$W̆ySN &H()! e者.1vJb_~=Vc Q!K7%C<޸IvAÚ'QFҴiSYpK%v Lϳ׉wq :]+%J|4|3_^rf‹}\3fgOK.0_{TZU8 @}Gt0gPɘ} 1SO>݄(ʠ# F3^`ORn"4-[%7746(I>s}Z1Px'{V~? '#f7&HJ#@ Qy_dž=8YgY^Zϱg@.7tQ0Ҏa-_L>IH,(LYP T$5䮩mˠ5c9]`x* Ƥ>^x׺ 2p~5TIąp6J5•xH̓3k6LHΜ$Æ"&߶5IR=C*0|^z\05?+D |5b ߉'QG嵮i@?IΗ_uz-8acm,j/6A L~TV-)|ٲe ЊFN޽'-[Fs؂@o"kG srRڒ:xP-9z}ҥV 췐% у?&6h@Yggxm @#ϯ; ޟE{>#'ډSfafgeŸ$y2r-&ߕ/s`pkV@IDAT1cıܢygG&H) R2^;o7(7IR ?t3JUiF^$Reşgmʋ?,?b3W}2 h7 X?brEӃ>(zj c K˯Ii^vn7Dg]o1o/4ȡ~-9yIjbmҦ6b Zr{+8L\0 '78@7J?Y)iOd0`3o[ZEma}}MԳMּyھ'hhMtU(g> TqL-&yM7IE("ޱC1a`E?Gx?C_?䩉?6]j$m15WA15?7c_$ѣG5AxH/ u I?9Jδ?H> `M5ϘZjp2gkFB Rl&:^Uh|X(:t',?!ڬ"=zU8xesI'nq{ML3sY^qZ$iJ4@ҎW䠾"ȧA% 56㢾ʡ N:$ytw_m6v,Ͼ0rӇ}?J X^gyğDfJƅjܑ4dxQ;oܝ1cX+ÚW8,hyÒTwlJrf|V`~>L7?1F b4dgIq$ABʝ0Hͼ0ϣ`&)p܇{:~+% id?ɁIȁhQB?޹Sr̕췧J6MV(ğiy˾#p !JA)%wp+R=4Jȝ6yWKIG?)+0M~}m`4Q'xg=ERdFJM/)cg#ݻw2<"IWnڴK_Fr'-x?_MFn>Bp>M>,7W6'o^^x7`*ܯ5\''Ox.ɝd!U -c+Fb8QL h1*1߲e˒>cgFf<&2 +dM9\`v@0D=0/UM^y29+=~Di j֬i;tS0V>kfӭ%%7$ W?I-q[t7)eC}Q9WE5k*ϝaů{,:I*є_F Ug) .TpX\u.FYI:YYg޽ZKzZQNrpcr(lnTLQU1 ep /P.2AL=C쌥-+jXW^cCCVIj@2Ɵ)U^,"t4M K=1 幵]6vÆ b%E`zu 4\,%Z5IG҆ }$aPv\{cABЯd2υυe0!SZR~g%E-]&9OC?!@?*dJJz k]<^y?7?mIՂ?枉HrC v?4i4hnlE *ߙ**/=+}-7*X;DRv.qa~|J2U2/8W2b͉~i1MYl] DZ4#QGZ"&0񗝣=%of#31TRzh@7kZMD/bay_%EO̘)` &~#v`r%혁0֭"b~慂ʆ]aI{ d^JA@`FaR臑bttń-R쨾U<~^RJ#Pߨ9}05슻$`Q8+[O;YOσGZP[dפ`6/5jdX b^{MgLə6üe&ڶv;sRspo [v8U0ar!1mYp;fɶ-?BBT^?MaG>G Yw=xA (&)qg Ok?&P8,wR苻w[wpB?J_Ȟw.1_WijPʒֳf'#gΗWVݬetO?)TcK mtJZ<TebT !={i2q@$f [49{ Z 'F z' I/77mݺU_rZߛoYڴi=z"k&ďI6TY1%aXD? @I۵`gXn-<&Pdܸq(^G`%;{-=&~zé/n];j`F8ՁUV9tIfv'~aڱ$Nw)sXFr^82cyR%iÇI &4b1\1?Ǐú=\B6/19JܙJșn(N{ M{ 0Kҏ,)t{ YMrĜ/DYpvN&GQ(%{vC*!/景,_#_=uV#oÅ3w?f$v.ZED`ƶNuֵ*nVMciUY @SxnOr}W-n/g;UWC gwZwd-~  r GG)C5RB%K 1sb(هUzR=j/c,IgZqF<RzʪQ/C*n#PhTIRu`$IݳO.iT<=~EB`ӦM ̌%z^Q1{~G ju”&%=zcak0 GQ3/b䛇*:տa m [n-\pAb=):@#JG(j/[a<]Tc%iGaHsHKw St E>+VsnR6a@7Du]'L{M^1${*4W()];#/16 0? U4֟ O&,Zh7ء̖Ă={o4A w/w͗6B?I-KѦ;TR:u𷉿xֻ\Iex$+A`&8W8 1sbW*U^ )!|&آ&{Caժ;d(}xņ2or`eZxE hxa1Ǩs@Ǐ .2CQN{'P(Z6 4O\ի7 :fS`<a#&/\($*+GBu17oAݎ0yA(7ɮAÿ/\UtaԦGE 'W(#шÇ}]9,L*#ɠ7ʶO5k L:K&J* %oѯ+]:QX'U C&oo8BTcU*= yȔH@rRs/Ʊm၂ҥ 9ǟܢk`wX`?i_< &1o<kP` @o4`ްaä[n}׿@H=pdHhU-?R%q#IH2L' 3jqLYْqɒIJ @` &{LYi=sLUy)_}Qvnɞw*pP+&~:&&~+ ^G\:bɚ? ?kh +1,1Q0`yFe0E+$5i$~@rgO=/%/ޱapW,dX LA,V*]>?>Q)?NhP, P\ZE!$?lJ@#ҳTG#g\eQ WPʒܬz$mk|Ba_6LG?7 6ҩh&^wyt, E@93gIδp ![ bPjܱ8l\R9AX| Q^F`ra{43ϔ*UKbn$ V/r%o!? so0oVv`a>cĊCJF Yխ[W+C[)@?,}xUF¢E࣏>xϟ[hu,./LDcLOVz~teIEeE`˖-B AbˋT h=93W+",*cv i!k>P\v#Kkw%d8Hpn^`z!]t1%N(@ PXG Wݳ EqPJlfB P BڛPn L=S4*GHX'˭?8g&Ǧ;$(qa.vX$9?vE\-H+jI5B;7*Wye@49R~$ [dStGKÆ MS9"Pt_dWW9+P!_~)7n,4;?_`$ Q*tI%U)"pcF$C+blyU{'9'Ol+ Lò>&{{AIvLTY"` `|-+-[ ?c49p%W酊"P kwA_"ˆ  ߚKCf,JS3СCK~(@4-bO b4%E/b'~^lR˻S"D' DS=)7o|7-.,Ohi QgϞRF+"P.J/ RO(Nxdݦ|ù -I"X^?sE@"t4*3٥?uY[z5k[oes4Wء[jUڵb}E@pPHvNU_| ɂ?&-9hzoŊN(m7k%)!i޼Y*DPlFt=9z(,$欂?J_Yc#먞逸rcChv$s~He8GE AأmCѝ֡#eÏIx,sIÌ/oD?S3ҋ8O>v4m(X@[';oM7ZIi LsO$I'8=Dmg< @m\*ҋ=vښ/^zEmkc*T*)(Ptx87DE}Ac1OS`%^g@^sUW<6i#Vr+o]C)͡Khf͚uH3b?ڣ>w+O/px6XXфѠ纄+y0Ői*,C6BtVY*DPC #tpr+WJϙ_נJel4?v4m+q^*bw^3D@%E@%D=*bk o2~5PCXKĦvM|R\ B\gX7QܹA*ɒ%ntu =Uo-+4`驊@ s~(=M~Yv\zl}d>y`φ_(ͬKRz1D:X~L81³m=YŢ>s+ }Ej,؇/ (aѫ@<_zR'_XW`?1ܼY' ?,K.uc̟BXik#^׸qcW^"EɘvAT8|?͛J=Bm,_\DO@n̛pE&P~}u4QFΕI}1 N%0g5VOh%)d_@B&-1S@0B[kHU"D @aG,EXBV΂hW{`~-<r3ᅛhē4͵ڵt=WP<@R2oj OI(D [^wqlٲɿ 7\TB+PR` XC)9ҥkSFG}$oSc| lB2S) 4z"xS[Njqqu LWyE`Νr뭷"MEy**2 h,6j#mhu E T?%o(]L4I̙cWsѶCf cUyjժ @ܷMP@R%dOIHޞpnÕA_xvo\?np*LخkN:m%E@ՠ0(8S ,uMQ؆M+Q%mSlojX3R)@#-xwVs҂?l~(?|ںgT|85jq*@P # %#%c{ 8/#p뮻-?Bc R`pWfTR!/SgtUR pw}WїgaϩG*p/k&+)@HIP5?cZ'@CoGS. 'X{u/=_PBaƢJ;vXm۶V 0#Ն]*HJ" K_"y )\$aƌnDu\vI-=("A ^"[;Av^{G ٳg˝w]Aknߖ[f[S[JR d] U޶]v?l:Jv}[ "C^]v Vzvl Ѽ7nUΨ(A+$=]p\u}u=IK1Pu<#?_};D8*h.\hT SE fX@c­$17zV{衇vd'̳`'Ǥm+ih(!Biqɕuɒ=?j"gK/̈́?9\<o޼y. ~a{E  9T;@ܹ_s.m%9_NڵK."w\XB4!V(Lhf8Od)g.ܟ~N45޻KN@4 *uL**\T+ZP`$'W^{C#;^s'8G5 n()" CݓEHu}:蓛 sp E `cpE ̭(@ T=@y%{ #5t0, ]uV7n{Yzu&qMֶʺ"D%rj`x믿^fΜvo<#n&lTk _%wx(v @(:8sh2soF.r2 _|P[x}G&ƨ2EaUJe#A(Ko#;IV\vu}wC>\!Wj`.{] U@redWN)CQ<ܲ?^r%xM5nj OߤCn_*@(b #W@jC$%>_?u O^z%ڏa_|OuUؽ{L6Mo6F@.aԑ -駞$ʕJ>W:,;/unu|E ~B0|*Bn#ä/J+g;v]\n߻j`;?I&ǮE.UA|բ,IiF2L҆ Ijc;wҥKz#t#k׮լn؁ P/ yRɒvxlo=@@?.PL2.|E@DWKG90Z׎Q&^|Ehpxbu[!;_ȪUAnwE+@ *d&J HƥJcP/&K쇉`(coXhQR?"TH '?|T~{NL"?ׯBF'BG z/%;0) aaD**JAĀqMꮮauŰ**(( D1$)9g?``zNu|sknx|E@D z50drz̤׮u{20 6g!泹߂rV+رcu(2VXDӏndۤ-cQU<C3qhv>" ^9x(~Z3SWLG2jT@۶mͰaÜfl9tja;=Xıĕ]}vU(FD 26cžLgJ9d*r5T6mjjN:z2NUKUF%^ޚ%K:G%[ LpL9{]:;%oE<>%eߤI3bӸqcۊE +B<6m2=X,"`H+939/I?MTԮ]0\W`S*P9!h,@*.! kJq3/ &ACMVZ}E=Gv2`>,9'-$tp۴6eT*X}ǎm>tPYnfh#G4~ix*.gfC͚T3%t ={TcQ@*T eUWz.\hza2HG~4z/Vȝ=nIty. +nOH:\"HǪڵ 9 <pUKZK>)mܸљklـWT)4䎟`ҒEDž{\LŝMFDMׂQ,%-uPPR%;j76?`8mc*yMT441k*kt\@%"'4>]\%¨ y.4r@ Wx*=<: V%M1;\')?b2No,shn$s֮]kL~G΁S?=T\X>X*@ɿxL3YT7eqdtڴic-ZdfΜyqb14-Y/B$#T~)Y)?-9iGeSD^m ,lgas=׆:>B$eI˂*$ԆFS+W ($@9\Sfz[F 8piذE)(_(l4{=3`H6Tac:yi2@*U'ׁSdh T}] RMK )?۝z3/^4jȼ X{騈m%v @ :VGd!ۖ-[̒%KLn0)R" nfuDj `WLF60%.jJr`LE^zFeE8;BD[nCbA͝;הCXЖ-[*]C3Xתig}1ՂTs%7oݫs-#0w6vxVثpf„ 7@D9FuNs6x2;6?cI#k=7A/۴i̚5k,`+7mz#~CX\[ׯ 6>XW&j[|Yn 1%-$2Tػz9xٻu)ƒÔzo&^y'jԨFL//& 0 _ȫ?faEz;2)zm8>čq6t={lݺyw4)g\Obuf8癑ώ4o7)0?9sfZLCFv8h `… A[D @$Wv9rss8>@&a @`Rlt:[^?&*+ois=g8 Z&A"믿ig׬Z*HXT8|!{SnS&c`P%F?M̈#\bVZO"3lzw Kd3.MGse"Tf2?LcI0MJfY803wqY ,D_~Ws}9Kd?SI=! IDAT2.%x֭[^mfFHNc{1]w GL{yH7_|Ѽ+fҥDJJT"?CO6ͫ"p^dw2»` qWPW" 4F֭3?馛 2eY-*O>gŸ\H[7h2jr%LKku~,˔)rJVl%z뭷[uTV;vSNPzu mcuRUȋ *V~W8+soxg>5Y\C`{v# C]UG` \^I/nq*߁l hݺԩi۶[~w١?5棏>r^l iʘ-Yԇ@Af ~6*燁y?̜9ͅ7mW_9+hjoX+LnNQ֌vg83 c[jհcIIϩC_~3oʔ)f2%+H;qubs1p IKasVSO=՜vis1؁䜚۷;'OlkW6' LǎKHG@ZJ5kVRs7 /$KH]7Z5r&q't3 dG&|~ҤI?#b'XtB;;\\W_Mn.j =Rl /_i`܁ :t>P'~ 7{  N%W(/tMfϞ=^ds68(PK'@nݺ|m&f+A^KAr #8 k|_p:>ϙ3Y`PN :<䓆Qd"j YT6lHuqg30ЗPmHl`p76]J*NAR9s[c_<98.]j-Z'|\q!,N g0qrmqȌq_{FN;<ꨣ-\ˀBٲet)p"Ӂs222LQ1:yts.XoBi5kj(2c8q#DmlcͲ }Qŵ@Hg4oNɋׂ1`aÆ9cjw_t%;Ou\1 K" >%УGgc D (`75 )A&" s*T`7oo2:.DƎkwj/F] dѠ<z#G:k30`P^ԁ%7e%8d 2?r`8 /믛޽{;X˯Qa|T1vQUT A}³Ecl~\_v6ұk`yC D |sΆ˹M~tMo߾~  WUx3zx pH.Tzus)ě1~7|p"^OA` Bl (LD\?۷o7Z:Ĵ-S9#0tPsUW:!0ڧ7Op\ @b8CӾ&MdN=TSRV{qct`'B Ԛd" "  .t>QF* 1W_}}:l ]3/2dTuK=t^@f͜s]vRJ d>}1n8/O>pz,jbϡ:d" "J5k4_|tӴiS(h6s*ĉ7DE͡w zLDkh޼aE]d=d lذywͨQ̯Zp}u8cစ&x< ?p)@ `9ӝ3w}D]/ /ɒBn) k~D@DSt1 8;P,@l23uT3bg)f~r_+hzDCA&" 6`7'Bxg;5j0Jx afѢEfN͊+JSl(^awȃk LD@l#PdIgO.tC\0Iu%@DADFUV5u1jr)WaA LٲeS}k6mL[zsܹs :O\O BY9 <|pމ0@JLŊUVւ;x4VCλ߱c3۶m3+Wtٔ~yͅ%l@58rH1ngdܬw" "<t WLafV>D|J +d.gc"[[E@D@Dj ? +VLf86wom |-8R Ng 2 F{:$_(H'/}+ C,dr"\I3$' :^KD@D;o"k>Ѹ8NX6gUZd5-jC  2k lDފtarX"}] $ MEN54d" " #5buTdTb}hh'/NmYўI'" "f{P硈a# R$@л ::ReMD@D@J`21n;_PZZO@|@pG}' !<+$Ro?dWD@D@F)'?gsG/VB&" " !%0>k sx~" )#9rF娌D |8͟tٓ}hfkD@!oq _'z+7ێ΄d" % -7Y?7%sDis#MD6O` *])f5LP#mELl'@lcP$㵽 0?MD .+quPa߻ .3T}c,?@KUeP@:bk 9~N1x$G /vލ]4WԹ#B l=,bԳj3*G >Q@X \>>w.0]t; *[!瓎yPxޝMAgA2y]]ed:68 ,hH͡_ /Y8q!h$B`ྗ$TȱaPȏA 6@JpW}")f,PX%ljA )\Md6l@@s܌+MƕOf3aXOhBPw.80ڇAAS-:Ǐ6K[,V=E`?Yxe gnUDat?xF%bF!߯7 ՃNZA :2(lbT7{醏bltHAAH`ҺJ͟e V P;BqtJhZbKAS TblPF◛7zξ~1J` >ք@ D@RyoJkof~ 8oae@ .t~-=V fχ%F`xIbIhg*ȇ7_fIEr`|Bt - @}>ږ6so|eS=o M1ܖ %!^縛Rr;U hONnyh#񈴍NAF D76~C|͜dp5ľD"b 9?$'Pّ =t. AzQЙe[jЕ  ΰXu'<>Yu=A3RHNA&zg?nDfs?))!h&JImDO Pw@̴wm5Ȝq "nМVGss6:+9W+H&"P8:Ig^Dμo>̘]8*>0LDhհ((][2 6|f55 7YhNC0p |3Q-|L`?}!O9 ѳE'Oed" >Cus%,A"xAY "fw yxa% A zD@#χzb.H6LtAk_@E ~up'P~CTԝݸ! Aa{PI@ AQ(cʺGX{Id2J*oPHv ɕ%eyd" v81ڛ~cTW{|F}?C~ ?lf?ƨ'n|L8cw"f-1;a[DF(@6p/JHP O&"oG %Bϔb^@MPa r4 cUIN<p6wn3t-ąd'~1_/ED@K-!/~kg9x}lτd!#nw 0+W@xpOhZ8 t90(H_ ޟ=@K xZ~ R~B-h-Psc*AGCl΋4Xoo/kL@3 F @Aձ|Jgd>\Cc @ @A<(O aA7At^&" F3ćuBi;A8  0@#"$g0:L/Y$P@ `tszPHJϧ/o,$8 qt6tD((,Ƨ9ds;gH"9.U" "as:g@ABtb|_?,đw%K9)lD@D ql]8in^`+ ΠZ} 3A#r<lE@D AWԇJV2i[Fhb gCˠ<d`PQD@D 89PjA@lI`rtQ8ݎg05.xgN $ Y>cIENDB`ic05ARGB3`{N4Q1;RDrBYt FԇȀT 'c4kP[0*"Bye%?M{/]2EnqÙfc; ݙ!X\ɀ\% ̉N Iq܇"N&!2܅; /# "Z_&$p˜Q U+ SQ .oP4hÃl <ÇAr#m: aIj߇%ނPUY9]mgJ _b!$p˜Q U+勚 F o 4SQEo .oI'P4rhiۏA gÃl $2]6#!ӂ< #fvÇNL"A r>.#5+?DmEWЁ:A0 aIj߇%ނPUY9]mgJ _b!$p˜Q U+搝 Lt ## ;SQLt .oP/P4whn%ܓG!mÃl ,9b$=*(Ղ<+lzÇTR*ArE5#<2F!J‚mK]ҁ:H7 aIj߇%ނPUY9]mgJ _b!ic10PNG  IHDR+sRGBDeXIfMM*i@IDATx]dוyJ%R)e|ae=(tZT$GzR66}P.LV^2 Er3 Hdxh)tklГ~􃬙 qe觩k1Uq"|߂q>{[;"^,% @M!S{4㩽QJwǎΧ@@ , @#JoȧvL)62{$& 0'!@@aҚ_/~qG#g-,^@Q 1 ,[yIG'3I@ 1 Zc-5-!J{[B A@n@J"ZJMK觖x(@6.YZB z7xPzcC~٫b @-TRG~)B=;ҳ@ג>-!VRjȥT]+OS}o,nKB ?c% @G o.|\zv:EX6oW)}L۷,uo'{ SW @\o*7:@ X(s1|_E ܪg,5-&ۦzC @M צagaBoYbԴXtђObiRߒBk< @F@7MKjDklx >N`jP_K jk  @@jud,] mi M閥}K!Fˮ̒w \ FR#G,5-Dk#d8zG@-K/XХgjF% @`MfҮG 4eRf)x@@mmIs޶u;@  ҖXo }E:=i[jXB P*woX yd @^R @hFKt^Ky1ۖ@YiIQ]xR@%j[( 0 {YZ@(jO;5cԶ@ ӿiI7C0€6POص_Rj v%װ@ ` sȍ4n-հ^u[ >3K {,Hqٛ@0ƒ^ C 6=3瘟mK=K|@Ǯl?]@  4>KGϋJ Pڳ@X5U/4$`@R!ر {vɒ^+#BxA`մlXRgijZQ|˒-!;pҪG`L<,A <9evN=k;\@`qѲ]_8vn+C j;o t/r5oZjZB!6SN Ia) P7eS@7|;@Ȭ W>v_khARj w:YM 4MPneǪ Ph=f@h>dl9ͱr;@0VRfiR?Kd'G`;k;M6PNPpRcr>@Xnۖbœ@A@ nu7>|[YALh \vU7j2\ݜgt  hۀ#ZB' _(o~M !d̾%~xo@nHeݒnm6PEرߛ&OPl37 ZA.4^$qX5}8%Lhյ}j[ $ w]M7 Z@.hROg(77.`t*zfI7>6@p lRj @êvMIh@8 ]KhgoJ 5ҍ 0 \n;;j U?~t/!s뺵iC\> },!P.j@Pp?ԋ31DU]m蕗@2-m6Q%7dĨVT{X* ʁ*!>uJjbi/s2 ٲf)@7w,bg )@ӊ)(J:@ 3%1Y@)ou6@ l]j Y]onR>] ܺtP P:j?ofnaqO;Yg@ fdRjw /vӳ_ @  o2:fʥp ,=@ v@Kݙ!?Y%7ԛWE:TC5ұSsoY_%u|"5eX+27&gGG* :_jc &5K|a@ lZBFP0v~uشJ:*#:G$&S, \̬_ZUfcݻz軆@ 5۴@ T?8wx0{v,&,,k#3Gmo^jRS]1$nȑ~k@\4M?MSv>_(3Սx(zm6i^fR?$ +fF7 SbFW_@κ}&'=3[S'JYi)L&зW,mLْ X͒Nj@PǿYA]T@н+rj67f~oSN:~n :S%d:@fU6K$а[%OjZh@%%u\UC4մ4-צ%"eZw9WI@@92w ^0 YyXF,/lf nwd9{{{IH8@ՒZմM`Wo5LNL pε'Tqy(1|sHAV:MK#0촫C|`~iƑWݔi>q+j0f& f!q8of4iݦpt_ޏ@`À^ ,B2k7̚+%X`S P(rl,tH}}'ܳZGRƏ֤z}?24ѷ4I?f͒HW^M@ل)g^ԵT,@ @׬XeKdL 5ĮCU,@<_B9;}5B~)WN@UAloo (0Ƃ8tv6+_:/F diGe,X 6wm.5ME"0vֺ޶)k_LMx7SY{j.*%##V̠iT\'O]1\2KzδǞDR+\2+l7h_gy0YLMuj~[t>d]=mZZ:jpj_e ^*'(0sv $\ejj}OKzj**w|Qc=:%$iL׈?XD P@ Et"_sZִ|rŠ0Ski9BGdFsڢVkk,<3Rxf9eQ۴YsJ#EM c!@0 HOUo4iZ({~d_m&j͚(I>$# R677?̦|אZyZKqeҨ%Kʦ 0ym{sR{tM)t5<ӧaO#1#gjT,W^,`VWZzۿu^(#gUS4- ǔ,\*4T*ehEFɵk@n8=eV[MfoL)L$4lq'S+j(Q8[UjrUoj#@d6˖]K.#w4.uNC@\^,W[  E`v*ig+spzfଚ͠/fNT{ ҆zE%Qa_@Z  s4l9% E`FUܐf~]VSoKv嵺S!w|&#]S}VMu5ta@+xG`d_=ּC‹xa=_.:-ۖ%xUi.uwwwvr**'`ܡ'x?B#֤8s#W Tui?X[O^ԪwUz\_3A*$zzF*OU@.ѽ ){@f5?=1޹87Waj&*xYB!ξvZBǠj$~OwFgP5$PvzqVM?nC{BaZ+onn: ?@8- PP?5xk\eK8aj&.y8P_HX[87~G@ qZ`8?X I`ݮۜZ.+㯍y/,EA 2Dpu8 8C@]hZ-~c874-w:}s 2ڙpU1iЭ]X*_-*jЍ /z^rʕx?JCM$=DV_f9{C`;EbK[b !0@ȁ!}5^$f=3ϐ)麒>3}"Cec/]𴀲IS.~yu,z@z4"ي , a6Z__O 0hIfK0ӡ=fg 4g[ۆi~Wd#%G7 @ hs@핢S"#;@SXcbȆa% VUn\KK@4T6 z1+#=dmD7lW0T'pxa t3 ЛE`)=FgQǟNW8@ h#UU&7f" D 7#{ H OG`8φU1$@ 7V#F@;+0@ n\d U _/(AI9A{hg^e ̫A D=3J_N$^=36@v˨0)  0'8.sE*20EZ8N@s u;Twf9 9I70`*2"~!0ppf>N̖r Q@_(0]veK\UdNDo7HtUI2S piE,@jKJ/ fRVGC_-- Zvc4-4 jiV h[~Hyd 0Olh&'ΝL#: E~)R" __68#5EiUd`((PFU liԟѣAr9 hjv'{g\s_nxŵWv̂V`@^kΗYttFoA\@!}\E ӡ~vz#tȷ51H[;VXK*a2qQ"6["Bp(˒GZԽ%P4QE7`d:fo/2c4ׇXZAE/{ k[:w.9'x@`N{{{J, a6\L#(35%$Nf:KH~U#.ZwQ+6-}|{ k|'N? pG@AK.%zE" ޱe̸jdu22B9-SGmEiRk.*Nv;Y[ֹ :={t 3OMr| f , !LQ8oV^᪵edTo?ZQ *v3mF5C@#7uY~+ pS q|rteyŒ:zﬔh 8XɮvJ3ՙ *b'е"V/VꎥRJP?;a~?N3Omrw @@*?DPv  fi/k3T9}_tbuhӿ5\GmM hMe83Eå<B`ccc0 sb5g_a{ESk,>\QF4 |a]P&dvmdm˸]+YKLzjʢu_|/ϋK \6Aq,@#5ZXR*кiuTPUA`躡wZh?NI6jj2kއ.zf< tOcf# 1q!yҶ%e"hVTGgUzkL{uz tz;G;1$:Č` zBAA4zRt 4R ҬcJwihszm%j'fs0_k\|?D1?{'Ly@ |q״xҞ%[ R lBF'Bi BؼznZڲoIzğvG"$z?QZp_6gWaT}l7@` 0Y.|eP.ֳVYK7]F0l>v^ TugV:wZ:nƛImuH1_lX NJr[r]ʕLjqM V~??濔+sPT;}Rג/n-:ctXd#tuMGçɌbR"G$ٹք:FRC78C둾B)>}K'i}DF?J4.:@<`3 'f{r/yK|&{Qm,Mk{޲!-B8z?^j~q9N@A'zENؑK'r=a ;Lğ Q3_KԵXd mbl^;c=X!x_I zDF@ {{{ A.o>%MoNtLXo3Fcto#٫P76v!?ÁFw h  @{Ψ#.~6=S[_2$m<쑞Yv>X7L}KzEnVSNzܟ6C&pSHn+v@۵3+cFxⴣ6tQQ$/١-l:{^7F_~F ?CݪP?=y)99r*!M]A%:` `HÏ׾_"ڋm`[vZk@ naV-pVb@x:Nrҥ ["R[K8 rҊzzяz,;;ͩ^}*ΣthjdɆ~CcI@OY_V|S-U?%zqu ah9ԴP4LǷ,<еl-Wؙhl}*Σ?O~:Nz0'|v4|w#9e< 0￟h_䀀g-iy szF3xulH|szǏ$ж͑g"=hq3?kӷߙR"ؑl3\ֶZ?wԔb ߏxWvx>QuusC@SdS zɃoGJ,B~L{Q iۇg-E0:^Vf5C0yQ?gGAE _h1\xN}vF:0Qoc@ܶtR.eS-֎lW$&Im;8y8#͉:<=,/.k!4Nޭ|R̆5KjwWfSg*(%аL$MdwwmOl֮ OO/!hCw6UQ3;i>5wS4f)WFAJL`kLAX4򰵵E"zNj u`C0}UfjDycxjEnZ[i&;-)uZ[s$}ZV`۪uLͦEF?.|+\ M@A&z4[zyļPC/{@: Kz#uCR|˴*%SJkߟ] GК3~ޱ| g|"9C2 [ 9 (d;Vwn)`Ͷ%mĦHJjAJ) T껧V 4kGP#zH^Ya 0+x؆|hB`k!i[:o%:(fiZY:]Ų+pwSZyPXoYD"R<'<'ս[3{vZZZB!зjkhA57%OLS3V&j>9 #%+/k@ p%B14G ̎òbIw蚨c L&1I׌dp[7-Oq١ԕ哟]kj!0fqNjZG!Mg!B[|PV[zT]u,Ԇ.=K-aL~iP8LOStXCT+]QFє xJ@A6GX,ZרMw w羢hX8S9Y~[xOص=:ނp̶lIӇ,=k銥%8 +U\q}/;e81k*8'=wycjL&ҽ>M{Rᛥ^s ~Rz;=x yu˞>ѳ-}Rf)V\|吙⛾*?d-M{ى6M4_{Y7SsYr_U@n*Je$G9X%]QeյmhϢ_gfoxMc|fƛIa FGeq*B`cc#|r,Nc'/M9ؿafn[ld[[v1%O6O|_{)jEee\Aj%=^2# 5:Q>OX++XuejI*TJkkcbUi'V'o>Xs*5ۖ||SzA}5E`^Vkk+Z}3\}G%LR$!_})7p:/xn# {n^n:aglyY&NN$ ~wP-K'@0tT >^|Ltx*=ٱںVeE4Ftm^)*?"iCM?}Ir `GA+?,S2]왡Xb|ߘ'Ӭӽt[YZ*r![ Iu6Rrma[+8%^_-mƶHՔ ~`ʷ_B[fTA: ?8a0ԙ7d6+Zꫝr3]w枩ۄ´W߇Ua/D)~8B-?M!@yRG΄@.Lf[m/P'K_2WW+I%[)Y 8/ӳ&'B.= 00r b x꺩ZeZ:ͦi\NQtwEӽ}Z:_?(j!@"W򒻪UYj*iJbW0JAإiM3:z:Do'!eSK]L+Wf\IM*I-j䊽 ?*xʆ$dYe3}!|]yثVw*Tߥi6.R^9^GKױ4x_ih++eGz2ד4MХ&%VB}]r_R5TYj W0b5_`r[3Pb 4` 뼽vCp_B`*3tMڵW` D(tP%66< oITD@3D0bi홏kz,`UKR_0uꔋuV^CWkӵ*SS(M|z?6z߇X@E(| ]v7t"0;zwԩE:`Ybu=N=U;UkmVL?C!E,h Z솩珺kZ]0$bra[!66 ۿX h@K4[To7(1˪߬K+VyNۅ}'jAZS)j#&bC |r&ukS_*mճbWR fi1`^f@"_ ,3@IDATB8jJ P "k}C`:5'$A;f @ 0sH`HVƾ@km [GcL{pu)0?:c0 @P$d3-hI( lvnu\)Y#+׊B5[z0  @`)b@˩#YMZ:V9nsԮi4xDF|8oy 0gf0]b(pY%C\.IQ-3I/V)MDS@ Nrc5 PWhcH)nWL&,}jW*ařWgv,, zQ|Q؉ ȟ*j^hZŗ}S4l؆C?ҝ,K4U ]_{$l#=} }]fVhۮ|UX9զihҰLFA4|3Z<e'Fb9BJeRqVrR8閙4a]4sLr:bW迂1JjF7-s3ٌ{}ހA,Z ptE5YGb{u,hiEjes^enUKmK;-]~^ο8.lwHO8=g73^Av@І0Bѩkvp#ӵ˷+Gy.Y_’:[,5-/@~kZY8k!&هnUS(DMR4L֌/[f.MKmK;YRgӒ|ڴ,@@Dwja\zGX O13@L"񆀙qI'RR_%Y҈i7 |d"=3ƦCK^2)H>Ifcg|"y9a@?ㆀyx ~Ն)纒%leY+QRR,mY:KMEv9|:ν::%'~LE ~D" ?Ltor%@R dV:e1y37:T:fե-KzuԴ8L@k;;줊UF/ ㆀ@z`C@m ؇궗u{;VEjaT$53.^+sQ~oYUHUۓ~o=5$p2l@S hvS"e7楺J4JjrgMCӯN]9dqZ􌥦%}F<#{淲fP4巻kj@,4$Y=:} :WWUQ]uN֤#I-SʔS;߲e%͚X4dfohjtoX kWkaA/G@)nu],V3WM@]Ki;T߆颍[EzfHcjtRk?QqrΨSD +4 @{D$]u.{P[,Bd7`z y|S>_ 58I@:N 5[./U1F`jnV{MըLUKWh}'~/;3p&H}. 6&,yR^c@S MX%ο|,{鏨GEȻřzwU\as{BIH`ss3633~ ؚZW3!>+!F@Aux7yCy Dx/,/. @4nX+4Ga@%t=IrF)Em_~)9!x^ի|kJ ^. 0 (Nh@`.\袿苏>JO$zE$^Ya $iޘsf@H*ie!#?3` <迧CmDL YoTrlj{f$ss`/9yrp@ D {UOe3ӷ<]o+:+xJ"Yd)WNLnx^)=Fk̄@h"pX%2=]lcK @P_FO?Hvdw/d2B煪&UvM;ٷT!&@>{çYDQQ3u|W#!`DZ,fDԢڷ4 #㎐W 8\YΝbLB${-H*@ ԎG@fkkk5k@!3ms*;!^Ӣ6 #(KʠZML3@8|.Y՝2)e5j>ZC |POHO~N5{^?S_yx+7x]lيZlGKcQ|E@ O[ BW<q}7BQ@`V=PgM^Yʳ@Yd.W.6ۇh(E?̺Fr~*oW GjwWee 2_77 FOVh?l&}Q骧7{gk:B >,Hgvj@)` з̒`,xL;Sյ7aGK۷ 0g&~-;zG |aXTlz%@0  o%Z_E`@@d /SfE6rfJfI(5m#?$=8Bm#9h'[<05Ee@D,Rfa ~ ]˿x%֙;dB!b#, _eP ̮YX?DDH@6kY@ FI4ӟ)PeP LiVA]'wf1뤭tt JAh`D3Khᖧp2I rn:4OƠ j"h?H$+NE 3o/le(&hmnB@"Ÿ@ S , S_TZ"pGUWaVw,_VB L(%¥x7Gt&s,9. F = @ oC5h/~5UQ $Qd;N{d3_kp_@MgǏT=h)TwԆwZG!?ٌXhSp*@^x衇~?q^Na@,cfw4!P.FK \?39"p b@ Fm\2fM)[\q0OpG:#h_Jz*d@z^NjEP 5+(3|_]}Q:ms~k CFSB 4A>IHL["p:?8b Pmv먺:WBb"Ƹ @E{젃> |{ɇOu5MPp6263?, .ft6UDAQ(z:4@ hpeuu5t:aFi$qX&mF@{GQ|]9 hӿ+kR{DXI8@`qZxApT,&3ǵ +=\&0\w?_p`z$ծguΝ[0 \43Ssz*@YƥE.Z o9 ;d_`{)Ep@fpT;7RG_1 +Wvs/ CƦUSm;U^Ic 0o|MH3_b0 h_F Ϛyq8];:.!Pkʗ:WC h?2:e;yo?G!F`8WUeo% M!ӳ8gd6~$1esk_̍!lll$/_J95Z0  в<9# ӯ}"@y>^R^/tF@@D7o1CkذL-5d&}MG |/SkV!@`loo\sŭF{hE`j\%˸73#Q}gyf~?>X 7hL;} I@@{`j\3 -hry%0j_YpmD՟`*6B@Ozh%>1Y&0+1J`.`CY_aMr,C ν3z1h>l 4ۺ3,φ3PT겥b h-:~8<`8kԟ  hRSc#@Nf|B&1-+uM {o-+Ƣ ZʂA4M677A!p1T?=?>X_ 6?~{lY5c @IcItyјN?WnhSg1X{ |7^irGf@<6ɡ0Nx4dǒf h /(@kd2Y~fh8;_S(,fkF9 ,?Ϗ)3Ƒ xL?Њ|'@3G&)7} $Z- еjZvRH} `ef#uS  pJ:,wq==ڣ=x?4k1Cy@_\H pϛy%L@SdL%iʱF5"] m)^@(h'au3a٤Xcg"0&E)دf4o"< `Fi? (яG05 ML}?ph"M$1(1[fbdd4sWtzP-Oqd=l/;;;tKfM@~7cL#:ɇOs>@h@l6Ok@ ھ:o2k_wj&Ȧ0s0mOu#-?y ?y#c% =n DLdi6cɠ)F5c='\윁@S$g̙<QNd (*ӈ?#%MwwI)XFb<\0u׮J>O %)i;L@? &! W Ĵ-Z?;o=&esp h^xB@:%kjI5P, >QbI;,GB! wóI>U_  \'mg}"XLi>Od175hC|#@uf] 4y0U_E "A ):F_uVcjU8=T:&F7v{a~_/*EBLҙRAԦucR%uqU"V%ur@pԋNPy1ꟗ  ׺{ i.]d8s-4X)|dq"~_ob\)'jYP}_4}{K6D d@VljnY+ %Vk@}yi4"kVeD+|r$.#p{׆{h69h D.eWLww1ݣFpk*Oz0ljyoڴȿڣ5 ;tNg;o0W(& iki ${_O4_k# bN@SceC ?ԯ<(zC wx@R  vg?HeSoQL 4Pv=ҚM=G`H­MSGB F R@MwGMM4%,#$0o+):uW+>֔6 X Y鱈:Kbvj:z%yᲑJ.{`qB V~%pFW_ NwKb6sLwEjqѯYeA{1= ;͵md&Lgh F ӏ>(!`}ˮjM}# <濾X]wvv_~j*"Qب6{.,&4}],@!r{z QW2^S9hNW 2:ZSٝNQ2~1tT!7#{T:K*5êNNĭV+Ѵ@ ډ́lW_ gj!G(6sW B="'gY6\@?Ŵ3LQ%y橿-t4kd͙0Og߱tk #1@Ly fj2k 7x7)L, ӯXU |,C0$QkjU7%4bS|{bڏ#M@{,6Cռj#3tMVL̈@bO#tPkFNgDLF,X:;p$0{ۘ AcbN}>y@ߎ֢ eD+O5ׄW,*@>(̴]i9o$l$8X4ئ0SGbZ?qCa zÇ{OjzVMUaԢNFO#p<|u3 0@%0ˬ8%$'6 l@ѻiEiO43p8 ȡ r=ܴٹnl7,BAma42y=9J)Gyi>W̑Jm9O?@Nr& p m1=e^J Xk^"Ep- T(ǡ;ď I1@bznF& >7~?A|Y7w9G… TB&zb}lqh幪>'ۮ2+Ulac+VAЈp,rGD:ݰmƚn-"SWjʿF)IbMAi@G G CL:n9 s(~iT0'c-g+2 p8DO P7q?smvd Fs:Ŗ?˲d}}@n_{6'c-2k(c(ő_Q &a}>*KAo:*y︀ P`M#4blXI]ZX6EAMWFji MԲ{_&; x`ͬa~t4 #du*c{˼3Ui#1"WXj| E:̇@̇[i>;Mn 98@"SRmR0/hs@,w 0o4Zj~{:s0ſFT=7+@S&ٽ۲K/ :K! h_XQJóSj "@fêp'0?  pv(wi)d㿰u(D-VϱXv; -L_$*&ʂ@_Og+'@1(XDuɧhr MiE]R5Q ""q`1|۶l|YE?>c1 8H%QBӔ5_O^Q~BK#pjuiI.@1{iYxNtǀ0 )bֺ7 hoWLinTL@L̺ |ZS&L:9u)A5B@)F@4 e~ܽdhЋ@&?le:DO3PgUceRRk-QFn_&hN`{k$#eC>F~! cn;:ǀ>n,ǔMۨLo:j'H,m;#ҽ_\L$l6y DBaԺR#ퟑCPx @`N޴"wcMh?L'G8쥙Y״@ @`qE4Z)i 4~k!'  6[yڢ  ӣVY@`!Bs1 zS M׺!}TLa) 5%p',!"{m ~5$˲CGx @1ɟ?\l@i4 h [jBX־+!f!}4y!<bȿC-Di?@mXzx Qc9 PXm#J@@G˔ pGh@(@ 2vK4W%{,Y~<Ͽs{_ALV@B1n P Bwl6/EA8N@#lw c%0n8_(h TL qmV4M h2 L?:Z!" Ш??;,@' |/N'w$ юky@l1 "S zh4nS@ jn^#7~)piL{gKp@B4VV(1O kZlP 0S'Uc^/PHO_l/*_~K9uwpũpB @9[b&&#!#r<?(5k̕W9 @ܴ<9qZ53xR[dBfH"PdLb_ug$ -дP՜9-*2HE^bUVΈ-/^ؔ*POqZ͍ۋ\ 0_y?N74_+*@Bw:0g!X =>\1*$ 3{Xidٕ.wZrn?s LU H~m_T*$@bvl{Afwymy{ :1? Pq sI\vsϘCpyѶ+8CB!аQzWu'!+?b/J@]֒W,I3O6xY=1Qk?MGB(V@2@B(_^ r?sxe[vLe)4 P]\߷.j毿ffA,|*sj.Yϱ:!; @S.G} <)Quw cɿ~)#VLdNB Kogv1=zMV %mt| mv2?j 6@B +Pq;&i "(cloowzPIj @/֖2Cv]Ցz;3sA,|"ce3H :y9]U-'pD3;zH @Ch_x[O@Y/zͻDǞzL_lt5?-/^ؔ } 4]U JQuW P{߮߇mKˍh[I3ΙU{|% UOyV6UIv뙜 9W53VGPMk+w 1|{D tʧM[X dgR2f1ve |]֠\ci)\wRPKkGmyyG % 2HH(P/)x;e{ )]hDWn $L.Hyyp{}5|8yH h[үeAx&;]3qܿN{&ǻ+?n޼GFrK˦Z^BL@fޜHcگMh-3hH#pOu=mV3\@`O@PCCg~oiMYݟ,ŹZۍ~ >@r\DoG?R1H@-Ik?RVn1Gc)3 h\D@B(_@5}_~#zpF4? CJr MG!w-_# @/E|5OF3W^"@[[[_ v jb!.̥$@7?FFEjXg?#& .ۼE\MP@К$_\?c/͕@ WvK>y_yp1h[K1< ^ ſ*4ab7#] 4lkg@[c&{5 @l{[Sn޼x ,Z/5  ?}a4ƟTwla E7\ 4l "/ y mZhW߈_MH @sUkŽEV1_$uM1@ $]̸04[ON6E>$'7Oxw;ɦK9jX^OBpW@߻@sF+6eN{;!w F`kko4{sK-GBpW!;f/*U@LKŘf^ؔ:Nel't%PU?ꦰ q٭z{?M?)'Kq.{@BJ fijx=Lwa>*s 5   P@mp!P$-wRt1hꗂ"@X'atPԙEHyo˫cK3}"pp߇9|vٞs9:yMN BЃQsX_\{%Z )Μ9c:=B;ӯ Enۋe @ (f|zJ]5_Z.Id!pn*sty;.Ti vvvӧ38hۜ]Cÿ9 @z8|iOYܾe>km@1@Z5Oc`금@4*]i| `z?c7ʞJ? vZ)w>>iICBܹz@cCj  e@Y\e]lsm(Q y0gzu[إ®Dž@@IleUN?aoNy@qKرW8C9gŜ/]L^  0L@1>˅Y|@1V T TTL@PI )3_ lmmNqÿ'=+@B@|䓟 ҇OǓMr8"7o|y?2‘g!>@Fpe@5Fb`@>u|NY I  x/+PErPi;6zD/ . @@5Op-Kgb<7 A7boWbJZfw7B@h[:u\y%bS^8 q~:AeG٧@,@@I/>ܿK'w_nH =E?7EQW# [kѶO_df 1@ @iʣ@²߰[@@r%;d5Z b)A(YtE}@@ @lIi? AQj9@c&c?k# &u?qSJ t:%OC'TDաx $s}LQD G12Q.>j  ຀Z_ifebwʌ@?7Gjw/{(2E?3r[  +?s!AFB$:D{f>w%O@@ o|fb,6eF>3RxΨ9*PzQ_c?_k|# 7+-f?ԓQB#aSۇKQtg7" [x/fw^$7-km45^wkw=*裏-9G@hvՍ&-M_lMVAZ̙3[Q E(3ߨ! @?ƇSf/&"9{(38" @_|e\kN0 @Dă,sNjjj5ut !  쾵m(ڤܽ hoYq' 詸:}ܷhm  VD%~PT@HǭIs^Z# %bK="t8ZS?vo6*& @pS@iӣW_'cSfPӧOG0_@SE?s8+R#uO5_xi[| % |E9('QŹ*8-IAcUd_G1W  %Yco)SiJB ={lmm8>mًO! @_|y_Oɚ!S/tbx$is\ЇcC-G@}k%«M@`4v$EHxz pl^!@"PJeqO6_?ʚ&jFカl;!M>]?Vjz6 D(bKOK@~!9~ t-"" :e]0 \vxI=n>]?^@@b}?qZ] HXvmqMt5V;^Id@bL3 Xlʌ# _Aĭ27Pk! Os $8ݿ2>Y/Z  %ߚc:ZŦ 0&k#n,J0N]=GR1,j/@F׬Ǟz2ʲShMFskӽj  7ދ)y Z/3ŒRr(@B D42xN;X/Ԛ\  $ݼ}Mx[kQD?}BO@`@Du,Ef:jCM=t|#j\ 睴z(^"aVc}?d5Z}D@G TlR0@F=bKjzh? pz,uEF Ӝؗc_T|.D@  4G& !̱gٿpʈKKKď3'묎KzĘn$@`ZEZOx @P @ЮI1&Zcuʌ@:[ ."~C@\P}/1:>ƤYi)3 D߱J1(PKJ| C@'4y_tK}zx[d})pO k_Zt&=Z %,x5'_1biqovC"l׸<}q=@]:PG% !bwSvu\yB"lojP/ljZ(.C@>_ъ`Jz <_nH 0[ErmK T @@/7? Z:ph[/^&2!0??_e˼w@KQ\@]:}}`+"hZVRZ|t=XOm d.qbL1}c)3p2SPerH -'A@aٿ*#R`ee%—뭞`[Uhz#  {IH 0aui `[y6  1.&p5 @d@5"W F) $p3H 0Ml6v]h(V :X/+W/E"/u`[^ 8'qh?T@qvm_jEh F) "@}H[[f:.@ͅL9@@ v?7bg 0Z Tyob?\?*@  ԩSd .zimKo\H`[ p@M`Q в?Ľ7PM> (A@?}B @f_mzD"P9L  @3W^?Ϊ-01TL{|,x@@ob#hҿx mVS7l39=  =侟}s!.hyRFkBo Iz5@@`&ɡ]$@`@6W9RG. }  @8-Ao6=Ù9%$Μ9R)ˬݹ=E(q x*p>im Rks2%'3G@@Yxŝ̐pVjMirrRI ZEKW@@ w?wf./eڶ92@J@@`f/!ੀ49:IϷ`F@@"(R\<Pu4m9sNrU P@(B"]C4l`Bhg[$A7oY.  @HǾDH ,/7$@(%"Mm[nmΧ$D@Ѓ l!+JvBMs$PKsDC@@a+p5\xUAn[zCJ>5U#2! g73I~8$[[<x1?)WoH>/.^UF@"|v뷑ڟj-d9E=={Kz {7!'Z) $'sn/aギe@ef7;~jH  df L!@sV^(I$ q Lz,΂{XjP ?0@BtlwIw3c  P[VW~,q[]r@MoBNv) )@S?g"2k#P|nE*D@b* c+>E uj(j"n*H   (ptw P|I_u{h;E@ (f#  @t'ҁT;% X@4[u{*t^Q@(L`KͅG@Kiȓ&n@BVE}@@wͲt`\Ԑl6s'x94 J  Y(,!$p[@]ϟ?v&ɝ+}&@U  >p(AM@KgиȗSֲ[)jyg) @z,RQa,8L(O`eeh?!^ # .ҁsAP‚YԸb7^4L޹s'p @@<X:0UΉxҘT@PIa@@X:: 0oDMT&z#  tuC`^ݶO*zc"^  t`ULPc)*#  `   KzSUdC4jE`"= n<'p^"2Qd:`%dvl  <7|:.IK ?äu޾ :2e ^q#ys]SV#)-D@?}~d\:)0}afbNr2d ZѬ- @5C@X:0 ՟IE$$A@``,jgfR(HW@@ < N)Qٶ?}Q裏LR j) ~ 0_SnO{,bW MVv<(wQP ! K&.CwsӀ?6pR4@@K]@gggC/8k۝W9 }  ۗ2 $n$xoG^aޗ8'py&{P+ŬhNh#! !0sUSf.8Rh?@{@Rh xE@P=k"@ MGhwтD`_   L:ey7ou'!zI1H   <71OB v3]>E`9@pDwt$'dM7ݘϗZ#y $󼆇nB@  q$,i;>=&ܣ`@o@@RxROVh#X? `@o@(Xu wrjڛ2. UqN@ nwb($#   P1;ޛf$?8(5ch2O  G@@ 'cO=isdiиO'}Pfmm-BSb@@@uC !hKKK,_~qM~4v~D@P7uW.f9qɸ1@0A#@@`MwN $G?"=Ga=E@&y.w3S`vv(@'б?d l -=6  @zrmf^?=#GF.x6{짛v 0/1  u1_]I NjtqA1y_"'Jb>裞Ox y ?gM7s9}jeGD#CT(FB@.4ɟc^QzgQH'~?)@dƀo@@@zN.qG ?&AȘ$-t؃@@x~{5 x;Y\g"0@g~~dV=G@ko1$>F`FaVWW'8Cԇ8 `_# @T71j'!@~&%0/ 5  .p3q;_/%@`"i}@w|@@ V=kf 韄 (pmeIc (p}> l\Ɖn pbEN p0#/Tnm鋍"/˵@@V3cDŽ _a%mii)Sr@ xȶ6~lW_A Fhأ X$жIGhI#+@@ou$[ms܎'![&=: @H2d14eD@ N$vvMGBwМz%-аGh6%Ncڵkcͮ  jڛN$p_Zv  "0F%$X  hr?Ms>d hUM H`ˈ?)e$0$  .~@B?LToD|%@@Z%}=@$h4*vk47M'-(sL* :X/tbuWwu'!@X ckz[csEz|$@VShbSy;![ @٣SA{濴,/--vm. "0sU]gFٝ}@ *a"Jբ^  [m3տ8w+ 4MWK>.ی6|l|vҞ$kSn@W_7.OBx+/cw@M@iG^an &ToXAO Xŗ;   @fZOiy?gʉF UYG(d "1@&~wwoBJG x$I# ^Av8IvNzvڃx ,IH ( lnnhuij *M(Mx3~AݻZ'  o| :5ύ$@ ֖xg[Ȩ~ #HN }o_>DQj=Fr%D6ƫfE 9 8qLw؇O@`|$@v`8DN}З@@ 5cvOBPFsvн<,2UC@<`/+鑗~Ȳ~ܯd4vн`e&8C@@ fMwʶ?zu|#Pv ЪZ#k(@e=ݩ_h^i^L" I*OB 0v|wF.>;`.,| }5 (K@A h4ʂ/|}| 0Ҙ?z@@`<&SUw?u'!.^vۣ$*mW&$! x;ý/6l2-uN(uc}s>C@iͳ>;Q A=NyG?4S<l9)/077gY`pU~~UۍMʥzx٥%b @$@M _NQ? I@4P`~c_@Y8O/^LeՑi@2x7yL!@P ǛAVX}B@ 4ߩ߼ݝO=H VzȽ'\XX$d@y.w3Ys  8 .oÑ/ P, X2@@rmf߁  A#A 0(9h|9zhN -cwyѫlu'! XC-nTxL@333^Ov"F@ po?/ޔ~h{-s?ռ3E&jZINZ:nPwLfi:'  #p'^ =E- 0=9=+ _fz;D@=w'{I\ k_:;!а)CPwu!! aO3+W >LMMM|NPpGL CJܽ{蕄 G?1KIl#j`9Ӑ_+5@G*Ӥ4! C2Ft $0}a9rZC`uuhHiO@]/ța# .t V) @H'=cO6_c* @n >^PI? 0`^ @B@w4ɟF3@F~:=ÿVp& l93 ,EB@ q^VzʭMn$@4&=o~,r CJ. &;e[:@ \>II ([e MUSP@fj[ۦ̞%@`"-{9H]e,3vKJż )a #l>/`@Mwf֡$ wP7n8R?muQߕwg̬V12" 0P &bNk/@l}Ym9gYVj4!@ p2  @O=,B\P u 1J`VT_U7  q h9}z@`e=R'%˛\*z "׺ @HV(N]ns4jN) )6 @WwyPW7ocퟄ P+Ai#he7 hU~. zll=7̩߼m毌ޓ@h4F[j(`͜ $n@@`t+v[%H n ,//3)1v*EШ]tbe~P~@NʭYxFc'@<qڲ_.n9g p  0X@=zuOwN|& tɖ(ȱ1w?욁~h_ep6N 1G^yT/; ' ;w|^Ѵ_.rƌ`fjqVh#! 1ZO_=H  h(@Z^T i  $$c/, @2@[EU3 ?")ЯUם_@lUJSX/ejvc hLu!! n4ύ$@Ξ=*hKvy#$͖yraDJ*%EY@ eb(;%e4r^sKd;M-nܸ]_z  ȏ#  "Ls@2 E%)gXiNtvw8@9@@pM 5[4EnΙN`~~>2ҡq  8-PKyULz^fgg@@@ hPqP=hӬ}3kW9@@@ 4̙31h[ ":bJww惋#  YLOOm7nt>j3e& |hsq9pL>s= f2$   P>k666<#LYy͈`5}VS   wrQWZ3I؍3lO&$@@@g=ܹsǨsd-o;2OMx"E$nOxIRt'$@@@gz #Kj?U.\˾QH hL-W   ೀz4M&{P#́4s;1!@z    0Kb\r_!@fU0@`kk8x   h⢧O=' 9G&h4fuu5@@@`М[օI;*V 9,fnn\5@@@hg%=o>iyаiy(xze@@@ 7{Uέf9q 4Y0SVN   D `zz(FIjc5z@@@"pNںʪ?c7ik4f%sI@@D ^jOë́V y&@O*"  @dl~7Yص׮ٍƬw'@5@@@ @dn춓+~n ϒ~i677гz#   `LdVl/t1G|W YH   O>ewҼΥ=A=VH[GO*,   <cf@$O iőm@@"l i;ʇVǸ!@O7\   hjT/F:g-g^[+z?_׿׿Ā~UE@@ Ji?!y~nSyLluW`uuD֝ g   0Pt{ !/Z8)`|OZ$  .w1|0Vø*un _۳zC_ uH @@A@Øb(mZةQwL_s7qc@IDAT  ]\>?j`fbn_53羀zܻwϼ g"  @7n܈z~}Ԃ@yhmUoHa hR@ !   h)ӧO 04@? ),-mɃ  #%҇#uwx(g{V% Z-sY @@pI… .e'ϼ*nM!)Pђ$@@@&5\ 355/ZI@@D@(i[vU΢z( 8&lJEq@@@7."63apX&0$  *"  k4;+s(@@N_d>,kSv=Gy j,7j,"  &,?}t l*hQ&ߵovӄvwwͯk&)*  LOO;w>,問m{P>!>[nw^x_B   P%#X @k<}3˧j!z%!  y D4 `s~ѓ&udDpvv֬G*@@@@HVZ.ۍ>҈41/@O@@(I?47n(]JZY=z?k6CB@@.A86`~^bI A}?lnn&?   ={hHrI-}<,2 )e\YYHvG@@F^,3 %@‚9aH@ @@@ _|1Ӹ~z 9 Ϧ}7s)PVKF)5  % LM(kPvg` t:KK" kJBG kjӅ@f/s|U ! 2?? =Bs ~<(\jCA:M+0=2 ףv  $gΜ1Vkd5V(  @$Ìq%|^Z'F,//-HB@`=kHYC޽k4 @ |ӧOK ޚtDؽfx?P@75 W֯-4 @sp)вNT@-9FK@8(௹dFM .3lT-Cp\z0S?(禽by jrz%!-_YYIݭSCn߾Po%JDjq3K= @CX.pd2vDC0ۃB!"U-k=3@o ~d !#aaa<) @`KUȵF/X@Mܗ:z}{y@H&BP/Vo&yjQkPD? ୀm&L$xEPacGb@n p)[NV ȪKO' @hz ׿ϟ/,VU`mm׬w WVoFy@ZM "#-!N $z"L2[8B칠+oI/x_y@>B@sssfyyh' zwT, 3@/d0r=qn3ttW{(oFB 3E֜H9 Z5AP uO*q9<.ML@$KЪY8 @ 4ÿKIp-O.@Ⱥ'ղ7 @ j5SuQZ$0SZN%oAW zs"L{Pݬ؍^ޥEY-:jmbX@Q\R@Wb:J;>Cp_`ccLçӺ< `G67$䀫^y΍D-k׮c,& ੀɀm1@H Kh{P\]Ib0& ீ k9%oݵ[|@֩{g}LOOR2#ϛw}&?B=X:$ +%Ìe]ݯ^3 B*|Y\dJ!\<+jWp]W [KG4Վ@*LRU B $%Yo`(s@-%0z$u^^(Z@7-@ԃq777A?>CP6zkaS$H$x-EnM$@ۧ5?;@#-z+I{3nH&?pvw"(ƁV\JЃ8VM(5a, @=}Yq_ۦސpEhthfh Я~P~pU@3'0mu!!@^L>@\=v7 &, &;,kj7MHBIz8Y-d R ahEHE^Ӄkl;vL$GB@`L(=i@hZ|DKv[4>DT@x֖YYmb|9@dO:,4^p]`nn\tu](@ ZjZL΍@,:F:$p>JzCBz]5@$@lR~Y+{O@FP3gF3]||W|H("D ,^ӧO&vJ9 F@_# w(>]0_ TU4<@]HI @^zHzPUM{Ŋ `Z|ұomVv'#\-F6Z@!@7F3?5nww7r~7}jj^  @lmQoH #@II @=i&;Fn߾m Zt@;M߶[b% G4DUE$Lx@ H*JzzKpJ}D@TerNqMN! *e v P4G@2<^2B`4_vfV^ńEs-M@j[ HJ\o4@CH-u1W@L+@k_'?l6fqi2^ Zʖ4@i7O+ R4\ = jg ? /r~כZ6z}]U@l ݉c+;E 4uk˄9G7ʊs4W]V!V=\ YoccyqWׯ_giW@ OO 4V hX@2_&$!{jO^L#;|mt@ zKw D  T@&0_@Lߛ$L #'A/}ΜݮgHPo"a3sK~ܨ=Vz MVzCB^wq:؉oH#C0ѿLSfR*S&Ӎ)PTPH 3@ U'LwM.˗(+DhFcIb HI]Nő+&3  $Ki"?BB`Pa$ Ϟ=kYRzb(@#P$P=D*I+?Dz,6CRqD'@l<@1 PUo@ $C| 0 __Ύ ?:1 =dwq& GVx纁C; !{VgWCR-)2 {!0P@H =諅_[[[&#Y Z< ]P|pUP(L@a\hD!-fis97'E|;ϟ19*ޚd,& Hz=3bTUjٿsN.W=,UX @|wWRv$P'΄@& `m Ȅ4$þI*`2UWk|!@Q }Q׋:f(@,w !0&Z\\$8,j9 &k[ץV/) 0P7{g'<'}gI}}П++U&A_krho O@b |/\PoͽHYs e ٳyK$'pDE_i8 @(]IK2 _ v).b_1 (95&bR&И Gk&ѻ-  PXL$@g%H 9V%M_&  3/BE\  dV7 rn_v{  @ќɲ\K   0"vݾ3 *A WaNY :YJXc+vv~{"  ܾ}svP@Lb:!b62 ;vΞ  @Z\@vvvxwbWx7  @5A93H}+ Cê=PB@T*fssrFH!<L!SVav;@@do@`|7+)V@_t~ 9GwߡܹHOޱ2@z?D@;TN# HLD`2u{dh@@ [֓!pnT]дP  8#TA x񢊷Kԕles*΂ d#8r,3mȦV4z%! ǹ3UAFN@K={ְԟUQ. dWWH  SIj9/2 vvt: Wλu,2^Zjl\W  fccTUS8]@v|7 .XPN d__ Pgޖ3"  LMMz>8bPOItlN)}ڰۭj7  ZﶷܜS"3 ʊOv&]?5R Ǔg@$@@9i.]x2faۋ#K 4ї;y镄 8' 0sUCpFIDI2r/9@"ϫ"-"  $3y+@BzW$^PO  -|NV BTzʟ; $gG@&_m$[@1GHP@')TBVU\  )j~V)a ࣀz)csH?|EDW\  4ٳyq> $ys[żgyb  L 4Y8|HU1W{vwI !!!@( -,,H ڒ (u^N=JB@P3g0.Z"s't<7@F!P;WC@j)<|0 $ߡJ'+z!弟^Υ*  0V X]]5z%!?O]eӶ=ұw)K{m)@B@??)H ྀf5_WpݞFЫQ|y  f@t?#@_CxTrzS[6+Qw'K@8Z@kkkfzzpM`fZ  0@R1/_6~ 0&7 8 ps?g*6; 0'[Bn@@`LjjVWW& $!@z=/,,&Ko[3~*n}ͬݶA@Hh2-ٱ796x8B=;d [An@@`u[.끆VVV7d;)Pb8UC@@ @2?Kޓ@`@kf ?)p~oT C@@ 5I& $!1CB` &ЗU t9@W@C4œ@z<x.&ppn L nΚ@^V8_eU6z*vW݋=@@3-sssYݑOWѬk$3vΠ= U݆_Y&  L8{!Y.;6 LxA戴 #  4 U;o[yߖQ9&p1 P … ^<!P&vZwK+<ҫuT w7r )jZG$\{w)_%X- &ib%   <1=Su_[[3OB -{îE`7l D'U+ "Ե?.$ Xk&aB~߰'w{@@ 4P  !isPzė [ Q  P@ z>ڟV2رP vRlڍQ@&Ѐ_|;D`q 4_G{Tʖ(%0R) d,@0 cЀNC@vQ⭏RD(z'$@@I0^X~?3J>ªOJ 9 h΀$ 9!;pZr}w2Bu{zNZd(  P0cހm8Z~X`5j *~ZrET  @~a 蕉̚P_%Hz@@R Z<e!߼y=g9OZ,!Ku{v$@@ P @=;wt[O ,>M`5N5[<a! (駟=Cƫ _zu  LJp=6͆u-s5,f#WC#%8\j8H)Hl:.a aSͼLOKdd\d56|5/ @ @vuv>?<%F.0KΓu]7Ymϓϒ @5j%Z)E!C8OC+]V @ @@?YM[Ms@[,gf]&Er @ UشLmjwϓ @'& @ۢ)ojkd @ 0\&Mv]жh-R] k/ @ @`_,qf19O  @@Wip @ @`W7V%_$m  @ @)>ZyJRF @}2:: >nO>Yu~6O @ @?OGp؁E.<) @ @`th"t@)#|ߏ @8@}9fŮ8egԿn @LK`6+-xWY~诮 @ 0=_8Ugm  @ @tQ+P.% @ @:<]^UWF @2mij+yn& / @*pקuI+A}?J5 @ @@OL:Oz 1fmB`J??E$@- Ue>Z G^`V @ 4Y2) @:qw++p ҋXu+ @4yUKwϧe%@,Sʯ#5#y]yxsFxuW2*Ĩ>69O  0v ?KW)Z @`Mzum>Ͳ/ I&Oh~"{x\"5_&z]쳢u @@שQu&~qYJD3*& P|"+xWz ХTtYuE{aEX5#W?.e;xC `&c!dyq;z+PW]uho ~Re u c2eIN%*lm$@@wZmo,Z)'0K:v4Y9A6nRdMh>O6)EO)P-9g7ZrOMJ=UNH^%N,ZƘNgcꐾ @I[giZ O -8@}jV'ӧT\_LN 0UZ&L 7 @,];uMlγX,i D[c2m[6!@`?&yl{/Pӟa slN 0#u[W7m=_:U|\%8@i  G4In&ބËxuO}Օ<)hGN߬oGq"MoJ9OK}֛iZ" Xmm4r#n&V5@dM}An7Y||^ZG {ª:_D4Y2AlbX4&z ZK- 0aޝP$6JրfJ_ON) ԏsMܿuy/{e&)~lnk@Z` 7x' @Q#|eBAWy,5!pA5UJIy}[m^dOWIAXKf3P >4iD@I`<|T`% eub9&E  @uyZLF  Pʻ9_&RLS&ySz,C"~ @ ܦ 5[:I`T5ૼ<8_g]_ϋqҍfMRR:QIǗ.E^:0Dj׾uW }XoM/UYgn^>Z'&z94{ <ϚuLTYXY?OYWl׭8@&m=^%4v( N@×?zf"LLdC&<6gYZXӑ:|=&"*\Nt$ @Mb*+Γ}_?^?~noƛ;5z?<_X鲞 @`˴.lqZhRNegqϢ=;?M&*AWfiX`ʭI Io~'@{{4'؜P^'@ cǗȳ?H?fJ֙c2ZG  @X @~ Ա_M:]kLoWT>@ IX9t#` p7Չ &o&@LloeI%` _DN @L<&u'`𿅥 _D<~6.``w3k @`W-L< zeNT~1 S$pV#@[ m1v(A஀}⮆ Im,C w`ĄNU$b'@ {i D`E `< @`-``qXbB&&uGLTb  0fe:YbGՎU3L@ 0 @6R"LGN TW-f DP3>t+P'nT)*6?pәvYj_GڗZ@'=oYקKc}jt.P5uUH\'[%@u/_`~QKPI Gau=X-'W @`u,H.fMlfE-9B/G']"@ ukFN&UձnEg-5M'ϧQ}@Ii>x @868J%@4PG> n[z$G3 CI3ӯz2cT:u?M&vư1lE} @ꜣ>{5k1vx5vNK[!shO:J}S" @j=N/g}mX5OY4 s~`vjɂu]!{ߪ@F|@T,]I\:s~/[Zr`\@(_$[!1 1~7u>>"POySp6ԟRx*@~l\j @`,M:/Ph@ }1= nY`~j@V;cq 0vy:XS") PMir##݈I8;*fy@$yW9 @`/#7IDATj zO`wɿɓ\_ @ U]|yR pI<vV%@S 2x˩1LyuL 0! ^{,PÀ7]\% p@ ^$}0w<)8@8NNjE @ SdWXdt$PsA46d9.GY^?[M @Wi»TCӶ>:A,pL]_$}kr`m 0Ugst};wB{^oo>~@ h&pڷg @@Ꜧ&%}Ϸ;v͓ ,wI2O^$ 0,4y8c>:[ @`$. nI @+pK5Q)ŜX?cAu.3/A 0٠)lT}$@X_'YwJ &*PW:逷i~  @`:tmrL5b{|"^'zÿJ  @`tkY׹<) p檀L۴Yr @:_y6Nﲯ_%kY2kNRof3  @`+,U4u.928i}{.pvTyH"YouرJM:s# @{ ?$|F@N=<fmx* tɁX|\Ub7IA8<De }seMҹrDgWF @ ,R50K }X1_%(m inw&@U&~40-<~`3Fr & 0MAջ ,H 0`x=nA7}(`C @[`m&0wWe۔r 00M @GEyn7y>+``N  @ 0OdM\&gI1-&]%I^'o(Lb3 @S"BOXl Ẁ}A`&FYu @HHք@MTa 4i*YuF oc=$@8,E$"DVif_o$LLr4 @)&*V_`*n^}AZ] @@7T3_g]-bG7ɻz,x@8^"@ Ё"uYW ̒ԣ @e K:s#Ub'@ Нb]v3AP׆zZ7_u{7P Ц 65E @{ ?y=Z^o;nRB~]&w*+u}A@ QҀ5IENDB`ic11PNG  IHDR szzsRGBDeXIfMM*i  bIDATX LUϽR / *DACrkEGl0#"Yժ5۠cKJ0l?"3!8?}|߽{A[sy9=01DH4 9`x438 %<`.u(,3P._Z3*;tΎXKpn ,7c Eeԁ4QTT$ErrVUv!G^RVU {퇞9`;p%$$PCCYv %/^Ryl!"O@n =| ~dVV\%r}D~3藺0y94ĸ2oVainкL%=hr߯vc0¡9l"H'8Μ9LKS%1rt*x8[m6o0>NuEd^ Q9ܹbbbx ,C`#ΦJjjjhrn%c%r9d;؜I @ (} Fn[7@pLDrT* tHUo!^466J/y6gO$]v}ϋ;0.#l 2F/ W*zwwjjx 0Jhlcd{~ҤaɒIt^yed%~W&J16L `,WidOߚE)^(skkkŜ93>!^D>T$"7R'7s_ީ9Y6Yn`DC(dBTBXUUU' uBvj;hI u:d?BF-slx "'w}NqSԼ+ 4jnn~Lg:cх ]t I""Dq1y;8~Q]]mv`>JaE@!|>qӆx<01COD\;$i#VQKK m8&h֭h6x>B&Ç{@$Ԩ粃,SF'\ήN cNr(@?ө._4 xٳgV oRVV&sN#[Vb0Dff/!gȈtRL9J]09 v!^~Y5JwwyB{%,`X,)pmWEٓ ˗ -"##C \bEWWrz< | +2Apgjj`,mc|> %1 ?a^?P  @:pTʗ>) qbvM^f>(FF} RAHﳠfMi<IENDB`info>bplist00 X$versionY$archiverT$topX$objects_NSKeyedArchiver Troot U$null WNS.keysZNS.objectsV$classTname_assetcatalog-referenceTicon  !"Z$classnameX$classes\NSDictionary!#XNSObject$)27ILQS[ahp{$jamulus-3.9.1+dfsg/src/res/HLEDGreenSrc.png0000644000175000017500000005255514340334543017423 0ustar vimervimerPNG  IHDRX,=͖sBIT|d pHYsS S MtEXtSoftwarewww.inkscape.org< IDATxw|w~l_$N*NHQPOwss\b_\ؿ8c';ۗSEU( m}%(3;S<Nbgww_0 X?A 4<%/(*EQ.ŒyL'~h-L:=> l[m&,pϱ{U' &!=m\,B Q?Vs?G $b9ce~vU} jhͳ C=lqD!$`G}t GQZn$88WE6pu< X.c{dvgK$!GȆ=PHr{L!+#d=B!EӅY-$`?~-F"bU;|tA*"y]G!*۷O@H?#i7TIM!ܤo'RHMxU.}.L%U'x *+q,B!D x} R.$`O֓!NЁz.I')V"B(<_;]7'|Rπ[.Bk_^I|?tAH"O>d ;dI-B**ٻ s0n"kzNE!(#7;]|D"jkk EݟF{.]*&`=3{ǀJn^draPU~j9@H$B$Cs+N{@E{UUdjjh4tqDp{ PU<*'T-°U4'/s=Fv855hT=H* U hhhb|{s RX-.4Mc||QO@"x$TP@ @CC2o}B,=~%N322 )rr{ Pe'ƒk}7]zz^ꨯڲ7}ݺֳ>Ib9FFFr}3`RO0MiFw}T#M)ζqW&B=PKa"ѫx+/={[ < tY aSSSNgJdZ`ZdZdI"BXe^eTi 4oߜ dSƩzx.1&`z2WSSS լ6PSgV'IIkVQ!DA!⫥%κFև7^_qk^$gvKr*zcOvjR?2j3%_Wx/׺Fުs( 444cgt]wOVYDXEQ e4LLL|c059EB_|~eBN/3Jb(u_Zpmobsš̜ `bbYmxƀtArq} s=WC1hٳgFK>X03T+JAXBT2csvFv 2Rn]w!\{qV188H&)lJfR/>I !ʗ='0'KJ6Wmǫ\TIhjj)q~]wv0R{ SF#rix ݗ6ͱa>eL.pnWR:AO՗3V<ˢ@zinn&Xއ]e@~;t: X=`?e2>}ѢGCX>Iϰ:T}ţx EB|A !7H"xsBhFJMRӤ2Ij"IeWLX],\ y+.[HD"CmV ;tѮ X?.PpQLb8qdI >IRqzDhiYJs7T7U~$a!*RL΍3gbn1&ƙ3{<:0MlO+#r}?ngӡ吝Κvy8]\MAbgϞepph#hJԇFis-jMtle37X52$o}';A K_U[W\.Z*>a/ِ劎ɮX?|x2>>NQ&d>9ɷؾʮq庫u56XBaT&3qh} ǃ;K{ۛ;r2kzikk;'Nc%FFq}C&^-W+}O!ąt]>zI2S>۪wrG>}]v}}=MMMnB_p^xK-DhǏN;ќ+u<+vq˖۸e^:!I)}W'0w 3=Xɧc%0a֬Y |wp4` [ܰ8'O#jd y=sƛen|+uz[/84]{8"{mۮs{쨾c@A֬Y։wqq Xz۸ nX0$3 Tqٽ>z@! fO%fmΦi e{~N~WU~oO9s'֟pd9Noo/M;3 f%FmҎw#ܾnWw:B⥞+acf[y1v\BUQyӧ y--_ߒs٥>( no<`@]IwlB"ȑ#>rI&jZ-nWb5Kd ݿ7w5=.z.WZJkkkQ1, o+NK^|E?D)NMرc=}yүxYmwS7cl\Ba vyg?w{;;Ƈx.jgx.p^iQJ͒ФQz{{mS0fD9~鼷xc}|_`}SweBQt]g7?Mj2m@SSS۱ݻK_|̂a5<`F~7,~ 躟~-eBzs>_眙~W~|477S_ﺡݻR$륗^"{dhdd' 2mx3"'R{ tw V#W} ו# !@i5yt~h/k9>m#;n[AQ/mMOOӃmM>ޱ;k7sj ڿBS}O~|+J=U<3tugYvZ^vmZ-`˗Y gffO WՏZZ߸ῄBB{+~l2CKh0 с1"R+ox1֫-EٸEhÇi$+io nz!~X\Kw5;#[TQ0k3ٴ ^n-Ɔ^~C2?,hYclj3 B[ɽ>~Bb;3;ȿy799~ 58V2!e={^~z(j:}X,mD9c~[=֯{B!D4?(^~+t.|-EQ Zyٳg΍?JQoppĉU(/h? A _E~0(DB!D>^?l۫n_@物'~5@V `dd.7j W^!uz{a</? f77&7o-} !N{U !K_gAi3vϞ=۵A+Unvv?8ﱮy6Tǿ߱}g^B!䃁w~{ Zo=_jE.RVss3kww]XN|ǖ Ns!t^H(LZn-u3 !ntd0voðsZ(ڵk n_߽{۱![ց>[ ?ff~ I21ɘ/i_]5Ba^~o3{m`4,>D֮][ڪLݻw/H,݂K/ P3ː &h9~n|zjK!6Yy{BYῨ6ô6֐2iE+,  6^ :p@?I 8rH^Pbs`z'o8B"gQ.-w;jⲪϙZ671`ݻlĎa*JqHye7Yv"(|rbsVq/__9 :0 4411AuuM-d.d#`8p >|0y;yS^q%w{]3Bas/p\ƗW-g!`㭷ޚsX(p;\(AD77o| ǗB!;=tOpvvV\nBᵹyrIfff},t+:0W_}yTUkH )^9%kwTj)O: jZ?x96֓s}u_dSpm7 VWW֖wml[̸xE Wy+}/3̒T¯;U2)reE*uX5/t˯Ocd}6'5*B<'Hm)sfr^5XR'w(rooԼdB!jvk7k:xgPVEoNcc9[n1lWVu=x9TGȤB!"mwwW\nH={\SuifggWFv,f]~}T7rEz '9 :65~Y)N35WJ*#GAbVH;#39M0DZG:XڬD"aN6>o?%Y|~-l4S]h`p<ٮW 2rZFrT*GGѨ.?UňD*H?Xe({Ub1ѨCļ3C0խQQ1$v^ g31Ƅ>J 8eY',}0 \7_!L(H Oi XdMzݲٲYiɀo80 aK< ƃgM^[/BQ$hnëxM7yRKNOZs 7\T;\ &i+PwK.B!Dqy=^[-_y5]czX %(m\\8:iۣxhtAjυeMNb%#k^fBs _e2Ǘ|n)( ߜګP=>\5XR%(krp.qGu}nZZ%3E뭷t4MLL\0NqC^K r97_!0]ab2 ]kjyEQHRyoֆnK`9ʝa$4`9 UdeH L?dzyzk|gK&2DrK,G_MMMYZ~8t ã[ T]r|L,>x]QU/ Es(%㖫TZ>`!>|BQAoreH҈3ӹ2kɤs^.XoV`H&''--%s;Գa_X`7_!%-7 Sz`q #̓fu20w[k_%B!(|FA`PcT~X Xa,jBys{&B!D MG1n&qxXߙKQݥ.M4EUՅeXr &X3LBBII1haT*EUUcXNRҬ4KX0H\Ja:8ny)5!#&#\" nDt:bHA *^ű8O !IL+2j _82.6xRlpX|6T䛯'_DL'j)KkdkQkK--Ɔi^Sv1EHMWMM}`iKwtwl:g_nvʴ7m,6>;W_!7^m C%d=Mu| #+B?WZh<1f*_΅ a|XDH4gP4~4M0 jxz>`+W&bitrp-zC!ʅd;al·ez.XUUKiV.B \hD`<>L} "d!_]&q2ciZ=M ˱5_eV*΋)65nm{BL.YB|SBWc42ssm C5{h(% =wΛLM ٶM!Li0zʶbnZy5^lvbfhPͣ%mn7sZwټU!{HNǮ1{`h,^UU]1].'ʁ~v4_GؾJ%+  s()jbbz( ̜ KK_bxn:7^rRr`]jiۇIH(154D X^4S?2E{N&Um !$o*:0CN7g">EQtGX"1\z@_ZE_Bl&5E\wh%EqG&,0W yԢ4;: W__ߖB䋐pӳ}EiuR1w۩>X 8w/;2!$# !ʃ|nP <))N)rGhdV~NV)TBQ}EMn&tNtOM)cWwwGn !Ks(!,KqVk*g9(&Bkm|>BKU%ptC9^jE\>u[L:QKJ }TQ9|BT UE=BtY}^d3'hjW]?B"$*JIF#w'MNvrwּ\/^&Bz4 !EEʵLj@˯Ys\>>X&4Λ7{u[KW!%VrvG'Sqm",!gcfHѽk͊>DCsa !lSW,!ȩIZ+s+ V˔\|֖7d,P8>}]Ko!*TQ?r|FZlv>XNm3J%ZZFOs|0;(BT P508>sO*Mͧ(J(1kr`^ݏS*9@_!p~\I;:?>e>G# Z\!V CB5*i}PiU++[Eqjz!;a632¾*#d.8 q3GIIBR5X \'Z U yuk}I3!Y` !Dޤ\@ea岁 2s5XVWwd4e4Ǧ~o,7B 1a<9xha~,h>XfOwbi=űOT 嫯nSKH18k_ WNPKR 'f]*BrwN.•((ϙjg`E15( /;{uMJO6b rTc"9Pc]-ʨg#*תm"Tp8L<_|DKQ< NGOY$d_7".M$8({8jzk[o X\/\8]͜;k(v j+ByDE tO$BahqS58{#3ĵUzOjB|ZX,cɝZ |W$9DX]]mip:ʃ,}1:k.)o%W\<O 3efVqu5XL:窪C,|BjF,\epIS NRk\h\-)lpb^`)0j ̓ಀs $43#vMɦT]e8>DP+>UB!D4Cc<9B\\1%FK 2z > XG(Aus .BDQe5✸#?ECH 6*(OsY&RcVfZ&,kjj>cL:j~‰*GF]oS8sj`3A/ C"  5oVl :S79> SSSC,3Nd z!o`OpR䠸N43lf0kXntx L X;wT> l+uIs aEo;Ub9&'I USh 8]$aFq+3SgIOglW*eny0\r4z/R>laVCC=\b1|rm 'Tj SoSB2W;ƘL뗝M .X/j;>;٪LP=W\D J/C\#Q!+w:NXEXRZi=݁x  z+ ::RkJR[[jB1qu:G! 9]U2VLe]*j9$ -N,].P4im(Oz]s!,XuDcckUBq)=A*S!쭮*nqPc(ZʗA4!0WLVτRE.{Lf:K[MorX٧*!"R :GBa;GVΗ5XB .n"KF>1ԥuZl,bʃa!_'tn@Va~( E z#%*o14hǑ*a\.䒑,8xIx<ꖜp9uLKZ(m$Ig((AB0op|(ƻ"T2z$'Ѝs V /e_A%Mcqzd `Pdu :Z(H)Rz EUzC=!^|Z)3NJJOb:u7]k λ `)2illrǪ_H\1URZDQ==A~O3*A%RTG4#CZO֒zJf!_^GM\P{+;v:KZ$  Hw\lalI [ QOU|Ö㗦D!JJ>oK/B~2,fIHkf> jvq͂Kv JS sTipWnaiEH y.p?~'O]* !Mc!iT=CH֟9W#miy[p ,~`2. XuD%`B32hZ8ŋWS|x^ŋG:\U7_!*M%}T @744CC3T4CE54ŁJjL~Zu^p8.V,EQ.JaRUUE]]AG a2d訆jd?dÖNjWGq\Òq00 }QΏMun-a("ȴ5X۷o?rH`&k֬9^k'ڙݴ( g**SP(.EonTP@jDY@CF7cu@G0aj>T-Α:ҹlxo\n/jq‰', :Z7d%h_OX&q1 X,SVN3Kc%WK຀hnnft4wܟ jaqEd_X%=>r\AhK4(,ֶlZl<&+"#"׺䶋[)?~S}`?n6*Nrfׇ}rv"!"\?ci]͛7ofA+5RߥLmT{{;O>? a2܆E#W-!Lf'eK* p `y,,EQfkl( 7n'r vo ^vU!L\( 6Zև BnXtx¦Kyĉ'\>KKK LMM]xα ݌\(b!D)(l^Zu͛MX `ͼ?6/4SKH "b !ɐMG|3_BYV6}މ'nR:uӧO^~Ki 5dJ3\7@^wXU7mt,7j*mmݺuKsFt]Prr+92B"29 %\| kN<#`m655D+u2 !IԒ K?@vV ,MR |?um@ss3T-Ct]=On%^ʀ!DْCԤ{nX[7n|W.4`^3ٳmmmn6l Xm q@4>ÜV:q\2!JU'/QN`T~(BKK >[E.p lyܶ5C5=b}ђPg8A 'Bvaivysy_[[Kmm%*\aÆڠ Ooغrq/U5yu#v+/Aa("&݄ȯ.%js g6lE;7XU\ pe_pg4rB8ArQq%9,Jձc&|Z~M{V|Bf(mvnS}ٳm&T-gf.Y l\.wׯk7ZpԩW[=z4-L_ڛ<.!(HC7yjllRZ "ò[*ٚ|jBc4~O`$ a|*x [ã? smmÕJ ԩSJv'M8|0sss=get:mio=aj 2L N;B|XJqv-gB1}>ny_n,ӧO? U!'IچW'}DDŽB)۵Lm`eWt8yϭ[bTlwW6FQzzz4Dr۬j _Ft~s .B0T\n@wTp'JZZZk׮=T X_h!L?~ "m=.BaM8QGeaB!:B_^v8Y~ri}}}LLX'W 3mgHvT;pDBmx3M ~aZwwp N|[Vx25ottSN-d8̛k2jma-Q.%&ڙ6֜N ]e6GgömxsEj';Fb|a2\v|Z ytcq !چNں]Oss[nv ࢀ044ljs,f-dhg,6A|ӰB7_!LK9mmx3cwWUUdS#dI 2U `hhhp7|a>79W&AK;%cbZuֳ69rD\Y`wggNd!,=~-%K<Ϲlh#Z]x2r]T5f\qu{:::^q 2` }{.d### ^ICiRkHuNyHBO`KTE`?Qippm8s׀8]|iN>䤹 TfYqIm3jb5)n#B,/nvW(9 De#~~L](˗ޝس| 6 \.Gow""-bY\\<o4kWRys c8HT...t* YDDD| i/WT*p4_m:{qq1ABJ% | <ڊHl]^\.4KTQTނg;LgDDLpg. ^uہoyYDDD< |)=h:M"켁fkHuqυgT>\mP*""Yӹ\9ABO+++!78"2$9R 2l68}Pm gp?mh8(Up?l6j:` ɶyW#""2Wo?f ֈض>\n8H?ޟl6e:L`m#׬d8Ql61&HTĶCW Ǒ)"r{_e21Pjznz,""2ܛd7$T&ZwMe㈈tXd26fZ`PVA7Od2L,êjwQm5ȔкzT=N˦L3,jo-Z1GDD<0P:0RZ6\[nN $""^]WL:cTJt)%^^dpxpln{0ȣ +J5&[HwIENDB`jamulus-3.9.1+dfsg/src/res/servertrayiconinactive.png0000644000175000017500000000241414340334543022045 0ustar vimervimerPNG  IHDRc pHYs.#.#x?vIDATxV]L\E>{  İHKE P@a+Ղ]Ac!5Hj}1X$PPix-ĀH}-aˮ߹]N9;s|sΜ;f6B:0  @&GK8)a(_]Ȏ"^v"Bt||<%''^ȧBB!EymgD9lMLLtp苋ihh D9L0?Ԑ2Ì5ҝ*%aσbbbh``>>9=X>yȀ^y(X1 nT*isZ*9>tmHPss3H,͑18*/~PJ$ǻͤى)66}Dft| '$$I+ p xyB"]Y1ivIbOH DGG<**寚H}iҼ[^KrR>L6٦3I(B|$몭r,oλ]'fiLd/x(s[HQ4)a;QHIڣ9N> I*j$Hk! ϓr^NNe݄JըgffXby;5omh*'ADÇ\wwwd;8OcDy<}'1cI|}}ma[R--sslQAAYk{ITXXx,d^o~>Tg㑿:::v_ IOJR p7GotAZ,}vv#kصu}||j63 X Wؖuz.y{{oi>233.I.G&W(**"\i-//v1,ކDTRR"!(("$W䠡j&ɾU?^d"W#kDDTTYYIvӛ<~Lox2Gئ5oa~$pDx`l|?@'L۷:{$kS p38!ļUIJafc +Ɯ'wd,?aJIENDB`jamulus-3.9.1+dfsg/src/res/jamulus-icon-2020.ai0000644000175000017500000065123314340334543020050 0ustar vimervimer%PDF-1.6 % 1 0 obj <>/OCGs[5 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream application/pdf icon Adobe Illustrator 24.2 (Macintosh) 2020-06-30T20:13:54+02:00 2020-06-30T20:13:54+02:00 2020-06-30T20:13:54+02:00 256 256 JPEG /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7 FXYq7FXYq7FXYq7FXYqsnuILeJpp5FiiTdpHIVR8ycIBOwRKQAs7Bierfmf5esyyWvO/lH++xxjr /rt/AHMqGimeezrsvamOPL1MS1D81PMM5ItEhs0/ZKr6j/SXqv8AwuZcNFAc93XZO1cp5VFIbrzT 5juj++1K4IPVVkZF/wCBXiMvjggOQDiS1WWXORS6WeaU1lkaQ+LEn9eWgANJkTzU8WKtDd3UJBhm eIjpwYr+o4DEHmyEyORTO084+aLUj0tSnIHQSN6o+6TllUtPA9HIhrMseUj97INO/NjWYaLfW0V0 g6stYn+8cl/4XKJ6GJ5GnMx9rTH1AH7GX6R+YvlrUCEeY2Ux/YuKKv0OCV+8jMPJpJx83Y4e0cU+ vCfNkysrKGUhlO4I3BGYzn23irsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdiriQoLM aAbknoBirB/Mn5nWFkWttJVby5GxnP8Acqfam7/Rt75m4dGZby2DqtT2pGO0PUfseb6rrmratN6t /cvMa1VCaIv+qg+EZsoYow5B0mXPPIbkbQGTaXYqmFnoGuXgBtbCeVT0dY24/wDBUpkJZYjmQ3Q0 +SXKJKaw/l15vkFfqIQHpzliH4cq5UdXj73IHZ2Y9PtCIP5Yeaqf3cJ/56jI/ncbP+S83l80NP8A l55uiFfqPMeKSRt+HKuSGrxnqwl2dmH8P3JRe6Lq9jX65ZTQAftPGwX6GpTLY5Iy5Fxp4Zw+oEIL JtTsVTjQ/Net6K4+p3BMFatbSfFEf9j2+YplWTBGfMOTg1eTF9J27uj03y1+YWk6uUt7illfGgEb n4HP+Q/8D+OazNpJQ3G4d7pu0IZNj6ZMqzFdg7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXY qhtR1Ky060ku72UQwRj4mPc9gB3J8MlCBkaDDJkjCPFI0HkXmzz3qGts1vBW202u0IPxSe8hH/Ee nzzb4NMIbncvOavXyy7DaP45sWzJdeitO0zUNSuBb2MD3Ex/ZQdB4seij3ORnMRFktmPFKZqIss9 0X8piQsusXNO5trfr8mkI/UPpzAya7+aHb4Oyesz8AzTTfLGgaaB9TsYkcf7tYc5P+DarZhzzTlz Ls8Wlxw+kBNMqch2KuxV2KuIBFD0xVJdU8m+W9SqbiyRZT/u6L929fElaV+muXQ1E48i4uXRYp8w wfXPypvoA0ukzfWoxv6EtFl+htlb8MzseuB+rZ1WfsqQ3gb+9g9za3NrO0FzE0MyGjxuCrD6DmaJ Aiw6qUTE0RRUsLFnPlD8xrmxKWWrs09l9lLg1aSMe/dl/EfhmFqNIJbx5u20faRh6Z7x7+56nBPD PCk0DrJFIOSSKQVIPcEZqyCNi7+MgRY5L8CXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYqhdT1Oz0y xlvbx/TgiFSe5PZVHcnJQgZGg15csYRMpcnivmnzTe6/e+rLWO1jJFtbA7KPE+LHuc3WDAMY83l9 VqpZpWeXQJJlzisx8pfl7easEvL/AJWunmjIOkko/wAmvRfc/RmJn1YhsNy7PSdnSyeqW0fveqab pWn6ZbC2sYFghHZRuT4sTux9zmrnMyNl3+LFGAqIoIrINjsVdirsVdirsVdirsVdiqWa55c0nWrf 0b6EMwH7uddpE/1W/gdstx5pQOzRn00MoqQeS+afJepaDIZD/pFgxpHdKOlegcfsnNrg1EZ+953V aKWI3zj3sdzIcJlXkrzrPoc4trkmTS5D8adTET+2n8RmLqNOJix9TsNFrTiNH6PuexQTwzwpPC4k ikUNG67gqRUEZqCKNF6WMgRY5L8CXYq7FXYq7FXYq7FXYq7FXYq7FXYq07pGjSOwVEBZmJoABuST iAgmni3nfzZJruoFISV063JFunTkehkYeJ7eAzdabBwDfm8xrtWcstvpHL9bGsyHBei+Q/IIkEeq 6xFWM0a1tHHXweQeHgM1+q1VemLutB2ffrmPcHpWa13jsVdirsVdirsVdirsVdirsVdirsVWTQQz xPDMiyRSAq8bCqkHsQcINbhEogii8j88+R30ZzfWIL6Y5oyndoWPY+KnsfoPvttNqePY/U85rtD4 Xqj9P3MPzLdazn8ufN5sbldIvX/0KdqW7t0jkY9P9Vj9x+nMLV6fiHEObtuzdZwHgl9J5eT1bNU9 A7FXYq7FXYq7FXYq7FXYq7FXYq7FWAfmh5mMEC6JavSWcB7xh1Ef7Kf7Lqfb55n6LDZ4i6ftTU0P DHXm8vzZuhZt+XflAalcfpS+SthbtSKNhtLIP+NV7+PTxzC1eo4Rwjm7Ts7R8Z45fSPtes5qnonY q7FXYq8+81/mXcWOoyWGlRRubdik1xKCwLj7SqoK9DtU5sMGjEhcnTavtMxlwwHJFeTPzCk1e9Gn ajEkV1ICYJYqhWKipUqSaGgr1yGo0nALHJs0XaJyS4ZDdm+YTtXYq7FXYq7FXYq7FXYqsnhinheG ZBJFIpWRGFQVOxBwg1uESiCKLxXzp5Wk0HUqRgtYXFWtZDvTxQnxXNzp8/HHzeX1ulOKW30nkx3M hwnsv5e+ZTq+k/V7h631kAkhJ3dP2H/gf7c0+rw8ErHIvTdn6nxIUfqiyrMV2DsVdirsVdirsVdi rsVWySRxIZJGCIu7OxAAHuThAtBIG5Y/qP5geVrElTdi5kH7FuPU/wCGHwf8Nl8NLkl0pw8naGGP W/cx67/N62BIs9Odx2aaQJ/wqh/15kR0B6lw59sD+GLzzUr+41C/nvbg1muHLt4CvQD2A2GbCERE UHTZMhnIyPMq+haPPq+q29hDsZW+N/5UG7N9AwZcghEkssGE5JiIe8WNlb2NnDaWy8IIFCRr7Dx9 z3zRSkZGy9bCAhERHIK+RZuxV2Kpb5k1ddJ0S6vj9uNKQg95G+FPxOWYcfHIBo1Obw8Zk8Ed2di7 kszElmO5JPU5vnkSbZJ+XenS3nmm2dNo7XlPK3gFFAPpYjMbVzqB83N7OxmWUeW72nNM9Q7FXYq7 FXYq7FXYq7FXYqlnmPQ4Na0maxloGYcoJD+xIPst/A+2W4chhK2jU4BlgYl4Rc201rcS206lJoWK SIeoZTQ5vIkEWHkpRMSQeYTPyprjaLrdveVPoE+ncqO8Tfa+77X0ZXnx8cSG/SZ/CyCXTq92VlZQ ymqsKgjoQc0T1obxV2KuxV2KuxVQvb6zsbdrm7mSCBPtSOaD5e59slGJkaDCc4xFyNBgOvfmuilo dFh59vrcwIH+xj6/8F92Z+LQ9ZOo1Ha3TGPiWB6nrerapJzv7qSc9QrH4B/qoKKPoGZ0McY8g6nL nnkPqNoHJtLsVdir1X8rNA+radJq0y0mvPggr1EKnr/smH4DNXrctnhHR6DsrT8MeM8z9zOswXbO xV2KuxV5n+bOs857bSIz8MQ9e4/1mqEH0LU/Tmy0OPYydF2tmsiA97zzNg6Z65+V+jfU9Ea+kWk1 +3JSeoiTZfvNT92anW5LlXc9H2Xh4cfEecvuZnmG7N2KuxV2KuxV2KuxV2KuxV2KvLfzW0MQX0Or RLSO6/dz06eqg+E/7JR+GbTQ5LHD3Og7VwVITHX72BZnOoe0fl1q51Dy1Cjms1kfq7/6qgFD/wAC QPozTavHwz970/Z2bjxDvjsyfMZz3Yq7FXYqxrzX5407QlMCUudRI+G3U7LXoZD2+XXMnBpjPfkH B1euji25y7nkus69qmsXJuL+YyEfYjGyIPBV7ZtceKMBQedzZ55Dcil+WNKO0vRNW1WX07C2ecg0 ZlFEX/Wc0UfSchPJGPMt2LBPIaiLZppf5SXTgPqd4sPcwwDm30u1AD9BzDnrx/CHZ4uyCfrNe5k9 l+XHlS2A5WzXLD9uZ2P4LxX8MxZavIetOdDs3DHpfvTi30HQ7f8AuNPtoz/MsSA/fSuVHLI8yXJj p8ceUR8kcAFAAFAOgGVtzsVdirsVU7i4it7eW4mbjFCjSSN4KoqThAs0xlIRBJ5B4Bq+pS6lqdzf y/buJC9PAfsr/sVoM3+OHDEB5DNkM5mR6u0fTZdT1S2sIvt3EgSvgvVm/wBitTgyT4YkrhxmcxEd Xv8AbwRW9vHbwrwihVUjUdlUUAzQk2bL2EYiIocgqYEuxV2KuxV2KuxV2KuxV2KuxVJfOWljUvLd 7ABWVE9aHx5x/EKfMCn05dp58MwXF1uLjxEPCs3jybOfyn1H0dZubFjRLqLko/y4jUf8KzZha6Fx B7nbdk5KmY94+56tmqegdirsVYR558+rpvPTdMYPfkETTDcQ17Dxf9WZum0vF6pcnVa7X8Hph9X3 fteUySSSyNJIxeRyWd2NSSdySTm1Ap58kk2VS1tbm7uEt7aNpp5DRI0FSTglIAWUwgZGhuXpHlv8 rYIglzrjerJ1Fmh+Af67D7XyG3zzXZtaTtF3em7LA3yfJntvbW9tCsNvEsMKCiRoAqgewGYBJJsu 3jERFDYKmBk7FXYq7FXYq7FXYqwz80dZ+p6IthG1Jr9qNQ7iJKFvvNB9+Zmix3K+51nambhx8I5y +55Hm2eceh/lNo3Oe51eRfhjH1e3J/mahc/QKD6c1+uybCLuuycO5mfcHpma13jsVULy/srKEzXk 8dvEP25GCj6K5KMTLYMJ5IxFyNMQ1f8ANTRrbkmnxPeyDo5/dxfeRyP/AAOZePQyPPZ1ubtWEfpH EwnV/P3mXUuSG5+qwH/dVv8AAKe7bufvzNx6WEelurzdoZZ9aHkh9C826zpN9HOtzJLByHr27sWV 177E7GnQ5LLgjMVTDBq545Xe3c9zRg6hl+ywBHyOaN6wFvFXYq7FXYq4gEUPTFXz7rNl9R1e9swK LBNJGv8AqqxC/hm/xy4ogvHZocMzHuKM8nXZtfNGmy1oDOsZPtL+7P8AxLIaiNwLbo58OWJ8/ve7 Zo3rHYqxHz95xGjW31Kzb/cncLUMKH0kO3M/5R/Z+/MvS6fjNn6XXa/WeEOGP1H7Hj7MzMWYlmY1 ZjuSTm3ebR2i6Lf6xfpZ2acpG3dz9lF7sx7AZDJkEBZbcGCWSXDF7N5Z8qaboNtwgX1LpxSe6YfE 3sP5V9s02bPLId+T02l0kcI2596dZS5TsVdirsVdirsVdirsVdirxHz1rP6V8x3Do3K3t/8AR4PD ihNT9LVObvTY+GAeW1+bxMp7hskCIzuqICzMQFUdSTsBl7hgW968vaVHo+h21kSAYY+U7125n4nN fCp+7NFlnxyJeu0+IY8Yj3Jdq/5g+WtO5ILj63OP91W/x7+77J+OWY9LOXSmjN2hih1s+TCdX/NP W7rklhGljEdg395LT/WYcR9C/Tmbj0URz3dXm7VyS+n0sRu728vJjNdzPPKeryMWP45lxiBsHXTn KRsm1DCwdiqceVNCfWtags6H0QfUuXH7Ma9fv6D55Vny8EbcnSYPFyCPTq93AAAAFANgBmietdir sVdirsVdirxP8w4BF5uvwOj+m4/2Uak/jXN1pDeMPLdoxrNL8dEitJjDdQzA0MTq9f8AVIOXyFin EgaIL6JznntEu8wa3b6LpU1/PvwHGKPu8h+yv+fbLMWMzlQaNRnGKBkXhN/fXN/eS3l0/OeZizt8 +w9h2zeRiIig8nkyGcjI8yu03TrvUr6KytE5zzGijsO5JPYAbnGcxEWU4sZnIRjzL2/y15cstC09 baABpWobi4pRpH8fYDsM0mbMZmy9VptNHFGhz6ptlTkOxV2KuxV2KuxV2KuxV2KpL5x1n9EeX7m5 VuM7j0bfx9STYEf6oq30Zdp8fHMBxdZm8PGT16PCs3jyaJ069exvYbyNEkkgbnGsgJXkPskgEdDv kZx4hTPHPgkJDoitV8ya5qpP167eVDv6QPGMf7BaLkYYYx5Bsy6nJk+opZljQ7FU10nyxrurEGys 3eM/7uYcI/8Ag2oD9GVZM0Icy5GLS5Mn0hB6jZGxvZrRpEleBuEjx1Kch9oAkCtDtk4S4hbXkhwy Me5DZJrex/lx5e/Rmii6mWl5f0kavVY/91r+PI/P2zUavLxSocg9L2bp+CFnnJlmYjsXYq7FXYq7 FXYq8d/M8Aea5Kd4Yq/dm40X92812p/ffAMSzKdc+j8517Z5B+ZXmA6jrJsYWraWBKbdGl/bP0fZ +/Nvo8XDG+peb7T1HHPhHKP3sPzLda9g/Lvyuul6aL+5T/T7xQ2/WOI7qvzPU/2ZqNXm4pUOQek7 O0vhx4j9UvuZfmI7J2KuxV2KuxV2KuxV2KuxV2KvLPzY1SSXU7fTRtFbR+q3u8n9FH45tNDComXe 6DtbLcxHuYHmc6h2KoizsL69l9GzgkuJf5I1LH6aYJSEdyWcMcpGoi2YaR+VWsXNH1GVLKM9UH72 T7geI/4LMPJrojlu7LD2VOX1HhZtpHkLy1pnFltvrM4/3dcUkNfZacB92YWTVTl1p2mHQYodLPmu 866+uiaFJJEQt1N+5tFHUMRuw/1Bv86Y6fFxy8k63UeFjsczsHiBJJqdyepzdPLMg8j+XzrOuRpI tbO2pNcmmxAPwp/sjt8q5j6nLwR8y5mh0/i5N/pHN7cAAKDpmlepdirsVdirsVdirsVeLfmNMJPN 96B0jESD6I1J/E5udIP3YeX7SN5j8PuY7BEZZ44h1kYKKe5pmSTQcOIs09380auNI0K7vgR6qJxg B7yP8KfcTXNFhx8cgHrNVm8PGZPBWZmYsxJYmpJ3JJzevJMj8h6ANX16MSrytLX99cA9DQ/Ch/1m /CuY+qy8EPMuboNP4mTfkNy9rzSvUOxV2KuxV2KuxV2KuxV2KuxV2KsF/MHyTfarcJqWmgSXCoI5 rckKWCn4WUmgrvvU5naXUiI4ZOp7Q0Msh4o82Jad+XHmi7kpJAtpGOskzAfcq8mP3Zlz1cB1t12P s3LI7ivezPSPys0S14vfyPfSjqp/dxf8Cp5H6WzDya2R5bOzw9lY4/V6mXWtnaWkQhtYUgiHRI1C r9wzDlIncuyhARFAUrYGTsVeKefPMP6Z1x/SblZWtYrbwND8b/7Ij7qZutLi4I+ZeX1+o8TJt9I5 MczIcF7b5G8vfobQ41lWl5c0lufEEj4U/wBiPxrml1OXjl5B6nQ6fwse/wBR5shzHc12KuxV2Kux V2KuxV4D5ivBea9qFyDVZJ5Ch/yQxC/gM32KNQA8nkNTPiySPmqeVrU3XmPTYeoNxGzD/JRuTfgu DPKoE+SdLHiyxHmzP83NTP8AoOmK229zKv3on/G2Yeghzk7PtfL9MPi83zYukexflnpIsvLq3LLS a/Yyse/AfCg+74vpzUazJxTruel7Mw8OK+smW5iOxdirsVdirsVdirsVdirsVdirsVdirsVdirsV dirFvzD8w/orRGghal5fViiod1Snxv8AdsPc5laTFxSvoHX9o6jw8dD6pPGc3DzLK/y68vfpTWhc TLWzsaSSA9Gf/da/eKn5Zi6vLwxocy7Ds7T+Jks/TF7JmnemdirsVdirsVdirsVSzzNqY0zQb29r R44yIv8AjI/wp/wxGW4YcUwGjVZeDGZPA83ryDNPyr08z+YXuyPgs4WIP+XJ8A/4XlmHrZ1Cu92n ZWO8nF/NCXfmBem6813pr8MJWFB4cFAP/DVyzSxrGGjtCfFmPlskNtA9xcxW8f8AeTOsafNjQfry 8mhbiRjZAHV9DWtvHbW0VvGKRwosaD/JUUH6s5+Rs29lGIiAB0VMDJ2KuxV2KuxV2KuxV2KuxV2K uxV2KuxV2KsAsPzOW31Cew1mKiwyvGt3CCdlYj40/iv3Zny0dgGLp8fadSMZjkeYZva6jY3dr9bt p0ltqVMqsCoAFTXwp3rmFKBBojd2sMkZCwdniXm7Xm1vW5roE/Vk/dWq9KRqdjT/ACvtZusGLgjX V5bWajxchPTok6I8jqiKWdyFVRuSTsAMuJcYC3uvlPQk0TRILSn79v3ly3jKwFf+B+yPlmjz5eOV vWaTB4WMR69U4ylyXYq7FXYq7FXYq7FXm/5s62D9W0eJun+kXIH0iNT+J+7NjocfOTpO1s/KA95e cZsXSPYPyw0k2fl76060lv3Mnv6a/Cg/WfpzUa3Jc67npOy8XDjvrJ5Vq05uNVvJzuZp5ZP+CcnN rjFRA8nn80rmT3kpl5Ithcea9NjIrxl9T/kUpk/41yvUmsZb9DHizRHn9z3LNG9W7FXYq7FXYq7F XYq7FXYq7FXYq7FXYq7FXYq+f9fUpruooeq3UwPzEjZv8X0D3PH6gfvJe8/eh7a+vLZZUt53iSdT HMqMQHUihDAdckYg82Ecko3R5qGFgzb8sPL313U21Sda21iR6VejTHcf8AN/nTMLW5eGPCOZdr2X p+KfGeUfves5qnoXYq7FXYq7FXYq7FUJqup22mafPfXJpFAvIjuT0Cj3Y7ZOEDI0GvLlGOJkejwX U9RuNS1Ce+uDWa4cu3gPBR7KNhm9hARAAeRy5DORkeZVtC0mbV9WtrCKo9ZvjcfsoN3b6FwZcghE llgwnJMRHV75BBFBBHBEoSKJQkaDoFUUA+7NCTZt6+MQBQfOhJJqeudC8Um3lK8Fn5l06cmiidUY +CyfAT9zZVnjcCHJ0k+HLE+b3jNE9a7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq8E8zqV8yaqD 1+tzn6DISM32H6B7g8jqh+9l/WP3pXljjuxVNNE8yaxosvOwnKIxq8LfFG3zU/rG+V5MMZ8w5GDU zxH0l6V5e/MvSNQ4w6gBYXR25MawsfZ/2f8AZffmty6OUdxuHd6ftOE9pek/YzEEEVHTMN2bsVdi rsVdirsVeQfmF5tGr3v1G0eunWrH4gdpZBsW/wBUdF+/NvpMHALPMvN9oavxJcMfpH2sPzLda9Y/ LLy2bGwbVblKXN4oEIPVYeoP+zO/ypmq1mbiPCOQeh7M03DHjPOX3M3zCdq+cWUqxUihBoR7jOie KcCQQQaEbgjFXv3l7U11TRbO+Bq00YMlO0g+Fx/wQOaHLDhkQ9fp8viYxLvTDK252KuxV2KuxV2K uxV2KuxV2KuxV2KuxV2KvCPN6svmjUwdj9Yc/QTUZvcH0D3PJawfvZe9J8tcZ2Kpjo2garrFx6Fh AZCPtyHZEHizdBleTLGAst2HTzyGoh6j5Z/LvStK4XF5S9vhvyYfukP+Qp7+5/DNZm1cpbDYO/03 Z0Me8vVJluYjsXYq7FXYq7FWC/mZ5omsbcaRa8kmuk5TzUIpESRxU+LU39sztHhEjxHo6ntPVGI4 BzP3PKs2jz6deT7DTL7zBbW+oyiO3JqFbpI4+zHXty/synUSlGBIcrR44zyASO33+T3UAAAAUA2A GaN6x2Kvn3W7c22s31uRT0riVB8g5Azf4zcQfJ47PHhnIeZQWTanof5U6+I5ptFmb4ZazWtf5gPj X6QK/Qc1+uxfxB3PZWoonGfeHpma13rsVdirsVdirsVdirsVdirsVdirsVdirsVeGedlK+a9SBFD 6tfoKgjN5pv7sPKa7++l70mjiklkWOJDJI5oiKCWJPYAZcTTigEmgz7y1+V083C51tjDFsVs0P7w /wCu37PyG/yzAza0DaLt9N2WTvk28npFlY2llbrbWkKwQJ9mNBQfP5++a6UjI2XdwhGIqIoK2RZu xV2KuxV2KuxVLfMHl+w1ywa0u1oRvDMPtxt4r/Ed8txZTA2GjUaeOWNF4r5g8v3+h37Wl2tQd4Zh 9mRfEfxHbNziyiYsPL6jTyxSopaCQajYjocsaXrf5e+cDqtt+jr166hbrVJGO8sY2r/rL3+/xzU6 vT8J4hyei7O1niDhl9Q+1meYbs3i/wCY9ibXzXctSiXKpOn+yXi3/DKc3OkleMeTzHaUOHMfPdjG ZLgKtrcz2tzFcwOUmhYPG47MpqMEogiiyjIxII5h7p5Y8w22u6VHdx0WYfBcw90kHX6D1GaPNiMJ U9ZpdQMsOIc+qbZU5DsVdirsVdirsVdirsVdirsVdirsVdiry/WvJWs635w1B40+r2XqJyu5B8P9 2v2B1c/Lb3zZ49TGGMd7oc2inlzyraPf8GbeXvKOj6HGPq0fqXJFHupKGQ+NP5R7DMLLnlPnydpp 9JDENufenWUuU7FXYq7FXYq7FXYq7FXYql2vaFY61p72d2vXeKUD4o3psy/575ZiymBsNGowRyx4 S8N1bS7vS9QmsbpaTQtQkdGHUMvsRvm8xzEhYeVzYjjkYnmFmnX9zp99De2zcZ4GDoe23UH2I2OM 4iQosceQwkJDmHvWj6pb6pplvfwf3c68uPdW6Mp91O2aLJAxkQXrsOUZICQ6sK/NvSy9rZ6mi/3L GCYj+V/iSvsCD9+ZugnuYur7XxWBPu2eY5snROxVN/LXmO80HUVuoPjib4biAmgdP4EdjlWbCJii 5Om1MsUrHxe26Vq1jqtkl5ZSCSJ+virU3Vh2IzSzxmJovU4ssckeKPJF5BsdirsVdirsVdirsVdi rsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirCPzQ8vrd6Wuqwr/AKTZbSkdWhY7/wDAk1+/ M3RZalw9C6rtTT8UOMc4/c8nzavPPSPyl1g/6XpEjbD/AEi3B+hZB/xE/fmu12PlJ3fZGbnA+9nO u6XHqukXVg9P36EIx7ON0b6GAzCxT4ZAu1z4hkgY97wGaGSGZ4ZVKSxsUdT1DKaEZvgb3eQkCDRW YodiqbeXfMuo6FeevaNyjanr27fYkA8fAjscqy4RMUXI0+plilY+T2Hy75q0rXYOdq/C4UVltXI9 Rf6j3GajLglA7vS6bVQyjbn3JxlLkuxV2KuxV2KuxV2KuxV2KuxV2KqF7fWdjbtcXkyQQr1dyAPk PE+2SjEyNBhPJGAuRoNafqFnqFnHeWcglt5RVHAI6Gh2NCN8ZwMTRXHkjOPFHkiMizdirsVdirsV dirsVdirsVdiqnc28Vzby28o5RTI0ci+KsKHCDRtjKIkCD1fPd7bNa3k9qxDNBI8TEdCUYr/AAzo ImwC8dOPDIjuTXyVfGy80afLWivKIX8KS/Bv/wAFXKtTG4FyNFk4csT5183ueaN6t5V+aPl02uoL q8C/6PdnjPToswHX/ZgffXNpostjhPR5/tTT8MuMcj97BcznUuxV2Kqtvc3FtMk9vI0U0ZqkiEqw PsRgIBFFlGRibHNn3l/81ZowkGtReqo2+txAB/8AZpsD9FPlmBl0I5xdvp+1SNsgvzZ/pmtaVqkX q2FylwvVgp+Jf9ZTRl+kZgTxyjzDuMWaGQXE2jcg2uxV2KuxV2KuxV2KqF7qFjYwme8nS3iH7cjB R8hXqclGJkaAYTyRgLkaYNr/AOattFyh0aH136fWpQVQf6qbMfppmdi0JO8nVajtUDaAvzeeanq+ panOZ7+4eeTtyOy17Ko2UfLNhDHGIoB02XNKZuRtl35YeZfql8dIuHpb3bVtyeizdKf7MbfOmYet w2OIcw7HsvU8MuA8jy971XNW9A7FXYq7FXYq7FXYq7FXYq7FUt8x6zHo+jXN89Oca0hU/tSNsg+/ r7Zbhx8cgGjU5hjgZPBHdnYuxqzEliepJzevIk2ut5jDcRTL9qJ1cfNTXARYpMTRBfRec89ohNV0 y11PT57G5FYZ14k9weoYe4O4ycJmJsNeXEMkTE8i8J1rSLvSNSmsLofvIj8Ljo6H7Lr7EZvMeQTj YeTz4TjkYlA5NpdirsVdiq+GaaGRZYXaORd1dCVYH2IxIvmkSINhkmnfmN5psgFa4W7jHRbheR/4 McX+85jT0mM9Kc7H2llj1v3sis/zeSgF5pxB7vDJX/hWA/4lmPLQdxc2HbH86Kaw/mr5ZcDmlzEe /KNT/wARZsqOhn5N47VxHvVx+ZnlIrU3EgP8piev4CmR/J5O5n/KeHv+xRl/NPyugqouJPZYwP8A iTLkhop+TE9q4h3pbd/m9aAEWmnSOezSuE/BQ/68sjoD1LRPtgfwxY/qP5neZrqqwvHZof8AfKVa n+s/L8KZkQ0cBz3cPJ2nlly9LGLq8u7uUzXUzzynq8jFz95zJjEDYODOcpGybUcLB2KrlZkYMpKs pqrDYgjuMUgvafJPmuLXdPCSsBqVuALmPpyHQSL7Hv4H6M02pwcB8np9Dqxljv8AUOf62SZjOc7F XYq7FXYq7FXYq7FXMyqpZiAoFSTsABirxvz95sGtX4t7Vq6dakiI/wC/H6GT5dl/tzcaXBwCzzLz PaGr8WVD6QxTMp17sVfR+c69s7FWPec/KcOv2H7uiahACbaU7A+KN7H8MyNPnOM+Tha3SDNH+kOT xa5tp7aeS3uEMc0TFJI26hh1GbkEEWHmJRMTR5qWFi7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXY qidO1G8068jvLOUxTxmqsPxBHcHwyM4CQotmPJKEuKJ3eveVPPmna0iW85W11LoYWNFkPjGT1/1e vzzU59KYbjcPR6TXxy7HaX45MozFc92KuxV2KuxV2KqN5eWtnbvc3UqwwRirSOaAYYxJNBjOYiLJ oPKvOn5gS6qHsNO5Q6d0kkOzzfP+Vfbv38M2un0vDvLm8/re0Dk9Mdo/ewvMx1bsVRmjWxutXsrY f7unjT6GcDIZDUSfJtwx4pgd5D6DzQPYuxV2KsX85eSbbXYjcQUh1ONaJJ0WQDosn8D2zK0+pMNj 9Lga3QjKLG0nj97ZXdjdSWt3E0M8Ro8bChH9QexzbxkJCw83OBiaIoqGFg7FXYq7FXYq7FXYq7FX Yq7FXYq7FXYq7FXYq2CQajrirKtD/MfX9NVYp2F9bLsEmJ5ge0g3++uYuTSQly2LsMHaWSGx9Q82 Z6d+aXly4AF0JbKTvzUyJX2ZKn/hcw56KY5bu0x9q4pc7incPm3yxMvJNUtgP8uRUP3OVyg4JjoX Kjq8R/iHzV38waCgq+pWqg9Kzxj9bYPCn3FkdRjH8UfmEvu/PnlO2B5agkhHRYg0hP0qCPxyyOly Ho0z1+GP8TGdW/NuIBk0qzLN2muDQf8AAKTX/gsyYaD+cXBy9rj+AfNgur67qurzerqFw0xH2E6I tf5VGwzOx4owGwdTmzzyG5G0vybS7FXYqy38s9NN35mjnK1iskaVj25EcFH3tX6MxdZOoV3ux7Mx cWW/5r2LNO9K7FXYq7FUo8xeV9L1239O6TjOgpDcpTmn9R7HLsWaUDs42p0sMoo8+95J5j8naxoc hM6etaVol3GCUPhy/lPsc2uHURny5vO6nRzxHfcd6RZe4jsVdirsVdirsVdirsVdirsVdirdDQNT Y7A9qj/bxS1ih2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV7F+WuhnTtBFzKvG4vyJWr1EY2jH3Et9Oa jWZOKddA9L2bg4MdnnL8BluYjsXYq7FXYq7FWnRHQo6hkYUZSKgg9iDigi2G69+WOj33KbTm+oXB 34KOUJP+r+z/ALHb2zMxa2Uee7rdR2XCe8fSfsYDq/kjzHpZZprUzQr/ALvg/eJTxNPiH0jM/HqY S5F0+bQ5cfMWPJIsvcRrFXYq7FXYq7FXYqm+k+VNf1Ug2lm5iP8Au9xwjp/rNQH6MqnnhHmXJxaT Jk+kM70L8qrKArNq831qQb/V4qrF9LbM34Zg5dcT9OztsHZURvM35J15r8pWup6D9Ts4khntQXsl QBVBpum1Nn/XvlGDOYzs9eblavSDJj4YiiOTxWSN45GjkUpIhKujChBGxBBzdAvLkVsVuKHYq7FX Yq7FXYq7FXYq7FXYq7FWR+SPLD65qq+qp+oWxD3Tdj/LH/sv1Zj6nNwR8y5uh0viz3+kc3tgAAAA oBsAM0r1LsVdirsVdirsVdirsVdiqX6j5d0PUSTe2UUznrIVAf8A4NaN+OWQyyjyLTk0+Of1AFj1 3+VnlqYkwtPbHsqOGX/hwx/HMiOtmOdFw59lYjysJZL+T8JP7rVGUeDwhv1OuWDXnucc9jjpL7P2 of8A5VBc/wDVzT/kUf8AmvJfnx3Mf5HP877FaL8n12Muqk+KpBT8S5/VgOv8mQ7H75fZ+1MrX8qP L0RBnmuLg9wWVFP0KtfxyuWumeVN0OycY5klPtP8p+XNPobWwiV16SOPUcf7J+RzHnnnLmXMx6TF DlEJtlTkOxV2KsC/MLyQ14H1fTY63Sit1AvWQAfbUfzDuO/z65+k1NemXJ1HaGh4vXDn1eXZs3QN Yq7FXYq7FXYq7FXYq7FXYqmWg6Df61fpaWiVrQyykfDGvdmP+dcry5RAWW/Bglllwxe3aJotlo2n R2NotETd3P2nc9Wb3OaXJkMzZepwYY448IR+VtzsVdirsVdirsVdirsVdirsVdirsVdirsVdirsV dirsVdirsVYZ5w/Ly31VnvtN42+oGrSIdo5T4n+Vvfv38czNPqzHaXJ1ms7OGT1R2l97yu/0+9sL lra9haCdOqOKfSOxHuM2kZiQsPP5McoGpCih8kwdirsVdirsVdirsVZH5Y8karrjrLxNtYV+K6cd R/xWv7X6sx82pjDzLm6XQzy78o9713RdE07RrJbSxj4IN3c7u7fzMe5zU5MhmbL0eHBHHGoo/K25 2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KoPVNH0zVIPQv7dJ4/wBnkPiU nurD4l+jJwySibBasuGGQVIWwTWPylNWk0i727QXH8JFH61+nM7Hrv5wdTm7I6wPzYnfeSvNFkT6 unyuo/bhHqinj8HL8cy46mB6uvyaLLHnE/DdJ5re4hPGaJ4m8HUqfxy0EHk4xiRzCnhYoy20bV7o 0trKeb/Ujdh+AyByRHMhtjhnLkCfgyHTfyz8zXZUzxpZRHq0rAtT2VOR++mUT1kBy3czF2Zllz9L NdD/AC10HTistyDf3C78pRSMH2jFR/wROYWTWTly2DtMHZuOG59R/HRloAAAAoBsAMxHYuxV2Kux V//Z proof:pdf uuid:65E6390686CF11DBA6E2D887CEACB407 xmp.did:0fd80808-9f7c-4f9d-a485-1f8bf7c87813 uuid:6bbc8c84-715f-d94e-a3ae-24a7383faa54 xmp.iid:4dd58ca3-0986-47ff-8023-cd572bb485c8 xmp.did:4dd58ca3-0986-47ff-8023-cd572bb485c8 uuid:65E6390686CF11DBA6E2D887CEACB407 default saved xmp.iid:4dd58ca3-0986-47ff-8023-cd572bb485c8 2020-06-30T20:11:53+02:00 Adobe Illustrator 24.2 (Macintosh) / saved xmp.iid:0fd80808-9f7c-4f9d-a485-1f8bf7c87813 2020-06-30T20:13:54+02:00 Adobe Illustrator 24.2 (Macintosh) / Web Document Adobe Illustrator 1 False False 1024.000000 1024.000000 Pixels Cyan Magenta Yellow Black Standard-Farbfeldgruppe 0 Weiß RGB PROCESS 255 255 255 Schwarz RGB PROCESS 0 0 0 RGB Rot RGB PROCESS 255 0 0 RGB Gelb RGB PROCESS 255 255 0 RGB Grün RGB PROCESS 0 255 0 RGB Cyan RGB PROCESS 0 255 255 RGB Blau RGB PROCESS 0 0 255 RGB Magenta RGB PROCESS 255 0 255 R=193 G=39 B=45 RGB PROCESS 193 39 45 R=237 G=28 B=36 RGB PROCESS 237 28 36 R=241 G=90 B=36 RGB PROCESS 241 90 36 R=247 G=147 B=30 RGB PROCESS 247 147 30 R=251 G=176 B=59 RGB PROCESS 251 176 59 R=252 G=238 B=33 RGB PROCESS 252 238 33 R=217 G=224 B=33 RGB PROCESS 217 224 33 R=140 G=198 B=63 RGB PROCESS 140 198 63 R=57 G=181 B=74 RGB PROCESS 57 181 74 R=0 G=146 B=69 RGB PROCESS 0 146 69 R=0 G=104 B=55 RGB PROCESS 0 104 55 R=34 G=181 B=115 RGB PROCESS 34 181 115 R=0 G=169 B=157 RGB PROCESS 0 169 157 R=41 G=171 B=226 RGB PROCESS 41 171 226 R=0 G=113 B=188 RGB PROCESS 0 113 188 R=46 G=49 B=146 RGB PROCESS 46 49 146 R=27 G=20 B=100 RGB PROCESS 27 20 100 R=102 G=45 B=145 RGB PROCESS 102 45 145 R=147 G=39 B=143 RGB PROCESS 147 39 143 R=158 G=0 B=93 RGB PROCESS 158 0 93 R=212 G=20 B=90 RGB PROCESS 212 20 90 R=237 G=30 B=121 RGB PROCESS 237 30 121 R=199 G=178 B=153 RGB PROCESS 199 178 153 R=153 G=134 B=117 RGB PROCESS 153 134 117 R=115 G=99 B=87 RGB PROCESS 115 99 87 R=83 G=71 B=65 RGB PROCESS 83 71 65 R=198 G=156 B=109 RGB PROCESS 198 156 109 R=166 G=124 B=82 RGB PROCESS 166 124 82 R=140 G=98 B=57 RGB PROCESS 140 98 57 R=117 G=76 B=36 RGB PROCESS 117 76 36 R=96 G=56 B=19 RGB PROCESS 96 56 19 R=66 G=33 B=11 RGB PROCESS 66 33 11 TEST PROCESS 100.000000 RGB 77 170 203 Graustufen 1 R=0 G=0 B=0 RGB PROCESS 0 0 0 R=26 G=26 B=26 RGB PROCESS 26 26 26 R=51 G=51 B=51 RGB PROCESS 51 51 51 R=77 G=77 B=77 RGB PROCESS 77 77 77 R=102 G=102 B=102 RGB PROCESS 102 102 102 R=128 G=128 B=128 RGB PROCESS 128 128 128 R=153 G=153 B=153 RGB PROCESS 153 153 153 R=179 G=179 B=179 RGB PROCESS 179 179 179 R=204 G=204 B=204 RGB PROCESS 204 204 204 R=230 G=230 B=230 RGB PROCESS 230 230 230 R=242 G=242 B=242 RGB PROCESS 242 242 242 Webfarben 1 R=63 G=169 B=245 RGB PROCESS 63 169 245 R=122 G=201 B=67 RGB PROCESS 122 201 67 R=255 G=147 B=30 RGB PROCESS 255 147 30 R=255 G=29 B=37 RGB PROCESS 255 29 37 R=255 G=123 B=172 RGB PROCESS 255 123 172 R=189 G=204 B=212 RGB PROCESS 189 204 212 Adobe PDF library 15.00 21.0.0 endstream endobj 3 0 obj <> endobj 7 0 obj <>/Resources<>/Properties<>>>/Thumb 11 0 R/TrimBox[0.0 0.0 1024.0 1024.0]/Type/Page>> endobj 8 0 obj <>stream Hln' S`0MFը>@fL_wT"%?}||^˧ג~5]߯T?n??Wɭx*yX~|^~/\ߓ#WaۥoG59SD^ekʥ>"]w7ut32S_koVWͫ߮H}qj}jjdK n#W⣡e wM;/,D9oގN"i^OWBXxcFkkZ-©:Z^UȄ2Vna=VP[<+:Sv3Fe]eI?Y[n6=-ʇ Zp~k+SD AZPT{62-aMlh‡$)ԥF.åf* *"C6j < 0 cS5C=Tu|M'CSR`ۮ *I(AQ9 VDz^>L:Ld {H.T# EdP{_]3OyXӅQ$xw, |݆\ 25gF]zg,w nzU]`D~Lv)p Qa&K^'VR..648UEAR@981; q HNWuKԐ5 ~[pl|<Ι8waO9Q*Ps0,#5-oe{}]M\qyРBH:;k_qLVZκmpzZjwr_l> endstream endobj 11 0 obj <>stream 8;Xu\=`WUX#Wu19(k:Ym^45j@8 /Y3$3=iZ(;Z!duM0pNWl;NI_HAl`7WN5`@Hl(5:3(<0h>T;\Bgs6reKH@ViiA3FWH bXlq?<'QXXn=:7$ak;W$X2MA)'5LR-'m)pV'D/lQC@(QXm<*agiY2a@mS]?Y[K4Y^s;que:8&W!qBC*!8Q=sk`d?X1m8%u@ZRCLl_ KrLD8%BlsJYh)SA:*TQ:.2cG6W\^-m?GVmp7IM4B#r0+kl@EieB@`o.iZfXcFZf8% \cP+)g-3[-\9GdMH-CGXEdn*;63 q1b+O/!#R6V5$C\V@9oo*nuH5>[T_c*nj++>rBI[VRG/NN(X@ZJ%m 4dN[h\,P'daV*_d_5M;9F,b(N@Tal`5t=Zn_EtML`"Mf:%ge@):WX\%qN[BbRcH-k %)tO@r>P_pmSmW~> endstream endobj 12 0 obj [/Indexed/DeviceRGB 255 13 0 R] endobj 13 0 obj <>stream 8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn 6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> endstream endobj 5 0 obj <> endobj 14 0 obj [/View/Design] endobj 15 0 obj <>>> endobj 10 0 obj <> endobj 9 0 obj <> endobj 16 0 obj <> endobj 17 0 obj <>stream %!PS-Adobe-3.0 %%Creator: Adobe Illustrator(R) 24.0 %%AI8_CreatorVersion: 24.2.1 %%For: (Martin Schilde) () %%Title: (icon.ai) %%CreationDate: 30.06.20 20:13 %%Canvassize: 16383 %%BoundingBox: 0 -1024 1024 0 %%HiResBoundingBox: 0 -1023.99999999999 1024 0 %%DocumentProcessColors: Cyan Magenta Yellow Black %AI5_FileFormat 14.0 %AI12_BuildNumber: 496 %AI3_ColorUsage: Color %AI7_ImageSettings: 0 %%RGBProcessColor: 0.303952783346176 0.669295310974121 0.797335088253021 (TEST) %%+ 0 0 0 ([Passermarken]) %AI3_Cropmarks: 0 -1024 1024 0 %AI3_TemplateBox: 206.5 -273.5 206.5 -273.5 %AI3_TileBox: 232.5 -892 791.5 -109 %AI3_DocumentPreview: None %AI5_ArtSize: 14400 14400 %AI5_RulerUnits: 6 %AI24_LargeCanvasScale: 1 %AI9_ColorModel: 1 %AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 1 %AI9_OpenToView: -382.195936561518 341.839054681202 0.525464021782669 1268 658 18 1 0 96 133 0 0 0 1 1 0 1 1 0 0 %AI5_OpenViewLayers: 7 %%PageOrigin:-194 -573 %AI7_GridSettings: 72 8 72 8 1 0 0.800000011920929 0.800000011920929 0.800000011920929 0.899999976158142 0.899999976158142 0.899999976158142 %AI9_Flatten: 1 %AI12_CMSettings: 00.MS %%EndComments endstream endobj 18 0 obj <>stream %AI24_ZStandard_Data(/XܝƳ 5qBzH^PVբAMxJ)ęV^%l o򫡓QT)gҧUQHRX M&}mFxŸ_‘g:lWD*>.u Tx.j}$p$bve}ld;}|~r;\w*-qH7exTwc,zku2oV͑vzfH:L6*h"ɘ#j,pHa*T̝I+j&Θ9t150 ŢơQff4 OaK@b0 ;4rqc1QvhpaK"cX|`,≆)qðB85r \ hHÈh h:4 y#hAH ~xV Ca {ZbY,@PV 944ܰX긣c8Q1jqK2axs<:;5 G&P l@l:)+-/1'"E6C{^_DF8"q@( DaL '(Q K\xH$E!EV+ EA1-n #_ bX4,7PC5X5`C6: ¡aSS)Paa*;# c|ƍrK$ cj*k00H ; Ţ(2hH4  lkkj7a bX(FbX _E-hY8( BP\ T(E)HA +C!H$00q KXDp@, D@D 17|qGslE*2|fb^ZVR:؀ T AsS\;כs-,ajPRT^/,**Wkʁ""ӐEYӆYL`:áaQD,a^VXbFXLB199sc P0#F':gٰ";ԡ mC""Z5֡A 1y\Q8q!QcFTp! PqA 2p!ǕȠB{hPH@A  Tx8@a,8NÃ6 4aB20 AP! TpXPB L 2TXq!B$P$s@\&d C 0@BTpXAC<#L`! Pat`B*LР 040!C $P pA 4@ TCC l`AA  3P@p+%aᧉ ɍ2D@ @`p` 6C l9a0h@G=d#£QSw2am!D&p *LȐ "lA*x`ƒ6PAD 6`C"PH$@C*3֟#%Li.ɼV/oi+2ŽMeNweG1]5}e/eKtsznḍxfg$Σu{Rk>dhQw=ӕ3S4wOHBKlF仫˩ǡt7g>ه$)˩gs2tYiI]蘷Hv4vGʘ×>kNҋb `?,IҭףnI=5g5bj˺]~r{*^ikp|lelFt+;Qz e!X1ʒtNUsO}Yij]kͩ#KTmFxg}lj4M迡:m}cC,ik*.Cr UwOjfʫKWkȭ&NxwWf9ƈn26yϷ7RDf֩d'6-+8)!Ppz=Y^O:{>+w<ݽQ|C*WEמIHlߨ-'6Rv'g NdY=BTI6k'j3ߩ.:j5^;)^ Z; ^S)|"wWvw̒ ၱ8Nh7yFv;V{N]^9=qo>$Q!|toʲ{P+2}Xy61N{Tc)<9ȳRM:y&#h2KW2i]{͌EO$ϸ*f$:NDjub6L<)iTdNu3ܸb&V4%b`oHm}d5RY rXbnV0n7\w7gV"ѭzӽ)"M-H^]]]Nղg YY9snW ai7rl&~Ke%tN,KIBY`k~J{O:HM;UQZ)w5!eI9=*\aѴ{#kK6/KcɽI>sT>t'u[':^+ ړYLIL< »q)O )ut[Rc%Ϫ?ɤ~}Ho 2qJ'JJ܇Wg8Iu<k'!̜koӒkv?ylǵ=cKkWީ%}L֑9&M9KHHþ LNU1{kKQsUV=ycӯ#(,ܫ' pO']naӿOޤ;DGlj-w:5ץb\+ fF'$DwTq6%崗Į_؜vt&G6,j iQ{V^({`?DݧNX?(B NZ/{2wzqNr3dhp$LJ3q)3[`{6L{vO<{/ٲ[Yx=6fv+=Iǝk$dޏ,[lI&"KSJakg twN:v?D.DDhc3-{x.EBWԏ;)uG.z$lDTgZիa3&fǝ߫^~G;Y2V{c* GeZ6#&u8>%tśR&}ͬd{i^ ^xH֤l5Z냦eo]L9&É {rvw)nlЮr.o +Ǭ2i,J%P>WQIZݩ{zt.y!"݋IB39~RwTv:-Ks $0y$q8#뮩'KSJ)QX-#*3I:tv%G>bt$I1Ē)V'y{/S]{Htrdc(|4S :٤[/O7$J PqBҤG֩^z9b=3=%w>Mc,C2reݔu,Ur6z7:oKY3ϒIJiN5 K3c'i/ݩe“ԓ\(隩 kx~ʆ =SҧdV}j&&V5û}6I貰h&K%C&F/IRTҝIG9,C'I}BmH'+UMVQDBsSbnO0fդrzq3g4HJUM']I {2-V `')hl*;n})p)ee %Dlսl)S-R}؍fw-G=dEht%2֩U6E2'ȈEd|=2tT:Lw7wYlJGW4 $VYj2Wřt/#<|2it޽H|TeFWѐٱKqU˓rџsڒJNq1+IcK҉ylkaw"D,*|ќ\eRwgFK*JՁXXQy%k4ug-Iqh4VG:91CMIN3>(4I)yK!jzj]먐oty9F]=?voZ%XGԺј8:˗Gs2ցU4{J[WHSF&iyc%Ji<;]cdGoǹ伥ٔMVNǗv&/M0U&i&Ҳܔ4Մh%u5MU|{Mn #:mJ{IQ 4a/{? {zNJI^i"4n=bGs%^6KniJ{%uXRHIVGn0>#v'9+^ϊQVtR,ݕQ0Q%e>4 %Ju{M^ZG >F$O9n=dR<>f%e397;^fʡAj]j߁|h':/h!%MWxB4A<1;*i#oΌ7bfě1f~\+zH>#9X)Uj?X9I:Ow>1QX5i} %M5CqjK}J(7s'>Phoe2Si?פL#_hO1Ŗo Oă+R(8w5Su&ÞԚjxw3I4FsY?:VyCsoY(j/>H<^QL$Gef1᧬$ 8E  T ƒ Ř Ag\Dbt9pWɺY+FK_7{,u'Q$\#º3n,9%<~}H'S[I\Q ;r Ze(is9Pfq2wLe,/KX#ձvy3x×drYL&F˲3KTA^c?{LJFcvSiO7g 1g=!&M2Z H"KjJmitTv![~˛ӐٿOXi{J ZGu&qJ eU%MyXYACě#ܳ|I6shXvx>?˓;׳D詟ZCJU]/Z2ӳlIU6u55ͫc:Wf8IesWO?E'iV2^_xkvHEwP팮J"K;jW>{;6gӹq2jHy՜{5giȏs>tT6{gD)Y껬i<Oۈi/ ?fԝJ#+(#Oeg6\n,3˰4Ycռ~|9:~!GK*5ͦ&ޥ\|ۤj4E:ܝ=mL߮N-U|J)D{j qyixΎ}WvԦft^w{XY%Hz49 [?<<iޮ2kIG{"t!4h:tri/E(Lɤe3T$Ice&Ό#vMNhÎNM x=8sv%YX!'UnI]/Br]Ulr/h|!؁GsG+*:TH(Ĩ>J;2kF@ޮBvGJ&D UV=,sH|t&F7Xw92w$Z'厶)vkE"UZS6xc dW۫ʾ+thZO|&itSZZ/J*Uu:Rh4eTBֵIIeS|R YDɩcLnW&&2JV+zVLjSIlOI -+*UʦF4]|'\wiƐn%u* k^76Ye{'t"<2-yDRcrBW(:7h>eIK3ȹ#A5)c;u>Ju5IG}ԋdaHE9:"bqiSU:INN5$"n0Z[VD#9;ScAšd\HDad+CGT̐MaY7UR%sLRFjqBת[vYсfS)ykoBi* ER5&T}qMf%tV+"$˴;zIF5QDB?<݄:x%D.sO892aEy2He29sTL:giY݈.?A/582;.u/\<2;fGtT>Z]e?{ eV?czaYVC[򎣔6kr: +dvJ8ūnw>o4;Z8sV:YliCDUt]|PhD)+-фxO2ʼ݊N{FR\j8XGWšO8t+#T*}#Ω(-<|ChXZY6gf<挌DH|.Z˗KfNF7« iFO1zq.f>RLF"eS+W.K+-eYɮGf3lҴz2jwE7IEL?^Gv`x`O+yTGzݤG0Ų^5_=)9߂&S4}JPS]竘OyuU/Mx 힘:n񝼦HiJUC<bs0P›$za`{wf!m6t⡛{J(;}`՜Ўsh.1]]rWsJҺ:ɧThl;LKKXSU[3.R Ō7~~),wbdY4_e:DC8IUvw,0Ɛ ?o$woI"͆6 ĕiC Iʸ vD]7a.Me9,հhB}X^//b7 ,7'ۍ`pv!VF<2NHv&vB0*S)ڦ2()kq52uKIk9u:ՔlM+ ,..:D"(*l?6$m'dPk EHVFqPD/%܊[]@jN*fT@] Ӻ72b`?Nq$ŲMM1L.|8EXֿG ́D l506~Y(S B>GD6Wd;,! dY6}1'WKBր ?#[W ^**.(P N^AbEm )e5R[|t4xX6P-]e!a%ZT_`4Tt%hӜGM >Ca9 %GœObPz5Vvo]1;^6x ?H&?$Qg$D%^O#G!B7T TpC24Ⱥ wVY19V7POB!Cß9Wcc(bo5gI|GƏ69ܲ ?L.PAV[] 3 Hɍ&NtK~KRTwQG屛kοrI+u 3Κ)bޯfbobCdc b&T֋?/NJJ= xsف]0CGŠHozZI)fIC3AIAb 2zױ4 BӒmtNH',IʉzB!D?fJH *a-&|Vw/Y q?v V SzLg#y["ppS8>}ΆO. @GkB?8p n,{> jGF~Z(qD'H$-T2^'; ~6#1LjP{Ge+M`,? 1Mh~S~G T!:3%%LBi:|.γEp'3 L~/ \n/$< 2{򐩽14QL{^͉1G6QB0smȣetB)*S&q"pn,Q$ +<?p6-% W'n"}InK6E0uk &]]RAa!WӬ!X{R+*~B8#D4kқha"{Q0 G_54+2H*Шy}c};qȤh\cc%BBB+$wѯ/J xo񐬍Oj׀W%RfiFMӸh! XjJC:o|C"䏌ٯa`,cwS K$ * 2)Ee0(L6h)ekDd6|K8='ܲ@i跠487[tuJ!~O^&z?' KRJѼ9~oӭ~om†``HMZ*p&B:f'[2.X+cf4/abzB*dSmR@c5+D9 iAJA}t<>idi;9/Ψ-7tT}Jˆ>[6Tr`1oA\K/h9@'&d|2Š̑GOXCsnU12ر,(A@=j [3$]O#ͅЈfZ5W}WNz>MbWuWug6~l^qٙkT(8e8E\DL-j[Q߇hGIBY>%kxTADA rK{]0%܆ϨXkr3YgmlB9PE3䕇D"1bgO]L/3ҤM3O@s҃)"JI]̞>_VzDbl0\zrqGYIUl"`)))0 It0sZ| ȭ_.Z x*^yx;b2a=WӆdX$9y.O.OUp|$ː. ?(&bQR{+C MIJas!nq]Kr*P /lA},[6 :dFzS*\r tY+W E[Da$-`$UHjᷭ( dR-3K7m9\i7M68N}-y6 Ӳdd#GRXC k8=<9 }!pQ4ɏa¼^p&`vLڋt/"Dbfȴv Ev*@`Uax!r>\5xpz/Ne `gdA~=PEK]qZ^&/,e2LC2?cgC+yK*1 ~G|0"$tnvw{$W〄cޯݢ,VUrA4$RZ@U!U}ڽ5VIHd%xTׅ|Ď팡yÒxw\6ھkz@`{ԝH+GeQ>PO@x_vJhTcϕqj hHDŎ3--C\4hp(@a# R}eô#!&ZXoNVMw||3j oP6kbNz="{s?~eݘ(#wH6YQC)77>ɹǷiȷ sLTR.^ isCliK߰.aࡗ\ eUUpl6&>v ;~ q[s` E%d^MBZ>y. l ;M8sSJ[2aSs0oB=-9+NbVgD! iqjb-ﮦ2NYA,@ A2)C sGZ#Pp;|uox2Sb:DZ6UgUklT-޽k $ڣw&!PNpkT/59fP|MWf:zdvD!F1Șx2`w3h\Q:0=܊2Zx=;@׻ͪ^[bӑ} +Dy(B|]Qz M,٩Wj^QtնNxM'GP;J '1Wќ h`(Cfo;5tW:)7mͭ%$ ,{w/A*q {EmA5BdN2i1[}΀dc v'C}h |7.BU8oWQSPJ@ZiGupkr®u7WMlv0vDP\A*_0@yV.>ǮHI57)'k)n=>{}9@>#J]@F=%cB6AAx*swjxy>8^Y_0@o֠bJ ?i}`Zp 1P0Ә-@KOU)_F5ɠV%GvM6撨m'A?m ɱc}&}b*ejFllܺ2l|ԲfY{>T'4rN%upd@d~:v;*, =SӣvSJ>Բ@he grLi⭟HeVASc#hMhG!!oQv۱z,{&T4p#X2sxl"dG@aל ^\r=>[`[9ӟD"W2rhAvоDSMnշO6\%ULUSVuo ·4"L戈 ,ZF1m jT|#ΒV/ցsj@t#(Ⱥ =zdd5>(-=lybHbcN$E neΛ>8ⶇX7W ܎A!"}`V2y;'B׋UXq[Rןw~>O|3st 5hO+"փWgKThMR݂ )gLok AMuZ+6EY쬃q|׻lp,oLzx0~'N+&ˠ[܌ ǁ &і8, M0Ɋ:~莅^%, cpu$^L&:@K˸1n9G{喩 Clh$fPNBU<(WS𧌩OhR8M$)``w}3+ sX\pl=kOŐټ5›Pxli?*-;DeH@ ˆ5LscfQَmKj6"qѮjh7tΏDpt!}H#rc3 $Ǹb( 1ߛ]7_k }1GQUB"?Hg"C|&IUaGp bsHUNJ z$r2?eaN74U zuHx1'P[Q"sc}cC>ⵗ<9L49!WHcʾSi %*G%ofy 6*H.g>W'mR5r̆r Ǖ4[tgUG_y`Zov9ERalbz{EŠrx⬳f-8ZZ[TK] l ݒF[҃;`BoK8EK_, GEy$UO5C XHz\ V1̢1ZV0x"ƕcq:dK =C0r0b#R+s~KPW2,+0$ez9f`ҍ'|f EÙ:)gpIj 3E1fhj"w( -XL .N3 #LTjrjb@f[3i ?PrCVfVȍ2ëfz|Z}~8=YN@.x5GL-I*ᔠeuSp[z w+ gMjT1Q[Gܮ.j*X 3z7"GSHKD3 ),P6㵓i Ƙ Ґd?t][DG`\zE1Zak^ТڐnE^#ґ4;z]^X=MhYQDLłwWk?gO1x#{FFb9<0-tQY8'uKh5ep<"yb:@QBg:mMjn D fiW:\ p3q;do cA%C-#d#?a.%f _V:DC K1AwtD yE'@AGjNƨʥ0 +JpmƁAi}Ĩ`15T]Y԰ZQ-`+J^ k> 8G+viQG`fY㶒ϓx?Q"c@m )F{.Bls2,e/vH@1#}!zEB8#} ́@]`p ;L$,uњX Itf蠉S|C`-u@K TxdȮP YTnyw?B_:'4qUr  7NAStMfp);Tpy *6HJBpj%̖pLؘ.nv@>PGH'ßx\x?LKfڄyPg;y|̟e?}|:((cGp6 Y>Og~U~=n ǜ yhE+!㣔7=Te>%74 TA\PvSaz0Q702Ps Yaв/ ; [f. `kuJ91CBhj@Wa8% N*zӑj]EOHhjԄ]|6wlA' v\s PrzNK$xa /?|um4Ε`w:7L*lNx$8Nw4%N5%@NvKv:$uQtŨ6V`5i7܍ZM nP: *`e?."1U|QZdʤPH(4KcDJŜш$w*r 1Ilxݸզ1\H壊AV}&8]l}]|Z>jZuiW{2@x[W?MC,J7: ]Ӗ6(R q? \G|MYR`3^iO\[uְJQЂR&v4 cOFO29C`MesԔPg `*s)1[H-0B`@' ^ bT-Yk"sMȲ&v}X.*W@k nLg`k5Klm 793ɧPD Rg?HHMv> ыYvdJ,ɛWПeqꯁ"&^ {BR; wԗu!{a4.VզU\Ю=8 8|)=~Ba`.dSrrX=QG:2 ӡ.&2FjtJJ:QMiS`~Vp;H]B= &k2 d+`"3;ʏtj ײ+9 ;ZnzcAꮇ6P܏ʽi##jl 'ܟf[f()X&4pzcYoUӋKf+j?L4xzoP1 lzikm1(1{4bfKLE *q?:@w'?k@p5]6"KCV:P΃{r@kl:ٝ$x<[ UdVpst΁4O.G_E!$bq*zOi>HBWIM=grY `Sd  8Y׭sɴy1]|*j&vOaڅeio!y2.7 U)\_KUŬ Qx>iw$faBUk^Ѕ #O;l'T4JK 93un-$f\Q(XqSR.єU1J2HT'/"i=mo֢I +g^r&zV 49&q谚71 c8 TSB Y2r KX/*)FXx@ո[cH9v'MBo&@:AЌ h)EKǀRn^ٞ^') ^6ta1ii'weDJ8jI]X][ەܭ:YDG> ~H`鶤>k,": 3 Ej&plZH_85vkˈvuh Zñz@f`*z*p\yG-p?(gFpAkźZ )lB RNtZ/FZ^ض>[uַpx~ܕ17ЕS,K.nBٿC tlUGAT \TvSڤoѮNn`z'lu.cvMhǞ."W90ׁ׾iua_5 t7W a,oF!]:I͵zc-^ϤW$u<ϽW,dgl37#F}C94̕vlw]/QygN"VH53n2@'H[38,\JPHI'R&+NlD(fA^ni#jiu!XP| [15eG .jՐ7q3]9iq{=q#Wj_j魆o*0?jOY /_R ^F'(Sy7ז=M_41- S`@8YJ [Q>K)KJ-ql$x^ ғñCP#G?Om> Pn֛ݍu2G'6,#FW}Y %NQ@3a[0NҫL paYE/>ȗ,uptZ%L ɭ7ͣ❤fӎ"?ˎv\ub|C{Bdj[ y5϶1dbt#iS#|'ݗ L\[պkq]+@+:p!xtcM/⅑6U?}0hs5EU}_Q`U^%8{|}+JRRfֳnn1PX]Ze,SGpYsGѸ^ vIW`|$ KДI ":n& TNVUCT7%3c;)h/6 &4lPtrP9u)|п2 (ܕ**4l^L C.lՕ xP5$ o146ϥKm;3 f/DQa[(^g0:Ի<ӫeZ2fc9-`.}Td%צy gxkq4C_ёpF@eEU,үC~| RH$L$SlDp!g<a-;Zْ1bE_On2XFL$b%΢p 6D+)0fZ)8ڲÎ]F,)OJhl=srIA^c<1lm~4u_.O.Pq⿴m۽/=t؋s{͍_p A}W8 54H㲔D#} GcGpTI9e#xہ7*'S,U~Z6: Cac0jCMH~D]f _aZ cEs]Ajd۾n[1(y֥HlخIK]Hi] |md(T ^$L{_ JXpܛԞ$H9\PI@GWݢzÄg0ܮ:U?Qr'PXN&ZmŸ婏 }ßeioj$\K(3"J 4`Wnu 6!yUϚ?^) cY>GM_)h?HyJaQBevA.m.+O_I ԌreFWe"Va" T+DZ| u`D&S:>47>1<8DZ *CIh1g %QƃUYb$="Y.yܚWmUPly<~4nv d`tl;,y~'6zmcCڰ۸DV֮HG$q \Zho{f6ݫʯ"!(=?Ջꕵx RfTT^Np؎OᎧtǶVt\%/91@k|kt|U@S?ErPX('P шeB8:1ɒ|7RO k*7R=F |FX8jr.*H[ȎDTn]A}Lϫ8~m|P P|Hq]HH+pP=Kģ|X>NhJ(^5 up&ʹҦQ%6\0 P %i.^$={e]K 7t1O6Ly;*aP,z| `>91ɧȪ-V20攠͉x^@xcԅ^)W ȾoUWCӿe,9x4rX3zK){h@w*L?D`(\2: \N(mY3 "̠3fq?bh"Nx~1f:Vc9~F? ТO V' D?֧ D˻gǤ쟪=JD&D, 94@agQHx6T9srg ؋L)ykYV2@^y2+eX7 M5@)MK-/XAnP9QDu*vؖgǣ_ Q/ks7a#(9bj#WγAHDlc/ޅ+B@,)l^hns[h\q]'w#;.7W= Z>qP}`!5я|'i軾Ք4kZ*{PLO3cnW.Ď=RvI:yX3GYm6MEqXAE;rG*&3zI/2o8vOeG>>`gp m=UA䂓M.]aSҖKٝE ث͠>TWHK.*'z@3pEV 4q3‚zlmG1ZBP)dDB܎y.t9kYWSPZLިl!tZЂp\]tDl@;CE[mGeBkvԜjXQ' cڥ́=t*Vo"tq3A򄖥0QtHqf+y.G6Vr}-N:Xn9e3`pnE#dI7x^=.$'²0,1gILFYnx Upwx/-6L06iijuNk~A>/.r_\u)aT?S,{W-Jjd5b{`21ɀM, ̎VQQ4l%J p,%RnnGB1qg%NrP)Ո## `ށڢuK7B*VY7/"H jG"Fu# lon-8</2 @%4MW\  /!&~/`}!Q$1 CLZKmU 7~#M/ Q78GǶt<`7|!S^C xqRFȪbuwOUN=՚uR,-z 6H)`-* jYj\(frb9ؙ!@<7@Js@RY(yqB U7x 4rS\ hB]'z$0,j݁VhzXQ^JA5M&Z(GR4:qw!A!>&X ;>B$Ύӌwe*]}(HzvN@JLa^Sj)rY9 igG$}J!NZE?3Nz& 3艔EUeoNǧ9{MdoI(4 <\5.SW+c)L$\J;v׉)HJp@RRXa >Ɠ6Hヂeb"}<_@LD!k>@Go/h…gm2, Yqӽ)~԰JّLcE-K >Zv#N9|q= O-MK(xតA so(aDJWөsD3DqpgF_G-揣rPGUZ ]Ia=x8ֺ-nTMFʢMg>nu\=-#J†X, LZ3EL>`혆~ËN8P3Z@RIC_ qPL3G%[J9Lkew\B86ܨZv5J[O0Xq|T0~bBJt%؇EV6-Z,KkX⾾߫Z^Dq 5\(\\/pm [O깬G6L%bM"M1@zI?9O(j[ `'y1!GbouǵR ~ gat317'ܐڈ_-7/&_VMrH^ͮAdںgS~󬆛:N$ҌGMM͌e!É8#5GH6hJ1a7fLˠ]2,3*MH ,R9 zrBqms"5Vo/ˤz\ lQ#>ñQO>Kڣ { qu89!..;&ansv͎QDXƯwO/2-.=IAW;ZAr-:a{?ZD%CWV1:V!jyn u!@-6dd磢lg`KqғK6iz=ݢo;a|FPL|Z,3Quk;}_D˛YŌ:Ur^ـ&djC}*0_FUPsZRc ?'Ѝ߁FmYUG(Z4Ym@ 4j)^Z hydM댈{z]L1J`_~==3 ~z4^:DA /(5iዲ;O j(v*Tk0@26H҄>ȃ[stIWո#eJaԃ0蹼CEM;Hy!IXi]Zcط@&j5!-hwmYȝo!wA) JVXb'M{47~z2k0#lG َ/83g&KMoƁ]wIxf>P8֥p;+CC6NFCFz`XN`'$vq Luq2N.VnIU+# 4 [Jig 㤅mVQbrjk= 22Kz .˸40%m55h&L^F4yWuo}o5#2h8>25H.fwD PvrZHI+^(TsQ'~> ^`ʡTuA9Hm舫f}߭ -gOE3j|m;fEyS>rS6V֭*A9  V'Sh=(4| n Yd{ `9L*RtRF QKBS$Dk0JPz'%Le%i(vl8d'ʱDJ`UV Ẉ*/lŋ) `@Hc hƉ'ޠ qB\;A˟ZVhe`juw^Cxd=FCV;"Hɝ;OH3#ƒCts@uN@]M)аʴ4-}IUX;(#qZ˚B :[g$K@Yݻ0r^ 'x(2~K;~in-!*he@pCI&${A@/ϪYiZ ^N ϹF&׸ug+Qu,JXx;۞e?|Sd8AM{RD D(8CbiOopu>N v&r]8A\ AO_-a>)hwAĹbI6a `Dk)=F'%=X"'c8}pust(=)wwcP9Vl}*yb| EZd7]qjESͷbP$;! 6wXKcOÀ#FRJRJRK^b.  ?wHo"roclcևfe1 Cc AfJJjCPLLa.4?D,C2a>R|^BNE5RapjB%*LȂ*$|$2Z)l& 60Z̻⩚ UE0MeS}~bn&H)N$3F"d~a_gO {$n>oLR}Uzq>И)SH12/1ZֳXPrg_N{U0D.R03p&]%LNд~΄$L($@0PĴ@iI cbb6Ra6cD:G"RԠ ·PE8l6hb42%.U:4d2jdu3 XƘcZ[D$1'' ~bs'5)Ws3E݌F$ɹ\T_c1) 괇{Ej9KV:!-Hz"Ijߌ bl-GO6 %QB1q[a(.&Bd C_dƉØ:6nN I2nS+:%1bF=K !SN6*hS3FNpRE-%UPhEX=i""F(Q(5VʝbS@,+^/Ͷ ߺr ΢dSP::HJj{\E*PU?1Hv}:TJ>ed,u1CMM tk,5U'󁭊ˉ mXWRb A!MrX"B4(H!C.cՋAf EB0P:D <%L%D! !!b ‡EBEH7B4J!a6;avpg9!;ᗒ'<]*)O>g¿~l);E0p8³kJO6ЃObNCB5%!0y R5uXajhHU3b%S=VpUPĘPUQo1 K;-,=2jB)U&Ea:jeτUU*B+P)rq5Щ<2%=4;jp^%4CM4 P40>d2 ’f g$d{Vxx bh%1njob3|Rr)<:!Ib2_lJ܌ M$ϡ0D^e\H_)ט̤j`-FjTjM{|/Wm,"i M$Ar=yGzK=b);"c 46v Ic]Q[F#uZuɐ&*A 'רIָ4cPYD9EnTg=E:3L|0\y#pkGjeZcVS$=V|pE%+5dED#@%xe&-&rh$]&19ӘOW:3U55R2rhB4!##R)ҕ"(cAqhXc Rƛ TC"oGPCjCz Aۅa/Fclx}52GBgAW)MĐ-٬Ih>*!rQYT[\i=RטJJ*ŻC)`7򉴣 D!u2Jr4BQ"HQDH&[X7B) z_T+#D'Z#VԂ|Ѹ;D3>HpДtU*e/k/~l5XVf5bDSj̸hibbSUH(|O&D+%8s{,SlKH;Gn2ѴvcƒhB\0':-Xr5$f1Ǎc"cUc4;kdjQhy#POhiV6dF(1pD$&CLS"0P@ZGQ58jj3EdzNO!?OQI)fHbjʵjVSd|}s},D0D'hNG:Dm4FZ%"P:6xy8 yA(DaE*(UU*%>uQN_\f4 E/p8$up,^!v r*j8l۶xuIWa(NpBP8 DCD"jRTTm#%F6iU$&."$/ZقDn&fHt]QJBD+ur tZ71TKލdycµ\#U+N]%):l.TgZ: EQbiF+=6I#I W\p/l*7en%+9blՖMUZ8ZTp$fjX pb/QF&&aKLi&:UUUUPb\UwB4 4%Y dIF(=B’ lˁ t =~+BhԪ(^VI'aX!+.2Uap Xb~#"DP(Z!0ŨőB(@#0"Ã0]0*A `" L` 0yJ"Є"$3|IUB%\214E^ٗ#BU,z"gU50hEǔ#Ѩb|F&ԷnYoo'%d{ 3O]ȸk.-s eU)9-,% `X )#M$ wQa/G 7%i*QQ^;kK/rǚ ye5>#2ZJ6Bf~5 k3S""!aTaJUg/9t2ϗs&=Cc$iȌȼ.## xuLȼU8adQG0װCl*t\gRIeް[ vc%D6`HG$dj!Bg͜$$TtFrVHŘm'R.2C[X(U%{31*Eij&ތʛ$1It- h9R~Ҷ57I[$.UB\C,:m.jkݱKUm~0 qbjrD#QB:ͥjbP*++9zCv OQ#.kEޚ8ˬh_)حaqxWfoJfEp*\dh"=jTC地ܞiTK rXXL k'˦B=Š{m7 2aO9-b55v$+mDQKUiZuuQ*kqעM3I\TS4MX&! ALJX {'ݣoK+ya|kuw ѹHLp&rGWRBl)< b"Xf,Ցn;tE/x"E*GQLj<ݓ[JŨy kx n9m-;^sx Ri\jxP"pnXsjD t'Bq톺BɈAP`n). \&A܏xqThܞqIh-&q({{.w7~?hUDLW<q6R|!;iT!8X^*D͊B, [HXR;L W"*H PUE끪@*j#PpĶP𠗇(,lٸQ"ybp8`,82qmih'̉QX31 Lj0O>f"eE8B3"91EKJ%صDa+ȔyIޗWɜ?vSO(7xxs[%~}(jY|PB2 %P bYAJA6~ᦨg\n|e \'S2oh5,E,qbD>$H Q7"{PBJ( ]T ݺ`@ Cvx8DCBA(*2@/sڲƘ5NS8MBلg:EV̰,OԈk[dGIWR:'DGZdJk 3'liTA.ktWʤsL%썑\3S;{ N ד՜ME=ǜe]RB'Ux؀v8=#@N #dϲ[$_lu13`P1 FkZ'&%e 7^b@N$|Qm!1j-4ef#,=h&ekI0^#_^^ P].4Ag1 < Ԏɻnf` a  iGk_ᔜ;f"7 k.\BX9'`MY:;6[F3gW}1 yO"Y?D\噂+BȂ҅K<\ǧFg&pJɰ*X!EM|SаS{!F;VFUq`즽 ST}j&~1?UPWk&kVPt~iˆ]E7fg(0ctE*LzG(DDc/98:faJyEoZ̅-t W>CdK@JD?!n,}r{pe29jPE oj0a݉ ?|aM8YH3hc\xQ0id98!?$TܿC#>^N\/m9Hs&=.ݻ#C})eІyPv SWrJ׶ê$a1wG+d:nWO/M`;Ee C#lx< N]NdfeL$JnB,$KzFGۇ>[-IoS!ܬQa@HRXz4ڗOfe+8kC YWOav3ڥc(`..xܧ ̺V<h2^,_`yC "hHr)Kg*cQ0ylow TyZ_wiٞnܭ}'2ΕF~ٲnJԕv9'b N`S2svʹdQm5[։bsTH3ޠXIy~Y@>|?L~j ˨0adk`hUۂ'XQ R8˱h ?~WGޣMg0y.md 8%7JAH #mIǀY&9 n`6O:UhƣSBjCxU:ݤ=1z֥'E"T6Qm#3.d^+"GXryuUs)XR \|&ΗJQ 0'FayZ#9D`޹ R!x=@!S ܂quŎJ:zȨ/l\  +]- I1kZҐFr7ح#kv1s1ƀ݂]XBRҀ+K_#m&>[/fI]K 3o0dLRuT"*# f'0&V(֏;2SK-ћ?Rkv8^FSLq()l*s.~jk/3>L[tu{`BP@ Uj|Q %2*uOAXx (A BL>/$au$p4?}WJoKѵLpuA)>#Pz>WP&iTA/ͱDAVBe詢FOFet;GXȝ5rMkpH7DS %b%Rez͗Dx`HS%bsxx_[]JzuX :%w)^0/X7=퐅#G\rd{@1åIBX&~7b9"x.^E)w~~f#UZk (Tү* 0-{De^d= Lx.`|.('M`M{1s˗U_w "4.m`[nޫ@æ9lP֕&ن|!c!9e* Zan\GiW& TY>tƑI=LR>tnepiP!k)85:? sA?vbw,%@ rɫ±erJC/1 Ŗ-_SBŠ80+A;xH~nCzW;Y=j!72I7x xgKd<ʔ `;?%\g'o~p7жr'Djl_o-ٷ7d ַi 9ѱed <\E*]`'S1J˻tٴGf,'#ӟ`A`KsO ʣVOxe@XmЇ=6,v)f-V1+R1?:&pq%*Hyij{"[Q}~X9l~Q%j$Wq)^Vojѥȿ$]nm7PAn;̆&5QV_(pVV\i>ƷDǏ xZ!0DE9$A,if.e|]cTav8C44<1_`5V62* QYİ) )%N B឵n՝ԐTy =w55,ը$qرavb(i!J8/![pEe·RH ҍHRaU]8ǠϓӧHB oX+QNlczӺUʉfܔeш1@w@Pe (bڸ7Azp F4sX4Dnv@μ/4]Ϳj]S5|m ƀnóIL9nF|424eύ1)fgrv=Z9QpI9~;5K[k˫zKIK^3]۴ ^1}\Rݫe'`S0+.Bi@a}Y&&YLz#z&YLZz58t)KmْF 1@J4A0ݣ9zI҉ hߦYxA3KkiⅰBă)o% 9$(<֥I"hKVSe\GKͬ3|.]B@c/qԻPnws 8H^0!xo-LdD0_  -*'~!K}'ҽ0b9J pVCgT?($u@u,8 e{{ad-b 6w2fUTeEkO$`m2fgó#n zW8R.b=w،!%C'ga8aXYڮ%"<p$U#@2 V`xK/:DS rtbHNJ+F>R ((N<$mΩ3.5ńg/:d_'I/[ N4p`C*b1^|־[,Xk OM>d."X'ru}[“b7} PUʦL.Oʞ-DPF3+t~V^P`kڼhC醞R wQcIcrfp̠((QDb V@< }WAu!Rݱ%q( 7d@| bX6aiv|LsTe.;ccZ#b+tWŮ_MP΄Y!Nmv5wUu4FrHڠe+v* ?xd,6Z} a&ױjoRPjVAC&%ag9mrU`ya 1座) rnYrS-A<9B)~-gI_'XUɊu}ר7f^t„j??^kE72O ,H j&\g,<^oND2}M=WWTh! @9NDa{EZ)z;xE Y!̋;8 UjRxL1]\0eS -9)E2UOKHðԿD(,KwZ߷%c4ldz!(_ d4kp2<דF[〬~7ahk!k|i쭧[ h6DxfconK?>lgHoH'`˃,o rVbj9u {^݄~|P+&jI)j]Ox0Y'H0X|@ d8Sw`Y/zξ+k/ϒ`MSp膌 s @M7#d*cEk>B6 /*شd!~ss'} yĐ) {ηW(-D]~?趁^xޜw_~I V^x `s?{o@d1b6V^W8xnkL= ݎaԾ"BG|~@ },PaibNա-@3Wɘ\p՛Z,PNv)f$,\|PP[ove,!>UqžfZf;0:)КՇI0R,es%vM5:CoaX4!dB*2խ6qDw^.`!8H~QMTP{PӤӁ%!QӘnEw05mO+Dc%*X[oc-P&^!H|Lbd\GF2&JC28?UqRK;/^ ~5FPjV)ID6xXK(c@2>DyxSTm-#X cN ϓH$-m '4%m6q1XH@M%XTNJCEF^܁i3m[3aU1zQ6,61٤Ebp һ+uڞ <Gt?kҬkN˜{sn:dc깤f.:ȉenBCy ,ȿ Pl;t%go^eM粪K3]# ק6cwr=K1h5ꊰ_37An!m+BL'4:t)DAb0iᘒV/_ۓJ$η^ĀM6ѹPZÈrk eڠ_W׳b_)5sBF;h$ז }jOIy I <.UvVPKÏNFh>Lc_ X~ s&Q :Wjyt6a9G vF.΍ mk=.< xSL1X91%]ᘒ+̈́~ 5ghc'*N~6 Ge{嚆 Q&H%6"sS-{pF_8VsAaVs}/A܏ +C\ױY: o+OviZ}>=~n!M! 6u,u}dTDQ@G1 kkoXrp. 󏻻c8\ ?с{[-RFJE!OYO@?gRHo)%.~P%Gsu^FPҫVj40~^+^:$XvOi=b@ 0k=ll!M5fr\pWˍkN[:Spra9Qy鿨EVLM0?))BK %'k$D C\-&A'ms kE@ Њk6\15_gE 1wA8gΨ'pAdqkleQ%|PRzt+rcpf (uH#2H+i0HՒ'Zȗ&ȥmApՅfLLhektWχ|"ހ\Jx}K8ٕDؠ+&-X2btTn2CUΤBg8# _!%|܇.=) Uu@2s鼲^q5 vs7)DۭptU CKh)/q3aVCmqB69RGARe83PRyWu~@?0ՃЗH_PvlŬ!6|f"C9Itztå$:A"h Gdw_DFC3xH{zhy"O`]H ¬|އ{`;"?4!LCѬ!e9}C$D(Ć5Dh>CdUUu4xAsExg,х8/Q r=" $!10 M=G%ZBHBhFY%BE#J]=W!!Uթ#qv<3JT#|C/o0mhDq@A H8 :/n(ڂ/ 'QЂ&(DO%zDW쮣DcWҁgsDd :~[ &:&%pChvBəh&RABwM8 m+8Z*'t`m'-<?\ʴoQ EW痄B m(B9G$ eN"K6[Ǐ.RT|41L>)6bW!5C(P5~([QQIT?~6(N!gdNG*z̯IEVT>Ҡ]Zj W=tuÆp{ +O{~Q#mIzԹzBգʢegN΢Rz$%ZEtEiQ&!"<ڪEZ]\-(~ψigd9j0G'W4SФ!&9EVN jx9,ROQj881QF0Pok8,Fq lT8بp~̐ 7F jp poXݍ%?Hx 4jnGAAıqQB۰9h%r؄m\2S)F) P?PV97CJ`56젍o>ޒtFz$vT#ka./XzW6$yZmm'!H+U:c;l\iE:5$?ېq>t8GXDt%<:[C.Dլ1k<LWCС s|%cTQXT'ӤW\Q#GrP9i s*56QgL@Ԣ4k*/Ǯ5GiX:ؾ䨤Θ(9/g it%klud#il̸пA算C^Ɗ \,cZP$|926U2.s2DW&#$)+ uQEƦ͐>Alrt\[Mm p5!3rcxb&c1fT OQCZ܈Qy!Ƈq;Q1a4t% 3ba$~4=a43 !`0#'t 9(&@qXB` BrAƵ9L/+r|3_xF/ D}FWba+~H6r'#59Hk}E9d's8`T }9,pρvC@st@^ * 8ŽБ:h##u.(~.{ 3nꂺtt1ƹ¨PJ.qH?qbt͐pq_\[`jg.P!ˎ2ֵXѠZ<;YZdL@)) dHWUE@_B Hˡ,L@A8CxP* 2Vt EE)QQ䂸2 S4 f=E @%Bu qIH?NkSmBx)$d 5)LRp+ 9OJ)M VdIQ)B`Hye-dpA!^</ >.!& TU :]ݐCQ bp_Pp;P0ZK%mHLW} 7u7d}w '@Jw'IJª*t"Ɯ9qp MC|kC-a8kB  ލGbwìBJVAOU321!#&%GLxo ! {Ĵv ruHnC$Z"e8KXC]&=䔕TJxê*qE%(!퇔eJ )$*DD'D$fI4ψD]$sDDM($4FZjH XX ]8U I#Z 2`kx1Ҭ#`jQ7$h$hFb"e#g)L9c#<$B#,aw)"~-3?R`[@؊$T IqHJ=D8"4VaH Ha%6-ia8!*6­NCx$8 6! 8B%/*Bܳ2'@-&A%$kIK8=]Bx%Č be_BD!Z~ vw틉(p]PWAf"x?90؝%8UoXvrM}Lڇ:nb\}h&NCą-N LJ@|Y9PT5=jGD':i^=NE" Л|<`PPnP\~#BA 5~5ϭeC11 "F =EEQO&m؇Ah_%QAHT@DG悆m~JIeDٛ(^ACE-MOWγ.~PU5G ..CoGРbkРwX(D=9oʟDQg Eb+V)/ 2-b[ex(U8(cQLYQ($FHc᪑BacZRZVj1(7T 9203ja=Lq0e4 5 )^MN#0=_p)E R/x=TZ :xJTUTp*3&;ں@h!r6U7$VUjTɅW1qiY&jy_ʼn[pVق`Ȋ`̊$.E+Bj%RP;[,tVڙBp" kfJƂz6-2,7Y!LN~~EVȋbD] ? X5h$KÃ/eA*ٲtJϩ\T@YLE xb g `ME?8ͦRL@K-%iWKQHa 'liQڲD/롰nK YX0?= s#@8+`̉>Fa_ cE o0!n"dXG|"B_q1F;!dA1B[L6& !ĸG%o3Ax[1Rc "d4t^@!i xGO~%#gJqLF*}@EH:AyMP@HSyܠ4 ).i@h$4#F 30jHԨIVP2pjh58V)lxA`A5 , d08i | k@z6sVwKj-vZ0,kjф*]C+|rtV*l'67Vc9$#Qdj; 'Su1Dqmzm,}pB/vnr13(n%'JS+ nsjF[rNUH;$XyG#tgit^H'I6KRΘ}dlϏ3xiA@_DM_|`>G |Z)0:M4:d7bLj8ˊʰٍl+{`kX|Ve?ڑbM-'v P09a`^XB`XޖTZwiK*O! BpDB0PuF B`]B kIV=?w%A-6AgRF!1ǜ8*R.LF2FPֺ[U\L6P Yzx7 tU14\T* m+'Ă@6MTi^"@p!4jk nmk Š (G:0KۦfGo`$ ˿V 9! JqCJZK`x\2??ۨ$a- &TV5).j.>N*hrm ld&*Y(C%|U( `SV8|Ggz:7f` %(l: k$ س| lJ4){];u&I@]\&pI O5J&erfX̫\HWG^k$siHHd`w+X6A)l`@݄E `#.0A |6O/N9GRL"hV!O@P- 㿳ncYd+PbܠψGdp MRC ):)\>PV ۛpv 1Dfs6/L2`  >iP0;rAТMXf`ԡc"O}?._V{ZtS><\b!ǸlȔFoӠͭ!wP?S' Z1Cg_a'$AߏR#>TF~*Z l:0Ma {~fx$WSh^:7d ϓ"|0Wl'ٷ@?bd{4A5$re IXw%h 9rbE4!kKwC`'Zx`1WgA#z_Ʒ:r?xYϲ,H'xi]YHWB.9^ 0tG-Gq(O { /=(`x+:DͿ}'Xgvk8KlV=)mKSvq|\fɣ-T'_~Fy"W_u dp==&:Xz?BoFP^=m:[Qo= 2qJE#Tj VS n X:5Ċ/~@*ж'~l0nȣ߾QTJ֟-]j<}L1~~;M{ҮDI UdmLPĈ;C/l`˓`yn0;U 1-|3P?_/#29U_4l>UՇĮM} E(s xN` [KOC)vm{^-Cs{5 R'~g~~o_!BjO-q]̋L/E_ ]߽BKKuY;dpy=A}Ja v@@k7j!J{xƣ^/B>!|KƯ봽q"!})|5)E9+\b嗘9(?Hh_(X*Wk"Q 0>Xd) )M%_V`Bޝ4jM|BGhA{@MD ` ‚y{N kGד2eY}k*^/:<}y C`$4 J8'`DTEh]}r Ȍn`V;Gݩ~.$*exG^FUbUk-FGËQzo7:%C0zz^&O8y? EK5o{/٪d+YCqI?备zjҋaQ7ө˦ܱGYSF̜&JQ(zG{ E5&4 b)Rx zK+~(wU~\<!Z&2Qz>"cx~ 9RsޖT6H*I1  v{0rS%m˿ovڼWs5?4̰EE/^f^>B7B̻gPeaoW'5i sPzmt_gdy-=V^W$au+nbMʴ9y_"FF#&U!sysDƠhːPyI=5tBac2Q~-pacB@[yjr5+*oe}o+ٚޕEc[}Wz FAOEieYꎩ{=DLtlZОMŔ|K~~/c!̒`2K 7xB$m>'՘Тܛvq *,]}+t&Ȏ;:epuԻݻoo\?lL~{'2i*x_\/:P$laP u@]/b|V{shʽ&p+ʺC0Ϟ u`BO|Gw- lc;Uހ鱹ba@Za=\-]B"&Ftă{qgі[ w'NH;uw{݄}oߟLK~\Ta[s>퉇O,o11WCk{FvVbَ+ * 9영uDc,]XNq:/Nd[FP_vi;"9 yXS=4^0Vgs?܇ 6{ti&7#"̘ޕ+-8eGbA,u (y=5H)\\Jou{pcwabg$.v2 2Į՞4Xyv/i*k:1Pu-!{GYПPQ|]°S ":#[%Wz kXuStOuлsq= Õu%}bNl}rZ.>C.Y!&pjsWPa]pAW/<垫ElIh'E+ W;}t1/8,N B&ۦ)`\cD+ -emfK_[ݵtlEڔN ̉J;JOdpJWդ7ʵqꈋC(x. y J0 BjN!{vj%%-m,@diMu־']q0\Ֆ -e߻ lyЁL*jq/!. ,FB$A.yS~_\ *s^jcЙqCnkeASjrFAz@f^U'PcށCCC8^Ǜo֨Zua7w i <lj`cӕ)KQp?ZcjӬj# n](sу?Pj oP$ sE`0,<9n +# G/|aMhÆ._fLt+@#[NiV=~)n?o#3,Y~ly>a,xtԄbon!dT-VyV7K^V9fIi,E!,˔@8cRn+"߇ "NL'O,<$I'WDd 6LF5Ǝ/o]K;iR(֒?&m4nij5s`թ.~<!U4FM%aFi;DUㄆDv$X󙯀⍮˴e /8 P[ ó#A d?CE N҃%`=Ww<S [xuc9i=F=p)(ҕ~v9Idž⣼- `?ˈ)MMVbZ]- t4NpWT)agyvXj8!rAZx<Rpr H<WȈޟW=AF'bݎh55y|Bzuµ]9 48upG.ngds~)b~1|k@82pXLtcK4 |8BUjQƼ (WX|7&;%¸G8ap5&<+'‰Q5\vj7ut*p9%:Tl@"1M~cipQk])k|| k UѠhf:Q ^jpzT%Y|o58Ti@tp-,8 o'ү3P@>@wMZ[5{o N͔n\I5B45\ICPhbXv58=Xy٬XKC K5 ?E;8W{ԫB\Yp"3?T-Oz~ s -Zh5"ͣة 8$0p~88?^?ǖH*Q<* QX(~g3>iH$W6oi$o[@_/&M5,+߷"ς1-} n7E?Gߍ(Ov /t (,oAxN pzىL330* WLbkos1}~]g.BӀ:Apdһ}hR-匚}Qչy-i딉]5gJ^oEMxs=69;Veݴ2 ]vPjSe)rsUΧ,AT$duX";KC[Jnœ1 ˙(csHymJcTHsG{yTuŘ;sAmY17jx2憬9~1͊y6׬(k6w U endstream endobj 19 0 obj <>stream 9gsH_?D[s#ihzE+=;B.ʘ-ypy4s<* p77Vs屿 snH$GIk>;:wabP^tn^fu֥C3fMƿ$GE:U;WshѹMhq*$ϽX0As-jMrWzsk\K{6Zڝ.g]8 0o:7͍9QXX;E6r7 9ι=55Ha:l0j\?4!.plصw$i97OӦ xlÆ\m0!+ʼsQsOk8AeZ]<1ItnM!CvQ,s`1;.fJ[6wiQk|M lFҷPT\Kf h [8=gԲ-)eSKP @[G/~0$zy9`΀_6 VF}?hEP G\ "f@ $Y;U,gbE*.%ۍv"@B!VivF6Qxpۋ@l/v1nS-$1U e?yۖiGڔ.~|Xk۲R%?`!^Y\yE^C$^SVa͆Gl?SLY*Ķv 6#p6o^\kGʫl)Ƕ%kt l^ #GGԆ[ϧ=$X>v0?FT+]PGᇥ$(Ɩ ^~TKCd{YJ7@AwnVp.Lܳ?Kl=$̈t(JGH7(lI6r*֥MMևfVI˞( كO v]@097 :ӷHUW"7Rֶ]Pc)8yE!h`nre!S`lamЍtO*fdtkfcZXJ$|Eu+RY_ی%y?@'$(l@=O^Z@뢓(dϠS vVJQ ]jԨ6"Q6f58E&6KFxj]nf e-J}chu qڡ_X9"aӴknԞ:/kZi`\nht_ݖU;9}υ~ӟ(E:鹚\&tSF- Ihf4Ěd2OBPbHKҿ/ڥ]G8TcۖV~4۴VV]Riem''O$‰JGAcpH@~ʷύ9==9|J6\ȠS$FG˱I^Gˆ<{٣bC}y}mGcctji4ϏCʚǘMF@?hxq /Y%he؀!oEY#6.:hBꢩնu`q J2һVEtren Gzn_gjC]8oo|l*d<)C'^@ >@A BK#ܞ;0aC{4z3qT-=s$jı;,px'πv*-fnV=tu{P t.wV$b˸ywL ̏2T_g3O̶:{@kSvb:i0ӌ4F .s> 4YY^jBEI/qU*~ gBfX<&'bT4كkps9 [-@Eъs0VI;M66K+kf236ٽf` \O5Dv}SwKF6v:k4-:8Ꜫ|kxf-%IUγɝ+9q)Mhx`1=Q7UE\r#Y QI=QuzGC6#=c".sϴ۫A; 7w=!H߳M|ƑO%wAhkVgSk9 /1iP@s I*wy3CL ;rJxm;#Ե-1:me8y)Σ57Cs~]h1#uZUW퀐p*d˂[v .=qblF7[w$,:O[ 1F%t\Cxu+Ri,HoLRp,z\Kʑb'SsbRJUP)Y)6G*ԅJ!]K¥Tw&1S,fN;f Ā04=SQM oSxSϯ*4gJlm_e6O9?d lTy zrޛ/ *4"F u} ~ly kcTtTjPƠ %FRG=!Ej\[)PF©@qCk%W jX"֖)L0Uث$jE< sJa*ۑޔ[rٴ4ѕ, X&Ǵ)^e3R9WN9zB꫗60X3Kk0&koiԖBnqї՜ZJ7AkBȒVb $wSV^p[gwn-p5pUe"2Nr\"2R˲\K#wz12a8O{ :=g/v uШ{_yc_ g&!6 آ~ }eEgr }KŪJzۃmF];M Yw%7|+0T}(kkFCXWDȲpqӤrz'UK.fT !Yh vl`{"kהv3l|f"i gqZڥyis~+l:`QDT.*L%k7)lzx]]_{AayͤL2[ h bқkY"@mkh'80n?'l!L3׭PLԚ%|do-ǩj8_W .$iHNttz*NvQݥ@[M.}lRJF́\!$hxf;=*}k]Rp*jf<>u yu׉?"2[r[(1bI.;s]=NZ0tGB2ЈۂP*o5'[;'tL,q2. {K&;vB _;]-K}o__fYfGN'op)C.4Ynr&jfqwqT V/$KJpx;_;'a g wW $Yc^*E?pΌp_FxX)Wґs`/< ~Oso(;+܌Toa98B}=H@z S?J[<9mV}/!{9v>}#ֵZ$JPG:oPF} !rSɾ.v3$*Kj#?e_S;.CLB)u'h_"ײF^#l U2U/4 OO<ho6vuҾF}`u֒1YB\/Vʅ;%`~o3^ z5a:]`ߠE]D369v^(ڄQkf`k%z- pk%5ey3~olEi;ƶ3cdP7էq%mǺaIN؇P"-7+8<=r+_iΪ ('@s\;LP5ivn3|p-0x/\ivPLs`vWY6aUO ޙU"`e`3!78 ,r~3):3J K ǧ^4`/ْah+i.9>;lwzx0"b!EL38 \,V] QvA(.zƶFQecus\QOߣR>;+oZWYKGK=J(;ق_*ԓ9xic(^unykIdDŽg_Q[4Ms:rS_ɿ3֪\]8XhGkh-k=m'?nhk>:yt~ wр2wkK [KϢ\o vH w& Y) o]YHuPjʷ~+IIL%k]7 l2ZgYަmT\KvN-*-Wv /K]|P\K)ÖsiBh)6D;ܿµJ[wҌEu$6oؔZk^bMkTEQw6o\fD|Ac#=E`sD ZFFywC{UV?ܚeH=fT ΂D3hˮ$>6[jx!v#} mLدc0#v+MV+];C9*lR_"YNS9FaHvҡ|]]7@mmS} FM8f_-q;"ܖ>>wl<4ϨynDάجiPe eȡuS=uz -}t{k3YOI%{`F~54?35n!'pdKĖw1 r.B8N@^—v?xɁp. p~ZyfLbz-<ݚ,;1E y~3arYۺoԧzO%?\īNj2,}_\/twy䷿a/K#@͡:>D{W{5ﴽ<^e6\z{ͤàӤ{(bS:uojO% 8~='=z=S$z۠}'S@8lq?7WnKqES܁ʷIPOH~̷oKyv~P[BY17wku7ŇX q'x>_(m [ᇢ &c +f]*aKZ$ݲE Ms&;Or[X،%cBsʅdtI*kw.1.k4-\. 2{G$4Y};:]8`sM_'ߺ cK{ g,D'ሾJO_J do:w|;yi#8:U9d0 .">q;<_ު:lB) @(y{4E>{ҏ[3 _j|TĿcfiKYM4 1H3gX70ZHl1g3c:{'lwE9}͐*vݻ.o!Hϓxݾmðs `6$s>a3|juGh{9 q9^;'SEC^"6,Ao|0&PDc ФTxG&s>fX@I]}ºoij$|lɿ$ڽk4MO\#JB{m[m#8Wt>NMaZ йGή |2xj3NwnV4ؕ<({]ƾ(>{Hsu>{}RD T8'=qt'qAE:`:ۆ07t0sȰn]#AzSPi,ǕxK$طvn58) RHļW EAӽ?|" g0U4k;8`fsn28a:&kn,nnbuŎbG0#xeCz-dKV IFin=S,"} |xZ<4k+&?%mwvwS!7JGgg z!к͠eU`$T( H|i=Eg ǽ?V8rS**껐|~&-ÇVB~~% :]O4)x,}D3bbX8l)1Ъ)'q~5㕳< m¹?ӷ6U)t'ki0$t&X'yG?%Ю`LW54-(k9`G?;UG$M@DrL9^"|x$E=#::=F=1϶!0x ce=6YOm#~Q#i.UTkKz(VEw 5K6B=i?A~vߛq;wvvҦ6p-C{|{7N7 uOA*J`J1lK#Yױ|Pv JBi"RIydmuÒf~P>>zI"~Q$ZP+}Pd}8mM`qA}7!) n+H1thV;Qg> Gfu~0ò^߀T߄굛@x<iG#@Xs~Y;6ge4|m]mv2PЭC{z6i/pX71Yk蜷|t V|U U}2&l Dch:40۫ [JdMR_pSLP98`~Ihk]Dү/[E2k SF,^CmoioZ5ZHvLEc_.^9쫃n>׃&k]љJŤ7PF,~*@j}naԳH)G@BG*9~AEA{7Q䠭4yo?{o7t'weP !!I߻R9>yZŞ*Fd4l3b1:3 mA6KVOy)TslCY6vOyH@[jWP.9.ü;l+csMY6oVkanm䝿1c=mx:Ỻ[?_)yL`s&6sLG]5q.ݿ!5}p]N3gr| F2wj5߆}eȬbD+MaMp?Y'(h'y~5c@"-(\5ha_2/(k MHg tS|e"~kؤpDfM |qr=1H{}GU%u{a F:!@i[?< CDF6%]T xEE)k3JݯR! k 8sA wx?K#:;&ܹu.Z>ܤ»iЎbEH7fG0ufZD IR9۱m?˹Z1;6'\WY+![LФux?*~,e_5\K߻G=[GSǝijZO-&lsW&2xj3ܗauطN&w&6]:G\W1xxv[2;[!tih?8zH3z$ϮQú-W[;vױl}Eع[+Ç[[+gźu-Ahoik'}v(#R&ٽ0Qe9wpyYOMV8& L~;Y Vh;\RB^ҲZK02*I9^; LB I@i(N;Iy~͟c5o g y?cW;϶dX5Z aXٌ̞kmt-}-VgsvMa̫mpu̝6ƎM;cd.\HyzP_?$ XDv(M\-F,}#N X7[ۗژ2Zf/M3_dm;Ӹy:׎yB>'\W3k a6oF0ſ/D zηߕ9ȳsm꙾FL9ģ0 }g$y=5:FlgvJ J?6pcsw5s$[$T94N( :_;K|&>|~'{ `\m#o͟5~p?zr$8_ΗΦs6q2N, ]-LF|^' I^4~pL_hm^RY;xP ¶W'~,";2wl򌟛lC(GU@@IbDc7G.؁c/v&o5V;t5a9:C(e<g#Rd 6F?1uI>{Gluu IEg|l/1;w>h}y@?D)2g3~o'Wp?"~E?OA̳N5ާc0nf^ OܣMAgQ9?{7w <.NbT*T+"~D0q~˹Yȹ~僲OPY+p؋<b XzfP mh;Osy:P;v~,S)$:xC" \H'To?&z] S,"kVįڵJ{Uw~Pò+0pNv?|~HSA$cxst_Nj}l G[H9>{r#yP  mC 8s^N{᝿!9:xy =g/PvU [*iheB 9Kw H H_9.lKOG?zvs{>`}S86 QF?$9o <ӗև B~_38g8B~6ԕ6[ cgoqp//h[4L-7ݸ_CqqFƾu2,Zp[6pֵ/k쥍&{Qbq8G4ju vkl?˹Kڬ[mj:lKk0>`|6F+q8[e\C ˂1H]Fș9ݹ9>ޓיB7tG8ÿ4>zЭƺu-?{#XKp[92D}~NX ?;цBUK^{ l(ºpeT( 7%gq-sVе=zGQ<7PAK)k }Bc,$MB.ѤSWt Kaf7,c&1ui81CwPߍw q*˚<\&O0 T=@zx;ry>nGgںM\7,`P~vfm0g=6uC;FǾIn"HvФqض{C=,,A9ݹ g1v7Wžyfkg3ya0z\2'\#y Y6\]Od^\fa[~&&¶&M9|ko v{[2{i[ź1{&a wkcc`/gٱ621nbض{ ǰf}+stv3{juO^}E>}avmMB?sv, Cwx ʿD}"=ȳ;~ۇq,9_m|e 2{i˛MVW3z mA3|j ׾mXζ2yk-6=yGȝɼYW[4{o~殭Si~LZM w޾5z=zq1Ļwtܙ<6_f IF_d9h3~oShm ᜷ 7s~|g7~o("mɮ]o11whsX.:w'{Ih/u~oMgtl<+ij(ۗ<\"@#g旷NfL޽lmg5p*xq&*#3҄׶1ziZ,hbxYLpMn{adֲX{w|LN֕_q07%n]CAB.兽dԲ3lB-M!<]Ӿm}l ܃qxaFr&al=m^Դ88tu ehjjrnrdմUtk9jrM`7 t6MUM tβ쪨xhҪʺzťUťdťw6֤F#xzE Ճ,UUTYXYX\9ڢzp K֕,*XYq  cEAW*0?L`~wxqcF!:N5utf&ḏɘ3ӱNGZ X9Vx%sx 0 Pt?~(@L @ 7{d geAp-_Ș1m*Lic&G NDE C(v"nn,R5e0dѩ٨2S|cbJ׮WJ cPŲp YS|•ޕe/peq ׅ-nk'`2عm$ 0.O[;mȢXd)d?*)d ~=8LR5ITi/@?5[NG%bʿ$="^ {2 X$H&ؕG̮D1[`I졥,EMSL/#0O(s,YR/BN2s5\%oiRQ'|+m긒f9d +lK.<\hu,zi+OI\D,EܥM; *$-_~oX<| 6M#&U d?U1p R`5 llC,%TLۺ8!K!t%MH# |+Yj@`7e`Q˜Ĕ6PV'uxik(!`Ĭɔ{ Sƕ4XN6Ie.,2)ɹXH$-f dme |%3+mLJ+D;ȈK"5(cC2IXO8I\Q ;G A@,5dҕ n'b<>xp?OP]$B)*PStG'HNQM /*tGNNJ#N!!@5`BRb1Fp_'LR2Ů '4?dtzR%aFFXMD $a71rkPE-uՉ^QI$@l?#TQND[؍:dN :ซ̉N;AߘȰԸȸϸPm B`-mr.\$QqbfeB$^#L,7(R2crE ] ld42X2ahhK.eH|HW*ʘvMr]b `fvH ~\n/`u{q ]Aao0u9S ڿ[%e_"OR|*,>Z˕S~c/h7p9͠Qc 1Zr  'iW(# `WITa-ԉ^$0"G0PN!OPa\\VA dG&*j4}X@݃B⣞؎9*?G#ULWT 7eLV|&vR),) mɞh(s6)Ya;~,M3jYj*|57mPQ۔AeQG3LQ&yH1s뢣2tg/.t)3QT2 h Kz2MV(qM4=y.4ubJ"J&,j<}8wPt3-6?$YC˚*n!̅wbWH?HFUXY.- ӤoP`tJhuLr|'5z"CN(.3#'Ҍ19qYB7FX5!$sX5J o :6J#܌LAo ٲ lf ڳ NB?6b/:XFp'X".۴1^ 0BҙRᨅ`쉋~WD}$=G VFFköK%q9s1+4,΃9ڑ?5bVbst nW3&4n \L n׺l]nvV}TЎRn'XlL W:ULi|be$Aō3Q'DMS'uP$]b-\jE-LV!t!`{B)C ϭRꠝ5{i13\97dIÞz2)̰0 Zc3*CAPmVmX4r@-% 2p!YkHyx7d}SY1 DvHeV(~JEW:2g-P& ])Ȩ;b^rC6F;F2b[RZ=YR栽~ŅbYf6umEms1Q)RM!RYRQkAsИg+.dD` #(2Y6ń@%Mf]?1aFW ʪ@EUZw&)+ ۖҢTR=ʊTyBQCVz}6zPHDʽ嶳">;@-SƼF6{P\ ;m400~ m-$*(hI椅]QNtGaof -3.&VF^*Wb*s +vWTi $'2;#i1QbRX}*TJ*mAJDvpcdT`Tr*KHB 6+am;I]kMK9ɸ Q,\WQQQPBm%.,%gB÷)ѤɊޣd[FbRDx[;8i,u K.A33$ 8_C?+I5#sj["Z3197QIG Ygx%9(|Y$ܴ#(-a[dП - _m:7ǗӢa!BVr&NѢȖMvȷ5mdl)ƪx`q(3J_HJXc;\1cJL\A8)+ ǟգ+5ob%u&4U_jwcTzȉ2")*8(hŻ'ujMD xC(Yo Cf"H?ʄbeu*-#qMJ#,8$2^]Nفʹ*\WQ͚25&zgPH͉ {ʎ7/"ְ BS<E홨Y'$/,))y ' ,H ,6up\gVF*bOJJB(D]th8}/eBѻy:6@y.$WX+ƾIhGP ZDbj*Ma/ 1P*@Vm-&?~>~P= N40$IB5@G8V8*vY{Z]Q)P~ H$>'!OG =8t0ra])GP!VNƶeo ,x#֛e޴4nshamLڼhב@~5*6kMz3(AK+eҁyE7*5N>U UBJIP;BϚ G$mźĚXECSƪ9'8`R!N m"JB h\4ԈtufL@j"S`TBQY;K ɚeGb'qz"A( Q"m"m(DoB)O0])۹I e;`ay%#ʑh0=Tw#yi V N4$Ÿ4zs4P`4l N&D,>M [-Ӈ6|`}jR >| 1Eġ9B] }<Ne9fԝ5n=',m^~9ے@E`MN?&3i2i H/dI8eJڀqB8 NP- c}QBO%sI$@aWQ١Vm$PBF g[|YduKhzXaM`J*M [B*[尤VS:CѯH]hʸ PF5c*1^H~*~iSl+ HeNB8rMxnnj{ -s)T|eCsd9KpB2A#?zXY9.{&ב+)& d}Ulmzk:~}SOPԀ;ri*?*z mѤ_S)kd9x(Hha (7'}|/XhIh"KB;U?1BA{ߦy==`hT aAC];~,Ŝ/]O G3zo5O؎CHgԝ/h?ዋ}}9~ OJ-R2AŞ :ἚH!I3IwaU3⮳lFBgH2B$]$u&TAIohR- T+" ?S̞ZlvoW=6e%ToDZ`x XXQ&kP]^HJ{WѾCrAPmo"?{P$rhY.4T(VFVm)G HEWPcGHJLZJ$ !+J<3akpRڱ|p \XC>lwMwu#MAτ Y=0 &QHCzgR~ngǸ ` T08W\5#3$! ""`zp0dV`B6 yz~p~/#wU(}=&P}I(FD( Vn1%Yļ%c 0@}}^j4!'PDw2>;Zs@2fh H G@ >OFm4i"]+gR @}:_;"J;*Dc]5N‘H:jEb@Ga E'~'paIK02*W82J[BJcp%z =@i(D;[ghS8D}%31> ( o*6T݃g'y|Q+i0<綥)tuwi5[h*o:AY_VP=$ՌDbݤ*xpj\ @4A1̣p_JXk GL,=QzWp;&>ks"vs;BE:k꙽ahlVW Löd#V[¸qe<7'#1ue3kl}루g[T$&mO»Fkol;5E2NgbPe O02*7vM/ TX9, vN1@}J5Ѷji;۳B~]й‘Q)U'Ёoż6`,Xԛ*h99)c z],ܟa=6?Vʖ:$!'g=K`S)mv6ѪGc׸ڗVrFgM=LxXWրDQhwBѸ9WrT},VH6 pbk_yѡ rѥ>X[`ª"v{Fdj&h-Fe-gxJ=a- !)01 2D7paIGp 6m7V6{Ȳ`c_3؃.f>5l7זsv]omM|ֆC &Bّ̟iwJB}ډU LmD"m-Z jN =zZ"Bm@dӤܠϢ^n"}~@8dXNnJn:"47^H Vdt;傒 qs7 7޹ynyģNu)rWmVMYjc4ZX׀旵ZdʹC'l'c|;g01fY-0P(@Ǯð)PI>`@ T1,g32+v\ VDG?}uN& <)@`]F^EJa^" D; G.~i12fejL]Ҧ k!zKPlWZC VԀkUq ew&?Ώ1@BRJt+VdvHhբdYJW>@Rg#J28sX7$*{*a!AOV[ M"O02*uzUzIDHa!'VGk'7}9kiϺ]Mkn'wx\W4?[1>Łi/ɾ [q![";5r+t+EDRb:MQQA_pBJG"*/X HiP&g/#Ɠmr25VK)M#^Z K_2od/oMmԛN I&cݺ6`f1V5,CpBנϨؠ[X[()h2($j,M U2IwUYrȂZGP"*GP*SŨ2 kF#Bog adab_, 6% @@=9<8inA }jFJ8j)$,(ȼp+,ȶ1Ъ}XMJtrWխ䄍ů)c1'3Ppe5[SRݨOLiDXOCxwx7A>ȭ;\WV \ _i{1*tPe4/jc| B'kq;!Q)dqLH0[镃( g' WNT멼 f, xô~C?DU}2##kj?ؙH GT\mv&H D jMւḱ #zءXZbV0#/Ueu7s.x\ Bn3ewvXT H Q0.~`E3k,#LlLc JmQ-шe$4wFBhwPztK B j1("E\d7Cư%DGTQ6,>i$.d ؑ>T KVZۄ> ̰J0z ƾ{Glg]o`\Y^eV4p 98J'ټ̥W(P,TxЃ>2q0 a\h *ՓBa(+%cN0nHl@Ģt @,'j='8n H:)r=a?8&L$n*3fAиtn4nJE'<#$! m9u5ceh#Pg$RCqԛcв0u6 |sxLľΤoSFc6CؘX aø{ 94\CxB\abLØXS7*XDD=pAG`Rmd"fDZxnDjP@Ėb‹Q!A(+&n)Xan@B6[›#"=;4OO &6]-~k`8R2YvwgSoAQ40fohbz@u t/07@p\m#:&.f?^.1Z$RmF9 y>bR@ PRŠ% /P1x*`o#i_NN?5H˵SN |KFƵ8p/3;jW{U!kai^>ڜC::LD*ĨmeȂJ$T* dC8l9?jj-HGFd^cb[ 99Va ȠGH†\S`O .V7 1n[0m\?A+thPW˲^c 픍J9Teϊ1X)hTz/*^ꄢKm iX_sq#l ̢en¥х)bJZ؆"_7sfr0Al+¸%3DQ+Ѐ)pXCGi+$oUU RȕYʢn"bYg"Ϫ9 r>X|2$(,2rUNm@댕4۴q, <čdhXk R*tB<6sxFX W!s٦} $c&`k/0@ @Q"%`EˮzRxx= 0~`ZX1E.I!Hiܒ1 v*k-#ixO8{0Ĩ% LZ?7jD6OQ[dڢޱ-S ~uxd`s9j1<c67&@߫G@@8ueР`KPpbYmdxN5Apj2Ef$d+I#a1*EHKQ_MYGt$Mz&۳1,="66vp5r'`@`DRغ $ | +06L/y(gqŀk^ j@80)!if xi[ q~h[ +J#5.rk\KjLҸUH-q8oeQw1)"4--"!e& 8+mX1Wwe :1Z73̃&"K#}~.Z?~Q` o|Y8Ic]>C'Լ2F% `Kj,8!-bf=}p0'#>ěd~8'I1B\I&;UX LOJ@"Z&)L shN&s*m*$P 7"6va<C񖮣*V02ܮx'M!è8^W8!p[GIAS?HGO`2 xӠUA IH_G8330\ƀPE A4̍B1s  VM8`FҐq"Jbc+:.T'U5B ,p-{I7+F $q DJ`ijxV*2\ECSd-<MNk'A?X y8Va#@ P!":QB%YD T-4d&8 ί9>-{0.6a3ƴDD*[!0Ă9g!9LDĻSkKZaOGɈcP"jCė`@Q2 ]dzw,8)Q@cJe\cE gJ$n&D(K"~8 t8Wcġp?\`9 =p,ց{\LqSn$It "IH g77: m54|c 2@!K%h6aPt~w 2cHWN02Rd6޸ |[^FjXϐTĭr g@ĥb8G{8:(Ƈ7p.m`xC.tzqBE[d *XT,`RPs89 4p MFF K4a{SZլx3īnNq:Agk - #!?)P5D>\Gp݁)W) |мtwIdĥ߫L:2gl8 w{L&X M/_66 y5 CWPCH2K-<-Gvj \yew L0B)a`9$",AÒHLCa:28X;C<{t^'v]1 \ 3)B\`g>/4\gs9p9s_x 6.i86ZMd:t:\TVZ\Y9z`KMk kk*TWۃ*46645-4-5))4lkjhYUYOzFg%]U%`%_`#9v>{bdU.([LvV_TY6U.}bɳ0UeK4 V4z$gv~ \Ц$H~І:e,X/. 9Ki5qfO:༠G/57mpݏyC%Y01;6ɓ^@шs|R3zǾW%o=;;? 3@ ?柍7p+eBU6s6ra±)g!FLMiBHKZ܄*3~n \!Ly Nh] lC2&C_DY0Ф`tjh3cca_xV\Ka'WMYn')-NQD&RF>.uկ5jw5)NH~'_9Й«茅ò/0!ٗ< + ) Ghw*=32vPRh=e3PY׋6 `R O> }߿)ij!˿EjER#֌ˏ1 }#"? I?iuy9;|}ch\_Ke/,jep]#@|L=D)L^ZY;Cw L0z$Y䳑26TՍʚ^2&/06֥`f-a(漅TD eNP /j3vgyz~|R# kO+"?)QJD ڙ5Z) ^dX5:VŦ}I#FH`#XNS)cxMȬ m R#{Pd VE>Hh`.ZlIKJaQDU}6PA _ e蘻[)|2/HY7pej=6&p1uyucќ`<P=N ɗ[Lk&E7? ͹Y-~VoqrQqM`qșX8vCxQ$MWL,$?U ɮZh+yvkh}a)MFDƣD lp=Zi& ȕt֪YOX$l#NTz 5lଧJLvS$*Lw73_=d.~;Э!sU J ~@ qYzi{o FڊFem@uv%QRMB$fPx.B~flo[2Ȱk!!eƾ/I̳ww6Ѥ=wc3?ˊu thz ><=8_S/DɆ FDz96ڈjh;Nb@c_":Op%.W.ʸ qlſeccVm&RDW16iV: FchߺYcR!Xg?&P~ f;vrRi`=M=Bҭ([ [Ҟs*&7u`\y<ӨV\ߜ}"g`HLLN;+=قO5F ZTS%&}Qe yJ2tdz+0ý?sV9:?Dw7ZMR"d hzQ`Tt H6A@ţXix+yvo Ǿ_ xKPz|Z<6it} hM@7B ]|cd[{AӎݲI4iЭ.^`BYQhRSw-Kk `A4U+bj`\TXS8B*KJ PL*@)o srAzv&mDQ[:8i IDk=icc蚽SX` U4"xUU̺I{4f"}U_ b7yE6$؞"iC*z|5o_[m'DoIKLQAX=,'=i{#ǍKʰd`0$ FBR9JejMY6:g >Bi/"^jB2PI3l;1zxe ={c时9r$W1(?͞O+@IzEp @/UB3H/j gF=$Nt$ET-%'0@3~kfΖn VFD!>@zx;}R R[gqnLg! uO9*j*:=QIv-h#U]x$BWkiR]?~= ۣF$$? M)m tQ+fCornj^BH} T]Q{NgGb0O^ O~B/SVةy~3+1䳁n?68W1ti4e8 neEz*WŨ T3e_BnУ1{eሩ`dT|g꘺4gqV2>Y;wv6NWξ})UHhA6uO$_:-D9ŚL H8_ }D鵕4ܟ=Vnkmľ.4~n]&/yov5kM`Dzyg87L,I;k9xy[01E>/AHV1,R)ᗧG0fѠH7N ${ k+a~F>(x)h0\O{5/rk׊nAޥ4}m58sJ)a,ql9FcIOFCxy1]9HOxLTx# AkcqZ#2ݓXW4gMB~X446&P&z' =WϖK6oH Tl<ձ;vflുyua[=>e$yh%Qp-U'y~{h`@$M5rED57cF+T9ZDc͠F$Q9O:C8HW?2g MN FHk#F+&OXϖ;o^3,Zy*6X2 HBT?#6?z~E%=BU/g3Zy,MB^G@%SCb.v($R?Ҧ#@~܇3is(t#T|2vjixoCwyR(Òz`^IUV#(? IdCTo 0ա , ul|^Y+M> ήm,Ӏa}qv=[ø*nB.fMTw/E:wg4l(XMI {,J AMt8/&hRоQYs0BjW@ZuFףRVH`c픊H7&v)] '5_AZ[G{Sr|`FPȩ+0EgȬhJ_ډ5ܷpW4.;SiA0dJzoB-<TD"vP:i[cФ7LQ/<@(3l2v]u-J/< au>`|Ӎokz ʲZGH"]* "@?FmGo:g\:p-8EBO>2LTxBD9xXTv FH{$]Jc/&Cg6&&c&@"JBc1WG?X*fų8Vǀw2}j[D9yM}2/sGz,k!3ܑ>ީUqr"Ѕր$t cGBS9 2 2Zo#U3*~*dYk82ǐ,.ҰD[I(<ͳG8?7Od_muz;"^eaO ?jh/vm ʾI<:ю1a̲;ytxN~Ac1thŻhYu>YfOm8GY:x4\ CǕu<)ok%%>ğF~9s11!J#ݣgt0Hţf &0nJ@ VD]CS?uB;XqYSvgNB>ɈGR$;tP䟗CmVF/mz> @}6 w~9ێ}2%c0[ݭS.A<)8,{E1fpnƲ,6F^?4Iwj;0^dJ pfd/n؜vlo6,4; [Fgn5vm[D@Nbo8d7mo~a!A?qIu;Ót+BI䳋, m]HH"5PQ@~1uJ ع|\I>(3~k4[1Am[ D Oc_1q f.'rOu0/k6%_@%-e^J'i i@Agy|f/vQV 4|ps_d DH2,ѩ$zgjFbưu CbͲ | C!\A XLZ@@U<0T20Y=<GJ\F>e;&5nJQDWSnBw`r׀8ӛт-G49{*2 Lo2j-Ԃ`|?9=dA_iVτELHu+xĈ/U)1sJ{A79$T5tYWФ!Jhb}S`Edd lD$V2(?C*C 9 U 0ti٘2m 62C5i'yzSӨ׹5X\#UqP  `H:-S@0 Xԭ<afc B@ӢCsUg'w8 rTgGGUtg=!= D3 'c^0a? HYTv+T}zW y`7g]>Mg~O> XV+fMWv.vpネLta[wƗd-to۽QOy1#Guxe> ĵX ]nk;Na"mP7Ii-_n_{^B4fKq֓: |F~<j6p'ʮ^Y?kͭ;uI^qFX')0%Dι,_lH$z ϚUVx^K y3[=yn~_b0g=MpmgquL-\oYN|'6tS2>?P!q=ʯ=cw 9Z.xDE`H7;Y}b%v?Mu+2`=cU}V}iqgGbVX[1xOR:4AT=/.jAqȫ7&M'vړxq8z|=;YMB-Һ,h?4 2+1O~ g[90"A:VAk6zw*^['+!1?԰-|Ÿ[@t~Itù{mК%{,2/aEԥDC 5NK'z'ح>ȧvbZH*=z1y/cD/t;@·D3;ӝ&~>4h T 3Rkh͏shp vDT>g ρ޵iv_ISq`MMuī=g/ ? ku]ʞ[\{Ń 񧊫w̽-;,mfg;q(h?7G (7 !WSO^fMxVa5`]؆.LUlݑJ%+س/8ӄ<^ ^%+T(Zz&{::gw5! 9 il$^r\(Ui5]T{읳ռߞ;B2A xؔ"H=n8ˍ'8L@c| gxIܵQ0!Ng(<\+ 9Z: 5v)۳r%sG7Sī*pcoQ9} 5׌8j]%1C!+kAu1E@7)q&[l~6i4 7 Lμp%/ls߶rPMqGH?\~[y84S#ܔՖNpgvQ(Iۮp?Z?܁ԍ@`PzV@FjI|2gH0V W3@hxF͇^Y_;$Ƶ)6 (xkJhAk6_-ENzɪS Ϧ} |nXz8az:]-JnjAk {LP3&(i6 vi72 ewItvyj`Riq䀛6s_ ώ ? <]]%^MQfTL#2AQkO}f#:OḬZ晣! l!Z X{k{ܸ`,g$ZjNh/cFUgԂRAɹvA¹=ϡ-m||T!rڄT,P㐄,^]gt ˯%Py2;ٞG"k #Q}"V}Ճ;1J|{XһqF,a1cU߆EM%K1V.@ Q),.m 'q4b枺 *(c'_ W][F8.ʡB+P҃&JygZiX5R@9Y:* @e̵n.di.3< -襶_&RE ;5 oCq.Ijl@:#1'ƥBi15@Wu CS U@E5_rtqa^gh"kIyUqj-D͊S@# 2:!ƾW,H\ٴMT]6#bK 5Do+> oT_AT {\)M;#1: 5=[Mse%V+ @q@ P;CR̹AJR3EV,V hL~ ̭=Hw(Y}H>wW{\qA?%ω/:JJuJKUh'5}L ;!XI_La4?CP;[s>ɽl*/=20obIa4$˽s.Z-F4ݙP;ܡY;͢1:J&m>#:*fւ.3;XjZsw֜1P~J/ 1P`hR{1VBU:+casKR" hrBWPh})t`1_! l11Ĵ*4E_7DS Ѣo+I(zOS q q81y$iyj髝58=3`hZ.r%رe?92oԱd"y0 y#OO?ala9#dmul!DŨ*Kш#@@L Es=[%>@A0@ a0HA@ R$(5v!&1zٌi4RAL bjd52 Qhq#%Mb4pxN] |J <`8x+>EA+27zd(|u(/\Kb%]2YGkJ@Rfa&Vd^ʖM_%R@)FS{/=AA6TaS p0D*J{E^mnTC[ZlV _;!$@*`xMQ"DY:^}TLC4 2?vE+dvXۜQX55)R[x,vC<}IB0Y[8lC1`cDcԂktH?N(7L] GM:n)ޞ":u o@G; #K&xIO'm9TkpQԓޭD0YOk'`?F~7CVә1c_X!e gr@݌% ^\p7f}KC_r[GW`RHO!VbsJk]Dbo?"[V""AgF&sUgU=Z& N@_-:y{2fc`Yx:jNRF^UVئ\uu!fr"s2z+&+)NO{I&dmGM\aبEkQ+uG`!rƺ0ƪc=҇N@.-?+# D(+f'n=Pyniao#yPbli'w_0Ɛ%yա'=8;wQO# ,I0>@0 &ʊ[ze%JLM|Cr6h23=Ni?%͛deѐ͋yxw`#k ~&tIZ੖顉91,uxQn3^[(? NXj _)nQtv'jWDȾ@ ,\'beC2sxIQ[mS) ^"324Y&ؖ{o69xƫZDb%ްu^&<J\0M8D Qc|_ kd&h,vyp|L}3r}EPƔ] 9itzj i)be";҅ҐC5 y{ DHȉv@&iC#c2EzfxK{({k >s~f'_Ļ+Pco¥Aב7БKuTp;slţI4 tiXPtOh szI,mIXWk5_[K]zψz6Q9'yܴΠ2ݢ8u?L?5ӣ20rّUЩ|wv=kC~".t _ӝ&OKNfFlQ" bb("Gt1p-\A>.FHIb9pMm*t*'}#A/uVѦ!'>sUGD] 2-c&rHo-1%-c,g.Y5^PY@'o_d22F.pQ-ڵNvɣb-Nќm!Z5/ѕ5e oF8ۍ:JQWC$41I>bF^hU>X0#n)p5e')"YkN(^g¿J`ND0@;FʛpsD.y%\6G`GUiS)>ꙶG+ |\摝 Zh}hFjn{w*^6BϘFns#UgP MDXlߗ k҅g/Ae[*4'r$[+:4Դ*\Ìsx@(e*mXM0g  0:(;;[8x#D *>@dy^)hOh$ $57DB\ ILj@H4(Lw+T~6f-ޗKZ$ģ=N/*)4 lqMtO=Sn:Y(lsur.]S%*FeMx(YeM3wԉ:nB!r8NKe;?2',# n4-8aa唛ѡ[0z&9Șʅzn:k4w6=5݃d[;d)>wt`ZmD-XL/ ϶Q e3 %D cGS?QP(Kd[7w]M$S. hyJ\RJK3NnȒF' %g C !B!(kNo9B‰Ho EҶ9-Lܷ(- u@*։G0CGUzsED~q,)-lic Q@F:RJ;EC!x5x?:n^wﲮx-EZwYE NH^*ؖO^UxoN$NG@v+W{mV+STbo՟^k֟)Qҧ+^O,/NnE( 2ʿ/q}:jI 0nIN{GLa{2zGZk3J R[N`mO8?ZF;׊H!bkg};Z-e'?) ı~S+UZaN[~=<'YkFQߏ%+أ-hKk|p}XqRNk9=^ݭlX%Jlҡu@': l-蠪a.k[-.]21n}R-V;|i|[}BqmS :u݈%J RV?V꒱ވ)uan?ZmGiYbkƆUQ^ϫWƶ5b8ߎ2k.Q8sH)OOJ*{%hᬕ8NïïrO >UoAKԻZݺR}*߲v[ "lǟbd!m bAw ^L]CJ]/ ݡ;GLcۏ=-JzUݧSv*mً*DSni[SJk)=S%Wtt,w68PʋjY~ˢ.?oQ%|r0oY%0җrq )] T.O婨T </OUT:EXI}'d9`B(t@Ji, iQI l sQ sa. Zk#^0R~lvwww0tVzc;Z㽗(LS)0V,#(L߿2Ea2_uH- Stbgu=bkzEalT'yZYǿl n_rR]/NN6~ 7nD{* O(O ,TSy*O<՜\<2vmOU6SQ:Q><5I1P i?xKiqVl/pNkc g|;kߖNcz+{R mkw_'7^-?#`:c;TK}ǴeuԶlVw.J}eWkym?z8^+QuEU. ]27QB:F+@VޏAߵ֢@/uVgn[TKdn]pu*(xSXzU[it $лGk>ĵvTbut 1A [vwޖuĕIqg]N;)Xq_OؾRK{kq~cSW:oWbK]}vv?ڮ}VZeΗkVy{mMqWz-YZ;oRV[mR.-eM|;k}^IrS6t/OS6})Kt\N@)?祲6/Tʋq Im׽~^9{}U];[J^c۳/O-~^ܘrMK~Wb'NU~|9N[?'IٓF\ v+g_-m\R bw+j7rzuӦZgŔJ ^))KrVkպ;Z{}Jٲkc|kl*- }w~^+>tJWm߯_\S)b)㋿>}g*)s֦T;-:e-޷V[)ۊ=}ko:η.im|'O(S6S<6;]J~S1\`NoCY]76\>ql]g:қ6lO_uj\}ZT~c;]J'lNP+sֿVw~˖Ni߯;rzy´ƆӛRbJWvR;G[9N8ePCQ||8qB[_X*lABudB4O(F94q] 40w(_`hLTa&\NNMts;Au wr pmpԡ m1}[qmQi%DчqFƁ^:1K?cC+Sҿ'}jKJ!'(sDll&D.aYRc߱9$ mB[6Lyd-d2GBa`(tyqqOЧѩ1:lNC :|9.ONeD( e 0eXtqe PIhMZpNL6дL3 mlyBEhZSh0_q&"?PD '&݆u_y؅¾ɼce&`h;Mv`!:(p[ƄpK(+#lP#p2ipb~P4ڐv0 ɮ}^]<(!  ZB)a{cR B "|#lr(_pCS[.2>QyYqpeoL+3a#ЉЂ#i#!&@ -Np!6`C Ӏ#] e!'sGz+X//e/*y>}Pl/n1ߦv⍺y*OUHwE`A`QuPH5$߈B2ѐLzX"( C(g轸t,8؇e0&É@KС`VDٷŇlه}dqn4fLޝXrV:YJ\Ye. m&kYG8}Rit9öO4-oB2y|4y9^mHHL/d;PЖaC[F??0]x3 Tº3}'vR޲.(Ƀ[%*`r9-L0~[.H\d80X[(˦,e5-ޖe me"9G̎r'uF):. :Q2u#qqDvd8̄aBBM~a 3Q\ ^e2 ܨyItH[5Si'<ta-B?:)~pFGPp M`/xX,@}^g2eO8uL$Lؙ0Yzdbg2dL[HPp>EuQo LZP"LǐmYL&LQ H*L1ԁpEd:yD@LMaH*8S, x7:K fCC8LdYPz@3im=2 e߆:d(qO$B.0Meo;L&ę<; qƁg*NIk3m.u9B&-ReBQiH>Ƅˡc ,ȉ-8.O]L >iҰ"L&NcT@xXY`mxa/,tB}e8e#&l-@CjZTZ/{%klL|:a8,5SAS )dF^aZב7L||aerh@H;Sd-q'? MuB>i߉k-OevBC ״'i(_~(_;4)W7煎BB<(_iec} 2Y`0wy.|;H+xBYq,0}&;N0gx޻i'ͅԱ:ׁſd/A6ˇ2tP9i+}?fSoLCl.':0{ 2-Ahh@@h|u!$vL]&LG_(S2g*U|]&NhVo :B@e ԁ0qCSȆ];pe /,.o0MM/w t8N N}_ ahtY;qL"}q8-s|[q,턉rƻrg1qFoqxPE;2}8m WV2-`_ݳ4ޟOt1%5`M b.B|a ߉#sR3U3Sz*yu: :)0Psa 5`BؗKD^Y)L{ 뾒!´.[\x![}D78m'(_%O ?Lr2Y30o} &>X_tٲЖ}$@T"u9D¡3R=Dgpu[[}Nz1/)ۭޞu1vZL/nZi):L ~>ΧpDr1o_ǷwJ)8gnyדּ:[+k|lukI}bi)=s~u[JKZ)_ϧ.-/cuNOZ^wJLs֋%֋)rR6z%.-ŘZkgVzߞM6vm;R:pD(X鬗zΧWZo:罗VoS.C8a~B8uր$hdAMa@UCPD F)z B!4i *P}©aX\׫4l$*Q::L#7d`L.'e:(ʃ|͂LEYB `,Hp)F ,$q1 @`]<S}0>.xM{qy Q;Ϧy<2ydE)HhʃHCKx@L$pX"I^&y'$LX"A-0::>:> "@@hLt>2*24(aH' (E)1JqpRQ!2 N"CE"E/s]&B1=(χG,B(⫼EE| e<,Wx)%&P^(H0S Ӡ¥ICC^Ie xE"c8Mb@;i*zļL  <6n@p(_ *D$:S(cz ֆidUCEp$a*>UĈjlp&\ ,V:"dL. (^0&b͂ ` NC82Cی6*]W}:0Qz9tZv&q050`tSnXp!Ȑ°Yp؈]H>ﳉ:>.?1"ȄID&DgS <"E$4P@9bpEaaL &ǂG 6T8Fƒ dcT$+JB$$OB8M%A,<#j !C1 P?Te0,gS|t>:Ec* ƒ0x˝aΤU `"`".& 'U0EQz x' h FS`ya+r9x*LB}.8>PTBEbaS\x%~<a1zU$eU(+)$e1@Dž[}\.^,SlMERTLڄ860(dqIEqPB~*ǀ%&$$r>clh!"B!0. $C0@jM*YM IEe>0v!AԜǦ"pܔ$aa$ YQ *, DBV< LMNɊx9 QWT&%9.QQ q99xx ?<C&UU8 'EW,`+ "lT<\DDX  !QUT*BaHEu"DC61q5&H"AP@4DCbG u+B 08_ )a90P+ P`d#V4 m|c@E55bVaP bq%G5x tfp= fJP| CgEJ6i( dt`(uʤ10-7RYWC62_2*H,`82 RE#$:"$@0!U$ p?m_XȊ(4`y1FnH}RH@2( m"10U48:sӛJCh X<#qXp& 6>'xQ8fyLT,<  3480!H  J(6 8C#ۨ*jqJT|܄a<|W 5<6?U P \߸Gu &@**!!"L iy)`xŁ0অt`d}*HљtG*cШn:ZѠL `#PDxHȇN"4ֆ 6 bpQС:aԐA#525&ŀ-0A$3Qy x4x  ,|,!BtF݃͊ޛ t/ D`tApPG" ȏjs+6(f3'qG뼫2 6"y`@ad*ypagAa- J 6&-d'TDBhf0x(ʤ VȬfP.zVD.cHRGq@A(AXHݎ˘S8"^ ?RX{`AV2F~ 2?eM~c woe{/.n=p]hH^ɝpj4&mI\{w]sV1QwpZAoZJ )t(n#qO -B9ž =E.ož)03N'4/( 608k@%=&03!69m}fЖe$C[Ik0 endstream endobj 20 0 obj <>stream ZKOna9R:Uc>,,¡#ycGvT Ǫ#2yaWMޥ6+P5mԘxͤO,8!Dt2hVVd4&ozբY*墻R8V#2:$eYt#P]7GG7Ϙ(#id$ _"<~t *nUҵ؈_ FgbNX"7!HZFaǶ3,Y[ nIHb0) dƧ>W1H9zs:7ÌZry,^/b zZ#IULaf'&@=Єv skAĉ@UY4kV%a3j0#0[=J\=$,ejwа*)Irfm ^G MsoSw+ `A@alw4VG\ROe&%D9 3-ֵ Xl<`&0Sl%ߑ6&*wee!;xM.8 a"IXʹ8BshՅ! XS - x\iS3㖨#X|jI6Ϛ]0Ӆ̣tkm%1JWWx.f䛓y5HnVϣP[5H8PUػ+ӭ\D醉[Ontlϒpu˗*3]Sۼ $sǜ_޲ »7 Q n~i2^ c6kBȒnxe8*g9W+$ Y,6#Ab쾧8w?-d'0gq]R-U)axF.%.ON:s1sPOl`q]1_I ,8'[݃b\" T9~T`?TT""zVLkltJGdIڷ|m 0:kPrEa6& DtKfdf8Y.jD]dž,BgyE*S-( F0|rSs Se(u( yM<օMO/m/Cou\ez v@LVvf8Ŋ-jy|H ~SviD.1V?S%L+[(Pt]-g/GƎ9ZI?yЬ=VXlnK}IԼQ+Z܍P@I^&53֖ IQCjPmƯ nZjiݽvGbpZ.ݰ(M>,/_<iQFSkv  ^x63Y=Q|"_/|<ɇSieG$_m=8mudRG#f"䣖 gzQ QP, $DW{)dGA&AH4)pƩm TZ2#ȁȖNhWDT nDZ=lf"p>T7m< {9ɗb\5)5tTh%E5lSUC C&YR4mFUs{ݛg&D{W2Qa}/8-sbМ"ȩC!j;_E=}yz)-Ըgq}S[BԾkRPM1Hp.I8"LJ7ϔ`8[xәIUTj+ռ͔Qy y)$nNxܝpvq=< v[ ޾TiC o$-$A/#WkVØumf"}bgF] NkB D%,0+,ET^B:%Y-ڴn;aYR? ݳbp)e|"r5m\@6LڐeNO}!8S942]8bQa7q%'`o+$"91gfgdSӔ*6f~RET.9.oO!V  kK<Ȏт%fCe)qYDP6ݤBF,W D5ڿ\7dB󇡇',XM8we, XM+CpZK1qv1#+[Xt ͬ>]7m1NHBf{̐BL.@&[J.vCԄ@%+ڨ[Y'?z` oyՄQ: /0lrB!&Bԡ@i'"e*Np?>Hq! 6wuq=:֤V|@*qM|8.(o-xwb5zEhcY8≌,@ʫq,&&Vb-A!>#@AMcpoږ#.ѻj}G]V)nUIkCwn*C,c=EIWsbjT88Q1Z`w{ob>A÷T4 @Ƅ)M ڈ \h4An76.6L!=9r[W'PR*a 0AR`?~x01*TqؠDTj(@ ijT%zbi!Xď#2CH\3G(6 oYBd{n"8&iO'XR1!?Ee`hÕt?XZbAeTǞFkȷ/T:454A{ɏ+@2M; DMU3d "6iwyqҧE(E NPV4Y;MaUEdFX~#}p̣:aoZ;aral+Q}+?{z qaKL5<(9))<;tMLq0hPA=4 \N$uYy쐩?yLu(¥mӽhL7ƦP-uqQmu3:i Y'SQS.Z-W;K~۟×[OwD įq Aj:cb6ѵƵȡq QhՎLF@l @ݶW|@Z"+LlP%Kyjp5w 4 c gxj\lQvHG8}rZk`lV8$ۿr1 #jK'<%.|xRj >i=kPT5P&Kuq+IZ{lЙr1#,h 1~A[Mi*CkQz8-K/fbagaEq!Ӣz-뀯aϡ qj>w~ӷ]~2w SY h_Iz v/S 'IB @$ Dzqam r! 8Zh@Pdm(no~ 'TRM9 hp\/jU^( 1oTAu3 Kɛ\DYfN2تS՚jsyeE",3xϠ/a8'W:+D )oNiC;\ϻ+\2~Z~DHA*PWLNUi1V12r {2I!is*a.~2褪d:BX"HDqAߝę p~beKʥ=+w(z 0*5hF[8䒷XK-ʞLiWYlD$fj5ρD_s#{Ж23`D@>{P|ҡnQ';[SڵKh=pRB]YY%/~4xƒVbbh\# SN׆6JPKy~ݙ#F{b:֤@"*bnG 9bQ6V wRܥV(ч!(Jut1C(15*7ntb㶺b9UOϊ4 <an[UVaa/]61"߶5 c趆dM=ox?, ={{ *[ iU RQm2r.55GPy3' Pץ 7F9qYXp#7[Y%;!d5U/s!N'/]BPz孮XӇ.$Xv\\b|uvS,0GW}Ig DzGÍlX 3$@t6"ЦڬK9GxnCEl=iy<׍b)Ĕ }`ւIlYEHX2{Kw) NҦMFF# ݆+Ɯ}ZhvPECƸ%bw7/:Ck 4xQ@ҖZ ~>fZ7QK>a%z+ !n&d`iF,+5)ᕅXއQ$QU$ $8KH 0xrβ pl?;A8dlJrS8qpֽ]ޑ WdPy@}#eWU1-wcK .Í=Ԯ Z~'M;E9o(?+S_2.%:[lY+cKboEv3Brt֢^°3(!\(z˕9@1{Pi{J7 CIB6kn~N<[Hw@xy`)/ϏXFIA!2p9iJ VTy0U~e2+F ,>ob4` ۏ2GCF"&m`; F0qAJš E5{ gyr rz j9;Υ k@s (4lN^'4Y>)I-z RAed% 1/ `õ5Rs.8g`n<9%3\&fIAE|>2|l=1NUg^~wE3K UA&gv  -?"~>vbkVJ ZʄU'&SܸN2G"[i<[ A0QDGyo>e%ďT9>'&hGK`8=LXDOFy8Et8 mӣ?L!џ*3̥.O"4+E9@1-s xtXe@M}v6Y6CˋZBP+1S@.X :F@Ém98us=b;3ێ+q 1,q,Y@`VjZ sao gcc}v(baC.>0@p0d:IQmU'A,rvʌPtX}bL̲<-a)/DOHffOzjk X }V0 4VW;3"=:O*cyw`cʄJ"L hrJ"0'@AsHt18 m((JssV )|O ЫzuEsBjLDQHL\R&ALFA~rI.=NDY= k@ "GDl` vocv%_+nEL(A)C5UG$̈́0 <794ZJC~[͆\k=kaN缢c16=# G,r(U[P_9k2р}L7Kz~ ? 4o DŃ9'n:.,Loاe>tu$b=2"H?#Ѧʚ߻nUCO?q@q|p-oEMֈK{ rx/BQx` nr6= 9 *fq0+Ŧ|F<|ow鉹壱cZB(Ȇ7WYs$퇪>`]~>yqk^)ub1iKEuChPFBm'FxB'Q?#9,%IW1x?id+hha7yy j |=Aw03e|c/YJF#8.CM G7$ Q4r30)K"j 09OHB{KR\/k=Y9 Nw{ܑZ.cD<ѥ!!/Wdf{'J$x채HPpdxsPpd'|hn#Zmlxެm#UGnM6D6 v"g{_Dmq%G0bcz;B^_-ہHn2 TJXB/ה!&AJ[O JBF;CLęwLWm7>T7B7->3R20Xv9lፏ U +<Ո>mxO WF֕yxL.\)>-:%nl60~l%4[ ?`AЏrՇa1Sk'EY%*teTl^C?'́ي5 !.GqqVY]r~eٯ8}0e+Ղe'>zlI׊|3Ӹ"ev6X_0 >FB/ K.%&5Ө-Ș]tJɠp+ i=z1~t'Bá vtISkJa,\넧m9.y"m)Fi5Pǀjcsyc̨!r j&yeŰeKҏbj$@H|8/>7/͚TO2}3hb_CBv]㺰YF:xQfPnfj/)EY8kc>H)`1n_vGa71X,nQrJ !DJ(]Az[┲M3%:9wCb:?BSSuNNoSND\1&_fKkZ4 +Rp,|^[c\$C(ߍ "+բwjn(\[G9}N='^./ ⶣu~E bO*Ahtiz)ԟI}si)^2dٞ{E8PL/h?s>{2-bA&U [jy|^,I"WF2!uTOcU NHe MBFeߨr#tnc?N!>}6%#Y'JcWY=:V 5X*o/Wr؟چbkI ̔wP C Ċ٢J%\d9#"ȅC˲7pF `TXS=`dIHo 4E-)ipL[&pgo8(NuCM n<ϻ.3p\B0,@tEg5Z'X#-5Q1WJsrо*~m pc8KiswSkxI3t2d@K,s>叀0 %| ŃpIHdL̮7D`h Z!k`mD$udriNoWf0U Ff* b_9xvgIGX@ڛ()\abUj Ic}:X5}>+ ví]uہk wcᎤ^B&H2;ylr3"YC5xOȞe A,3V7f/ 4"PQg={rt#5P'U9+&~[iM6b?ă=Dyw$秖+ $2k?2:Whn[Ⱥ֝|jx+شB؅/# W νoS1f6J&+mې Yد" 0  oJ@t ,[O GDߧ=wC|I7$%|ܵtH + ՛KLWEV7ڰ;KE>w=C*YI|h,PKD޳&BcHc$ N~(WA(6FaHp$>[C2CI`^ u#ЕO=: (UV }9/R2a.ل'~dBe{D74 ?xc_ lBHp NZ]C`K"YX^Er^XБ\I L% ayHzTtϐ émŨ`!'Z%d["VOw] DZT1p85htsL˝ʡjVȘY{m5 q'CseQ0]?Eͩ;b[OԄMnRSt뒼;+۵ֲWUVU,aR-7k YQk#C) iX~ԫ\M+t*,{红 d#߃.]>w``执NR]Qh3#䴫Z.bkrD)`m'`%C@ErTz<&=9.1Ə;гݙH,D=YK_ :~͈̂^2U 8怌q-ԓKG{?Z4&V`]KVT?:?݉'Ӥv>RY!\~"lX@Vӗ:Uj{Y1Ͻ`AC fť&g}Z0`h ==t? &068e~}PԹqZRݾNJu32ᖱ$ǯ5&vD[hƘrky1'ͻn;8nX:(Hc}zq>1 R8o^[H(_aIBC[myhߔ˷"Ӻ6U_^8nUvgN#~⏎r%?o'6;O|ßlfCZC`9yH@z;=j872>pܬSJ;zeSh"r4e 5Fmx(z ?~םc!GXn: ;6+D?GKu!(6 *yi#aϮySF_oCQ m]ARo̵ե/sz5fNE9잘mTe. de-`"HJ9C}| 9\=XWhqh_Y2 :-,{~fIAA ePF 2$|p0%:|n+,~B8.N֧^0AO;LxQv$V*JQge~ ݌b"0&*lwTM5󄩡Z阯-I1Jl)+譄/F " kBճo3єR<h\A>k%UIsMک24ފoEB|bw@uy,_Ov7^\.OsI~"ц9EKtޯ`l @uzE 3l_< t/%e5vQSmW $`V8̆MT/T+G=Fs\^nRT(6* n[S*F5 j|G8&h89N*|~xѠ%2/`"= R.>m5٣1gR-(5ʿz\OF0m-fF5K-\58Yl{dR( }5.tȳ ' ͞Dh ̻wcأޭ=^?q)-kϗ'lidS mi롾^8G3jśţ,,# -#}xF,FJ#`_1urk(ʹc:\aȦ[)5u nT[ʂԂ׵R^ - 5h%cbwUϦƛqfnpwiSfxŞU 4K ]">Nh4#(?L6yttA`]2-VXfN^WTj3,㇙YB d3Awƙ" 0Y؍|VW3H-aꜶiޏLFYy6Vn {ȘNYgCA-GŽ #%4A,.+wԮM6HC#`ަoP0&3rM7@%Kl+U-CL(epԤўE7+]+vFsS_C|mvoJZXdx,߄$`*ϗ4.N]5PJUjSTO='hAE+tRHst 6MN?:qlM: ZR1$og0r5J e7>cJG<ُ<ҢH}Ugq0XÉI[RSa|y_/jC8DjtT ߦ_CϿ/8x*T?EhS[B됟(H%?>J膻w6*ϕYu"`•"b[v Hԍ7~ٟ_sDm5y CIhIBxpd͒%Xly_#UL &vQP,,@ JiiS&咡W^ DK"6R%$"?U(L";=WveFZǥ n+j=>ܤ/J8Mdێq7 wgdz-y7s"lz6 ^ӼsI f ̪Bo S{7]7Awbq~,};9-p +Qqm6bgz0Gr R6P|  wvrxmJV\60 Ȑsh2 "ұxl]heOQ|ZR  twhc- QR|dJFiگ;+uww*::54kUFГGޚ@a  kcW$U*I*Q?o7Āg")Nc~&/<\VRF0>@8T뽽MI"0m}QǏ|uVIgY[bm&:#f,gq5GUZ6OO@ R{T>G]{АmcMR@$"Ke%Vg$YM@B5몢H'`ms1ZS矮-:T@Y`%h!6X0\oʋ~qyvt_ȃq+_K$fjΔ}/ŴĨެ{r-v?یa=)oJAjS.RO_JhƩ廉'Q㯇D:\цPqQX<@2FKFuI F81VJu*M* Yg=+o0MI"ex^#/*`PH3@8YP$ `SMTDaN)A/@QؓHˈi$a ^?;GǥCMB/i^$4qME+AǜXDȂ"G@Ze2}.SiA>/~5h"aqZ:Tæ%H@(n>f(4Fgv.&=X6۹p>0۹h$RaL:-([ ŵz OpFš ; " HkCuKj`qnoC>FQIB8EjvK}`VZMRWhlP5)`Mc(_Ea@(ĄaTzjYNb-x*!L8sd)[- t#{܂] LVV `8`8myPDMeIFIa$Rb)q10hxG%dbx\VXjhJD0A$,4hjbr< %ڇb &{P!I$`Zu=&?9*6$h@C8 , ZupsA KHi P iU"Qu P@H[D!H΀MX"E0BDdTbv|z(.ZNj㘆ӘŶx\J5$  (x̫q5H*xdr.46 0= U2Ԣ$@KQ*bb kH,@)D#B4 [AFiu:S[ΰ\V8AG0F 7CB)cD(Ϣ3TBo"J<) P4(74i w hl*iuL ӑ:?"B?*7q46?QTLP$T=a"C$ 4P(<(@h.Bt5VGӘ0H6 l5JW):*NӰPu&1Y$"M | V1:jq ipi"U"@C0$, +q 9& {Y0Xª4a4|$QZE,O51,Y>!15'([‡zPVfZf<4N'RW嬆3 h)֤6&hR<z3 U=ZB{< 倄Y,J#q " z >B) }(L #Uo TZv\xC|# )+ꡐQ [gzr[/tdYG6rMPfѤ6NgԦf>#/ 4ֹ^$6b]C4LU24DXWK'?MUjqF^ V5BDJՋRXV[D>*LB)efI$l1ȣ:mKNX*x(b- ;„ёb= 6X'CqPɁ0S"H8MNyc%-;ץԤ'pt\~6 iQ#" ?Sh!CMS88 mv@9P2i|0,1Jˌ~fU- f \^F{Ջ_@>zXlރfC`%ݤ'qyH~5;.{_nxoJ33RrK1zmL;[VRM{ik~Z']dy,<2ݼvǵg˚sww}ŝ-Ι9{rbշNL˾rγc931SZϜg~g[̴rrBN >p"a5効6H\C8xY;BXZHj!p(QK#@h%Mb2 SU8 &)J`MkJ?ia`MӋf\\5\h$Mh`i?YLEdP Ȅ8%TI >[@.prb#sŏJ(`X9ы7Vz ^2=$Wc=0pP H'G ͉U4Wa }!,XŠ 3"p]d/xv<k3 q MsѡFl?it =,M&a|HEC mY= 3:$qؙ"p]>/3q-O<&ǁ3,ԙGffVe Q'""JdP.> C(8&)ĄqQEHZK-0aT~En(DXxMFq+DZ #3vᄙI|9"aydY, l]fqj.&sb7W&jWmA3Ͼ8M1*tJeww߿ލeeS vVZ>wb[c<]өxN9lZmO+3`7曭9PgsƖ^jA<ϊ7[ϊk6_Zejm,k_Wkks}V5YNZZ\ݶڝmZ.\w/@)g\% vL:roeթXU^}ͧ)u=}e{yeuҊov)f,qO7Ϯ_SL17;ڛ vzuWs}ve}/`gcٺXcy,}Ϛsbϖv[R{ձ:i-igԽO8rSlcy1ޏ+R vߞ鼷w=/~Z˹8;͝ZVقLwsw7]nhozs:s;{/e[ vӊUz}?qLq]O^/ӥ(Řc0((IDg|nD.8D>2.8aQB SLIV* O!S9zjڠ/1}qȭ_xW63PlwEu/D8`L:P"UT{=/_^fd,ldQbS@9 e@okPp( u:3 +\fTf|5 %k S`.UϽk*?Q*?g$:UF+1{xQH\H)B~ۅHv=PAefe (8 CLh2K-j\ص7M8J0gj/:Cq`ǯFbׁ Y`/e44ETK\DB/)EWv Tz4=FZҳC)z@JO0j HJ"CIχP T ?'+z>@x:٩ ~=#8DG4 W<'6Q7 .I&i=fēL+z!ѮltU߹yRkolXIej0So9<4+<$mŸSSR7U C#'ڛ#D4cX3b%4nnȱ)51F $6M2ؓ/XrGIS/] 멱|УZЧ0 P9d?>yp)˜&(־΢!rJ/ukOR+0}Tcl< Gr.}sꖕK4l H.+ڍ؂"s{Raal/EQ^ N6 G͸de+d_|݄ *?LyJV̽ɠE!A?%3^Q|A9Js75H{YdD)ipEƛiEykqDIqݛ4j/M^QL@B_h2܌ it@d3QiR7cL15!VT=xY&:r*iBhgE0 )V)xu` bm,qxDTMh(fi)TQڑ8[ԳaR4CL輍czc{#1F a;?ƩܟX7]/ѩ,/g *b tu01N%"S` 'Qd ;U,J7/[g05BO(Q͊/T2CM\ј#J;Fm˼\Z A*G}E׵VdgY9HZQS,9#t=&Et@,4@|8'j6>{4swP!`*B ӎ`Th'q́S۔y^ 3ztBk^ X25UR1 Y>eǶ"[!1CM[oSj&.2pFV`>a/5zj5Qv=&$zb1P8B1GD{ezϸ/lYH&ܧVo"BM zʛBDo̽W3Lp4[GT?)65ri`mG' 2O v7WIK X"UOad3 wϊ2wC|m@ٟՓXu$I^QeƍЅDlHpLy$3.jQBR9;XK/PqpUN໦OH*aVsp]d+3"_N"'/թ~W$r )ĞDD(Sbwg+)K(ңJPX`3̅ci;@}@0LAVt(9 =@a)% G'bZ#ك鞛Ql(黦zfQ ~M8P+GC`nNH2F"ؼl%0uZֿgYШ@q˹j`Ls&f#&I!,Dy8/RM}-D2\ǹXXFދPWp+F0\@UԬD_Η`7r;d<͵50r@lGGmِuk DxK(.EFQW23D?:\+LT4IYs [ftɃq8 |K y8sŻC7瞃㶲(WB3F"8Hq^BA cdKXG@1UdDH4ƒUoIX{S=p5:fCN2!R^vv7UC=5yHs6v.^{QV?aJ*C`u(РٹEDyP|^qtݒk7.#܀'JnBA4|I] idO )Tu, ƹ2sO g P##ZDxb!#DH?dV8:=7KpD]8|ԇ^9!kNZć1zLs._I5OSί)G!9_Dٌ,[7L^3 5q׳5)_hcCB]ع ѱ&r1qĵE*K=SiRC7 -t r0,3u|m-kMOp qjWi <>"tF[UƆV01P”.n "v`C{Ld`LP˂s@fF7ZqQb#2F&jBR](+/VOv=N~\H\fAn~\TbA*ԌBh0R-R5xt} #6VZ\lI`ǯzXlH2V&$|B`TRG`LAk/auyuԃ_巼A(rٵA]ȱ0UA-(jXFa( ͣC>Gb՗|*I~2 GA|?2j.11Dac[UOW>-‡DHţFuQW/sڏt5^@#[F4c9!;n)%=Y"GOp%e9O%g"hwrF&N:R޺2Ӊ ـqFMMB[+ *E'e.aJey7 &K4_%%%Σ34YeigԿqlgmwߢ "x*-xDxy.` 'IX633-F#anj؅+: I4&-Dl9 *=3K^~o 5P%\+ WMQ~&@Э'Q[^s3.OXZEIF2o~<,vU(!PVuZkrk Gh׳ț]b\rQ#竆Aq#0> z!\3mɖ,oI)Q(J_H$%cG Qfof{m!|P>n*wMѻ&GgBhq \^HZ{FDgI#5ǰu䬥R'qC)?wFA TN)ԩm2:kʒ};ek8 dxhX5ޭC1FXںFaJ`7ӂ-N_`|'ȈK3$}OH֌%3VMts]ݫ> 6"ZUPO 6Q|t;&}t/dc^gDG$gלϮ:ZX&z !҇Z/M'0Ѣyj3Pgi>ɼB'C"9{&S~+ 'R)2Ul {:bF8QJ=Z )jB*4MK@P, lQHOC)IW@zs-">6lƷo`)GGB'b_1CW׈xGdQ".m%Kj+^ aQͩvu>B&xĩk<=wV4gqV%17\  Y)xv.>gOSsx Ĺa5vSx khi<D,h o<~X̴NQl31 rSuh Ⱦ]YZ[t{Y7)2혔|è#5X0&?IqSioxcᆔAar3_J~(GcG!RY^1kfecf}%u"Q c}說]pJ\Q2sR 8Bݽz A2eGs 3nҕTU^k7Ha?rP ܉ (/9a-Q/>K!3WP0u1*ANRp L4LUuN$XoJ1S5/ƃ$Ŭr~oh/czw+s/ֵTns2-?)= !Dx SFM`c)CrX~i Oz518s=`{:g ԣ Y( WS|8J{={xD1 v.]V[%pJ_ #ĹYFۛz 4^=[yYKſE(ϯLY_¿d^SFLUh{C!"o-#ylenw-22($bzOՅj~_n1k4y3$e,*uvh\U:%?`jF+eG!@tХv;ں_vZ$=56@#P 0;T{LeM`⣼R1F_U&n+4vՔT %Јv*58 W[xHefZz"[Bd 9`[0v @T">c|>)$ [-M7}GzMe'͗D|Rxz5 飅@a7H5zҩ~rLÕz5ɆO5h[ PDRoIՑ͛(]Ⱦz|hT_k0% N>cݝܹiAe8zx4t]/͑m}ObU2>lUR40JO6.Ic~?O/%KP$v̬P*aR,c)i5pwf<1A]wPQ >Uq >qY"L3.r-ЇWْZ 0 .T!|e9A}oZ7sɾPsA@ l;ib -av(=}z躯0wɬ9U/B/iodHzۑz|!nW߈?)zo UoR}9Z& eU8rB#,`@I(z%[گ^w:37ڨW"AJ Hv^>WYQ㑛O[YY  [̘ ̊ *B4e䚰v2Cz}I(atfBbvA'΢M%hUz5@jլ\*7# Z'ISeHךQ'zkKg2m=|7災GwI)o%A?b`H´2 d ү7&QEI,$r&EJ hK>ķPO cY2()~LfPPy~5S ٧sll/|AKgrýHNJZms)2 !BbE[ xU]#~,]$6jEZ~ͼ}>3 g}w7$e8/9_mqau(᫓-{t #lsųƻw Ж!W9>\ݵ* L&3xMe5U\jf>v^ |LT}Pg,lgJ~8[=pkSʓ'Pi}m.x+7kZtejny,բE9Փ< %D gr$eMfbZ,>p<շ'g͘喹uFh"," }:j5b(Y/зݸ;COs>o4[h JkGNj>m\cńn<Aָ`[ 2 endstream endobj 6 0 obj [5 0 R] endobj 21 0 obj <> endobj xref 0 22 0000000000 65535 f 0000000016 00000 n 0000000144 00000 n 0000050674 00000 n 0000000000 00000 f 0000054021 00000 n 0000216933 00000 n 0000050725 00000 n 0000051086 00000 n 0000054320 00000 n 0000054207 00000 n 0000052310 00000 n 0000053460 00000 n 0000053508 00000 n 0000054091 00000 n 0000054122 00000 n 0000054393 00000 n 0000054589 00000 n 0000055803 00000 n 0000121391 00000 n 0000186979 00000 n 0000216956 00000 n trailer <<90A246E9F2D74D3C99497A7810200A9C>]>> startxref 217163 %%EOF jamulus-3.9.1+dfsg/src/res/HLEDRed.png0000644000175000017500000000270714340334543016417 0ustar vimervimerPNG  IHDRv&zTXtRaw profile type exifxڭk+' ,IrhUAãw܊lhYH ls?"sCIGa}O^aoc?v}.p׫Y=q t<effL_:νg] _Iv b4EWw'ӢŸsxtrr"lUܕ;eyr8M7pJU*>^c͞prvmՈ#mÃ#i/{V|]krwZ쫓7}m},[L(bo䬹CšbKGD pHYsS S MtIMEi"IDAT(υQ=KP=7<^ bL Vġ.ӟ1Aum[,"I[gM(~9%Ǟ:,WJhai1 H(",˩;Y-6@F k- z+yq:] R?{N+:SD,\LZs'O]!`8 뿕\Va#avLizu]OajNRt2$߄YQۋ ,(RZky[oP1buss ƈIENDB`jamulus-3.9.1+dfsg/src/res/win-installer-banner.bmp0000644000175000017500000006233414340334543021277 0ustar vimervimerBMd6(9d8999:;;::::7421/--.//////.---------------------------------------------------------------------------.0369=@CH¥LħPũUǬYȮ^ʰb˳h͵mηqкvҽ{Կ†ŋȐʖ̛СҦլرڵݻ9:99::::9::8641/.--/////.,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-/258Οʗ7++++++++ϸsڷǬ\+++++++æP֮Կ-++++++9ȒԫI.148=@DH¤LŧQƩUȬZɮ_˱d̴iεnиrѺwӽ|Կċǐɕ̛Ϡҥիװڵܺ߿7667999:9986ʔΝɭ]233562Ѥ+++Ѽ{ħS+++++Fˆ+++װ+++޽嶓++++++2Тө϶,++++++‡ʘǬ\+++++I̛۸У++++++‡ҧǑ鷕/159>AEIåNŨSƪVȭ\ʯ`˱eʹjζnиsѻwӽ|Կ†ŋǐʖ̛Ϡҥիװڵܺ߿556678999886ϼ55Eٴ445663ҥ,ƏçR*****Eˆ***װ***޽嵓******Ͷnϸt**ĊƫZ******ӵ+*5۹*****͝H**۷1*****+F+*ҽ~0158=ADIæNŨRƪVȭ[ɯ_˱d̴iζnиsѻwҽ|Կ†ŋǐʕ̚Ϡҥիׯڵܺ߿555677898987ƍ675ͽ677775Ӧ.˘çR*****Eˆ***װ***޽嵓******ˆF**ŪX̵m******ѥ***װٴ*****װ굓***ÉE****++,,ƫY0158=ADIæNŨRƫWȭ\ɯ`˱e̴iζnиsѻwҽ|Կ†ŋǐʖ̛Ϡҥիװڵܺ߿55577788888777777ο998776ӧ.,+ѻzçR*****Eˆ***ְ***ݽ嵒******ˆE**çR̴m******Т**********ְ嵒***ˆE****+,ηr.159>AD£JæOŨTǫYȭ]ʯ`˱e̴jεnиsѺwҼ|Կ‡ŋǐʖ̛Ϡѥիװڵܺ߿45667778878668878ο:98765Ҧ,*)ѻzçQ)))))Dˆ)))֯)))ݽ嵒))))))‡D))çQ̴l))))))Т))))))))))֯嵒)))‡D))***¥Mѻy7,.149>AD£IæNũTȫYȭ]ʯ`˱e̴iεnиrѺwҽ|Կ†ŋǐʖ̛Ϡҥիװڵܺ߿{566677789899999::ξ999753ǑĩU*)ѥ<)))))1س))D͞)),ϴ))))))‡D))§Q̴l))))))Т))))))))))֯崒)))‡D**+++Ͷo̴j,-/.159>BEJæOũTǫYȭ]ɯ`˱e̴iͶnϸsѺwҽ|Կ†ŋǐʖ̛Ϡҥիװڵܺ߿s66677789999:;::::ξ888640A̚լٵ(((((((ҦرʖHĪWʖθs((((((†C((§P̴k((((((С((((((((((֯崒(((†C)*+++D֮ȷ.26:>BE¥KħPŪTǫXȮ]ʯa˲e̴iζmиsѻwҽ|Կ†ŋǐʖ̚Рҥիװڵܺ߿j6677789999::;;;:;ԨР976651*Mݼ˚0(((((((,ǑĨV(ְηr(((((((˲iݼ;((DݼĩV((((((ݼѼ{((((((((((Ӫ(((˲iݼ;*+---,Ǭ^ȓ/37;?CGåLŧQƩUǫXȭ]ʯa˱e̴iεmиsѺwӽ|Կ‡ŋǐʖ̛ϡҦիװڵܺ߿`77889:99::;;;<<;::9876552,((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((()))+,./00/--,,-/48A£GåJħNǪSǫVȭYʯ_˱cͳgεlϷpѺuҼyԿ~ĉƍȒ˗͝Тӧ֭ٲ۷ݼ ? ?>>>===<=>>><9630+''('''&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&(+.01478:;<<<;986543468;>B£GåJħNƪSǫWȭ[ʰ`˲dͳhζlϸqѺuҼzտ„ĊƎɓ˘Νѣӧ֭ٲ۷ݼ¡? >=> > >==;<> > ?=9.('&%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%'),/246779:;<<;:97654348;>DäHĦLŨOƩRǫVɭ\˰`˱dͳhζlиqҺuӼ{տ„ĊǏɓ˘ΝѣӨ֭ز۷ݼá@¡? > > ? > >=<>¡?¡?¡?>93-()(%%%%%%%%%%%%%%%%%%%%%DÊΠǮa'%%%%%%%%%%%%%%%%%8Ҿ۸֯ͷs0)+.24667789;;;<<:9765349 > > > > ?á@á@á@ ><<:40(%%%%%èVǒۺ֯Ҿ;%%%%%%§SݸܵѼ}-ɰfΟөͷr0%%%%%@ծ޹۴̜=25FǏ̚ƩR;<===<;984458=A¢EĥJŦMƨQǪUʭZ˯^̱aͳeεj϶nѺsӼxԾ}…ŋǏɔ̚ϟҤԩ׮ٳܸ޽âAâAá@¡? ?¡?¡?â@á@á@â@á@ ?=<:881%$$$Ŭ^խ9$$)ΟڱԹm˫N˫N˫N˫N˫N˫NΰX͕ɕ-$$ҿ׾vˬO˫N˫N˫N˫N˫NͮUņηnĈПá@ >===<;9546:?¢DäHŦKŧNƩRǫVʮZ˯^̱aͳfζkзoѺsӼxԾ}Æƌǐʔ͚ϟҤԩׯڴܸ޽âAá@á@á@á@á@á@ĢAâAâAâA ?><9666.%$'͟ҟѴa˫N˫N˫NˬOֽsƭ_1г^˫N˫N˫N˫N˫N˫N˫N˫N˫N˫NˬO̓ʏΰX˫N˫N˫NͮUņܽEծӹj˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N}׾w˫N˫N˫NԹlڴ > ? >===<99;>B¢EĤIŦMƧOǩSȫWʭZ˯^̱cγg϶kѸpѺtӼyտ~ÇƌȐʕ͛ϟҥԩׯڴܹ߾âAâAâAâ@á@â@â@ĢAĢAâAâ@><9322/)#$խΰX˫N˫N˫N˫N˫N˫N˫N˫NּsМ˫N˫N˫NͮU|Θէ֪ҟƇѵc˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫NȊݸ̬Q˫N˫ṊR׾v̔զתҟɍӷh˫N˫N˫NΰX̭R˫N˫N˫N˫N˫N˫O޺ ?¡? ? > >=<=>?¡BãFĤIƧMƨOȪTɬWʮ[̱`ͲdγgжlѹrһuԽyֿÇƍȑ˖͛Рҥժׯڴܹ߾ģBĢAĢAâ@â@ĢAâAĢAĢAĢAá@ ><71+&$##۳˫O˫NˬOպoʐўΘņϱ[˫N˫NѴaΗ˫N˫NzЛͮU˫N̬P׾vˑў͕}ͮU˫N˫Nֽtٰ˫N˫NԺm߼էд`˫N̬P̬P˫NѴaʏџ̓ҷf˫ṊSԼw>> ?¡@âAģDťHƦKƨNȩQɫTɭX˯]̱aγeϵhѷnҹrӼvԽzֿ„ĈǍȑ˖͛Рӥժذڴݹ߾ģBĢBĢAâAâAĢAâAģBŤCĢAá? ><93'###;̬PͮTџֽu˫NҶdϙ˫Nѵb߼ӷh˫NҶf˫OΰX޺ӣ̬QͯVݷϱ[ΘڲŤG ?áAģCŤFƦIǧLȩOȪRʬVʮZ̰^ͲbϴfжjѸnҺrӼwվ{…ňǎʒ˗ΜРӦժذڵݺ߾ĢBĢBâAâAĢAâAâAâAģCĢA¡? >=;4("""ʘպoӷh۴̬P˫NؿyΗ˫NӸhίV˫O˫N˫N˫NͯVحáAáAģCŤFƦIǧLȩPȪSʬVʮZ˰^ͲbϴfжjѸnӺsӼxտ|…ʼnǎʓ̗ΜРӦժذڵݹ߾âAâAâAâAá@á@á@á@âAá@á? ? >;4,$:ǒѵdLj߼ե˫NͮTҶdίW˫N˫NӣǎĢCŤEťGƧJǨNȩQȫSʬWˮ[̰_ͲbϵgжkѸoӺsԼxֿ|…ʼnȎʓ̘ΜСӦ֫ذڵݺ߾ >¡?¡? >==> ? ? > >=>;51Ƒ~ŅˬOĢCŤEƥHǧKǨNȩQɫT˭X̯\Ͱ_βcϵhѶkҹpӻtսyֿ}Åʼnǎʓ̘ϝѡӦ֫رڵݺ߾<<=<;;<==<=<<:;ջo˫NըӢĤDťEƦHǧKǩNȪRɬUˮY̯\Ͱ_γcϵhѶkҹqӼuսyֿ}ĆŊȎʓ̘ϝѡӦ֫ٱ۶ݺ߾<;;;:9:;<=<<;9ը˫O̭SăԥŤGƥGƦIǧKǩOȪRɬUˮY̯]Ͱ_γdϵhѷlҹpӻtսyֿ}ĆƊȏʔ̘Νѡӧ֫ٱ۶ݺ߿;::88:;<<><:9ƍ׫̭RӡƤFƦGǦJǧLȩOɪRʬUˮYͯ]αaϳdеiѷlҹqӼu־z~ĆƊȐʔ̘Νѡӧ֫ذڵݺ߿<:987;=<<<<9@г_ţEƥGǧJǨMȪPɪSʭV˯ZͰ]αaϳeеiѷlҹqԼu־z~‚ĆƊȐʔ̘ΜРӦժׯڴݹ߿=<98;¡?á@=<<;9ŋƆ߾ŤEƦGǧJȨNɪQʫTʭV̯[Ͱ]αaϴeжiѷmӹqԼuվz}ĆƊȐʔ̘ΜПҤԨ׮ٳܹ߾:;9:á@ģBĢB ?==96ܵͰ^ţEǦHȧKȨNɪQʫT˭W̯[Ͱ^ϲbϴeеiѷlӹqԼv־zֿ}ĆŊȐʔ̘ΜПѣӧլر۷޼8<=¡?ŤDŤDâA ?=;82־{ģCŤEƦHȧKȨNɪQʫT˭W̯[Ͱ^ϲbϴfеiѷlӹqԼuվzֿ}ĆƊȐʓ̘ΜПѣӧիر۷ݻ:=á@ģBŤDŤDĢB ><96+еgģBģCŤEǦHȧKȨNɫQʫT˭W̯[Ͱ^βbϴeжiѷmӹqԼuսyֿ}ĆƊȐʔ̗ΜϟѢҦլٲ۷ݻ¡?¡?ģBģBģBģBĢA ?<91!ɑβaģBĢAĢAģDƤFǦHȧKȨNɪQʬT˭W̯[Ͱ^βbϴeеiѷlҹqӼuվzֿ}ĆŊȐʔ̘͛ϟТҦխٲ۷ݻ{âAĢAģBâA¡?¡? ><:6'á@â@âAâAĢAģCƤEǦGȧKȨNɪQʬTˮW̯[Ͱ]βaϴeеiѷlҹpӻtվyֿ}ĆŊȏʓ̗ΛϟѢӧ֭ز۷ݻqá@á@á@ ?=<<95-ܻзmá@á@á@á@âAĢCţEƦGǧJǨMȪQʫT˭W˯Zͯ]βaϴeеiѷlҹpӻtսyֿ}ÅŊǎʓ˗͛ϟѤӨ֭ٲ۷ݼ߿g> >><9873,̷sܸ ?¡?á@á@á@â@âBţDƥFǧJǨMȪPɫS˭W˯Zͯ]αaϴeеiѷlҹqӻtԽxֿ|…ʼnǎʒ˖͛ϟҤԩ׮ٳ۷ݻ޿^:;;:83-&%ĤF > >¡?¡?á?á?áAţDƥFǧJǧMȩPɫSʭV˯Zͯ]α`ϳdеhѷlҹpӻtӼxֿ|„ĈǍɒ˖͛ПҥԪׯٳ۶ܺ޿U67587.'ʳmФťH====> >¡?áAģCƥFǦJǧMȩPɪSʬVˮY̯]ͱ`γdϵhѶkѸoӺsӼwվ{„Ĉƍȑ˖͛ϟҤԩ׮زڶݺ߿M00/574)ѦƮb ǒӹ@ϻ{ٵ)͸vǎ<;;;<<<= >¡@ĢCŤEƥHƧKǨNȪRɬU˭X˯\̰_ͲcϵgжkѸnҹrӼvԾ{„ÇƌȐʔ̙ΞҤӨխرڶݻE1+-494#Ѧȱiײм~)Dڷιx 5čҩS4ϣŎ1GƏ֯ηs45898:;;;;= ?âBģDŤGƦIǧMȩQɬUʭWˮ[̰_ͲbϵgжkѸnҹrӼvԾ{ֿÅŋǏɔ̙Νѣӧխر۶ݻ=,$)00&ʴo7мڷʙ¨X+̶rԭ͟ǰe'%(+--,*)&$(06778899;<>¡@ãCĤFƦJǧMȩPȫSʬWˮZ̰_ͲbϴgжjѸnҹrӼvԾ{տ~…ĉƎɔ̙ΝѣӨ֭ز۷ݻ7 #̷tݼѾ- !%)*+*)*($$&*02467778:;>¡@ãDťHƧKǩNȪRʬVˮZ˰]̲aϴf϶jѷnҹrӼwվ{տ~…ĉǎɓ˘ΝѢӧ֭ٲ۷ݻ0 !$(**''*($"%)+.46655668:¢DĤIƧMƨPǩTɬWʮ\̱aͳeεiзnҹrӻvԽ{տ~…ĊƎɓ̙ΝТӧլװڵܺ߿$"&()*)% $(,/0--.*(+05;@¢EŦKƧOǩRɬWʮ\̰_ͲdεhѷmѹrһuԽyԾ}…ĊƎɓ˘ΝТҦլװٴܹ޾"'('&"!&+--+*'&('(/7>CäHĦLƨQȫWʮZ˯^̲dδhжlѹpһuԽyԾ}…ĉƍȑʗ͛СҦիׯٴܹ޾#$#!&***'%" !#%)19?EäJħNǪTɬYʮ]̱bͳf϶kѷoҺtӼxԾ|տÉŌǐɖ̚ϠҦի֯ٴ۹ݽ #((*&" %'-7R՝OΗ6bW KsYJ횹Yi,Udwez1 P2KV͐*>6o&p 6?XxJ;m<27>yqxHgd:e ,>cX,RYH$J 0LY4,I7݉}+-벿~t>h?|ѣO;1ԡ_b!@cAa\pO0Ch4KRAFCHHHA0nw~qvo?xpݿ_X~G(~v $cl{zQ^~χySvG=b4stC8 l̄R=|׾y{S7}Ǥ_V/2;ssb9@Pduif9bdD)ȝ4HWtLf" 3b֗Ե'}o8>'׵,u}ꏻ\t KVt,[<lEЊ^ +&p ʱJ"%TϜ\gjS`Nc^&0 JЕbp^L+ Bc̔YKY _+ 4>D) p[@+"e'T0ܮԻP Z:j]{l2eQ?' <ov0H`2;`ڷwt͐pP1Q(5BS!fheOr7- $\H}p9 J@-5'~hGڷviͱ.+|0s ¿'A,A ZĞIW0a&G]xVXVt&Gt~G;s* `IZ4 <%I "b?T@B22 CLc`F6}qOalusԎg: 3 m &ZSHi/,a؎#adF6i)go]sM̰5#ˀ5ж#/'c+F%p[-aW  865ڰ7~û4~O痫~o¢x;M``dy{6|6Ycm}6_n _y80Fli{)^ܚRab\.8?;7J^Z~ܻ~eŗ֗on~o3e;qw!=+WC[_zj۱eD H)Z-U|)VզcLI^f~?.濐Tww>s2/Oٝg33y/RIgƴ68x]nЛjbl il4n=?o-*dڭYR溵T乔2/ŸJ:8g9Vl[|jGWY1Pl`7wߕZ7!TA.e*au]JcD Efacfڏ3I;;v8dzjbZo>%7JSD~Vbf SM2 3 eWP{o'D$)fc25_IENDB`jamulus-3.9.1+dfsg/src/res/CLEDDisabled.png0000644000175000017500000000216514340334543017405 0ustar vimervimerPNG  IHDR sRGBbKGD pHYs~uɍtIME ;zI'IDAT8}kSI9sαI$M?V]i;T.g+Pe+^^HAWEP.5нs-j֖M 搜 MZفwo_D8DRGY!0+Fkk;wĔR_7biB!2ǎ]6o_ {< 2mxtwwސƅvFm$r=47߰,ބϮ]X,NIR}ЫWw8%/pf2T 0>Ta||?qL&cѣG-B/-8={pj8^Lիd }}Z[˳gϞB\dg'_Rj jb88\;ožG"ض 4/]J(Ji~?SSlv q>?ގQ* T*@TRXT*R-&1FGY(gulFJ 0麾EA^4M,erxȆG㬮0Mzi躾ER:ib㰼mj Zm۬P0 0R"DRf혦 7'D,w/aڬA>O``s泥.wuuQ*蛚b߃M,:\նH 42B0l4eV4mFJ| ޿Ͼ{#Gx`&n޽03yu=#t:&/jž ,YW?wyӧTw$w.P(4l߾}ZJ\@9͚6:i&Fo//RӃuRx(^g_LFB*8,j MzҴ/֭[/l> !Ra^===BEq !}J`V)5յ n^IENDB`jamulus-3.9.1+dfsg/src/res/IndicatorGreen.png0000644000175000017500000000154314340334543020142 0ustar vimervimerPNG  IHDRH-iCCPICC profile(}=H@_SE;8dNEEEP :\MGbYWWAqrtRtZxp܏ww^f1e$cQ1]^уĸL=ZLs|׻>Ur&|" xxf9XQRω #e8xfH'Cb6fEC%&+FBeg\e{sJ4H@*J(BVIڏz\2J`X@*$5SnR0 tе 4j}lۍ \i-~^ki#onip >!9gMY`5q-Pǻ{LyrGbKGD pHYs%%IR$tIME :DLtEXtCommentCreated with GIMPW;IDAT(ϝ=HqC+]Z ZVM炠@(B胃m()B  R3&}_7x5iD|f0 ϋJgWt#{3q+P LVıv&QdɣԖ䆸4D_{WDT˸\#6jQd8iSKSѦ6-C+;e“sd)EtfX2x{8ViR"E1T ?^3='DUC{O!mF4P*I*N%!bcEHIENDB`jamulus-3.9.1+dfsg/src/res/win-installer-welcome-asio.bmp0000644000175000017500000045565614340334543022433 0ustar vimervimerBM[6(:x[#.#.̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M64-)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+**+J̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+..,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+)*+YZ[wxy)*+)*+,-.STU)*+-./9::uvvllmBCD)*+@AB)*+)*+)*+MNN)*+)*+-./FGHSTU)*+)*+_`a}}~)*+Z[\||},-.)*+CDEkll)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+\]])*+匌TUV/01CDDSTU)*+STU)*+)*+)*+789hij012wxy)*+)*+)*+呑뗗)*+ʝZ[\ijk)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+)*+)*+ccdz{{CDEVWX)*+)*+/01XXY[\])*+STUvvwrrsBCD)*+)*+wxy)*+)*+)*+)*+)*+)*+̉)*+)*+Z[\)*+)*+)*+)*+)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+݌)*+)*+)*+)*+fgg)*+)*+)*+xyz/01)*+STUXXYwwx)*+hij)*+wxy)*+)*+)*+뫫Z[\)*+̉)*+)*+Z[\234)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+Ξ)*+)*+;<=123TUV678)*+)*+/01rrs)*+STU)*+)*+ğ567ccd./0)*+wxy)*+)*+)*+hij}~IJK)*+̉)*+)*+Z[\hijhijhij-./)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+^_`CDĘ*+,ر@AB`aaz{{/01:;?@䜜)*+xyzᲳ234)*+}~)*+)*+TUVhij)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+)*+)*+)*+-./)*+)*+)*+)*+)*+,-.)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+wxyPQR)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+/01)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+)*+)*+)*+)*+jkkwxy)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+;<=GHI678)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+./0FGHABC*+,)*+)*+)*+)*+)*+)*+CDD)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+)*+)*+)*+^_`)*+)*+XYZ)*+)*+)*+)*+pqqjkk)*+)*+)*+)*+./0옙345)*+)*+)*+)*+def)*+)*+)*+)*+)*+)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+)*+)*+STU)*+)*+KLM)*+)*+)*+)*+)*+uvv)*+)*+<=>)*+)*+)*+{{|*+,)*+)*+)*+)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+)*+JKL)*+)*+)*+JKL)*+)*+)*+def}}~abbRSSOPQ)*+=>?TUV+,-)*+)*+UVW678)*+)*+)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+CDD9::)*+)*+PQRllm*+,)*+)*+)*+)*+./0+,-qqr)*+)*+)*+z{{)*+)*+123PQR)*+)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+;<=]^_)*+)*+)*+RSS)*+)*+)*+)*+)*+)*+JKL)*+)*+)*+TUV)*+)*+)*+wwx)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+567)*+)*+)*+VWXŇ789)*+)*+)*++,-yzz)*+pqq)*+)*+)*+)*+NOP)*+)*+/00)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+)*+)*+*+,)*+)*+)*+)*+PQR)*+mno)*+)*+)*+)*+)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+*+,)*+)*+)*+)*+]]^kll)*+)*+)*+456,-.)*+hijEFG)*+)*+)*+)*+)*+)*+nop>??)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+hhi)*+)*+)*+)*+)*+)*+)*+)*+jkkRSS)*+)*+)*+CDD)*+LMN)*+)*+)*+uvv)*+)*+IIJEFG)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+)*+EFGDEF)*+)*+)*+)*+ccdSST)*+)*+opp,-.)*+)*+)*+)*+)*+345)*+)*+)*+wxy)*+)*++,-NNO)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+)*+)*+012jkk)*+)*+)*+)*+)*+)*+)*+HII-./)*+)*+)*+)*+)*+WXX;<=DEF)*+)*+)*+)*+)*+XXY)*+)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+hijpqq)*+)*+)*+z{{bbc)*+}}~)*+||}憆]^_)*+)*+)*+abb)*+)*+)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+VWX)*+)*+)*+)*+)*+)*+VWX)*+)*+)*+>?@)*+)*+)*+)*+)*+)*+)*+mno)*+)*+)*+)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+:;<)*+)*+)*+)*+)*+)*+fgg9:;)*+)*+)*+)*+456}~)*+RSSƚ)*+)*+)*+XYZܑ/00)*+)*+)*+)*+bbcz{{)*+)*+)*+)*+)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*++,-./0)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+<=>)*+)*+)*+)*+)*+)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+10,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M43-)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+--,ǦL̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MSK4KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2KD2QI3K̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪MͫN˪M˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L̫M˪M˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L̫M˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L̫M˪M˪M˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L̫M˪M˪L˪M˪M˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L̫M˪M˪M˪M˪M˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L̫M˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪K˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K̫L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪K˪L˪L˪L˪L˪L˪L˪K˪K˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K̫L˪L˪L˪L˪L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩K˩K˩L˩L˩L˩L˩K˩L˩L˩L˩L˩L˩K˩L˩L˩L˩L˩K˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩K˩K˩K˩L˩L˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K̪L˪L˩L˪L˩L˩L˩L˩L˩L˩L˩L˩L˪L˪L˩L˩K˩K˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩K˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩K˩L˩L˩L˩L˩K˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K̪L˪L˪L˪LʩLʩKʩLʩLʩLʩL˪L˪L˪L˪LʩLʩLʩKʩL˪L˪LʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩKʩLʩLʩLʩLʩKʩLʩLʩLʩKʩLʩLʩLʩLʩLʩLʩLʩKʩLʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩK˪L˪L˪L˪L˪L˪LʩL˪L˪LʩLʩL˪L˪LʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩKʩLʩLʩLʩLʩLʩLʩKʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩK˪L˪L˪L˪L˪L˪L˪K˪K˪LʩKʩK˪L˪LʩKʩKʩKʩKʩK˪LʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJ˪K˪K˪L˪L˪L˪L˪K˪L˪L˪L˪K˪LʩK˩K˪LʩKʩKʩK˪L˪LʩKʩK˪L˪LʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩKʩKʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJ˪K˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪LʩKʩK˪L˪L˪LʩK˪L˪K˪LʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩKʩJʩKʩKʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJ˪K˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪LʩK˪L˪L˪L˪KʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩKʩKʩKʩKʩKʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJ˪K˩L˩L˩L˩L˩L˩L˩L˩L˩K˩L˩L˩L˩L˩L˩L˩L˩L˩L˩K˩L˩L˩L˩LʩK˩LʩKʩKʩK˩L˩LʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʨKʨJʨJʨJʨKʨKʨKʨKʨKʨJʨJʨKʨKʨKʨKʨKʨJʨJʨJʨKʨJʨJʨKʨKʨKʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨKʨKʨKʨKʨKʨKʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJ˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩KʩK˩K˩K˩K˩KʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩK˩K˩K˩KʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʩJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨIʨIʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨIʨIʨIʨIʨIʨIʨIʨIʨJʨJʨJʨJʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨI˩JʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩK˩KʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʩJʩJʩJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʩJʩJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩJɨJɨJɨJɨJɨJɨJɨJɨJɨJʩJʩJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJʩJʩJʩJʩJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩJɨJʩJʩJʩJɨJɨJɨJʩJʩJʩJɨJɨJɨJʩJʩJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʩJʩJʩJʩJʩJʩJʩJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJʩJʩJʩJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIʩJʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJɨJɨJɨJɨJɨJɨJɨJʩJʩJʩJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʩJʩJʩJʩJʩJʩJʩJʩJʩJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʩJʩJʩJʩJʩJɨJɨJɨJɨJɨJɨIɨIɨIɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIʩJʩKʩKʩKʩJʩJʩJʩJʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩIʩIʩIʩIʩIʩIʩIʩJʩJʩIʩIʩIʩIɨIɨIʩIʩIʩIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIʩIʩIʩIʩIʩIʩIʩIʩIʩIʩIʩIɨIɨIɨIɨIɨIɨIɨIɨIʩIʩIʩIʩIʩIʩIʩIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨHɨIɨIɨIɨHɨHɨHɨHɨHɨHɨIɨIɨIʩJʩKʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩJʩJʩJʩJʩJʩIʩIʩJʩJʩJʩJʩJʩJʩJʩJʩJʩIɨIɨIʩIʩIʩIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIʩIʩIʩJʩJʩIʩIʩIʩIʩIʩIʩIʩIʩIɨIɨIʩIʩIʩIʩIʩIʩIʩJʩJʩJʩJʩIʩIɨIɨIɨIʨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIʩJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨJʨJʨJʨJʨJʨJʨJʨJʨJʨIʨJʨJʨJʨJʨJʨJʨJʨJʨJʨIʨIʨIʨJʨJʨIʨIɨIɨIʨIʨIʨIʨIʨIʨIʨIʨIʨJʨJʨJʨIʨIʨIʨJʨJʨJʨIʨIʨIʨIʨIʨIʨIʨIʨIʨJʨJʨIʨIʨJʨJʨIʨIʨIɨIɨIɨIɨIɧIɧIɧIɨIɨIɧIɧIɧIɧIɧIɧIɨIɧIɧIɧIɧIɧIɧIɧIɧIɧIɧIɧIɧIɧIɧIɧIɧIɧIɧIʨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨJɨJɨIɨIɨJɨIɨJɨJɨJɨJɨJɨJɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨJɨJɨJɨJɨIɨIɨIɨIɨIȧIȧIȧIȧIɨIɨIȧIȧIȧIȧIɨIɨIȧIȧIȧIȧIȧIȧIȧIȧIȧIɨIȧIȧIȧIȧIȧIȧIȧIȧIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIȧIȧIȧIɨIɨIɨIȧIɨIȧIɧIɨIȧIȧIȧIɨIɨIȧIȧIȧIȧIɨIɨIȧIȧIȧIȧIȧIȧIȧIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩKʩKʩKʩKʩJʩKʩKʩKʩJʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩJʩJʩJʩJʩJʩJɨJɨJɨJɨJɨJɨJɨIɨJʩJʩJʩJʩJʩJʩJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHȧHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHȧHȧHȧHȧHȧHȧHȧHɨIɨJɨJɨJɨJɨJɨIɨIɨIɨJʨJʩJʩJʩJʩJʩJʩJʩJʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨHɨHɧHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHȧHȧHɨHɨHɨHɨHɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJʩJʩJʩJʩJʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩK˩K˩KʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩKʩKʩKʩKʩKʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʨJʨJʨJʨJʨKʨKʨKʨKʨKʨKʨKʨKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʨKʨKʨKʨKʨKʨKʨKʨJʨKʨKʨKʨKʩKʩKʩKʩKʨKʨKʨKʨKʨJʨJʨJʨJʨJʨJʨJʨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIɨJɨJɨIɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɧIɧIɧIɧIɧIɧIɧIɧIɧIɧIɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHʨIɨIɨIɨIɨIɨIɨIɨIɨIɨIʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩJʩKʩKʩKʩKʩJʩJʩKʩJʩJʩJʩJʩKʩJʩKʩKʩKʩKʩKʩKʩJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧGɧHɧHɧHɧHɧGɧGɧGɧHɧGɧGɧGɧGɧGɧGɧGɧGɧGɧGɨHɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩJʩJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧGȧGȧGȧGȧGȧGȧGȧGȧGȧGɨHɨIɨIɨIɨIɨIɨJɨJɨIɨIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩLʩLʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩJʩJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨIɨJɨIɨIɨIɨIɨIɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧGȧGȧGȧGȧGȧHȧGȧGȧGȧGɨHɨJɨJɨJɨJɨJɨJɨIɨIɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩLʩLʩKʩKʩKʩLʩKʩKʩKʩKʩKʩKʩLʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨIɨIɨIɨIɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧGȧGȧGȧGɨHɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʩJʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩLʩLʩLʩLʩKʨKʩLʩLʩKʩLʩLʩLʩLʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIȧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHɨIɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʨJʨJʨJʨJʨJʨKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩLʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʨJʨJʨJʨJʨJʨJʨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɧIɧHɧHɧIɧHɧHɧHɧHɧHȧHȧHȧHȧHȧGȧHȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGɧHɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIʨJʨJʨJʨJʨJʨJʨKʨJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩLʩLʩLʩLʩKʩKʩLʩKʩLʩLʩLʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʨJʨJʨJʨJʨJʨJɨJɨJɨJɨJɨIɨJɨJɨJɨIɨJɨJɨJɨJɨIɨJɨJɨJɨJɨIɨIɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɧIɧIɧHɧHɧHɧHɧHɧHɧHɧHȧHȧHȧHȧHȦGȧGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGɧHɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʨJʨJʨJʨJʨJʨJʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩKʩLʩLʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨJɨIɨIɨIɨJɨIɨIɨIɨIɧIɧIɧIɧIɧIɧHɧHɧHɧHɧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGɧHɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩKʩLʩLʩKʩKʩLʩLʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKɨKɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIȧIɨIȧIȧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHǦGǦGǦGǦGǦGȧGȧGȧGȧHɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJʩJʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩLʩLʩLʩLʩLʩLʩLʩLʩKʩKʨKʨKʩKʩKʩKʩKʩKʩKʩJʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨIɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨHɨIɨIȧHȧHȧHȧHȧGȧGȧHȧHȧHȧGȧGȧGȧGȧGȧGȧGȧGȧGǦGȧGȧGȧGȧGȧGȧGɨHɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJʩJʩJʩJʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʨKʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩJɨJɨJɨJʩJʩJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨIɨJɨIɨIɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIɨHɨIɨIȧHȧHȧHȧHȧHȧHȧHȧGȧGȧGȧGȧGȧHȧGȧGȧGȧGȧGȧGȧGȧGȧGȧGȧGȧGɨHɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʨJʨJʨJʨKʨKʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʨKʨKʨKʨKʨKʨKʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIɧIɨIɨIɧIɧIȧHɧIɧIȧHȧHȧHȧHȧHȧHȧHȧHȦGȦHȦHȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGɧHɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʨJʨJʨKʨJʨKʨKʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʨKʨKʨKʨKʨKʨKʨJʨKʨKʨKʨKʨJʨJʨJʨJʨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɧIɧIɧIɧIɧIɧIɧIɧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȦGȦGȦGȦGȦGȦGȦGȦGȦGɧHɨJɨJɨJɨJɨJɨIɨIɨJɨJɨJɨJɨJɨJɨJʨJʨJʨJʨJʩKʨJʨJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʨKʩLʩLʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʨJʨJʩKʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɧIɧIɧHɧHɧHȧHȧHȧHȧHȧHȧHȧHȧGȧGȦGȦGȦGȦGȦGȦGȦGȦGȦGɧHɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʩKʩKɨJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩLʩLʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧGȧGȧGǦGǦGǦGǦGǦGǦGǦGǦGȧHɨJɨIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKɨJɨJɨJɨJʩKʩKɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨIɨIɨIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧGȧGȧGȧGȧHȧHȧGȧGɨHɨIɨIɨIɨIɨIɨIɨIɨIɨIɨJɨJɨJɨJɨIɨIɨJɨJʩJʩJʩJʩJʩJʩJʩJʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩKʩKʩKʩKʩJʩKʩKʩJʩJʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩJʩKʩKʩJʩKʩKʩKʩK˩KʩKʩKʩKʩKʩKʩKʩJʩJʩJʩJʩJʩJʩJɨJʩJʩJʩJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIȧHȧHȧHȧHȧHȧHȧHȧGȧGȧGȧGȧGȧGȧGȧGȧGȧGȧGȧGȧGɨHɨIɨIɨIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨJɨJɨJʨJʨJʨKʨKʨJʨJʨJʨJʨKʨKʨKʩJʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʨJʨJʨJʨJʨJʨJɨJɨJʨJʨJɨJʨJʨKʨKʨKʩKʩKʨKʨKʨJʨJʨKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʨKʨKʨJʨJʨJʨJʨJʨJʨJʨJʨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIɧIɧIɧIɧIȧHȧGȧHȧHȧHȧHȧHȧHȧHȦGȦGȦGȦGȦGȦGȦGȦGɧHɨIɨIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʨJʨJʨJʨJʨJʨJʨJʨJʨKʨKʨKʨKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʨKʨJʨJʨJʨJʨKʨJɨJɨJʨJʨJʨJʨJʨJʨJʨJʨKʨKʨKʨKʨKʨKʨKʨKʨKʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʨKʩKʨKʨKʨKʨKʨJʨKʨKʨJʨJɨJɨJʨJɨJɨJɨIɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɧIɧHɧIɧIɧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȦGȧHɧHɨJɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨKʨJʨJʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʨKʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨKʨKʨJʨJʨJʨJʨKʨKʨKʨKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʨJʨJʨJʨJʨJʨJɨIɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɧIɨJɨJɨJɨJɨJɨJɨIɧIɧIɧIɧIɧIɧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʩJʩKʩKʩJʩJʩKɨJʩJʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIȧHȧHȧHȧHȧHȧHȧHȧHȧGȧGȧGȧGȧGȧGȧGȧGɨHɨIɨIɨIɨIɨIɨIɨIɨIɨIɨJɨJɨJɨJɨIɨJɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJռsƈʩJɨJɨJɨJɨJʩJʩKʩKʩKѠԹmʩKʩKʩKԹmѠʩJɨJɨJɨJɨJɨJɨJӸlџɨJɨJɨJɨJɨJɨJɨJɨJņņɨJɨJɨJɨJɨJɨJɨJɨJʩMӣг`ʩKʩKʩKʩKʩKʩKʩKʩKʩKʩK׿xņʩKʩKʩKʩKʩKʩKʩKɨJɨJջrNjɨJɨJɨJɨJɨJɨJɨJɨJɨJջqҡʩLɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIȧHȧHȧHȧHȧHȧHȧHȧGȧHȧHȧGȧGȧGȧGȧHɨIɨJɨIɨIɧIɧIɧIɨIɨIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJֽu˓ɨJɨJɨJɨJɨJʨKʨKʨK߼׾xʨKʩKʨK׾x߼ɨJɨJɨIɨJɨJɨJɨJ׾w߼ɨJɨJɨJɨJɨJɨJɨJɨJΙΙɨJɨJɨJɨJɨJɨJɨJɨJϱ[ʩKʩKʩKʨKʩKʩKʩKʩKؿzɏʨKʨKʨKʨKʨKʨKʨKռsΘɨJɨJɨJʨKɨJɨJʨKͭV޹׫ɨJɨJɨJɨJɨJɨIɨIɧIɧIɧIɧIɧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȦHȦHȦGȦHȧHɨIɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨJɨJɨJɨJNJɨJɨJӸkʪNɨJɨJɨJɨJʨKʨKʨK߼׾wʨKɏɏ֫߼ɨJɨJɨJɨJɨJɨJɨJ׾w߼ɨJɨJɨJɨJɨJɨJɨJɨJΙΙɨJɨJɨJɨJɨJɨJɨJӸkήVɨJʨL۵תʩKʨKʨKʨKʩKʩKʩKʨKƇʩKʩKԺn˩MʨKʨKʨKʨKʨKʨKȍʨJɨJҷi̫PɨJʨKʨKʨKʨKʨKʨKջrņɨJɨJΰZɨJɨJɨJɨJɨJɨJɨIɨIɨIɧIɧIɧIɧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȦHȧHȧHɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨJɨJɨJɨJɨJɨIɨJɨJɨJɨKɨJɨJɨJӸkɨJɨJɨJɨJʨJʨJʨJ߼׾wʨJ߼ʨJɨJɨJɨJɨJʨJɨJ׾w߼ɨJɨJɨJɨJɨIɨIɨJɨJΙΙɨJɨJɨJɨJɨJɨJɨJ̕ԦɨJʨJʨJҶfʩJʩJʨKʨKʩKʩKʩK˫NʩKʩKʩKʩKҶgʨKʨKʨJʨJʨJʨJʨKʨJʨJʨJպpʨJʨJʨKʨKʨKʨKʨKʨJʨJʨJʨJͭUɨJɨJɨJɨJɨJɨIɨIɨIɨIɧIɧIɧHɧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHɨIɨIɨIɨIɨIɨIɨIɨIɨIɨJɨIɨIɨIɨIɨJɨIɨIɨIɨIɨIɨIɨIɨJɨJɨJɨJɨJɨJԥΙɨJɨJɨJɨJ߼׾wɨJɨJɨJɨJɨIɨJɨJ߼׾wɨJԥԤ߼߼ɨJɨJɨJɨJɨJʨJɨJ׾w߼ɨJɨJɨJɨJɨJɨJɨJɨJΙΙɨJɨJɨJɨJɨJɨJɨJΙΙɨJɨJɨJ̭UʩKʩKʩKʩKʩKʩKʩKͮVʩKʩKʩKɨKƉԥΰ\ɨJɨJɨJɨJɨJɨJɨKɨKɨJɨJ߼׾wɨJɨKʩKʩKʩKɨKɨKɨKɨKα\ΙɨJɨJɨJɨJɨJɨJɨJɨIȧIȧIȧIȧHȧHȧHȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHɨIɨIɨIɨIɨIɨIɨIɨIɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJ߼׾wɨJɨJɨJɨJɨJɨJɨJ߼׾wɨJɨJɨJ׾w߼ɨJɨJɨJɨJɨJɨJɨJ׾w߼ɨJɨIɨIɨJɨIɨJɨJɨJΙΙɨIɨIɨJɨJɨJɨJɨJΙΙɨJɨJɨJ̭UʩKʩKʩKɨKʩJʩKʩKͮVʩKʩKʩKʩKʩKʩKɨKɨKɨKɨJɨJɨJɨJʩKɨKɨJɨJ߼׾wɨKʩKʩKʩKʩKʩKʩK̬Q߼ϱ\ʩKɨJɨJɨJɨJɨJɨJɨIɨIɨIȧIȧIȧIȧIȧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHɨIɧIɧIɨIɧIɧIɧIɧIɨIɨIɨIɧIɨIɨIɧIɧIɧIɧIɧIɧIɧIɧIɨIɨIɨIɨIɨIɨIɨIɨJɨJɨJɨJɨJ߼׾wɨJɨJɨIɨJɨJɨJɨJ߼׾xɨJɨJɨJ׿y߼ɨJɨJɨJɨJɨJɨJɨJ׾wɨIɨIɨIɨIɧHɨIɨJɨJО͗ɨIɨIɨJɨJɨIɨJɨJΙΙɨJɨJɨJ̭UɨJʨKʨJɨJʨJʨJʨJͭUʩKʩJʨKʨKʨJʨJɨJɨJɨJɨJɨJɨJɨJʨJʨJɨJɨJ߼׾wʨJʨKʨKʨKʩKʨKʨKըҡѴbʨJʨJʨJʨJɨIɨJɨJɨJɨIɨIɨIɧIɧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȦHȧHȦHɨIɧIɧIɧIɧIɧIɧIɧIɨIɨIɧIɧIɨIɨIɧIɧIɧIɧIɧHɧIɧIɧIɨIɨIɨIɨIɨIɨIɨIɨIɨJɨJɨJɨJ߼׾wɨJɨJɨJɨJɨJɨJɨJٰɏɨJɨJɨJʑ׭ɨJɨJɨJɨJɨIɨIɨIѶfɨIɨIɨIʪNɨIɨIɨIɨJݸņɨIɨIɨJɨJɨIɨJɨJΙΙɨJɨJɨJ̭UɨJʨJɨJɨJʨJʨJʨJͭVʩKʩKʨKʨJɨJɨJɨJɨJɨJɨJɨJɧIɨJʨKʨKʨJʨJ߼׾wʨJʨKʨKʨKʩKʩKʨKּuʨKʨKʨKʨKʨJɨJɨJɨJɨJɨJɨIɨIɨIɧHɧHȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȦGɧIɧIɧIɧIɧIɧIɧIɨIɨIɨIɧIɨIɧIɧIɧHɧIɧIɧIɧIɧIɧIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨJɨIɨI߼׾wɨJɨJɨJɨJɨJɨJɨJ{ѵdɨJѵe׾wɨJɨJɨJɨJɨIɨIɨIɨJ˒ɩJ˫OڲɨIʩLɨI׿zͯWɨHɨIɨIɨJɨJɨJɨJΙΙɨJɨJɨJ̭UɨJɨJʨJɨJʨJʨKʨKͭVʩKʨKʨJɨJɨJʨJɨJʨJɨJɨJʨJʨKʨKʨKʨKʨJʨK߼׾xʩKʨKʨKʩKʩKʩKʩKʒʨKʩLΙίZʨKʨJɨJɨJɨJɧIɨJɨJɨIɧHɧHɧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHɧIȧIȧIȧIɨIɨIɨIɨIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIɨIɨIɨIɨI߼׾wɨJɨJɨJɨJɨJɨJɨJɨJ޹ܷɨJɨJɨJɨJɨJɨJɨIɨIɨI׾wϲ^ʪNʐɨJɨIɨIɨIɨIɨJɨJɨJΙΙɨJɨJɨJ̭UɨJɨJɨJɨJɨJɨJɨJ̭UʩKɨKɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨKɨJʩKʩK߼׿xʩKʩKʩKʩKʩKʩKʩKջpɨKɨJɨJɨJɨJɨJɨJɨJɨIȧIȧIȧIȧHȧIȧHȧHȧHȧHȧHȧHȧHȦHȧHȧHȧHȧHɨIȧIȧIȧIɨIȧIɨIȧIȧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧIȧIȧIȧIȧIȧIɨHɨIɨIÂԤг`ɨIɨJɨJɨJɨJɨIɨJɨJɨIņņɨJɨJɨJɨJɨIɨIɨIɨIɨHɨHɨIдbٰӣͮVɨJԺn޹ջpɨIɨJɨJɨIɨIɨJɨJɨJɨJջrԥջrɨJɨJɨJ˫Pԥ˔ɨJɨJɨJɨIɨJɨJɨJ˫Pԥ̔ʩKɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʩKԥϚʩJʩKʩKʩKăԥѴbʩKʩKʩKʩJʩKʩKʩKʩKѵdخէϱ\ɨJɨJɨIɨJɨJɨIɨIɨIɨIɨIȧIȧHȧHȧHȧHȧHȧGȧGȧHȧHȧHȧHȧHȧHȧHȧHɨIȧHȧIȧIȧIȧIȧIȧIȧHȧHȧHȧHȧHȦHȦHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧIȧHȧIɧIɧIɨIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨIɨIɨJɨIɨIɨIɨJɨJɨIɨJɨIɨIɨIɨIɨIɨJɨJɨJɨIɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɧJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʨKʨKʨKʨJʩKʩKʩKʩKʩKʩKʩKʩJʨKʨJʨKʩKʩKʩKʩKʨKʨKʨKʨKʨKʨKɨJʨKɨJɨJɨJɨJɨIɨIɧIɧIɧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHɨIȧHȧIȧIȧIȧIȧIȧIȧHȧHȧHȧHȧHȦHȦHȦGȦGȦHȧHȧHȧHȦHȦGȦHȦHȧHȧHȧHȧHȧHȧHȧHȧIɧIɧIɧIɨIɨIɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJʨJɨJɨJɨJɨIɨIɨJɨJɨIɨIɨJɨIɨIɨJɨIɧIɨIɨIɨIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɧIɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨJʨKʨKʩKʩKʩKʩKʩKʩKʩKʩKʨKʨKʨKʨKʨKɨJɨJɨIɨJɨJɨIɨIɨIɧIɧIȧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHɨIȧHȧHȧHȧHȧHȧHȦHȦGȧHȧHȧHȧHȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȧGȧGȧHȧHȧHȧHȧHɧIɧIɨIɨIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJʨJʨJʨJɨJʨJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʨJɨJɨJɨJɨJɨJɨIɨIɧIɧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHɨIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧGȦGȦGǦGǦGǦGǦGǦGǦGȦGȦGȦGȦGȦFȦGȦGȦGȧGȧHȧHȧHȧHɧIɨHɨIɨIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɧIɧIɧIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJʨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJʨJʨJʨKʨKʨJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKɨJɨJɨJɨJɨIɨJɨIɨIɨIɧHȧHȧHȧHɧIȧHȧHȧHȧHȧHȧGȧHȧHȧHɨIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHǦGǦGǦGǦGǦGǦGǦFǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȧHȧHȧHȧHȧIȧIɨIɨIɨIɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIȧIȧIȧIȧIȧIɨIɨIɨIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɧIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʩKʩKʩKʩKʩK˩KʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKɨJɨJɨJɨJɨJɨJɨJɨIɨIȧIȧIȧIȧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHɨIȦGȧGȧHȧGȧHȧHȧHȧHȧHȧHȧHȦGȦGǦGǦGǦFǦGǦFǥFǥFǥFǦFǦFǦFǦFǦFǦFǦFǦFǦGǦGȦGȦGȦGȦHȧHȧHȧHȧIɧIɨIɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɧIɧIɧIɧIɧIɧIɧIɧIɧIȧIȧHȧHȧIɧIɧIɧIɨIɨIɨIɨJɨJɨIɨIɨIɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʨKʨKʨKʨKʨKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨJɨJɨJɧIɨJɨJɨJɨIɧIȧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHɨIȦGȦGȧHȧHȧHȧHȦHȧHȧHȦGȦGǦGǦGǦGǦGǦFǦFǦFǥFǥFǦFǦFǦFǦFǦFǦFǦFǦGǦFǦFǦGǦGȦGȦGȦGȧHȧHȧHȧGȧHɧIɧIɧIɧIɧIɨIɨIɨIɨIɨIɨIɨIɧIɧIɧIɧIɨIɧIɧIɧIɧIɧIȧIȧHȧIȧIɧIɧIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɧIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʨJʨKʨKʨKʨKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKɨJɨIɨJɨJɨJɨJɨIɧIɧIɧIɧIȧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHɨIȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGǦGǦGǦGǦGǦFǦFǦFǥFǦFǦFǦEǥEǥFǥEǦFǦFǦFǦFǦFǦFǦGǦGȦGȦGȦGȧHȧHȧHȧHȧHȧIɧIɧIɧIɧIɨIɨIɨIɨIɨJɨIɨIɨIɨJɨIɨIɧIɨIɧIȧHɧIɧIȧIȧIȧIɧIɧIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨIɨIʨKʩKʩKʨKʩKʨKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʨKɨJɨJɨJɨJɨJɨJɨIɧIɧIɧIɧIɧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHɨIȦGȦGȦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǦEǦEǦFǦFǥFǥEǥFǦFǥEǥEǥEǥEǦFǦFǥFǦFǦFǦFǦFǦGȦGȦGȦGȦGȦGȧGȧHȧHȧHȧHɧIɧIɨIɨIɨIɧIɨIɨIɨJɨIɨJɨJɨJɨHɨIɨIɧIɧIɧIɧIɧIɧIɧIɧIɧIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʨJɨJɨJɨJɨJɨJɨJɨJʨJʨKʩKʨKʨJʨKʩKʨKʩJʩKʩKʩKʩKʩKʩKʩJʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʨKʨJʨJɨJɨJɨJɨJɨIɨIɨIɨHɨIɨIɧHɧIȧHȧHȧHȧHȧHȧHȧHȧHȧHɨIǦGǦGǦGǦFǦFǦFǦFǦFǦFǥFǦFǦFǥFǥFǥFǥFǥFƥEƥEƥEƥFƥEƥEƥEƥEƥFƥEǥFǥFǥFǥFǦGǦGǦGǦGǦGǦGǦGȦHȧHȧHȧIȧHȧIɧIɧIɧIɧIɧIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɧIȧIȧIȧIȧIȧIɨKгcֽv׿xӷj̭TɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJΰZռt}€ּuг`ɨKɨJɨJɨJɨJɨJɨJʨKʨKʨKʩKʩKʨKʩKʨJʨKʩKʩKʨKʨKʨKʨKʨKʨKʩKʨJʩKʩKʩKʨJʨJʩKʨKɨJɨJɨJɨJɨJɨIɨJɨIɨIɨIɨIɧIɧIɧIɧIȧIȧIȧIȧIȧHȧHȧHȧHȧIɨJǦGǦGǦGǦGǦGǦFǦFǥFǥFǥFǥFǥFǥFǥFǥFǥFǥFƥFǥFǥFƥFƥEƥEƥEƥEƥFǥFǥFǥFǥFǥFǦFǦFǦFǦGǦGǦGȦGȧHȧHȧHȧIȧIȧIɧIɧIɧIɨIɨJɨJɨIɨJɨJɨJɨJɨJɨJɨIɨJɨIɨIɧIίZϝڲԺpɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨJɨJɨJɨJɨJɨJʪNĄɐ̬SɨJɨJʨKʨKʨKʨKʩKʩKʩKʩKʨKʨKʩKʨKʩKʩKʨKʨKʨKʨKʩKʩKʨKʨKʨKʨKʨKʩKʨKɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɧIɧIɧIɧIɧIȧIȧIȧIȧIȧHȧIȧIʨJǦGǦGǦGǦGǦGǦGǥFǦFǥFǥFǥFǥFǥFǥFƥFƥFƥFƥEǥFǥFǥFƥFƥEƥEƥEƥFǥFǥFǥFǥFǥFǦFǥFǦFǦGǦGǦGȦHȧHȧHȧHȧIȧIѴe̖ϜѶfɨJɨJɨJɨJɨJɨJɨJɨJг`߼ݷɨIг`Θ߽џӸkɨIɨIɨIɨIɨIɨIɨJʪOΙ޺ݸ֪ͭVʩKʩKʩK̭Sɏџв_ʩKʩKʩKʨKʨKʨKʨKʨKʨKʨKʨKʨKʨKʨKʩKʨKʨKɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɧIɧIɧIɧIɧIɧIȧIȧIȧIȧIȧIȧIʨJǦFǦFǦFǦFǦFǦFǦFǥFǥFǥFǥFǥFǥEǥEƥEǥEƥEƥEǥEǥEǥEƥEƥEƥEƥEƥEƥEǥEǥFǥFǥFǥFǥFǦFǦFǦGȦGȦGȦGȧHȧHֽwֽwɨJɨJɨJɨJʩLНܵ׾w̬P˫N˫N˫N˫N˫N˫NѵbѝÁɨIɨIɨIɨJռsljΰX˫N˫N˫N˫N˫N˫NͮTÁŅʩKʏح˫PʩKʨKʨKʨJʨKʨJʨJʨJʨJʨJʨJʨKʩKʩKʨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɧIȧIɧIɧIɨIɧIɧIɧIȧIȧHȧIȦHɧIʨJǦFǦFǦFǦFǦFǦFǥFǥFǥFǥEǥEǥEǥFǥFǥEǥEǥEǥEƥEǥEƥEƥEƥEƥEƥEƥEƥEǥEǥEǥFǥFǥFǥFǦFǦFǦGȦGȦGȦG˫P޻ת~ҷgΰYѵc}֩޻˫QɨJ̭TٯΰY˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫OLjٮҶeΰYѴazԥͮVɨI͖ջp˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫NѵdăѴaϲ]׾vٰͮVʩKʨKʨKʨKʨKʨKɨJɨJɨJɨJʨJʨKʨKɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨHɧIɧHɨIɨIɨIɧIɧIɧIɧIɧIɧIɧIʨIǥFǥFǥFǥFƥFƥFƥEƥEƥFƥEƥEƥEƥEƥEƥEƥEƥEƥEƥDƥEƤEƤEƤEƥEƥEƥEƥEƥEƥFƥEƥFǥFǥFǥFǦFǦGǦGǦG̮WɎ̬P˫N˫N˫N˫N˫N˫N˫NˬOɎѴdջo˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫NͮTÁ̬Q˫N˫N˫N˫N˫N˫N˫N˫OƇخϙ˫O˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫NŅz˫N˫N˫N˫N˫N˫NѵdɨLɨKɨKɨKɨKɨKɨKɨJɨJɨJɨKɨKɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɧIɧIɨIɧIɧIɧIɧIɧIɧIȧIȧHȧIɨJǥFǥFǥFƥEƥEƥEƥDƥDƥEƥEƥEƥEƥEƥEƤEƤDƤDƥEƤEƤDƤEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEǥFǦFǦFǦFǦFǦGʪPϲ\˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫Nг^ϱZ˫N˫N˫NͮTÁ׫ܵ̓Ѵa˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫NΰX|˫N˫N˫N˫Nջqџԣ׿x̬P˫N˫N˫Nӷhӷh˫N˫N˫N˫N˫N˫N˫N˫NΰYňͯYӸkѴd˫PʨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨJɨIɧIɨIɨIɧIɧIɧIɧIɧIȧIȧIȧIȧIɨJǥEǥFƥEƥEƥEǥFƥEƥEƥEƥEƥEƥEƥEƥEƥEƤEƤDƥEƥEƤDƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEǥFǦFǦFǦFǦFǦG޺ͮT˫N˫N˫NӸhʏӣحԥʐӸi˫N˫N˫NͮUΰX˫N˫Nӹj޺ljˬO˫N˫NҶeɍԤجӡˑӷh˫N˫N˫N̬Q׿x˫N˫NΰXҠ׬г_˫N˫N˫N˫N˫NϱZȋե׫͖ҷf˫N˫NÁɨJɨJɨJɨJʨKɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨJɨIɧIɧIɧIɧIɧIȧIȧIȧHȧIȧIȧIȧIɨIǥFƥEƥEƥEƥEǥFǥFƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥDƥEƥEƥEƥEƥEƥEƥEǥFǥFǦFǦFǦGǦGԻrϲ]˫ṊRϙΘ̭R˫NΰXг^˫NΰXݸԥҠͯV˫N̬PԺn˫N˫Nˑӣ̬Q˫NͮTحѴa˫NͯXʨKɨJɨJʨKʨKɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɧIɧIɧIɨIɧIȧIȧIȧIȧIȧIɧIɧIɨIƥEƥEƥEƥEƥEƥEƥEƥEƥEƥDƥDƥEƥEƥDƥDƥDƥDƥDƥDƥDƥDƥEƥEƥEƥDƥEƥEƥEƥEƥEƥEƥFǦFǦFǦGǦGʐ˫Nּrռq˫N˫N˫Nջpz˫N˫NͮU׿xҶeӸhг_˫N˫N˫N̬Qƈ̭UɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIȧIȧIɨIȧIȧIȧIȧIȧIȧHȧIȧIȧIȧIȧIȧIɨJƥEƥEƥEƥEƥEƥEƥDƥDƥEƤEƤEƤDƤEƤEƤDƤDƤEƥEƥEƤEƤEƥEƥEƥEƤEƥEƥEƥEƥFƥEƥEƥFǥFǦFǦGҷk̬Pńă˫N|͕ϲ]˫O˫N˫N˫N˫N˫N˫NΰYɨJɨJɨKɨJɨJɨJɨJɨIɨJɧIȧIȧIȧIȧIȧIȧHȧIȧIȧHȧHȧHȧHȧHȧIȧIȧIȧIɨJƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƤEƤEƤDƤEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥFǥFǥFֽw֩ջqתņҶdȊѝΗz̭R˫Nϱ[ԺpɨKɨJɨJɨKɨKɨJɨJɨJɧIȧIȧHȧHȧHȧHȧHȧHȧIȧIȧHȧHȧHȧIȧIɧIȧIȧIʨJǥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥDƤDƥDƥEƥDƥDƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEǥEǥEˬTحд`͖˫OΘܷɨJɨJʨJɨJɨJɨJɨJɨIɧIȧIȧIȧHȧHȧHȧHȧHȧHȧHȧIȧHȧIȧIɧIɧIȧIȧIʨJƥEƥEƥEƥDƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEǥFϲ`ɍ̬P˫Nljϲ]ʨJʨKʨKʨKɨJɨJɨIɨIɨIɧIɧIȧIȧIȧHȧIȧIȧIɧIɧIɧIɧIɧIɧIɧIȧIȧIʨJƥEƤEƤEƤEƤEƤEƤEƥEƤEƤEƤEƥEƤEƤEƤEƤEƤDƤEƤEƥEƥEƥEƥEƥEƥEƥEƥEƤEƤE̮XΰY˫N˫Nг_ΘʩJʨKɨJɨJɨJɨJɨJɧIɧIȧIȧIȧIȧIȧHȧIȧIȧIȧIɧIȧHȧIȧIȧIȧIȧIȧIɨJƥEƤDƤDƤDƤDƤDƤDƥEƥEƤDƤDƥEƤEƤDƤDŤDŤDƤDƤEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥF̬P̬QʐʩJɨJɨIɨJɨIɨJɨIɨIɧIȧIȧIȧIȧIɧIȧIȧIȦHɧIɧIɧIȧIȧIȧIȧIȧIɧIʩJƥEƥEƤDƤDƤDƤDƤEƥEƥEƥEƥEƥEƤEƤDƤCƤDƤDƤDƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEɏͮUռqʩKɨJɨJɨJɨJɨJɨJɨIɧIɧIɨIɨIɨIɧIȧIȧIȧIɧIȧIȧIȧIȧIɧIɧIɧIɧIʩJƥEƥEƤEƤDƤDƥEƤEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥFȦH׿xLjʨKɨJɨJɨJɨJɨIɨJɨIɨIɨIɨIɧIɧIȧIȧIȧIȧIȧIȧIȧIȧIȧIɧIɧIɨIɨIʩKƤDƤDƤDƤDƤDƤDƤDƤDƤEƥEƤEƤEƤEƥEƥEƥEƥEƤEƤEƥEƥEƥEƥEƥEƥEƥEǥE{|ʨKɨJɨJɨJɨJɨIɧIɧIɧIɧIɧIȧIȧIȧHȧIɧIɧIȧHȦGȧHȧHȧHɧIɧIɧIɨJʩKŤDŤDƤDŤDŤDƤDƤDƤDƤDƤEƥEƥEƥEƥEƥEƥEƥEƤEƥEƥEƥEƥEƥEƥFƥFƥFƥF۴̓ɨJɨJɨJɨJɨJɨIɨIɧIɧIȧIȧIȧHȧGȧHȧHȧIȧIȧIȧHȧHȧHȧHȧHȧHȧIɨIɨJʩKŤDƤDŤDŤDŤDŤDŤDƤDƤEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥFƥFǥFתΰ[ɨJɨJɨJɨJɨJɨJɨIɧIɧIȧIȧIȧHȧHȧHȧHȧIȧIȧIȧHȧHȧHȧIȧIȧIɧIɨJɨJʩKŤCŤCŤCŤCƤDŤDŤDƤDƤDƥDƥDƥDƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEǥFǦFǦFв_ɨJɨJɨJɨJɨJɨJɨIɨIɧIȦHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧIȧIȧIɧIɨIɨJɨJʩKŤCŤCŤCŤCƤDƤDƤDƤDƤDƤDƥEƥDƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEǥFǦFǦFϚ˪NʩKʨJʨKɨJɨJɨJɨJɨJɨIɨIȦHȧGȧHȧHȧHȧHȧHȧHȧIȧIȧIȧIȧIȧIȧIȧIɧIɨJɨIʩKŤDţCţCŤDŤDƤEƤEƤEƤEƤEƤEƥEƥEƥEƥEƥEƥEƥEƥFƥFƥFƥEƥEƥEƥFǥFǦF׫гaɨKʩKʩKʩJʨJʩKʨKɨJɨJɨJɨJɨIɨIȧIȧHȧHȧHȧHȧHȧIȧIȧIȧIɧIɨIȧIȧIȧIȧIȧIɨJɨIʩKŤCŤCŤCŤDŤDƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEǥEǥFίYɨJɨJʩKʩKʩKʩKʩKʩKʨKɨJɨJɨJɨIɨIȧIȧIȧIȧGȧHȧIȧIȧIȧIɨIɨJɨJɨJɨIȧIȧIɧIɨIɨJʩKŤCŤDŤDŤDƤDƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥFƥEƥEƥEƥFǥFƥFƥFǥFǦF߽ʩKʨKʨKʩKʩKʩKʩKʩKʩKʩKɨKɨJɨJɨIɧIȧIȧIȧIȧIȧIȧIɧIɧIɨIɨJɨJɨJɨJɨJɨIɧIɨIɨIɨIʩKŤDƤDƤDƤDƤEƥEƥEƥEƥEƥEƥEƥEƥFƥEƥEƥFǥFƥEƥEƥEƥEǥFǥFƥFƥFǥFǦF˔в_ʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKɨKɨJɨJɨIȧIȧIȧIȧIȧIȧIȧIɧIɨIɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIʩKŤCƤDƤDƤDƤEƤEƤEƤEƥEƥEƥEǥEƥEƥEƥEƥEƥEƥEƥEƥEǥFǥEǥFƥEǥEǥFǥFˬU̔ʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKɨJɨJɧHɧIȧIȧIȧIȧIȧHȧHȧIȧIɧIɧIɨJɨJɨIɧIɧIɧIɧIȧIɧIɧIʨJŤDŤDƤDƤEƤEƤEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥFƥFǥFƥFƥEƥEƥFƥFƥFǥF׮ڲʩKʩJʩKʩKʩLʩKʩKʩKʩKʩKɨKɨJɨJɨIȧIȧIȧIȧIȧHȧIȧIȧHȧHȧIȧIȧIɧIɨIɨIȧIȧIȧIȧIȧIȧIȧIɨJƤDƤDƤEƥEƥEƤEƥEƥEƥFƥFƥFƥEƥFƥFƥEƥEƥEƥEƥEƥEƥFƥFƥEƥEƥFƥFƥFǥFʫR˔զʩLʩKʩKʩLʩLʩLʩKʩKʩKʩKʩKɨJɨJɨIȧIȧIȧIȧIȧIȧIȧHȧIȧHȧHȧHȧHȧIȧIȧIȧIȧIȧHȧHȧHȧHȧHȧHɨIƤCƤDƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEǥFƥEƥEƥEƥEƥEƥEƥEǥFǥFǥFƥEƥEƥFǥFǥFǥFռvʫQдeΚԺpŇɨJ̬Qݷ{ʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKɨJɨJɨIɨHɧIȧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧGȧHȧHȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHɨIƤDƤEƤEƥDƥEƥEƥEƥFƥEƥEƥEƥEƥEƥFƥEƤEƤEƥEƥEǥFǥFǥFǥFǥFǥFǥFǥFǥFǥFǥFąȎǦHǦGǦGɨLѠѵeȧIȧI˫Rը߼вaɨIɨJʨKʨK|ȋ׾wƇ˪NʩKʩKʩKʩLʩLʩLʩKʩKʩJʩKʨKɨJɨJɨJɧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȦGȧHȧHȧHȦHȧHȦHȦHȦHȦHȦHȦHȦHȦGɧHƥEƥEƥEƥEƥEƥEƥFƥEƥFƥEƥEƥEƥFƥFƥFƥEƥEƥFƥFǥFǥFǥFǥFǥFǥFǦGǦGǦGǥFǥFƥFսwʫRǦG̯Y׿{Ȍ€ϳbǦGǦGǦGǦFǦGǦGǦGˬSОԺqǦHȧHȧHȧIȧIȧIȨJӸmÄƉֽvʫPȧHȧIɧIɨJɨJɨJɨJɩKăȌ˫OʩKʩKʩK˪NӸkăɎÁջq̬QʩKʩKʩKʩKʩKʩLʩLʩLʩLʩKʩKʩKɨKɨJɨJɨJɧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȦHǦHǦHǦGǦGǦGǦGǦGǦGȧHƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥFƥFƥFƥEƥFǥFǥFǥFǥFƥFƥFǥFǦFǥFǥFǦFǦGǦFǦFǦFǦGǦFˬSڲņǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǦGǦGǦFǦFǦFϳanj߽֫۵ΚԼtɨLǦFǦGǦFȦGȧHȧHȧHȧHȧIȧIȧGȧGȧHȧHȧHȧHȧIɧIɨIɨIɨIɨIɨIɧIˬTҢݹܷէÂΰYʨKʩKʩKʩKʩLʩKʩKʩKʩLʩKʩKʩKʩKʩKʩJʩKʩKʩKʩLʩLʩKʩKʩKʩKɨJɨJɨJɨJɧIȧIȧHȧHȧHȧHȧHȦHȦHȦGȦGȦHȦHȦHȦHȦHȦHȦGǦGǦGǦGǦGǦGǦGǦFǦFǦFȦGƥFƥEƥEƥEƥFƥEƥEǥFǥFǥFǥFƥFƥFƥFƥFǥFǥFǥFǦFǥFǥFǦFǦFǦFǦFǦFǦFǦGǦGǦGǦGǦFǦFǦF̭V̖ܶ׿|ȧIǦGǦGǦGǦGǦGȦHȦGǦGǦGǦGǦGǦGǦGǦGǦFǦGǦFǦFǦFǦFǥFƥFƥFƥEƥEƥEƥEƥEǥFǦFǦGǦGȦHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧIȧIɧIɧIɧIȧIȧIȧHȧHȧIɧIɨIɨJɨJɨJɨJɨJʨKʩKʩKʩLʩLʩLʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩLʩKʩKʩKʩKɨJɨJɨIɨIɧIȧIȧHȦHȦHȧHȧHȦHȦHȦGǦGǦGȦGȦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǥFǥFƥFƥEǦFǥFǥFƥFƥFƥFǥFƥFǥEǥFǥFǥFǥFǥFƥFǥFǥFǥFǥFǥFǥFǥFǥFǥFǥFǦGǦGǦGǦGǦGǦFǦFǦGǥFǦGǦGǦGǥFǥFǦGǦGǥFǥFǦGǦGǦGǦGǦGǦGǦGǦGȦHȦHȦGȦGȦGǦGǦGǦGǦGǦFǦGǦGǥFǦGǥFǥFǥFƥFƥEƥEƥEƥEƥEǥFǥFǥFǦGǦGǦGȦGȦHɧHȦHǦGȦGȦGȦGȦHȦGȦHȧHȧHȧHȧIȧIɧIɧIȧIȧIȧHȧIɧIɧIɧIɧIɧIɨIɨJɨJʨKʩKʩKʩLʩLʩLʩLʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKɨJɧIɧIȧIȧIȧHȧGȦGȦGǦGȦGȦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǦGǦGǥFǥFǥFǥFƥEƥEǦFǥFƥEƥEǥEǥEǥFƥEƥEǥFǥFǥFǥFǥFǥFǥFǥFǥFǥFǦFǦFǦFǦGǦFǦGǦFǦGǦGǦGǦGǦGǦFǦFǦFǦFǦFǦFǦFǦFǦFǦFǥFǥFǦFǦGǦFǦFǦGǦFȦGȦGȦGȦGȦGȦGȦGǦGǦGǦGǦGǦGǦFǦFǥFǥFǥFǥFǥFǥFƥEƥEƥEƥEƥEƥEǥFǥEǥFǦFǦGǦGȦGȦGǦGǦGǦGǦGǦGǦGǦGȦHȧHȧHȧIɧIɨIɨIɧIȧIȧIȧIɧIɧIɧIɧIɧHȧIȧIɧIɨJʨKʩKʩKʩLʩLʩLʩKʩKʩKʨKɨJɨJʨKʨKʨKʨKʩKʩKʩKʩKʨJɨJɨJɧIȧIȧIȧHȧHȦHȦGǦGǦGǦGǦGǦGǦGǦFǦFǦGǦGǦFǥFǥFǥFǥFǦFǥFǥFǥFǥFǥEƥEƥEƥEǥFƥEƥEƥEƥFǥFƥFƥEƥEƥFǥFǥFǥFǥFǥFǥFǥFǥFǦGǦGǦGǦGǦGǦGǦGǦGǦFǦGǦGǦFǦGǦFǥFǦFǦGǦGǦGǦFǦGǦFǦFǦFǥFǦGǦGǦGǦGǦGǦGȦHȧHȧHȦHȦHȦHǦGǦGǦGǦFǦGǦGǦGǦGǦGǥFǥFǦFǥFƥFƥFƥFƤEƥEƥEƥFƥEƥFƥFǥFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȦHȧHȧIɨIɨJɨJɨJɨJɨIɨJɨJɨJɨIɧIɧIȧHȧIȧIȧIɨJʩKʩKʩKʩLʩLʩKʩKʩKʩKɨKɨJɨIɨJɨJɨJɨJɨJɨJɨKɨJɨJɨJɨIȧIȧHȧHȧHȦHǦGǦGǦGǦGǦGǦFǦFǥFǦFǦFǥFǦFǥFǥFǥFǥFǥFǥFǦFǦFǥFƥFƥEƥEƥDƤEǥFƥEƥEƥEƥFǥFǥFƥEƥEƥFǥFǥFǥFǥFǦFǥFǥFǥFǦFǦFǦGǦGǦGǦGǦGǦGǦFǦGǦFǦFǦFǦFǦFǦFǦGǦGǦGǦFǦFǦFǦFǦFǦFǦFǦGǦGǦGǦGȦHȧHȧHȧHȧHȧHȧHȧHȦHǦGǦFǦGǦGǦFǦFǦFǥFǦFǦFǦFǦFǦFǥFƤEƥFƥEƥEƥEǥFǥFǦFǦGǦGǦGǦGǦFǦFǦFǦGǦGǦGǦGȦGȧHȧIɨIɨJʩKʩKɨJɨJɨJʨKʩKɨJɨJɨIɧIȧIȧIɧHɨIʨKʩKʩKʩLʩKʩKʩKʩKɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɧIɧIȧIȧHȧHȧHȧHȦGǦGǦGǦFǦFǦFǥFǥFǦEǦGǦFǥFǥFǥFǥFǦFǦFǦFǦFǥFǦFǥFƥEƥEƥEƥEƥDǥEƥEƥEǥFǥFǥFǥFǥFǥFǥFǥFǥFǥEǥFǥFǥFǥFǥFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǥFǦFǦGǦGǦGǦFǥFǦFǥFǥFǦFǦFǦGǦGǦGȦGȦHȦHȦHȦHȧHȧIȧIȧIȧHȦHǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǥFǥFǥFǦGȦGȦHȦHȦHǦGǦGǦGǦGǦGȦHȦHǦGȦHȧHȧIɧIɨJʨKɨJɨIɨJʩKʩKʩLʩLʨKɨJɨJɨJɨJɨJɨJʨKʩKʩKʩKʩKʩKʨKɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɨIȧIȧIȧHȧHȧGȧHȦHǦGǦGǦGǦFǥFǥFǥFǥFǥFǦFǥFǥFǥFǥFǥFǦGǦGǦGǦGǦFǥFǥFǥFƥEƥEƤEƤDǥEǥFǥFǥFǦFǥFǥFǥFǦGǦGǥFǥFǥFǥFǥFǥFǥFǥFǥFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǦGǦGǦGǦGǦFǥFǦGǦFǦFǦFǦFǦGǦGǦGǦGȦHȦHȦHȧHȧHȧIɧIȧIȧHȧHȦHȦGȦGȦHȦHȧGȧHȧHȧHȦHȦHȧHȧHȧIȧHȧHȦHȧHȧHȧIȧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȦHȧHȧHɧIɨJɨJɨJɨJʨKʩKʩKʩKʩLʩKʩKʩKʩKʩKʨKʨKʩKʩKʩKʩKʨKʨKɨJɨJɨIɨIɨIɨIɨJɨJɨIɨIɧIɨIɧIȧIȧHȧHȧHȧHȧHȦHǦGǦGǦGǦFǦFǥFǥFǥFǥFǥFǦFǥFǦGǦGǦGǦGǦGǦGǦFǦGǦGǦGǦFǥFƥEƤEƤEƤDǥEǥFǥFǦFǦFǥFǥFǥFǥFǥFƥEƥEƥFƥFǥFǥFǥFǦFǥFǦFǦFǦGǦGǦGǦFǦFǦFǦGǦGǦGǦFǦFǦFǦFǦFǦFǦFǥFǥFǥFǥFǦFǦFǦFǦGǦGǦGȦGȦHȦGȦGȧHȧHȧHȧIȧIȧHȧHȧHȧHȧHȧIȧIȧIȧIȧIɧIȧIȧIɧIɨJɨJɨIɨIȧIɧIɨIɨJɨIɨIɨIɨJɨJɨJɨIɨJɨJɨIȧIȧHȧHȧHȧHɨIɨJʩKʩKʩKʩKʩLʩLʩLʩLʩLʩLʩLʩLʩLʩKʩKʩKʩLʩLʩKʩKʨKɨJɨJɨJɨIɨIɨIɧIȧIȧIȧIȧIȧIȧHȧHȧHȦGǦGǦGǦGǦGǦGǦGǦFǦFǥFƥFƥFƥFǥFǦFǦFǥFǦFǦGǦGǦGǦGǦFǥFǦGǦGǦGǦFƥFƥEŤDŤDŤDƥDǦGǦFǦFǦFǥFǥFǥFǥFƥFƥEƥFǥFǥFǥFǥFǥFǦFǦFǦFǦGǦGǦGǦFǦFǦFǦFǦGǦGǦGǦGǦFǦFǦFǦFǦFǦFǦFǥFǦFǦFǦFǦFǦFǦGǦGǦGȦGȧHȦHȧHȧHȧHȧHȧIȧIȧIȧIȧIɧIɨIɨJɨIɧIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʨKʨKʨKʩJʩJʨKɨJɨIȧIȧIȧIɨIɨJʩKʩKʩKʩKʩLʩLʩLʩLʩLʩLʩLʩLʩLʩKʩJʩKʩLʩLʩLʩKʩKʩKʨKʨKɨJɨJɨJɨIɧIȧHȧHȧHȧHȧHȧHȧHȧHǦGǦGǦGǦFǦFǦFǦFǥEƥFƥFǥFǥFǥFǦFǦFǥFǥFǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGƥFƥEŤDŤCŤCƥDǦGǦGǦFǦFǦFǦFǦFǥFǥFǥFǥFǥFǥFǥFǥFǥFǦFǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǦGǦGǦFǦFǦGǦFǦGǦGǦGǦGǦGǦGǦGǦGȦGȧHȧHȧHȧHȧHȧHȧIȧIɨIɨIɨJɨJɨJɨJɨJɧIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʨKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʨKɨJɨJɨIɨIɨJɨJʩKʩKʩKʩKʩLʩLʩLʩLʩLʩLʩLʩLʩLʩKʩKʩLʩLʩLʩLʩKʩKʩKʩKʩKʨKɨJɨJɨJɨIȧIȧHȧHȧHȧHȧHȧHȦHǦGǦGǥFǥFǥFƥFƥFǥFƥEǥFǥFǦFǦFǦFǦFǥFǥFǥFǦGǦGǦGȧHȧHȦHǦGǦGǦGǦFƥFƥEƤDŤCţCƥEǦGǦGǦFǦFǥFǦFǥFǥEǥFǥFǥFǦFǦFǥFǥFǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǦGǦGǦFǦGǦFǦFǦFǦFǦFǦFǦFǦGǦGǦFǦFǦGǦGǦGǦFǦGǦGȦGȦHȧHȦHȧHȦGȦHɧIɨJʩKʩKʩKʩKʩKʨKɨJɨJʨKɨJɨJɨJɨJɨJɨJɨJɨJɨJʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʨKɨJɨJɨJɨJʨKʩKʩKʩKʩLʩLʩKʩKʩLʩLʩKʩKʩKʩKʩLʩLʩLʩLʩLʩKʩKʩKʩJʩKʩJʩKʨKɨJɨIɨIȧIȧHȧHȧHȧHȧHǦGǦGǦFǥFƥEƥEƥEƤDƥEǥEǥFǥFǦFǦFǦFǥFǥFǥFǥFƥEǥEǦFǦFȥFȦHȦGǦGǦGǦGǦFǥFƥEƤDŤDţCƤDǦGǦGǦGǦGǦFǦFǥFǥFǥFǥFǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǦFǦGǦGǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǦGȦGȦGȦHȦHȧHȧHȦGɦHɨJʩKʩKʩKʩKʩKʩKʩKʩKʨKɨJɨJɨJɨJɨJɨJʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKɨJɨJɨJʨKʩKʩKʩKʩKʩLʩLʩLʩLʩKʩKʩKʩJʩKʩLʩLʩLʩLʩLʩKʩLʩLʩKʩLʩLʩLʩKʩKʨJɨJɨJȧIȧHȧHȧHȦHǦGǥFǥFƥEƥEƥEƥEƤEǥFǥEǥFǦFǦGǦGǦFǥFƥEƥDƥDƥEƥEǥFǦFǥFǦGǦGǦGǦGǦGǥFǥFƥEƤDŤDŤCƤDǦGǦGǦGǦGǦGǦGǦGǦFǦFǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǦGǦGǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFȦGȧHȦHȦHȧHȧHȧHɧIɨJʩKʩKʩKʩKʩKʩKʩKʩKɨKɨJɨJɨJɨJɨJʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKɨJɨJɨJɨJʩKʩKʩKʩKʩKʩKʩKʩLʩKʩKʩKʩJʩLʩLʩLʩLʩLʩKʩKʩLʩLʩLʩLʩLʩLʩLʩLʩKʨKɨJɨJȧIȧHȦHǦGǦGǥFƥFƥEƥEƥEƥEǥFǦGǦGǦGǦGǦGǦGǦFǥFƥFƥEƥDƥEƥEƥFǦGǦGǦGǦGǦGǦGǦGǦGǥFƥFƥFƤEŤDƥDǦGǦGǦGǦGǦGǦGǦFǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǦGǦFǦFǦGǦFǦGǦGǦGǦGǦGǦGǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȧHȧHȧHȧHȧHȧHȧHɧIɨIʩKʩKʩKʩKʩJʨKɨJɨJɨJɨJɨJɨJɨJɨJʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʩKʩKʩKʩKʩKʩKʩKʩKɨJɨJɨJɨJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩLʩKʩKʩKʩKʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩKʨKɨJɨIȧHȦHǦGǦFƥFƥEƥEƥEƥEǥFǦGȧHȦGǦGǦGǦGǦFǦFǦFǥFǥFƥFƥEƥEƥEǦFǦGǦGǦGǦGǦGǦGǦGǦGȦHȦHǥFƥEƥDȦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȦGȦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǥFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȦGǦFǦFǦGǦGǦGǦGǦGǦGȦGȦGȦGȦHȦHȦHȦHȧHȧHɨJɨJʨKʨKʨKʨKʨKɨJɨJɨJʨKʨKɨJɨJʨKʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʨKɨJɨJɨJʨKʨKʩKʩKʩJʨKʨKɨJɨJɨJʨKʨKʨKʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩLʩKʩLʩLʩLʩLʩLʩLʩLʩLʩKʩKɨJɨJȧHȦGǦGǦGǥFƥEƥEƥEƥFǦFȦHȧHȦGǦFǦFǦGǦGǥFǥFǦFǦFǦGǦGǦFǥFǦFǦGȦHȦHȦHȦHȦHȧHȧIɧIȧIȦGƥEƥDȦHȦGǦGǦGǦGȦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȦHȧHȧIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʨKʨKʨKʨKʩKʩJʩJʩKʩKʩKʩKʩKʩKʩKʨKɨJɨJɨJɨJɨJɨJɨJʨKʩKʨKʩKʨKɨJɨJɨJɨJɨJɨJɨJʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʨKʨKʩKʩKʩKʩKʩKʩLʩLʩKʩLʩLʩLʩLʩLʩKɨJɨJȧHȦGǦGǦGǦFǥFǥFǥFǥFǦFȦGȧHȦGǥFǥFǦGǦGǦGǦGǦGȦGȦGȦHȦHȦGȦGȧHȧHȧIȧHȧHȧHɨJɨJɨJɨIȦGƥEƥDȦHǦGǦGǦGǦGǦGǦFǦFǦGǦGǥFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǦGǦGȧHȧHɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨKʨKʨKʩKʩKʩKʩKʨKʩKʩKʩKʨKʩKɨKɨJɨJɨJɨJɨJɨJɨJɨJɨKɨKʨKʨJʨKɨJɨJɨKɨJɨJɨJɨJʨKʩJʩKʩKʩKʩKʩKʩKʩKʨKʨJʨJʩKʩKʩKʩKʩKʩKʩKʩLʩLʩLʩLʩLʩLʩKɨJɨJȧHȦHǦGǦGǦFǥFƥFƥFǥFǥFǦGǦGǦGǥFǥFǦGǦGǦGǦGȦHȧHȧHȦHȧHȧHȧIȧIɨIɨIȧIȧIɨJʨKʩKʩKɨJǦGƥEƥDȦHȦHȦHȦHǦGǦGǦFǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȦHȧHȦHǦGǦGǦGǦGǦGǦGǦGǦGȦHȦHȧHȧHɧIɨJɨJɨJɨJɨIɨIɧIɨIɨJɨJɨJɨJɨKʩKʨKɨJɨJʨKʨKɨKɨJɨJɨJɨJɨJɧIɧIɧIɧIɧIɨIɨJɨJɨKɨKʨKɨJɨKʩKɨKɨJɨJɨJʨKʩKʩKʩLʩKʩKʩKʩKʩKʨKʨKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩLʩLʩLʩKʩKɨKɨIȧHȧHǦGǦGǦFƥFƥEƥFǥFǦFǦGǦGǦFƥFǦFǦGȦHȧHȧHȧHȧHȦHȦHȧHɨJɨJɨJɨJɨJɨJɨJɨJʩKʩKʩKɨJȧHǥFƥEȦGȦHȦHȦHǦGǦGǥFǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǦGȦHȧHȧHȦHȦHȦHȦHȦGǦGǦGȦHȦHȧHȧHȧHȧIɧIɨIɨIɧIɧIȧIȧIɧIȧIȧIɨJɨJɨJɨJɨIɨIɨJɨJɨJɨIɨIȧIȧIȧIȧIȧHȧHȧHȧHȧHȧIɨJɨJɨJɨJɨKɨJʨKʨJʨKɨKʨKʨKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʨKʨKʩKʩKʩKʩKʩKʨKɨKʨKʨKʩKʩKʩLʩKʩKɨJɨIȧHȧHǦGǦGǦGǥEǥFǥFǦGǦGǦGǦGǥFƥEǥFǦGȧHȧHȧHȧHȦGǦGȦHɨIʨKʩKʨKɨKʨKʨKʨKʨKʨKʩKɨKɨJȧHǥFǥEȦGȦGȦGǦGǦGǦFǥEǦGǦGǦGǦGǦGǦGȦGȦGȦGǦGȦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȦGǦGǦGǦGǦGǦGȧHȧHȧHȧHȧHȧHȦHȦGǦGǦGȦHȦHȦGȦHȧHȧIɧIɧIȧIȧIȧIȧIȧIȧHȧHȧHȧHȧIȧIȧIȧHȧIȧIɧIȧIȧHȧHȦHȦGȦGȦGǦGǦGǦGǦGȦGȧHȧIɨIɨJɨJɨJɨJʨKʨKʨKʨKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʨKʩKʨKʨKʩKʩKʩKʩKʩKʨKɨJɨJɨJʨKʩKʩKʩKʨKɨJɨIȧHȦGǦGǦGǦGǥEǥFǥFǦGǦGǦGǥFǥFǥFǥFȦGȧIȧIȧHȧHȦGȦGȧHɨJʩKʩKʩKʩKʩKʨKʨKɨJɨJʨKɨJɨJȧIǦGǦEǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȦHȧGȧHȧHȦHȧHȦHȧHȦHǦGǦGȧHȦHǦGǦGȦHȧHȧIȧIȧIȧIȧIȧIȧHȦHǦGǦGȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȦHǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȧHȧIɨIɨJɨJɨJɨKʨKʨKʨKʩKʩKʩKʩJʩKʩJʩKʩKʩKʩKʩKʨKɨKɨKʩKʩKʩKʩKʩKʨKɨJɨJɨJɨIɨJɨJɨJɨJɨJȧIȧHǦGǦGǦGǦGǦGƥFƥFǥFǦGǥFƥFƥFƥFǦFȦHȧIȧIȧIȧHȧHȧHɨJʩKʩKʩKʩKʩKʨKɨKɨJɨJɨJɨIɨJɨJɨIȧHǦGǦGǦGǦGǦGǦGǦGǦGǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǦGǦGȦGǦGȦGȦGȦGȧGȦGȧHȦGȧHȦGȧHȦGȧHȧHȧHȧHȧHȧIȧIȧIȧIȧHȦGǦGǦGǦGǦGǦGǦFǦGǦGȧHȧHǦGǦGǦGǦGǦFǦGǥFǥFǥFƥFƥFǥFǦFǦFǦGȧHȧIɨIɨJɨJɨIʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʨKʩKʩKʩKʩKʩJʨKɨJɨJɨJɨJɨIɨJɨJɨJɨJȧHȦGǦGǦFǦFǦFǥFƥFƥEƥFƥFƥFƥEƥFƥFǥFǦGȧHȧIɧIɧIɧIɨJɨJʩKʩKʩKʩKʩKʨKɨJɨJɨJɨJɨJɨJɨJȧIȧHȧGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȦHȦHȦHȦHȦGǦGȦHȦHȦHȧHȧHȧHȧGȧHȧIȧHȧHȧIȧIȧGǦFǦGǦGǦGǦGǦGǦGǦGǦGȦGȦGǦGǦGǦGǥFǥFǥFƥFƥFƥEƥEƥEƥEƥEƥEǥFǦGȦHȧIɧIɨJɨJʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʨKʩKʩKʩKʩKʩKʩKʨKʨKɨKɨJɨIɨIɧIɨIɧIȧHǦGǦFƥFƥFƥFƥFƥEƥEƥEƥEƥEƥEƥEƥEƥEǥFȦHȧIɧIɨJɨJɨKʨKʩJʨJʩKʩKʩKʧJɧJɨKɨJɨJɨJɨIȧIȧHǦGȧGǦGǦGǦGȦGȦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȦGȦGȦGȦHȦHȦHȦHȦGȦGȦGȦHȧHȧHɧIɨJɨIɧIȧIȧIȧIȧHȧIȧGȧHǦGǦGǥFǥFǥFǦGǦGǦGǦGǦGǦGǦGǦGǦGǥFƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEǥFǦFǦGȧHɧIɨJɨJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʨKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKɨJɨIɧIȧIɧHɧHȧHǦFǥFƥFƥEƥEƥEƥEƥEƥEƤEƤDƤDƤDƤEƤEƥEǦGȧHɧIɨJɨJɨKɨJɨJɨKʨKʨKɨJɨKɨKɨJɨJɨJɨJɨIȧIȦHǦGȦGǦFǦGǦGǦGǦGǦFǦFǥFǦFǦFǦFǦGǦGǦGǦGǦGǦGǦGǦGȦGȦGȦGǦGǦGǦGǦGǦGǦGǦGȦGǦGȦGȦGȦGȦGȦHȧGȧGȧHȧHȦHȦGȦGȦGȦGǦGǦGȦGȧHɨIɨJʨKɨJɨJɧIȧIȧHȧHȧHȧHȦHȦGǦGǦFǥFǥFǦGǦFǦFǦGǦFǥFǥFǥFǥFǥFƥEƥEƥEƥEƥEƥEƤEƥEƥEƥEǥFǥEǦGȧIɨJɨJʩKʩKʩKʩKʩKʩKʩKʩLʩLʩKʩKʨKʩKʩKʨKɨJɨJʨKʩKʩKʩKʩKʩKʩKʩKʨKɨJɨIȧIȧIȧIȧIȧHǦGǥFƥEƥEƥEƥFƥEƥEƤEƤDŤDŤCŤCŤDŤCŤDƥFǦGȧIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʨKɨIɨJɧIȧHȦHɧHǦFǦGǦGǦGǦGǦGǦFǦFǥFǥFǥFǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGȦGȦGǦGǦGǦGǦGǦGǦGȦGȦHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧGȦHȦGȦGǦGǦGǦGȦHȧIɨJʩKʩKɨKɨJɨIȧIȧIȧIȧHȧHȧHȦGǦGǦFǦFǥFǦFǦFǥFǥFƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥFǦFȦHȧIɨJɨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKɨKʩJʩKɨKɨJɨJɨKɨJɨJɨKʩKʩKʩKɨKɨJɨJɨJȧIȧIȧIȧIȧHǦGǦFƥFƥEƥEƥEƥEƥEƤDŤDŤDţCţCģCģBģBģBţCǦGȧIȧHȦGȧGȦHȧHɨJɨJɨIɨJɨJɨJɨJʩKɨJɨJɨJȧIȧIɨIǥFǦGǦGǦGǦGǦFǦFǥEǥFǥFǥFǦFǦFǦGǦGǦGǦGǦGǦGǦGǦGȦGȦGȦGȦHȦGȦGȦHȦHȧHȧHȧHȧHȧHȧIȧHȧIȧIȧIȧHȦHȦGȧHȦHǦGǦGǦGȦHȧIɨJʨKʩKʨKɨJɨIȧIȧHȧIȧIȧHȦGǦGǦGǦGǦGǥFǥFƥFƥFƥEƤEƤDƤDƤEƤEƥEƥEƥEƥFƥFƥEƥEƤEƤEƤDƤEƥEǥFȦGȧHɨIɨJʨKʩKʨKʨKʨKʩKʩKʩKʩKʩKʨKʨKʩKʩKʩKɨKɨKɨKɨJɨJɨKɨKɨKɨJɨIɨJɨJɨJɧIȧIȧIȧHȧHǦGǦGǥFƥFƥEƤEƤEŤDŤDŤDŤDģBĢAâ@á@âA >>ţCƥEģCá@á@á@â@ƤEȧIɧIɧIɧIɨIɨIɨIȧIȧIȧIȧIȧHɧHǥFǦFǦFǦGǦFǥFǥFǥFǥFǥFǥFǥFǦFǥFǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȦGǦGȦGȦHȧHȧHȧHȧHȧHȧIȧHȧIȧIȧIȧHȧHȦGȦGȦGȦGǦGǦGȦGȧHɨIɨJɨJɨJɨJɨJɧHȧIȧIȧHȧHǦGǦGǦGǦGǦFǦFǥFƥFƥEƥEƤEƤDŤDƤDƤEƥEƥFƥFƥFƥEƤEƤDƤDŤDŤDŤDƥEǦFǦGȦHȧIɨJɨKʩKɨKʨKʩKʩKʩKʩKʩKʨKʨKʩKʩJʩKʩJʩJʩKʩKʨKʨKʨKɨKʨKɨIɨIɨJɨJɨJɨIȧIȧHȧHȦGǦGǦFǦFƥFƥEƤEŤDţCţCţCţCģBâ@á?á@á?<:< > >;997;ģBǦFȦHǦFǦGǦGǦGȦGȦGȦGǦGǦGȦGƥFǥEǥFǦFǥFǥFǥFǥFǥFǥFǥFǥFǥFǥFǦFǦGǦGǦGǦGǦGǦGǦFȦGȦFȦGȦGȦGȦHȦHȧHȧHȧIȧIȧIȧIȧIɧIɧIȧIȧIȧHȦHȦGȦGȦHȧHȦGȦGȧHȧIɨIɨJɨJɨJɨJɨIɨIɧIȧHǦGǦGǦGǦGǦFǦFǥFǥFǥFǥFƥEƤEƤEƤDƤEƥEǥFǥFǥFƥEƤEƤDƤDƤDŤDƤDƤDƥEǦGȦHȧHȧHɨJʨKʨKɨKʩKʩJʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʨKʨKʩKʨKɨKɨJɨJɨJɨJɨIȧIȧHȧHǦGǦFǦFǦFǥFƥEƤDŤDţCţCţCģBģBâAá@á@ >;:99:976558<¡?¡?¡?ĢAţCŤDŤDģBţCƥEǦGƥEƥEƥEǥFǥFƥFƥFƥFǦFǦFǦFǦFǥFǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȦHȦHȧHȧHȧHȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧIɨJɨJɨJɨJɨJɨIȧIȧHǦGƥFǥFǦFǥFƥFƥFƥEƥFƥFƤEƤDƤEƤEƥFƥFƥFǦFƥFƥEƤEŤDŤDŤDŤDŤDŤDƤEǦGȧHȧIȧIɨIʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʩKʨKɨKɨJɨJɨJɨJɨIȧIȧIȧHǦGǦGǦGǦFǦFƥFƤDŤCţCţCģCģBâAâ@¡?><:9987766554332369:979á@ŤCƥFƥFǥFƥFƥFƥFƥFƥFƥFǥFǥFǥFǥFǥEǦFǦGǦGǦGǦGǦGǦGǦGȦHǦGǦGȦHȦHȦHȧHȧHȧHȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧIȧIȧIɧIɧIɨIɨJɨIȧHǦGǥFƥEƥEƥFƥFƥEƥEƤEƤEƤEƤEƤEƤDƤEƥEƥFǥFƥFƥEƤEƤDŤDŤDŤCţCţCŤDƤEǥFȦHȧHȧHɨIʨKʩKʩKʩKʩKʩKʩJʩKʩKʩLʩKʩKʩKʩKʩJʩJʩKʩKʨKʨKʨKʨKʨKɨJɨJɨJɨJɨJɨIɧIȧIȧIȧHȦHȦHǦGǦGǦGƥEƤDţCţCģBĢAá@¡?=<:9877765544320/..////036ƥFƥFƥEƥEƥFǥFƥFƥFƥFǥFǥFǥFǥFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȦHȦHȦHȧHȧHȧHȧIȧIɧIȧIȧIȧIȧIȧIɧIȧIȧIȧHȧHȧHȧHȧGȧHȧIɧIȧIȧIȧIɧIɧIɧIȧIȧGǦGƥFƥEƥEƥEƥEƥEƥEƤEƤEŤDŤDƤDƤEƤEƥEƥFǥFƥFƥEƤEŤDŤDŤDŤCŤDŤDŤDƥEǥFǦGȧHȧHɨJɨJʩKʩKʩKʩKʩKʩKʩKʩLʩLʩKʩLʩKʩKʩJʩKʨKʨKɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɧIȧIȧIȧIȧHȧHȦHǦGǥFƤEŤDţCģBĢAá@ >=;:8876654443210/....././2ƥFƥFƥEƥEǥFǦFǥFƥFǥFǥFǥFǥFǦFǦGǦGǦFǦGǦGȦHȦHǦGǦGǦGǦGǦGǦGǦGȦHȧHȧHȧIȧIȧIȧIɧIɧIȧIȧIɧIɧIɧIȧIȧHȧHȧHȧHȧHȧIȧIȧIȧIȧIȧIȧIȧHȧHȦHǦGǦGƥFƥEƤEƤEƥEƥEƥEƤEŤCŤCţCŤDƤEƤEƥEƥEƥEƥFƥEŤDŤDŤDŤDƤDƤEƥEƥEƥFǦGȧHȧHȧHɨJʨKʩKʩKʩKʩKʩL˩LʩLʩLʩLʩKʩKʩKʩKʩKʩKʩKɨJɨJɨJɨJɨJɨIɨJɨJɨJɨIɨIɨJɨIɨJɨJɨHɧIȧIȧHȧHǥFǦFƥFŤDģBĢBâAá@ >=;986654554332110////////1ƥEƥEƥEƥEƥFƥFǥFǦFǦFǥFǥFǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȦHȧHȧGȧHȧIȧIȧIɧIɨIɧIʨIɨIɨIɧIȧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȦHǦGǦGǦFǥFƥEƥEŤDƤDƥEƥEƥEƥEŤDŤCŤCŤDŤDŤCŤDŤDƤDƤDŤDŤDŤDŤDŤDŤDƤDƥEƥEǥFǦGȧHȧIȧIɨJʩKʩKʩKʩKʩKʩKʩLʩLʩLʩLʩKʩKʩJʩKʨJɨKɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨIɨJɨJɨJɨIȧIȧHȧHǦGǦGǦFǥEƤEģCâAá?¡?¡?>=;755444432210////....//0ǥFƥFƥFƥEƥEƥFƥFǥFǦGǦGǥFǦGǦGǦGǦGǦGǦGȦHǦGȦHȦHǦGǦGǦGǦGȦHȦHȦHȦHȧHȧIȧIȧIɧIɧIɨIɧIɨIɨJɨIɧIɧIȧIȧHȦGȦHȦHȦHǦGȦHȦGȦHȦHǦGǦGǦGǦGǥEƥEƥEƤEƤEƤEƥEƥEƤEƥEƤDŤDŤDŤDţCţCţCţCţCŤDŤDŤDŤDŤDŤDŤDŤDƤDƥEǥFǦGȧHȧIȧIɨJɨKʨKʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʨKɨKɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɧIȧHȦHǦGǦGǦGǥFƥFŤDģCá@>> ? > >=:7665322220//////...//0ǥFƥFǥFƥEƥEǥFǥFǥFǦGǦGǦGǦGǦGǦGǦGȦHȦHȦHȦHȦHȦHȦGȦGȦHȦHȦGȦHȧHȧHȧHȧIȧIȧIɧIɧIɧIɧHɨIɨJɨIɨIɧIȧIȦHȦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǦFǥFƥFƥEƤEƤDŤDƤEƥEƥEƤEƤDŤDŤDŤCţCţCģBģBģBţCŤCŤDŤDŤDŤDŤCŤDŤDƥEǥFǦGȧHȧHɧIɨJɨKʨKʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKɨKɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɧIɨIɨJɨIȧIȧHǦGǦGǥFǥFǥFƥEƤDţCá@<;<====<9764221110......-....0ǥFƥFƥFƥEƥEǥFǥFǥFǦFǦGǦGǦGǦGȦHȦHȧHȧHȧHȦHȦHȦHȦHȦHȦHȧHȧHȧHȧIȧHȧHȧHȧIȧIɧIɧIɧIɨIɨIɨJɨJɨIɧIȧIȧGȦHǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǥFǥFǥFƥFƥEƥEƤEƤDƥDƥEƥEƥEƤEŤDŤCŤCŤCţCţCţCţCŤCŤDŤDŤDƤCƤDŤDŤDƤEǥFǦGǦGȦHȧHɧIɨJʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩK˩KʩKʨKɨKɨJɨJɨJɨJɨJɨJɨJɨIɨIȧIȧIȧIɧIɨJɨJɧIȧHǦGƥEƤEƤDŤDŤDƤDţCâ@<9:;;;<<;:73221100/.......//./1ǥFǥFƥFƥEƥEǥEǥEǥFǦFǦFǦGǦGǦGȦHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧIȧHȧHȧHȧHȧHȧHȧIɧIɧIɧIɧIɨIɨJɨJɨIɨIɧIɧIȧHȦGǦGǦGǦGǦGǦGǦGǦGǦGȦGǦGǦFǦGǦGǥFǥFǥFƥEƤDƤEƥEƥFƥEƥEŤDŤCţCŤCŤCţCŤCŤCŤDŤCţCţCŤDƤDƤDƥEƥFǦFǦFǦGȦHɧHɨJɨKʨKʨKʨKʩKʩKʩKʩLʩLʩKʩKʩKʩKʩKɨKɨKɨJɨJɨJɨJɨJɨJɧIȧIȦGƥDƥFȦHȧIɧIȧIȧGǦFƥEģBá@ > >¡?¡?á@ >:98889:;:9621100///........../1ǥFƥFƥEƥEƥEǥFǥFƥFǥFǥFǥFǦGǦGȦHȧHȧHȧHȧHȧHȧHȧHȧHȧIȧIȧIȧHȧHȧHȧIȧIȧHȧIȧIɧIɧIɨIɨJɨJɨJɨIɧIɧIȧIȧHȦGǦGǦGǦGǦFǦGǦGǦGǦGǦGǦGǥFǦGǦGǦGǦGǥFƥEƤEƤEƥEƥEƥFƥEŤDŤCţCţCţCţCţCţCţCģCģBģBţCŤDƤEƥEƥEƥFƥFǦGȧHɧIɨJɨJʨKʨKɨJʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKɨJɨJɨJɨJɨJɨJɨJɧIȧHŤC=¡?ŤDƥFǥFǥFƥEģCĢA >;::99::8777666776420/..-------....../1ƥFƥEƥEƥEƥFƥEƥEƥFǥFǥFǦFǦGȦGȧHȧHȧIȧIȧIȧIȧHȧHȧIɧIɧIȧIȧIȧIȧIȧIȧHȧHȧIɧIɧIɨJɨJɨJɨIɨJɨIɧIɧIȧIȧHȧHȦGǦGȦGȦHȦHȦGǦGǦGǦGǦGǦFǦGǦGǦGǦGǦGǦFƥFƥEƥEƥFƥFƥFƥEŤDŤCţCţCģBĢBģCģBģBģBģBţCŤDƤEƥEƥFǥFǦGȦGȧHɧIɨJɨJɨJɨJɨJɨJʨKʩKʩKʩKʩKʩKʩKʩKʩKʨKɨJɨJɨJɨJɨJɨJɨJɨIȧHģC;:==> ? ?==<999888877665543221/...------..//./0012ƥDƥEƥFǥFǥFƥFƥFǥEǦFǦGǦGǦGȦGȧHȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧHȧIȧHȧHȧIɧIɧIɧIɨIɨJɨJɨJɨJɨJɧIɧIȧIȧIȧHȦHǦFȥGȦHȦHȦGȦHǦGǦGȦGǦGǦGȦGȦGȦGǦGǦGǥFƥFƥFƥFƥFƥFƥEƤEţCģBģBĢAĢAĢBĢBģBĢBĢBģBţCƥEǥFǦGǦFȦHȧHȧHɧIɨIɨJɨJɨJʨKɨJʨKʩKʩKʩKʩKʩKʩKʩKʩKʨKɨJʨKʨKɨJɨJɨJɧIɧIȧIƥE¡?9999:99:9888888766554431/./.-----..--...../1113ƥFǥFǦFǦFǦFǦFǥFǥFǦFǦGǦGȦGȧHȧHȧIȧIȧIȧIȧIɧIɧIȧIȧIȧIȧHȧIȧIȧHȧHȧHɧIɧIɧIɧIɨJɨJɨJɨIɨJɨJɧIȧIȧHȧHȧGȦGǦGȦGȧHȧHȧHȧHȧHȦHȧHȦGǦGȦGȦGȦFǦGǦFǥFƥFƥEƥEƥEƥEƤDŤDţCĢAĢAâAâ@â@ĢAĢAĢAĢAģBŤCƥEǦGȦGǦGǦGȦHȧHɧHɨJɨJɨJɨJʨKʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨJʨKʨKʨKɨIɨJɨJɧIɧIȧIǦGŤD=:9988888876665443333320.---,,,------,-../01123ǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȦHȧHȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧHȧHȧHȧHȧHȧIȧIȧIȧIɧIɧIɧIɧIɧIɧIȧIȧIȧHȦHǦGǦGǦGǦGȦHȧHȧHȧIȧIȧIȧHȧHǦGǦGǦGǦFǦFǦGǥFƥFƥEƥEƥEƥEƤEŤDţCģBĢAâAá@¡@á@âAá@âAĢAģCŤDƥFǦGǦGǦFƥEǥFǦGȦGȧIɨJɨJɨJɨJɨJɨKʨKʩKʨKɨJʨJʨKʨKɨKɨKɨJɨJɨJɨIɨJɨJɨIȧIȧHǦGƥEģB =;98887776665433212331/.,--,,,------,-./012223ǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȦHȦHȧHȧIȧIȧIȧIȧIȧIȧIȧIȧIȧHȧHȧHȧHȧHȦHȧHȧHȧIȧIȧIȧIȧIȧIȧIȧIȧHȦHǦGǦGǦGǥFǥFǦGȦHȦHȧHȧIȧIȧIȧIȧHǦGǦGǦGǦGǦGǦGǥFƥEƤEƤEƤEƤEŤDţCģBĢBâAâAá@¡?¡@á@á@âAĢAģCŤDƥFǦGǥFƤEŤDƤDƥEǥFǦGɧIɨJɨJɨJɨJɨJɨJɨJɨJɨJʩKʩKʨKɨKɨJɨKɨJɨJɨJɨJɨJɧIȧHȦHǦGƤEţCá@=;9888776554322212320..-,,,,,,---.--../012323ȦHȦHȦHȦHǦGǦGǦGǦGǦGȦHǦGǦGȦHȧHȧIȧIȧIȧIȧIȧIȧIȧHȧHȧHȧHȧHȧHȧHȦHǦFǦGȦHȧHȧIȧIȧHȧHȧHȦHǦGǦGǦGǦGǦGǦGǦFǦGȦHȦHȧHȧHȧIȧIȧHȦHǦGǦGǦGǦGǦGǦGǥFƥEƥEƤEƤEƤDŤCţCĢAâAâ@á@á@ >¡?â@âAâAĢAţCŤDƥEƥEƤEŤDŤDŤDƤDƥEǥFȦHɧIɨJɨJɨIɨJɨJɨJɨJɨJʨKʨKɨKɨKɨKɨJɨJɨJɨJɨJɨJɧIȧHǦGǥFƤDĢB¡?=;9877765443111100110.-,++++++,,--,-..//12234ȧHȧHȦHȦHȦHȦHǦGǦGǦGȦHȦHȦHȦHȦGȦHȧIȧIȧIȧIȧIȧHȧHȧHȧHȧHȧHȧHȧHǦGǦGǥFǦGȧHȧHȧHǦGǦGǦGǦGǦGǦGǦGǦGȦHǦGǦGǦGȦHȦHȦHȧHȧHȧHȦHǦGǦGǦGǦGǦGǦFǦFƥFƥEƤEƤEƤDŤDŤCģBĢAâAâ@á@á@¡?â@ģBģBţCŤCƤDƤEƤEƤEƤDƤEƥEǥFƥFƥFǦFǦGȧIɨIɨJɨJɨJɨJɨJɨKʩKʩKʨKʨKɨKɨKɨJɨIɨIɨJɨJɨJȧIȧHǦGƥFŤCá@==<97776544421100//00/.-,++,++,,,,---./0012333ȧHȧHȦHȦHȦHȦHȦHǦGǦGǦGǦGǦGȦHȧHȦHȦHȧIȧIȧHȧHȧHȦHȦHȧHȧHȦHȦHǦGǦGǥFƥFǦFǦGȦHȦHǦGǥFǥFǦGǦGǦGǦGȦHȦHǦGǦGǦGȦHȦHȦHȧHȦHǦGǦGǦGǦGǦFǥFǥFƥFƥFƥEƤEƤDŤDŤDŤDţCţCĢBĢAĢAĢAĢBĢBţCƤDƤDƤDƤEƥFƥFƥFǥFƥFǥFǦGǦGǦGǦGȦHȦGȧIɨJɨJɨJɨJɨJɨKʩKʩKʨKʨKʨKʨKɨKɨKɨKɨJɨJɨJɧIȧIȦHǥFƤEģB >;;:87765544322100//..---,,-,++,,,,--../0123333ȧHȧHȦHȧHȦHȧHȦHǦGǦGǦGǦGǦGǦGȦGȧHȧHȧGȧHȧHȦHǦGȦHȦHȧHȦHǦGǦGǥFƥEƥEƥEƥFǥEǦGǦGǦFƥFƥFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǦFǦGǥFƥFƥFƥEƥEƤEŤDŤDŤDŤCţCţCţCģBĢBģCŤCƤEƥFǦFǦGǥFǥFǥFǦGǦGȦHȦHǦGȦHȧHȦHȧHȧHȧHȧHȧHȧHɧIɨIɨJɨJɨJʨKʨKʨKɨJʨKʨJʨKʨKɨJɨJɨJɨJȦHȧHǦGƥEţC¡?<988776654432220//----++,,--++*++++,,../0122223ȧHȦHȧHȧHȧHȧHȦHǦFǦGǦGǦGǦGǦGǦGȦHȧHȧHȧHȧHȦHǦGǦGȦHǦGǦGǦGǦGǥFƥEƥEƥEƥEƥEǥFǦGǦGǥFƥFǥFǦGǦGǦGǦGǦGǦFǦFǥFǦFǦGǦGǦGǦGǦFǥFƥFǥFǥFƥEƤEƤEŤDŤDŤDţCţCţCţCţCţCģCģCţCƤEǦFȦHȧHȧHȦHǦGȧHȧHȧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȦHȧHȧIȧIȧIɨIɨJɨJʩKʩKʩKʩKʨKʨKɨJʨKɨJɨJɨJɨJȧIȦHƥFţC¡?<:988877654432220/.-,,,++,,..,+++++,--./01222224ȧHȧHȧHȧIȧIȧHȦHǦGǦFǥFǦFǦGǦFǦGǦGȧHȧHȧHɦHȦHǦGǦGǦGǦGǦGǦGǦGǦGǦFǥFƥEƤDƤEƥFǥFǦGǦEǥFǥFǦGǦGǦGǦGǥFƥFƥEƥFƥFǥFǥFǥEǥFǥFǥFƥEƥFƥEƤDŤDŤCţCţCţCģCģBģCţCţCţCţCţCţCƥEǦGȦHȧGȧHȧHȧHɧIɧIɧIȧIȧIȧIȧIȧIȧHȧHȧHȧHȧHȧHȧIȧIȧIɨIɨIʨKʩKʩKʩKʩKɨJɨJɨJɨJɨJɨJȧIȧHȧHǥFţC ?;99988888655432220.-,,++,,--.-,+*+++,-./001233333ȧHȧHȧHȧHȧHȦHǦGǦFǥFƥFƥEƥEƥEǥFǦFǦGȦGǦGȦGȦGȧHǦGǦFǥFǦFǦGȦGȧHǦGǦFƥEƤDƤEƥEǥFǦFǦFǥFǥFǦGǦFǦFǦFƥEƤDƤDƥEƥEƥEƥEƥEǥFƥFƥEƥEƥEƤEŤCŤCģBģBģBģBģBģBģBţCţCţCŤCŤCŤDƥEǦFǦGȧHȧHȧHȧIȧIȧIȧIȧIȧIȧIȧIȧHȧIȧIȧIȧIȧIȧIȧIȧIɧIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨIɨIȧIȧHǦGƥFƥEâA<::9888777664442221/-,++++,----,+))**++--.//0122223ȧHȦHǦGȦHǦGǦGǦGƥFƥEƤEŤDŤDƤEƥEƥEǥEǥFǥFǦGǦGǦGǥFƥFƥEǥFǦGȦHȧHȦHǥFƥEƥEƤEƥEƥFǥFǥFǦGǦGǦGǥFǥFƥFƤEŤCŤCŤDƤEŤDƤEƥEƥEƥEƤEŤDŤCŤDţCģBâAâAâAâAâAĢAĢBģCţCŤDŤDŤDƤEƥFǥEǦGǦGȧHȧHȧIȧIȧHȧHȧHȧHȧHȧIȧIȧIȧIȧIȧIȧHȧIɧIɧIȧIɧIɧIȧIȧIȧIɧIɨIɨJȧIȧIȧHǥFŤDâA¡?=;99998898876544322210-++++,-..-,+*****++,--/01122223ȧHȦHǦGǦGǦGǥFƥFƥEƤEŤDţCţCŤDŤDƤEƥEƥEƥEƥEǥFǥFƥEƤDƤEǥFǦGǦGȦHȦHǥFƥEƥEǥFƥFǥFǥFǥFǦGǦGǦFǥFƥEƥEƤEŤDŤDŤCŤCŤDƤDŤDƤEƤDŤDŤDţCţCģBĢBâA¡? >>¡?á@âAĢBģBŤDƤDŤDƤEƥEǥFǥFǦGȦGȧGȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧIȧHȧHȧHȧHȧIɧIȧIȧHȧHȦHȧGȧGȧHȧHȧHǦGǦGƥEĢA=::999998888887544322110.,+**++,--,+*******++,-//0111123ǦGǦGǦGǦFǥFƥEƥEƤEŤDŤCţCţCţCţCŤDƤDƤEƥEƤEƤEƤEŤDŤCŤDƤEƥFǦGǦGǦGƥFƥEƥEǥEƥFƥEƥEƥEǥFǥFǥFƥFƥEƤEƤDƤDŤDŤCŤDŤDŤDŤDŤDƤDŤDţCģBĢBĢBĢAá@¡?<;; > ? ?á@ģBţCŤDŤDƤEƥEǥFǦFǦGǦGȦHȧHȧHȧHȧGȧHȧHȦHȦHȧHȦHȧHȦHȧHȦHȧHȧHȧHȦHǦGǦGǦGǦGǦGǦGǥFƥEŤCâ@=98999999888888764322100/.-+++++,--,+++******+,-./0111222ǦFǥFǥFǥFƥEŤDŤDŤDţCţCģBģBģBţCŤDŤCŤDŤDŤDŤCŤCŤCţCţCŤCŤDƥEǥFǥFƥEƥEƥEƥEƥEƤEƤDƥEƥEƥEƥEƥEƥEŤDŤDŤCţCţCŤCŤCŤCţCţCŤCŤCģBĢAâAâAâAá@ ?<:;<<;<>á?ĢBţCŤDŤDƥEǥEƥEǥFǦGǦGȦHȦHȦHȦHȦHǦGǦGǦGǥFǥFǥFǥFǥFƥFƥEƤEƤEƤDŤDƤDƤEŤDţCģBá@=;:88999999888887654322210/.-,,,,,--,,,+********+-./0011111ƥEƥEƥEƤEƤDţCģBģBĢBĢBĢAĢAģBģBģCţCţCģCģBģBģBģBģBĢBģBģBţCŤDƥEƤEŤDƤEƤDŤDŤDŤDƤEƥEƤEƤDŤDŤDţCģBģBģBĢBģBĢBĢAĢAģBģBĢBĢAâAá@¡?¡? ? >=<;<<;:9;=¡?¡?> ?âAģBţCŤDƥEƥEŤCģCŤCƤEƤDŤDŤDţCģBĢAá@¡? >>>>=<==<<;978888888988888766653211110.-,,+++,,,,,,+**)))))))+-///00001ƤEƥEƤEƤEŤDģCĢBĢAĢAĢAâAĢAĢAâ@ĢAģBģBģBģBģBĢBâAâAâAĢAĢAĢAģBţCţCŤCţBţCţCţCţCŤDŤDŤDŤCģBĢAâAâAâAâAâAá@á?á@á@âAâAá@á@á@¡@ >==>>>=<<<:999975479;= >>;::= >á@¡?=<;987766667766667888888888888776654322100//-,++**+,-,,,+*)))((()**-//.00//0ƤEƤEƤEŤDŤDģBĢBĢBĢAâAâAâ@á@á@á@âAĢAĢAĢAĢAâAá@á@âAâAâAá@âAâAâAģBĢAģBģBģBģCţCģBţCģBĢAá@á@á@¡? ? ? > ?¡?¡?¡?¡?¡?¡@¡@ ?==<> ? >>==<<;:7554466568777789::877776655667777888877888788887766643211100//-,****++,,,+*)()((((**+-.../////ŤDƤDŤDŤCģBģBĢBĢBĢAâ@á@á?¡?á?¡?á@á@â@á@á@á@á?¡?á?á@á@á@¡?á?á@â@âAâAĢAĢBģBģBĢAâ@â@á@¡? > >=<<<==>> > >¡? >=<;<= > > >==<<<;87768:7567778888878777666666666678878777777778766555421110//.-,+))))**+++))((((''())*,,,----..ţCţCţCģBĢBĢBĢBģBĢAá@á?¡? ? ? > ?¡?á@á?á?¡? > >á?á@á@á@á?¡?¡?¡?á?á@á@á@âAâAá@ >==<;<;;::;;<<= > >==<=== = >===<=<;:988:866778888899888766777667677777787778776776554433110000/.-++))))*++*)(((('''''()+***+---,,ģCģCģBģBĢAâ@ĢAĢBâA¡@¡?¡? > > >>> > > >>> ?¡?á@âAá@¡? ?>> > ? ?¡?á@á@¡?=;:99999999::;===<<<===>>=====<;;:99:876788888889988877776767788877777788777766554432100000/.,+*))))*++*(((''('''(()*)(()*,,*+ģBģBģBĢBĢAâAâ@â@¡?¡?¡? > > > >>=>>>>>¡?á@á@á@á@¡? >==>>>> >¡?¡?=;977889999:;<<<<<;<=====<==<;;;;::;:767788878889988876677777787788887777777775544321//////.-+*)((())*))'&''''''''((('&'()))(*ģAĢBģAģBĢBâAâA¡? ?¡?¡? >> > >===> > > >¡?á@á@¡?¡? >>==<<<<=>==;99978:;;;;<<<<<<;;<<<=>====<;:;;;;98777788888899888767776788898888888777776655432210/////.-,+*))())*))''''''''''&'('&''((''*ĢBĢBĢBĢBĢBâAá@á@¡?¡? ? >> > >===>>> > >¡?á@¡? ? >>=<;;;;<<<;;:::9::;;<<=<<;<;;;;;<<=> >==<;:;;;:88877788888888887766776788899999888877776655432100////..-,++****))('''&'&&&''&''''&&&&&&')ģBģCģBģBģBĢBâAá@¡?¡? >>> >>====>>== ? ? >==<;:::::;;;:;;:::::;;<<<;;:;:899:::;<<;;;;:;;;98878778888888777776667778988899987877777654432100//...--,++****))(&&&&&&&%%%%%%%%%&%$$$%'(ģCţCţCţCţCģCģBâAá@á@ ?>>>>===>>>==>>=<;;::::::::::;;:::::;;<<<;;::9767889:9:99:::;;:98887888888887777777777788998999988877776653322000/..----,,,+**)('('&&%%&%%%%$$$$$%&%$$%%&(ţCŤDŤCŤDŤCŤDţCģBģBá@¡?>=========<<==<<;::99:::99::;:9::::::;;;::99865667888999::;;;:89987888888878776667788788999999998777765443221100.-.------,++*)('''&&&%%%%%$$##$%%$$$#%%&'ţCţCţCţCţCŤCŤCţCģBĢBá@ >=<===<<<<<<<<<;;:999999999999899999::9998876654467788899::::9888877887777777767766777789989998887775443321100/.----,,,,,+**)(''&%$$%$$$%$$##"###""##$%%'ţCţCŤCŤDŤDŤDţCţCģBģBâA¡? >===<<<<<<<;;;;:988888889999888888899988765544435678888999888888877877777766766667777788999998777664432221100/..---,,+++*)))('&%$$$$%%%%%%$$##$####$$%&(ģBģBģCţCŤDŤDţCģBĢBĢBâA¡? >>==<;<<<;:;:::9988777778988777788888876653333444667877788777777777778778767766778878888887777776653322221100/.-.-,,++***((('&&%$$$$%%%%&&%$$$$$$$$$$&')¡? > ?>= >âAĢ@â@¡? ? >==<;::::::9:999887666666777665567776665554322233455556677777776666566777766666677787777777665655554322111100/.-,,+++**)))''''&%$$#$$$$$%&%$$#####$$#$%&)><;:87:>=<<<;;::8899877888776455556656665456766665555432122344455556677766665555566666665567777777776665544433321121010//.-,,++*)))('''('%%$$$$$$$%&&%$$#""###$$$%&)á@ ?=;8568999998776576545566543123445544544345555665554332223334444445666765654555566665655666667776665554444322121110000//.--,+*))))(&&&'&%%$$$$$$$&&&%##"#$##$%%%&&(ĢAâ@ >;7455555455445332212333210/0123333343333445555444322112233223334455554555444555555554455455565565554431111221221/00//..-,+*)((''&&%&&%%$###$$$%%%%$#""""###$$$&&'âAâA¡?:65654432233443100122210/--.01112223432223554343210111123233343344444555444445455444455554544456554433100111112100///.-,+*)(''''&&$$%&%%%$$%&%&&&%$$#$##$##$$$&&'á@á@ ?;766555433455421111110/.-,++-/00111221111233322210/0011222344433444445544554444444444555554434555444221011111111100/..-,***(&&&&&$$$$%%%%%%$%$%%%%%$$$$%%%%%%&&%& ? >=:756554444543211000/..--,*))+-./000/000//00000000////01122433323343444444444444444343444433223444331100//000000000/.--,+*)('&%%%%$#$$#$#$$$$###$%%$%%%%&&&&&%%%$&><:8645555445543111100/--,,+)((*,-./0/.../...---//0//////01223334333333454555444443444333443333223333210000//0///00//.--++*))(''&%%%$#####"#$$$#""#%%%%&&'''&&%&&&%&<965554455444442122100/.-,++)((*++,..---..--,++-..///..//00233434343322455555554444333323333332223322100//////../0/..-,+**)'''''&&%%%#""""""$$#""##$$%%%&'''&%%&'&&&:5444444555544323432100/.,+)))))))+-.-,-,++,+++,--./..--//02233222222222344445444333222222232211222100////..-,--.---,+**)('%%&&&&&&&$! !"!!!!!!!""######%%%%%$%&&%%&844443455566433454443210.,+))**)))*+----,**+++,--...----./022232222222223333454544442221111211112221/////..-,+,,,,+++*))('&&'&&%%%&&%#!"!!! !!!!!"#####%$#$$%&''&&(64443345645543456443321/-,,)(*)(()*+,,,-+***++,---.--,-../022222222321332112234554432211111211111110//...---,++++*++((('&&%%'%%&&%%%$$" !!!!!!!!!"""###"####$%''&'(44333434444543445332211.,+*)()((())*,,,+**))*+,,,,---,,,-/011111111222221121124444321100110000110///.--,+++,,+**)**)'&&%$%%$#$#$%$###"  !!"""!""""##%%%%'34444433444444433433111.,+*)))))()))**++*****,,,-----,,,-/00011000111223222123333332210100000///0/..--,++++++**)))(&%%$$$$$$####"!"""" !!  !!!!!!"!!"##$$%&&24444443344444323442110.,++*)))))))))****)**,,,---------./000///0111222333322333233121000////////..--,++******))(''%$$######""""!!!""! ! ! ""##$%&&1234333333333422332210/-,+++))((())*)***))(*+,,,,,,--,--..////...0111222333322222211110///.//...-.-,,+*)))))((('&%%###"""!!! ! "!  !!!""#$%1112322222333322121210.--++++**())**)))**))*+,,,+,,,----.///0//..0111223343211211101110/...//.-..--,++*))((((('&%%$"##""!!  !!!!     !!""""$1111111222233211111100..-,,,,,+***))(()*****+,-,,,,,,-,,-./00/..///011233221110//0/0000/..../.----,,++*(('&&''&%$$#"#$#!!!  !      !!!!!!#0///0/111222220000000.-.--,,,,,+**))())))***+,,,,,,,--,,,-../....../112221100/....-.///...-----,,+***))('%%$%%%$#"!!!"! !     !0///0111222221100////-...-,,-,,,,+++***++*+++,--------,,,-../.---.../1211100...--..//.------,,,,+*)))((('%#$%%$#""!!!! !     !///00111111100/.../.....-----,,,,,,++**++++,-.......--,,---..------...0000/..-,---./.------,,,,+*)('&''''%$###""! !""!!   !////0/00000//.--...---------,--,--,++**+++,,,-.....---,,,-...---------.....-,-,---...------,,++*)((&%&&&%%$#""! !""!     !!.....././//..-,,--,,+,,---,,,,,+,,+++***+,,,,--------,+,,,,,-,,,,,,,,,,+,+,+,,,,,-...------,+**(('&%$%%%$#"!!     ......./...---,,,,,++++,,,,,,,,,,,,+,*++++,,,----,--,,,,,++,-,,,,,,,***)*))*+,,,,-..---,,,-,*()('&%$##$$#"!!  !-...--...--,,,,++*+++++,,,,,,+,,,,,,,+,,,,,,----,,,,,,,,-,,,,,,,,,,+**)('(()+++,--.-,,,,,+,,*(''&$$$####!!    !-----,---,++***********++++++++,,+,,++++++++,-,,,+++,,,,,+++++++++***)''&''()***+,,,*++**+**)'&%$#"""##"  -.-..,,,,+**)))***))*++*+++*+++,,,,-,+,+++++,,,,+++++,,+++++********)(((''&'((()*,++*******))'&$#"""#$"!    ....-,,++**))))))())*+,+,,++,,+,,,,,,+,++++++,+++****++****))('())))())(('&'(''')*++*******)((&##""""#"    ...--,++*))((())('(((*,,,++++*+,+++,++++++*+*+****))))*)()(''&&&&''()))))(&&'&%&')**(('''''''&$"!! !!!  /.---,,+**)))(()(''((*+,,,,,+*+++++,,++,++++****)))))))(('&&&$$%%%&())))))('(&%&()*)'&&%&&&&%$#!  0/.-,,-,+****)('''&'(*+++++++++++++++,,+++******)((((((''&&$$##$$$%'(('(()(('&&'())'%$##%$$##"!  0/..---,+*****((((''(()+****+**+++++,,+++++*****)(''''''&%$$##$##$%&&&&'((&&%%&'''(&%#""##"!!!!   //----,,,++++*)))('&''()**+*)**)***+**++++*))*)('''&&%%%$#"##$#####$$$$%&&%$#$$%%%&$!!! !  ./.-----,,,++++**)(&&'(())*))*)()*++*+*+******)('&&&%%%$###$$$######$$%%%$$#"####$#!   ///./.--,,,,+,,,+*)'&&&'((()))****++++*****)**)(&%%%%%%$#$#$%%$$$$$$$$$%%$####"!!!   0/../.-,,+,,,---,+*'$$$%&'''())))))***))))))))('&%$$$$$####$$%$%$#$$###$$$$#"!! 10//0/.,,--,--..-,*'#"##$&'''())(())))()())))((('&$$$$$$###$%$$$$$$%%$$$$##"!!! 110110/-----,-./.,*'#"""#%&'''(((((((('''()))(('''%$$$$$#$$$%$$%%$$%%$$$$#""!!  211210//.-.-,-...-*'$"!!#%&'&''&'''(('&&'(())(('('%%%%$$$%%%%$$%%%%&&%$#$$#!!! 322120/..--,-..//.+'$! "$%%%%%%%&&&'&%%&'''(((('''&%%%&$$$$%%%$%&%&%$$#"#"! 422220/...---.0//.+'$ "#$$$$%$$%%%%&%%%%&''())(''''&&&&%%%$$%%%%%&%$$$#"""!4322210/./.--.0//.+'$! #$%$###$$%%%%%$$$$%&'()))('((''&&%%%$$$%%%%&%$%$#"!! 44321011/./.../..,*&"!!#$$##!!""#%$$##"##$%&')(()(('(''%#####$%%%$%%$##"! 554321110////0//.,)%! "$$$#!!""#$$#""####%''((()((((('%#$$$$%%%%$$%$#""!  5544322110///////,($! !#$$$##"!###$#""#"""#%&(*((((((''%$$$$$$$%%$$%%$#!! 5443322210/.////.,($! !###$####""#$##""!!!#$&')()())(''&%%%%%$$%%$$%$$#"! 333222110/..////,)'# !""$$###""""$#! !!!#%&''(())'''&%%$$$$$$$$$##"!! 3332220//..../.-+)'$  !"#$#$#""""##""!!!!"$&&''''(('''&&&%$$$$$$$#"""! 221110/..-----,+*(&#  "##$$#""#$#$#""! !"#%&&''''((((''&%$$$######"!11000/.-,,,+,+**)'$#! !"""#$#$%$$#"!""" !"#%&&'&'(())'(('&%$$#####" jamulus-3.9.1+dfsg/src/res/CLEDGrey.png0000644000175000017500000001323714340334543016606 0ustar vimervimerPNG  IHDRH-=zTXtRaw profile type exifxڭi:sqF %(b_71n[RS$Teef6?>_IESl[llϟzwߏ/<5yAqS>uȯ:nsܽ~7u]_kq Xo.X^(yu!q k ?||%x~{(ͯ/1zwϱ:#9/t~%vz~Vc&Rټ^ĉP{Y/ܟOe-95}ߧL1 Oo~ _H2I\񦫌gzWct9s~Ċyyai(sz,+/_`a,b$p8/hS c'&`g3v}q8Vә2R˙CnB$z5s}aDC!5 Ɋ1+)hRJ9TSK=s9,%XRɥZZ5XS͵Z[ͷ[1zgέ;Ww}FiQFm |fiYfmWXʫUW[} vi]vmN8O9?_2Ys)cW>R޷p1/ʙ.F)gy"y撒2Fv>eL(o9Խ2{կ UbjÁ8ak&}_QάkuʚB"yl|Z+ӯs~AnN[R(ufYwݼ>-LtLAxFw8^w̱s:Egޚ~T\թ2OGͥRP-SaOS)1g9Uit|nn}0_f)7I@.ߚOO{m˱avcۑm ~1>YHj,{f"_2pr+JZuiε c_{WGI r@뚓(ܦma/4*LɿR.ʔjZ78S > &(1y-(k@c1d^ce~1l8t1M0njwo GWۍم-evP,c\=Thk'x,ӪD:Dt16_@Z$>]** 5lMMei)?~\% 5GJf1tL*x'V(ąE|Wx7χ q&*gNzfY~Q; %5aZZoϴ 8x- K lG{% "9;4@sUQN_`}c4kkbܭ`w Eoڅ;!m{:(>P '?jϲLKnfqXO.\'&^dHAUή>?nt{{]E632yr;9<|9w| <&PDAXJRM"=1T *Rl)MCh=1rUD?A1Y(įO]*a| +;:?3o`2 xL%kߺk쎎4tXEUgZB)[k }<єXKHRڮ~l*O9ly'7ؗTj*}*mY:?mN&a_uwWcb2z5+4=#znR#C/.2\mU;z?my[ Q*~2z*ݸ]qκcL2v´@[3qz$Ԇi}#S5lm\@Gj璱P*.xI3CaAv 奇.$oCu-EM(Rzp2 :iZIUMLgNMW}3cx-]wX2ŭ vA X=x.4XQl QP>3$u9@kH![ l}Y\A<q-Ģݶ0tt#|1r"6m4Q3s\"F0 z{cm YFFxG -}ǙlGP ,xmɦD(,j0%<0!ĽQ8ۈ 0m2ss0iLjA&]҅k*߯6 &.?aߝ&e6,*!2 va9{'m`r.i[{=˶OU:u ZURd):iU&(DkPSkUǐЭg1cȼ˜tAj G(jKE5>j}9^;x%7g=m:vwvVYiiz^! `p/bN r0{Svdw{ıj힌L4{=$"^׍7;d&W8qMfVOiY'Vfؔ0H.d1B^2y:XVT`-'pޮ2̄0#j+$ZS'1+߅ۻy%.2h՟1Io=ЮwocH2B~}um]ZS.?e>OjahNoNUe߀bKGD pHYs~uɍtIME4W*dIDAT(u=K+Q9gllb#W⟰Hk֦_XYX_҈fa?m4(^_f)(˲QaBGDd>L֟LCWmƯe 4M"ry~~؂u}NNNyoooi pqvvQu<8==r`0(1vf$a<1czƘZ;3:yk-)")UU=!0 W*>zlT{ʲmP۶eQ$IUi꺦io$IPGEQ6YV8pEZ*{yNjf󝝝kV"zyykv.r*"כq @Q)[vWmLʬws&Rs[l^xSx?ky98ߚ9?ym y&su B#D?wsn?l}kO ]!j9z[JnBܦ.4s}y ɯ=]e_o3≯5%0s{bG4u;K?=00 +[7/t睿?&[޳I˗A?{)uS̺žeh/ȈOP Ob)L'̕=Ol֘+~^';H.$-d%Al!N\J~HC"ֆwyXLC!7-Ɋ1+5r*$ sJRB%\Jƚjڪ4ljkM{ 3K6xL=SϽ[|FiQFm3LxYfmr (YyUW[;.#kOV'kdJǕq{4/L9#c>:2^4klu1z͜6OU$"f:+.hB\Χ>r?ʛy9;y3+YdV뫊**GyZs55Ynlk."UW {"GbCc4W&7BֽmU ;4rkQ%A):,Œ}ynye"$ד ]qu4޹ALoujwVJb2tE63d^ {hTMl=YdtJgq)XӸyS]*wQV`q[ <Ӫ İ tnlqIv @ϔ$`lC& DEAmOWK0Gg15wB%fB]qWWzPXT2֝E(, q͵ڛ3%uٻ A^ QY7IHH'uZUK EGm)x8!X\'C}x fV2hX4Fr04¥EHNj>м1v-k-pgvipBzR^T,eb!*s1𓑮&^^>@׋t%-:\&\&B 963~hމZ4 }n@b=$i%_s6փ-haA=݁}'KJZl{D6ʜ ¤pSڔ BERILGZPo鬻& P2nO=k:}UaϢ%gb&J4$ȵ-݆h^,'BLE"rx2(S[S6[M +P}1v(sP"(vˊ5TyUX;XJ;3QCnہI+:M FYʎ>"~U L O;kk{7fAsG-ܪQtGF#+u't,-qV.FN.@AEIY.R$B[7 Xz!E%/h%h1d~r4nN+EPTA,ik0jx[K :@C A9EOAFi,y8 I:ԚTd6Eu_F'NiQ#:ܜw+E}4HQtQN۱a>ez 547mңb5,Lڶ٣a[7 D@I)zx`6eɧ+K&>td)ϥѡ15>×U̗ɏ18:t<z0]М`7s"3h'T/nyl8fnnHJ` IL|}P% 9j4Zo4'q|gb#JPbRMt쓞 &jG_iGPpujKRNǀjG X214ܙ6Fo4GZUy:($cէY:7e%)w~\r9M8@4Iv'YF'F7WrnMHwS4 vƜ9S̃5ڰ6xBOs`T+mݪl.KbBN/Zm4X2c&fSHCư'Q*u< RORt4Lסlݙ;s/K@E4xr[} !Dqv&uCh1`wW}XR3J7ͷr)mAI{]3өāpu ])[Fnʗ&J66uNmԪ6㉟68Q1݂Ѷwf{tz&mvW.GW jw3VB:&:.*HKSwN[pgp^ ^Z|.7u?s'[p6F2S +UH4F1?m2-% khG\\[ [ p(LWCP=kLxaz̨ߪZv&4/@%kS Xrx,b FTdI!g!QzM\=1$rF/~cFt`z- T.с3in0 :zc[2.eHk1E+S_ 谪Z#Wi5rsЕhwl@<2L{03`~TxUAK <\]*zeW~NZJ^N~ą9~kB*wS{ 5`jt]B̥僪Z'~fƜrts]/#뒨c0pT`#A۲[5F鎆8N9#!qOEjBB@buGfKPBÂZg\z!A󁎻>/n1ТдpZ %FIa_yXTOƘo}'ŚK&\u 1tiCCPICC profilex}=H@_S"3:dNDE EPjVL.& IZpc⬫ ~9)HK -b<8ǻ{wP/346SɮJ]i 2|=|,s5g1 2ô76m>ȊJ|N]QscigJo+u`ZKuKSɐMٕ4|x?o}@[s@JH}j3~TrJ9bKGD pHYs  tIME7.bItEXtCommentCreated with GIMPWIDATX͙ϋE?U3o aC`\5J~ O ^;!$$'膀 Iٷ3]{x`a`0ߪV8sWud4M9d3qʏN{ڶΝ5FugiQr #:D_A9m{O !TͤI)1yAN;A( !Tg<3)M4 9%&}XZv׾{`fhۖ@yƣGCda+:ڶm[ X=EbTDeU0˨@1K;^z#^9r BB]׈1F/1XV)Biv>vއ+/CAq7D˜4-} zii'NP*v'Ɏwg`|sń;襽{>(f:̌u>*|x߾}u܅*VTUdҋǸu XpT1܌ut]7XO1%R0Dz<EPQ$U%+^B̦YU<3 Œ63 >,KгK_U1ۯt eFo;wēCIՋs#Yt9@Lrp5-~{ 8#2-fԘћ#:-fq:4_Ѐt UU݃@JN;,uUS:Ldf[R1}6|Rx!RqKP)Ŭ=Ξ+++hȞpw͆=l`NԀ`nFNF w?lP\I{a2'Odi^ԐSƧ.4*Fr6M ۸,//s"F٬4{ ۷_ypQ]xa4& D"fKL&ߣhXsizZ#!NrN]!w5RBJGAL5ȼiKqK{NɐHteRF smB0mX}Sg.QQRuxqKL,?z8(JmClb9B`2ACrD PבSWտź"ϼv_^03L:n\hXxIENDB`jamulus-3.9.1+dfsg/src/res/jamulus-server-icon-2020.ai0000644000175000017500000070400714340334543021352 0ustar vimervimer%PDF-1.6 % 1 0 obj <>/OCGs[22 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream application/pdf jamulus-server-logo-2020 Adobe Illustrator 25.0 (Macintosh) 2020-11-07T20:57:34+01:00 2020-11-07T20:57:34+01:00 2020-11-07T20:57:34+01:00 256 256 JPEG /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYqk nm3zr5V8o6YdT8x6lDptpWiNKSXkb+WONQzyN7KpxV45qX/OaH5YW9wYrPT9VvkBoZ1ihjQjxUST B/vUYqy3yR/zkp+VPm67jsbbUZNM1CYhYbTU0FuzseirIrSQk9qc6ntir1HFXYq7FXYq7FUNqOp6 dplnLfaldQ2VlCOU1zcOsUaDxZ3IUYq8X85/85efljobSW+jC48x3iVA+qj0bbkD0M8oBPzRGGKv FfM3/OY/5oakzpo0FloUB/u2ji+szgf5Tz8oz/yKGKvN9Y/OL81NYYm/81am6tWsUVzJBGa/8Vwm NPwxVi13qF/ePzu7mW5eteUrs5qfdicVQ+Ko2x1rWdPINhf3FoV+yYJXjpvXbgR33xVl2i/np+b2 jFTZ+a9QdVpxS6l+uIANgAtyJRT2xV6d5Y/5zT882RSPzDpNlrEI+1LDys5z7kj1YvujGKvb/JH/ ADlH+VHmdkt575tBv3IUW+phYkJ/yZ1LQ0/1mU+2KvWo5I5Y1kjYPG4DI6kFWUioII6g4quxV2Kv mv8AOf8A5y0j0PUJ/L/kSOC+vbcmO71qb95bo42KW6KQJCp/bJ417N1xV8/335/fnJe3P1ibzZfI /IsFgZYEqf8AiuFUSntTFWZ+Q/8AnLn8yNDuoo/MTp5j0qoEqTIkV0qdzHNGq8j/AMZFaviMVfYf kjzv5d86+XbfXtBuBPZzijoaCSGQAcopVqeLrXcfSKgg4qn2KvD/AM4f+cpPLfkm9m0PRLddc8wQ 1S5Afja20g/Yldal3HdF6dCwO2KvAr3/AJy4/Oe4uGlhvrOzQ9IILSIoPkZvVf72xVmPkX/nNLXo LuK386aXDeWLEB77T1MNwg7sYmZo5PkCmKvqvy75j0TzHo1trWiXaX2mXi84LiOtCOhBBoysp2ZW FQdjiqY4qknnXzbpnlHyrqXmPUyfqmmwmVkH2pHJCxxr/lSOyqPnir86vP8A5/8AMfnrzHPruuzm WeU8YIFqIoIgfhiiX9lV+8nc1JxVjeKuxV9e/wDOJ352ajrRbyH5iuDcXlrCZdEvJCTJJDF9u3dj uxjX4kJ/ZqOwxV9L4q7FWndI0aSRgiICzuxoABuSScVfPf5rf85deXNAebS/JccevaqlVfUGJ+oR N/klSGnP+qQv+UemKvlPzn+YnnPznem78yarPfkMWigZuMERO37qFaRpt4D54qxzFXYqyXQ/y1/M LXlV9H8uajewt0njtpfR3/4tKhPxxVmVl/zi3+d90oc+Xxboehnu7RT1p9kSsw+kYqmZ/wCcQ/zl AJFrYkjsLtKn7xiqU6h/zjB+d9khc+XTcIBUm3urWQ99uAl5np2XFWE6/wCQvO3l7kdc0G/06Ndj NcW8qRH5SFeB+g4qkOKuxVnP5e/nR+YXkOZRoepM1gDWTSrqs1o3j+7J+An+aMqffFX11+U3/OTP krzy0Om35GheYnoq2Nw4MM7Hb/R5iFBJP7DUbw5dcVRP/OTnnu78o/lXePYSmHUtYlTTLWZTRoxM rPM47j9zGyhh0JBxV8B4q7FXYq9z/wCcRvPl1of5kJ5dklP6K8xo8LxE/At1EjSQyAeLcWj9+Q8M VfTX/OQX5g3Pkb8sr/VLF/T1W8dNP02T+SacMS4/ykiR3X3AxV+eju8jtJIxd3JZ3Y1JJ3JJOKrc Vdir6C/5w+/MS70jzs/k64lZtK19Xe3jJ+GK9hjLhxXp6kSFG8Tx8MVfaWKvAf8AnNHULi3/ACw0 +0iqI73VoVnYdCkcE0gU/Nwp+jFXxTirsVdirNvyT1G40/8ANzyhPbkiR9VtbdiDQ8LmQQSf8JIa 4q/R7FUp80+atA8q6Jca3r14llp1sKySv1JP2URR8Tu3ZV3OKviL86f+cjfM35gTS6Zpxk0nyoDR bFGpLcAdGunXr4+mPhHfkRXFXj2Kpx5X8o+ZvNWprpnl7TZ9SvW3MUC1CrWnKRzRI1r+05AxV9Ie Qf8AnCx2WK7886sUJAY6XptCR3pJcuCPmET5Nir33yn+UX5beU0T9B+X7SCdOl5Inr3Nf+M83OT6 A1MVZfirsVdirsVcQCCCKg7EHpTFWA+cPyI/KrzYHfU9At4bt/8Aj+sh9Vnr/MWh4hz/AK4bFXz1 +YX/ADhn5h05Zb3yVfjWLZfiGm3fGG7A8FkHGGQ/Ph8sVfPWraRquj6hNp2q2k1jf254zWtwjRyK eu6sAd8VQgJBqNiMVZb5i/NPzj5k8pad5Y1y8N/aaVOZ7K5mJa4AKFPTeQn41UfZLfEOlaUAVYji rsVdir0D8gbG5vfzk8pw2/Lml8s7FRU8IFaaT6OCGuKvoj/nNuG6byNoEy/7ypqZWX/Xe3kMfbwV sVfG+KuxV2Ks9/IeC5n/ADi8pJbV9QahE7Ur/dx1eTp/kK2Kv0XxV5f/AM5I+Rrvzh+VOo2tjGZt R0101OzhUVZ2twwkVQOrGGR+I7nbFX594q7FXYq9j/5xX8j3fmP81LHUvTJ0zy9/p93N+yJACtul f5mk+KngpxV9s+bvNuheUvL93r+uXAt9Ps15O3V2Y7LHGv7TudlGKvgL84fzh8wfmV5gN5eE2uj2 pZdK0pWqkKH9pv5pW/ab6BtirAMVe6fkn/zjDrnnRYNc8yGTSPLD0khAAF1dodwYgwPCMj9thv8A sg9cVfY/lTyd5Z8p6SmleXdOh06yTcpEPidunORzV5G/ymJOKpzirsVdirsVdirsVdirsVdirE/z D/K3yZ5/0w2XmGxWWVFItdQiol1AT3iloTSu/Fqqe4xV8TfnF+Qfmv8ALi5Ny4OpeW5H42+rxKQF LH4UuE39N/Dfiex7Yq8wxV2KuxV2KvsD/nEv8mNQ0OOTz35ggNve30Ho6LaSCjpbyUZ7hwd1MgAC d+Nf5hir2T82vIEHn3yFqflxmWK5nUS2E7dI7mI84if8kkcW/wAknFX50azo2qaLqt1pOq2z2mo2 UhiubeQUZXX+HcEbEbjFUFirsVfQX/OGOk6BdfmFqF/ezgaxp1kW0m0YfaEx9OeZW8Y0IWng58MV faWKpX5q8x6f5a8ualr+oNSz0y3kuZRWhbgtQi/5Tmir7nFX5l6vqUuqate6nLHHFLfTy3MkUKhI 1aZy5VFGyqC2wxVvR9E1nWr9NP0exuNRv5ATHa2kTzSkKKsQiBmoBucVereSP+cVvzU8xXcZ1Ky/ w9ptR6t3fEerx78LdT6hb/W4j3xV9i+QvIPlP8t/Kn6M0sLBaQK1xqGoTlRJK6rV5p32GwHyUYq+ L/8AnIL86Lr8xfMpt7F2j8raY7JpkG49Zh8LXUi/zP8AsA/ZX3LYq8nxV9R/844/841rdJbecvPF pW2YCXSNEmX+8B3W4uUP7PdIz16nbYqvrEAAUGwGKuxV5r+Z35uw+WpW0nSUS51niDLI+8VuG6cg DVnpvx6DqfDMTUang2HN6jsP2eOpHiZPTi+2X7PN4hqnnnzhqkrSXusXUnLcxrK0cY3rtHHxQfQM 10s0zzL3eDsvTYhUMcflZ+Z3VtG/MPzno8yyWerXBRaVgmczREeHCTkPu3wwzzjyLDU9j6XMKlCP vAo/MPefy1/NGy83QtaXKLaa1CvKSBSeEijYvFXf5qdx75ssGoE9jzfPu2uwpaM8UfViPXqPI/rZ 1mS6B2KuxV2KuxV2KqF/p9jqNlPY39vHdWdyhjuLeZQ8bowoVZWqCDir4l/5yH/5x4n8izv5i8uo 8/lGdwJIyS8ljI5oEcndomOyOf8AVbehZV4ZirLvys8u+UvMnnGz0PzPqM+lWl+RDbXsAQgXDECN JOYoqv8AZDdmpXapCr7P8i/84yflX5Ru4r9LOXWNShIaK61N1mCMP2khVY4ag7qShI7HFXq+KuxV gX5m/kl5D/MSJX1u1aDU4l4w6taFY7lVHRGYqyyL7Opp2pirw68/5wcuPrDfUvNyfVzugmsjzA8C Vmofnt8sVfNvmby5qvlrzBf6Dq0Xo6hp0zQTp2qvRlPdXWjKe4NcVVfKHmrVvKnmXT/MOlSenfad MsqD9l16PG9P2ZEJVvY4q/R/yT5v0nzh5W0/zHpT8rTUIhIEJBaNxtJE9P2o3BU4q+f/APnND8wf q2l6b5Gs5P3t8Rf6qFPSCNiII2/15AX/ANgMVfI+Kvrj/nC/8vvq2l6l55vI/wB7fE2GlFh0gjYG eRf9eQBP9gcVfTmKvmj/AJy//Np9O0+P8v8ASJ+N3qCCbXJEO6WxP7u3qOhlI5MP5aDo2KvkLFX0 B/zi5+RyebNTHm7zBbh/Lmmy0s7aQVW8uk33B+1FF+12Zvh3owxV9qAACg2AxV2Kpf5h1VdI0LUN UYchZW8kwX+ZkUlV+k7ZGcuGJLk6PB42aOP+dIB8f3d1cXd1NdXLmW4ndpJpG6s7mrE/MnNETZt9 mx44wiIxFAbBRwM3YqmGgazdaJrVnqtqaTWkqyAdOQH2kPsy1U5KEjEghxtXpo58UscuUh+Pk+w7 eeOeCOeM1jlVXQ/5LCozeg2+MTiYkg8wvwsXYq7FXYq7FXYqoahYWWo2NxYX0CXNndRtDcW8gDI8 bjiysD1BBxV8A/n5+Ttz+XHmspbB5PLepFpdIuGqxUA/Hbu388dRv3Wh8cVeYgkGo2IxV95f84zf mw3nnyULDUpvU8x6EEt71nPxzwkEQXHuSF4v/lCv7QxV7DirsVdirsVfNv8Azl9+U36U0hPP2lQ1 v9LQQ6zGg3ktK/BNt+1Cxo3+QfBcVfHuKve/+cV/zltvKGtXHlrX7sW/lzVOU0NxKaR212i/aPgs yLxP+UF98VeV/mX51u/OvnjVvMlxyC3sx+qxMa+nbp8EMf8AsY1FfepxVJdF0q41fV7PS7Yqs97M kCPIQqKXYDm7HZVXqxPQYq+4l/PL8jvy48u6f5btNbXUV0q3S3jh0xDdF/TFGYyp+45O1WNZOpxV gut/85waUjMuh+Vp7hf2Zr25SAj5xxJP/wATxV8v+avMmpeZvMeo6/qb877Up3nmpWi8j8KLX9lF oqjwGKph+XPkfUvPHnLTfLdhVWvJP9InpUQ26fFNKf8AVQGg7mg74q/R/wAvaBpfl7Q7HRNKhEGn 6fCsFvGP5UFKse7Md2Pc74qmGKuxVj/5gWU175J1q2hBaVrSVkUbklF58R8+NMqzC4F2PZGUQ1WO R5cQ/U+Sc0j7C7FXYquRHd1RAWdiAqjcknYAYoJoWX2VpNq9ppVlaPu9vBFE29d0QKd+/TN9EUAH xTUZBPJKQ6yJ+1FZJpdirsVdirsVdirsVYn+aX5eaZ5/8mX3l69CpLKvq6fdEVMF0gPpSjvSp4tT qpIxV+cer6TqGj6rd6VqMJt7+xme3uoW6rJGxVht13GKst/Jf8w5vIX5g6brfJhp7N9W1WMft2kx Ak27lNpF91GKv0ZjkjljWSNg8bgMjqQVZSKggjqDiq7FXYq7FVO5tre6t5ba5jWa3nRo5onAZXRx xZWB6gg0OKvzx/PL8r7j8vPPVzpaKzaPd1utGnO/K3dj+7Y/zxH4G+hu+KvPcVdirsVdirsVdir7 K/5w6/Lb9EeWLnzpfRcb/XKw6fyHxJZRNuw8PWlWvyVT3xV9FYq7FXYq7FXyt+aPlix8ueb7mxsZ Ve1kAuI4RWsIlJPpN/q9v8mmabUYxCdB9a7C109TphOY9Q2vvrr+OtsSyh3DsVeqfk1+W13qWp2/ mLU4THpVowltEkFDcSrujAH9hDvXudvHMzS4CTxHk8l7SdtRxYzgxm8ktj/RH6z+Oj6CzaPnTsVd irsVdirsVdirsVdir48/5zM/L1dO8w2HnWyi422sD6pqRXoLuFaxsfeSFaf7A4q+bsVffH/OLnnd vM/5UWMFw5e/0FjplwWO5SJQ0DfL0WVfmpxV65irsVdirsVfN/8AzmH5n/LubyzF5dvJvrHnC3lS 402O3AdrYNQSfWGqOCSx/s9SeLUoK4q+O8VdirIfJ/5fec/ON39V8t6Rcai4YLJLGtIYyf8Afkzc Y0/2TYq978of84T6xOiT+bddisgaFrLT09eSh7NNJwRWHsjD3xV65oP/ADit+TGkqPV0mXVZlpSa /uJXO3ikRiiP/AYqznTPy3/L3S6HTvLOl2rj/dkVnAr/AEuE5H78VZEiJGgRFCIooqqKADwAGKt4 q7FXYqo3t5b2VnPeXLcLe2jaWZz2RAWY/cMBNC2eLGZyEY85Gg+QPMWtXGua5fatcbSXkrSca14q dkQeyqAozRznxSJfZtHpo4MUcceURX6z8W/LeiXGua7Y6TBtJeSrHy/lXq7/AOxUE4whxSARrdSM GGWQ8oj+z7X0ho35P+QdLmWdNP8ArUyUKvdu0oBH+QaR/wDC5tY6WA6Pmep9otZlFGfCP6O328/t ZmqqqhVACgUAGwAGZDoybbxV2KuxV2KuxV2KuxV2KuxVgP57+Tx5s/KrX9MROd3Dbm9sfH17X98o X3cKU/2WKvzpxV9E/wDOFnmc2XnnVvL8j0h1eyE0SnvPZvUAD/jFLIfoxV9l4q7FXYq+ff8AnIb/ AJySi8pfWPKvlORZ/MxXhe34o0djX9kAgh5qdjsnep2xV8Z3d3dXl1Ld3cz3F1O5knnlYu7uxqzM zVJJPc4qr6Po2q61qdvpek2kt7qF03C3tYVLu7ewHgNyew3OKvqz8qP+cPdPtEh1X8wpBeXezrod u5ECHrSeZaGQ+KoQvuwxV9I6ZpemaVYxWGmWkNjYwDjDa26LFEg8FRAAMVRWKuxV2KuxV2KuxV2K vMvz58y/o7yvHpMLUudWfi9DuIIiGf8A4JuK/KuYesyVGu96n2U0Xiag5D9OP7zy/S+ds1b6S9l/ 5x68s+pdX3mOdPggH1SzJ/nYBpWH+qvEf7I5n6LHuZPE+1+tqMcA6+o+7p+PJ7jmxeDdiqE1LVtL 0u3NzqN3FZwD/dkzqgJ8BU7n2GRlIDm3YNPkyy4YRMj5POPMX5/+WrLlFo1vJqkw2EprDBX5sOZ/ 4H6cxZ62I5bvTaP2Szz3ykYx8z+r7Xl/mP8AN3zvrfKNr36jat/x72VYhT3epkPv8VMw56mcutPV aP2e0mDfh45d8t/s5fYg/Kn5h+ZfL+qRXUd7NcWvIfWrOWRnjkSvxCjEgNTow6ZHHnlE3bfr+x8G oxmJiBLoQNwfx0fVkciyRrIu6uAyn2Irm6fIyKNLsUOxV2KuxVxAIIIqDsQelMVfmT590EeX/O2v aIq8Y9Ov7m2iHjHHKwjP0pQ4qnv5Fa2dG/N/ypehuIfUI7R2qAAl5W2YknsBNvir9GcVdirxP/nJ L8818h6MNC0OYHzZqcZKOKH6nbtUeuwP7bbiMfNj0oVXw3PPNcTSTzyNLPKxeWVyWdnY1ZmY7kk7 knFU/wDIPkHzH568xwaDoMHq3EvxTztURQRAgNLKwB4qtfmTsKk4q+8vyl/Jjyr+W+kiHT4xdaxO gGoaxKoE0p2JVOvpxVGyA/Mk74qz/FXYq7FXYq7FXYq7FXYq7FXy1+a/mb9P+dLyWN+VnZn6naU6 FIieTD/WcsflTNNqcnFMvrHYGi/L6WIP1S9R+P7KYhHHJLIscal5HIVFG5JJoAModySALL648m6B D5a8q2OmEqrW0XK6kqKGVvjlavhyJp7ZvMUOCID472lqzqdRLJ/OO3u5BJfMf5w+SNF5xi7/AEjd Lt6FkBJv7yVEY36/FX2yueqhHzc7R+zurz78PBHvlt9nP7Hl3mP8/PNF/wA4tIhj0qA7CQUmnp/r OOA+hajxzDnrJHls9Xo/ZPT498hOQ/Ifr+15zqGp6jqNwbnULqW7uG6yzO0jfKrE5iSkTzelw4IY 48MAIjy2Q2BtdirI/wAv/KkvmjzPa6aARag+teyD9mBPtb9uWyj3OW4cfHKnWdr68aXBLJ/Fyj7/ AMbvrJVVVCqAFAoANgAM3b5ATbeKuxV2KuxV2Kvz/wD+cn9PSy/O/wAxBAAlwbW4AHjJaxF67Dq/ I4q840W+On6zYX4PE2lxFOG329Nw9dt+3bFX6j4qxj8yfPuleRPJ1/5j1H4ltl4WttWjT3D7RRL/ AKzdT2Wp7Yq/ObzN5k1fzLr19rusTm41HUJTNPIelT0VR+yqrRVXsBTFV/lPyrrXmvzDZaBosH1j Ub6T04k6KoAqzud+KIoLMfDFX6E/lR+Vmgflz5Zj0nTVWW9lCvqmpFeMlzMB9o7nii1oiVoB7kkq s0xV2KuxV2KuxV2KuxV2KuxVi/5leZv8O+T76+R+F3Kv1ayPQ+tKCAR7oKv9GU58nDAl2vYui/M6 mMD9I3l7h+vl8XyjmlfXUbo2qS6VqltqUMUcs1o4liSYFk5r9liAVrxb4h75KMuE20anAMuMwJIE ttkd5g86+aPMDk6tqMs8ZNRbg8IRTpSJOKfTSuSnllLmXH0nZmn04/dwAPf1+Z3STK3Pdiqf+XvI nmzzAVOl6dLLCf8Aj5cenCPH94/FTTwG+WwwylyDr9Z2rp9P/eTAPdzPyCW6zpjaXqlxpzzRzy2r mKWSEkx812cKSFJ4natMhKNGnJ02fxcYmAQJb786QWRb30n+Svk79BeWRqFzHx1HVgsz16pBSsSe 2x5H579M22kxcMb6l8x9pe0fHz8ET6Me3x6n9D0PMp5t2KuxV2KuxV2KvhX/AJy8AH5y3RAoTY2h PueBGKvFcVfqpir4f/5yx/M5vM3ng+WrGUnRvLbNA4B+GS+6Tv8A88/7oV6EN44q8LxV9yf84ufk /H5P8qJ5j1SADzJrsSyfGPitrNqNHDv0Z9nf6Afs4q9wxV2KuxV2KuxV2KuxV2KuxV2KvAv+chNf muNdstEWot7KL13/AMqWb/mlFFPmc1mtncgO59C9kNII4ZZesjXwH7Xk2YT2DsVRemaRqmqXAttN tJryc/7rhRnI9zxBoPc5KMSeTTn1GPFHinIRHmaekeXfyA8y3vGXWbiPS4TuYlpPP9ykIP8Agvoz KhopHns8zrPa3BDbEDkPyH6/seoeXfyj8kaHxkSy+vXS7/WL2kpr4hKCMfQtczIaaEelvKaz2h1e fYy4Y90dvt5/aqfmf5vXyv5UmmgYJqF0Pq2nqNiHYbuB/wAVrv8AOg74dRl4I+bHsPs781qAD9Ed 5fq+P63yySSSSak7knNM+sMw/KzyefM3mqGGZOWnWdLm+JHwlFPwxn/jI23yrl+nxccvJ03bvaP5 XTkj65bR/X8Pvp9SgACg2A6DNy+TuxV2KuxV2KuxV2KvgT/nKe+F1+d+vKpqtslpADUncWkTNQHp RmIxV5dp9o15f21oteVxKkQp1q7BdvvxV+jv5t+dk8k/l5rXmEEC6toDHYqf2rqYiOHbuA7BiPAH FX5uzTSzzPNM7STSsXkkYkszMaliT1JOKvUf+cb/AMtl88fmNareRCXRNHAv9TVhVHCN+5hNdj6k lKjuobFX6AYq7FXYq7FXYq7FXYq7FXYq7FXYq8n/ADh/K7VfMF5FreiKJrxYxDdWbMELqhPF0LUW oBoQT8swtVpzI2Hr/Z3t3Hp4nFl2jdg/oLz3RvyU8+ajNxmtF06EGjTXTqPuRObn7qe+YsdJM9Ke j1PtNpMY2lxnuiP10Hpfl38g/K1hxl1aaTVZxuUP7mCv+op5n6X+jMuGjiOe7y+s9rNRk2xgYx8z +r7Ho1hpunadbi2sLWK0t16RQosa/coGZcYgcnmsuaeSXFMmR8zaJwtTsVfL35s+cf8AEvmmX6vJ z0zT629lTo1D+8kH+uw29gM0+py8cvIPq3s/2d+W04seue8v0D4ffbCsx3ePqP8AKjyd/hnytEk6 cdSvqXF9XqpI+CP/AGC/jXNxpsXBHzL5R2/2j+a1BI+iO0f0n4/dTM8yHSOxV2KuxV2KuxV2KvzU /NLXBrv5j+ZdWRuUV1qNy0DDvCshSL/kmoxVEfk7o7ax+anlWwA5K+p20sopWscEgmk/4SM4q99/ 5zb82ssXl7yjE1BIX1W8X2WsFv8ARvL+GKvlHFX3T/ziX5KTQPyti1aWPjf+Y5WvJWI+IQITHbr8 uIaQf6+Kva8VdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirAfzl84/oDyu9pbPx1LVeUEFDRk ip+9k+gHiPc+2Y2qy8Ma6l6H2b7O/MajikPRj3Pv6D9PwfM+ah9Regfkx5OGv+Z1vLlOWm6VxnmB GzymvpJ945H2FO+ZWlxcUr6B532k7R/L6fhifXk2Hu6n9HxfS2bZ8vdirsVdirsVdirsVYl+bXm1 fKX5ca/r3LhPbWjpaH/l5m/cwf8AJR1r7Yq/NjFXvX/OG/ll9R/M641plrBoVlI6v4T3X7hB9MZl +7FWNf8AOTvmB9Z/ObXPi5Qab6WnwCtaCCMeoP8Akcz4q810rTbjU9Us9NthW5vp47aEeLzOEX8W xV+n2kaZa6VpVlpdovG1sIIra3XpSOFAiD7lxVF4q7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXkO kfnqlnrF3pPma3olvcSwrqNsCQAkhUepF17dV/4HMGOso1J7LUeyxnijkwHnEHhPu6H9fzepWGs6 TqFh+kLK7iuLLiWNxG4KAAVPI/s07g9MzIzBFh5TLpsmOfBOJEu58ufmL5tk80eaLnUFJ+pR/uLB DtSBCeJp4uSWPzzT58nHK31bsfs8aXTiH8R3l7/2cmNxRSSypFEpeWRgqIoqSzGgAHvlLs5SAFnk H1f+XnlOPyv5XtdOoPrbj175x3ncDkK+C0Cj2GbrBj4I0+R9sdoHVaiU/wCHlH3D9fNkmXOrdirs VdirsVdirsVfKn/Oafn9WOleRbOWpUjUtVCnoaFLeNqexdyP9U4q+VsVfcf/ADiJ5LOhflj+mLiP he+Y5zdVIowtoqxQA/P43Hs2Kvjfzxqh1bzpr+qE1N9qN3cb+Es7uOw8cVZR/wA496UuqfnP5Utm HIR3n1qhod7OJ7kHenQxYq/RHFXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXx/5ujaPzXrUbfa S/uVb5iZhmiy/Ufe+zdnm9PjP9CP3BB2eqalZJPHZ3UtvHdRmG5SN2VZI2FCrgGjDfvgEiOTfkwQ mQZRBMTYvofJC5Fteo/kT5O/Smuvrt0nKy0oj0AejXRFVp/xjHxfPjmZo8Vy4jyDyntV2j4WHwYn 1ZOf9X9vL5voXNo+cOxV2KuxV2KuxV2KpL5z826T5R8sah5i1V+Flp8RkZagNI/RIkr+1I5Cr7nF X5u+bvNGp+avM2peYdTble6lO08oFeKg7JGtd+MaAIvsMVRv5c+Sr7zt500vy1aVU30wFxMBX0rd Pjml8PhjBIr1NB3xV+k+nWFnp2n22n2UQhs7OJLe2hX7KRRKERR7BQBir8tGZmYsxLMxqzHcknFW a/krrq6H+a/lbUXbhEuoRQzOeix3J+ryMfYLKTir9HsVdirsVdirsVdirsVdirsVdirsVdirsVdi rsVfI3ntGTztr4bYnUbpvoaZiPwOaPN9Z977H2Ub0uL/AIXH7gkWVue7FU98r+dvMnlmcy6TdtHG xrLbP8cL/wCsh2r7ih98sx5ZQ5Ov13ZmDVCskbPf1Hx/Ae3+Tvzx8u6xwtdYA0i/b4QztW2c+0hp w+T7e5zY4tXGWx2LwvaPsvmw3LF+8h/svl1+HyelAgio3B6HMt5d2KuxV2KuxVxIAqdgMVfDv/OT v51r5214eXdEn5+V9HlP71DVbu6FVaao2MabrH47t3FFXhuKvtH/AJxH/Kh/L3luTzlqsPDVtdjC 2COPiisKhlPsZ2Ab/VC++KvoPFX5WyRvHI0bji6EqynqCDQjFXI7o6ujFXUgqwNCCNwQRir9K/yx 83R+b/IOh+YlYNJfWqG6A6LcR/u51+iVGGKsnxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2Kvkz8x kZPPeuhhQm8lb6Gao/A5pM/1n3vr/YxvSYv6gY5lTs3YqnPlryjr/mS8+q6TatMRT1Zj8MUYPd3O w+XU9ssx45TNBwtb2hh00eLJKvLqfcHvXkb8mdA8v+neajx1PVVowd1/cRN1/dxnqR/M30UzZYdL GO53L592p7SZtRcYejH9p95/QPteh5lPNuxV2KuxV2KvnT/nLX84L/y/pqeSNHEsF9rEHq6jf0ZA toxKGKJtqtIVIcjou3VtlXxtirPvyM8t+U/MX5l6Tpnmm8S10x35rDJULdTqR6VqW6L6p8ev2RuR ir9FURERURQqKAFUCgAGwAAxVvFX5lfmBpbaT568xaYV4/U9Su4FAFBxSd1Uj2IG2KpBir6f/wCc M/zJW3vb7yFfy0jvC19o5Y9JlWlxCP8AXRQ4H+S3jir61xV2KuxV2KuxV2KuxV2KuxV2KuxV2Kux V2KvlL80VZfzA1sMKH6wT9BUEfhml1H1l9c7CN6PH/VY1BBNPMkMEbSzSELHEgLMzHoFUbk5UBbt JSERZNAPXPI/5DXd16d95oY21uaMunRn96w/4tcbIPYb/wCrmbh0ZO8nju1PauMbhp/Uf5x5fDv+ 73vbNM0vTtLs47LTraO1tYhRIYlCr8z4k9ydzmwjEAUHhc+eeWRnMmUj1KKyTU7FXYq7FXYq7FWJ /mX+Wflv8wvLkmja1HRlq9jfIB61tNSgeMnsf2l6MPoIVfAv5mfln5k/L3zJJo2sx8kar2F+gPo3 MNaB0J6EftL1U/QSqxJWZWDKSrKaqw2IIxV9tf8AOMP55P5y0r/C3mCfn5m0yLlBcyH4ry2Wg5kn rLHsH7sPi/mxV7zir4I/5yo8vNo/5zatKF4watFBqEA8RJGIpD9M0L4q8ixVGaPq2oaPqtpqumzN b39jMlxazr1WSNgyn33HTFX6J/lF+Zul/mJ5OttbtSsV8gEOq2INWguVHxCnXg32kPce9RirNcVd irsVdirsVdirsVdirsVdirsVdirsVeD+Zvyv8y+afzI1iWGP6npnqx89QmB4U9FP7tdjIflt4kZr cmnlPIe59A0PbmDSaHGCeKdH0j3nn3fjZ6j5N/Lry35VhBsYfVviKS6hNRpm8Qp6Ivsv01zMxYIw 5c3lO0u2M+rPrNQ/mjl+34sny51TsVdirsVdirsVdirsVdirFvzI/Lry95/8sz6FrMQowL2d4BWW 2npRZYzt07itGGxxV+eHnXyfrPk7zPf+XdYjCXtjJwLLXhIh3SWMmlUdSGH474qh/K/mTVfLPmCw 17SZfS1DTplngbsSNirDurqSrDuDir9I/I3m/TfOHlPTPMmmn/RdRhEnpkgtHIDxlian7UcilT8s VeBf85seUHuNF0LzZBHU2Mr2F6w6+nOPUhJ9ldGHzbFXyLirsVZr+U35p65+XHmiPWNO/f2koEWp 6czFUuIa9K78XXqjdj4gkFV+gfkzzp5d85aBb65oN0t1ZTgcgCPUikoC0Uq/sOtdx/DFU8xV2Kux V2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2Kvn3/nL/APLSPW/KEfnGyi/3 K6BRbwqPiksZG3r4+i7cx4KXxV8W4q+rf+cKfPDsmteSrmSojA1PTVJ6AkRXCCvuY2AH+UcVfQv5 ieT7Xzj5J1jy3cUA1G3ZIZGFRHOvxwyf7CVVbFX5q39jd6ffXNheRmG7tJXguIW+0kkbFHU+4YUx VD4q7FWaflf+a/mn8utcGo6NL6lrMVGoaZKT6Fyi12YD7LrU8XG49xUFV9zfld+cfk38xdNE2kXA h1ONQ17pE5AuIT0JA/3Ylejrt40O2Ks6xV2KuxV2KuxV2KuxV2KuxV2KuxVLtf8AMWheXtNl1PW7 +HTrCEVe4uHCLWleIruzHso3PbFVvlnzNonmbQ7XXNDulvNMvVLW86hlrxYqwKuFZSrAggjFUzxV 2KuxV2KuxV2KuxV2KuxV2KoXVdMs9V0u80y9T1LO+hktrmP+aOVSjj7jir8xNf0mXR9d1HSJXEku nXU1pI60Ks0EjRkgiooSuKs1/wCcffMTaB+cPlm6LUiuboWEw6Areg245eytIrfRir9EMVfG3/OY H5XtpHmSLzvp0JGm62wi1IKPhjvVXZtugmRa/wCsGPfFXzpirsVdiqK0vVNS0q/g1DTLqWyvrZg8 FzA5jkRh3VlIIxV9Kfln/wA5lX1qkOnefrM3sQov6as1VZgPGaD4Uf3ZOP8Aqk4q+mPKXn3yd5vs /rflvVrfUowKyJE9JY67fvIW4yR/7JRiqfYq7FXYq7FXYq7FXYqluv8AmXy/5esG1DXdRt9Ns16z XMixqSOy8iOTeAG+Kvnf8yf+cy9KtPVsPIdl+kJxVf0veq0duPeKD4ZH+b8fkcVfMPmzzt5q83ak dR8x6nPqNya8PVb4Iwd+MUYoka+ygYq9u/5xE/Nf9CeYX8j6pNTS9bk56YznaK+pTgCe06gL/rha dTir7KxV2KuxV2KuxV2KuxV2KuxV2KsT/NTz3a+RvImq+YpiDNbxFLGI/wC7LqX4IUp4czVv8kE4 q/NqaaWeaSaZzJLKxeR23LMxqST7nFURpV/Jp+qWeoR19SznjnSnXlE4cfqxV+pOKpP5w8qaR5s8 tah5e1eP1LDUIjHJT7SN9pJEr0aNwGX3GKvzl8/+Rta8j+ar3y5q6UuLVqxTgEJPC393NHX9lx9x qDuMVY7irsVdirsVV7G/vrC6ju7G4ltLuE8oriB2jkQ+KupDD6MVereVv+cp/wA4dBRIpdSj1q2T YRanEJmp7zIYpm/2TnFXqOif85wQFVTXfKzKwpznsbkMD40ilRaf8jMVZhY/85lflLcKPXg1Wzb9 oS28bAH5xTSYqmaf85afkq0XM6ldI2/7prOflt8lK7/PFUDd/wDOYv5QwJyiXU7o0rxhtUB+X72W MYqxPWv+c39FRWXRPK9zcMfsSXtxHAB7lIlnr8uQxV5n5n/5y5/NvWA0dhNa6FbtsBZQhpae8k5m NfdQuKvI9Z13W9bvWvtZv7jUbxtmuLqV5pKeHJyxp7YqgMVdiq+GaWGVJoXaOWNg8ciEqyspqGUj cEHFX33/AM4/fnPZ/mJ5YSC9lVPNWmIE1S22UyqKKt1GO6v+1T7LbdCtVXq2KuxV2KuxV2KuxV2K uxVbJJHFG0kjBI0BZ3YgKFAqSSegGKvhL/nJT86F8/8AmRNM0eUt5W0dmFo24FzOfhe4INPhp8Md e1T+1TFXjWKuxV+qmKuxV5h+fH5MWH5k+W6QBLfzLpys+k3jCgau5t5T/vuQjr+ydx3BVfA2saPq mjapc6VqttJZ6jZyGK5tpRR0cdj+sEbEbjFUHirsVdirsVdirsVdirsVdirsVdirsVdirsVdiqbe V/NOveVtcttb0K7ey1K0blFMm4IOzI6nZlYbMp2OKvt78mf+cjvK3n6CDTNRePSPNdArWEjUiuW/ mtXb7Vf99n4h/lAVxV7BirsVdirsVdirsVQOua7o2haZPqms3kVhp9uOU1zOwRF8BU9SewG57Yq+ NPz7/wCcmL3zms/lvyqZLHysSUublqpPfAfzDrHCf5OrftfyhV4JirsVT3yJpL6x520DSlFTfaja 25p2EkyqT26A1xV+m+KuxV2KvIvz1/5x/wBH/MWxfUtPEdh5ugQC3vmqI7hU6Q3HEHb+V6cl9xti r4a8w+Xdb8u6vcaPrdnJY6latxmt5RQjuCCNmUjcMNiOmKpbirsVdirsVdirsVdirsVdirsVdirs VdirsVdirYJUgg0I3BHUHFXsv5e/85U/mV5Ujis9QkXzFpUYCrBfM31hVHZLkVf/AIMPir3ryv8A 85h/lZqkaLrK3eg3J/vPWiNxCD/kyW4dyPcxrir0Cw/Or8o76P1IfN+kotK0nuordv8AgZjGcVTC f8zPy3twDP5r0eINspfULVQT7VkxVjOs/wDOR/5L6SjGXzNBdOPsx2SS3RY0rQNEjJ97DFXkvnP/ AJzYtFjkg8m6G8km4S/1QhFHaot4WYt7VkHyxV85+dvzF85+dr8XvmXVJb5kJMEBISCIHtFClET3 IFT3JxVjeKuxV2Kvav8AnEnyo+tfm1b6i8Za00G3lvZGI+H1XX0IVJ8eUnMf6uKvurFXYqgdc1zS NB0m51fWLuOy02zQyXFzKaKq9PmSTsANydhvir5X8+/85patJdSWvkjS4rezQlRqOoqZJZAP2khR lSP/AGRb5DFXinn382/OfnyO3XzNLbXclqf9HuUtYIZlU1qnqxor8DWvGtK4qwzFXYq7FXYq7FXY q7FXYq7FXYq7FXYquMcgRZCpEbEhXINCVpUA+1Riq3FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FX3T /wA4ofl6/lf8uV1a8i9PVPMjLeSBhRltVBFqp+as0n+zxV7XirsVfHX/ADmR+Yt7e+aYPI1rKU03 SY47nUI1JHqXc680DjuI4WUr7scVfOGKuxV2Kvoj8tfyI8o/mv8AlnDquk3LaD5q0yRrDUCAZrS4 eJVaOV4iQ6M8TqCyNTkGPE4q8+87/wDOPv5qeUDJJfaNJfWEe/6R06t1Dx/mYKPUQf66Lirzkgg0 OxGKtYq7FXYq7FXYq7FWbeSvyY/Mrzk8Z0TQ52s5Kf7kbhfq9qB4iWTir08EqfbFX0Z+Xf8Azhp5 f05or3ztfnWLlfiOmWhaG0B8Hk+GWX6OH04qz/8AOb8lNG83flwNC0OygsNQ0YGfy/HCixRq4HxQ UHEBZlFD/lUY9MVfAd1a3NpdTWl1E0Fzbu0U8MgKukiEqysp3BUihGKqWKuxV2KuxV2KuxV2KuxV 2KuxV2KvU/8AnHz8o5/zC85x/W4m/wANaUyXGrzdFehrHbA/zSkb06LU9aYq/QBEREVEUKigBVAo ABsAAMVbxV2Kvz0/5yNguYfzr80rcbu1xG6n/it7eNo/+EIxV5tirsVdir67/wCcH4rkeXvNMzV+ rPd2yReHNInL0+hkxV9M4qxjzP8Alh+Xvmks+veX7K+nf7V00QS4P/PePhL/AMNirzLW/wDnDn8p r5mewk1HSWP2Y7e4WWMfMXCTOf8Ag8VYjef84N2DvWz84Swp4TWCymnzWeL9WKpb/wBCOar/ANTd B/0hP/1WxVH2X/ODdqrK195weRaDlHDYCMg9wHa4f/iOKss0f/nDT8rLMq9/danqb7ckkmjhjNPA Qxo4/wCDxV6P5b/Jz8rvLZR9H8tWMM0e6XEsf1idSPCacyyD/gsVZlirsVdir5w/5yd/5x+fX45v O/lS2L63EoOr6dEKm6jQU9aNR1mRRuo+2OnxD4lXx2QQSCKEbEHrXFWsVdirsVdirsVdirsVdirs VZT+XH5ceZPP/mSHRNEhJJIa8vGB9G2hr8UsrfqHVjsMVfoP+X3kHQfIvle18vaLHSCD4552p6k8 zAc5pCOrNT6BQDYYqyTFXYq7FXy5/wA5hflPe3Zg/MHSIWmFvCttrsSAlljQkxXNB2UHg/gOJ6VO Kvk7FXYqitM0zUNU1C307TreS7vruRYra2iUs7uxoFUDFX6I/kt+XS/l/wDl9YaC5V9QYtdapKm6 tdTU50PcIqrGD3C1xVnOKuxV2KuxV2KuxV2KuxV2KuxV2KuxV4L+eP8AzjBpXnGS48w+VjHpnmZ6 yXNu3w2t43UlqA+nK3842Y/aG/LFXx15k8r+YfLOrS6Tr9hNp2oQ/bgmWhI6BkYVV1PZlJB7HFUq xV2KuxV2KuxV2KuxV6n+Uf8Azj55z/MKeK79NtK8tcv32r3CEc1HUW0ZoZW7V+yO5rtir7d8g/l9 5X8i6DHovl619CAfFPO9GmnkpQyTPQcmP3DoABirJMVdirsVdirTokiNHIodHBV0YVBB2IIOKvB/ P3/OIHkLzDdy3+g3Uvlq7mJZ4IY1ns+RNSVgLRslfBXC+C4qwm1/5wcu/XX615vjEH7fpWJLkeA5 TgD54q9s/LH8ivIX5eD6xpNs93q7Lwk1e8KyT0I+JY6BUjU/5IqR1JxV6HirsVdirsVdirsVdirs VdirsVdirsVdirsVSTzZ5J8qebtOOneY9Mg1K134CVfjjJ/ajkWjxn3Vhir5y87/APOFAeSS58l6 2I0apTTdTBIHei3MQJp2AaP5tirxfzD/AM4+fnFoTN9a8s3V1EOk1gBeqR40tzI4/wBkoxVg+oaP q+nOU1CxuLNweJW4ieI132o4HgcVQeKp7pPkTztrDhdK0DUb4natvazSAfMqpA6d8Vem+VP+cSfz a1p431G3t9BtGILSXsqvLx7lYYPUavs/HFXv/wCXv/OKH5c+V3ivNWVvMmqR0YSXihbVWHdbUFlP /PRnxV7UiIiKiKFRQAqgUAA2AAGKt4q7FXYq/wD/2Q== proof:pdf uuid:65E6390686CF11DBA6E2D887CEACB407 xmp.did:951de943-bba8-43ef-aea5-cab77fa8aef5 uuid:712bf3f5-e035-5944-933f-a93da12a05ae uuid:7db1d830-3358-1345-97c6-ce947c85e793 xmp.did:18110077-86fd-480e-ad7a-4a63df187377 uuid:65E6390686CF11DBA6E2D887CEACB407 proof:pdf saved xmp.iid:951de943-bba8-43ef-aea5-cab77fa8aef5 2020-11-07T20:56:10+01:00 Adobe Illustrator 25.0 (Macintosh) / Web Document AIRobin 1 False False 1024.000000 1024.000000 Pixels Cyan Magenta Yellow Black Standard-Farbfeldgruppe 0 Weiß RGB PROCESS 255 255 255 Schwarz RGB PROCESS 0 0 0 RGB Rot RGB PROCESS 255 0 0 RGB Gelb RGB PROCESS 255 255 0 RGB Grün RGB PROCESS 0 255 0 RGB Cyan RGB PROCESS 0 255 255 RGB Blau RGB PROCESS 0 0 255 RGB Magenta RGB PROCESS 255 0 255 R=193 G=39 B=45 RGB PROCESS 193 39 45 R=237 G=28 B=36 RGB PROCESS 237 28 36 R=241 G=90 B=36 RGB PROCESS 241 90 36 R=247 G=147 B=30 RGB PROCESS 247 147 30 R=251 G=176 B=59 RGB PROCESS 251 176 59 R=252 G=238 B=33 RGB PROCESS 252 238 33 R=217 G=224 B=33 RGB PROCESS 217 224 33 R=140 G=198 B=63 RGB PROCESS 140 198 63 R=57 G=181 B=74 RGB PROCESS 57 181 74 R=0 G=146 B=69 RGB PROCESS 0 146 69 R=0 G=104 B=55 RGB PROCESS 0 104 55 R=34 G=181 B=115 RGB PROCESS 34 181 115 R=0 G=169 B=157 RGB PROCESS 0 169 157 R=41 G=171 B=226 RGB PROCESS 41 171 226 R=0 G=113 B=188 RGB PROCESS 0 113 188 R=46 G=49 B=146 RGB PROCESS 46 49 146 R=27 G=20 B=100 RGB PROCESS 27 20 100 R=102 G=45 B=145 RGB PROCESS 102 45 145 R=147 G=39 B=143 RGB PROCESS 147 39 143 R=158 G=0 B=93 RGB PROCESS 158 0 93 R=212 G=20 B=90 RGB PROCESS 212 20 90 R=237 G=30 B=121 RGB PROCESS 237 30 121 R=199 G=178 B=153 RGB PROCESS 199 178 153 R=153 G=134 B=117 RGB PROCESS 153 134 117 R=115 G=99 B=87 RGB PROCESS 115 99 87 R=83 G=71 B=65 RGB PROCESS 83 71 65 R=198 G=156 B=109 RGB PROCESS 198 156 109 R=166 G=124 B=82 RGB PROCESS 166 124 82 R=140 G=98 B=57 RGB PROCESS 140 98 57 R=117 G=76 B=36 RGB PROCESS 117 76 36 R=96 G=56 B=19 RGB PROCESS 96 56 19 R=66 G=33 B=11 RGB PROCESS 66 33 11 Graustufen 1 R=0 G=0 B=0 RGB PROCESS 0 0 0 R=26 G=26 B=26 RGB PROCESS 26 26 26 R=51 G=51 B=51 RGB PROCESS 51 51 51 R=77 G=77 B=77 RGB PROCESS 77 77 77 R=102 G=102 B=102 RGB PROCESS 102 102 102 R=128 G=128 B=128 RGB PROCESS 128 128 128 R=153 G=153 B=153 RGB PROCESS 153 153 153 R=179 G=179 B=179 RGB PROCESS 179 179 179 R=204 G=204 B=204 RGB PROCESS 204 204 204 R=230 G=230 B=230 RGB PROCESS 230 230 230 R=242 G=242 B=242 RGB PROCESS 242 242 242 Webfarben 1 R=63 G=169 B=245 RGB PROCESS 63 169 245 R=122 G=201 B=67 RGB PROCESS 122 201 67 R=255 G=147 B=30 RGB PROCESS 255 147 30 R=255 G=29 B=37 RGB PROCESS 255 29 37 R=255 G=123 B=172 RGB PROCESS 255 123 172 R=189 G=204 B=212 RGB PROCESS 189 204 212 Adobe PDF library 15.00 21.0.0 endstream endobj 3 0 obj <> endobj 5 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/Thumb 27 0 R/TrimBox[0.0 0.0 1024.0 1024.0]/Type/Page>> endobj 24 0 obj <>stream H\I q ] TIM[  a{j{TDe@f_/|m/Zfq=z|(-ʏDC不X)NmNзog{5pu],սxkV}` w5coUbQQ<9wy:,jܩcz Ӻz*dKpm^myQ͵y`rѢ̅wS3ϧ.;Lf Yxh껗v%i XxsӪK.4kz]ڹclS%/{w=#]T)tzݝn]\:a5p+ޱk+w]1;jU7ohܠWeʞvxёXktf0o2C^:s݃Q}@YgZsG:!jdL%1t%3H[usKkmw#ɉ[ stvt7|OD<nVh2 Lא @pU,hHyЗ{P.睑0NBsu+ز~?rrr;p\B͸[P[܃Kҕh;=t%"ANT:@`cvOqC` la9T4OysO/PzfZYDNy҅lQ-5@u5""`C{Țr`HRE/CJQ= 9فy[v }UE[JfRsM ZKCc8-o"MgP_d&-W3a}A)1P~^Pڅ O5j$hO%ED΀VPM1X>Z>sQoa(BA硷l,USgI>'_!t&h͑&jDK=TQC=ξ)^1%!Af"ۭt&.{Wsr_6MxW2 ";TSy֚VSWܐ17 acڴ橤nJhQ+' &#Cel`CrdI}ĠpPvGPJy+({G\L2y }l⤎ȶ$&DK%(ߋ7ǖYy;ɢ T="i9Y>9^J\AI}2B}]vO$+7xj7W5?\ *2q}غN~Fz H: 7 }NmmGdMj\JHcpua`"k_` I75WS@J ^E¨2r~Dlľy%IUR%hJ\Cv{FWEFhgؑSl8{'bH9:4RXWBcRB2™ΦfITv]I @s݊)s9fw~159HO<]0gO̲uJx.RM\+^+KU(eK 5Ol*L^ sD])ORU5OM(b\j&OfvUL=|J1;#nVWPb ;0TPld{s\auR<. [5<ŪZ9JyRd4Ű[41͇6o) bN9>%RK^%.5 ]d$K8u SsNd.e@Woz;%I-'M 'Y>Wk)2]RMžjD|6.5u^p Uܚ2!FRmɇ /ᆲTrO@K"<2vdf5KiY,BP;h-UGeӈD+2*g-CzA~εz; 3qaYٵQ]cx]y#EN'֩ A&/%x]AϱC5(A#FXZ%`Z9PDM+q]0s %K $3oh$A*{{-,k/A|[xZ,>JbւYt懗4f89ϣw{gzFk}VB:'NHҎ+`7=RMm*m?vUDМ|O"يP KcЈ(̊$X9eW9%hR^*R62[rHO v)+Ck:ʁ٬dWɕT[ @&`^d )rwsFT|@# uC|6˔6nQEyC_bWKb8)I*f$zmY.8_iޗ9y#9o`%{sE-fEbq-i endstream endobj 27 0 obj <>stream 8;Y"299R18$j9Dp^RA6" .)W,Lr,br6Ubd,oceQpTXRkZYF<)&*&OG8,\gciWKX6((HU)q@cU;\1Gb%qq*=nnk ehO-HlM6B_$nHd*:!OXa651jpS`mc2Z#E<6T\nempcW9tNdlIj5`arJF-MLpd!nNg 4/TYIAR.-74Gi[dU*)POTD?-;7fn>8,`pGWV:V9$AG?.nWt\M?;^3e8M3`4JJuOdA :T:;RQDTM/K(l/rfhPN2iTK8L'hNH6H&FUUXe"/[TmX6EY@Ru<@NS\b3GJ; Llq&,CkWjcE^l44J!K^McuAE5Y;UST#.tE4uSE8@]da .,2_*JiN#Bg%3Js<-T##$tn-O:O.@LG86e9QWPq)pJE[2uCj3QSQ) %V`tj8s/\3DX]RbNr^No~> endstream endobj 28 0 obj [/Indexed/DeviceRGB 255 29 0 R] endobj 29 0 obj <>stream 8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn 6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> endstream endobj 22 0 obj <> endobj 30 0 obj [/View/Design] endobj 31 0 obj <>>> endobj 26 0 obj <> endobj 25 0 obj [/ICCBased 32 0 R] endobj 32 0 obj <>stream HyTSwoɞc [5laQIBHADED2mtFOE.c}08׎8GNg9w߽'0 ֠Jb  2y.-;!KZ ^i"L0- @8(r;q7Ly&Qq4j|9 V)gB0iW8#8wթ8_٥ʨQQj@&A)/g>'Kt;\ ӥ$պFZUn(4T%)뫔0C&Zi8bxEB;Pӓ̹A om?W= x-[0}y)7ta>jT7@tܛ`q2ʀ&6ZLĄ?_yxg)˔zçLU*uSkSeO4?׸c. R ߁-25 S>ӣVd`rn~Y&+`;A4 A9=-tl`;~p Gp| [`L`< "A YA+Cb(R,*T2B- ꇆnQt}MA0alSx k&^>0|>_',G!"F$H:R!zFQd?r 9\A&G rQ hE]a4zBgE#H *B=0HIpp0MxJ$D1D, VĭKĻYdE"EI2EBGt4MzNr!YK ?%_&#(0J:EAiQ(()ӔWT6U@P+!~mD eԴ!hӦh/']B/ҏӿ?a0nhF!X8܌kc&5S6lIa2cKMA!E#ƒdV(kel }}Cq9 N')].uJr  wG xR^[oƜchg`>b$*~ :Eb~,m,-ݖ,Y¬*6X[ݱF=3뭷Y~dó ti zf6~`{v.Ng#{}}jc1X6fm;'_9 r:8q:˜O:ϸ8uJqnv=MmR 4 n3ܣkGݯz=[==<=GTB(/S,]6*-W:#7*e^YDY}UjAyT`#D="b{ų+ʯ:!kJ4Gmt}uC%K7YVfFY .=b?SƕƩȺy چ k5%4m7lqlioZlG+Zz͹mzy]?uuw|"űNwW&e֥ﺱ*|j5kyݭǯg^ykEklD_p߶7Dmo꿻1ml{Mś nLl<9O[$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km endstream endobj 7 0 obj <> endobj 16 0 obj <> endobj 17 0 obj <>stream %!PS-Adobe-3.0 %%Creator: Adobe Illustrator(R) 24.0 %%AI8_CreatorVersion: 25.0.0 %%For: (Martin Schilde) () %%Title: (jamulus-server-logo-2020.ai) %%CreationDate: 07.11.20 20:57 %%Canvassize: 16383 %%BoundingBox: 0 -1024 1024 0 %%HiResBoundingBox: 0 -1024 1024 0 %%DocumentProcessColors: Cyan Magenta Yellow Black %AI5_FileFormat 14.0 %AI12_BuildNumber: 60 %AI3_ColorUsage: Color %AI7_ImageSettings: 0 %%RGBProcessColor: 0 0 0 ([Passermarken]) %AI3_Cropmarks: 0 -1024 1024 0 %AI3_TemplateBox: 50.5 -50.5 50.5 -50.5 %AI3_TileBox: 232.5 -892 791.5 -109 %AI3_DocumentPreview: None %AI5_ArtSize: 14400 14400 %AI5_RulerUnits: 6 %AI24_LargeCanvasScale: 1 %AI9_ColorModel: 1 %AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 1 %AI9_OpenToView: -924.521149296938 1848.14924411266 0.197049008168501 938 689 18 0 0 46 133 0 0 0 1 1 0 1 1 0 0 %AI5_OpenViewLayers: 7 %%PageOrigin:-350 -350 %AI7_GridSettings: 72 8 72 8 1 0 0.800000011920929 0.800000011920929 0.800000011920929 0.899999976158142 0.899999976158142 0.899999976158142 %AI9_Flatten: 1 %AI12_CMSettings: 00.MS %%EndComments endstream endobj 18 0 obj <>stream %AI24_ZStandard_Data(/X\nư 5 oB IHSm'@=?xRJ)q&c:N %i Nt<ԔcӛjttJ#ttAx|F>(oyIy+GpYGʥDyH3>K(}|vڣo!<0$ItYE$>wA;NzםʧC_\h8 }S*-+F "A @ !B (8(XQ \P„ &,2\@ c# dh1=Dp1H`c <0:x@WVtH+I<3* ( (8.@c64XQ nq5 ,84ѐ0a,g H3h,ʨ"08`Lx@yNMw&(ؕ9h~ÏﮋDR5fbp5~r?ƺsрpP"iG$ `( pҨPL W`sԌD"`4"anP$h>G9. YPUz1ºZU%++2;ٲgG)_LmHT2խY֘̑sMϕ$N9ҍA:k=3滄E* ¸i"oF7h$4D̅2i$r81XH ao8-2q,aL:jp0J6a]E& xqАq +D#(|YaZ޳geev8dCk,qjV9gvt@ECBbhjp44,fq\CIQWbX( ipC78HEGJN㎹>leՈxəՒfg#a,P, }ᢢqf* D@z"P^ajlxCaPr0tCaaF"a\A 2 !4/Do9Š\ái0ҸV84, E&mECAH7( 5F`4(35<q"qi$ B؍c);`fDgѳ\݅9~sZlp@5DeQqFI0WcQC¨GDPaeXNZQ3v̩AeH(505X{6Xb 2 Aeء4E K\X4@Swh ca$O4@HeѨᐋ\QFXgDFFkFӡX(eFEóZ K@d2m`$ɡF6F$WcqdbQc_ٜhd Ļè! psܘ'eħind26Ykޑ9N/+vYsY62̫]^`֋ze餒߆n[kmf*taiu# CXL *<"a,tE^0H   c`>aLMe7 ŢADbPBH, qӡ)` << /(2AхX,""cƘ1H]\ao@K2FޝqDD%WfT%bn` K6@ F1 `k-itՆLâ!FèL@@ C—-8Q 3f*3R.sqUJ2fcc}ΑF2agExa(e%ҝF ^C)+Y6X(sa[3$yd3c&2G QSIY#oi\Wv<Ǝ;L0$ <00H@xpBx`q>:FC5(tH4$ E"@s87ؘ ՘l#8a|yFۙ +rݱCІ:aa(("ѨUJnI |u12`d8aTA 2`d0!P!q\-  .Xp82  *ʺҡhyYML`}u#ZV?rݨeuUhlwZyOD*g,emIͺ!Qzgnݚĺ Nk,m?jS3#`Y<"["a ϔ{`Uۻv"+Z^tWvDsU׹YV_JNN_D\!>GFVϺj)]̒Fr2)pXudVn6({j脗x{,m&+ ov)3+oi|zS(EdfJybӲ2ד#r5g;ݱrUz;9ڪR;k#ezrIƻٓ.$,j OndxX96꒬V%APJڨUQ=+{c=%1cq\`ov&rzv|8v/IBrt4e9yI.6+U;=汔zJlWz]|\Fvˆ|9,Ng{ ai vhgd3V^=WV.j3焬9g+4WA96dϥԒ}:'^teTMo5?'u(v}۲Wٜ_ٞcvRGhZ{LI5%ɗX~$MA w9kD:ӭߴK;-ubVYW'3dey9ϣ6w#Sß^RBEyGG>JU#~I($R3ZD3eƕ:VOY5»Rs0]Iqy*1NB˙9; ־ ަ%~,َk{ǖblSKV5 #sL(X'seˑf%}e!^;晠":bs֖-H+6f{ _G$PY$KWOzLmI)O68M¦IwX%Z:h?y{cu&!kK+^Vʗ}NHTu+Hu*޹3mJx&KFwY7$bU4J΄$a^i*egƳCRax'YG#IlO+e[YZpVx&+$oL$KGnz$y4sl -n"|m_x!X:}i/ ]z9x=LlX()$P2ITO~0Q=R?_dQW$˫g""XHgБuSf|~m>0[˫"y0Y=^^e"IgVei{mtW{)5j$z˜ 1Ddiv*C)lmxyD.t=IGh{ݝ!مrmwVv&eϥSqǢ1%]䝍7_z2[:>l{_\h2vXQ a/vSȇCo$ѤtǧεxU$ϰl4+1ѫ^4 tÚfCCVc}д쭋)Ǥy8UAyRΎgwu4lug^>j3>&ih(&yܒN5=dr?rz!,Ú{Kk|uc]\wG֫nH󠪙baU_H'VHQ}%dSؠ]\VYeAYJ4}nuZSB+qH%]0BDbLsxUrz+on,t ݛk]I:xK|zãOe9WHwX=<;\{7% YKK-Ɏ󛚏'[4C)^Q9mjէbQ;` 8PaB@ c%S>N_ԑPh;$tI^nh#I>.kZPqBҤG֩^z9b=3=%w>Mc,C2reݔu,Ur6z7:oKY3ϒIJiN5 K3c'i/ݩe“ԓ\(隩 kx~ʆ =SҧdV}j&&V5Cۦ~N$M¢,"$'IuSJw&i |P$ !T7Y9_2GU* OA=DrjR׳+9(ՠFRj:=JZأmյJ;>LAeˈP鬄lu;OԇK)Cw/;/!`eK2g7Wna>n4h9 +B+1tԧ(N2з)ܟ4=?FF,"+푡# ǔaIb{U?$g%9egʒ`U9*Τ{quXa IȦEr/3dȎ]^ ՎZӖTtҌ[4YI[N3y(w(WG )nD ّWIyStfAvr+6 [ytId[kiD:Z莦/n<%t"^"-㮣. 6{<8Yzi׺Q6Yj%f_>ʧ^&YY`bV9A) eHzؑS/ $K2 aU#P~)faM|=#JIK<D+Vy|fHE$F# wIbD)T%xi !Xwq2A852/;ƒS£ WLDxrJ̴Ux;H.]StڛҪ|Iwi>1׹͌>ϝ;2lFY|n 3 JIi&,'!~j#^++ɎWEt}kULϲ%Uf̫SW4l^bͫ;'ޗ]=M"I/浗ٯ&[{<~хNGXU8.l5:"}sdY卌r0sv4K#mLvD_*{Cgyos|yXT{mm!ل]ݕ>Evծ|ZwX mΦsdՐ;999992c·fLcsq(%KZ}5i1m6%njSidttt~lFX+ݍt}f&kÏ/GǏA"hcIcBEĻtНotXHg;Q?]ٝZs1[I ?Fڟ=eMDGgYG ݹH2LzӞY^1G5TU=2*A+՜ts> Ye١ɹXK;E=\DO!ΌgƲCfgE]kgFVySڞ)"J*KIdwɤ2/eDVy)#V|vVdY{b*|7f}bPuo+}2xetL>rnuG 9kJ؎9zdhR%|FtQrbk%tRQXGz~aeTGdSegdq ɤȶ̻֖U':QƈlXf.c>Ww-R-QQ?U43dSX~MFnkZuе-vVt TJeڛPZ+JggcƣT&U>j\dt ՊH5z"It2-쎞En|ak7;^ Q}zXQL!RL<+gZVǵ8h7p;K vKK<̎9&u)պɑ󹭹z$UAW^n9Ϩi1XG>70d$y٫8#E۱mGQjW%G:>DʲɚWgUdKK-uX-YE6Dˋ|:syR.SK=:jĺlZ9'u)8v4/غhkK㫳_qP>?czaYVC[򎣔6kr: +dvJ8ūnw>o4;Z8sV:YliCDUt]|PhD)+-фxO2ʼ݊N{FR\j8XGWšO8t+#T*}#Ω(-<|ChXZY6gf<挌DH|.Z˗KfNF7« iFO1zq.f>RLF"eS+W.K+-eYɮGf3lҴz2jwE7IEL?^Gv`x`O+yTGzݤG0Ų^5_=)9߂&S4}JPS]竘OyuU/Mx 힘:n񝼦HiJUC<bs0P›$za`{wf!m6t⡛{J(;}`՜Ўsh.1]]rWsJҺ:ɧThl;LKKXSU[3.R-8h=|](fdqKf 7;$ˢ੯wZc1:&DLPc !H0@0 Q\~B^2GL1!`MU_ xyA!/"{d n)lꩴZJTFNFϋP/:aK bpGeZa 5^^48:ź\'}HvJBFfpJ4!™Bfqq{]FVZ43tN_{!-Hz}at;,R7člJTT eO$ۂ_QY Tl_T%.Ga0B1 ff;Mys\1KάJ l\jvȃa 7Sh*Qo)wFH:I+9c nlM S(4/jX+mLuR'䃵&Z<^f, `ޥ<&%ɋIJtighÉcTTq䗻L> sO⍸[VyHK$]L 8c%cPl]?O+Fe"MtK*o=× "6¥/VtwiEP(4R>zw/-ܪg]6jօ Pٺu*"y<]ͺ!}T׀nʭm~:K$xgEFL'9u#uiRޜ,)mlv%>@"X+^;;KQ ݔZ-M"K1 I$!]vL kߪYWdbgL`Lܙfm*Ӆ3'H t&a6݋PnAB=G%J@E_.Ad#8z8ӥM,21xrq%6zHE_z,>bR/˿=t_vއbu,y*0n~>*BE5 : ytwe=":zR0BihC6{qAN8#ZLo7*7`5U4u^̩h1}dhJM-AIMd ٗB Ll=/'!PL 7S>, :y=$W!d #B;"dv[)|{U5R:x]OVpB5ĸ1yD# Aaf\ 4A`ksq?\l-cD>K!hAApT 5/?PSټs.I$h$ %}ɂFk2 )B@O͔ rF^N5yVT#wւ[/\)|Щ7QYC*0&}R.Iǟ AV'*J=TVfYo\|+pΌiAkuP@ >/dlw]~:=u`1ODH*׮Mol# !5G$kܩ;%. p 7Es?E6" ziXoܶꯇ6N~G$7|pQ!q;+GJY*oY_ښ sqCڛ)q4 4@F^E_!p`=k[4U=Ma ^n8ضZ7FXIA l-Ne eB*d; =O}:-o.<+|WLn_n. *ĺ/0U!qYa i_\P!V: YBY/'C"qj;z@A:WVͯX!6FSny'mॄ.q^G@4 ݿ\ݧ6>~Gao͹H3&H)AH+= *ITW<8 4mGxj]w-= KCꫲԁ }eZdǦV YC/8ǭGis8W޴HH+\)0O\W"Jl!RVq+20`칥֪Mfh-ē)agvO eCm aq1c9h Ҏ(ޟ"lYY> RfpiCsM/-cnac!m?}moX,M%i"P+`E&Z8&LijyԒxǷg)Ow<4ՠ[ ĕ_qNJ`6ϮƮdr'̌ZJ9plz,R-Sⷑ (!a(Q]9};?#><0񄣦&ُڄ+(#j”< kD9sF\XiK֮ě0d1 Ki DB8 T5IS9,a\$e.8C z@JAɌvW6W RSN6!ts8hhڈ`)*-]:☩-Њj6 8rNbʍhyUapLm9=-#zJ2CqɇbyQm5ü(B[,M]rZc{IEe*aoƅCՍgK+"@[H+b*IyQCo :p'6Y!'o.{}ss^:g5jnѨlN $9:xH1~M'涰eA.Ao~ȶR^Uǁֱ*/+yC׊";Z`M*d IQw-P;ѮegVm$^_,(M6r "JA:5-E/P.+4JɺƝ|EiOK Hf}~ IbΪ,,v epPsDdTKq=B{~qC% 2\ZxӃjUYo0XI8ps{ݶG]NP]H`!78m/t/6E1 [`.g bx,`U*[\ 'fP-W-)_?cxu5c3K4'i:aPV 5{Q.Q~eHL~dDx}PwFXd҃@Ut#I[a"D ~r)alJH!:,w|ԣL?{qCd\lEmvRԑ/6*{ѵl:p*:b^,'0XjzӾ@"(̅gj{A8Y.eXl~8CN%Lƹ˷5_I``%1NߏN1ޯMonv|Y^3vbt^zŽ b+41bxBK =-jrb0PHbȒ*$JPQ*j^3$DFTAd69Mܠd}!LLHF[ZEx?fU @j a2SKc& $ ;l1eVg( cYa?awy/@r#z4X"4i&2yj{=nI(FER\A}tX,ed5x9c$gJ Ґb8+ y;89()g<@J-va-Fxi7o`cðL'L1O0N,$֜ %y!<. #Drz/ axXp#"B熫_){]/" Ϳ^Bj*=R-RUl5L[b ^4"ŕ]ߠf11GuK54cmjN)U`~u|x#Cv:t LStZ2[~b5l *CR舩j`_ E=X|E UY2s [a,7ԣؕgMS6@ȉ/ 8}DPܬh^"F];+ډ0O"į=_0a^t0 ? * fP."~P` 9> }}Hq7"X&6j2Ms,hP Ŋ滛RJb-yF%^?đ΁Nf¼[]3蛕I!ظPxP-‘CW/P&0҈3?q]ڰRr;z7gI~.y^UZOKGf"HKO?Arܒ޷i.̕Ê9Gߖ*6LF31yH:=0ߖRK5{;08ńa~/fVl8#u;ʥwN~ ND* h MY &+\ܷ݆Ym4}Ƌ&ϗh_Fֆ]Of􀇀/3\G^dL*#ȕ:`GM:m;,nLHc5Ķm#ܓ w4EbKII!hhۍ+1mV( AHP,^, jR(fk<UK/X 6 V^D{ȗe.[@A'-/ ^p'؀@8=ysעuK18|#7JoW*> 2^Ul5F8ٕPanwF[T>WSY\ЕAqb1@ZYĖ@s7mӕHH!ErJJ_|1njVNyAg"7;{NE:Da]ƣM5c(Wsk'9)CEi2/{?5#5Rfq18y';=0ֆ)5hcz_Te"yСʤ닡Ӥ'&,-}d->^Myݨ|U$3"cŵ`R j&kk]M7c3@v!4D#j]%kda肉lD]\h p,8EVnbC=}rE1J2t*R9 G0D'sa1{ChQ{A% -tFꥶYG.YL,)ш7&ٌNt^ZjQ>O!$kZI`D96O5>`LppL³1U_šy\ɟ[NZB]LK_P)f ^ ?,o|1Ty;oLӸxRV73DOl &=Qˍͻ Fc#*͠JXCS C"~Q}N^Dtn0ւU2F!.iVkf΄5 i̎dHԄagXA@bPEXW^OWOi&eցR7?8cgV+' wN5A>G9}"$BJt6w)cNB1P ݢ/`IY_`l$"몄%)\v%$kC 14^}yW 鞱ocƨA5?bQ" 5@  ?^Lp%R# osCJM7|Ƿi()'*CkZ1 (aV߹QikoBAЯ\l_Upv ONT &qĭʳdrE%0/S&'-_yN_m(y͠ NS5!3+Q 4O%=sCĺA'y0n tDL-> +N4"Wgr#L ٴX51wUrFtY'@' C C#s!3ҹQNjx]Nv5~JӣUH<'aotUϓIM1ܻ~cXn3?$VN( @RC6\;A.R8SX. Fi2 0>Ƽ/_<ԺNH1B- ^yu!uqyHWLcZ5PSb\KC2=l0QGh3dٴ҄Cg^vӦqTc#4HV%:C]OO3tW&I-@`_ %v0#,Bzp,j[Ê2bQ \2`1e~j45 `]THnUz:~{,چ "@E 2ץo~!] ^^FuFߔ{=pW&^KFH1tI:R [8 Z"J2>/;}_j+NW"y!ufV75(jY>"$6ݽ.TwNaȉJVh$_BxC4& oo&Z;0E`[i<97 гI4(PBm1Rt;k ㆀF G TiL )PJ%7crMrihUI#]rsIiۀӦD>oD>*muiJ5_{/N:0_rj,^Ӛ^6qp] A4_2Y?iU]@^<] !u+|dEf/(VӌPL=&wwygA*B IB}b4Z,x>$w[ĮvHe!ᳶ7 7K杋0\@60ӋK~u6hSH)YT|t4̐2h\ V/קԫ(pĭaF@ yO%{+DHJ $Fp4 1#kjL/dz1g0u{+I5CjA͊i[P ݄2Hz&+ O)&cp\?9a72] LD9_0yHͼK05xS}Rgqg%[Vb,UfN1—t3x>8 O+G[i(Y@ufAݱDN3G#[^G|bbf6L,tK{^K`Ʃ~̌)reA*lLH ~)G*0XbMSXAL7"IN饯%q[AbP#9zGla$(I>feELWL'b 5{HO '@UQaƅVcn/>hXh8l+9run#o0 T.&c1wڏ H0 >VFvV:vц^2" l( ˗;f̤g|f 8 c3>Ù?#Uuf)g`<j^3-pAC45hUJӖlM)ƓӐjz55pL_8 'Sր4h-2v9 Ҥ+#SxNM*z4 zO>KOiPsSئi4 Ct[xuUo!CeJؙtatFճqZ=h m$WU ~R4>4-κ뎃y8Q˼P ~;۷yϥ=#m//ᮬW&boR,:6/K Vd A >2V+)>w)g]ၝV4 EԹ ,{5 ഻^w1D1cw*Ё#7NwXY\gMWEWyB\jim#'?u.w}!nH^ 0'NRc^HZ B&c;C1zg>Uچ|1vOw<ʘD_Z}cEsZ`d7X/j9/)}XM6bcs9JRG'zKBWjgT[1XDOx?*B;R_Thב^='e6-z7lǢQ J_xTBGqMR QCifn»'IgyEk:8ٴ,.5 "kLP@/%'UID WD| m6vE4I5flkf-(VءJߨ/*AȰK1l‡eيNS֠Prt/,6ʠ6ju<U7DpGNA,W4UL, t1S6/Oa~M,(} % "Aژtt+%SZ^a0x0Jol}|hit Q?0AYiNŽgGHNDj ;Qté,׃v O3M"~=47Bz% R0G"0.\A4`wO_)ty+=̛yO]Sphdf(t8|hŇf͟-(:Oi eQ!d@ 9B]!B;''P9CJ$řޠvv3Dp삾_8} z o%$I@Rc uKpA&x4o'X\(*x,珼K9RPmNN0=>-dY?}޶|$@OS;ODR1y A)[>D\S\'rCϔ;c& <(Eh@(UQ*#Cnqx^ T SY(L H #IƻqTe[`[a^v0‡۲I˅6(jCXs5 <̲Օ/K HK,m<ک1v`SF, Kc׋ӡT;鼊F$'ftQt:ݯ<%XoMPCz6HQ *M'AF(u5u}z_ OFH:JO(wEJș}XDD"^s}.&r2x5v(G95R; | 5&\$ȁw MQx(}\HQt4铖^NDl(lb p=L_]41&ϵbE7I1z_§$N,\-2OtF KϮ~A ?0kM!pklx skɵ/!k:A t$!gv9y⹷VzJ(Rkvu9`PO^7I>- M=.,.mo)-54C۾v-[ܖ]gb`oVВq-*b jbppf,ң$%Ō?SDS}f4vt|D-R,[(\◞ HwDH7lǖɲa>qVw㺌#QG +!ZL'+%v%Q?he\8AW#}*_c6vSa0ʕ\+Z.M׳YZu(F zdJ8)]V-4ˤ Nv,gE[_曣i5pGdXCՑAgwU[;!+|[! V+:cf(;C]a"3Ud3C+6Z{NZ_iU/I_gL"WT0t(;K8B4I[1B5Rn׃VXQ^xk0t# ɑ }Ą'%}Ը؀k 1qJ> ^5E_DA:%fO^kֆEn L~ rUJԻq<݀Iqži4f6}XA;ju27 sy9 IBMuOCF]6z@Zwcb|@53W"v**WlOKo+Uf}+t,\[gh&['VD.i%'yfrB*^4:9ArMe|8H@K-ߠdg4#VۜD`#EdymM$`@Hʁ_S$v%LYWKg?% Eoӧ#6\SEUQ?2k揹il9(CRl<0!|%x)~$bjӳ"dT[LX0$u߳c%H0(M}h+hQ)ng"4quɍK4nY"rtR"$_#BJ*ұ|M%xW*cK]R~16YƔɽyQjnt6d LۢvрS*5 ~ҋ_>jfRʴ+&/#cr2c1N_wwSUۏrI17]y>|ǭL}zxq+, \Xb*| o.ͭ֘ۈhGD@V\_;zTlAUg>m`c$2>q(8b{D#Y_By(U@8Mev';dEpqψ(jD-jJ쿽D$=1#ƢM`DݺMSByZ@cfww}rpjD@ْlx]y,jol³ZƏ͈;|zZvxX}{n崔<{,$M3Yʲ: _D(nAxy &N_ '^x2%t&U4a!- yа$ٶlhh,BBk~NF"P(,v*6M]:>wuǖ\XދAӅȋC V:]ov3@חi_=ڑ2ua<ڂp^]HQ R GչĂ^f`ynAk ,}6 lAUV/3[Q+_ƶ9m{6umo :cX%z.E.>h|.啴y膰fVyO-&W.]SӴk"2vٻҽӻ}9?f tgڥ:<tu\!} T[z]@w{ޡ>`yU\ er!u(4|]d&X5Tr]嚓Gȹ$UK7 &VdGI+&y~rbT=s-sB~JvU1{iy%u =t}ld~({<)f"b9S8Gn eNҍ)_2|Te pd^In ]xC\}Jo LmW{8 U~oo3:)VrC/ѣ_o3S>‘R.JO<0rvOr ;?rR' uٜKkn kt\'A$Y(,}Hk=#PMN [0 yKke*8,oz c,m:TX *;N4o1a}^lr{7kv39re g6 0ěIk<ɿ79bGmrS_ӍzTyT{ـ{t)ZVPVz{%֣nrzq"t";Wl,CW T,]w8J*XBJnu+y;hS!wa6:a}ܒu/*84]痱 &IquX,OrhёU_H1ᰞp70XeUevF "P}H*ܫ |uLdu d\p0fCZgX|\\x&6'_b@ŊAl|غ' #˼@1VhjdTN 86#k_4-ßp˳L:3TB}ࠥ[!MK:`?_/U| Yi!د[NP+PqB EQg+`Wp0Ryt+IGŦU ke; w+Ytr;)ʾ9ߥ N;(ȽH1 P|QARi<;ki$ g2Ux{Lb*K/GwFW P9]K+t 'GlFѬ ޙ;dc*qs\Y0 \BG`ݭת!m+=Ua횱$X%)W9ro βu `1uLr#˖F {Hۚ|bv5+7Lpb9[>u 5Fdl۠,?r7 ĩFg&rOO׽{\mJEYG,TtWͱ ZtEEнښmM(WfW&n +K7"j ~m_ nvd<ݘ3A㔶d,B=2OKtHEN-:FTZYuV1u~ZHDv(*5&㒍*#i[|iּ,3l7o˛KqS$!-dᔬGXw|E=qvqYM1K:R՚v" bZwmD:㒰[@ix33뾟P^PY YJ{#En\˩^C,[hSarb;Z;Z:K`36pj }J4&r2&Z_!\j}4>fK !d=7T+WfBiӛFFCЎ0\8y \vρ3,Qr8u7f  wq(>QX%ik :H]upq %N͜r+y8N D'a1TWvݤ^%C5bcsje{I< v 9_Yq:UM4NO)+nqo&B}KjGQB$^I3g# 0Q? ąp|kq@+}+[ Y`U 1x3ZU5[험d7U%zfMKL_m&;My-F2c4F#c}9#)qˏ=qAs5#%A5-Zlubv_X^4!'rU<BdN1 ?-/OM3 tUZyz>| 3r@w+ P )wSFY8ʔN?V~ /e(K%6Bf RUY DMf ЩeAŃt*q:%EbǨ.}v/Y͕*.e : +:_GLr>pHY*JIIa=Y:4?,NG3hЮC4rkye=y-IHxŻtI'd7Wk,[-縒}:@ CVC[u]5B@OwC UKb{Zzr4mw {Uo~%Օc碋z"Ji==Z:TEQ^G^5U h׊q6/K/]p=;kN{ָ< e Bw.[;E 8ܬ3;7] %2!?oV(梶- QQK|l: v)Ian9&(}J" ?*EgA!;TΫ?Gv`\?iR l8 i$h (/iz e1}( KuR%޴4\$390ޓHvb@OkAl?=z9P3_F6= p}.&8牢qO2B0ؽFIpξF|V~9&<3%P!Ã#5BJtDtsbD7i罉QUG CF9C}ɶۦ!a%XV0uy& q8f7+As#'2$-{O O7].fy_^@Eۃ M,kL\."֨- 1-X`1p#0;|+&l7c lbNF1XSH]ͬ(-vՑuuBF28Q ecaJE7†_uCR'/n\HO1$y֋4J8em:x3x&p|)jJ64rZGC@jY@25}WOn(#*bVF"0_[ZуjE{]# ~h%sVz@_tPd02naDO) H^-L_0fkA^D{j֎ZOmՌb;G* ^@v~ (nŚיBDj0\ _^$!䵊AU RUyFUM\,U1o5ӂKUfxR_Z`I5돩ʁ*4,U#jHSrY̛sUUL;7\jK@@Y(|]5 w]aE;S:5@p64*W/Hf!q(ֈTX߳ؔJxz5@~K3cE!=IX)'6ZVqgyLlbJ\wbg"FD !TtvLb2XK,CHFO- H5o9I ڝB.${z`!`Hh|;3(/PEs Ue=?hl-=4G80j}KU"J|-Gc\\yD؉m;iҕ=us+懺* VX9@[>vㄈÑf/㫜t ov#ފJԃ_uZA0`sfxv[ʊ|T. j}xqHgHۃZBOf6iBHB T<ѪY~#mZ_:iC{PZj1z Sʡ;׶ΉkQR:i qȣ';)<'KiXΠ'R.<{C֖?5̈s%A&BVCt]aD2tu);\) 6T~"'Az0_IYbm1 zO<{giWo˾s}Ƈ Wշ DN/b&jooV/ eqᓈ)uLe?@ɃJQ#?{x=;`. Kx(YQi1#x`кYe sb.5~0-B K'bARM]^vM5] 7Sm }[JwcSi9S}%˸wiJ8SZ j2R5m0 QR7LtDt:6jcD{g t2Q^9A64ģn͙P܉},.p Ҧ4r_Ȅ~68W`ת́7ô%u s]F5lewQ$K ؾ'/I.m[byd -liqeR-GD^%B'͵ĵjRr˚|QϤ*nu_WLg #8AQUgcʬe0 ~M>SZ ,n4X>S.dP`(3-Hl (2`+A4EX:C, ES#zR$EW8d"[Owc2S =5uŀVR"Ig ŏ$v:(TiEKR^eR V^KwǷ,#~Q0QgϐObBQ˙I*/H],lŊ^"!? ] 9p@C`?L !!>OM!uc(Wɍ<6"ѾwTJ~0ZRI3ȯqӼa6o_?yЙU{Dbtx0/:q99;0e:{tɎ+]c553aVod׶?0B(E ӮH ;zkgͮe]V)%jCvMV2]XiXvTѶr[PnM2ApFͿT8+. XzO|z]By5Za*-Ȉ^xͭ* $]GAz]،|5m rURmqwDnxGV0D%Lve6tǑt cn(iw&m$igi r eHEc=@E! ?r񻍫";tbk+mfdʓ,Pd3jh7s=#G[*Ŵϭ.H7K ''','3Ob;]ġvc蔰#SZ3iݿ6t6hg251,9#MDMDLGV 9q "|xbnTtkhOHk# f_7a>*xɁklL]Ô rTW <-ThA("əɘz23O3\QSɰva&ݽ?V_`8sk#Lu$U%xxC9?h",~6<:6Q` X>À#FRʔLRKG}^bVZb*f11fBǨAteZu;9Oc>aA*<0x*§ϧLRmJPkEӆW<\;US^U$#16;so"oj5,N D4>h(ife.]WꐟM+b$,!'#$Vl3!S#OYƑ *μ0P"BDWH ]VŇdFLYy^WΘͫ"l¦k/3AD %IPl:ACCa">M_-}/!W(А1BK&K:kk䫠6S%sg*Nx ScLN WUՙ҂)ш+?֢ <6%{ YW9+jY8ZXvJ m2HD&Cތ!AؤoV!FΗ8/&,P\'*O ܼZ؞o30q3 e%d*&}aS+d1b}]=/!;L7)#'W")AA 'mw#AUL1֩Er .WUSffo:XEMgQmխ)&ySz4BmT鼈Aͅ,C$2Dqe2ce#M y}b$WF4A\0]`Z#/BP$D+/PL"/7T8QAD(0$! cL )XR+B(P( DFDɱB[!ꕆ!31`G=N .). EV"tv d6\UpU3Q;Ԝ=u<}v lY)&Mmڤ]v@{'س]OZ)pHa!zh~ ѵR> j%md2rj=),g*^5冓$`#;1eńJF\BE UkcI=SF0PM 'w.P 5fy}wcn;2E#r3=b#$0ZT 4^%zZ>q{ e(=)qΛu^(Oh6m IǻJR&ALNBJmd+1 HVNQ%JV9J%E+ҽ(OusZ m8$Q JjJjĢiG%.KR!5J`FG I G-=99,)t-jY.3SUS3Yh>, O:WiFx>"tb˄"ww,Hz&d!UwaPѾ$.[ye< yuo,4BʫlQq1&W~skAkki hb}^Kf2NQ>"+f!qtPNbɥ+;7FhqzY%$95_ڷ0ٌ) v]TG#D~MF#VԂtѸYj5exTi4hdaE=ZPt&Me(6Bru\DjITxۙ#\t'"KxalfqNӯJ6 wňxaIgZA4ATpjr:IA^NlQ.Tg܎گu !7k" r4"mӶF6Nm}9_L2r8%:Z5XY#e.9.E*M4ѩ(Hwu`YMS*z 1!bdGJd2*PUR1q+Gŏ?:5tVV``pb#(9 LbuD#"D"b$y :  ( T 00AD@`#Є۟TF%h}bhj}S*4*As9S!QǮ"BbPYdS1ʠ=2aB)*)'HQŒ(Ǵ F+h +.,XDI_T5bZ 8*sSHTAtŪxkfM.Ɨjǚu2~3W:?ZԄ5mNelb5!FF>k3M+p=ԙ)N/:ATQ^֕\4cZ?Q~D?ΰ3K3gq7OgZ>WeU'z$4VFah-?9+U-gJ^я%ZG{9vo`\Oq<5cI2gB'+dF7+V b61΅i?C[Ju;1ED^{7D}%&$IKt .|""Rn$$R!;y5)3ܺjСƶ3\kjQ^؎t]#J4ߌ(.L%g]hH.*KCӒİ)jZkdBYjoԣQYfqɤ1}B۸ 4F\b1Q#Y Eka­BL#V)%_{ƬA9_%rCngqcD!t*#ub't}lre !?&8MӐ(TZT=aZ bQ= %#,ˈ qNċ\Ň)9t}EH?O|fcB(/I6r'Wp%'fX6KMMcBzɎj۷(EDV EkLJYM$V)5d6/ƛ\3gGMIhTSxyT4'B]t6{n/׆vTۺZjgڟI\.*!rHBq9zQ#t<ڑ%-D܅s (ƯP>FBLf߰B-W^$(AAEqrDe#XvObF30\9UK#q6"QiAjf2⡂))$ ` M}ǵg<?0ؾ3U4zryk)!?ˏgyBE-wO&qkȨUiCQ A!&NwD':QN" Th ԀÉF3a9N m/ 3 t8&0dÃ6Ipjиu L 4cqjF"T D4D@S@y()9WI=B!h&|uP'BAj:oEGRcTxTx)4lsHQB44کNSX뻐1u)P4>fvWNrZEa,Y&kMk\>E3c| ̴VTHr ]Ejcar(L5$*<$94ǸwÏO*&*bbNC_aS@*YD :0%4 ^ԁ3j@!I sj{: iitBCd̊0a4$PA"SB4*t@RP.! )IwE^#Qf̽@$^ԆԬ杬DKDDDcټ(Y2m:%0 ),gE[M¬i/BOPbg f"A-OB󡮔C-PD"t(x<ǩ\W'p.Øat] 0_`(oA%e Y[Nb P@0{eVY.ZC_?4N~,5LȜ&LHbR*p8 *GSt͞FD#И31R6bFP9j0!e :SX(:Ta>7EfK[FTjRh .|-=BiD-C`ZS-pZx(Bu&B'0 ^VRp2 SV3 M,2i^{MGVL7T}Tn`@| yE|s9|!"m] DRE?ka9nf!)7￘)9J^U#!W.7AZUI0T#b=Æ%0r&D"iy\δ5 ,BG164 >zDZ wh5@Qa뺸,2.'-6HAe>^* ZăV/7s ;Y(I2`uҜ*έcvJq H~gb ֧OQNtZC3C* U&vW?M` 4V?S`4:PF9YHTD$I0wOŃ_n(b/e#+Vf( X,zBM(f(@>m $URSi),YA LK94Ga,DnڅcY $B,G%pڙl\@IJkvGK.2#Pu."`;I -_d7y 5{ˑ3ۙ\#EP +nFђZ7#.F&arL@?JY5% ٌԯX7^_aLlPT32Q,S{oDUBp*phĿ v̵v Oʔ [:Qvl)0>p62)S$>!Xݘр| =X W7.Yf+ 'ˋ_N *9@7U,/J.建1- \/}m$oW*J&#DB#tHzL@*Q$f͆UZw9!zQ2!|Ž]J1Zj F&\岘/V'k8~IU_E3%XL=7ϋy$8ic kBIڒs|b]6t`y 3ѹه ?TpڱJhdMJLx1 j*T!!+^OX'x( vf&A<NxAS $eyIJeF,:؜Hyd;UkQ'I_]henpH)s_7;,-vd~Wй)@\)ucMȄ40qEEwأU^G!!da]y21PU;8 65t$-K%ش5GLֽ!0҄ K\`Mȟr{C5f(|3XǞO鰢#I '?pÐ&M4*ׄ\8mx.\<,QkЅP̍8(B EɷxŻ$/ K$&@O#؀-ݱ.S/MúUf0 !YP`>0+.Ws6Ēy (m}My,yX:#x⟌bM"4ς~l+ooyFՂZ4@`$SVz :8)!Tk~h80.ÂVHaE0@SSܹK&|ّsHLdZ fFg0;]/ïM#JюX2`,pċ%2|k0{b5!-!1ڴhCs8c  T6tDJ[7t %t 4ş8ji!n3p<ER@kۀ}*iFjI(JO*p6z1w8`P{{P J]*kVIW+2gC`BOgșr=JYX1wnKg~#lkҎPi PAcK;+l1Fr٭p PY-EBD̉ÆkdA4צRvPJ?ցA U< zv>rwGz*b̵<J*$Se텕.*w)Wb[O:%@ND/҅eܘ!%Kz`s]K?+%J@^+3nL>7+g2ue -ڡlxæ3΂g?NW({1߳fV\#nE4μC3}iV{F0+".9.h6ʦ2ؔU D9)N۽UTvsf#g ]VHhyl%* 5*we,1c|V~7BnCmƓ(aI; F!6Dqʇe$̇IϘ=c4F"vXL"c֞^kf b ;MГ~DL=s-⮌ ` cHײ8is!5Z[+omK­ u.LHVp)W_1WרXd$/spWIr"wx#(uybWϒ^ttB H!7u]!հcs)OF;2?;>H7}]+)"rL\ pVtI@z P#EH2!2:t.({P󏱲~rRBԜjbNvQ OQU!wS`KjܚI(ZI塀vDK'_,(=kAM^ DIkԇ%Z2aJLKR-}U WwB0F?jFKiuL={;\BwWq=I,ԗgiS ¾M6mBקVqVTz+C'amo9\5!&IQ)C{ ġ7cB3EkgBOM4HO Rزjr{{BE}!enmKԁkx#iDw~PڋS7;^RO)#龜DW+e%~Ƅ^;B n67X9ǯ #ba+4ܴ0D:%r=rQh:]z݁2lH)a5F.BaAk@CNU'*B;19.aSP3Y7^ uZj CO:(/Ǘh)k\&P"  "P(kq.CQ["!Kho,1Ms !kFWOwlkCY+&(A/%dž<%pL.]Zl4˷ r1:q)zaf~@[Pw'g+gS惄 A(Z "1LC@Z+[ԬWМA(v '4qbVuf1ړ#-7\9z3K 9a^0\W ޗvguXZ6Ѵܳݐi0  uc$w-"V!ILy$D;TI_.B|矌\q n\ь_q[",)S2,#iP6"P.g9DGoSV`Y98srN7;F;lCP3ArכH|zOj:"(*&/]A/G19,WZ ZTnk*Pa1&0 #U )I{]*iF;q|hhۜHysHr`2Y=\B#>eZ J>#>CBN7YK8_[^}cŒcʠw-t)8o6AI$|^0J'^ޱ{@kRPgv4*g6F6M'T\Ĥ7hm!fZeCA^$835 >e[?D0P=5H=ELI=.QP-sRԌqR:Wt9Q;IEП DMc:E^_3@'o,EA0T <\텀:]qտXx+ccJ u".deir+<#7*kʘ@rw $N6I: klp)Qu|@Vxjo^gt3z+U{t\7CT TW[ZY8Frvu[ " =o8Pyio` B2N kfm-X[^]-W6X*V tUpNI_I,j˔(/Oe"$6mQp't-@}*~{N !Zj21_#ZJe[/Ƙ)QB4MXCòI0}83DnrՅ0Hddψ-%.Z}UeJz_捇GZ}MT> %5x]ιY"lQ%7rYyS8~tܩn|}=gϣ6X11|^=醍Y"&RXd"n8P)@=DZ2/{YCS.ڼAQ(yIl6?TX 3S3pQlnoeʷA8!)607x>,D<conT-vhvZfKsBgX_0G_K,spU,<_Y|θk (=HouڐՂҷ8AW7X\_:@|*TMLt#99d,GA@رS4BDqC*~<dӇ6p՛7C^"`NVE.lFḯ,؞Ɖ&7ZϓFKcC eLu1t('7\l1Rt>}erO |]F^ Xܯ"0<['A2CT=O1"l9aodɔd+ PkqӚ?kLSq1kE]L` atbiJ: ?blpK޽~Z8] LRmFXfbt=BϯP #)HK'&rM  lʒFa{9b $qczýI BW`ቓe&jQSB41Pe (74vW5ҫ pjcIX #8C.Ӡ[9ttAWȢQ ]lPɺ>l-xFɢk_ݣ#sorMz4gy(?Z0pkbj ,rGY͹0nׅY^zp8+BJ/HH;"|A }`؉ i@ J1 2H109MvX{*8Sq2bOB OW6f)2 Og2?4!  cCv  A !*e=XCydSVE.e dЅaZB rV: v8DҞCD-! IH'b<!cgRga|HĂ!tNj.7E6,(T:BQ$.2RGb rMR[%18IQCPb HS "JduV@5Z8N:0 n D/` R I \'@ R&8݀p&([@@ xe8@DM N@bi6psi `{GWyX0VB{ݏ6^A*B2yߢ0M(  ? +K}+SPlan ҧMPD} TRQT,&GS1Z>x3ݪl|̶ Y>9hf}v4X{An ٯ+{ 5؃a1\\5d!zTYhb0,FJ[hу&z0-&DQ<ŤlAQyiyĿ!01 -HN<\0$kA.8 ж b6zw`T|4 ;;c_, _,AA"uDŝ x apB; @a@a܇a:1,Xua1X8Buiѣ9ƀctBƧtL #Keft]31 Ё ,pO 7.Osj!S 4V9bh,1h,a9xN98&&.l.r9YAPc8JTcbo5G Yh5T?9bcևcRW":kAG2mzm|)8H 1p7HZ~n ޙPHyo,~cy:1I1 ٸpv7?) S6O:z L' ,/zbMP8ow)]8w6^$@ 1@15 i4:ǀ1 uZK:J9&HH: 6j19RQFk @1S^rbA1&g4`r,wg@%EUn9b3xfԘa3cӌ=Kۧ46ebF#UZy2J 1+*Ȕk@hrLY'PG|+fLYCF@1c@p119u0 jJQ15]O9vc1໨S>1ȖC#F7 14l> cʐcq0Ƕ э~¨Fj (q, Ơ!ZqV0#Ft "D0lWJABо@27r0IN=^BH n`K>9RNP ڥ@xb mW"pd%dTJDݱVp!R9@3Q$fOD'!5 .&aLY2"{D3JaDb=hz"DhHZ"!AHlףSȦD1x="'2G#ҥf}t#A#؈35" ]6|FJđsj:Fx}G콈IlkXsVEA2"NLH֤CBH$'\dl$JGD"Iwdz$AD1 AN(IF=: IZBP% 2D S¬JVDJV?^ɆbX2Ovp". !(<tfJ/dL0! b61,Θ@PuѫH 0{ aaw&hT4f/5PX܄M.Z0l‡r|k{hBNVzu¼z貜 7;ٚyVyȐ092CW XP:}\K>L_JTLd3;YٹJq);* @k[>.x2;NV;<9L;? i݁dNU١;@:8N$i |ƿ$W@=:0 ͡`/w"sd(ȁda zkN6C␇lp@NHdoNF4pP o:iuN |bAf6*'d? 밁ekpXLH0H s? \]6 rrdJ(Nhdra&$'l"1Bu2ڲ8* w2yɰÿja[CXaZD6"4jb9Lq!"`CC`^b6 C!П ic;Beb P165FԂǼP:Fk @ 8g! y1y Eh?@?2#JF+Rc2X|u2~`Dy7;/3 ,_m0R~De68/3l,N(b]7{(rfACiFiங%ی)G 8\G49Wzss;8(L33=C80d Q&h4wʲXnseڀfU6X4KVN ZrX>jPёyP ( ivn3s͠O#0 5ۖ娑H/5$T3R5Ӎ/Z /.V. k% 60P0k\  $W]z|Z3kX* +e.7\@/2k` 6O "J^x͐euc.NXC\ ( X V*pl6Nd#*hղ6S0he pGmJ A NYqQ@؆Y 7 o3 7DAl07 =}n.Ivaw7X)tϛY @~oO *ԁlP}6g<_B!8ɓ~␀ f)y/F`C 8gR:p_{*rǪC"(U]'9o'gP|K92ۭ͹s% ,%@< :i͉2  =#@s8C9#`Gt(FgxPF:opX:xD#c[~$ׄKcLJ !"hZjw)ksLbwiu!!7mC R-u#<,+B67'(}djUh?aNg@>g @|LB 0sP ¶$hcH'Id'"3Q } Aܽ^خmR} 팑'nyIJ\ Ts*#D d40cĊ*Y _~ هNWc5˞Aq9&ʥG&u OHqCWVr@9գpkXJ61;Z%?1!g..}@)> |PGo{=Hz*gȃ=Е,O`c$aoX`f`S|+Q;Ήh5I^uf@vPS nG,B@E'$3aL& w`V R!o:uu ٳ},;j{9n,rA0.(I`aʁj4~8a& FĶlzq+@N֡46Ў{Uץ9 p&6:m@qYh&al 14noB,(x^UvuC M2 eho[1Mxh@:30a#Sp, ľ Afʀ_sc F֠d1kd0ꭤ$:|sӽDcR|gL] @5Zq\NCW@ ueC5$/pќ дܑЪP(zoKeaO~ #E#':,Qri (0T2R KzJfnPd3PdsD\Cґ.@P# ̥## КYlm\Ə FVw+"nRD $>>ݕcHS|F-gB *97:]Q>6B],T{q # y,|X> #l\O%ePIAW 䀮~w;%#1ۀ_lҒ\Ka. hXZmN#;hkN5B1@-Gmh^|@L{-%Xx-e=(?LT{`N,pvtToC6?ж?1Cr[CFՙO-PxFN sB+/z>χ+c+[ʴZ#aJxgP@wŁңY.r4`*D4`'PEGL_yݕ Yxgdox|&9e -o03~.ߤd*`W~yu jArC;Z7~pYuRڟY-;&LOO=kL"|}U d7|Ďu~~6; U?ϗ&z:gy4ԗd% ┢C#TѩbR҃oX&-M^!G*Ћ'~l= jRo9V M-ѣ ۳t$yºS7*|CÓ>;M=B>@3_*}ݿ4\$ւ~i@+b:ܐz}PT R?aU݅X*Y҉23~EM}-D ;mPHow S>l{'2X 1q C>a%o~@0Gu=}1A^Շ Ǫ}OmA 2?}Q*PE1Es:2^ri|td!E! 1Y[^[~Ü%Cd_׫L*~ݘL=( Yy~T$b1jN:?*‹U8pƅL,uLa_/T19?l`D˿3tE2|~)=~mNg8˧B䣔bj](:Ri[ݑ(IzcUFC (U`A5=' JO7+wB-$Ay{I}0a8R^K+*7hlds*(b9/"~u3e_&?3nmPMx/f鞼>yG|>r||ʦ:s>o+J,@㻨3 &>ѩ,!(~~>+mf1K~08>>e0/_l  XcAωzh-$c skțXb=j3R1&Ȃ8 F&çܫW0b, @·*4I>tyFY>]Iաhi/*M"@Z\L,(V294+!P:BnX_{Zҥ'd c=涉޻WIu-y "'ч]=sZ)%Eg L$݃Djk֭Qr_DVj{d>ōmN> ZL2H8{T_pGCa|j_&2ʯ Zگi_1S(%KG/ՃL̾<{w%n{R+Pt;s/8A9+ ߻^Qv1zѱF9gʞ}^RMe[/exOVA֗Y_(nK MM{bX%+:Շ=z\gQ[*h8/7zà۷~%(N:7<{&hG%5K?#\l<+?c1鯜$ށ#TzHR,u:^{ˑxs8n'h5XM^2j>UVJX٠@tPmq=F=K`G"u|>XaHMRZ>3罇#BR42ݜ|H=T}rW35*yÎPN\EoqvHfҕ7ͼ_g.BL4|5'd#zytOzMy'Oطɶ'vڣ{x[|z^R#7uQO(M^WgakpÚC"\P\Fk~<|X!23 ?O0VaPJ Hfc`αwSL]*6!zLa-娿h11ܰ4(at.ޯ-g +/d"xyu/N]wU^IZ'bvZP19!(xų& BmRU>u ZĖp6!hԿq(&]Uݿ{p';|2;*xB-Pr뻿>j fQV{:q)%ϲ~/t*d dp:/{}ۻUU;/6k::%]/:>Q.K, զ븎h.peNq# j->kat^)|bw Pp禳} /̳_[pcζzfy+1KWmaDrQӉB:0ok6$r}6N Wnv7U/l"d9n4P*VX{Zç9mWD,&~իnR lo=|vu%i;f!]{ .(/~(4b2ڃN LA-!}@vHտvi' v}v*V0C ٻcK.2fzgHI6`?%*pڭl )uK n#XC^*fBLI!T96\?z.:` \ !{Sʢe`op%kuf5DA9GR: d2]g`[?ֺd’=xz)js[@>N\Wxrn]'[I`'[O.uBB{/S%p,(xIA8SR1,7vDՙXXˎ.Qj@QLX6m<2zT Iآ{'ПpACV.fzXt[&/{~]|k kr; حOon~F|< y}s 킳ϑ$@'k\V dcR^`Ec[X:nQ}Lt~b3֭u?T MO5+yu(q6rZ؜YkN ۱lB9(iF5A |ft9WZn [*Y[(>:H0tI2&J =K^>V`n(6lsQYI\^;l9eˑj'Џ 16&˕7(&d嫁)DPV:D9*{c*ev:)J%UTr$d3!YBU%#Qo(o.t}r)AX@ft[El*@odUqlLysZ'L<-t$ .JNfy8+@j+UUGTk7"E~ꀇU[9`+_nltÖer}D IA05@^}*~9׿),IM!F[ :n͍˲ou l5jFOv8ݮUqC}nSX ޝSAy(iM:f- ծ޽f^nx9sQ岙O[LY&GB2Fiip1KJE~ˆtԭ]Øj G|D[q*o.ix' /"J]ydU`{,ѥ뒢mfStk…&~E6>?7{2ZP5 78$ި/mU~ޥ1Y9xi'U=oyG:AL"CYyۨbaHWx6N=zdX+ez¸ @Ȍ P`9ehZFGfԆ KQ&6r"]-vk~ T-rlv\>mEE>Xzs|RUZ]^;p" u\2 ]K{$DF:ϭ1LrM#L%lܱ`ʾu=L9cXŽŦErZa2e:ce}5B!ˠcn"m1w>bn s~Y=*]{p7N1*-ܩH1^s,3O " endstream endobj 19 0 obj <>stream z%es_X—lnIêO57ٖYgsQGܹ2/:XeSp l@WRc+5w1AY[!M;$X3Nz?P3й&߱hseҷ~zALVLrtnNθѹiZ!xh>:7έʭ竑 X܀)Mۚ}T2>w-sn]]w"Dh?!%&u9I:+SsK4)~%so5ՒQܺoH*so,ܐ#^'PnEɜt>#Jœӆ"9wb97HC>̹=MjnIriv^m>*b *[3jnI<'IGہ8DtQ}>*{8ܒ.k[6>7a_׫#ro:7A5;E˶IIS*XA%]&, 9}tw=Ȑ1wƯv4DYd{Q< w2ؒ%avVs8$T@i E"v2ׅE,GD*@oh16յkGD\@t{mǀ1}xM#0!"SkbFNd̒Ǎ:-+hE^GG->DY=݂&<6mX$9:tu>C*6m<󘩩>b˖_w;&M\7&6wO#HhSKpXm[m sNe _Ƨs'(>Bj{v) J٭>0[Ϗ/}hc9ˮ>jyUv WQb,@W1=*;Hv5w$ t}𛰂$" VcPk . qn[Pn,Dd샒;q m@d+ZڨJbLȞbD6taA$JG"2} UAjjuu6+iܖKs;o 9xGy%s+ {Zu}vAunD?}*h5KhkgFCx ^׸e\ײ^R"*Ip?77V(V#w j;wCvmR/7ĆNת>\Suyf\irGR>!vHݹz+&>"`S,l@y@VB[&{Cu2Y{8ueLW!Æ~xmJq`tW^r2fyXԖPgsX{a]&#pނb O?Xs'ݨ== U=_Ne!RIMrCtD /Wt .;t*Ԧ-o\I[ӵd,dp"My{7Gx!Sn v< !B]/OfK4ezђA@4{0%KWMG&_ƭ[+vI?)!)]ExzN P: ԓDKkiqŹl"TBC(2F-J􎐞L,-k] p {O;oTw"?h|~袬I58MuG~_DFAͩL9hC3 ]fKrR^щn3VQAwk[N26:ʔ#C;V [H|)BZ&wjX恥+BDý[!q0-73M tK)bteőFPMpL\Mp-Ã` z$Ϛ)&ˤM:6$|Xz|{ h7];Hqgv3* <74&d,>EX5Ѩ#9$@4@﬑F3`2h7,R:#ɦiϔYd(f69wsb7BpqyE2L hH1;Oe Z&Pd %8W`B"SqN">3dtgBp6t; o.R /-U@7wd?M(\[ٝ]XKyS \TA*.utEqyHfs^0 FN5SS\ ˾)p477\_f@L\?sV4>~9P)j~fxʠAySUz?3PD:3jJgnDm =9jcUCUu f['ʹV9>= t/)`uJ1sLĜ@Q3FRW1s9@y3#" kf+GVgFQɮ34yE|D3'P ȭ3o O(E3 Z$0r hg3  0әgXfz"Bj{="éH3hXi&zIiME$M;wX,c3 %9 h+۴CtA"6JC7 tz 9|H9Ka̤/y2Ld~bNfP@*\0{\0[ 3g\/+_oH闝7{HF@|Y>d(I')XgJX>DhTk&nӭ58X]ddIZh1tdl.,G;!| Nb[h|jsvツa;Чghb ]w sgB4uD>Ut; $E+JJ 8ih?1Q`F.7%Ӊxt`G[;f@*>!4`<[&iz+n2b.%-y'-Cg)5SR<Jh;Tz߬tmΉXzZ.%޻a*den f*2`> MsSu/i b"A'6l))LRO%\:d+!6~54* g!? ܿV'k1IGE8tT(c .SޟZ:\'(pTTّ䎇 "EUd^|Yn>~yT뚪-ZUd1jw1X02{ iUJ`Ooí.ٴ$*&!ɐB*-=vWsX)n$YprU4-E"n(R/x-Κr6׃2"%zqH*Idkn 3x>u[g)ZpqlnfKuINF HWh35S ^oBd׹:odu Խ2gnWM }#`&0e[-+`GCvݸe[LX +;vrX= _(/y>,\VC KFt>7iaȆK#pbH"xR5Һ)˲ʅNONf}u^aͧP fǷ3KvdUoYۗ$o@2>k㖝}4ϭnc{;F0o{ "< aͣbqr>@gAR\X22TЍ;.~x]MkH2J:ڶB,_t`5 Jn/F3ħ.ƌO]R9^]*q(WFNv;FĖvL ݃r6wb:GޕG>ou&%}yo/+^ ޟ#0SiPJ]/[rfלcF{.w>,;Hx%nC"sm}e ~]HE_$y]]vOы+iW9,c_JSDj$9`MwN*(#OxBKsL?4LtM]KFo j8-w2`,:xíĘ Mηд#%yKkF/䬬a.B$:WW߽hE/X6|D=W0_ɌpO!Kě ^iؿ5 Nϸr\E,ɽrߌ09Mv3:$!m^l&y2MԳ_\.@wFE_O1Lo`ߓTJ:QwBۙCrY'歿ZlR6wJ> (jS 3 _\,d{g+wZ0L:U~A3:- Jl@0b\Tly:ɡwV{>_\&u旄aBv~dDҪ] }ů&r߫}Qv;;F=ōܷgإs_I3ܗe1~`g| hm16U'y-lo]oo iExOvM#_1 n2#$$|1/4*̽#S4J\#\|ZjpL{e}>'AZ`JI}ԗi&7=e)7Ei~>(Ά_ #"UFÏ3ʄ4]__Cܓ1Լ#3s_ёEEKrGUE*rpEK;Ffˢ-]64G5 Sݨ.P@}QAz}Էt<@}0}ѓS"/2ҲoAеպ+oRTO`P δgvܰI Xb&d_\iP FUEwWsҾI(JMd}1m4B6Pu7 2ݙ a`?PA0@.$oR`s[i_$v}Z'!UkS(@Y$sB"~wE͇ ګh-)ɑM<FNE1Ϳ9/QJ}":*aFi 1}ҥ]|jX_ޥ__vϕ(~qYöǰgt;\[[ƅa4dJ>?ߓ5?"͈'oUg}Ŭ! t#lPVSDU3yo0y S<%@ô/4uwS O' s&לq%ha #wKGإa ၵϨz$^k"(z:bV`=?nM ;@1qI!X}PEb$r܊Y>$aMK:n8|Xt/~M"&c[3iCEF:ōucJ' 28frf fa1ݙtqdyy BqJ,ౄCAiup7DFn7mdpj ӣ8Ipʶv䗍O }쀗\5NxbA[gR@~6䅭 g'pz=xϒvڅ%b.U!7w?8PK=|XAЅJp aB*43o4*y&8Z*Y![乎=>bJ.Y%6%۪Kj%O -@"Y-2%TJ'K>K- .Yt %_TfJ)Qߒdx1vKϏr` MN5id2ɶJ'%C/K6CxЏq"Uy d-!sɾ+ 5 ZjXۻqWC&^I%`, 0PK:yٶXdo 6afrqHr]XN'2muH9`Lyg}hURTyh.!W_31Wcy}3$Zߵ<I']v2߽q<Ba:_3}?Yu[+23ӝYRP"74jRR:I\ lY $-!:7i&L2v^;zYTpY(۝bqŏ)Y!b@yíOr41Z,kThQfP3wSN4+pW4a+Z&Qit1b8|+q [C^beJ!š-]Xf<i PTuԤ*Ҿ”]zN-mPM?&˫+\lbEȤ݄ 굩R8,!5:E/zv0A,/r,N{0CqEL-&dARԹK`VgNxgԢV)!uo̐n*\!C4ݾt哢b=Y?iBAa~򀥬ZU0۷FH=ӧ+y!ܽ0DnKwRo-O*RQ$ ^Է`s#rRw^I 鿗;_jK#fR?&(@ǥN2Hg5lRq^TʏOhcROd}ϒtx@ZO%@.-u@;eb(V]퉵w *IQRcH!yȤ^tD4I-݀I9 @Z02H*I0 NdM Oj]5j=߆cªS򨑶/G ^멬2:1,<HjǠWzCTːΣ!6^3~G o[Ԫ%E}cQ=EkS(jFQۍ^ 5[F".Qrt8=P^w[?ϪS[osFF7'X v4wkBv+/P@mB[+ O3+ Pp,!vzϚU@_p$PcgCx*P.#&M jר7:a[IVNSso<咀:N %Aq kURXt/J+74&>iY#NLS@*Ա1z܉Q*V$uސ mZZj=ޚ3p$`?%" vc[6u򷡪O yH{mTt;Uv j n[<ȗ@'][GA X O-FֳSB"(lٸ`h4h.[k UZZ Ecw+Fym~d6k, {BY[4{lZ (Z`ҰMf3^g?LV0tGjRQfDFΕ xf>^!xNmm:$$7I1YTAuќښr_?us];g!;~X=ꜣ~vwtɓE4?u<woRyfjm:m@25$PVxݭSsαE֣gsV,H5d,HYzW\s8i%5ŵ]7xO[u Zg@$;z\\W/W*ݺHB3K$^q R*'G[nj| 7[/h D__d[ ['zNICcwhzy]%5חvl)[C h5ݾay@ška RQy^ys/pR-3d6ۣ^y؎pd+Ʈ{krL014,~\ ߠ[6OOf' /@m_g˞>= sjsqI%ٵ{`#XE^(Mfi{o99m.D a=tu;x?h;!aq/ b}}W=GR.7TGL6߇^ `|r1TKpaa~[0w8߽ B9R3EyIOx;o!Q?5wu>wxhZv a%u[ %f&8 gX!<\R|k]xVM%;\ȿ<~y: R}iD{~a` B#Z?qՉ0-q& 9ҎXǍJq OLO`X7ߟJErlbXwwͅ<ˑ9+v.ЃaM7(Ls3H ~/4̇"+(sqg_+6Ycv5mOӃ^9t>r9i@t@{,弑7:cN)+DճeD!zr8-L^a깎'Y뀽Tzvi( )/&#]LsC>8 T2 Aj58+wCMMe'sLmp$_ ȅ6A܁IA~iAW]\/>Z>\9`F{5NyO !Vrσ5+* v, b@X qעyӉre8]D@sTH&l/>RXįǸlp bvV_?k8Y+3!z@1AbзPUGx*jɔ5g` j~|ۘ0< ht_6Pb?z (\Y=ȓ[`n`*) 0Xg-o1;̀ټkD:?=iMMrQ sRdSf>otUAtR ŕ QmOyO6( ǣQ26R}gޛW,a&}&:^% {="p*'=@N{H֠II}UkOr-ЗjgW[w;z?;?h\&ޭ~pBHũ?^7ަ؍1J JN&MDW[>>2}+sVD_ͨ:"@wgxH58^)|t? ɞm3y5RX&e8 ,', $4e i%tȝ[LOrn1Ue3n{i= ip)~hr>B8nGL\ |6$ p7_bX&a,bZc7NF@WΤc!eqibX D}UR iV&3eչUe.">q}ު:lB) @(y{4}ׇ5%/~9wZBV/d5< :3ڃ ONeþLԊGG&N?PzNgjluFH@~91tf3c_G`2vnZ9{k_ +Nsuc8zn taۚ7~9\ öLEI y ꙿ9lكk|!MTi@ZxK|ӧVf/NH~"=No9g3ymwVoU"|ηt> ݷs4{mq5݃gcSJ3|СYb-8؏"ߟ0$tZ)sxK] FP"5:Lggifû 緜zYӆmyK@EzMu.#utQf}5|'0h_Ḭz;:gB9/gF'yv^ Nb?އz?.$<*BYȦc_AzS;hAYKICI+D(~׃&>ɿڽk$MO\A{mL[m(Wt>=aZ̵o'ήt2wi3NW ei+u~fqs?| R4(}gpt|c g7hO#{xz^z܃us \}#o !炍aۺ6G,׃0g&X豏+;h:ÿ)4C!J=xQ*e7q?k=2Yԫz84i: w3qqu=&9uRT qs4MbX!ܴS4 ŎĢG@bF&JǘzjZ@v}~tZ=2k*h;ẻ 5B#Ƴpn`jТ*O8*GPA}~ţspd$tf3Oޟ[gh¸ gp \I,w~b}0ݳxbsg y;{ޚ,ӗ(VЭ*j‹)Y]EF=jY;X`]zN >ô;:;Ik0!i =w>b kl㺑gwB{%P_7P!l;Iױ~L K@@%oD}AJʆ%}@5|8}>R&0=L`)4\L,}$}(m qA|7)Y n-H)vdT;'>+fcQY/yoolsW6|?ЏHT 2{i3F_HŽN)>'t굛BxSLXG#HXozY<4gd4{l]mv*P毭;{y6h/xX;!Yk!pN_F##_O$Q"';jW Ǿ߳xu(h4NG~OiĻ( m»I>p-wU D6 "N"ݏC5ݵN] Im2q9Yv#y¼4zlPQ =j.ss6i}focjny96l+D4GND)8I_ opo X,3$i'=^opF0,q~Fz{}Mu]"h'HؗD?{{ EG9 IZDc0$tnB =R$j}.Y̳FvGP"G&5}p9EAz74xn?zO7s'waN ""I߻21>xXž >Tif웭b0teZIA-X#d- L6|z!7*lHv?8g*[ SN PLg4yxE5~o#_s@$t>Ph49hME$]4I06gJ/%b'(>!ߍC(ijC>{'|ssx4mN]} aʶ5p3&g -B|F0@:xt͟[]y&Opbgx:A ;T9lP}q?jO=\MD)(TgIAv$ߝӥ2ukL^[|~ӕy{ǰ%?|M#Xw Eq0$tٵ( 0!=zgܱ2wiϣ^C_Ḥyܩm,4 a%T%[/-#rQ$㭛T䓆 q42y5_#qoᜧk0udۘ<3l;M`689F2b~+gmgdEڦVإmc83:ƮL:sQ#AϠdWb2yhb7 H^]me웽}aYlܭ#edL{)^ضb?z|G.4st5<& 9ߺn3mẎIB豯|#:kfsaȴ1xi[;r'yv"Kcvj'T9޺oi:kW#08KPR)8=M4j0m!I@qsq]!ʿww6o?9_*!h3 E|l6o(*$NȱuΓ׃qse Q-4 qs}OmqMb'yvR3!9Kx# Tmܸ^CD> H@ӝ=zA~#uo?xv\n\-m~Y,7;& @|F6cK,Fg>A~%`M9XmNc 5E8 J>ϣG$u)>BOGeE"ݗ;aȶ0sfbb˚}/kCgQ yK/4eֶ0teZ::?z'yz=3|lb]?*L,z!zG 8o#kN]ILFح3}m`D"vbC;;W'k(5z`j ?|RKEIRU VD^T T;[qq~,q Ż/g] EqsP Icxqq^l$d/IJ_ Fzl8~2=V5.k#mEOaq굟P GbjԻnܷl1we3 []NŞTXL)-fvՏNaIgb/;t?(+hXcȤ̐l `4zɿ[{y ~}"JxO?Ӆ:9 g}ûOGü0pdNE?zȒ'q}c^-65oNa^퓸1>|Oy]ݓ0*?z؉,N;vQ EE?J%cg@}^ǰ8y%obMR$=e v$/F]*cd@Ec2إH,z7A}?iH z߻RaAI<w*H^g0yE;SHy do -D DSh{栭 0mFxw#azSCۀ6 gMDvQe6pFPd99{G&C}6R&鵍$ Ǿs7T gt8[*M6o5CgFèݳ]Y~88U5;$4~%OM_2?6o]&R)?sh>5YFMt>|u7 9u4kW4ymun]كnu?7_gzLCg6@Ōξpk-_-4iּN#al9LGm@&p)D~;xAy ȾcXg?;J7Ed:MJ*7o]J`?b=J]48w%o" *ʮg0E_0?@{簮x_u<7ӝ{~^\[oO"߽굥F$ R<~(m(D[ik+q~'C)(3FFQ\M$g@66f#iz=}C ~ꡝD}@r6oMrywF>{6R& o>Voal9ƮL;tg˜ކ<}E;?ӧF|<9a!;D}|NX0t S}żڦFشzoþ`ʶ1rj3̛vF/\4}l=fƲ[ڽCgj: Й2rl5A}Pĕ0t9;~Nx }AODIXCF03|h}+w8rO-$g~ e0uGkj:{r {9ӊݲ [}Ӆ5k gh[þ,ݭuʽn3m]^豗4Y,&9rLCVܝmn+>Pn_̶c gcrLw[:ٻ5:7h.ly1B$*e~L\ӕ>P#߯{=z {\}#8{{^i{(5Kkjl[bnmN. ;VNAf?jFϢ C?dgGP k/}D<3HW!LAǿM4w>}GLwة1slsbI5o}A}RhF;ufpyJ;)sK$h7]o'eh7+ԥ2xft A~Pcw:v\#?N0usN\D;f/;n׍ ƥIx}ˮ} h6|qZ6!ǿ;ȑF$F7$o-dgs& z~NW3}ktLMin^ڙLa+wAto r4t.ֵ3hFkm]o;|q @bظ.<{׋YVem,c`/juî}1lYa$N_ Y>wwwl6_d xC"後fL;AERо4{p^Zr/e[-vl#m ,Fܱ3znsO"0qf2rƕg:ceh=wVcѾ/ivO98utbaԳy woB}dU LߛR}3(m͠Mߛ*m$ٵkM`7 |4l4܃.Ёc^dc_1}eY6&M}a, '~mor2L٘ Zv恋mǸ4kn ソ`o;Løv^ZvFpm;3!\gjڗm//հ/ka ^^0eŰlKAx 2tqCVVVUS<3 UM P5QMTM dU5TSMTMTM_n 2ipánjJ sgPGu,S:rMTWU`aA3kJґut>PY5zU` ˪UUVՃUXm=ں²j`! +4x,VWYUXXYZZZZZZZZZXY[@ TYi]Yi=ze%Ճ PYe=zU+,+*YΚN*,+XWt2h]Y5Ҫ`ՠ *#.e$(tjNA1zcS ȋLT=(V Xqr% ˯_40 s@4a&Ep^:ָ Oh6@,c 1|s 2]F+Y$-dd qnPɕS@ʲ |LozB0M<qm 9p"4[BԒMc^X`*^M?RtAy !:xj)v2dkMJ',ZP/ed9L RKp=B?%:Imc3@!aLPE N [H_% xTMo)G>Í87H<'"r9`mc|7q ~āxL|(oJZWK0BPlR^'Ĥ~NfL--bJ288B`s YĔb'(=NQ*X![Ēs:|$cR4s1g&JL16L-)[^) K6$8jO Bˢ8+*Εc"\q/ +SƁ'r¸=l^bY#Kk$f`MbL6A,QMoXvăl7's5ϵ!UA :.?dp6at҇2U4?L/=d\}8 r0/HĞ(u8l]vjܨ0b.[jT,O],[/ } 1,RX$HU\c BD~qN~ l m$Y+3q!g!MN׽(r-UBv'BF2zS5Jhe/)F׽MV4w\A$Y5N&~/2;H|r< =mr$ 6JYҿNxG#WnRN'CRA`b"!Mm2W vZz+b~O@tH@6<@7<@`n 1qxk[1d* ,ae-I'g$'k8*YO"cU`Aa?`L1PC̱Ւ S@$Sh.cpc)c/eyD_x%K', ,i4mJGzꊦHixޏNܒNܗ3E½\}}er)Nӈ G*fX禢GN#1yX@/K111̛(i6!kR0I /SKB$$,ؘkcүɎI%!D< &]EPB@"y xDV*\^ 8@{v2{Xd24Us`؇N!%dcc_,UhF"b GDšD38f"|lDBk)bE JO !a[9/BPdvq)8Ć%a+ A#(*^"6q4TFKF7eǭ兽u]3h93pY9-H1{Ѥ, DH+͊lK sQƬB(5,RMG#DD3CL3FH1BXX 1$ߒ~MxL91dGRdHnZ>,a-rgP% U5Thd[$lrvh"N)a9HHH&H9/ꁮCJZ(n8IVSBb Nz Z˓:ƕL X @òRa\ظGnH $  [ī\(k(gW*.ZF'~Mݚ̰ظ̸͸PmB`.in2T,1H"fȧeJ$#M*5$N6_be M|DQ8Q!(=.dIV*\}ΘnUr]d\fxDXn1@uk%i [Aas0u9W(ٽ%d_2OT*-וZuS!XePXa 3X[h+ah1 s +iPQP)$po:$ı3\s)g7f9,@U1+$abLόQ%MF+uIzPqP~[1Вc+GHxʍʙ"*va'H2R: x Vm#A"e Hݨĸ(*C\Ka"ǥIiJ;Ȗ{D7LV"[ܚu ^!)0BV7Tv^.tM7.d)ei6 a4 Hps5J\)]I?1qxEnps,) KքsWm 'nNBMD˼A m ۉDchy L(P5^fmyJ *j;]戂&CJY[ubL|L? %{qa-LRhn0Aٸ$يt%sp!\).S^'(׺Q4kdIqA ˴ܠ"OE$\ -j+"bʛ+fF\_$J`"WiQgA,BFAa-a5מ ;%F͎ C;KŭVnH dkM aYF_`nHT=(,#jݔ"4 +kGtL(] Bf vtrV|XGp%X2ٴ2] 8}3 QٓN[HI z~$]ǯSb{ u)#<"3ƃ˽6$'e~Nضe͆{IR[.6Zu 5%t 2ȕ2S"]p3KPiDRH0r[d+[K~J:.cl/Yh4bhJҹUB\.-+3,4ؓT?&eWw\veaA>Z|Ia&?Qz"#(ʲCRaZ/" JT jݛf-l[NSQQ(,Ne QDe]V-ٔj!Fb)bkʐOƖLvnٶQEѤ໖47ˌJonAox! \̕}r@rڻ\$$Ԍ0"A効~' jēB9YJ$-*"|(ۮTe.f~9l iaV~5d~ßm@c64rHH&TS|%\MQ.U`I+KuK XeT3-5+yY(j٭-[V~/) dO"WxX9*"tKA > X/ؽv+LXYXx+)~~~K'u+^0(4ژAk C1o 0c5V!VS@ CVRE~u +%J[RIOXdNhY>()S `(ZXY[p"J7(K0T<$ 8Ր K3«(3G(T=.Q6gr{(+"̚il#}5խ,$=;1ѐ̸{VlT?&*!s]eE/sPRߺdIPܾ _C)k(+joOveFaU9m,ZyJ7Yᳯ%j/,4))BM:Oy9OyЙQ+)Is]\Si 3)rVLځ JjaOBWɐ P((hC9-Q +tقkFd"9kn\I]TNi |]ZJ/,)J>I HlE#WPYO@:Wј? Az7g[f2ҳOdl^dS̀N$z'%'='P H&fp崶ܸ\eZ+&zYt҂>3 L,]Bp٪Rf BgJ=yϪGcmD7(N ^ fU Πd7$Cηȕis6FL& hrLJߞg?6pNSaȴ2}j:7 Zon}/m6|8a$ÞA}P>DiH_Do0t my[I@W;0i?|sЎ"pF2S."֏YQيF&-E±J2؛NU6֐OyH<7;)gx*kxrJgФH*O`3XٱvdW4*{U.e#mzp\X;2g*).&~ރSO'g?{> bZ*{MY1$):V<*ƤRf>@*>Tm*^ Ɵ>ľI~(yy^(@jqFy*?jFS,U H[FR(=*(Ŀ Nb#?zs'쓸l9[.t#0X_MO&cȲX?3WA2vnZ9I/y@Z/mYH]` J"H3쳲aIcZ;.jXQ_ZM }0GЃВ5\1L$B~_i{#e*xKY3X"`HןVjdX66(=^JĢiM49 Z-w6|ѥ`}J >{͟) E9"Y}C< ]AǺJeR5>m$}Gr1j'&>IհܫX~Tz5 eT~~R=JLi FB# uT(CR#= Mzʄ?Kb[3p RxP+o$@ _1>{a|GXX8.k" ?$_-&c챗z,McxG4?z4@#_IfHR_QVID?>/(2}iۡL@J>u?oF>o%1Y'P`$A9K`)G0Ii5訤'- / 3 E@4T*3yk͟![`ѾAMIw6sg'uxQ,i<׶!luvI_p*sز:AQ^VN}%S ĺ)U\+hX/hحlX B0A~N)ģh^KV HJ]CQ%z[h팑3$+{QSNB$N??zFnrrT?59t*D(~Ұ-$gĝ0m\9}N9x~ ٌuZZ$`P%$m%&col4=2gBPE ŴS8"*7v$M/ zSX:*kVN@|*~v 3vl5g-o.!$ؿ0>琁uqYp\#7P8rr*a bI@58ݺ~Gy5&'izm} Tqt5(#޾[aޅ&*4? G@)sq!v RFk& m"L@)_jʾCKh够P$0neޚcyudKqγL060jh;yRwAҩ}0Nwk:zK'}E)GXA~I5LC0)orJIAMREJh=ǽD^ɨ$WPn E>ISLأD Y622*{ ݄ Fی#HstZ I@F,m0rN$[H< [Fl)np2@|)%dZNV<6I_)U\/xIsmI'/ zE j@UޜXpTWA,&:Db:*c*sRBک3Rh0w,'ӂc9ẹ Gc0uL`6i ?}4ML#&HI` 6tffB ?}%Ѧ쫉2 (S?0A4[2u{rnCv rV{#ZKeRT)"KiTj\Yr[}1(lW 8f DhwJ9[bT}*hf?־C[)&"Ko}@5dUfeDJ9i-0f reYf]O$#>ҙ*e-%±kxrJ{=Y/$+4) .Dө;xQIKh 6~l76?6?6{b_3؃,f4,7sǖ su]NmE|ւ |5C_QiwR2jĦa|;%sǶ}*XcH`U VTI۞<-Q( !hRpfQf.X ^Dn[y!_";Er;uteDbb檂:M!QQAcx% 2e368 +ݥn^R K_ڧoc/ntMwm̛Lɻ&cz8`0pVi5,GxV`jPtfTn---5VtHKn;d9%, %,Ƞ0k;F6Sx@2ҩM*S3 i EFzV.0;Re18n6CW8$`OPFIK5nÀ<|*0.;GeAx \Ù=PQ( s$3{!lr4 ʹNJrI0QؙX i[PVe*e@[ΰĔ&>}5+t%ڟG9PŚ*݆OСu?Hg 7|t~/mƮequNc̷x \VޅBW;ӧ&ءigݲ'1L: Φ1 lB!,,5h \p"doKdXT4]؋Yc('c"cPY2,R͵rC۲b{a1HBjv`n.gȾHN P"g,sWU ,'gaˈ슢k2Zuv&YG`9'~iw/~i4k'eOyQOj8}2zjZž}pBZ% Ӱ@. @-. jB$@Ri! GUEuu|?AaEi\8[  0/lQVB pP''l"-HT';໛G|wqk Ye~OanleYOk/8=\`v&?{ۗ4ؽ9 &z7`R c:(&:-A33+(dNBT`\\P4i8`ZRa gNE>.Ym,iUkPbWKFX&BEY\}YPy9 @8i4* nP&6Z{Jfه(])3l'QPd XfOe;wf0h0-1L`6`<@bp{x- u`ean0~qa,}xb jl1/10yllc`]r !JivLd=uu)'H RI{mIgKXܷmȌ;I^!I ք0TVwf(O-uiWp2*@HyXZ7`uYNg8W+v^p5Ś`QD6u[.a wia .tqC_0#~؀,xռ <,8ܬu0a,Ãl "g;Ĥ pTF[ZtJ ӞİV?Z'v! !gqDjXB8F_ڨK7n4B*]PN3hD:X41ygY:{CGF9޻z/m`a^\K gR9x;Cҁhk\#}m}|0fb܅=x c">d!`ć0N!aB,JiXY" \B%4! Y6s2Q(\UD3#f-:VQ6aTJB4J VV!g˘e,l V/6+:8U;6H4֌Ś6WW=d8G'DEhso." ԀFv4Ʉ*3P(,]V*sp0ajbQHʳ+ne[Xp(ν@Z|eu) ᘥ А #,ʪ̝VfM;C-2l4j pb ޖ7ɉ9*uRiFpv +))bEAw%bjf}8&Dvc7w9tr$0aO'XuWAHTʦ "R"F& rBO`P p 4!dV&ĬA1ehk\dCڸJ^&ZRhnP*߹zVݕ )eʨ"P$?4چ-Jh-}ŕ5\ `R-w, c&ip]ɼȅZUQG21ȉ߁yo 'n+˨/.\0DxJ#ރ|;sG= vL 2cPbQ2*P!0~B WRHsf,i~O?YVՁ,V@}Cs p,bxˇ1cܱ_F4 za[|/8i0u@lJ e꜁ܥm.c|AW-J.zURxK*kdCD B, %bOtC'VLJ-2?zfbˆ0;hنp#utzHĵ0h \"(mt/06a %&IԊ)@8_ 8wJ5=< YBU=n {rvjVxTv*1&f>,I :̀Ƥ\%dSۻ; :c)6X2@p(Y/-h)ME0CU\hc&b A>!`Xɇɗq !Aj<P P+O9< q h׾TN%4Tg2.-V-އrN: U7* NJeA6i>λ6xqV\X82 c $!(` nl%k6v 0j삃?EXFo {YX;$ĥ1@ttYpEb x !m,F0G#Ha sCN'fpT"Z=|Gp p@6`P*fgQLBU4(k=!NI *l#}P.E"b ,m?*b@$ye-.YHH ;# q86ɀS EĒE@%P Y?.JhG)LV4gdI#8t\lEXHظx+^ ڡ| h )IHY.l6bl+(ppFG9,|bW \nx^g!TÏ`` cc`<ݐYXx3dt\\0݂ܦ@?/fI1)WJB;񕯰^d0` CC6,ViR!ɽ[G &*l`װ4fR F8̀ \Lw1 EDwC2xLö 눻Ȳ9Iiċz#󰇧&q~(c&_J8 0 y c%00GU+"Vk#͐C,bb9! `TLAr )ođh) 0蚀 $[ `JA!? qòCe KO'w/HӍ05V!F 50r||HBraXp0%5ai,I 148ɈO&N$ÉbxRW ;88DGgC<S sI!CH-|1`1duTʙxsՉ*iK(KjY]0d0u4~!mWn;(8!poħ~x%N&hZPoV5$!q/T 72VEJ?[`abk\@B14;| r Y#ᡋ(dlV8<pT Kcn^'j>hsG 8K=0iJ<@@+! FI<Ȉg!q"#U4-0 LF“Ĺx$;@h:6~2'a*^#WB :$K`*G^5>huóǢ"8@Lk\1k&X0(DZ\./"8zB` xMK= JDxLw Ǒ+ D2D4ug&L"қCH7L"b&0oLF"3!k0nD%ZXkSˉ[=q/'W4q&u[ q=A)';8EɆa8>&!jx/:܁D/TK!L*[wpz:\yA##!%Ut12GQ^6`-)J%إ,0o(*Dq8\6+ !+ #+R6D< yrA|a ' y## ]H4V"`R]E\΁nHeRI ">Ljo )!@G7! r87>p,3x`zy($ ˃f@J5{^lfCsQ&&$.)q :O%ɯ)^#Hx{2F\BPB p"{lj 5\pd4 B$Æ_<8;~pv 1G' 688xq |8Jz{7,_ʉkH*r g@ĥb8G{8:(Ƈ7p.m`xD0pz~y&b5< GR):^MÕ`xы8|pq +ia#AL1!bZ!Ĵ$Bxic'xG^ :|u,QCӰE%4Nj[q )G>ca -T._>>3;bdz{I8$ɧ7h!ϯ&^K4;|HIڄNǥIOWScdLEp[ !.q=ofc0EFJ4}\x% -h`%~~IP!b sH2D7M$B1}pj6 a$$mR 3I\&#HK/VA@0f[j$Hq DHIƇqqx 10,4pm <"p+aW1PKo+KB")0ER3@j.FnN_.縡Yh&XG M^16 sꐡ)q"gd!Vx+ 8fHsX}X  hZʇ1F ؖChv4q!cťwL b<81 wfH,qc3S'gO, xiD  6`LK Wa5p_Epm ᜿År VI825ȍf}ԛr3IxL(p@8/?PXvy09p23N"bJB5*,ZձScS8W-XI;"djiX 8".uvpBu8 1|9c9 s9nq 2c9 8<'ZMc:s:N[\MXTUԨaQQMmaiMY]MQMeQYa]YA:Bšzf5ufv5f6uufueeBV**MUWXMdP:⸰֨ l=J[ӂ0eFj*+kl, j+JJ63gUc3tZۜ)ZTδΪ֦ Le]MA:˚BR{pU%gm3kʻjzЀJ9TdYdTdRM4x?ܩe;:fyf溠ZxH$?V  _h@TQ~ :K?((\#7?`\"FP*h1~F!I?nA,9V42iPbf" R@:i88k*tU Kzc*Gs|d`U/&]Hv(_DI4U/}!η05a!˿$ X0z(Tg{v~^\&fzH~І2], X0,1KIqF/:` Ǿ/Eb7m0ݏq;ٯ05s^PhS|3z GWo=b;+?Ա3> ?Q7o*e:M6~r6qaʡ)g#HHMI@(s %գSn:6孇 lUò mUzikoƼUA @7$J^hG@I`\Yv.:\ٖcaswCbDH2A|݃gl"@{Ϭqgn :#~tz+qqY:< 2$?I>#aI2rkD :=} HϙBedsv)ť.0 gC*~74;V KJfNŤIo!ȬXT;uB(~88k^Jb_ RDj/ zDZNN"v԰' YG2tK7 qox%Y@6*i"3HG8บ3k5@ZG7jĴwR%/ QIe=eBQ7~kbqY;z&oII4R}*ţ"?*%Nqik3X@V8ڝdKRgjETD % CnC>؃,MX`Pq(5numb/gZ1[);w E NDvJ;5I2vi=Vex+id[Z H HFe J)] ]M`.8.h2.&>juŽMZKgO$g3F)8xSxHR[4I< xn 6o=fs9uh3@x_PM`n䠍$ J FS0rme72f&r2 OQZU*`VBv, ƹ`_0p::(LaZH綋,$$"["*D)HfdWㅻ. ZG."=*U0o"XX72i"PE-5ai;jw U0";dD o @<{"AEB<[?.z>q ]Z=SmNح /pjԻi<=|ഇ_i{̡Ѽƒ&tٲTApP$=^?j0o6.ͳ`87AW=(u`3K˾u1 j>{D߆̙8qu]⿚I?qYC&>xK0aXT-tDLBۨRz D ezoq3 jh7?LMH>1Z&n#A% s^,<eg9n= ;b;&l~AHRCs$QKcdE=ZkUv*ln}u T8~$6smȽ_b*9 7A: hS&"VK[AGhk+ez?zF m-Jn]{>u<^iԾmv6pe\PBDo_o|!3%Zs''(pV}1^Z?})3isX$@/eCBKr&a,Nn4o[[Lۖ>m%o3IU|ȧWk(Yqte~ +~y~TBnVIi{ݾ\O>aAGv [0Q! W4& FPOξ ݹOVs;Lsz,גZGΖk9^8 \mt)\8- Ho8t HE4'ZdCj?qY#`erXz)VEhRGw ґIA|PdVL$M1on2aޑݍ}cuY-#ahƦo5x9fq jx?&$MCK-aGsr&/4[]i82ϭ,;ÖA{FSuX72i,(fTqT1A:lI Ž),Y[pJcx%9@)#Je_1{ףV ǗZ4l3T*ʨא6iպMq ~$BkH59tX:K6kxx2zfP%_2.y?:C 6-~{Bl{{)eb<]SH *iA NE\L ]ٖRV9*u?*E{;W&G(3A(N:/zCc*bwΎ33|g>w7Xz ׷2yjۘ=4MMBkj=;1IX?#)3@yy ZtC,Mbюn)+cg.ܫbSF$89V R&}R緃vD hLȶʸh@[kq_h*'HXK`؀VU=(g P@g)t |h݅Ĵ:byHzc 2vf5|=:`; ƢlCP 1zdOdgAIOE2zf<ַ:vAEۃPnO{cζع)|,]A'ÏD :~_G,aʶ2|hF9*"- GT*gj٩4<ӧFü;_<{ h<|\\GeUT% A$AcDR 0H [_LIUl|cY݀}9I]B+:I!ɧգtzNgQQJ\L›^ %4=Qu96Ϟif%QpX Mt/H2оAYw82j[HZq ƺӨףP T,oMk;|ٝD:jbtg䗶mNnI{&"OAAə̉ [ n=R+b}P'{(rVU'P4EdJAٱ|T[A:.#FJ&vD*BJWm>LWCD E>{WZRѻ+(}@b7 XO)(1Z"J'm~`[]#, D fcW2N!&!I|Uò3{Уo DDKF7(“ޠHn}:X'zk,4)5'SzoM KJ'4byhrYXvV {vQm+(eDF0bp8BTR\ӅmaʶXw̆pN> Sx%H]qX;{&(aXk*KX*+y]uCd %hmX,nHMCCQ:Qn-hU3.#VBWHCUmQ&!}@uMZt9))jq%F OHx2)1:Xs,tSӮUz{!9ZAg:8*t! NJV;: X@F8L@``dWX8D>E.g QJtp]3uYT @  `S@0 \֍Fɜc1 ӞCͻs*QfϚBM{!c̈́aD 5ƻٺ] {su/9k3×9[&?* o0i"\23dF9?{Y973%~sI {f'x >#NMtBĊn/K%B\>"s__տ)'l_gY)p/MrNb5F}Jf]M'i[_ͺ].Y*%QAR$sq$Ye5qB?wa{wW?q}V3PcǮ:dɷ2Dɏ;a>勘K*O.GkG_'cmpOW% ͵ UwSyH/?\^iiV/9rߑ/~ɹD/$DΒТNo؝LB>νϪ:QW95u>MlezTFy;0MarO AbpM<*Yw]G|3K V:CF>¸v?'Os! /<~?}1qcYg18 ?é|̂ɎL^^> Cqu--e+47?'8>l YYrVY0 1?)?|ōw8~%!s[i;p5Y#?>uۖu{^|.16gٖۅZ ÁQvmϋSp:_8w&p\w℟5q>V{5m/Bq3#mKa֤I8߉3Cjq{B4cN `ruT%,n<ԝ`gϹV?1x;+~81o㰟FXB2 0%Pι,_6 [wU y lI u@a<>ۃ6ÉL=jO[zKl9Eq?a?aaVR {,6 ##YE(wq v-qڢiخ;_]/t]Ǐ?B$sR{؟?;g^x/;w =I=֭/bܾ!l:1CiO=c֧WG4*Jv}9 j\O7Ȭ$m¬;]{"^ rLhト<[m{~o=̎_'k&}!?{jcT25?|szU8oQLRBp g^MbS+0^`Eykw;j>o_Aߤ8 z]=č 1KiBm7e4էbrI6n/lN"ykE(kT^4Э*ߡ_*;yst}<6.]^e}ôepEpL9ASlz!a:Vl_=vg^l=Ύ-†х$r 0֥l4ߜ"2O7wn,o᧒x&>qUS+c >;,mF;XX}OGY?Qwsr\^-WOޯf KxPJ][*Ʈ͆NCݺm;엏%&;X/Ә<$^h8PWhQLb@ggha[عAy54km17OEL}|>=22H8*O+myEv^ƳFjP]n˗,"_U|=hη z,Fƚ$SW;T鯛|a$뼋Cb\[ʼn;xu䐹~IRK9y jI$޻&ܤJ[noџ?~v@GfNtBaR<rťA@455/iIubjɎI $1_G t]@/A^/\,Vۻr0*v9E`{ w{ko{FBka1.,Q'm$J+Gq^3>k7?};κz5N{A _T9DU0: > T!5o{oU#݉nLGPfb*, 1#$&\MwT3,= Z35Q7c&[tv즸7  '_u3ZSQrt. LtxMhaNJH6Ȃ*rCxl5dOT1$s6l| ]Rx҇I?Xtf$eM1y. I[_uzEb  CYΆ]sZKApkGb~/u6fuRF \#97}Ye[ݭcFKWXRÈ__o%ͦ$ MlMIh;Gcyr ]z.sDlDGN{d߳R⋛ief+{~3w%hNSq 2~k U<KB-ɣ9p EcΦ07Guϐ:MՌ̹aRkaye4C%j,CDa (ڭx?'ri#&┏=o6F] aQa4 )0?J&P8p)RRI){ā4}鴓><}sg2R5Ӕ2,.`m ?0z+}& " *3GH]35%{URׇ͘(CS21=BU:'x9icA1 5E+3$:EP͈B8b%0m\U+ldě*F`'Eg^{J&Sں@BJM+!>;؊m@T`z9 z{ƛT\\孱%-gzC>P'M2Bo2ks>{n,Z>Erk]wvݵwV;bs9kk+{9[փqV\-g  [E"^ d5l5aiȊ͊L8wO:Ozt\7[7.Fdk{/x*j>LM5 #"VKX,,ybUg޶XX@e<pn9cDa5YZ l^cdڢbV4=DwZ?wM:isNƆ]*SHdP@( FœMs%{@P$cP @ @ P (X .pQnpym#ugXŶR+KDmӋh+rBh(r1AcC3v䑶A(x$8d[Sj-7D XB|FphGv_['ryP2yoϣȖ[ xIT+JGۿp{Nl=qҰR˖oбsypn"^8ެiQ#U&]>6gOY(I& s'Β|nbQB^s >+] |V P/Sw*\+%v<҈&SC7fԦQɨIGaH姖ϩ LCSIB2&޽ EGM#$ù}3-sm貛p֪11I`529;P vʹy1<:!l>7 <-1*G)PY2 Q 9vGD)E{3kQ9%x^Coe-yhC_d>ȧy 4&4gBɹ(8aIx#oGfǁM/ʺnM;4)ס& ]vG\|+&!b#Uٖ(qatw݈f t,JltVEy-u|A/c蘿#,=n[#EqP.y2[kW޹Fܶ!%u1lt%5 :,;ՁMQd",u⠞ك!DɈ+c=J>&1ǖ!ч[yEa:dOY;M4v܃ߕ+s. koM (u6Gр(I$HOA36I_uort cexuhbZ ^+C_"w[@u z7Hyeհ憶Ӑ:?3c,41@bfqh:``9~I)3`D+M"ti83ˣrZ =|2//[YsЩE}O^ɩC]U>P>=*Ձ+Q}vJ^1ӟŔe,],wWBϏ>$*MsdF<93ȤF@fW_n. Cޢd_a6\$"5:V0 c#DzӲͲ^#'%8@/p6$ԆVv BKqKQ0QB8X:_YLW{[ E\{ 搩IemC![QWHL"NE<`n+rԧ ]"1:oo64٥cCl,ǏIbx=+%t|Ѿ=GcCX֟x#9k"-!H8ko[Gy9? AYb\KEnːK~r^/! A@fJ^&s2+Sܚڄᘦ4a&46v+ϰ5ns=euS2:cu$k"ֹyB81坕C5bA^,&( csQ̖jLԵGk|hEr Jłx9+VAZ2/ pS\ 72EU7^ @ IJvvډ^?y, Zn^6Daaիœ)Ag}_,Еn@kS3P?1Cy*!* S%~,֮gkK@'Ű3,=d؏욉[ f]9IspA5s&Vdvc=3Po3M^/Tm3r}b,kͭd2 BEBh3ay1M&f7[ȨLl:QMqi_B׸S` O*i4,<4~M4O&/ZubZkuopeRcDI} PzPv 3!&/e2Jst[tI( 6QtC#LX-v([nmL%04AKj6E$K,}!~F/w9םyim-|_؎0cjma?D/._\k bHw(=b]NL4QabDc^b>`#6PP#V]SzwY<>h }8iG|2r 5qK|+Np)bv{Pņ.^|LsެLdNUrShWQ܀Գ.;$NL@Pn7EhFtg LJ(T ގ*Nqc+\:yq`Qy\mMl&.x~b Iqˑ+NQ #qk8}۹ HBFdAC98uSaSXFl"{ k.Fy8FFI JjSEI1ؔK` CnTpo?SLt=# 7]xM߸uas:Qu;CC40WJvyA\1|F#ŧr8bՎ8[!54)f`mTS"ܕro ޱ~!CSՒ EX%hrZNMLW$FsHsZ$QKq]0K[WvIp? k/S6?&yK` H :P:URPšW!Q(z "p*7BVEGc.=Y4ycԌH y/Vq3r sc`s16Kqx[GچMY]IYZ2BnDv48qNĉ3JA+"Q y$oȶ\SH6/#^rBNK|7|j= ubomҐ5 0EP&Fr=r /;phξFn8K X&|F8/D-F' ^l5B|31  - H D>{-u2nA+&"D~5M'Z1-s+xZ/ZPao.E!K@԰ПlhPs,S :ԮU*Z;UN:zMRl^siibi3$@~ӨamNN2r 2h#lD0NAР0YE~?ƴNlMEqV1f 6bJ)Re[녫c & L ߋ卡5y..8 F/pϏ|~xfPG Gq3SaLmm A$),cITv`NBW+CAL P C,c/KϥT! |dDF0'yw}oΝf]+f.豸\cPܔ'`(P2Y`\kcIBi:$XXIV0Sa5X11dddw^' %$~Z,ui2$H\36Fv$Qce杙̛y﬒lRkYg3ϗd$XJ_U+~JaZfT%X#Cnq;*ۿCY[v-gqT?l3T!ȚWX1g~:wfZS㺌g{i~f&k;޿3ϯ֎lDZB|כs^^[[ݼfךirrg[mfk $;y~iqlKOyy76VssgjҞm}/}Õws3gkj^דml7&8ZKjygSKk~lq꿝n[s:{͟(;BgK}ݙeLint?֚um3O/77w[L|.su'Ts߻5o.s=q):͝ڟϱP;Ϫ'}-7Wvfſ+ܴw\縭ߌ39Ky~^^eVӛm~>{g拷fޕӜVKu]=Se݆kjg]]uv:l;&w֭i~.2j7s13|7XSo':g9iO}6{Mk[Zs^W^kuW-7gWl实Lu3Mo_rي=ܳnoe?'vr6^󟛹it/۝TYWyϺVg۷u-O^fn@2ܓD.Le_r\͟nnjk7Z;{/}{{^V*72l^ݦݦ3mi:fڲδe]gLƴlyL˴Ss)1?\v\]UNr;Y}8ܮs);}͵wv;/]M6ݦt٦w޺{oi߼6ZZeuT߬ۖrγ.ɳ(#+IDW!"+6_DmDG Ae Vfeꝥbe7~C"DV^lz݄ʏ%y@@72F%nJF2e>)U_Q4K+1 @T}<[)U_;ϣ(<1qr}w (*d y@ \`$s¯,=je҃č#J}WFK|.P%" dI'eZK0@u PbGr@W )=GLS ?7g=3y*FFX~vNovn 9f\K$,cb %I.6m"ʃ*EI"Bot'SY(+F.$>G0T.}.8nJWS}(5z3?WldB3X(# 1m )F"!(&Ru/,mRaLԠ@"-Jt*S!x*?@K2`"C2ts^YP40md>GJ/Kbںi3mĴLi며c1$iD;|<׿nm{v{nb/=]ۍwϜZͷֹ^|4z'!E3-2h>^[׼s}:3qkX;kޚ׍mq;g\1c߷lo9[k_Kk6[|K_Fkr̵9X~3\{k~sy5[gW\͵~]f~$Xkn9߬5Uc9s/YWs~XIƼ#͋:Xj~1׻v}sX+/{^ݷsŗm|;:c1}gw՗Wurkz:|޽3~w_9v뾷[Vc^3}^ub|o+缫bq/y[syb>֋W3f|3hfw+[;ʹ\g/_><_]ro֜_m}\}{۷֧+\ojv]u޵E3Ϻ߷5_c|L5̵ƺu8wq7e$/w?cZת{s[g}sh&mslkֺ̯w]sVv~λնʱ~15{9|ڭV[|fŏ7{_6c߬/֕q6z[v9}m{+z:ʫޏsZ{̳^4sǝUjiX[k|㷶oqZ[ߋfr{}7ΜV\_g|~/y_Fo+߷zչ9;)(x)/~A`}0* Ad@Xe 䃵-`i=FO=~Lǥ%=Ue%,X1CwGTfQ43/qhV d-sB}PBqDXCs7~>-D##2"x7~`ѽj (IS!F0pD}Pg^;3 c ,]8*~sRWP8;w4f 7VnR 9~%#g0 :#?05?4/~_i2^<$] o#4_w.W!LT@edRCZf-t;$J-۪ Vȝ$ͅ\Ҧjʮ(!!K C(CC5 O[9քB>cBc9 LeRTtLDP0o"& mZW--R,} 2Lr111E2P!M0lfYx-l#,$`ޅׂ`.(G(/[Jɑ !ґ 4" F"/ȑ `ӄnii|uVrC(1VaVaEpZWD?%b)-y~R%bCo<=mtE{`p,:a ¢NF@!-rHQSـ`JDV\1FwV46( &(OECg⡁)ABT1 *3bd :&+عBO<!Wh ܵHS0X4 j6ZZACC ,8>t$^ VJxre$݅\BD0p Pƈ!5Mh6ݨ:K>C>teԄZFэtX*)Pu ?11QMIj4}0Ѵaa9ǫ8ǫ8ǫ6,$&$$&ȑ xU:pSJ/,:وQ|`L"-JHDDLDL$d(I|_ $U7Hn$TlY}%`H P-n*"1y_eU. -j 0䡀5-#P endstream endobj 20 0 obj <>stream = -KIJLCʖ!OJpOʧD,[X"ʯ&S:߲A:##pxyQ~rOȲlf)TȀ0 Le8BL2&6"*>JBE_*T D nE `*tÈ,dv0& ƊUݲdžŇ3hh(/&䀹-{8HZd`4 KDl$fZlB0J̤P7HBE|:Q`*, d(y SC[<*ERSɖA$0 A$ p`*/IF"Cy͈DcW ",-w=4&,Q퀵%_䡷AA^P`þF[ {dF 2ק5QwI4  ʴRS_ p"ьqd(?9]@#t.816qHC^`Xȉ.ed@.q͈CyZF5X@ ia*@i* !䄁߲>X,@?VFBY%+R2;0Ј-uDIT&4@4l8x1 q|^J1 ?`8HZLRXрDl*mXlb8tXKъ9ri!TF1jB!ASG%^0KQ^R-@Rrа%^IRQj[".Ccx r#6!%-)*Dp/2ՑP<=`t8CĐTlB\AlҰ`/F ҠsP>* n$"Ҟ=" AnYǧfd2$ OݲhTO!0@a2lBŦ<(JB; `9 [&"1*3.$bI#oY$hL%ƻK(GDp'd8 ` [*wY%`n8Tu}2@11&b9 |&އ :6BGP1{p|>3>Jn4) ؂). ۈ2k!c*!@H`$ې`U8[AV(dF[i⣐2!Q]bj)7CSXIJX:c \odpg(U2*:bC&!!E$>D 'c*  5 W>Vu@ !sfg by;UH,KNZ1U.BUM p nޒP*j9*;#c*Y(#T}!؍" z"s }x$PV |GeЃ$VBђtBo$Μ>(#- X G6:\& BrXjb*ԆU 6OC"r]ߤJXbQOP[V*8jt'Q)U:D#ӃHDҨt(TDQhhdH0x(Ʉ$VȬdP.|PD0P FRGqAdQg:S0t/PWjHΉ-ă)?fLL!׷oh;.2냷V2'kyG)^xZ@-!Y`,kRrA!h -^lY>&tIp$)GɠU=nbvMu9cEFXv#Tߋf 'M2Wȼ@eƥ4fZP*}xL?GJ#6M]o9HϐQ2g EiOB]'8ȁyB ^xi]JC= &~Apmy?l2[>9헉565ϡte }~zo+[ރdv)~s#It8xaɌxem>Lg"+L7=!vmjr vlLp+Obtޙn{R,Qܩ%_eĹg(R4#'aug$J_?-(U#RځDN7q9=XNʠ3v]WF{QY.ݒ*yNnPZ0b\_Z. WR R1tf{ıx447D鮋(WhUN9QP bUJW,|n0'~j]>$c*ҍ͸k9, YiӥλR3'įgLohAmoP1vāgv8 q<?U9^E٠e,܋ Q!Ug>Dh3Ѣ akȩfߩn<>=O|䪊%G&D -CH_K-WlPelc{x)G?KюwC{h Crk'Zբq T  On}p9e^j/F2:R*PMR?R%8-ZjT)9%CXytk *BwR<0UZ| 6 q6& CEZ{/1vʠfCD6F!alB,od%@JiZ4ߛn&#Wv!$4qL"VjI42Bnʋe@g~Zret^"jʗpY2u+5d }ҵY+ Hm԰n.Q8kldRs:).dpq;83zMjYzۦ@~#}L۱ gm:0n~U`w·J3P3qkoPpu#s>a|h85ɇfkɔEK:xGҊq63;~.JzLhAʰeV6Bc;w%BYʴTzӼF|6uU0Xoo[Aֹ'53r0jöK|V?+M6Y Wmy |=mu}[ԡn(qڗHZlc qbuc'!MoV~,Qzvwc @ R9M/pG0w $ѠTُsl>g0@x_`h޿z11#j^q܀9" pcPӘ"65-%>0&پ,E 2zrzdcʺ߰)t KD_ܕToQyO=p:O`NKu:ujI Y-Ty2- F 3&AsԵpלDc[đF]>FQЍ,pԯ|M00F ︃T.$h qK,Hǘ/SZ\xX}KZǚRH3i.g3!~l@rhED-Fx+BD92B7h 0i\o)I}'clSYp TΤfGb&$Uҭh9gFȶ`}JCRt0뛜w1Vw33|d^ĪEl4}_ jN lxL!`Bf u_1#WTqBkx wdi 7!z0Vq #ZjNtZ]42eyCO΍abyzE vJ<\Ӏsܹhl[WİB&:މi U=G"5*xRy2d1(lb4_xŴBda9ɤD̸t5JV#U*|zIWRfC ʡG ^Oӫi)\)y H6b5_@(*e o0^* ;drΑQX'Ix{S!~)0[mkЌ `&|j< kg2M-w3>)/to| &1d4l ѕ`pɢ<(ʏ5:;FS=3 #jRFGӍ]{l,6Sm%wΩlqT/ yM@:nMB{(wBub9(subܬ=SWtk u\Y#ݵר7H'oTyrs[lOFzB/JAd(j?eEބAϷ cۅozkz6oORacW0oW1PB^Ш |^X0Kƀ^KxSդpMӭ'р&?P*fpEʝ˷ Y5ȹ usTi<8|#9JnaLX**k$VA -ѵXJx9@^(AezQ=o2u=d{e ӿy)DkrE Ӽ>T3Q; ? OX-˟B(!LxzcŴUhŶ\U"3W'YBm.źjSU䊤8/*LBѝ1;-6ε}W': Ý`qM‘Qϭhzz.Mi<0lQQ`/|c@|U93nX8Ydf7s'.>@]wt#&|x+E KÅS 5x% Kڔ#8\zwFS'-DوRAV:[%kg_I qg¸am>)ֈ%LZisL#L ʁ5'Brivp:7EhC3Z !:!=Ai1©U'U\]?< #DA[:e(xgΓGbGC0ҫ]PMKlbTj]rb, kr]4M+tlkƝ\;i3I"6!jbې2[aȃKo4q]nNEz;s&4LZX0DL\AЌ;d3{a{;0l:Xk4@\>ar1S~E9K#9AȜ} ]KY8pj^>,();bJe(׻Bm[:Q(N 8umʪg^DuǺ6/jUZ2i_Fhbl` 3uLM 3Ci,Kګ4+,|=-F₌07Ȅ4B#L7X6t[}\+ŏ:0BS"Y1$奲 Z/F6i] dWYTCHedB%v-``0@vy v0ʮlcf0؃lXu~GL2D61} RT d%1`OY~PIa`aT'+AP;K5 tp(O;bT 0az}Rf4ofBRx+w2m:ꮗ3'%9-cȤQEkԒppMPcj&ý(챈*]os~(bɓfc^%Vt|6sޱ[NcE&k*Hm9mꤋ2UêԶXx5{ {ZƇeGTΐgݖ>gV50"@/~X ?][ÝHKw3*zէ4e];q6B qޠ)щ|<v)3ڰDG6P#W¥MI0ݴ.,w8Ig%[p]`EVlc;"H!^l@,]NIù3y_],-8+Whϴ|.'JV}K/05H5#h2w`OucHKvKwP$ZN(P 4b6espf_;3,Ii\x;@vߚ皕Cln|'}#198 BG]GQL^=W]d\x B<:1ˈQ @ .&?S~٪>A7Mn!c}pԾVIWGkFҌΗ>Y=^őp !牚.H:AuY|\?; !T%Hl/RL_XU# {BRfXAɭ *fXk"So6#ۘ{VcYNsՖד^H]+n%!Y K?!PM +2l\1nit ۫E*_Ls)gўյ `M>hm-4yjh%acJŽuh fHKA~cpL᜵+AxePYԶSl),8. @e\s1:zoܹ=t|$0X 侨@X 8 + SZ,3d,$E&VEvA#w%Ý*|ʟG}"Q5MUd]B/k"` L͹Nhsms("?Onpi"a֡;^R縐$ i6:1.ݔvדNRee[*ɜ^.)qGT^lZYA%SK[9C _T^dR,KLVÔ|~\gy;NOy;!͇Kw> PKJ$Jw*O]y1҅Tl^B8Dw^B[&6~JɻBQyZL= 6rɁIHz| 9|HHPL PT"?R݈{0vPgwjMQRҫN9ua9|D%ùv՗V+&iLK%٘adJp+naxnB. "-f7@Q6[y⒒u2(b78]@̸/;O6vL}`jK0K{Tf$$V1+HBb&wR %OFdsWWޔ~k{е(J4yGRv vʥstMsҒ1[ll0!ue@WFm(53! 7H9I;胅(?&eUh*F}{O@ift}0jwԾT $ _ɓF6|Nk I(0*j\߫(aid6XA{Mk&hjդK<^Ժ}5eQKX(l_qN| 5r{QL ־(_/P0\bJ|]1>-LʪdxO%1ռ+ Iimv+v%w )=.#]k}/b)ocٹԑ?H r ,Wd- xs6P1ܔ/m\ؠH5QH4- :#/fb)#2mT`y)_10‰QEץĥSDʼn_!K wkt([<rRsSjfsˀ]ssqQI@o/&+|0Y$!DJd_v%R#H>\*}q / vdPIi;GU f5gcxfT4o2Xe p5WL9qHզn XA7~솶@6@X/,מ)u0bJ C!Ye1˜~{. gfC=SAܖ,|']-'=A˔-@8<t]А䂏3,Us@ NJX0=ʪl~`H; }JsIsΪIk~I&̫#m@;BZOu@DlY #-}]m@%K eG̔اC~~gH)PNpFuupPNZ4x|6 B""2I.ƐHR<^lgg͖ D\:s ;VC*rM~)k-B A,^P>rU@3t& (xqi3ߤ Z,)D"2-nb͘?ki/i(s1$AsB"R*T pڬH[B0,Yf{R4V\0O7R;T驇8%QCG;l8ԋp5J;ȶG 2c,4cm%ZX7Kכ'pMQ82C)S70A5cNeZ?wal(*Ӗ]9եC'+9]d-Kw mH1)MN͚rvV2#MgVWU1S 62H֓=2u* "D=!˹ʵ,Xiy"pc%X,Gv@}LĠ*꿃8'@xOۚ(jF+U $b|Ɓ+I:GYȏ)0gMvcƪVÿJ&ݛZ0EWeo_~.(̻Oq9%ӄCcL{jY(jJ*.dB[OH)jx+W DŽ+9V$ܛ1P:IXO$1Z'+$42ǽ'Pm-`!y1P -nu(]8.uCޭ]zPƏQν>&4~x$Y?lf!8qv0|_PmC?g/@@^j@@LLRjSSʂŇܳޏq6A^)!8TV|[la^jA}%!:@ apS{LQߣ,HxW$oN@xQO/$n%^3ZTT oL&,mJJ 7tgs▐sv͂fO +TA?@Ww 0I x5^ߢ.#O1SF Xh, dmu#o8U# wTCgervǐʂZpv4Y Hy#GV!C2߁;? Ty *OOqk#a6[gYat @sXB4p*)0V6‹paT}V0CE#*!–GsH.x1lC7Q/$jxE%!AR ;FG}'ci뜊P~dZym1JyٯKԏҪ"]enJp,-IpRxpV5fqwBfZ^d>E)ʡ)g;F*- j.%s[ĉPi,h.IE,bls9"8kȏ׼ Z!4-Ph*I#uvzaՄ)|d #ʧ;pyw;i29H"5H@PLd4p#AqG MҰf'f<.D9Cl7!휌u`!A*H*=N1K@(U&tOPAUpNT#@ 8.u ^[F܂)oQZ)lg-8ڥl}Alr' %/a33R9 h78dM6ʄhAL=p϶T iwrU'L ƄT'WA ׊RJB]}IjN4gaDd~icZkS4+6؝>lٮ!'oS4gտ4 |Sh"ʷ \jkw?L$.5!s:AHIE0v  .2[~o\?wʅũ~tY;@o>u0g|^(ݯ `aΈ po*>JI&,e'㧣ĄFp>n0>J%Z,L >4oI@Z@0(^16GxdKF>a^p#0p DQK), ]GEqdd+d9'IΉL「aKe2Oȼ-|` awpa;:vlQd7haذq}?8 #,hkLhZCf7j1% ]MՔAK# bi*@!s'BkbV)cȒnu+H9=)@ӵ͍e7S]Q vXIiIP懋`OWpVWfPKJFL\! n2@Er 9H\MEW'=C恔SY p1]P-@xRg^PbS@߆$ po.O ÄV7zΒŃtYcN~ )GX)ԴLbZiLŐh@3ޖ|N2~.Cm+YaZx*n3wE Y>.B,gR$djAkri3@1iM;K㗿wP=|msyL8Zce˔\ *ˣ뒛[q97!n|`8 #[G<ʞ24Q&a:4G8MHlZ6oIy5ѭFRZ qJVi,4* 2+l3.ڵ.$=vҤ1O< hl k ~rǜ?C7ط2<ӏگ55z2`d m^lX @j*l4gͣofF/=k0i18gQ³@~k1}] -[ ,I+R"$x Gp 4Y zACC:; Kk"&9iv_MGw61- fZr8ϽVq' h5Ĩɞ!DEv>i[R+@K|%+!'si(J#hEC *?+揀_ ڈcꃨ"E;Rͩp?%L r۰vz8)à1eԠl$FԈPs"yl,`؝'!ğ͊ƈmQS%$Gr(uj2V2 `ˏ]sUBr" y )wҭK_RҘ;TH6XKG-40Mܮb#$:0*kiyv?qCmrc+mwa({ gVm8B[YbzlTc;M92{0^4u@T͆UŵBZVhأ 'Kwۋ]*N&}o~RpZuh܎Xje,#/* @Ir](*J|JEI6ˀ3 _"|Qf5᪙=.duas"3hvAl].0&BC,W.2ǎ^w_SbHu3 gr -}k*h9]M uVBk]hVIyѶ8fw17mL `lm3 A\eWQNk;z@x^.>81v0A o\i}?j;.$F͟.d )(A];[)Q*:V}޸RoM0c-~q9 C1 B91qΧrP )m`HGسT:hS9?/KHCҷ4Ϊ{UQ"UBjCY1螢;G+ ;=Xc~`%LLOJѺà֮,Ivɂ{ S`$T2w鷧`\t؂ꝙRTj&Qt+cM)+P)"CkaḢkiĖ髻A{)&>^[ݪjAיH/(;UO5{T%Mn?S!*18j{?xFp"80ޫ,4= oJE` %99[WcuZHExV8zC &_]"Խ a4 49MDe1ZYR;T*@۳4~Kz]|5K-t#izEAUQ#mc v&Z $"B@4R` t3"Ѩ*S`n|BJV1PiEҭ Yb0ցK>.$, А @ a(P11DeBG,p8PHjbtL!  01&*LgT:PH'+ ƄDBVCk#d7G@;pۨCH!I"\NJ>yQ$Jh c!бO ù Li.D lļL48:v221Q"0hCc@Ei.RRsRIlf@,aC#abqݐ- \)%Ԝ`BKP52Ё +#dR00J 7PŇ!d #$ŧ7^fD) \\8qi&$!2C1b44JDSs𗗉& ̐)0X l `x çP`e\ŅI,Gd $P>@dI@Hp0$LX1p:F3Ӧ.(PH`!`9q@5YO ̬RߎD BP11`gd3 !O.2Ф8 `la$td$ qLt:I |!-|H$<`t: K.FcB@́B&,|Á :) 0@BzIt8@c"@,`!V HD XHˁʍAh44 eJD<"QH3E(`1,Azx @lԩqH)HSJ62D8DpdJHL OCA'$"m>":OȼɸOsHHȌ@ İ`X Ԝ`  H(J-RH>:M3#!!jEpñx0`Ch / /  ǁ.t4!L 2Zjh"rN.Z.jJJTaD!v, '%i H(%V\xE@ CIЇ3<@څ$dΚ4>@^>42t OHDj xЙOɸ PX /ˆ$`lJ$D>GRj) \|H*21]lWkxpݽiv߲Lꏕ׷+bڎ\TŇͩHqo^2VԺj}5u߹+ʝyRF5⮶mim~:gD#-|c^wJ;ϝyW5{#f;g].4gǧ>͟sX7mQպmOFn{_vvmZ1.Ƕks]WQʯP?1WS̮Ԙotkū4[9#0Poڽ+ 0{fS4NL[eElVVϥ~vTi{2;Jysw2ݷ眨dճsN_^S7|rdG57K^ʽ|Q]3rEi1nvgj3.n(U|F4Sg\_hvWmj{-6{d]jմ4f9~yeWԫ6?-6uݼ]Q˸ {WYi_Wԝo]7^^bW곣MOW-Mgɣt:HBOu2+ v\:XdHױPHt$H D h8mTn*HLGO߆l"D£t8F|xPY::ϧe:(+lt! .K]T% éPHa!KEB-kPHA 1$X0 t3CA1ЀHl$@v<|:#5+\pLHDD0ĈŇ _8Px Iu0faQ DP"5 8@g B&if8BN:ÁP: qbRUE89G Ŋ$ M3b1Ō,OG pLdp> q8HpԜ`  M]B3^*2]G:B" J IReFF<İ\ QbR, XlFdS1lBƠ,FSO5"3"5Zt 틍pX\\xS1*IQm;YчaNV1B%X σ,:yǸ*pIpH(@Y'fFV񜬈>6Y'4j#*QR"rs)G`E8P 7됩43tl[̋+JOZ|b\oRܻ';Z^K6zyR̺ǾǿifoffRlu̾~eyl_Y^/ٹK.}E2^IsRݞ췞RMcSG=\[>|(on廔r2/} 1m*3V*|=5najֶuJU xu~E2m]_Qm}|~EaZ2Եukm_|Je;aJju~|=9YQyv%ņyʷhy|l{_QH={-(fwNl ۛϗW8K>>]o4D[__QϋǿQjG)ۛk[ZQjfh+*Y6+o_Kmo45y]W/vdMc^xָuܶʗԼ ug_\QxdžFsvފ7_eGug̚k^MݮyynE1]:W/hm7u.nE.Dշ٩۽m+LsVj t[3Ֆm.}D6eM=s~exfܶmo\;][{]YQmyx̛zYQiYQnhYQjֲZwܻŶunY){v5pcE'c7%nru_]^j3u~f|+s=wO# mP.ym:2e/3<}eWTvafw+o~DnlMƫ(fKE][^hyn٠T{%bE2r&g ]9]v6uT.:gņ~w˞}y}m9=&cc/jK ϔ[M+cGgӜ Nᰴ &A BcSBBȰبP,Piа, ڠTϚv=m5wdO]whTu[eVnk9%Z݊jccyK{+*O3Wofwm{ź VZrrΊW5Μij>4+}+}jEw3/ggb:˼VoW'+U׫ZQX))3j[ *vv2;=V?\ Ϙ?7+&Sj8ͶQM],x};+]/{}1gKt5c r6X0{9L~NuٔcEu^&f7[)NJ[ۜ=+ {1uLS1uLS1uLS1uLS1uLS1uLS1uԜ͜\wn.Nݼؗf}xPVnاj)EKl۽;W'?.su/][߫ƟK)>_ZQ݋cּf￿kw^׵=/sN^RM}[u>vƋеVMYWᣧ-ޣ}楣f*N7׿V޳:εŶkh˼V]wne珹.b܊ZDv}]?wWVT"lPlh\Qw 9#E{ǖ)w>4]z~ټ,q%?yxx2sN΋|+CK^~2d|Ů\>ltmt\}nr)Vn>uFU=}\NŨ:޲G\k?skΈJuw왽蝷-8Zy19!wc.l[g޿m\QݹX?-߻c[mS{}?m_gv~;um1~[QjT3.cƜSYwފjVK]Dɜq/nIVkWT#wuj7Q~ں^vǖvԹ);r}vl5cm_֯E37u/ev1f/7q17̶v+0n?wZmjQUskv2T>[MizNsc{ؔen~ƭk5Hn/Q$yks!$.8)YWG^] *r,s(֝TJz\l m)Nm$It=!l}?:shC6[.ұ7T)UC)3f^SX19?P8hp}{d.'e-ZerUS?,Q'et(sS ?a+lKGZy6Ȣ!7E 4r!)sXf([okSh= RAǣނ̄|ib$=zt>56}'/k]F}@x\!W- #$h!~+ov8x '7!M&zfӷ:I55-ZMȤ&znN7&4X}{:=l5)3Xt!)"Hɨw{Lrz{[tfz>J)dVWW"dasؔ[ARQd6:]E}jEXy[.npK6+r{_(^s9/ErA<~x̍-')ho Txy7*4H=KK牗PC\u(^!d  1qGzF+@#U4o(wBEzh%/}޾ߒMkEq]kf $35M8?h g{*j^$k87J]zJ-Hkm`nm_-.z4 f.cċFm?T hڹ"ۋ[F8/Lh_ XYXlNC=ONet5VH;Do 0'[tj0?ɴT65 4l)o]ɸ8Ys^I{=c} AX Vx}^OY8f 2`wMB.5yM%a`< /s HfG[TayM}#hcbFKā$tgAk&5T{d}ܖ<\d#s^E [oPI~ke}KZW8DJ4O<ɬRd@ƛjWW#ƚc,`#! hA62L}߃S렑O2w kf& u>jwqKtF!&ѧfn0.ZY7+b- G~&7%~U7<A 4ri2k4kG8`̔62d4W]L{G-Eǵs8$(,{]/>5@hYFomBy$#09Vc`5Ңfi>Mb`t GBםL 2c#񼱥y+k-=`ocnCT0Zt~}yW1 6ڡl0&fV/-7S2  ]+&4Lk# "5*g #\gG=(ä$2n^47``p|MNA bQ}kT:.}:Ӹ>LQnV# 9w^:+ ӳ<ԈUSu{' )N͎hSBcɰ2p )HU vCAP~ pQ)N6f.Dc9g%#eCwVzz9 B,ۀnb懽gZZ] trc&ZN4j/2~r>`t:&xN>dW8mcudZs#Ԏ:pKrN 4lsQJ:!ȷN,zˇzZEJGBtjyDŦ%b~:cH i} Vu0&wn?O[AO| '_&ԭro)`Sk^)OFudZm fsʐ~w1ҍcFݥ<΍w I-)fQTrqoUUr]FhO6P*\jx G0-O>w4p A"PUpkGj7M5,kXTdftjQSE6 ^kRNPtiW5 _ SXv_=.~P:52Sj 7Ö}kDW܋5[O*Lj:))AcdySDm?b=50PczPѰ{L±q ])[ grA1[+rxsujwFųyq:_+Sk73 8ܙ)J!NCRxD4<1d/2p4%׽$.Xvˏ3y J}BS 8ʟ/CoC+2PdCV]g?3kD$rR;-8b+dh,>#!]0Pf~&J0zfdQ z3@.(Bmn"?[yHHnJH2KB;HIp>D@,7K Maw%n$-sm0'[/By#dDw K3Fx{L__ώ@ 8᪍9SĩM_z4R#7ܱU*<8~t,RchyNGnxj:zl_AME'%g l̈ ꧬt!qz$mn`s`Z D/K^Bp;g]%wCm?%[5~2_b2B#T;X:rϕ7" q%((I Ub}LGkڦFx K)rʾs8mOqMՑn1%52 V J)(~' H#_xS`I ]@ )Ha]r \BHD A?@;S? Q/HBufT-..0 q4`4^P{: `E)XHCD_HPf>)"UT!Qm"AJ7} >") _@#'m'e``Y曼5t0%݋[ws#ݹ6*r> L-LV97 |$M ʹ;XPV!(ƌϼBA)d0JXG?ΝUĥyB'7ۯL8Y|0M^ (\<q58^h6،b]PJ[=}ci(23Œ#wab0A˜2\0)eJ@􂟫8e#܉CΌb_,_Fƀ )5FY^@Ս:2;jIcr w 1Re9PdT3ST˽im*7F#2RXca+ -h,^iAN@! ?n`|{)\ @7R4n<&O,LÛͨ=H[Srd,?c3Cxe ` S/8h)yݘ^įMy EQ#A5Ymua;xcc]UwC nj-ˡÂFDJ %- [7pX $η!qaP슒LJ>u]I QsHrȑ&w(ҜJJ:1LFr5Dd7$k(>U#Z%HDf 2u_1jG0ݩ J>t Ts$^P\Es^!Wn0s8[kXqr'<+ 6<oXTvFe>&pd~tȝ4;2l5ǪCP#{ΰpVÃHKkLB9 1%68IS$AA4&4FCLPP&|c%r\X8i24n? a 8:SQafBK&`Ī|_IbɈg$zcumla5äU\u ]=t>5;ʔY+F۔ X)w4:r\!~Ԫvܨ'헰'5O a}#3To%M%6 lTٹP:K<<É_JTu"k tgv$Kb,R2)f7'/ "=pq fM4 .Üv^j2۪ywJIs.f)mk|h9/ޟbYI&^Ǝ -#+"7E2mI7[SL8s ^p)xDZaN^Ǡ~I/TqH9JA5haЏaC,億\YUy@n+nR!rU'!+&GtqshA OȷY."}sKO"Og !P<8_ZZ dXolC%TjKch&hDsNg!:#1)>*Qdfj6UT.,-{GhnU6#Ckck|/, /hwv%a/DXv$rjp:1Az>Z`4?EDZTz$xrNN0Z5:Z `âRk1aX qsk~m%<%#R"3ZCy|-tFRj|a``-3:Y< /z'E=0#},bvg#ov fztiD`F-d~̷ֹPEX{eIO0<ɆLlA9 Sխ/ƋPlP>5Y8Dg|̿RW5@!A }نǓ+Ysxr[Z&gטK!=8a4|"D,J'4zT퇘{-+큜4&rVdIMn~74v~P7̋YW ju^| M>!'@_0e6blxi~{p9Ic+c|1!QXX5ϸt)@]?Yl!4 KHZSqn/%Ʀf#_i6GX":,ЄYșVċcT^;M)Jԍ*UPΚE)#c^\粌 Ap͕J@\\I*]AU 7 F7*hQ^4a9z[v"oh9#:2pֳEQ2kW=PcTb& Cyf)`UXK^zPgJ hg<. :q.wpQ2%Ě^bZ+% ZR_sM!>ɁIdPQ|zU{˽P3- ɡz6PI^)zp K9æ"yV s 4 EI-p7+RuGkcDj~נ$T__~!a lIRelX,e^W`/ւ+,_Rʁ)ϗvp2eRMtwbItOr儍d5#ʿmQ[wu):4n!rt-,w / $+'Penxup*?:PuA Uٝgxm7&ʕ1;T.P1C]fo4YAhYzx{&v j"@]0( J%~w\ Жȳp &^fr0x~TC /z lp#>+,NcfvPei 2 {"VkzJ[j}dlunZi46r ,8sq̓q&=7rA|\~? ikzx [.腰blGSǺ$mϖЦHT)0EpaPFzi cA唺"Cv Bd4ߊ"`5v@(ȍ( B*bko%3h{nxGh)),^E-ģ͛wO0gon` ok*[R,YhSFsKMͪ#/;9Uۿ;EV$Bh}eDT""weav3mJ\HΉ[ene ĉO=UpqƲ! E,Ӳ,Zc ~WQu!8`]^/Qlv+~;b J4&[+)FX86c?y )W)EX nŎ3gE,O|b0 {,*oC -:cBωm Zď=N}, ҝ.UI.͘l(dn*ة xlfYG !B/4B XctJf\[bYzR|';=];Uod4=O:WԸ ^T'Vc氲4<^~*%@@Y&jO"tminkE$$T6jh{_,#0yG+lV'#/O4K7 "Vcʽvlz_PX\[{xN ݖ-;{ 4]\1~C<0lr6ܤA:Tw-Fx*iJ"w~a>R3'tuJ%$ЉmR#h25֛NTVT" [Ii'Rӳ3d"!:g}v͟ E?,3K]XX`lF-] I ^L-)pwhƾdWccPga C[,K@4V$޵Z3/mo"4/DB1u" P c~w Q뼻$xw1gpB݅#/'ݽ7G8Xٿb͓D&0P<_+6w]|]TҐE|1wu|"($ޭL& 025YW zws6t f8b~ϒy6 endstream endobj 23 0 obj [22 0 R] endobj 33 0 obj <> endobj xref 0 34 0000000004 65535 f 0000000016 00000 n 0000000147 00000 n 0000053354 00000 n 0000000000 00000 f 0000053405 00000 n 0000000000 00000 f 0000061435 00000 n 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000000000 00000 f 0000061508 00000 n 0000061704 00000 n 0000062855 00000 n 0000128443 00000 n 0000194031 00000 n 0000000000 00000 f 0000058452 00000 n 0000230347 00000 n 0000053794 00000 n 0000058752 00000 n 0000058639 00000 n 0000056802 00000 n 0000057891 00000 n 0000057939 00000 n 0000058523 00000 n 0000058554 00000 n 0000058787 00000 n 0000230372 00000 n trailer <<99675286E35B4B338630FB1C02CD964F>]>> startxref 230599 %%EOF jamulus-3.9.1+dfsg/src/res/CLEDBlackSmall.png0000644000175000017500000000107714340334543017704 0ustar vimervimerPNG  IHDRRWiCCPICC Profile(ϕK(DQ#,$RCLiZ΃{Ml,,lZ*>d`#bms x#ρ ?in@$mW=: H0Tq!85s*٬XUH@W_yf&trȞ^Fo[aVmD? iov[JQsJ8D&sYVrfa3jD@">jntV쌢;60 7gJ916f."1V:YvPP"됆<ĆӋzXݩ@f\tK[/&x kU3b8u]G)S`"HQRY&X.Zc 5] 9bA4;ǐ%Mj9;[LBeSVURJ8s>UX:D fiP#RPaxz@QTPOXt:E.m: -N***P' C8ޮY.ĦqY!qiFեV)&R }דJj1,s"Tdv0$ 9Zw/`/nx" }{H_}%gmBQL, DTzjcos/ɷ%668"UU#Uju{ˉ<λ?tH_[MLZW!EygH@Kauy LnyO[/[R^]Z$Dl["~DN$@1+!О KP ls625ඉXN[2R%S"152P6Ì.@Ư{Tsk@B /m!=|-9m.6!1ؚHb 5-m۲\,iϗܽ⳿'{Ex%\ُ84`^s32pmJv~`(6 ؞fn2c5oMK:xT0m^~o?SԸ1縵JxgqPUk /D &iϏIENDB`jamulus-3.9.1+dfsg/src/res/faderhandlesmall.png0000644000175000017500000000235714340334543020537 0ustar vimervimerPNG  IHDR'swsRGBbKGD pHYs.#.#x?vtIME  tEXtCommentCreated with GIMPWJIDATH}1EW3{Md$KH8!Ad`l8r=s{޵'ٽ7U^yzAo:c@22R$ <{3`KE+;ҝLAH 0)poLeB x\VRd̘ X0$d7"I2 $$3IDB)$BZqw_+*DpJ0Z+f; x$JZM4HB$"KB*'T  !Acpr;@lJ?lxIdyb(EHާwi!D½J3HȄZ ~L~?+ukh`J!e23b$Z4n3D&D4t Y4 GlVcYδT}>G&4CZм1ۙʼeRY [%wݿ=R ȭ@)UDs9lpuR tMRn1*̤)ؗDEPYcD2 ?9^Ј10Ig>z=7i7R$`sO?>Юʄ[2L(z9_n$t'$d+B ܚoљ;YE0 A[Qk%W謔aم+q8Ƽֶ׫ (bm;Ŧֺֿ7 ZIwɆh!%,Ǭ"1 ]r Jb]&j)}>3Izt dLvgw̱'3Ou_mfI$7=eBFje=D~,DRDF86:IzK)|r6AdO<(p? Hl{LDZgSDTR G6;wYH[ 8Xb4ɇ@/?_udKqGr왶пqLXoKFHo:li$a)kIENDB`jamulus-3.9.1+dfsg/src/res/fronticon.png0000644000175000017500000000562014340334543017246 0ustar vimervimerPNG  IHDR--:tEXtSoftwareAdobe ImageReadyqe<uiTXtXML:com.adobe.xmp n IDATxYylTez춻I(mimUjB!"%}4h4 @zATBݞv߼n8y3oVuu W^h4/;2#W\tPWEJ 9=o@p>][sja > !Z.]v']CoC1j8+2Jh~Rԓmh[谽F ]-A bx|vn2ݚj%iqet# LdpGzZ< <9@ePV=-kv7HUK> çYI ("Tu}MKt {fGL8-F_n1I]7(b~s%h̴yӎĒh'$KIs ,~YO!˝$브v ӊ3=W8{g"r10|π 8#mXEN36rvDNiZlo3.[R^rπ׵!=.w]A/odϘ0K<-&'6<`nF.UvC ,څ5)V3N':iE+`X-͌;ҿ: rsm?V%CP\נ\Ij'LYkEo$zo/^uV0_?;Fq;zM] +3?*i# iTC7śq8 07Vd+~nug4-jHI Pᗶ,^7 ~pfC4y @Y\cg.Y2>Sb~7#UvW^(ҕSiܣU!o ʎ|/UTI)p&{(K @?jJG3aAmrISAEh2!q'kCA=6Ձ:DNk;evkˤ]ؕ6n 6N{k[ۿLc࣓9R_=  `N^ y)4f^鐛7 IM~hi.Q_Dymi֔R~T㜱#h%ЕҕjrO;p.o?^#jz,].)ފf$rCDvѨU8 u:_3Tor tYO҇灁:51|,L- E!pd p)o4A+|Y fZiMxMk/}Z^Y,ɛ}^(VT1D eǣ:=@ :}-:a9G3&EKPsY&eLڟ ] ; ̥^n2b&Rfkph7&^f}.[DV5FސB =hb' Hoع[F]J#t( /SK{qUʼnd7S$ 0'IENDB`jamulus-3.9.1+dfsg/src/res/win-jamulus-server.ico0000644000175000017500000034605514340334543021024 0ustar vimervimer hf  00 %v@@ (B; (F} Fn(  *K zELO###aaajjj666===ZZZRRR***???jjjzKKKKKK LE###6///,%]]]cytxxx|f`333VPytG@b\:::(fffgb###/ LLL>7TN`tvwumhpk HVl ]]] +XS- e333:::###H ( @  fD*_r6^(l/Ywy]4l)iU~ `N PPP***F___"KKKTTTSSSttt$$$iii1333555###+tttYS2+///^WQ #MF444RL #KD[[[c;;;NH92&yt!!!\V2+zzzd)!ql:HHHmgic,$...%A:z/'d^HHH-0(4,MF)!*"OI5-)"QQQX(((b]4,|w?8%YSEEEe$d_lg)))x)))rrrIBB; \V +#kkkVndw+++3+#"<47#qsoccc>7LEFFFM7'7wwwTNYS\\\LrB$\\\FFF{G\ !!!zzzkkkV!m d---GGGQQQEEE))) LL'jMdV{-@ (0` $9Z9dX cR^^%;JNF3 L}8 IIxS`555OOOXXXLLL///X ***uuufffLLLj !!!$$$zzzYYY7WWWFFFWWW666 ***nnnLrrrggg&&&3dt###wwwPJLLLd,,,+#'e`SSS +##!6/VVV)!$$##MG :::( $$$'MGWWWkWWW&"#!`[(((!HHH#>6;4!A:x%%%}( !333~ \V 70P=lll,$ vq zic 1)000]sss"4-f`1) icQQQ*"$# %B;|xxs!,$hhhK333TM!&5.% ,$UOke)!!]WrrrEEE#&b]3+!"$$( mmm>>>=6e`NH*"!"!TNXXX"""{w 1)wr>7#MF999EEE.& ~)---hhh_Z ;4a///!#"A:HHH#?|||C<"$$ VP W: I)!$$$#6.AAA4BPWLLL1*#$$"B;|||5+V ooovq!!!% vHsssUOZTu"1? 3XXX||| ++9$H7(((@@@ B'222GGG (m---NNNgggrrrmmmYYY999v "."y3"6$) Qa",6???0@@`p(@ @+ @It' Sa#1?EWi "#bx)\g5Riaay*-@32bH" 777mmmsss===J,[[[ddd%000888DDDOOO,,,FFFYYYdddfff^^^LLL444999DDDO%%%cccwww555 <<>>7\V!#92: 999,$#!zutphc!#3+000%FFF/' *"OI0)#!mhUUU&$$!"3,c]up!#-&ttt'$$$F?"$$$#!%@9zu92#!a[nKKK!$$'""#"!+#QJ]W"$)!eee4,#"[ULE)!!"#!#)!$$!UO*hhhjd!"D=sn<5$!#$$$$&DUUU( $$]W0)!"$$!OIlllP000OH!!YSJD( !B;JJJH ```"#,$rmVP%%%0[[[:2#!vq `'''XXXvq!#3+{wqqq)W qqq%$# ' ni)))e_"$$$#!Y^fff.&#$$$$"B;...:D "%$$$$$#2*wwwj+V3?777*"$$$$$"<5!5]]]RL $$$$ to+++J8E@qqq¿?8 !!!SM<<<xRr7nnn}YS^X<<<QJANSSS***z U)))wwwIqIKKK---9!. <<7d_KKK]!7/ 6/nnnFttt4-###PJ>o***1*#$$!,$to |/'#$$$#!?8uuu///-%#$$$$$"&]Wkkk(+#$$$$$$$$!2*bbb=)!$$$$$$$$$#"IBuuuH]]]' $$$$$$$$$$$")!ke&$$$$$$$$$$$$#!92C%$$$$$$$$$$$$$$"$SMbbbKKK$$$$$$$$$$$$$$$#!;4<<<|||#$$$$$$$$$$$$#!6/~B"$$$$$$$$$$$"0)up "$$$$$$$$$$#]Waaa_!$$$$$$$$$$"}x((( !$$$$$$$$$$#5-e!$$$"#%$$$$$!qlEEE|~ $#">7vq#$$$$#/' TWUUU|w!70~>7"$$$$!d_KKK1+++to-%vq#$$$$#*#0 G@"$$$$!YS:::v%$$$$$' ^FFFQJ!$$$$!NG0,( $$$$$$NNNf\V!$$$$"D=l111+$#$$$$#*hc!$$$$"<51116BBBHA0(:3je0)#$$$$"z[[[]N/'!##!&E>}up!$$$$#5.;;;to $$$$$"!-&WQ6/#$$$$!rl^f` $$$$$$$#!#81lg}"$$$$#/(¿ !!!"$$$$$$$$$$#!'F@>7"$$$$!e_YVVV5-#$$$$$$$$$$$$"!.'YR#$$$$#*#((( lf!$$$$$$$$$$$$$$#!#92niG@"$$$$!YS333<)!$$$$$$$$$$$$$$$$$#!' HA&$$$$$';;;///PJ!$$$$$%"!$$$$$$$$$$$"!/'\V:3#$$$$!OH>>>EEE#$$$$#2+zuRK*#!"$$$$$$$$$$#!$&$$$$$$$<<<=SSS;4"$$$$'yt@9%!#$$$$$$$$$$$$$$$$$"E>666iWWWwr!$$$$!_Yb]3+"!$$$$$$$$$$$$$$$$#,,,NNN,%#$$$#/'OH*"!"$$$$$$$$$$$$$"<5 ===ZT!$$$$!}xwr>7$!#$$$$$$$$$$$!|&&&$$$$$">7a[2*""$$$$$$$$$"A:'{{{B;"$$$$$MG)!!"$$$$$$#6/,@@@~!$$$$!UOup=6$!#$$$ RLkkkl%mmm1)#$$$$+#_Y1*!  4-@@@C!!!d^!$$$$!rlhc{v }"""uuu'$$$$#81RMMMJC"$$$$"fffz/JJJ"$$$$"G@)))A999YYYxxx6/#$$$$$(!4-WPU222ql!$$$$$$#!$YRVVVz"$$$$$$$$$!D>F---/(#$$$$$$$$$$!YRppp8XR!$$$$$$$$$$$$$s p+++*#$$$$$$$$$$$$$!WQmmm$` $R{{{!$$$$$$$$$$$$$#5-!6[D,sn $$$$$$$$$$$$$$*"¿NNN,~@MMMoj $$$$$$$$$$$$$$( Br2{ $$$$$$$$$$$$$#/'# !/4S",$$$$$$$$$$$$$$"F?EEEjs"p222?8"$$$$$$$$$$$$!{lllQ.1sMMM#$$$$$$$$$$$";39_roO%4```_Y!$$$$$$$$$#*"q=$C5bggg`Z#"$$$$$#!0( e feeeA:%   !,$[UH= gVVVrlvqRw/H7!===lll~L ,!!!DDDsU8&2 fff8GiQ/***MMMh&m&FFFmmm",n KKKpppGLnU u777VVV\#?+FHHHfff)))p V9 ***SSS}}}kkk???89(vWBF $$$000:::>>><<<666,,, jI>o&xd"t { j+SVIXs#~<?ok9 2yF s< 2izA8t7_lC!G\W:?????0 > ???x?????p08?|??PNG  IHDR\rfFIDATxw|Y !0AںWѪXV۪ԪjQYl^a]qu;{ }y}sg( $[:h$ ՟@q//PYʀpȭn'<{" [Pɜtz݁N@*F S !)}4PNd 8 9@"r\"8p8>=! =@A(\ դ_)ҋkIa,cO"5[~(`>ҨgRw#[7B̯ 5V5p 0i| 6QH([e!zh<3V*`:oӐ~zrjBr /tX V=c0z1#˖nU+D6u5(5e n~3HkI ½M$WaB" KQ!~X,8bbbuKtt4X,o>xr())r***x<!~"3wYǾnMG@\5HEB*VہNݰX,ǓBzz:YYYdeeNJJ mڴ!>>(VɄHUUnN'UUURPP@^^'Nرc:tǏKaa!n*ґδV}ug12˦8vY%C;pu-5!G<'**:M߾}ɡK.Ѻukl6܃ MII gΜСCܹ۷gN:Eeee"Ot뇴$A+i~Zơد|D༕aHh <:fHKKSLկɓ''O˗/O=4iHII&)4 K OSMyf#ՅP gt\;v ,B!k .{zq(//;w/5kHKK 0 iS]Ex8a=؋2N %?D`9.Ƃtc:OJJ3f8xpzt:ݻ?/&L Zjw4HgW 0!ש06R ZVӧx͛Eee5իWsPh;ho5uD:ѱ2dV!}&"@&**J?^O=7C>ׯX,|/܄s t7kB;ڏ.!t -|`/#O.-Z$a3g/, "VP$W'f3܏L| fd7-(H[TT6mXx(++{΅%yyyW^\r0zKnic5VL8yAGzjE'"F)~mQZZrssł D.]~Ѐm0y@:X| ߷16de@ӵkW?Q?^9q*/n{^ː~zwY'O V^7Ѣvd@#..N~b߾}zϣr˗Pvt^!<"^0kxPW J4KnrSE 8PJӬpo+ڵkЈfzqL* EmNdL~S#ݭ'͛'?\ix^矋'FpF O4N~+T/?`q ?O7WΟ?/}QѺukKc(*G{Z\dư sdf1cصksvŻ+3$nF=;A8dL[+aEX|BfΝbԩ:l䟏yC;["߱J lC.tknM!]2K"Dƾ( ~E>kC?IJg͚ /@ZcǻwPYYo&^Z㞹X iZ[y"ߣ*B}AP"Hր_I72ʃ}nkBϗΚ5_|1x_Uq}óq\ѵL~ z8֣` .՝LÆ V&KȕRwLCGmd0A#Է dTmd~%<)|=*5j9Qa3eexV ~}[ԩS@ 2T~9Ȏ_4K"cG="J4JZAn'laHsM_ң/ߴi_>ZJœA9ۍw6VXrȓN:ѳgO֭[GQQ?ꊜs4EG&Nh@7d6~*9Zx 1x>r E?=_~ ?~[lV0_Me|^zF~oEDHv9oNG1l+>*Lbr]wY43x}s>F9EAa/'tfXVݻ9tHVށ~&aN㑉5.g!((2MJ;4mbFZ޵8lF+L5kNNNЏjEETĹ<7P QÌ3g2w\}}z ů_&NϲExFi8T;/܏.z\_ɓ}aX{0a?;Z;ҁhz"΋y#51j(͛9.jAxN(([#PC$%%F{F!41F72:n`2g ShZ ;>,ȸȓm1>[w}A iSJ2JtS<#sj܂,ؔ@ˑY*ݵD7fj n=ێ8(0L¬Yu;1OÔX(0g#ܹsYljLi0O^:࿑.Z7'M&rߌ Z_pr7oqqqL#6{U' @U1wɑ-vmZ}EA@1҅X}2. /H_|]O)L&IIItڕ~1`zIzz:mڴ bEI)@3 )) یiڥbj9+SzGY'B_$2a8}ڧ Ӈ'SiC 33!C0zhHN<[ݹ_U^:_>_bJ׮]2d|ځQ v;]taرL2KcDYϫҪ/3&v&O̢Es) RB=Mˀ~о}{ƍW\III z5p{0uo韃˭7#F %%gziw  V<Mfٳ1c]v `ZY#VlOE jԴAdeeѷo_- !@(2at0 &&#Gr72i$ڶmaj~>OK+/꿪b:F|-hF>1!!!\Nbbb?~(UUk~}Q^!'ٌw8я=>}`Zqݾ^ 5ZОO?UW]EttP=|ߤ`tIƽ~eٶ]Q:k) kQ2'@tBBByyy^ĄJ6v;g';;;Dو vmJA*]-r=r>]w^DIix!J87_gcZGBD!%ҫW/^~ejx>߀`u:i4 z.φy(QoU:~AM5 *]>+NLtnkup<7Zg9*~CϔP2DT_~۶ms=Ǹq~5|7m8#w{ D__-bFMuXR0hxWlf`Fi+3&f͚C=f{ 5k\$9Yv̝3mx}zIkK/?ɗ9W5Z*)Yߟ`ԋ8\[ҏvR|s`JI2d  )%;N\~mL~4sgMrBKjpE٤$ϟOnB4<- l*4&4{Ly#%׬6.YXnj:i}Pvqo$jf OOCx^4u*fvtԩu]-g(=uw'c4۔?IEyQc#St:)//ri/ W'EFFO<"OWOQ0!6r9W{zM!DE:UUUZB@נ1bp=}ADxI?Z*~VgU>(eoE8!P3ĖXV\\LaaK *:"C}5--&MoepZ ]տ6 ˠX'O:|(d[}ڇQZP긂[ Mx ?x-W` oTX={`8۸1dA9sy8߾0T:a,/!󩬬r陦44&>!@K@jŜ ˨Ҡׯ/$ "wѶ'{fR>}ZKi06E@꟝͝wމ9\1J\lMeSUvA2'pigR,/ J™ǏktmN?>`N׮c |#%&QQFŏ-Uc1u IE`{谦oJkkZ\=zT˥Fk"t?h Z`%p]s7*~ ,K~9(C3߻w?+һr!-Qh8Z̙3ǧŠqxsZEk&$%b۔IXG s#8z[[UŜ٩EŹs8uꔖKMֻ!C0k,Ǧa;GPT`'E9; c[W]3xvĵ؟HgѣGr1qoDǦa2al̙T&[P@UQVv)X6eKrPZֻr|_yy~f)tcϞ=Z 4@S儜Oo%" ːA=vI)ltΔV0:q r#G W_i GC/EQIMM{lZ<ݎ{77ZTi пEAAvripv1Ӑ}"33gdܫ^hQ?uq!;ғխNriӦDkH~&5 ?i&\((w+4|4 7m#s1nk| ϿA1p@ P|:U`5BЕSNuV-jb r/fVs 8Ȁݚ~-0b6oɓ'\z 8P? @_ĉ@=qۀ/VMu4UUYl@X |݄ҥb8yC\~E SNi? VϛxEQ/)))Ѳ 2MπSf'W0p9"?<˷ߑ@w۷qo(8sS{n:8P[ DÉ{\ w^KMjhkޢ~jrY-V_5 9Rtt4Æi:54Sv<zL`?jL 9{,|7!#C/ ?۷GzA0X%8~[Bů~&b韃}ezBXtRvޭRXE?|+a߳gO#O3GrȕlF=Fs ҠFO`(..7z XY?*ׯ_?lojeR0PO/Rz^} :/5~ʕ+ٰa?Z#|>ZWq12ݎb|W ޯRRv8~qQ}:~b[|O Z xZ?4D%$$)[B=p?7]uDi?Z*3~jXr%VzF#+DZZڵTL- q[<>dz+FIgտM7]~JJJx嗵JiN||t;QYkRyU6uraɒ%^Z{Oh,V " &mMW0kL$0K~_ԚL@ggWL MP6sSoM^~oc2!O|;=>!@bSk }e0dΝ˨fBCh`6fB~cUVVsi- r)4>dՊðж ,f`zTsدR }}]nTo N˹pႯD"&s rC:l:t PQQ{7a೫AHQfYi1L&{Sv<|϶!g`SYY3<Ν; $,P`Bp`4 HdA JJp5kM1wb[Vo_.0QZZ# " )tg"/S)i M#M61| }VߦY>|PjST>gJoCnG gϞG2c_/2! Ć@FQ-**Z P,!jOPv\\-Ek ?Yp!BzZ.,lܸџD _u ~z?mիo~Ͼ`)Oe 3:biU렁ئ_ C9?Lnn?9/~!˨Q2Ha1@/_5%޽Dii)O.9HLԓ*)vڠ A(g^/JT$n8n5b'_wV kj*7BEټ.B`C%`-Hxb{9}hvOǂ1Zo}vvСC=Va*^/دuaǎ;xG')X ,]4`dC``2ؿm?//Gy}{h%䣏>eJTTMF>s,b~/&9țo? )LH/vORp'6%.M+د%fĉ&_ HFf`*۟*1cpq1;q]x㛪Ʉe b|7`JJqBjj*#Gd޽>Ïm 8ެZm۶V/4O#}X' }Q޽;߹첀;<5DUTTp82e fo3xǽrMnDEav)ѿ~SQb|NJ$$$0vX?~OG& 32) e„ FŠfw~+4Tnj{$GVZjرc9s {7 @j>fdih p1v&Olha\K?$q <!h4̉aرc} RoFW8qcҾ}A8K&^Xg'MafcĈXVKzG&Y'tǴiӈ O^Tݪ e@߂)], C ba4r> N~5 i ~ 6lXpG 3gq-Z"v\lOMCXrXퟯX,lذ@[ XN#GZ 5CUUkƌc F8j^EyPU۱M$gNGm^.FuV!hC5 \B QTTą :u*vT>X UURT݈~~ sFz<6sA@* N`(,1>|$#_@# p*+AUQZq<֑e qM/8sF~Gި!zٵk$###cf$Dq1~:r8ѿ| נIлk͚D:uIJe˴ 5!'|чÇ3qD GHCٸ -70gw7CDΝx<|gZ@.-*@Z0ĉ2alQ(1#rwEQի;vСCn|H9/AzݻwðaÌXBZP #NDEELyH.>fgzlݺLz+Acǎ~z-\t"pB&hbۗΝ;u йsgV\I^^[$#bP zaٺu+ 2 HBB^˗k1Z^U bE rϳ}vJJJJ9ΪU>I]v9XS9}4vbĈ$%% "8\.˖-ӢBo@1$W(ɓرA40hXlZ N"fӀ9q[neFA#syQB dzynn._|{6\ UV,ZHp4 dၐFgAnP :iӦ _~%_ˀEPֆ O@cUVCNNQi, %%%|GZ.% dbRQQ5k(..fD#&&EQZZQGp:LTn77ndϞ=008֭[ǁ| hlb !8x W&99nݺÈ ֮]duzwaX8y$+VryTN!… ,_|C\\^]1@f}^v-<ϧɓ'Yywdv79ƅMQ1|p'- B֭_hݺ7KBBXtk&I|:@{n ǎ{[n[lܸQ̙3G$&&L8Q\syT\T.Z@mm ''G뢤DߢYzW_}%na6?w[Z~dvs8bƌbʕt4 ^ػw.:tߢk׮bϞ=zw?Y(/I __KHHs[lG&"QUU>^|z?Rg"::W_-5t荵vډ;C|碪J+,qb׮]G{ncǎyyyz?^B̞=;q_d@ ֦M@|RrJql4,~͖%K@VZp8СCų>+vG>|XKbĉzm;w;wEEEK/ "{Z(]v⪫8zhx^q){[oUdff [DeeЬxWf |*[p@bX`СL8CҩS'}$\.lٲ+WvZ9 y_bccy~4 8Yػwo^{`l&55}2b Bvv6a]񐟟ٴi9۷oԩSnGyԻ+MUUw}7 . } (y΀`Eٳ'#'']J||̮]ؾ};{㔕i- T̙ /@TT]X.\ȼyV @D5lZ$$$Ю];233ҥ ;w&==T%::͆l)UUqTVVRVVFAAΝɓ9rÇsN:E~~>.fNHq8gܹzw%"ٰa\s Ǐk:kl58?w|dtFQV+111ő@֭3..Xv;QQQIo&EYYSXXHQQPVV ˕ڵkkƔ)SJDq1n5CSѺH>' F ֫W/uV `&%~ɌmbzϭD'?v0vZfmcƌ1@{WX`-saذ«3F۷Ovyb ࿁z`F 6dyf\pq7[YFA5u],YDx^矮۷OL6-Y 47pg {~-99Y<󢼼\yr^Xtׯ_ǽT&'~noY:tH92Ă Drrc~tf#uɌ-''GmI\TU[lf h9z/"Ɗ[oUڵK| (yyyb"==]qKp{ݘ9DP&!:u$~iq)ߔwyG9RX,V! b-rd999_HAPVV&/^,.@$ T+@C 0lFfѧO1|o߾O~9[oS Hn2 ih;9s%KχBlٲEW hkOFLc "(z0a}%%%%dUrA֭[ټy3}} PaDEEѩS'ɡs$%%Srp˞={ؼy37of]t +A( ѤAVVM(VwtRVVFqq1r1:ѣGͥ׫ja!2jWIO#qAP0Ll6p8l6&ӷtr ǣw/EL-v38wg !ہ.* ip2 |Ei,o&- n[3A, >"g) P<`&F00hao߳f[8_ʧԓ4 x qg`@e]S8i^PGH O,>X!C8e0,'אdy@kd=H2GHk_ Ȧ+ޑVͥAx F$gק9Y nYidhxKȣ0LOAtC" Fh| ~V<} )zq;k~׃Ɠ\.ڝ <_7z~h:tcdlj嬋՞^YݞB*ϱY(2.;9Agv2omټ"ܳƆn-?{B_gDIVEk콝>@`֢vL R,(.$% VA1RNmƊ`7})'>:+`T"xk.4Ms"FH&tFhR;)WG%bS+̋GNcܸ# /Me;yBku`&Sf[.#fA&H!6 )Uf%|2fT$•LDcҌeӍ @X G}Deq⍈Q$|qFeuU4jԤ95ƘbN0I!I13:uFD΅+H EK,sCptUlkQC*5ߤ-rGu}SE}OA8}P[uwA8  F&ƦYʀSiA߈A[nF'rf?șn{Z& ulh1sDD/p-y}!="#\#MӺQ59JCT~wUt/Vu^"#5=>cT3]w-ⱉq͔/sm؈7#-I߳=4BMQK~O4r{ 1_j4{]}ܜ~B?YWc|+N}bKGD pHYsS S MtIMEEIDAT(ϕ1n0oc hހ.1rJn}J:* S- ?Q(F3eH~z.cι;Fc{۶&Х꺆rD۶,9wGqWTbw$#s*_I)AD9\QcYo"UwiehHvX&">ޣs?H"U;q̓@/IENDB`jamulus-3.9.1+dfsg/src/res/ledbuttonnotpressed.png0000644000175000017500000000352214340334543021353 0ustar vimervimerPNG  IHDR&*ӜsRGBbKGD pHYs  tIME3#itEXtCommentCreated with GIMPWIDATHKuˏeUk}N[U(ZPP@$<+LL&?814FDZ4 ւu=g9طĕs9뷿ģZ5dlP-v>ݞRgǢ jXI3Ov 0b R6$euvCJ_!^+Cu Si:OEd=9wS^S;vڌ L{|;yZG}16rqNE c)3YuÝoL8̉d=d 3àV0Y aܭ"IL&x'><6Ư;p*b0MC>vnXV]&yeגلN'C!#E|J8z Ŝlp6ѥiɪyR3 V\,U a22(?O'{;;RK]<.;ca$en:}w}7zp!L8ԈVF7A$̠3g{k/}zq-{ O[tx7RL>uk٠Xg̽% @Nꙩ @I$l6Y 7ss/D6q> n銯 )!qJZ>!+Q0cKkSf&ֻUD2.yU p PDK ѲBDY ug= .n._l;ŭ-J-T r֪ ԬdEf,ؼ&aK5k6ad#`qboטد ]ABRmٯ(#a ! pDhcXV*V+wl` E]sQ. ODRLaydW]!6h!H7:>٢UrIx%.êaapE$Բ&[F3͖ Z4H۝Sn?6l59e3$2 o3o"mGnaMaAj yB)]_SG*1>;]\`qXD0 P,儧Fjho6pFixl1Coxb(wvs8_}zn$b{K_J2@Ela;]چdp/SʥqeٚhG,ͭ-ٳ_UdtII-yr{j`5*wk3LFȻe¦Ob{n.fC͆+ʉ;o(\sMWH 7h2*7:Ռj=dl>Ocߚ"w?7N'~қo|ŭlcnD ~5udv 3A^Yaԩ';YYs{ihx_7~G*CծjA4dkGR ?>vIk%?_݀KįswbObgD)4XC&DZcO}<WCwrIENDB`jamulus-3.9.1+dfsg/src/res/CLEDGreenSmall.png0000644000175000017500000000113014340334543017716 0ustar vimervimerPNG  IHDRRWiCCPICC Profile(ϕK(DQ#,$RCLiZ΃{Ml,,lZ* `fma`tH >)5>E\N\UYW6RGE9%*=viXH + 7>ɬ:POG ]C :c0,q n ^ $  3e!q~#:%T rpgneɽ,۾+t\kI(-010.)#w3( T Dq*XٙӾ.pa!P$   oKA !0"!j? m "jAp2HzyErAAT12c 3P k MiWWL=d . &(;X ?.*Deue*13Rj``;% z!/=W Hq.Bnr!=$ :P}_"'aW&-@!V3 8rs>6GVZ2|\ ;  f V 7 P  l ]{ 6# s : X4sJc{t A6E5`Ye"${axEi%R zo ]  MDjVn?~nPQ) PY:@#9t: X0)ChG7saZv#! Y J qTyzDrIe E-S;sM*u R9MP@l a(785>s`7$Ui|_G*ia5"8. ,zF>\}? rt:<?XPaxb?5kCLC1A/!e16LwA Cu[Ghx<<U3S\Lqx)X*_L4n9B%&Zuv| mw 'C MAk scrUGvZ4g\>(I :sL=ilbR Nr=ShV= #NR0o|^48Vps~p,K1| %/9OG|eE. bjB Hi_=:V{h}@O)iTGaI0Mpv!%VPa,Iji,eQ[$D=XZ~g#ga'M 5{&o# 7_B; X{DzHiFL$fXS%B2` }1OgcmiYd] k8MCpmz! @!Yr~Q(BdfDjeH,( . Z4_PmX:rN+< rL3ve=KiD alE9rUK^Q*zerk o=GL&NJ|]'<{7-=D;a+?`X'ZwUr%!GWOda,(`d, !Odi.:\Msbh}lC(0q "VH6v%j">po G1\;z|)z8%ax Uc'8! gM_}r}rc5=LsKLcl=Ku[H U@7>- - pY6AB{]([2$i%$^E6>pqXQj6k1X$7F0A|lC'&\as[%s; VcUA>DZ;`o /QVG}M]=!Ah45)!b@pm| {kloiroqx4nu[<2)7Di#~<zhsa KFyzPQ( P@wy( DoljU@=D EZk`>h.DRc%`o_LS<gA;Z~JC&#eVu@yN"~6lLs3At~'t  BE rS$aY4zU Lhlw_G f+V^()_E0%Cq W8('d^'`s{*QP$N6W:@EZ`mtG Y/9%i8>zUp6owXHhYdn_HrFhB)8M[j{0R%o t+2S{S`<q% =4QP-*N> K7jaG4?:t;#.,4' }T)%7C<%&5.tOWmY*O OM( e 72We5 fH}@x zqU}6&j &SY*mpN dl O '`FDW\lw..9+j0 Vq8WCDTYi=P{D~yxnM%Bawa/$)Su<etO+ \C6/'!% vA/'2\sh)k9MN<GLO!%AP$1OHYi~{ae{ +lecOK&V?-+AW[\O7 {y=iUnF=/9I]j3XR?0%&-5J9'2(+c3yl-s-/Y_UFKMmgL$'DVlwlM?%W+!"1SUV>27@QGD4 QT5%W:$#Ipz])9eNJ tS="2/Y %e<!.xA+3NP4N'BQa}r\  5nw7x)tJ%'<HhrtU:%#3?X^WDKx<HCI3~ ~ YNz:8R%9%).N[nmEi$m"b76 D!EiuvF+o_M#*V[ ZgqoG \C9nPF@*\u2Sl=GT&}l  0qpeEz f-Mj?QbE iD( K)OB)\Q~Y=z2+ytAFc _y ; Z '$${n&A4QD 9#QaLeEW$;p m Q [ Me>Yh 38,adK tsh- sH.v!}Cm'C @L9TWuk -%)@mr_B'n %[v`,Yr~ C|?;Tuz]I"+>^ki8t5]^ v7"CJq5 zCe9n`6 Attp]!3u 8s]%SWP+${`E@nrw'dv_*N^Hj1+Z=`Q2=V&d 6I%tQ{L=6J|'q!i9X5w+l3}iQP$w; [iLn|Dau SKb%WcsS{HIm7z$>:7{&So^cU"d!  %=r)1o#Z < NutbZC/,8=(0.=Nrpy[0W'ctY@ ",**8Qn!]g8boh:]wDAC58j/8B_RJ; 2kg[.@VZs|t\,cQLPUI3b=:l%Tfyo`> &Jp]8 _LCIUU\cVL@YeU4 (Ix$:GVo~El{  b0tI, qDl>.\4q6npiiceg(<Xgjm^[ca`j*<4WyaZ\mw}}}xsl;wE `;#5DGMy~jgh`g[P>@@PcrMGFFa{x$NTSF7"hH xK=HQaUOWmq^A_# Y eA:Ec ,.==5  ~cTG7 sN"bSNC>=Cbox^@20=Odyt{|1^u}9OkqtY,}M3 N`?8>BJNb~7GOVh(Ig}vyjHvsnY^ KwCmw~b5e!{_I.rdjHP}oyunZC8KbiswmkenW@ tO>;>6 #?f{mpzIovkebqmaPEHN\| e7 /6 .Pckffn$4C;)kT;,<G]kxytmlfkbXK7*&  YB%>EMR[RE2%,;T\]PI:&{oMJ2416KLWZw!9NWH?:5:=<;1.09?CMPSVVTH:#$#qL7 #NFVW\hflh^[KE2(&8>RVagiihlacXOIB44++&  -2LSesxrgVM5'#/FPbkytqRH$ rND!#%6Se8OcxsT= '5?GJHG95   "1;HLPQRI@*pkiept*0:882#w} $+2ADKIMB?2+)7?CEBC===7757==BADA@51! %$#$ +EO]hgfecb\ZWY\cdwwiXG0"  0'%(1FUfm|~xxhgUNB4*    "%-),'y~ !-?L[qnYK5( !?AU_bj`_J=, &13@>JDFJBK@C:81--,&6(85560*% "0-876<31&#   &)645/ "/-*3&( $ !#(/577986933/30,(# !%,27AAMHRMOONGG;5* '-=LTaaifildh[]VRLH?;3!! !('/76@B>K?E>51 *>H_jvti\F9% "0FQadnmjfYSB4& -<WbvrcS@4'5?MNQRGG92$ #)64?<@C>B>BA>D<F<C<:8+*      !&35A8G;=6/#   /<IT[bcgddb]WYKOC;:+) #$$%!"  (18CILSRWSUNKE=3/"  $#)$,&*$&   .5>IKVT\SXQMJ?=4-)"       )'/1518134-0-')!       (,257;5:502&&"  '.29:=::915&)  --:8<?7:10,!% &,89BBDECAB6:.)& ##$$#$!$  !!(.*5+2/-/((# "$+(-*,*(%$      !+$/*-,)'  ""*(2-52320-(!  "/59FCKNILHA>2,  '%149@<G?C=73'!(08IGVWY^ZWRJA5& (,9=FFKKFH<9/" (19@CGKCL:@1*#   )&1+2-/)(! &(236:9:<680/(!  !#(%.&/(,+&&  '#,&+-'.$* #  ' ,$%&  ! #"!                                                                                                                                                            jamulus-3.9.1+dfsg/src/res/sounds/new_user.wav0000644000175000017500000106301214340334543020420 0ustar vimervimerRIFFfWAVEfmt wLISTINFOICMTRetrieved from https://freesound.org/people/deleted_user_4772965/sounds/256513/ 2022-06-28, edited for Jamulus by chigkim under CC0ICOPCC0ICRD 2022-06-28ISFTLavf59.16.100ITCHREAPERdatae     &''%$+(0,2/315.-,,*-*515567399?CAC@?6=:861-6)+!%( &"#!("!)-/206??LJTX]]hmtu~vnpkojfdec]\egheovwv|yz{uskg^cMWXSMNEF;AIRUV`]_c[a]ahdeflmglfddlfbbZVPOI=L@>F742.)  }kl\SJ<2'(   ')9@B?>DD?;/xxqtmdg[`PJJHNSSZbiq}} #,HP`[jnxwypskxnrxw|!/5>TWW`czqe]Q?: l )xP5< j3 %*/z5R;@xE$JNmSVY\R]b]Z\lZWsSNhIC=6.&2 ~kab bSΨYs쟴蝄,Ӝڜe۝e鞖gp!{#>Ӭ!roQ GKEUR]=a&;r+h@ _ TcUQ&7 g"Z$&'0)@***+**)b)(''3&/%F$v#"!  TX-8Ki  T!!"6"G"3"!o! 4 j2rW ^" $%'-*V,'.d0~2f457!88887N642d0 .+(%"Lyh} k Y5{uLq  kbi r$Z(,036k98;<==<1;8,62I/*&"/ |+ =v`ԆӝoѬАЏй0BיݢmV,rGB P mBy*.= ` zx\r"d oYIwG9oGd~T)d*  zK  F/%cy"7`il3#U _ L^7>-Rl) # 7 Y@6(_Q5|0;TڔeL'Ү]Uʝʪ˓N&Lγ3ӘAmۿ3}`P d U ~( l1f>]ߢWBKփҌ?Ẅ́3FSxu>CГ yB ;ޓT<_2(m unB`< j! % [^m}p!`Nv=f %j"i[_ #kDf.TId;cX(Q6$) C h M)]jG$$cW ~  &n-tt,}6|G&] *  '? !>#$% '"( ))*]++,,#-3-#-,,@,++*)'&_%"$"!J zhgWU/ !"#$& ''(s)**+h+++ ,++++**K)('&%$#"! |Af - w G 7uh\tS`G3Gf{+u[{<&N@8\<esw`Q( o=+9h?wv2Aa Vjs>rDt\S3H.e#DX~!L~?D&xw_:@[Ze.{_ j$~)_! gL4wbN/`8f2_E}Q9?Hfq9oOK1V M ,  1 5 , #  N M | >qX>ksA ELMjKNaypvajgS#}w+`_Hmqear`':LW"@=b19w]l)i?,\+5R^e{uu9u*Mf"2'{1IPAv#M,DoKP5 &WKM2e.8x!m!Mt : = I h q  !   n [ P E   URA.tX'wT7-|uJGPR042 #Kb{-i  0>VO2>n{}xY@5+piWj{1CSa+oU*lXM( {CZpR0 SuP^P|%Wv !Sh2U-Qm!a 1@@C@ltYdhdfjwy3t _ r ! s \ ' `   N  tj`w8 [  q  v  h 2 @\iud4 s  L M i #OCSd]"-INyV&'0^@|x+ uA2!5}U~I[^Uy6)(@bP>T_`=F /[eunPV@B{XU 6`^cpxhfS8]|)iq ;i2L*+-Fhtoeh6 vvEm 2?A+2D nD y^b^e_LOfx`_TRQiz+wW]R2\;lI [y# `xMe/T6M XJ1GeOW2BXC+z9a&UXmjG0 yjYA2}iD3! @Nm#=d-Mm&Pu.Ss .Lj4F[r{;ZttrQM.zsoSSC4-/!!'.('/(#/ * zm{~rpqSF<0#'+:11+'7@Njqv 4I^atv %8Kch,IXO| 3(#.0   y6i8"xG@JRICHu'Ob,1=3@B("$oYGYTSGW^]60"WL= (!  ,To%V9[sszgb`ahWipoa\]95@8KKcmxZHD#|hcY\aXbsy}~}xurfAC2z}pkaPQ: xP,kTH9;* hJG633N[U`rvpmfjgt| -Efx $!""r\O<`A zN>'vlTI2$ %6?d #Nk*X=i$A\v'=:GPY`m|jmgSNB8( yaRI2&+JWs>]#;XqpmaCF82n^E>6!&/>Lap00DO^mgv~ ""0,:@B:908,<--&kob[[ID24?EMT\bkt}ymk^WNHBE850&.&3;;FRRWXa^`XZWLECE;,a7X3}h^RTHMNUc}j_JD,2 !;3AMSMSP^ajt%BUjlxvyztqpaXE80#qgM@& !3)96@JPVZWRSC:-vysptqn};Hcj,;H\m!62;8H9A;>2A35"^9];}un|u ++38?H[i #2>Oc]w$#-1./7?HNN^OMNIQE=>/2$ uaM;/tYR>- .7I]s ,)/6<AZOYVRI=E76432. 1(1/#-!3(2@?FNSUZ]ZVRVNSC;.uidXI5/%   ,%%$! }i[RGN?95%" $9EJ[hq~wkVK9(#  *6AMcn4Ol('--+;2,6,==GAHPTKFIJOILEFGC<C;B:ILCLGMX]hqw~naRG3/ytim[TOPJNDHE<>21)"&&'%(,3=OXj{nT>3zj`H<6, nm_]FC/   '1.<@HFH@F@?:2/%  !  zcN7$  ,,9;LNVat~).7FQZci}shYG?( }yvlcf[_V]_chw}!/327LMU[b_bskxws}"1<FZjstz   xnc^UJODD<:@EIPXit~)7HF__hbntu{ygjOB3$ wvjuxxyuxwttkspsdljphtrqu|wy    z|pojnjhY[NQS[[^ceiriodnonjswv}qz}w|r{z~||ne`WaNG<-$ '%31:B>@:A=>66*)*& %8;:ECQHVZ\]ZWZ]aiVXF@1,0" ! |~vw~y 23>HOTlinntxywskoroqbiSO:4xwvyrZUGC.( )1;;DKV\`eg^iedgeda^ZW[[[korwu|{sxyxmiad_gkai_YW[^a`WbecXXIC67 "%.=<:IT]ow      voXQ=4&# !,=R]o} !*;775/8-5"+&%")!"*!+,EJ[ckyytj`aUYSKJAO94,#&    )76@GPO^crjrmqonvy}|nqfpmpoimfgoinkmosifkg\ZX[YRZO^DJE7F5A.+)   !!+*324:9BBLWcenx#93+(* ~{p_]YZZT`hbimnjeegmkh`\^gafsepdsihhnmeosrshfYWWWX`]l`_b[`Y_jpvbjbUZTX_LJHF652.<25624>69>?NJQKLIQANIQOQRP@@?22.,(!%-'.16*$ /,=CPf_njtu{yhPSH62-2-)8!  ! "#/#$).0.--63537:;:4>.-+8:EURIHQMCF=D>78693:;6)+(! |yumc_TYMBF:69:3)%!!  05BGXVYjo|sole[\ZUKB?5*+ !!$)-1/:55##  ##*!#%4==?SPVTW\Y\`pt|zxrmcaZLHIA:4*  -68A?BCB@FLOXW^Xbhv '#)7=7@<40/++$0*" "100=:<4<5>/A<@CEBGJQV__opu{x|s{ohmjohcZZS\SZ[b`j^\RLMQJQLQX^htzxxnsytuopjYQ:4*#     (.75IMLWVbZgntr|}k]Q;/3)% !",$,/-1'7<9IDRRSKGNMGJBNIMFJORHFMGV[Va\]^etpk~x{svj]L73$tywruaeWY]LIKMLZ[TZbn|~xzmef\Ydfmnu}|xtrg^^bWd\amlmlm`hY`[Zh]m^d_ZVULRWe__bZjYWXWbVcmiemmppqxyuwnuv~}vlh[PNA1/.!',,$)06DICCKOHLOQ[]if|| (83@8BA?SN`jwzytosmpciifjkgjdhfgfk`g\[a_SWXV_Tdca^e]RUPXMVYMZPNFHEW^aemhli{u}yqgbTac]jclfefb`_djkhcnsz}y~glaaSKF;7 #64?::897$0!'"$! }zsptqu}ywyuwi`N?>0"%".+/",*0*';'0;GJ9>LU`il  #%026?CYZaZ[ii~tzrxnnu|{vm^`fUWJHEIOR[QO`^mbsu   l_I8* pdXK>:10.-028?6;MR\a~,0=MVilvrvkis^YTDF)1&-$ $+4;>KSUWXdsahgozwonmYP1/%sn]RK5(  &5uC2 "$&<()*+7,,,,[,f+*y)E('%q$"! mkORJ^,#puT]my1 !"$&(+-/2467`8)99876$530.,)7&# F| ` ; C'Muh$,uU "R&)*-03q68:;;;:Y86T4H1-X*6&!1W0 n2*i܅؂:Ԩӎ ӵcxՎׅ_ېݨ(q(V= k-ba  "P#T)@mVznC,54Ah܉p#?~K>2_#    45Dl\uGh8C#%*% 0 N z r` @ BUl#-l* Fڑ׬#mp="__Wʍ ́mtןUxSV`$ 0 y x \tWf7)Y;׭*ԩ!.I2ͩsT\̘̾ͺ8ѓ_W=F۱NcA Gz!=SC[k9 -Vy8Y!c$\4p#.Z72pB &\zR??LNPm(~P{ Bept{vspTG=_I* gaJDIf+l&7Jd 2 W n  ( H _ o  ' 3 : 9 3 4 !  o 7  A =+7w@{>l0hDzQ@iKrQB5 .2KLY\kw}~/KZ`ausukP8!n.{7 N m9 oDHi Ek -NZas{}wm]E;,%!P `o4[q@"svly4Oq$.AYu  %7M`m"+B>A;?4# ';BOcx %Tj|,7TZlo(;Nq7Pi %4HI_j{.KYo}$<Lp$<HOapq|_R"aIjO~ ,Ic:h<vY;],o5]  }XCR z[7<Xgj:#}U t?t#><gj>^>*$  )7876@8748-lN)c+{C!roRS:@A70(4Yl:!wMl:x]<mU5rVN<8&026DG_brrzxlhbbbg^ZWPUILI<70'3JKfx'=_6V~=l>M]x} *:Mf 0;J\tx<ayylH8oP9 $  ~ri\F+Y5#w_O3sW6}kd`fbjejkxr3Wz>e=Mjvyp\S6{wmdTD.tV;nP1. #$-?JYRmtxcKC7) tXI3' ,I`pznZ9+ytWQOQNHQVin&8Yl%29G^^^_\P5*kc@. aJgJ(|hdftqy(KuUJ{ #-08440 nK, \3 oke^[H?2+ "7Vi+Ih%Lm7_s <Rx  ;G[qtvyd^P7-|_I/ %4BPgt <Mp(T_ %*(zZP7w]B!&<>Qhs !(ELdj|$%:?Q_s~gV3 peeQMNO\W\akzztoc`TTGG@<8-,)"-$!.$-0.6:KQISB=8. ~g=#k8"qiSWM[[\^cfipr*.1(3+("  %)   }jLB.ttjjhhkldac`ceirstwjusplbhelmrsqw)=Ngz.4LV\ojrursnnskh]VGH66.)# yYJ:!zp]VMLWLXYdi^x~ ',8FS_jxp 39EYisu#168G=KKP^bnrxi_RK>+" ~tQD2*<VapaJI72)!ibI?%! ~ookmmmiSL03+&'*)-/4EO[lovqeVLD75("**4&4-!'  ,.;@HAAA@FDC=<+04755+2$%*&-#$)9HOh8Rez 1@Q_r||wvmnajfnklzrxhbOIG72+" */IPV_oy 5Md}(9MShuymi]PJ.0 n^\FFD@64/ %  &8IQl}ml[ZQJA>+{oaM9%|ylaaRB0 ,62?@KGIDHTNRXW^USRICIIccmrvrw{~tsyoqf`]WIH<=3--''*08?JHILCFGPOQ`[\[T]QLOE@>,(,5KP\^hvotwuwytpnvlmgih[d_^hi||idI:($*6@NYiyxhQ>-   wxipuzy~'08KNV_gsy|rp]l`XJ>C95;4C;EKFUQafor|xv~} #,1FDOQOeky|tp^VQIDDDFKI?@>AHPIRKWbjov  ""%  zudaNHB;0981--0'&+% ")'.-78=E=HEJQLUMWXYUKQNS_]mx|r|utluqtmlf]b_bZWZ`\ikqsy~tmnhlgohwl}{lYWI?.3(,*"+-'*%!$/'69?C:C=;:=374,(!! !--/759@BIED@9FIH]Xdkss{zztxgaYNLA9. }xrheXH@33.0'"" +047=CJLPTNSPLNDE<90'}ytrrljqhd`d_`_ikljpnmqxw|w|{~ "#'+148:=FADJQRTV]`ajgjjllkho`g_]PP@9.+%  ! 21>FPWeeut|%$/+94?@DLKTU[Zc\hfeqjusx}z~%)2=AJTTcbksr|~{txjrdh`][TSNHH@=<22/$) t{npifb\]STNJHB@;:17&1!'                                                                         jamulus-3.9.1+dfsg/src/res/CLEDGreenSrc.png0000644000175000017500000013025414340334543017407 0ustar vimervimerPNG  IHDRXXfsBIT|d pHYs~uɍtEXtSoftwarewww.inkscape.org< IDATxwWOui&H03ٲ匃,ɶ1`ؽ,/&eI#.e+V6β$ˊ$h3~d+:Tթ~zKXLW=ӡ[:G3 !0CMM ]QǕv\/[hZh,!čԔcH`0WA@ʌŁ6a vhVE5 !,!555$Ә]2Bغ՝ B8,!DMMcx7@ PWYNjU  BD98$m=p),M$.}R [$` jjjryK86U !&K,QSS]x< WZi`/ڒɐ%CԔSy7P݇LϼUWWw-Iq-pQ1S/:\]jKB,! fTV$rakAq=B% XBؤVHCF`:!,!,to#@<[;QHDZP5YmEB0SZ0,!2taRTrF=$Z+eE!2#K4ԔˁǀـGmEB*lP\YGI0/Rj.S[I52ɑ%Djjj%$B@mEB(&1^XBMMXD"T-j+‘zak}uuuPq=B8,!.< T#ՅHEPzbp X" >ܤ!rnQ]HyF#<͓$uivNU"*g+VF X"o\0Vq9B䓓ρ_XIu1BAi+WtXIe*!ԉ3`+2DNZre)U#iZ?]bYa6 X"\9aVXqHu1BE +W|"@E.D1WX]u1BdJZ+W Bu?X"!!Kd+W>P\:sŊ*DXr$,Q\9ԺHy˗R]ɐ%oժUS/GY"ŀ?[|A X±VZ5 xDrF :ˏ.Fk%gժUcoj!sIL˗T]%cժU#Eɋ|ŵHjժ*+$ۺ"DH U#,̪U_ (T\"w|sIݪUʁ> ).Gz~|Vň"KfժU$ 2P!Dhaň KbժU?ƨE''T ݲe˞U]}V^}c!յ!;-[ Յ%KXbCO !G~|mٲe2^N0ի}$a:^olٲbD%Lz%?T"):|aٲekU"r,իW0Gu-B-.[BDv%Ҷzbi௑5#e˖u.Fd' X"-W^LbkBjٲeT", wZ& E*$`^/kJ2AVK.oՅ KК5kFU\BҥKT"M5kָHidQf!K.U#I5k pZ¡^>t #K\f͚5$*.G!. o;K. .F8,5k!2/]5Յg%."|Bl!el֬Y3o`Z"G<ҥKO.DR]Pg͚5D•BB44Miڛk׮}z:҂֬Ygck搉1p_YdI@u!^ڵk~ W]B,YB}$`創k׺/<"ia:UrNdM{K,.FXOVXv(/LW]}aljbb>t˅.+vxx<}o l&/Y^u!Zrڵk#`ZDnFa"eh4NpF](((ywi:O.Y ֑֮]~|Vu-"N8& ]" [riW/Gaa!\rSHO/.Y$a> X9hڵC?E8[$!  ;mJiPXXoO7x%KU"%+Ǭ]v*'Ju-9t]' ^ .M[r/ ]~_Zĕ.YdBy$`吵kcd!C0V)4 OQQGݍ21"/^ 搀֮][x\u-ɐBe*.IUXX$ίO-^8 XYnݺuNťA T%U\\W]@ŋT"'+[n.{`Z8tuuE4U]륤qݪKk>xͪ 鑀֭[Ȃ9.1THtQ\\LII S]|ŋe$`eu}Z;-T]]]'xi*))ܴ֭ ŋ{T"'+[Xܥa]蠣.i4(++ rkŋ7.D$GVXn`=0Ru-"3N\.;aTVnh-^BčI֭CbյNWW.PRR"a+u]xՅIru=Ab+u3Aww7mmmtvvJr(--eȼt)|jѢE?W]> X~z յD"Z[[iiiy^ Dyy |mѢEr"w X~U"cե!RVRR A(--V{c-Fì_~ [rgEX8Vi9R^^Nyy9,_hQBĻ$`9U"0 :::hii[u9BXAQVV&ZwXhѢ  bS5 յkbpyiy2x` #8X tѢET"$`9+YՁ0ΝUyrQ^^ΐ!CйEmR]HWr LGGRpM(--eС.G\-|`ѢE+U$`)~Q:::hnnGFϐ!C(++S]\ x|ѢES]H? S*;봶r9aYT2dexЁO.\T$`)~Xz[scaBSS \";x^***4hv…?Q]He{$fh Akk+MMMD"䅰" = ACԈ7ĉqbFXߌ8qčqq<N<\xhn\7ܚ**@+TJ8QQQAyy-g… V]D>e{Uב à& 4IHo+AgX=zKH%/$\]_(rS)=wBWԫ2|>*++8p-pBY~&lsiϨ%] VPHu)Y@=J[x]v:t*bfPi@wA 9`d60`R?[p-&b= O յ䫎 Kq^ѳĚ9m%vybFLui<{3S`Py2[A?WSdShJ鱗R:T'.\(YH{9ȢJN:EooR=JS͜|^=՟ޡ *#)r?8_~1BR_,\P,""Z~+E"Μ9C[{zNh#g" 4iWyUDo$}Po.ͭ,8p Æ .%dYC.-h+]innٳyMXmx'P!f4NѼTx1BI+lt\ :CZ`qρ',X ad25~+[s鼝rAG1@]8c%1ptӑ 1[ )@o$. 455e zϪ.$H 6l S1ب;6|1'rn| U01S0bwlW\\ׯR,X S8H6l $qiZZZTbL1jhS] FN`lDFΡ[7*//gذaxΑANV*C\,V› [fr 6AMѧ-X@1,lذ$溒- [u)҉S>ɑAֳsbB**ʪXT[H/ v߽~^?wv1 H,L0$  E;o{4E.=g;8HkOKW! '3?Qqܙr3j( Ր'  ,3$+C6ly6*FapYr@p-GB9zIQ5MheUTVQY60u9r$IF:y ;s~aτ›+# Ƥ4|6ϥi :4B: Nu!LV6lذ#r7ezzzY؛M}C6/U?_?&Ų1T Bp(ǧD[Ziz'5r38r0Uw~"&oᶢ0[K~F)Z++U$`iÆ 5@~el:gΜYu)aɛmT]E\y 0j 7WMaԠ14iKgoV739ޠw Vq{=Lw>-ֆ BUU̝etT$`aÆ Sm_u-l4oD u[qa 7UUSy&WNadhr1IwЕT[ұ^^M[*}Õa6M|9 0kTm$`hÆ dxZ[[Ubpp?oY_/D`ZrM ɓPܗ'9^ 6.QrmL0'v8o~{+4&oʞ].**b|r~|hn@V6n4 k4zKfc52H nL0&<}ST ] 0 4c;slOF֭?wKKݽ<~].#F`&U$.󿪺u7n|mMǩOk S㝼́,pbM,}9N!,ۏ.P7/ÖCxfK'Bj>n-g贊d>>.$`aƍs琉DMqN MޗW޶ew>MUQ'.6\ןS[Ꭲ{!}>FK1`.ĩ$`]ƍ{1lgrfNFPn%wzOɲ;eęxܒEZNgYJ ռ~+y%iTUU1d=wM.`.ĉ$`]ƍ+Iu5Ru-.SWWG{{RR6Bk=wLw>ۖ2HƈsΟOaϲfQ R{qotΥ՗2F%]h7o^BF6nXjNoJ7K(رcB5""1}E,m)KxMݶW t`=kx7^5}.?OӲnBƎKaaDz xp޼yZPU1 XشiUג۩.Ayei'>;ećqYد5o԰vUԒ>\Z|n7FLu)`P=o< HĦMOC#pܹsUb X7oۀUגmz{{9z(Ѩie12q|~ޗ1aI a ⭁m?d+12ܻO+`F,pnWetsTb| X?>l}`[<[ͬ ?Ok>x2݂}8&?m||co$sKQqBn1cPRRls~NuvʫyǀgTבmΝ;G}}2j^l'Nshh,O?ʋX7WݙݡL+=EPݚu11|p cD>0w?..y6o< 8a> CH{ucmwy_fG(sFzI$YDUw;g7󕕕 :4ӒF7 IDATM'pܹs}nX7ovcpRʙ3ghllT]u5EOYzK ." ,52!יSxy-m]¢Syß538bСTVV<ĝ,`|[u٤fgia_y G}Wl/7?͉s._~>rbZl?uj 6LɾΝEX-͛gL 2d%x UrPJq#Ο^ FӟelD=jzY.NH-0qj 6gΜTbX7oObMkaP[[Kkki4i`w{&hhgbw cX]* 8#G:!ds .*9l capqۓy"7^]+?dd贞/rY~1~'7&.C=zrΜ9lڲe{l:Ǐ l.r<47?$xӸ]ԅDore髨o%`ٳ\" pi=F75ݿl Z ^O Ð{oZRVSS4EkYٳIp{I۳ZV`mݺu4pYT>[Xx^ ޺<#{+|l@ gJRV~&W#F0h oC0eu IWM\u8Ugg'ǎK{f}`-),+~̝#cjM*"MNΞ( u_fmi=PPare4cRRR'<{yHW[ku8Uoo/o6勪Ӯ>z=5Čh>`$?x2bNBdM鎟~=%cov3a~sgϞߪHGV[UDHÇfvMYNGK-LX%+"3vk|m.q=~ 2v *KΥ^':nGin={9Յʣ4 W9vc} ^X&./:GN9@ZrKn_${+?u::5fj]DQN8 pݦ֓#I?Te] ֭[kUDax ne m=qm)鿟E}5{Xwqqh0̚5k"RUk֭$ʼnhiiQ]::{q4r0{?jnQ)ʦ}3|晏H馂[SW14pY[V"4i$\]Scc#UԈYNNS?y\mr*]]Er:7WYZŏ|Oޛ2`G"u1WnwkRkk+>Cں,1x,+kZmv N+rIe25yrƧM*7eVl?WrSt:zPOJ?R7j(  'Ϛ5B~ꩧTאU4===;Z~f ]-DO>EF+Ā_own%#-DVhAX, 0vOu!Ȋm۶-֨ib"I`bdeө<|v֗LJ ;. o=?My__*o|L8'FeYֶm|$qpaGU~`̈wiw ιy!_u4;N"9–ϗW~p,Ƴ z.Uc&w^1`ʬYԶ.܀kkk:̙3*ۿi4O-9üoioCN;RdfHP&WΣۈNFѣ8obb.Y:`ŖԐʁcU]H_݂m۶!$,tv?nɶSR\˱hzS1L_].5;1p9"(w_"OoI2ުѣGSZ*Y\ 0k,徃˄B!jkkSzN_d~~ohǢHg{FOKvdq'_ܓK/9>_+jnhh`ĉ|0%$2'Tr=mڶmo9$sa `MpJy1|ZϽc<>SjrBX'.v-t#PL*5L8KNЁy7Tr-m4HL]]P負d#ie#§9qKIvJ6c#>/4}J?W - hhh`jp cau\#o߾QU$gϞܹsW S}Bk04@Rzh5",zk}'WJ}[IghC]CCHo}i2 88' E|ORѼ(0u+i%d]#Ur)'v} W|.57kFYYFR<#&`~xDuNJSSz3!lX|.=!%?WRvR8|=|yLJITp4N07fνbL=ؙ3g:bQ'M%$\Jmm**]iČ0nD9! 8P㉦񷳾=ל4lyǥ`H4440~xՊHd GrD ۫ș3ɵYQӎsHs&/S3>gbEײ-e/3"5'[K4}}&ngVs KAEE0!`̙3U,MӾÕ]ʮFވQ0d.&DV>S>OLu?s}ߎ= [\).. V]~$w"+9tHWRV9?>1?A&WTI~_|x$^; 3ʒ4inwlg0a̙ *pB בp$TBF5pat<XT.!K 8r y]YJGaK*+8Z?h4ʙ3g9RMsl"`=c#8#)ɱcǔcq*^q/0) crM^Ѿ8!h|7|5mcqL(qcƌD\&͜9T $\:-`?s:^BNlFgq0}frash`ie<\={pi+Y3v i|OSԿk ѓǝSM,9P3d0.ޱ-X/kP(ġChUH~gI d?X}9硼,kag3چ JpJa.'N};L s*Z>K+: ðN AHA ~ߦl~-KYTru۔> EHq uMgKp%! si@V^x9 ҿC%;13m^  qnT1x]>O$ѻֻ&13@6%v'/dݒ g@Fʮ(ތid_ם8@4gvs_Xc1sݞ| e)))Σvж1X/+58D]]---Y?Æ3wdGM*Wew:|ifҢSv<ֵ 80HŊٱ3;cyUFbѵ •E̾i!rO I J̜0 oh;:[x_jxܶ6SoA"֎`n&A`M (;U6 ;Ɯ r9bz4le]sU5662~x[`_~ꩧ, /R^nj^~2 >9xݾ~q!n@Iˍs~JWx Sv2a]z;^J['FRXXh>~ѣkޑ]-X_Lsm+o0Zy5'kxp (+%ڒ/gȒ2suTZM^̮эS~)Q p x[hjj+"X رM[z577FMy6cj0EavTO"`)^O+ ;OqFk2h5Ք t-ΎD8u;vтypH$BSSS?oV;sz)ۺ ȟ֤<}VN[pR^k9~CW{ %ܹs 8k~D#Mt'V vQy;Oɓ'ioou=F75_%4M[ Ȑ&Tw9MBm׏xkl˫x;E9rt00:kny `_l+1"4=^*!KW)_&/FsVÛ_^Sv)**uR@"o'cS1`{ P /FpIWss3eeea$֎;*{?%F0ٚUj28n25|O%TMa?@>0!9\Z/έ3B|bs۰(*('0m{"[y/:Cz]͔ILXvܹsmfc\ohm})ۺ}{0 ϡ߉\<oa1ƥKx+:zzC?uܹ|n^~!Ø ϟ'|iT2_RL;h|QXDnv7m4@vϼ>Fyyi">ڠ&o/+ٳ-gtMgZ4;ޓѢ\NNWПH [{}?T#fXqv9ɬeVѨmyEebJ}ɽ|YIw.֊ya [8 evbSnڵk׌3f2ccf`f[wxNIܑy{ɑLD_^!n+>@a#āۺ?Yt!dČ%߄dn 0oX3jXř;5w1;\.Fxˑ$~: IDATثLMf)H$ϗw[Idg2و+/sP4_!FĒ|s\4+\4akR'sX&R%KyȔ%BUU)22`ڵX6Q,5% ^ Mj,h.̥ NdVpz^UK_cs=SQQe`%ӧOJw`-q ϟGׯDc/bo9TnOy?Nzǫ.\Z%F;˲}\JuZ[[2d-s7n iZuAKKm{q+ysRros{Esa2@>?\v|?zH+ljiiaʗQ1Tݻws}~joouYCk5^pH\qIZb^^qyK#qL=z̲}9{ɶVX,Fgg'eeeA޽liіI riZYiii1u{}]Dsxl^AU~2M/O^y*~.,h wzQZ1`Hd_LVuaY3R{ 9;Y޼3y^)o/U|(G]ӓS6<kt{6% NQWq9+>qyw[yj3} OFEEEFBw]>}HkEJa25C8B0y?U&,&E<'%|}@r <~±5z8h hoogС6C"W:OL4:;;Ŭ*Jׯf+J,=AfPG="s\EI'-!&xn1e[7 NxnJJJL_Yk>TޗCkKGࢡ֞I*YIr#?%ʒ*lXyz\3f8SZZj#{M6-ʓizg YD"tu=ke4WpNӶZ[RWX/(W *ܣmWww7hkDٚʓ XY4N& αWѤ_&h`sx;:e^Km-kkkcСA`u4-+VW]ZtTKWp U7 ʫjBCWg˾2dH v_|!'3 s]WWHJݮi})WzX}2qkt`{{& Oi5,dx0|'"ʻ\)u QN3}G[JNGGG,Hd&:}M'0?z[")ZNĵ5ͅ#OČ#1MSV2nt]l,cMڳgOMՅ3L-z 3' s{W1(wο7zD=mbev R9 ;%yi?S\0Si>!1w$жd~85?r}%JvVЦF9bgyrgaouߩ^Ƌ2wwwcF>vjUgg'۲z(qOmĪ[[T 9د)`cLe?}-zb8$mݝo3&;R4s;뤂AH\]T.E f|R,,HMg떽{|nɶ`U`<{A휧MkCiܾfǿzF 0 k]꣜VVKv}y,݄%feVKvI{0ݻ3N|.4E@ bڒwY7R?PElqr-9AWWeee)?7Ā5-ZŻv" Qfa݃y+K^(@Y,FY@ @<v[/wQ<@$ӂWW\%NN([y$nD횼וj\x<5e͌cz ^+3 `iT5Yp94m{ BII \&qӯ|r5>nحMfSqt,\X?=k0gj~ 5ݜZ݃Quf" ߮ =X܈Bnyn̬^ d40Lm-Na63`ݻbZ9K,e_Jxq#FTqegh}oN sMߩoa_߬jCGqԲuiA~%r)+:uu XMۖvڲbAy-L~Ң\x(ixLxkO'Љ"t[@>,0tQ@1"ʺ/ By`&9\2I—ZǑ| N-ñPf0!LQ׸7v <84$`X<'秒\j/ Bys a1y gk1F`} 6]Ck߾}n>q_A{::ZmJ_9G\]/\: _! 5 -B~XOw K^Sɔ ڥaCIIq:ujZg_-Xwt]]]q^k$FjsSp,haׁ8?"Kߍ,-^)k߶3qɋgͣ$oD{e]{UwWo7hd d,d K cƖrl,d^ e 6ޛ7 ^kZr3c]kfdƍ{q?sf27n.(?XVdz?臽 o~zك$^.y'.bu븂b:Hu9FNKZϔ-ͭ0HQ"}Ir8b58D4m}B}q{؀|kfh4xZD:?uzO:w]з14=R:}.mH0{'e]Eܹl (ȡ H9VVSK҅70bTU.t"?7J1<[v(=l„ Z4MCB$q4B73XZKx#eO4PkW.GF7{08&1;3zOB,^MRoru9$;vpnsj.6.4X':,gBt` a,_Y`&;:`>$Td8dב'J[k*;Rm*Ga>oT\4u>~N4QT.7\Hvn\ձQ9pO~p6Zv M $N'o.S9l8r?p>^9 w+:˅G yɥFksw}k\Lښά _ߓA+$a|{ ͡Eew_V^z95$T̡lp~"gY#5HxBm9"kyԺ܇b>ۇu;3X~ 2jUNi0`x9],%=vqzi˜<1\oۨ*C9xXfa@UM)/~1:799vN*GС e<:pfMGU888ih6nA/~񋱏}c/.<; థ%앓(ovNte'݈?O}KO}vV *ɫ,~2X*p`fUz{L{Z`%>D/&_?֡G($BC _-8;RaN=bq<4NӎG_{($>%RH>-r㒎 rC5Xl:Vˋ;M ۯz8Xvvu*.3DFM_딇j0 t>KvyTNwg1MfzC4..] YZg<}}iB4B!G!BOO8xlp Z=L%EK\rAo]^ȹȊʑi5Myaz뭌(ΦAˁeH΍m^wMO[G ?1(TiQl=WZB**-}뭷2GK%1zk{I{ƶ]Q.~%C~P{eޏ}-*S;5l /_]@KɊa}cȎnY- 3*T/Ţ^i[4Eta%!R8c.yM\O샶K Eop&.Q Gem3%AIAA#\1:Aޥj4Mc"?,^N>d=ީlaLHY1zr,'͠':7nSK 5X@wF} ಚ%ML9z'>;M>sAuکl }t9.} |7nS{wʛ`B#SDd (6,E𹋶pI',yw2as=辍:!:z^ANAEy{1c9"b[V0aBN=Xo_aj tWϗ rwdf[dZh w*}`@U)9݋3Xҗ4|$EQ|<t .,XNyc}X&LCX2|lñv?U|(5 )+Mi wD$PWxr]8lpk2ɥsne.ȓC/LEwΏY>3XK|l Fו 1,c9z36 W.J,geαj膆z B5 s$N1BdWZܮC,(?͐)r;;*(!6kWV1GF75䠕VfWVnu )M/nYvO b_ԱV|9U>Ԕ24ͅ˪1/ˊ(@4sw-yV 0pH<` ArF.gvhMg'UXXF/z~_V,4a]fjM2v=L%EKq1.R~&Lqx]q$0M˄#AdyЪs[MδQO1a爵ZKDw&窗6h{;5G8`T8[1X<)B=3Zk@S%aՋ#wk2J3`y^kE^<ȽO} o~uP "}vyK)p :}?酶$YKuX/=uO Hčrr|!r1m' s6^`9# e:J4si!3c&.*mO̰y+DfE?W߃fv<~,iXY0˥cxfMiTl\ɴ/_!/>j; w'1Tv9T|7 ڍM0Aaz41 A'QY`fxbu\]Le7.W%'fUenHzo,+:j aY%±('=A% (F!HX3oV!6#~}\\"CtkhlؐÅH h>2X 0.r1޾Xm#scl]SlQoN58nn+M`E¢UGvc`&H3~TJ{w}<ɒ|16<ʿ|.kñ_o kr.Z"ăܻ'н-r(皘3]wcRp38l3?ǒhŶZSK̞IH.oI&tV Og3HG3|rB `Āo9֋1DD"m!76J\f^Zˋ=*G1Uаo6-T+TTWM;IIUBOvˀZha'Z i{ ulr,h+3X;AVXH_e̡!קD{u?Tbɠs`^H75ϽW'?6=ˣMw$SNUqxEQt *=XVZ WFSœܸ$;i-ȡ7HUbT%;=O_0U}GT"V89?C*tb"s8fV,P4[I$q3pQ$VY/"J!9'uOApo)"eģmv16],`zK1 {4^0B>UMfa.e [0QZE]bXbfaX5i$fH"[(F>bІMoQ]49m8 \tg &.G<툖A3Ka Am;O' UX)ҩ` =Ġ?޺No,·IZ k&)`?+(7X`-.$&WDKZIP\*[8Gacd$ E-,tg;m+/ jnV(*m( <\'zD!tMCrnhx\mD}KH"P1&6OQhx*Q!f.ذEIGr٫-DQޭ=#4[jJ&( U[yhubbf]K]^}K, 5G˃^{8]pP(v{S)'= VRzSZ > }-~țˋE5wVK>{c&N_mկ%+'(& ƢRYJz'sctkULEb55e lYW_}5oWx~ce̲rŵ4T3CqZNnv{(w N! %N2MvV&LW`:[Whyꫯ 4 t (HTBϣ 7zӖNmPc b Vs=PI}rXU;eGM[ǦSGAF׏prYO RˣuHPSF]b$SS3O>Z"|Re]D"֣ʕҲ#ò};L(PJL J{0[n!Wɡ #T]D^lbi#{X8 `yh4:Pa+XRa6F{vFQ180h㲤Jlf4 ;EEaiش>eG |AQD"Z-GIj#EƎ.=D5::82,b}6“~C\.si%\^覎JJ< \ '% );_~`(F mi)m$Q-F@p`R~%!)̉Ak.)3.^@NVĈ!lF85(˄rtg6gR[o !5tx`] r%x)7;FvL,+mlZ|K|<\4u޽;S':؁I‚- Ɏ!:BUD*A2>QI b|[(ޖ@]BSwA YO\?6ay V޽{㿜 id!쒘@ vNPPjw\DN5 Nmmve`hk_5&EP0임M36[ 30 ET%$B)BTJK]7g&fP1::d72)M:\UU?S{/2X ^;FLK!lDN 0&VAU L L"7kAn|:ZNEs5؃m/g Q$hyeEyqDQ4 ɴ'pݶj(ăIă 3Q=8./s9ihuԵ˨.JJ pAI.h Ny3Xp"^F:8Y1X[ @(Qt $b{:r#stk54}33AYmK:>:+Aقʴ'? ٶFG D1ăIDp ]=[,',SE3bsz'*㰑MNN!5x0(%Dգm5Ǻȵyrlơ0\E"?]`ۜ"D"fU6ȴ'5XM3ծcvPQV#">n'7#KCah-&ZFŽv l+`ɈWvQ,Vqne3XWgggb͍/3Lw1Z-T;eE8E$qIx33mDKocOGzjqTw>o3E< i(Fy=E,$^Gu&!5H E[0u&z -r[ّ!B4 c񸟖-`=Pp\` 0v_> &hdQ N-kB9ad;f EQQ#"Q{ .4dzK1acKF!2ZpV`6}sB!ǞO ݻw{]J4DNtZӨ Dl!&M-@@P !T)!WdI@3;mx19^rUw_ys`q,OoF[Lg$b!h9сft}(!jA%$Wx2D˅χ PiFy>\'VHr[4ޙe +\2%73&G AS-s#ĆSh@t?kj!%D@9%pPc8f̔4Ska !d"̘ օ /D"ug;C )8w4reRkFF J%Ȟ.bZ_9&tSaꗚU^bsw ]RTUO9u9xJtF88N/t/`"VMKsulX TEPPTE=a:oJԟFVbOb>\ gry}X>zW69G% uQkM3MCr 02\20WD0bv |/4^&<6N]b^r^^;#9r#l+~kvg"Lbک=A-T"!7~u}4aPMrύ Sf„iKMӉؚl,@P9A jH$.A/`E"B!h1hiBeqr =~ɍ z9/MЫyP3ޙa T /\~ ⠓$p W~x:LauFyh !)ʫЪXȠ)<Rz;wwRU( p y$׽!G|^H# Y ,3K\ D"\"»wsʭO ^*9t9K HY2k_+BL?/d2F&|Xs4-w#5nAyL*.i,z;`aUkrM籟`y+JAfK8ToΝ;0w@0D2DZ󃘬lk !#.>3d93id!4 lD1qygvn߾7֒,G@:>gT`1& b, ldAcZ ./d24`ieϪ=`R)${?T7"_;IQL` b 6OI6[];>]=+d` !CUU$IT*JH u9RK܀FN32Xd-`=6tɼ52DYn\4C p .( A o˄#񚽐 `idGXv !J$~\_`U9.N-N׮b?%-Ԉat劝Z=W i&JE/bmC{lx<{| FL fW uƃ=$L& t.9K4Bc?^ihY^ sidf @q-qy[^sAgL&\.% 6@o@pf{-- 2 T*9.ca >\ O螺m\A!oAr@デހFO ug5>­Hea ֿPbPDZKz(5XLZ_<z"kKU u~JX 0>1p.ݺu-~d2nk1DGpjz͓x8{h06tT_:߿y kC>3Xd@sIot'<  /MUvgd=\Y8극nng`2X*nDQ sIo> ]>Ekĺg6FO وÕZ^a>8AyfÇ n%p3XbrwhZjX"p&kg]E[P.@nnݛ7ou g3Q׹w|;#+:{ƍc`4M(EZ+~)t/?#4H# 97Bߵ8 pKKQ,7 L&QV4˜.`;Kz}!_$=0yn0՛vq?;t=o}휻qFѣG >mdYn fK+ϬBS;C}9Al 7I#6llczdzWy ۗ V,C,C^ax y79A!gbid6?_&Ч=‘Hί `&繆l6`5썬hqK jr@s6QQm~hBFsu0<\٫6L ֍7=D2D8FfJ axco3M  $6m"Mr(k`Q7n05a{q+O0yU9id%6Ubq-ٚwĽ0f 45GwLt]ˌ(ğ#:+'XYYa˟㌟IEQ0::CnifWO疦 FV >Y{61֚GFF*i,`<o"Gvu 4,CiB $7zid]M, ۽(^ 4 $4 F0qǏ |Pccc|Fiةظƕʵ3AKz"4Mu!.l35gB{FFF|4xrNh4|h|>NGEQr Z)Fj0yŅUd ⃟lc|w;| `' x &Ya !ncmkҴ ]ݣ;Z$Kw8>22]kee|Qvggx0YZƳaa¤?ib]4.Mt2p] BH$|'$?¼{>4cccx(X>|g-M~dи!M,gW#dFr8@ףSw`7׃~+nzrr[[[\⨾b0r3иy:v?ژD}s(4sׯ_w;G7+O'ӡJ4E*Btkxg1]<<Ž_Eid{؀JCM$D|94OLQugO>Z0Ox/1/] =E,7IW:dqk|TUE6&A~.+ifrC}~ҩUۨDC}xz@Jl#ҭqTKj4t aME19P{ɿO(ibccTQ ]LIpH Y\⢩ oF}g ^!Ӊ R̃k NL|8y+x~"*+,13Wl6wst=p'O|$F4D8 ~#{"/y#+qP1W"2%W_:x^e3c||ӽ!9?h hl`0ɥXi#;@1}̱Y^W]/3XAto Qmj,sxpZDKИ@gB5>gmd2)^[^vF 6uumuu#^iRd||zLla9lr; Lr!rF.$UU~1?\|g0&066>Ǣ!VP؏EksGFy赲A61_-FFFznp["d ;ېD$E aps[BA:9'׮]ek J###VhӞίϡl/xpG2r@녧sd#)CTlcP(T*H.@spG &״Z-!~>vٞ$| W "̡>'#}վܩ)|_zwz \oy>DdP*>J \,|+I<=D܌k?RmR"GB6?/ @EQ`isbo1'xǒ`jd%|%&]wuKt ^]z@Qfw_qPUt~U.Mv||3+m>۸b\5F:hHBgӧ=BEA5:X6cy $1v+^'Hp^W^k"P0X pn}?OD@@HY=X!FKX#"rcKWEPc@TDQdYy!ӹ5e8r'$`;+5br!چ#~$\e2i^DSzӧOlF&TVX|:6JA/OH#Kl}r~$OW^- DO>D„h-4 0 CH›\#-Bb%FPr-Ts }T_8Ǔ+`jjJ5W^%q$OhTV88SO.ZvG;԰w@-H,"'2{!po#ńi>A*sC` j82ڲ+\rN4¸):|. pX^^reP4X,BfG}fU#̢~r)DeQX,&][^^hAlCr9hێ^ӏ<:v&7N$<2]t0CL;bps =1 $!;kkk?@et:q0Ҭa4UI\B=JLc)P brrRƻ:ϧhA`M{ S{Zh|,{f|f1[UI@/{) Uh:+xW3!!D\ƈ2%AE/DF>GT3x2ʉCϕvw@zYDOOֳOB1RIRd2B5\ZZq"z.;qKgϞPu. @÷.--hpMuPjY B'gۡ/&e%qwt' =4U I#OQLLL k;KKK,Zd^5-w Z LLT-Ɠ].z"됕'dOŭO RlV^|1:ז- 1XS3:(R,Q(.9=hܗQNʍBDK:n} !]Fj7E V Dkժh037DGZh<. $ dY2 RE`@~sL>ͦh)+`lm>FsWװpxODQAoYZZD,X__%!ZE gn8?ݩeHN6Cg. 0# abbB_^\\N"ŭkݥByh=.T66SJ$}paQ   D ~Qr,..~4XhTix; )6ϥu'2$cv\(FjWdEQ099P($Z ekqqD,W\CFev$X oA tDˑ}d$qcH6GEKy8Ѩh?%Zİ`-{NBT*r9G=LfՅ/bwŏ{kD<$wZ 7?XNl6DB]=.ZȰ`DLT#,NꄚxE4#Nۺ)8S h)/,B;x`QZ(S,Q*Dx`uKŭ?0kPDf;Q|At:t:-ZuE 666CtZA<*:Fc}+(q X-"&G\0Td22wD ' lll}?$ZurhvM;ȍl Tb,z /-`|nY\\a"X%UEkjgާ?{zʒXyC g30@x<1|paa%Z BX)(ZuL! X2-WQN2{+V3dI/2I,ホN:bllL苫 h,R.?.Z uLCW7P.̫۲H[BlI"ǥ O.,,YVޒw-<%Cb՝%dS(|Hs5.,,lO,6hnx,h66ϖ .$IOzX:%K\?/Dp,:܀irn|Īx:vfƟ#ApPH"CUZ1ULUg`(A2-ō|gD lmmm4M0 syb{nirX3%&94UIg1*-EUU!F~r~~D VFZF!t]'/ 6w! U-E6u E̳[/26K&&& DKq#U;[[[S`F:tDKI'{͢)HlqJ+۽PP(h)ndƗ >B(brɫuRЂmRBLP cvEK7F|C` íyRQ/Ct;sh)/C+%&9&F sٻN-LCpb ߘiZDk[[[;íeJ%2,QM7sͨ73jOHL+HVDKD&A:-$ZHڊs7y^# uTLG7c@Xi A=MEQ0::x<.Z*OG 7X Lv#;#7v$ W RLcELb9G8, Csss뢅Floo3;MߏiEj؛JHX[F&R F-2r3; znnE 4X'?*Z)_-J{3Њߴ/ >{DZ F2!Z@ sss?&Z:W9ZN@>8HLDnlS2D2A-k˹c1bttXL/k9i*# F}]t%=MlhrFx톘$br$C?X"T]A8Cddv6|7%Hu Z1M\FCr8ܐX$^o3~e 066&OaD 4X}@( T*(e hr MNmH`VFG 8ΙR&e_7;;h!_p+AZ<4͝AZ5Ƿ`*[f b19G1U1A-"ZP!q~hBi~V` h)C 5q4 q ˢ~rT#l~/dE<G6!=?'ZeΏ:DVCPpEƷ߀jY{ע`'Eͻ&HE(l6D=\hԑ;;; _𝢵x MӐn;$(e\G3_L ؅ )L*Ea!;<Klf}";;;DkR rY &R9Mn&uȾ'fO<%$*tLF /o|쬵){# x ZFB.s]hEMn}tl{A@pcK45CndwG>1;;--H5 ;;;Ѝ5.Z =Ƿ|hb]19̉6RO2eȍr㳳 i`gg~_ gfi$J(07܄j_Ah٬9 idggOuaZi(V0h(>Cq|8g{=CpfI&ePN߹ [gffļ4X6wHn#ϻ>C4ewP@L{]j@ #]D67hݛQa"_-ĭHeݿ 4MT*J%Wb*GezЛGP -TqQ!.CQd2R)_Zqfffh!nF,~ [h|>f)Zz:rvd7ADTG]h2̌&`1bww{h~ZX,0C^@7<"za=֨ Άm| -`-PP6j8rk8O?a0)\`A0g3[؃o;!=D'7~?#"p(k+QZBHml #߀l i{#ƞ1chc5{xƞGi ^ncoQ~?ځ>DtT ( Ag7Ek8T|iҖ 0n:fT ) 7q͍cZFDvik*X)fT * <hF677p;"/V(b޽Zn?|> aB ﶙnȂi"ʞzsæ  x<YduZ"nxFkݦ\Lq;,(G,hƆ::+p޽xZ6jc-\iADV/,rjvM٤阎#27p"M￁rk:XTlX,&GKLg3 4MͦFd)x^VVVXYY4s<\jQ*X6T,ChGԨ8ht/rzfTlX,zv|ױ3 hZ4Mm^*XYY!jʙ>ܙ܆TlX,^|HvVEb H$B4%ы5nr"buUYdwonnlm={hwx[6<=,(ǀsMgUZNGeKRgpH$Rf-AdTT*ywz.^7-[nW[XTPhZAcF]l6è`9XT k,2_шN3-\t$Y ?-TpXTP >i: ÕJ Gm.nWӉK BD"HXޚf3DvOk J0^Yי"fiv}ӑEB TAl6#!NkJ[Zr&<`BLzmll`-RtkSҗ"1zz={0ԞTrcm 2;*XKT*e/1Em0Wz`a]T4IeJ| 2ɔLRZRrj:8x< ]еSχ?*VTead2z-x `-r|)`,-['hiG׋=@[DfpS&yt,(a; CF~xz}g9:{^7-P}"sYod2"rهW\culqP&u.2r灗""?d25DG-YDD\ʕhۀOqYDDL1|t1C96EDdl_k 9*XB\wwcvNu1ܓN_̌ L k;""0?I3DAej`8%7GD X*Wr,`ɶ.> t.pC: b?mMہ8""vz6TSX^f8iO7L{S[[[H""`U]ts3`ɋn:Ȃ|5NMP]Y[[{ YD@{9 -Tk`ɮU*_ !7_R aęTU*3ED,}=J6DMKfR0KH;J}tYKff`X7GDd'ֱYUd4%sQT2XG\3J@9,JJo""2mTRT*|tqIR`:,?,YJk8p7JuMwPT*IED ǑmhSLY-dtq,1Zf?n†`4dR ,1Zs@pqdÈ`mTs?fӈ N&"` U W3EԆ$gM9 VZhR9j| x2/aD%WVcmp%:qV:L&1FtT1K[ï#"xd23aDvBKZ7 p>L&u8 8VZW#6MR%0"%KV] oXO$o#rTdj;#"gjD"qtYQTr9^>H$È̚ ,ZÚ6|'F̓I17H$CyDFK\Vw`j]h8<5Z@"(#*X:ZkTrt jamulus-3.9.1+dfsg/src/res/win-installer-welcome.bmp0000644000175000017500000045566014340334543021475 0ustar vimervimerBM[6(:z[ . .̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M̪M˪M˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪M˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪M˪M˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪M˪L˪M˪M˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪M˪M˪M˪M˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪K˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪K˪L˪L˪L˪L˪L˪L˪K˪K˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪K˪L˪L˪L˪L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩K˩K˩L˩L˩L˩L˩K˩L˩L˩L˩L˩L˩K˩L˩L˩L˩L˩K˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩K˩K˩K˩L˩L˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˪L˩L˪L˩L˩L˩L˩L˩L˩L˩L˩L˪L˪L˩L˩K˩K˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩K˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩K˩L˩L˩L˩L˩K˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩L˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˪L˪L˪LʩLʩKʩLʩLʩLʩL˪L˪L˪L˪LʩLʩLʩKʩL˪L˪LʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩKʩLʩLʩLʩLʩKʩLʩLʩLʩKʩLʩLʩLʩLʩLʩLʩLʩKʩLʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩK˪L˪L˪L˪L˪LʩL˪L˪LʩLʩL˪L˪LʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩKʩLʩLʩLʩLʩLʩLʩKʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩK˪L˪L˪L˪L˪L˪K˪K˪LʩKʩK˪L˪LʩKʩKʩKʩKʩK˪LʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJ˪K˪L˪L˪L˪L˪K˪L˪L˪L˪K˪LʩK˩K˪LʩKʩKʩK˪L˪LʩKʩK˪L˪LʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩKʩKʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJ˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪LʩKʩK˪L˪L˪LʩK˪L˪K˪LʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩKʩJʩKʩKʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJ˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪L˪LʩK˪L˪L˪L˪KʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩKʩKʩKʩKʩKʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJ˩L˩L˩L˩L˩L˩L˩L˩L˩K˩L˩L˩L˩L˩L˩L˩L˩L˩L˩K˩L˩L˩L˩LʩK˩LʩKʩKʩK˩L˩LʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʨKʨJʨJʨJʨKʨKʨKʨKʨKʨJʨJʨKʨKʨKʨKʨKʨJʨJʨJʨKʨJʨJʨKʨKʨKʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨKʨKʨKʨKʨKʨKʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJ˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩K˩KʩK˩K˩K˩K˩KʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩK˩K˩K˩KʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʩJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨIʨIʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨIʨIʨIʨIʨIʨIʨIʨIʨJʨJʨJʨJʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʨIʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩK˩KʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʩJʩJʩJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʩJʩJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩJɨJɨJɨJɨJɨJɨJɨJɨJɨJʩJʩJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJʩJʩJʩJʩJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩJɨJʩJʩJʩJɨJɨJɨJʩJʩJʩJɨJɨJɨJʩJʩJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʩJʩJʩJʩJʩJʩJʩJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJʩJʩJʩJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJɨJɨJɨJɨJɨJɨJɨJʩJʩJʩJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʩJʩJʩJʩJʩJʩJʩJʩJʩJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʩJʩJʩJʩJʩJɨJɨJɨJɨJɨJɨIɨIɨIɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIʩKʩKʩKʩJʩJʩJʩJʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩIʩIʩIʩIʩIʩIʩIʩJʩJʩIʩIʩIʩIɨIɨIʩIʩIʩIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIʩIʩIʩIʩIʩIʩIʩIʩIʩIʩIʩIɨIɨIɨIɨIɨIɨIɨIɨIʩIʩIʩIʩIʩIʩIʩIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨHɨIɨIɨIɨHɨHɨHɨHɨHɨHɨIɨIɨIɨIʩKʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩJʩJʩJʩJʩJʩIʩIʩJʩJʩJʩJʩJʩJʩJʩJʩJʩIɨIɨIʩIʩIʩIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIʩIʩIʩJʩJʩIʩIʩIʩIʩIʩIʩIʩIʩIɨIɨIʩIʩIʩIʩIʩIʩIʩJʩJʩJʩJʩIʩIɨIɨIɨIʨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨJʨJʨJʨJʨJʨJʨJʨJʨJʨIʨJʨJʨJʨJʨJʨJʨJʨJʨJʨIʨIʨIʨJʨJʨIʨIɨIɨIʨIʨIʨIʨIʨIʨIʨIʨIʨJʨJʨJʨIʨIʨIʨJʨJʨJʨIʨIʨIʨIʨIʨIʨIʨIʨIʨJʨJʨIʨIʨJʨJʨIʨIʨIɨIɨIɨIɨIɧIɧIɧIɨIɨIɧIɧIɧIɧIɧIɧIɨIɧIɧIɧIɧIɧIɧIɧIɧIɧIɧIɧIɧIɧIɧIɧIɧIɧIɧIɧIɨJɨJɨJɨJɨJɨJɨJɨJɨJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨJɨJɨIɨIɨJɨIɨJɨJɨJɨJɨJɨJɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨJɨJɨJɨJɨIɨIɨIɨIɨIȧIȧIȧIȧIɨIɨIȧIȧIȧIȧIɨIɨIȧIȧIȧIȧIȧIȧIȧIȧIȧIɨIȧIȧIȧIȧIȧIȧIȧIȧIȧIɨJɨJɨJɨJɨJɨJɨJɨJɨJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIȧIȧIȧIɨIɨIɨIȧIɨIȧIɧIɨIȧIȧIȧIɨIɨIȧIȧIȧIȧIɨIɨIȧIȧIȧIȧIȧIȧIȧIȧIɨJɨJɨJɨJɨJɨJɨJɨJɨJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩKʩKʩKʩKʩJʩKʩKʩKʩJʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩJʩJʩJʩJʩJʩJɨJɨJɨJɨJɨJɨJɨIɨJʩJʩJʩJʩJʩJʩJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHȧHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHȧHȧHȧHȧHȧHȧHȧHȧHɨJɨJɨJɨJɨJɨIɨIɨIɨJʨJʩJʩJʩJʩJʩJʩJʩJʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨHɨHɧHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHȧHȧHɨHɨHɨHɨHȧHɨJɨJɨJɨJɨJɨJɨJɨJɨJʩJʩJʩJʩJʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩK˩K˩KʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩKʩKʩKʩKʩKʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHɨHȧHɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʨJʨJʨJʨJʨKʨKʨKʨKʨKʨKʨKʨKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʨKʨKʨKʨKʨKʨKʨKʨJʨKʨKʨKʨKʩKʩKʩKʩKʨKʨKʨKʨKʨJʨJʨJʨJʨJʨJʨJʨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIɨJɨJɨIɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɧIɧIɧIɧIɧIɧIɧIɧIɧIɧIɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɨIɨIɨIɨIɨIɨIɨIɨIɨIʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩJʩKʩKʩKʩKʩJʩJʩKʩJʩJʩJʩJʩKʩJʩKʩKʩKʩKʩKʩKʩJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧHɧGɧHɧHɧHɧHɧGɧGɧGɧHɧGɧGɧGɧGɧGɧGɧGɧGɧGɧGȧGɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩJʩJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧGȧGȧGȧGȧGȧGȧGȧGȧGȧGȧGɨIɨIɨIɨIɨIɨJɨJɨIɨIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩLʩLʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩJʩJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨIɨJɨIɨIɨIɨIɨIɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧGȧGȧGȧGȧGȧHȧGȧGȧGȧGȧGɨJɨJɨJɨJɨJɨJɨIɨIɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩLʩLʩKʩKʩKʩLʩKʩKʩKʩKʩKʩKʩLʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨIɨIɨIɨIɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧGȧGȧGȧGȧGɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʩJʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩLʩLʩLʩLʩKʨKʩLʩLʩKʩLʩLʩLʩLʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIȧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʨJʨJʨJʨJʨJʨKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩLʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʨJʨJʨJʨJʨJʨJʨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɧIɧHɧHɧIɧHɧHɧHɧHɧHȧHȧHȧHȧHȧGȧHȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIʨJʨJʨJʨJʨJʨJʨKʨJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩLʩLʩLʩLʩKʩKʩLʩKʩLʩLʩLʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʨJʨJʨJʨJʨJʨJɨJɨJɨJɨJɨIɨJɨJɨJɨIɨJɨJɨJɨJɨIɨJɨJɨJɨJɨIɨIɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɧIɧIɧHɧHɧHɧHɧHɧHɧHɧHȧHȧHȧHȧHȦGȧGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʨJʨJʨJʨJʨJʨJʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩKʩLʩLʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨJɨIɨIɨIɨJɨIɨIɨIɨIɧIɧIɧIɧIɧIɧHɧHɧHɧHɧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩKʩLʩLʩKʩKʩLʩLʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKɨKɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIȧIɨIȧIȧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHǦGǦGǦGǦGǦGȧGȧGȧGǦGɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJʩJʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩLʩLʩLʩLʩLʩLʩLʩLʩKʩKʨKʨKʩKʩKʩKʩKʩKʩKʩJʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨIɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨHɨIɨIȧHȧHȧHȧHȧGȧGȧHȧHȧHȧGȧGȧGȧGȧGȧGȧGȧGȧGǦGȧGȧGȧGȧGȧGȧGȧGɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJʩJʩJʩJʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʨKʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩJʩJɨJɨJɨJʩJʩJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨIɨJɨIɨIɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIɨHɨIɨIȧHȧHȧHȧHȧHȧHȧHȧGȧGȧGȧGȧGȧHȧGȧGȧGȧGȧGȧGȧGȧGȧGȧGȧGȧGȧGɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʨJʨJʨJʨKʨKʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʨKʨKʨKʨKʨKʨKʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIɧIɨIɨIɧIɧIȧHɧIɧIȧHȧHȧHȧHȧHȧHȧHȧHȦGȦHȦHȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʨJʨJʨKʨJʨKʨKʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʨKʨKʨKʨKʨKʨKʨJʨKʨKʨKʨKʨJʨJʨJʨJʨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɧIɧIɧIɧIɧIɧIɧIɧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGɨJɨJɨJɨJɨJɨIɨIɨJɨJɨJɨJɨJɨJɨJʨJʨJʨJʨJʩKʨJʨJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʨKʩLʩLʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʨJʨJʩKʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɧIɧIɧHɧHɧHȧHȧHȧHȧHȧHȧHȧHȧGȧGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʩKʩKɨJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩLʩLʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧGȧGȧGǦGǦGǦGǦGǦGǦGǦGǦGǦGɨJɨIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKɨJɨJɨJɨJʩKʩKɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨIɨIɨIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧGȧGȧGȧGȧHȧHȧGȧGȧGɨIɨIɨIɨIɨIɨIɨIɨIɨIɨJɨJɨJɨJɨIɨIɨJɨJʩJʩJʩJʩJʩJʩJʩJʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩJʩKʩKʩKʩKʩJʩKʩKʩJʩJʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩJʩKʩKʩJʩKʩKʩKʩK˩KʩKʩKʩKʩKʩKʩKʩJʩJʩJʩJʩJʩJʩJɨJʩJʩJʩJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIȧHȧHȧHȧHȧHȧHȧHȧGȧGȧGȧGȧGȧGȧGȧGȧGȧGȧGȧGȧGȧGɨIɨIɨIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨJɨJɨJʨJʨJʨKʨKʨJʨJʨJʨJʨKʨKʨKʩJʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʨJʨJʨJʨJʨJʨJɨJɨJʨJʨJɨJʨJʨKʨKʨKʩKʩKʨKʨKʨJʨJʨKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʨKʨKʨJʨJʨJʨJʨJʨJʨJʨJʨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIɧIɧIɧIɧIȧHȧGȧHȧHȧHȧHȧHȧHȧHȦGȦGȦGȦGȦGȦGȦGȦGȦGɨIɨIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʨJʨJʨJʨJʨJʨJʨJʨJʨKʨKʨKʨKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʨKʨJʨJʨJʨJʨKʨJɨJɨJʨJʨJʨJʨJʨJʨJʨJʨKʨKʨKʨKʨKʨKʨKʨKʨKʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʨKʩKʨKʨKʨKʨKʨJʨKʨKʨJʨJɨJɨJʨJɨJɨJɨIɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɧIɧHɧIɧIɧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȦGȧHȦGɨJɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨKʨJʨJʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʨKʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨJʨKʨKʨJʨJʨJʨJʨKʨKʨKʨKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʨJʨJʨJʨJʨJʨJɨIɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɧIɨJɨJɨJɨJɨJɨJɨIɧIɧIɧIɧIɧIɧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHɨIɨIɨIɨIɨIɨIɨIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʩJʩKʩKʩJʩJʩKɨJʩJʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIȧHȧHȧHȧHȧHȧHȧHȧHȧGȧGȧGȧGȧGȧGȧGȧGȧGɨIɨIɨIɨIɨIɨIɨIɨIɨIɨJɨJɨJɨJɨIɨJɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJռsƈʩJɨJɨJɨJɨJʩJʩKʩKʩKѠԹmʩKʩKʩKԹmѠʩJɨJɨJɨJɨJɨJɨJӸlџɨJɨJɨJɨJɨJɨJɨJɨJņņɨJɨJɨJɨJɨJɨJɨJɨJʩMӣг`ʩKʩKʩKʩKʩKʩKʩKʩKʩKʩK׿xņʩKʩKʩKʩKʩKʩKʩKɨJɨJջrNjɨJɨJɨJɨJɨJɨJɨJɨJɨJջqҡʩLɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIȧHȧHȧHȧHȧHȧHȧHȧGȧHȧHȧGȧGȧGȧGȧHȧHɨJɨIɨIɧIɧIɧIɨIɨIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJֽu˓ɨJɨJɨJɨJɨJʨKʨKʨK߼׾xʨKʩKʨK׾x߼ɨJɨJɨIɨJɨJɨJɨJ׾w߼ɨJɨJɨJɨJɨJɨJɨJɨJΙΙɨJɨJɨJɨJɨJɨJɨJɨJϱ[ʩKʩKʩKʨKʩKʩKʩKʩKؿzɏʨKʨKʨKʨKʨKʨKʨKռsΘɨJɨJɨJʨKɨJɨJʨKͭV޹׫ɨJɨJɨJɨJɨJɨIɨIɧIɧIɧIɧIɧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȦHȦHȦGȦHȧHȧHɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨJɨJɨJɨJNJɨJɨJӸkʪNɨJɨJɨJɨJʨKʨKʨK߼׾wʨKɏɏ֫߼ɨJɨJɨJɨJɨJɨJɨJ׾w߼ɨJɨJɨJɨJɨJɨJɨJɨJΙΙɨJɨJɨJɨJɨJɨJɨJӸkήVɨJʨL۵תʩKʨKʨKʨKʩKʩKʩKʨKƇʩKʩKԺn˩MʨKʨKʨKʨKʨKʨKȍʨJɨJҷi̫PɨJʨKʨKʨKʨKʨKʨKջrņɨJɨJΰZɨJɨJɨJɨJɨJɨJɨIɨIɨIɧIɧIɧIɧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȦHȧHȧHȧHɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨJɨJɨJɨJɨJɨIɨJɨJɨJɨKɨJɨJɨJӸkɨJɨJɨJɨJʨJʨJʨJ߼׾wʨJ߼ʨJɨJɨJɨJɨJʨJɨJ׾w߼ɨJɨJɨJɨJɨIɨIɨJɨJΙΙɨJɨJɨJɨJɨJɨJɨJ̕ԦɨJʨJʨJҶfʩJʩJʨKʨKʩKʩKʩK˫NʩKʩKʩKʩKҶgʨKʨKʨJʨJʨJʨJʨKʨJʨJʨJպpʨJʨJʨKʨKʨKʨKʨKʨJʨJʨJʨJͭUɨJɨJɨJɨJɨJɨIɨIɨIɨIɧIɧIɧHɧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHɨIɨIɨIɨIɨIɨIɨIɨIɨJɨIɨIɨIɨIɨJɨIɨIɨIɨIɨIɨIɨIɨJɨJɨJɨJɨJɨJԥΙɨJɨJɨJɨJ߼׾wɨJɨJɨJɨJɨIɨJɨJ߼׾wɨJԥԤ߼߼ɨJɨJɨJɨJɨJʨJɨJ׾w߼ɨJɨJɨJɨJɨJɨJɨJɨJΙΙɨJɨJɨJɨJɨJɨJɨJΙΙɨJɨJɨJ̭UʩKʩKʩKʩKʩKʩKʩKͮVʩKʩKʩKɨKƉԥΰ\ɨJɨJɨJɨJɨJɨJɨKɨKɨJɨJ߼׾wɨJɨKʩKʩKʩKɨKɨKɨKɨKα\ΙɨJɨJɨJɨJɨJɨJɨJɨIȧIȧIȧIȧHȧHȧHȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHɨIɨIɨIɨIɨIɨIɨIɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJ߼׾wɨJɨJɨJɨJɨJɨJɨJ߼׾wɨJɨJɨJ׾w߼ɨJɨJɨJɨJɨJɨJɨJ׾w߼ɨJɨIɨIɨJɨIɨJɨJɨJΙΙɨIɨIɨJɨJɨJɨJɨJΙΙɨJɨJɨJ̭UʩKʩKʩKɨKʩJʩKʩKͮVʩKʩKʩKʩKʩKʩKɨKɨKɨKɨJɨJɨJɨJʩKɨKɨJɨJ߼׾wɨKʩKʩKʩKʩKʩKʩK̬Q߼ϱ\ʩKɨJɨJɨJɨJɨJɨJɨIɨIɨIȧIȧIȧIȧIȧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHɧIɧIɨIɧIɧIɧIɧIɨIɨIɨIɧIɨIɨIɧIɧIɧIɧIɧIɧIɧIɧIɨIɨIɨIɨIɨIɨIɨIɨJɨJɨJɨJɨJ߼׾wɨJɨJɨIɨJɨJɨJɨJ߼׾xɨJɨJɨJ׿y߼ɨJɨJɨJɨJɨJɨJɨJ׾wɨIɨIɨIɨIɧHɨIɨJɨJО͗ɨIɨIɨJɨJɨIɨJɨJΙΙɨJɨJɨJ̭UɨJʨKʨJɨJʨJʨJʨJͭUʩKʩJʨKʨKʨJʨJɨJɨJɨJɨJɨJɨJɨJʨJʨJɨJɨJ߼׾wʨJʨKʨKʨKʩKʨKʨKըҡѴbʨJʨJʨJʨJɨIɨJɨJɨJɨIɨIɨIɧIɧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȦHȧHȦHȧHɧIɧIɧIɧIɧIɧIɧIɨIɨIɧIɧIɨIɨIɧIɧIɧIɧIɧHɧIɧIɧIɨIɨIɨIɨIɨIɨIɨIɨIɨJɨJɨJɨJ߼׾wɨJɨJɨJɨJɨJɨJɨJٰɏɨJɨJɨJʑ׭ɨJɨJɨJɨJɨIɨIɨIѶfɨIɨIɨIʪNɨIɨIɨIɨJݸņɨIɨIɨJɨJɨIɨJɨJΙΙɨJɨJɨJ̭UɨJʨJɨJɨJʨJʨJʨJͭVʩKʩKʨKʨJɨJɨJɨJɨJɨJɨJɨJɧIɨJʨKʨKʨJʨJ߼׾wʨJʨKʨKʨKʩKʩKʨKּuʨKʨKʨKʨKʨJɨJɨJɨJɨJɨJɨIɨIɨIɧHɧHȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȦGȦHɧIɧIɧIɧIɧIɧIɨIɨIɨIɧIɨIɧIɧIɧHɧIɧIɧIɧIɧIɧIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨJɨIɨI߼׾wɨJɨJɨJɨJɨJɨJɨJ{ѵdɨJѵe׾wɨJɨJɨJɨJɨIɨIɨIɨJ˒ɩJ˫OڲɨIʩLɨI׿zͯWɨHɨIɨIɨJɨJɨJɨJΙΙɨJɨJɨJ̭UɨJɨJʨJɨJʨJʨKʨKͭVʩKʨKʨJɨJɨJʨJɨJʨJɨJɨJʨJʨKʨKʨKʨKʨJʨK߼׾xʩKʨKʨKʩKʩKʩKʩKʒʨKʩLΙίZʨKʨJɨJɨJɨJɧIɨJɨJɨIɧHɧHɧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȦHȧIȧIȧIɨIɨIɨIɨIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIɨIɨIɨIɨI߼׾wɨJɨJɨJɨJɨJɨJɨJɨJ޹ܷɨJɨJɨJɨJɨJɨJɨIɨIɨI׾wϲ^ʪNʐɨJɨIɨIɨIɨIɨJɨJɨJΙΙɨJɨJɨJ̭UɨJɨJɨJɨJɨJɨJɨJ̭UʩKɨKɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨKɨJʩKʩK߼׿xʩKʩKʩKʩKʩKʩKʩKջpɨKɨJɨJɨJɨJɨJɨJɨJɨIȧIȧIȧIȧHȧIȧHȧHȧHȧHȧHȧHȧHȦHȧHȧHȧHȧHȧHȧIȧIȧIɨIȧIɨIȧIȧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧIȧIȧIȧIȧIȧIɨHɨIɨIÂԤг`ɨIɨJɨJɨJɨJɨIɨJɨJɨIņņɨJɨJɨJɨJɨIɨIɨIɨIɨHɨHɨIдbٰӣͮVɨJԺn޹ջpɨIɨJɨJɨIɨIɨJɨJɨJɨJջrԥջrɨJɨJɨJ˫Pԥ˔ɨJɨJɨJɨIɨJɨJɨJ˫Pԥ̔ʩKɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʩKԥϚʩJʩKʩKʩKăԥѴbʩKʩKʩKʩJʩKʩKʩKʩKѵdخէϱ\ɨJɨJɨIɨJɨJɨIɨIɨIɨIɨIȧIȧHȧHȧHȧHȧHȧGȧGȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧIȧIȧIȧIȧIȧIȧHȧHȧHȧHȧHȦHȦHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧIȧHȧIɧIɧIɨIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨIɨIɨJɨIɨIɨIɨJɨJɨIɨJɨIɨIɨIɨIɨIɨJɨJɨJɨIɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɧJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʨKʨKʨKʨJʩKʩKʩKʩKʩKʩKʩKʩJʨKʨJʨKʩKʩKʩKʩKʨKʨKʨKʨKʨKʨKɨJʨKɨJɨJɨJɨJɨIɨIɧIɧIɧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧIȧIȧIȧIȧIȧIȧHȧHȧHȧHȧHȦHȦHȦGȦGȦHȧHȧHȧHȦHȦGȦHȦHȧHȧHȧHȧHȧHȧHȧHȧIɧIɧIɧIɨIɨIɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJʨJɨJɨJɨJɨIɨIɨJɨJɨIɨIɨJɨIɨIɨJɨIɧIɨIɨIɨIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɧIɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨJʨKʨKʩKʩKʩKʩKʩKʩKʩKʩKʨKʨKʨKʨKʨKɨJɨJɨIɨJɨJɨIɨIɨIɧIɧIȧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȦHȦGȧHȧHȧHȧHȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȧGȧGȧHȧHȧHȧHȧHɧIɧIɨIɨIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJʨJʨJʨJɨJʨJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʨJɨJɨJɨJɨJɨJɨIɨIɧIɧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧGȦGȦGǦGǦGǦGǦGǦGǦGȦGȦGȦGȦGȦFȦGȦGȦGȧGȧHȧHȧHȧHɧIɨHɨIɨIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɧIɧIɧIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJʨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJʨJʨJʨKʨKʨJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKɨJɨJɨJɨJɨIɨJɨIɨIɨIɧHȧHȧHȧHɧIȧHȧHȧHȧHȧHȧGȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHǦGǦGǦGǦGǦGǦGǦFǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȧHȧHȧHȧHȧIȧIɨIɨIɨIɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIȧIȧIȧIȧIȧIɨIɨIɨIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɧIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʩKʩKʩKʩKʩK˩KʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKɨJɨJɨJɨJɨJɨJɨJɨIɨIȧIȧIȧIȧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȦGȧGȧHȧGȧHȧHȧHȧHȧHȧHȧHȦGȦGǦGǦGǦFǦGǦFǥFǥFǥFǦFǦFǦFǦFǦFǦFǦFǦFǦGǦGȦGȦGȦGȦHȧHȧHȧHȧIɧIɨIɨJɨJɨIɨIɨIɨIɨIɨIɨIɨIɨIɨIɧIɧIɧIɧIɧIɧIɧIɧIɧIȧIȧHȧHȧIɧIɧIɧIɨIɨIɨIɨJɨJɨIɨIɨIɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʨKʨKʨKʨKʨKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨJɨJɨJɧIɨJɨJɨJɨIɧIȧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȦGȦGȧHȧHȧHȧHȦHȧHȧHȦGȦGǦGǦGǦGǦGǦFǦFǦFǥFǥFǦFǦFǦFǦFǦFǦFǦFǦGǦFǦFǦGǦGȦGȦGȦGȧHȧHȧHȧGȧHɧIɧIɧIɧIɧIɨIɨIɨIɨIɨIɨIɨIɧIɧIɧIɧIɨIɧIɧIɧIɧIɧIȧIȧHȧIȧIɧIɧIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɧIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʨJʨKʨKʨKʨKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKɨJɨIɨJɨJɨJɨJɨIɧIɧIɧIɧIȧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGȦGǦGǦGǦGǦGǦFǦFǦFǥFǦFǦFǦEǥEǥFǥEǦFǦFǦFǦFǦFǦFǦGǦGȦGȦGȦGȧHȧHȧHȧHȧHȧIɧIɧIɧIɧIɨIɨIɨIɨIɨJɨIɨIɨIɨJɨIɨIɧIɨIɧIȧHɧIɧIȧIȧIȧIɧIɧIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨIɨIʨKʩKʩKʨKʩKʨKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʨKɨJɨJɨJɨJɨJɨJɨIɧIɧIɧIɧIɧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȦGȦGȦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǦEǦEǦFǦFǥFǥEǥFǦFǥEǥEǥEǥEǦFǦFǥFǦFǦFǦFǦFǦGȦGȦGȦGȦGȦGȧGȧHȧHȧHȧHɧIɧIɨIɨIɨIɧIɨIɨIɨJɨIɨJɨJɨJɨHɨIɨIɧIɧIɧIɧIɧIɧIɧIɧIɧIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʨJɨJɨJɨJɨJɨJɨJɨJʨJʨKʩKʨKʨJʨKʩKʨKʩJʩKʩKʩKʩKʩKʩKʩJʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʨKʨJʨJɨJɨJɨJɨJɨIɨIɨIɨHɨIɨIɧHɧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHǦGǦGǦGǦFǦFǦFǦFǦFǦFǥFǦFǦFǥFǥFǥFǥFǥFƥEƥEƥEƥFƥEƥEƥEƥEƥFƥEǥFǥFǥFǥFǦGǦGǦGǦGǦGǦGǦGȦHȧHȧHȧIȧHȧIɧIɧIɧIɧIɧIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɧIȧIȧIȧIȧIȧIɨKгcֽv׿xӷj̭TɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨJΰZռt}€ּuг`ɨKɨJɨJɨJɨJɨJɨJʨKʨKʨKʩKʩKʨKʩKʨJʨKʩKʩKʨKʨKʨKʨKʨKʨKʩKʨJʩKʩKʩKʨJʨJʩKʨKɨJɨJɨJɨJɨJɨIɨJɨIɨIɨIɨIɧIɧIɧIɧIȧIȧIȧIȧIȧHȧHȧHȧHȧIȧIǦGǦGǦGǦGǦGǦFǦFǥFǥFǥFǥFǥFǥFǥFǥFǥFǥFƥFǥFǥFƥFƥEƥEƥEƥEƥFǥFǥFǥFǥFǥFǦFǦFǦFǦGǦGǦGȦGȧHȧHȧHȧIȧIȧIɧIɧIɧIɨIɨJɨJɨIɨJɨJɨJɨJɨJɨJɨIɨJɨIɨIɧIίZϝڲԺpɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨJɨJɨJɨJɨJɨJʪNĄɐ̬SɨJɨJʨKʨKʨKʨKʩKʩKʩKʩKʨKʨKʩKʨKʩKʩKʨKʨKʨKʨKʩKʩKʨKʨKʨKʨKʨKʩKʨKɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɧIɧIɧIɧIɧIȧIȧIȧIȧIȧHȧIȧIɧIǦGǦGǦGǦGǦGǦGǥFǦFǥFǥFǥFǥFǥFǥFƥFƥFƥFƥEǥFǥFǥFƥFƥEƥEƥEƥFǥFǥFǥFǥFǥFǦFǥFǦFǦGǦGǦGȦHȧHȧHȧHȧIȧIѴe̖ϜѶfɨJɨJɨJɨJɨJɨJɨJɨJг`߼ݷɨIг`Θ߽џӸkɨIɨIɨIɨIɨIɨIɨJʪOΙ޺ݸ֪ͭVʩKʩKʩK̭Sɏџв_ʩKʩKʩKʨKʨKʨKʨKʨKʨKʨKʨKʨKʨKʨKʩKʨKʨKɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɧIɧIɧIɧIɧIɧIȧIȧIȧIȧIȧIȧIɧIǦFǦFǦFǦFǦFǦFǦFǥFǥFǥFǥFǥFǥEǥEƥEǥEƥEƥEǥEǥEǥEƥEƥEƥEƥEƥEƥEǥEǥFǥFǥFǥFǥFǦFǦFǦGȦGȦGȦGȧHȧHֽwֽwɨJɨJɨJɨJʩLНܵ׾w̬P˫N˫N˫N˫N˫N˫NѵbѝÁɨIɨIɨIɨJռsljΰX˫N˫N˫N˫N˫N˫NͮTÁŅʩKʏح˫PʩKʨKʨKʨJʨKʨJʨJʨJʨJʨJʨJʨKʩKʩKʨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɧIȧIɧIɧIɨIɧIɧIɧIȧIȧHȧIȦHɧIɧIǦFǦFǦFǦFǦFǦFǥFǥFǥFǥEǥEǥEǥFǥFǥEǥEǥEǥEƥEǥEƥEƥEƥEƥEƥEƥEƥEǥEǥEǥFǥFǥFǥFǦFǦFǦGȦGȦGȦG˫P޻ת~ҷgΰYѵc}֩޻˫QɨJ̭TٯΰY˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫OLjٮҶeΰYѴazԥͮVɨI͖ջp˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫NѵdăѴaϲ]׾vٰͮVʩKʨKʨKʨKʨKʨKɨJɨJɨJɨJʨJʨKʨKɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨHɧIɧHɨIɨIɨIɧIɧIɧIɧIɧIɧIɧIɧHǥFǥFǥFǥFƥFƥFƥEƥEƥFƥEƥEƥEƥEƥEƥEƥEƥEƥEƥDƥEƤEƤEƤEƥEƥEƥEƥEƥEƥFƥEƥFǥFǥFǥFǦFǦGǦGǦG̮WɎ̬P˫N˫N˫N˫N˫N˫N˫NˬOɎѴdջo˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫NͮTÁ̬Q˫N˫N˫N˫N˫N˫N˫N˫OƇخϙ˫O˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫NŅz˫N˫N˫N˫N˫N˫NѵdɨLɨKɨKɨKɨKɨKɨKɨJɨJɨJɨKɨKɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɧIɧIɨIɧIɧIɧIɧIɧIɧIȧIȧHȧIȧIǥFǥFǥFƥEƥEƥEƥDƥDƥEƥEƥEƥEƥEƥEƤEƤDƤDƥEƤEƤDƤEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEǥFǦFǦFǦFǦFǦGʪPϲ\˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫Nг^ϱZ˫N˫N˫NͮTÁ׫ܵ̓Ѵa˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫N˫NΰX|˫N˫N˫N˫Nջqџԣ׿x̬P˫N˫N˫Nӷhӷh˫N˫N˫N˫N˫N˫N˫N˫NΰYňͯYӸkѴd˫PʨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨJɨIɧIɨIɨIɧIɧIɧIɧIɧIȧIȧIȧIȧIȧIǥEǥFƥEƥEƥEǥFƥEƥEƥEƥEƥEƥEƥEƥEƥEƤEƤDƥEƥEƤDƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEǥFǦFǦFǦFǦFǦG޺ͮT˫N˫N˫NӸhʏӣحԥʐӸi˫N˫N˫NͮUΰX˫N˫Nӹj޺ljˬO˫N˫NҶeɍԤجӡˑӷh˫N˫N˫N̬Q׿x˫N˫NΰXҠ׬г_˫N˫N˫N˫N˫NϱZȋե׫͖ҷf˫N˫NÁɨJɨJɨJɨJʨKɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIɨJɨIɧIɧIɧIɧIɧIȧIȧIȧHȧIȧIȧIȧIȧHǥFƥEƥEƥEƥEǥFǥFƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥDƥEƥEƥEƥEƥEƥEƥEǥFǥFǦFǦFǦGǦGԻrϲ]˫ṊRϙΘ̭R˫NΰXг^˫NΰXݸԥҠͯV˫N̬PԺn˫N˫Nˑӣ̬Q˫NͮTحѴa˫NͯXʨKɨJɨJʨKʨKɨJɨJɨJɨJɨJɨJɨIɨIɨIɨIɨIɧIɧIɧIɨIɧIȧIȧIȧIȧIȧIɧIɧIȧHƥEƥEƥEƥEƥEƥEƥEƥEƥEƥDƥDƥEƥEƥDƥDƥDƥDƥDƥDƥDƥDƥEƥEƥEƥDƥEƥEƥEƥEƥEƥEƥFǦFǦFǦGǦGʐ˫Nּrռq˫N˫N˫Nջpz˫N˫NͮU׿xҶeӸhг_˫N˫N˫N̬Qƈ̭UɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɨIȧIȧIɨIȧIȧIȧIȧIȧIȧHȧIȧIȧIȧIȧIȧIȧIƥEƥEƥEƥEƥEƥEƥDƥDƥEƤEƤEƤDƤEƤEƤDƤDƤEƥEƥEƤEƤEƥEƥEƥEƤEƥEƥEƥEƥFƥEƥEƥFǥFǦFǦGҷk̬Pńă˫N|͕ϲ]˫O˫N˫N˫N˫N˫N˫NΰYɨJɨJɨKɨJɨJɨJɨJɨIɨJɧIȧIȧIȧIȧIȧIȧHȧIȧIȧHȧHȧHȧHȧHȧIȧIȧIȧIȧIƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƤEƤEƤDƤEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥFǥFǥFֽw֩ջqתņҶdȊѝΗz̭R˫Nϱ[ԺpɨKɨJɨJɨKɨKɨJɨJɨJɧIȧIȧHȧHȧHȧHȧHȧHȧIȧIȧHȧHȧHȧIȧIɧIȧIȧIɧIǥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥDƤDƥDƥEƥDƥDƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEǥEǥEˬTحд`͖˫OΘܷɨJɨJʨJɨJɨJɨJɨJɨIɧIȧIȧIȧHȧHȧHȧHȧHȧHȧHȧIȧHȧIȧIɧIɧIȧIȧIɧIƥEƥEƥEƥDƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEǥFϲ`ɍ̬P˫Nljϲ]ʨJʨKʨKʨKɨJɨJɨIɨIɨIɧIɧIȧIȧIȧHȧIȧIȧIɧIɧIɧIɧIɧIɧIɧIȧIȧIɧIƥEƤEƤEƤEƤEƤEƤEƥEƤEƤEƤEƥEƤEƤEƤEƤEƤDƤEƤEƥEƥEƥEƥEƥEƥEƥEƥEƤEƤE̮XΰY˫N˫Nг_ΘʩJʨKɨJɨJɨJɨJɨJɧIɧIȧIȧIȧIȧIȧHȧIȧIȧIȧIɧIȧHȧIȧIȧIȧIȧIȧIȧIƥEƤDƤDƤDƤDƤDƤDƥEƥEƤDƤDƥEƤEƤDƤDŤDŤDƤDƤEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥF̬P̬QʐʩJɨJɨIɨJɨIɨJɨIɨIɧIȧIȧIȧIȧIɧIȧIȧIȦHɧIɧIɧIȧIȧIȧIȧIȧIɧIɨIƥEƥEƤDƤDƤDƤDƤEƥEƥEƥEƥEƥEƤEƤDƤCƤDƤDƤDƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEɏͮUռqʩKɨJɨJɨJɨJɨJɨJɨIɧIɧIɨIɨIɨIɧIȧIȧIȧIɧIȧIȧIȧIȧIɧIɧIɧIɧIɨIƥEƥEƤEƤDƤDƥEƤEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥFȦH׿xLjʨKɨJɨJɨJɨJɨIɨJɨIɨIɨIɨIɧIɧIȧIȧIȧIȧIȧIȧIȧIȧIȧIɧIɧIɨIɨIɨJƤDƤDƤDƤDƤDƤDƤDƤDƤEƥEƤEƤEƤEƥEƥEƥEƥEƤEƤEƥEƥEƥEƥEƥEƥEƥEǥE{|ʨKɨJɨJɨJɨJɨIɧIɧIɧIɧIɧIȧIȧIȧHȧIɧIɧIȧHȦGȧHȧHȧHɧIɧIɧIɨJɨJŤDŤDƤDŤDŤDƤDƤDƤDƤDƤEƥEƥEƥEƥEƥEƥEƥEƤEƥEƥEƥEƥEƥEƥFƥFƥFƥF۴̓ɨJɨJɨJɨJɨJɨIɨIɧIɧIȧIȧIȧHȧGȧHȧHȧIȧIȧIȧHȧHȧHȧHȧHȧHȧIɨIɨJɨJŤDƤDŤDŤDŤDŤDŤDƤDƤEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥFƥFǥFתΰ[ɨJɨJɨJɨJɨJɨJɨIɧIɧIȧIȧIȧHȧHȧHȧHȧIȧIȧIȧHȧHȧHȧIȧIȧIɧIɨJɨJɨJŤCŤCŤCŤCƤDŤDŤDƤDƤDƥDƥDƥDƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEǥFǦFǦFв_ɨJɨJɨJɨJɨJɨJɨIɨIɧIȦHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧIȧIȧIɧIɨIɨJɨJɨJŤCŤCŤCŤCƤDƤDƤDƤDƤDƤDƥEƥDƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEǥFǦFǦFϚ˪NʩKʨJʨKɨJɨJɨJɨJɨJɨIɨIȦHȧGȧHȧHȧHȧHȧHȧHȧIȧIȧIȧIȧIȧIȧIȧIɧIɨJɨIɨJŤDţCţCŤDŤDƤEƤEƤEƤEƤEƤEƥEƥEƥEƥEƥEƥEƥEƥFƥFƥFƥEƥEƥEƥFǥFǦF׫гaɨKʩKʩKʩJʨJʩKʨKɨJɨJɨJɨJɨIɨIȧIȧHȧHȧHȧHȧHȧIȧIȧIȧIɧIɨIȧIȧIȧIȧIȧIɨJɨIɨJŤCŤCŤCŤDŤDƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEǥEǥFίYɨJɨJʩKʩKʩKʩKʩKʩKʨKɨJɨJɨJɨIɨIȧIȧIȧIȧGȧHȧIȧIȧIȧIɨIɨJɨJɨJɨIȧIȧIɧIɨIɨJɨJŤCŤDŤDŤDƤDƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥFƥEƥEƥEƥFǥFƥFƥFǥFǦF߽ʩKʨKʨKʩKʩKʩKʩKʩKʩKʩKɨKɨJɨJɨIɧIȧIȧIȧIȧIȧIȧIɧIɧIɨIɨJɨJɨJɨJɨJɨIɧIɨIɨIɨIɨJŤDƤDƤDƤDƤEƥEƥEƥEƥEƥEƥEƥEƥFƥEƥEƥFǥFƥEƥEƥEƥEǥFǥFƥFƥFǥFǦF˔в_ʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKɨKɨJɨJɨIȧIȧIȧIȧIȧIȧIȧIɧIɨIɨJɨJɨJɨJɨIɨIɨIɨIɨIɨIɨIɨJŤCƤDƤDƤDƤEƤEƤEƤEƥEƥEƥEǥEƥEƥEƥEƥEƥEƥEƥEƥEǥFǥEǥFƥEǥEǥFǥFˬU̔ʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKɨJɨJɧHɧIȧIȧIȧIȧIȧHȧHȧIȧIɧIɧIɨJɨJɨIɧIɧIɧIɧIȧIɧIɧIɧIŤDŤDƤDƤEƤEƤEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥFƥFǥFƥFƥEƥEƥFƥFƥFǥF׮ڲʩKʩJʩKʩKʩLʩKʩKʩKʩKʩKɨKɨJɨJɨIȧIȧIȧIȧIȧHȧIȧIȧHȧHȧIȧIȧIɧIɨIɨIȧIȧIȧIȧIȧIȧIȧIȧIƤDƤDƤEƥEƥEƤEƥEƥEƥFƥFƥFƥEƥFƥFƥEƥEƥEƥEƥEƥEƥFƥFƥEƥEƥFƥFƥFǥFʫR˔զʩLʩKʩKʩLʩLʩLʩKʩKʩKʩKʩKɨJɨJɨIȧIȧIȧIȧIȧIȧIȧHȧIȧHȧHȧHȧHȧIȧIȧIȧIȧIȧHȧHȧHȧHȧHȧHȧHƤCƤDƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEǥFƥEƥEƥEƥEƥEƥEƥEǥFǥFǥFƥEƥEƥFǥFǥFǥFռvʫQдeΚԺpŇɨJ̬Qݷ{ʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKɨJɨJɨIɨHɧIȧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧGȧHȧHȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHƤDƤEƤEƥDƥEƥEƥEƥFƥEƥEƥEƥEƥEƥFƥEƤEƤEƥEƥEǥFǥFǥFǥFǥFǥFǥFǥFǥFǥFǥFąȎǦHǦGǦGɨLѠѵeȧIȧI˫Rը߼вaɨIɨJʨKʨK|ȋ׾wƇ˪NʩKʩKʩKʩLʩLʩLʩKʩKʩJʩKʨKɨJɨJɨJɧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȦGȧHȧHȧHȦHȧHȦHȦHȦHȦHȦHȦHȦHȦGȦGƥEƥEƥEƥEƥEƥEƥFƥEƥFƥEƥEƥEƥFƥFƥFƥEƥEƥFƥFǥFǥFǥFǥFǥFǥFǦGǦGǦGǥFǥFƥFսwʫRǦG̯Y׿{Ȍ€ϳbǦGǦGǦGǦFǦGǦGǦGˬSОԺqǦHȧHȧHȧIȧIȧIȨJӸmÄƉֽvʫPȧHȧIɧIɨJɨJɨJɨJɩKăȌ˫OʩKʩKʩK˪NӸkăɎÁջq̬QʩKʩKʩKʩKʩKʩLʩLʩLʩLʩKʩKʩKɨKɨJɨJɨJɧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȦHǦHǦHǦGǦGǦGǦGǦGǦGǦGƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥFƥFƥFƥEƥFǥFǥFǥFǥFƥFƥFǥFǦFǥFǥFǦFǦGǦFǦFǦFǦGǦFˬSڲņǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǦGǦGǦFǦFǦFϳanj߽֫۵ΚԼtɨLǦFǦGǦFȦGȧHȧHȧHȧHȧIȧIȧGȧGȧHȧHȧHȧHȧIɧIɨIɨIɨIɨIɨIɧIˬTҢݹܷէÂΰYʨKʩKʩKʩKʩLʩKʩKʩKʩLʩKʩKʩKʩKʩKʩJʩKʩKʩKʩLʩLʩKʩKʩKʩKɨJɨJɨJɨJɧIȧIȧHȧHȧHȧHȧHȦHȦHȦGȦGȦHȦHȦHȦHȦHȦHȦGǦGǦGǦGǦGǦGǦGǦFǦFǦFǥFƥFƥEƥEƥEƥFƥEƥEǥFǥFǥFǥFƥFƥFƥFƥFǥFǥFǥFǦFǥFǥFǦFǦFǦFǦFǦFǦFǦGǦGǦGǦGǦFǦFǦF̭V̖ܶ׿|ȧIǦGǦGǦGǦGǦGȦHȦGǦGǦGǦGǦGǦGǦGǦGǦFǦGǦFǦFǦFǦFǥFƥFƥFƥEƥEƥEƥEƥEǥFǦFǦGǦGȦHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧIȧIɧIɧIɧIȧIȧIȧHȧHȧIɧIɨIɨJɨJɨJɨJɨJʨKʩKʩKʩLʩLʩLʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩLʩKʩKʩKʩKɨJɨJɨIɨIɧIȧIȧHȦHȦHȧHȧHȦHȦHȦGǦGǦGȦGȦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǥFǥFƥFƥEƥEǥFǥFƥFƥFƥFǥFƥFǥEǥFǥFǥFǥFǥFƥFǥFǥFǥFǥFǥFǥFǥFǥFǥFǥFǦGǦGǦGǦGǦGǦFǦFǦGǥFǦGǦGǦGǥFǥFǦGǦGǥFǥFǦGǦGǦGǦGǦGǦGǦGǦGȦHȦHȦGȦGȦGǦGǦGǦGǦGǦFǦGǦGǥFǦGǥFǥFǥFƥFƥEƥEƥEƥEƥEǥFǥFǥFǦGǦGǦGȦGȦHɧHȦHǦGȦGȦGȦGȦHȦGȦHȧHȧHȧHȧIȧIɧIɧIȧIȧIȧHȧIɧIɧIɧIɧIɧIɨIɨJɨJʨKʩKʩKʩLʩLʩLʩLʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKɨJɧIɧIȧIȧIȧHȧGȦGȦGǦGȦGȦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǦGǦGǥFǥFǥFǥFƥEƥEƥEǥFƥEƥEǥEǥEǥFƥEƥEǥFǥFǥFǥFǥFǥFǥFǥFǥFǥFǦFǦFǦFǦGǦFǦGǦFǦGǦGǦGǦGǦGǦFǦFǦFǦFǦFǦFǦFǦFǦFǦFǥFǥFǦFǦGǦFǦFǦGǦFȦGȦGȦGȦGȦGȦGȦGǦGǦGǦGǦGǦGǦFǦFǥFǥFǥFǥFǥFǥFƥEƥEƥEƥEƥEƥEǥFǥEǥFǦFǦGǦGȦGȦGǦGǦGǦGǦGǦGǦGǦGȦHȧHȧHȧIɧIɨIɨIɧIȧIȧIȧIɧIɧIɧIɧIɧHȧIȧIɧIɨJʨKʩKʩKʩLʩLʩLʩKʩKʩKʨKɨJɨJʨKʨKʨKʨKʩKʩKʩKʩKʨJɨJɨJɧIȧIȧIȧHȧHȦHȦGǦGǦGǦGǦGǦGǦGǦFǦFǦGǦGǦFǥFǥFǥFǥFǦFǥFǥFǥFǥFǥEƥEƥEƥEƤEƥEƥEƥEƥFǥFƥFƥEƥEƥFǥFǥFǥFǥFǥFǥFǥFǥFǦGǦGǦGǦGǦGǦGǦGǦGǦFǦGǦGǦFǦGǦFǥFǦFǦGǦGǦGǦFǦGǦFǦFǦFǥFǦGǦGǦGǦGǦGǦGȦHȧHȧHȦHȦHȦHǦGǦGǦGǦFǦGǦGǦGǦGǦGǥFǥFǦFǥFƥFƥFƥFƤEƥEƥEƥFƥEƥFƥFǥFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȦHȧHȧIɨIɨJɨJɨJɨJɨIɨJɨJɨJɨIɧIɧIȧHȧIȧIȧIɨJʩKʩKʩKʩLʩLʩKʩKʩKʩKɨKɨJɨIɨJɨJɨJɨJɨJɨJɨKɨJɨJɨJɨIȧIȧHȧHȧHȦHǦGǦGǦGǦGǦGǦFǦFǥFǦFǦFǥFǦFǥFǥFǥFǥFǥFǥFǦFǦFǥFƥFƥEƥEƥDƤEƤEƥEƥEƥEƥFǥFǥFƥEƥEƥFǥFǥFǥFǥFǦFǥFǥFǥFǦFǦFǦGǦGǦGǦGǦGǦGǦFǦGǦFǦFǦFǦFǦFǦFǦGǦGǦGǦFǦFǦFǦFǦFǦFǦFǦGǦGǦGǦGȦHȧHȧHȧHȧHȧHȧHȧHȦHǦGǦFǦGǦGǦFǦFǦFǥFǦFǦFǦFǦFǦFǥFƤEƥFƥEƥEƥEǥFǥFǦFǦGǦGǦGǦGǦFǦFǦFǦGǦGǦGǦGȦGȧHȧIɨIɨJʩKʩKɨJɨJɨJʨKʩKɨJɨJɨIɧIȧIȧIɧHɨIʨKʩKʩKʩLʩKʩKʩKʩKɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɧIɧIȧIȧHȧHȧHȧHȦGǦGǦGǦFǦFǦFǥFǥFǦEǦGǦFǥFǥFǥFǥFǦFǦFǦFǦFǥFǦFǥFƥEƥEƥEƥEƥDƤDƥEƥEǥFǥFǥFǥFǥFǥFǥFǥFǥFǥEǥFǥFǥFǥFǥFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǥFǦFǦGǦGǦGǦFǥFǦFǥFǥFǦFǦFǦGǦGǦGȦGȦHȦHȦHȦHȧHȧIȧIȧIȧHȦHǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǥFǥFǥFǦGȦGȦHȦHȦHǦGǦGǦGǦGǦGȦHȦHǦGȦHȧHȧIɧIɨJʨKɨJɨIɨJʩKʩKʩLʩLʨKɨJɨJɨJɨJɨJɨJʨKʩKʩKʩKʩKʩKʨKɨJɨJɨJɨIɨJɨJɨJɨJɨJɨJɨJɨJɨIȧIȧIȧHȧHȧGȧHȦHǦGǦGǦGǦFǥFǥFǥFǥFǥFǦFǥFǥFǥFǥFǥFǦGǦGǦGǦGǦFǥFǥFǥFƥEƥEƤEƤDƤDǥFǥFǥFǦFǥFǥFǥFǦGǦGǥFǥFǥFǥFǥFǥFǥFǥFǥFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǦGǦGǦGǦGǦFǥFǦGǦFǦFǦFǦFǦGǦGǦGǦGȦHȦHȦHȧHȧHȧIɧIȧIȧHȧHȦHȦGȦGȦHȦHȧGȧHȧHȧHȦHȦHȧHȧHȧIȧHȧHȦHȧHȧHȧIȧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȦHȧHȧHɧIɨJɨJɨJɨJʨKʩKʩKʩKʩLʩKʩKʩKʩKʩKʨKʨKʩKʩKʩKʩKʨKʨKɨJɨJɨIɨIɨIɨIɨJɨJɨIɨIɧIɨIɧIȧIȧHȧHȧHȧHȧHȦHǦGǦGǦGǦFǦFǥFǥFǥFǥFǥFǦFǥFǦGǦGǦGǦGǦGǦGǦFǦGǦGǦGǦFǥFƥEƤEƤEƤDƤDǥFǥFǦFǦFǥFǥFǥFǥFǥFƥEƥEƥFƥFǥFǥFǥFǦFǥFǦFǦFǦGǦGǦGǦFǦFǦFǦGǦGǦGǦFǦFǦFǦFǦFǦFǦFǥFǥFǥFǥFǦFǦFǦFǦGǦGǦGȦGȦHȦGȦGȧHȧHȧHȧIȧIȧHȧHȧHȧHȧHȧIȧIȧIȧIȧIɧIȧIȧIɧIɨJɨJɨIɨIȧIɧIɨIɨJɨIɨIɨIɨJɨJɨJɨIɨJɨJɨIȧIȧHȧHȧHȧHɨIɨJʩKʩKʩKʩKʩLʩLʩLʩLʩLʩLʩLʩLʩLʩKʩKʩKʩLʩLʩKʩKʨKɨJɨJɨJɨIɨIɨIɧIȧIȧIȧIȧIȧIȧHȧHȧHȦGǦGǦGǦGǦGǦGǦGǦFǦFǥFƥFƥFƥFǥFǦFǦFǥFǦFǦGǦGǦGǦGǦFǥFǦGǦGǦGǦFƥFƥEŤDŤDŤDŤCǦGǦFǦFǦFǥFǥFǥFǥFƥFƥEƥFǥFǥFǥFǥFǥFǦFǦFǦFǦGǦGǦGǦFǦFǦFǦFǦGǦGǦGǦGǦFǦFǦFǦFǦFǦFǦFǥFǦFǦFǦFǦFǦFǦGǦGǦGȦGȧHȦHȧHȧHȧHȧHȧIȧIȧIȧIȧIɧIɨIɨJɨIɧIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʨKʨKʨKʩJʩJʨKɨJɨIȧIȧIȧIɨIɨJʩKʩKʩKʩKʩLʩLʩLʩLʩLʩLʩLʩLʩLʩKʩJʩKʩLʩLʩLʩKʩKʩKʨKʨKɨJɨJɨJɨIɧIȧHȧHȧHȧHȧHȧHȧHȧHǦGǦGǦGǦFǦFǦFǦFǥEƥFƥFǥFǥFǥFǦFǦFǥFǥFǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGƥFƥEŤDŤCŤCŤCǦGǦGǦFǦFǦFǦFǦFǥFǥFǥFǥFǥFǥFǥFǥFǥFǦFǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǦGǦGǦFǦFǦGǦFǦGǦGǦGǦGǦGǦGǦGǦGȦGȧHȧHȧHȧHȧHȧHȧIȧIɨIɨIɨJɨJɨJɨJɨJɧIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʨKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKʨKɨJɨJɨIɨIɨJɨJʩKʩKʩKʩKʩLʩLʩLʩLʩLʩLʩLʩLʩLʩKʩKʩLʩLʩLʩLʩKʩKʩKʩKʩKʨKɨJɨJɨJɨIȧIȧHȧHȧHȧHȧHȧHȦHǦGǦGǥFǥFǥFƥFƥFǥFƥEǥFǥFǦFǦFǦFǦFǥFǥFǥFǦGǦGǦGȧHȧHȦHǦGǦGǦGǦFƥFƥEƤDŤCţCŤDǦGǦGǦFǦFǥFǦFǥFǥEǥFǥFǥFǦFǦFǥFǥFǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǦGǦGǦFǦGǦFǦFǦFǦFǦFǦFǦFǦGǦGǦFǦFǦGǦGǦGǦFǦGǦGȦGȦHȧHȦHȧHȦGȦHɧIɨJʩKʩKʩKʩKʩKʨKɨJɨJʨKɨJɨJɨJɨJɨJɨJɨJɨJɨJʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʨKɨJɨJɨJɨJʨKʩKʩKʩKʩLʩLʩKʩKʩLʩLʩKʩKʩKʩKʩLʩLʩLʩLʩLʩKʩKʩKʩJʩKʩJʩKʨKɨJɨIɨIȧIȧHȧHȧHȧHȧHǦGǦGǦFǥFƥEƥEƥEƤDƥEǥEǥFǥFǦFǦFǦFǥFǥFǥFǥFƥEǥEǦFǦFȥFȦHȦGǦGǦGǦGǦFǥFƥEƤDŤDţCţCǦGǦGǦGǦGǦFǦFǥFǥFǥFǥFǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǦFǦGǦGǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǦGȦGȦGȦHȦHȧHȧHȦGɦHɨJʩKʩKʩKʩKʩKʩKʩKʩKʨKɨJɨJɨJɨJɨJɨJʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʩKɨJɨJɨJʨKʩKʩKʩKʩKʩLʩLʩLʩLʩKʩKʩKʩJʩKʩLʩLʩLʩLʩLʩKʩLʩLʩKʩLʩLʩLʩKʩKʨJɨJɨJȧIȧHȧHȧHȦHǦGǥFǥFƥEƥEƥEƥEƤEǥFǥEǥFǦFǦGǦGǦFǥFƥEƥDƥDƥEƥEǥFǦFǥFǦGǦGǦGǦGǦGǥFǥFƥEƤDŤDŤCţCǦGǦGǦGǦGǦGǦGǦGǦFǦFǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǦGǦGǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFȦGȧHȦHȦHȧHȧHȧHɧIɨJʩKʩKʩKʩKʩKʩKʩKʩKɨKɨJɨJɨJɨJɨJʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKɨJɨJɨJɨJʩKʩKʩKʩKʩKʩKʩKʩLʩKʩKʩKʩJʩLʩLʩLʩLʩLʩKʩKʩLʩLʩLʩLʩLʩLʩLʩLʩKʨKɨJɨJȧIȧHȦHǦGǦGǥFƥFƥEƥEƥEƥEǥFǦGǦGǦGǦGǦGǦGǦFǥFƥFƥEƥDƥEƥEƥFǦGǦGǦGǦGǦGǦGǦGǦGǥFƥFƥFƤEŤDŤCǦGǦGǦGǦGǦGǦGǦFǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǦGǦFǦFǦGǦFǦGǦGǦGǦGǦGǦGǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȧHȧHȧHȧHȧHȧHȧHɧIɨIʩKʩKʩKʩKʩJʨKɨJɨJɨJɨJɨJɨJɨJɨJʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʩKʩKʩKʩKʩKʩKʩKʩKɨJɨJɨJɨJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩLʩKʩKʩKʩKʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩLʩKʨKɨJɨIȧHȦHǦGǦFƥFƥEƥEƥEƥEǥFǦGȧHȦGǦGǦGǦGǦFǦFǦFǥFǥFƥFƥEƥEƥEǦFǦGǦGǦGǦGǦGǦGǦGǦGȦHȦHǥFƥEŤCȦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȦGȦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǥFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȦGǦFǦFǦGǦGǦGǦGǦGǦGȦGȦGȦGȦHȦHȦHȦHȧHȧHɨJɨJʨKʨKʨKʨKʨKɨJɨJɨJʨKʨKɨJɨJʨKʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʨKɨJɨJɨJʨKʨKʩKʩKʩJʨKʨKɨJɨJɨJʨKʨKʨKʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩLʩKʩLʩLʩLʩLʩLʩLʩLʩLʩKʩKɨJɨJȧHȦGǦGǦGǥFƥEƥEƥEƥFǦFȦHȧHȦGǦFǦFǦGǦGǥFǥFǦFǦFǦGǦGǦFǥFǦFǦGȦHȦHȦHȦHȦHȧHȧIɧIȧIȦGƥEŤCȦHȦGǦGǦGǦGȦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȦHȧHȧIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʨKʨKʨKʨKʩKʩJʩJʩKʩKʩKʩKʩKʩKʩKʨKɨJɨJɨJɨJɨJɨJɨJʨKʩKʨKʩKʨKɨJɨJɨJɨJɨJɨJɨJʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʨKʨKʩKʩKʩKʩKʩKʩLʩLʩKʩLʩLʩLʩLʩLʩKɨJɨJȧHȦGǦGǦGǦFǥFǥFǥFǥFǦFȦGȧHȦGǥFǥFǦGǦGǦGǦGǦGȦGȦGȦHȦHȦGȦGȧHȧHȧIȧHȧHȧHɨJɨJɨJɨIȦGƥEŤCȦHǦGǦGǦGǦGǦGǦFǦFǦGǦGǥFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǦGǦGȧHȧHɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨKʨKʨKʩKʩKʩKʩKʨKʩKʩKʩKʨKʩKɨKɨJɨJɨJɨJɨJɨJɨJɨJɨKɨKʨKʨJʨKɨJɨJɨKɨJɨJɨJɨJʨKʩJʩKʩKʩKʩKʩKʩKʩKʨKʨJʨJʩKʩKʩKʩKʩKʩKʩKʩLʩLʩLʩLʩLʩLʩKɨJɨJȧHȦHǦGǦGǦFǥFƥFƥFǥFǥFǦGǦGǦGǥFǥFǦGǦGǦGǦGȦHȧHȧHȦHȧHȧHȧIȧIɨIɨIȧIȧIɨJʨKʩKʩKɨJǦGƥEŤCȦHȦHȦHȦHǦGǦGǦFǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȦHȧHȦHǦGǦGǦGǦGǦGǦGǦGǦGȦHȦHȧHȧHɧIɨJɨJɨJɨJɨIɨIɧIɨIɨJɨJɨJɨJɨKʩKʨKɨJɨJʨKʨKɨKɨJɨJɨJɨJɨJɧIɧIɧIɧIɧIɨIɨJɨJɨKɨKʨKɨJɨKʩKɨKɨJɨJɨJʨKʩKʩKʩLʩKʩKʩKʩKʩKʨKʨKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩLʩLʩLʩKʩKɨKɨIȧHȧHǦGǦGǦFƥFƥEƥFǥFǦFǦGǦGǦFƥFǦFǦGȦHȧHȧHȧHȧHȦHȦHȧHɨJɨJɨJɨJɨJɨJɨJɨJʩKʩKʩKɨJȧHǥFŤDȦGȦHȦHȦHǦGǦGǥFǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǦGȦHȧHȧHȦHȦHȦHȦHȦGǦGǦGȦHȦHȧHȧHȧHȧIɧIɨIɨIɧIɧIȧIȧIɧIȧIȧIɨJɨJɨJɨJɨIɨIɨJɨJɨJɨIɨIȧIȧIȧIȧIȧHȧHȧHȧHȧHȧIɨJɨJɨJɨJɨKɨJʨKʨJʨKɨKʨKʨKʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʨKʨKʩKʩKʩKʩKʩKʨKɨKʨKʨKʩKʩKʩLʩKʩKɨJɨIȧHȧHǦGǦGǦGǥEǥFǥFǦGǦGǦGǦGǥFƥEǥFǦGȧHȧHȧHȧHȦGǦGȦHɨIʨKʩKʨKɨKʨKʨKʨKʨKʨKʩKɨKɨJȧHǥFƤDȦGȦGȦGǦGǦGǦFǥEǦGǦGǦGǦGǦGǦGȦGȦGȦGǦGȦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȦGǦGǦGǦGǦGǦGȧHȧHȧHȧHȧHȧHȦHȦGǦGǦGȦHȦHȦGȦHȧHȧIɧIɧIȧIȧIȧIȧIȧIȧHȧHȧHȧHȧIȧIȧIȧHȧIȧIɧIȧIȧHȧHȦHȦGȦGȦGǦGǦGǦGǦGȦGȧHȧIɨIɨJɨJɨJɨJʨKʨKʨKʨKʩKʩKʩKʩKʩKʩKʩKʩJʩKʩKʨKʩKʨKʨKʩKʩKʩKʩKʩKʨKɨJɨJɨJʨKʩKʩKʩKʨKɨJɨIȧHȦGǦGǦGǦGǥEǥFǥFǦGǦGǦGǥFǥFǥFǥFȦGȧIȧIȧHȧHȦGȦGȧHɨJʩKʩKʩKʩKʩKʨKʨKɨJɨJʨKɨJɨJȧIǦGƥDǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȦHȧGȧHȧHȦHȧHȦHȧHȦHǦGǦGȧHȦHǦGǦGȦHȧHȧIȧIȧIȧIȧIȧIȧHȦHǦGǦGȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȦHǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȧHȧIɨIɨJɨJɨJɨKʨKʨKʨKʩKʩKʩKʩJʩKʩJʩKʩKʩKʩKʩKʨKɨKɨKʩKʩKʩKʩKʩKʨKɨJɨJɨJɨIɨJɨJɨJɨJɨJȧIȧHǦGǦGǦGǦGǦGƥFƥFǥFǦGǥFƥFƥFƥFǦFȦHȧIȧIȧIȧHȧHȧHɨJʩKʩKʩKʩKʩKʨKɨKɨJɨJɨJɨIɨJɨJɨIȧHƥFǦGǦGǦGǦGǦGǦGǦGǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǦGǦGȦGǦGȦGȦGȦGȧGȦGȧHȦGȧHȦGȧHȦGȧHȧHȧHȧHȧHȧIȧIȧIȧIȧHȦGǦGǦGǦGǦGǦGǦFǦGǦGȧHȧHǦGǦGǦGǦGǦFǦGǥFǥFǥFƥFƥFǥFǦFǦFǦGȧHȧIɨIɨJɨJɨIʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʨKʩKʩKʩKʩKʩJʨKɨJɨJɨJɨJɨIɨJɨJɨJɨJȧHȦGǦGǦFǦFǦFǥFƥFƥEƥFƥFƥFƥEƥFƥFǥFǦGȧHȧIɧIɧIɧIɨJɨJʩKʩKʩKʩKʩKʨKɨJɨJɨJɨJɨJɨJɨJȧIȧHǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȦHȦHȦHȦHȦGǦGȦHȦHȦHȧHȧHȧHȧGȧHȧIȧHȧHȧIȧIȧGǦFǦGǦGǦGǦGǦGǦGǦGǦGȦGȦGǦGǦGǦGǥFǥFǥFƥFƥFƥEƥEƥEƥEƥEƥEǥFǦGȦHȧIɧIɨJɨJʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʨKʩKʩKʩKʩKʩKʩKʨKʨKɨKɨJɨIɨIɧIɨIɧIȧHǦGǦFƥFƥFƥFƥFƥEƥEƥEƥEƥEƥEƥEƥEƥEǥFȦHȧIɧIɨJɨJɨKʨKʩJʨJʩKʩKʩKʧJɧJɨKɨJɨJɨJɨIȧIȧHǦGǦFǦGǦGǦGȦGȦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȦGȦGȦGȦHȦHȦHȦHȦGȦGȦGȦHȧHȧHɧIɨJɨIɧIȧIȧIȧIȧHȧIȧGȧHǦGǦGǥFǥFǥFǦGǦGǦGǦGǦGǦGǦGǦGǦGǥFƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEǥFǦFǦGȧHɧIɨJɨJʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʨKʩKʩKʩKʩKʩKʩKʩKʩKʩJʩKɨJɨIɧIȧIɧHɧHȧHǦFǥFƥFƥEƥEƥEƥEƥEƥEƤEƤDƤDƤDƤEƤEƥEǦGȧHɧIɨJɨJɨKɨJɨJɨKʨKʨKɨJɨKɨKɨJɨJɨJɨJɨIȧIȦHǦGǥFǦFǦGǦGǦGǦGǦFǦFǥFǦFǦFǦFǦGǦGǦGǦGǦGǦGǦGǦGȦGȦGȦGǦGǦGǦGǦGǦGǦGǦGȦGǦGȦGȦGȦGȦGȦHȧGȧGȧHȧHȦHȦGȦGȦGȦGǦGǦGȦGȧHɨIɨJʨKɨJɨJɧIȧIȧHȧHȧHȧHȦHȦGǦGǦFǥFǥFǦGǦFǦFǦGǦFǥFǥFǥFǥFǥFƥEƥEƥEƥEƥEƥEƤEƥEƥEƥEǥFǥEǦGȧIɨJɨJʩKʩKʩKʩKʩKʩKʩKʩLʩLʩKʩKʨKʩKʩKʨKɨJɨJʨKʩKʩKʩKʩKʩKʩKʩKʨKɨJɨIȧIȧIȧIȧIȧHǦGǥFƥEƥEƥEƥFƥEƥEƤEƤDŤDŤCŤCŤDŤCŤDƥFǦGȧIɨIɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJʨKɨIɨJɧIȧHȦHȦGǦFǦGǦGǦGǦGǦGǦFǦFǥFǥFǥFǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGȦGȦGǦGǦGǦGǦGǦGǦGȦGȦHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧGȦHȦGȦGǦGǦGǦGȦHȧIɨJʩKʩKɨKɨJɨIȧIȧIȧIȧHȧHȧHȦGǦGǦFǦFǥFǦFǦFǥFǥFƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥEƥFǦFȦHȧIɨJɨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKɨKʩJʩKɨKɨJɨJɨKɨJɨJɨKʩKʩKʩKɨKɨJɨJɨJȧIȧIȧIȧIȧHǦGǦFƥFƥEƥEƥEƥEƥEƤDŤDŤDţCţCģCģBģBģBţCǦGȧIȧHȦGȧGȦHȧHɨJɨJɨIɨJɨJɨJɨJʩKɨJɨJɨJȧIȧIȧHǥFǦGǦGǦGǦGǦFǦFǥEǥFǥFǥFǦFǦFǦGǦGǦGǦGǦGǦGǦGǦGȦGȦGȦGȦHȦGȦGȦHȦHȧHȧHȧHȧHȧHȧIȧHȧIȧIȧIȧHȦHȦGȧHȦHǦGǦGǦGȦHȧIɨJʨKʩKʨKɨJɨIȧIȧHȧIȧIȧHȦGǦGǦGǦGǦGǥFǥFƥFƥFƥEƤEƤDƤDƤEƤEƥEƥEƥEƥFƥFƥEƥEƤEƤEƤDƤEƥEǥFȦGȧHɨIɨJʨKʩKʨKʨKʨKʩKʩKʩKʩKʩKʨKʨKʩKʩKʩKɨKɨKɨKɨJɨJɨKɨKɨKɨJɨIɨJɨJɨJɧIȧIȧIȧHȧHǦGǦGǥFƥFƥEƤEƤEŤDŤDŤDŤDģBĢAâ@á@âA >>ţCƥEģCá@á@á@â@ƤEȧIɧIɧIɧIɨIɨIɨIȧIȧIȧIȧIȧHȦGǥFǦFǦFǦGǦFǥFǥFǥFǥFǥFǥFǥFǦFǥFǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȦGǦGȦGȦHȧHȧHȧHȧHȧHȧIȧHȧIȧIȧIȧHȧHȦGȦGȦGȦGǦGǦGȦGȧHɨIɨJɨJɨJɨJɨJɧHȧIȧIȧHȧHǦGǦGǦGǦGǦFǦFǥFƥFƥEƥEƤEƤDŤDƤDƤEƥEƥFƥFƥFƥEƤEƤDƤDŤDŤDŤDƥEǦFǦGȦHȧIɨJɨKʩKɨKʨKʩKʩKʩKʩKʩKʨKʨKʩKʩJʩKʩJʩJʩKʩKʨKʨKʨKɨKʨKɨIɨIɨJɨJɨJɨIȧIȧHȧHȦGǦGǦFǦFƥFƥEƤEŤDţCţCţCţCģBâ@á?á@á?<:< > >;997;ģBǦFȦHǦFǦGǦGǦGȦGȦGȦGǦGǦGǥFƥFǥEǥFǦFǥFǥFǥFǥFǥFǥFǥFǥFǥFǥFǦFǦGǦGǦGǦGǦGǦGǦFȦGȦFȦGȦGȦGȦHȦHȧHȧHȧIȧIȧIȧIȧIɧIɧIȧIȧIȧHȦHȦGȦGȦHȧHȦGȦGȧHȧIɨIɨJɨJɨJɨJɨIɨIɧIȧHǦGǦGǦGǦGǦFǦFǥFǥFǥFǥFƥEƤEƤEƤDƤEƥEǥFǥFǥFƥEƤEƤDƤDƤDŤDƤDƤDƥEǦGȦHȧHȧHɨJʨKʨKɨKʩKʩJʩKʩKʩKʩKʩKʩJʩKʩKʩKʩKʩKʩKʩKʩKʨKʨKʩKʨKɨKɨJɨJɨJɨJɨIȧIȧHȧHǦGǦFǦFǦFǥFƥEƤDŤDţCţCţCģBģBâAá@á@ >;:99:976558<¡?¡?¡?ĢAţCŤDŤDģBţCƥEƥFƥEƥEƥEǥFǥFƥFƥFƥFǦFǦFǦFǦFǥFǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȦHȦHȧHȧHȧHȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧIɨJɨJɨJɨJɨJɨIȧIȧHǦGƥFǥFǦFǥFƥFƥFƥEƥFƥFƤEƤDƤEƤEƥFƥFƥFǦFƥFƥEƤEŤDŤDŤDŤDŤDŤDƤEǦGȧHȧIȧIɨIʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKʩKʨKɨKɨJɨJɨJɨJɨIȧIȧIȧHǦGǦGǦGǦFǦFƥFƤDŤCţCţCģCģBâAâ@¡?><:9987766554332369:979á@ģBƥFƥFǥFƥFƥFƥFƥFƥFƥFǥFǥFǥFǥFǥEǦFǦGǦGǦGǦGǦGǦGǦGȦHǦGǦGȦHȦHȦHȧHȧHȧHȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧIȧIȧIɧIɧIɨIɨJɨIȧHǦGǥFƥEƥEƥFƥFƥEƥEƤEƤEƤEƤEƤEƤDƤEƥEƥFǥFƥFƥEƤEƤDŤDŤDŤCţCţCŤDƤEǥFȦHȧHȧHɨIʨKʩKʩKʩKʩKʩKʩJʩKʩKʩLʩKʩKʩKʩKʩJʩJʩKʩKʨKʨKʨKʨKʨKɨJɨJɨJɨJɨJɨIɧIȧIȧIȧHȦHȦHǦGǦGǦGƥEƤDţCţCģBĢAá@¡?=<:9877765544320/..////035ƥFƥFƥEƥEƥFǥFƥFƥFƥFǥFǥFǥFǥFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȦHȦHȦHȧHȧHȧHȧIȧIɧIȧIȧIȧIȧIȧIɧIȧIȧIȧHȧHȧHȧHȧGȧHȧIɧIȧIȧIȧIɧIɧIɧIȧIȧGǦGƥFƥEƥEƥEƥEƥEƥEƤEƤEŤDŤDƤDƤEƤEƥEƥFǥFƥFƥEƤEŤDŤDŤDŤCŤDŤDŤDƥEǥFǦGȧHȧHɨJɨJʩKʩKʩKʩKʩKʩKʩKʩLʩLʩKʩLʩKʩKʩJʩKʨKʨKɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɧIȧIȧIȧIȧHȧHȦHǦGǥFƤEŤDţCģBĢAá@ >=;:8876654443210/....././1ƥFƥFƥEƥEǥFǦFǥFƥFǥFǥFǥFǥFǦFǦGǦGǦFǦGǦGȦHȦHǦGǦGǦGǦGǦGǦGǦGȦHȧHȧHȧIȧIȧIȧIɧIɧIȧIȧIɧIɧIɧIȧIȧHȧHȧHȧHȧHȧIȧIȧIȧIȧIȧIȧIȧHȧHȦHǦGǦGƥFƥEƤEƤEƥEƥEƥEƤEŤCŤCţCŤDƤEƤEƥEƥEƥEƥFƥEŤDŤDŤDŤDƤDƤEƥEƥEƥFǦGȧHȧHȧHɨJʨKʩKʩKʩKʩKʩL˩LʩLʩLʩLʩKʩKʩKʩKʩKʩKʩKɨJɨJɨJɨJɨJɨIɨJɨJɨJɨIɨIɨJɨIɨJɨJɨHɧIȧIȧHȧHǥFǦFƥFŤDģBĢBâAá@ >=;986654554332110////////0ƥEƥEƥEƥEƥFƥFǥFǦFǦFǥFǥFǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȦHȧHȧGȧHȧIȧIȧIɧIɨIɧIʨIɨIɨIɧIȧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȦHǦGǦGǦFǥFƥEƥEŤDƤDƥEƥEƥEƥEŤDŤCŤCŤDŤDŤCŤDŤDƤDƤDŤDŤDŤDŤDŤDŤDƤDƥEƥEǥFǦGȧHȧIȧIɨJʩKʩKʩKʩKʩKʩKʩLʩLʩLʩLʩKʩKʩJʩKʨJɨKɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨJɨIɨJɨJɨJɨIȧIȧHȧHǦGǦGǦFǥEƤEģCâAá?¡?¡?>=;755444432210////....///ǥFƥFƥFƥEƥEƥFƥFǥFǦGǦGǥFǦGǦGǦGǦGǦGǦGȦHǦGȦHȦHǦGǦGǦGǦGȦHȦHȦHȦHȧHȧIȧIȧIɧIɧIɨIɧIɨIɨJɨIɧIɧIȧIȧHȦGȦHȦHȦHǦGȦHȦGȦHȦHǦGǦGǦGǦGǥEƥEƥEƤEƤEƤEƥEƥEƤEƥEƤDŤDŤDŤDţCţCţCţCţCŤDŤDŤDŤDŤDŤDŤDŤDƤDƥEǥFǦGȧHȧIȧIɨJɨKʨKʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩJʨKɨKɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨIɨIɧIȧHȦHǦGǦGǦGǥFƥFŤDģCá@>> ? > >=:7665322220//////...///ǥFƥFǥFƥEƥEǥFǥFǥFǦGǦGǦGǦGǦGǦGǦGȦHȦHȦHȦHȦHȦHȦGȦGȦHȦHȦGȦHȧHȧHȧHȧIȧIȧIɧIɧIɧIɧHɨIɨJɨIɨIɧIȧIȦHȦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǦFǥFƥFƥEƤEƤDŤDƤEƥEƥEƤEƤDŤDŤDŤCţCţCģBģBģBţCŤCŤDŤDŤDŤDŤCŤDŤDƥEǥFǦGȧHȧHɧIɨJɨKʨKʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKɨKɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɨJɧIɨIɨJɨIȧIȧHǦGǦGǥFǥFǥFƥEƤDţCá@<;<====<9764221110......-..../ǥFƥFƥFƥEƥEǥFǥFǥFǦFǦGǦGǦGǦGȦHȦHȧHȧHȧHȦHȦHȦHȦHȦHȦHȧHȧHȧHȧIȧHȧHȧHȧIȧIɧIɧIɧIɨIɨIɨJɨJɨIɧIȧIȧGȦHǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǥFǥFǥFƥFƥEƥEƤEƤDƥDƥEƥEƥEƤEŤDŤCŤCŤCţCţCţCţCŤCŤDŤDŤDƤCƤDŤDŤDƤEǥFǦGǦGȦHȧHɧIɨJʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʩK˩KʩKʨKɨKɨJɨJɨJɨJɨJɨJɨJɨIɨIȧIȧIȧIɧIɨJɨJɧIȧHǦGƥEƤEƤDŤDŤDƤDţCâ@<9:;;;<<;:73221100/.......//./0ǥFǥFƥFƥEƥEǥEǥEǥFǦFǦFǦGǦGǦGȦHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧIȧHȧHȧHȧHȧHȧHȧIɧIɧIɧIɧIɨIɨJɨJɨIɨIɧIɧIȧHȦGǦGǦGǦGǦGǦGǦGǦGǦGȦGǦGǦFǦGǦGǥFǥFǥFƥEƤDƤEƥEƥFƥEƥEŤDŤCţCŤCŤCţCŤCŤCŤDŤCţCţCŤDƤDƤDƥEƥFǦFǦFǦGȦHɧHɨJɨKʨKʨKʨKʩKʩKʩKʩLʩLʩKʩKʩKʩKʩKɨKɨKɨJɨJɨJɨJɨJɨJɧIȧIȦGƥDƥFȦHȧIɧIȧIȧGǦFƥEģBá@ > >¡?¡?á@ >:98889:;:9621100///........../0ǥFƥFƥEƥEƥEǥFǥFƥFǥFǥFǥFǦGǦGȦHȧHȧHȧHȧHȧHȧHȧHȧHȧIȧIȧIȧHȧHȧHȧIȧIȧHȧIȧIɧIɧIɨIɨJɨJɨJɨIɧIɧIȧIȧHȦGǦGǦGǦGǦFǦGǦGǦGǦGǦGǦGǥFǦGǦGǦGǦGǥFƥEƤEƤEƥEƥEƥFƥEŤDŤCţCţCţCţCţCţCţCģCģBģBţCŤDƤEƥEƥEƥFƥFǦGȧHɧIɨJɨJʨKʨKɨJʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨKɨJɨJɨJɨJɨJɨJɨJɧIȧHŤC=¡?ŤDƥFǥFǥFƥEģCĢA >;::99::8777666776420/..-------....../0ƥFƥEƥEƥEƥFƥEƥEƥFǥFǥFǦFǦGȦGȧHȧHȧIȧIȧIȧIȧHȧHȧIɧIɧIȧIȧIȧIȧIȧIȧHȧHȧIɧIɧIɨJɨJɨJɨIɨJɨIɧIɧIȧIȧHȧHȦGǦGȦGȦHȦHȦGǦGǦGǦGǦGǦFǦGǦGǦGǦGǦGǦFƥFƥEƥEƥFƥFƥFƥEŤDŤCţCţCģBĢBģCģBģBģBģBţCŤDƤEƥEƥFǥFǦGȦGȧHɧIɨJɨJɨJɨJɨJɨJʨKʩKʩKʩKʩKʩKʩKʩKʩKʨKɨJɨJɨJɨJɨJɨJɨJɨIȧHģC;:==> ? ?==<999888877665543221/...------..//./0011ƥDƥEƥFǥFǥFƥFƥFǥEǦFǦGǦGǦGȦGȧHȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧHȧIȧHȧHȧIɧIɧIɧIɨIɨJɨJɨJɨJɨJɧIɧIȧIȧIȧHȦHǦFȥGȦHȦHȦGȦHǦGǦGȦGǦGǦGȦGȦGȦGǦGǦGǥFƥFƥFƥFƥFƥFƥEƤEţCģBģBĢAĢAĢBĢBģBĢBĢBģBţCƥEǥFǦGǦFȦHȧHȧHɧIɨIɨJɨJɨJʨKɨJʨKʩKʩKʩKʩKʩKʩKʩKʩKʨKɨJʨKʨKɨJɨJɨJɧIɧIȧIƥE¡?9999:99:9888888766554431/./.-----..--...../1112ƥFǥFǦFǦFǦFǦFǥFǥFǦFǦGǦGȦGȧHȧHȧIȧIȧIȧIȧIɧIɧIȧIȧIȧIȧHȧIȧIȧHȧHȧHɧIɧIɧIɧIɨJɨJɨJɨIɨJɨJɧIȧIȧHȧHȧGȦGǦGȦGȧHȧHȧHȧHȧHȦHȧHȦGǦGȦGȦGȦFǦGǦFǥFƥFƥEƥEƥEƥEƤDŤDţCĢAĢAâAâ@â@ĢAĢAĢAĢAģBŤCƥEǦGȦGǦGǦGȦHȧHɧHɨJɨJɨJɨJʨKʨKʩKʩKʩKʩKʩKʩKʩKʩKʩKʨJʨKʨKʨKɨIɨJɨJɧIɧIȧIǦGŤD=:9988888876665443333320.---,,,------,-../01122ǦFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȦHȧHȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧIȧHȧHȧHȧHȧHȧIȧIȧIȧIɧIɧIɧIɧIɧIɧIȧIȧIȧHȦHǦGǦGǦGǦGȦHȧHȧHȧIȧIȧIȧHȧHǦGǦGǦGǦFǦFǦGǥFƥFƥEƥEƥEƥEƤEŤDţCģBĢAâAá@¡@á@âAá@âAĢAģCŤDƥFǦGǦGǦFƥEǥFǦGȦGȧIɨJɨJɨJɨJɨJɨKʨKʩKʨKɨJʨJʨKʨKɨKɨKɨJɨJɨJɨIɨJɨJɨIȧIȧHǦGƥEģB =;98887776665433212331/.,--,,,------,-./012222ǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGȦHȦHȧHȧIȧIȧIȧIȧIȧIȧIȧIȧIȧHȧHȧHȧHȧHȦHȧHȧHȧIȧIȧIȧIȧIȧIȧIȧIȧHȦHǦGǦGǦGǥFǥFǦGȦHȦHȧHȧIȧIȧIȧIȧHǦGǦGǦGǦGǦGǦGǥFƥEƤEƤEƤEƤEŤDţCģBĢBâAâAá@¡?¡@á@á@âAĢAģCŤDƥFǦGǥFƤEŤDƤDƥEǥFǦGɧIɨJɨJɨJɨJɨJɨJɨJɨJɨJʩKʩKʨKɨKɨJɨKɨJɨJɨJɨJɨJɧIȧHȦHǦGƤEţCá@=;9888776554322212320..-,,,,,,---.--../012322ȦHȦHȦHȦHǦGǦGǦGǦGǦGȦHǦGǦGȦHȧHȧIȧIȧIȧIȧIȧIȧIȧHȧHȧHȧHȧHȧHȧHȦHǦFǦGȦHȧHȧIȧIȧHȧHȧHȦHǦGǦGǦGǦGǦGǦGǦFǦGȦHȦHȧHȧHȧIȧIȧHȦHǦGǦGǦGǦGǦGǦGǥFƥEƥEƤEƤEƤDŤCţCĢAâAâ@á@á@ >¡?â@âAâAĢAţCŤDƥEƥEƤEŤDŤDŤDƤDƥEǥFȦHɧIɨJɨJɨIɨJɨJɨJɨJɨJʨKʨKɨKɨKɨKɨJɨJɨJɨJɨJɨJɧIȧHǦGǥFƤDĢB¡?=;9877765443111100110.-,++++++,,--,-..//12233ȧHȧHȦHȦHȦHȦHǦGǦGǦGȦHȦHȦHȦHȦGȦHȧIȧIȧIȧIȧIȧHȧHȧHȧHȧHȧHȧHȧHǦGǦGǥFǦGȧHȧHȧHǦGǦGǦGǦGǦGǦGǦGǦGȦHǦGǦGǦGȦHȦHȦHȧHȧHȧHȦHǦGǦGǦGǦGǦGǦFǦFƥFƥEƤEƤEƤDŤDŤCģBĢAâAâ@á@á@¡?â@ģBģBţCŤCƤDƤEƤEƤEƤDƤEƥEǥFƥFƥFǦFǦGȧIɨIɨJɨJɨJɨJɨJɨKʩKʩKʨKʨKɨKɨKɨJɨIɨIɨJɨJɨJȧIȧHǦGƥFŤCá@==<97776544421100//00/.-,++,++,,,,---./0012332ȧHȧHȦHȦHȦHȦHȦHǦGǦGǦGǦGǦGȦHȧHȦHȦHȧIȧIȧHȧHȧHȦHȦHȧHȧHȦHȦHǦGǦGǥFƥFǦFǦGȦHȦHǦGǥFǥFǦGǦGǦGǦGȦHȦHǦGǦGǦGȦHȦHȦHȧHȦHǦGǦGǦGǦGǦFǥFǥFƥFƥFƥEƤEƤDŤDŤDŤDţCţCĢBĢAĢAĢAĢBĢBţCƤDƤDƤDƤEƥFƥFƥFǥFƥFǥFǦGǦGǦGǦGȦHȦGȧIɨJɨJɨJɨJɨJɨKʩKʩKʨKʨKʨKʨKɨKɨKɨKɨJɨJɨJɧIȧIȦHǥFƤEģB >;;:87765544322100//..---,,-,++,,,,--../0123332ȧHȧHȦHȧHȦHȧHȦHǦGǦGǦGǦGǦGǦGȦGȧHȧHȧGȧHȧHȦHǦGȦHȦHȧHȦHǦGǦGǥFƥEƥEƥEƥFǥEǦGǦGǦFƥFƥFǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦGǦFǦFǦGǥFƥFƥFƥEƥEƤEŤDŤDŤDŤCţCţCţCģBĢBģCŤCƤEƥFǦFǦGǥFǥFǥFǦGǦGȦHȦHǦGȦHȧHȦHȧHȧHȧHȧHȧHȧHɧIɨIɨJɨJɨJʨKʨKʨKɨJʨKʨJʨKʨKɨJɨJɨJɨJȦHȧHǦGƥEţC¡?<988776654432220//----++,,--++*++++,,../0122222ȧHȦHȧHȧHȧHȧHȦHǦFǦGǦGǦGǦGǦGǦGȦHȧHȧHȧHȧHȦHǦGǦGȦHǦGǦGǦGǦGǥFƥEƥEƥEƥEƥEǥFǦGǦGǥFƥFǥFǦGǦGǦGǦGǦGǦFǦFǥFǦFǦGǦGǦGǦGǦFǥFƥFǥFǥFƥEƤEƤEŤDŤDŤDţCţCţCţCţCţCģCģCţCƤEǦFȦHȧHȧHȦHǦGȧHȧHȧIȧIȧHȧHȧHȧHȧHȧHȧHȧHȦHȧHȧIȧIȧIɨIɨJɨJʩKʩKʩKʩKʨKʨKɨJʨKɨJɨJɨJɨJȧIȦHƥFţC¡?<:988877654432220/.-,,,++,,..,+++++,--./01222223ȧHȧHȧHȧIȧIȧHȦHǦGǦFǥFǦFǦGǦFǦGǦGȧHȧHȧHɦHȦHǦGǦGǦGǦGǦGǦGǦGǦGǦFǥFƥEƤDƤEƥFǥFǦGǦEǥFǥFǦGǦGǦGǦGǥFƥFƥEƥFƥFǥFǥFǥEǥFǥFǥFƥEƥFƥEƤDŤDŤCţCţCţCģCģBģCţCţCţCţCţCţCƥEǦGȦHȧGȧHȧHȧHɧIɧIɧIȧIȧIȧIȧIȧIȧHȧHȧHȧHȧHȧHȧIȧIȧIɨIɨIʨKʩKʩKʩKʩKɨJɨJɨJɨJɨJɨJȧIȧHȧHǥFţC ?;99988888655432220.-,,++,,--.-,+*+++,-./001233332ȧHȧHȧHȧHȧHȦHǦGǦFǥFƥFƥEƥEƥEǥFǦFǦGȦGǦGȦGȦGȧHǦGǦFǥFǦFǦGȦGȧHǦGǦFƥEƤDƤEƥEǥFǦFǦFǥFǥFǦGǦFǦFǦFƥEƤDƤDƥEƥEƥEƥEƥEǥFƥFƥEƥEƥEƤEŤCŤCģBģBģBģBģBģBģBţCţCţCŤCŤCŤDƥEǦFǦGȧHȧHȧHȧIȧIȧIȧIȧIȧIȧIȧIȧHȧIȧIȧIȧIȧIȧIȧIȧIɧIɨIɨIɨJɨJɨJɨJɨJɨJɨJɨIɨIȧIȧHǦGƥFƥEâA<::9888777664442221/-,++++,----,+))**++--.//0122222ȧHȦHǦGȦHǦGǦGǦGƥFƥEƤEŤDŤDƤEƥEƥEǥEǥFǥFǦGǦGǦGǥFƥFƥEǥFǦGȦHȧHȦHǥFƥEƥEƤEƥEƥFǥFǥFǦGǦGǦGǥFǥFƥFƤEŤCŤCŤDƤEŤDƤEƥEƥEƥEƤEŤDŤCŤDţCģBâAâAâAâAâAĢAĢBģCţCŤDŤDŤDƤEƥFǥEǦGǦGȧHȧHȧIȧIȧHȧHȧHȧHȧHȧIȧIȧIȧIȧIȧIȧHȧIɧIɧIȧIɧIɧIȧIȧIȧIɧIɨIɨJȧIȧIȧHǥFŤDâA¡?=;99998898876544322210-++++,-..-,+*****++,--/01122222ȧHȦHǦGǦGǦGǥFƥFƥEƤEŤDţCţCŤDŤDƤEƥEƥEƥEƥEǥFǥFƥEƤDƤEǥFǦGǦGȦHȦHǥFƥEƥEǥFƥFǥFǥFǥFǦGǦGǦFǥFƥEƥEƤEŤDŤDŤCŤCŤDƤDŤDƤEƤDŤDŤDţCţCģBĢBâA¡? >>¡?á@âAĢBģBŤDƤDŤDƤEƥEǥFǥFǦGȦGȧGȧHȧHȧHȧHȧHȧHȧHȧHȧHȧHȧIȧHȧHȧHȧHȧIɧIȧIȧHȧHȦHȧGȧGȧHȧHȧHǦGǦGƥEĢA=::999998888887544322110.,+**++,--,+*******++,-//0111122ǦGǦGǦGǦFǥFƥEƥEƤEŤDŤCţCţCţCţCŤDƤDƤEƥEƤEƤEƤEŤDŤCŤDƤEƥFǦGǦGǦGƥFƥEƥEǥEƥFƥEƥEƥEǥFǥFǥFƥFƥEƤEƤDƤDŤDŤCŤDŤDŤDŤDŤDƤDŤDţCģBĢBĢBĢAá@¡?<;; > ? ?á@ģBţCŤDŤDƤEƥEǥFǦFǦGǦGȦHȧHȧHȧHȧGȧHȧHȦHȦHȧHȦHȧHȦHȧHȦHȧHȧHȧHȦHǦGǦGǦGǦGǦGǦGǥFƥEŤCâ@=98999999888888764322100/.-+++++,--,+++******+,-./0111221ǦFǥFǥFǥFƥEŤDŤDŤDţCţCģBģBģBţCŤDŤCŤDŤDŤDŤCŤCŤCţCţCŤCŤDƥEǥFǥFƥEƥEƥEƥEƥEƤEƤDƥEƥEƥEƥEƥEƥEŤDŤDŤCţCţCŤCŤCŤCţCţCŤCŤCģBĢAâAâAâAá@ ?<:;<<;<>á?ĢBţCŤDŤDƥEǥEƥEǥFǦGǦGȦHȦHȦHȦHȦHǦGǦGǦGǥFǥFǥFǥFǥFƥFƥEƤEƤEƤDŤDƤDƤEŤDţCģBá@=;:88999999888887654322210/.-,,,,,--,,,+********+-./0011110ƥEƥEƥEƤEƤDţCģBģBĢBĢBĢAĢAģBģBģCţCţCģCģBģBģBģBģBĢBģBģBţCŤDƥEƤEŤDƤEƤDŤDŤDŤDƤEƥEƤEƤDŤDŤDţCģBģBģBĢBģBĢBĢAĢAģBģBĢBĢAâAá@¡?¡? ? >=<;<<;:9;=¡?¡?> ?âAģBţCŤDƥEƥEŤCģCŤCƤEƤDŤDŤDţCģBĢAá@¡? >>>>=<==<<;978888888988888766653211110.-,,+++,,,,,,+**)))))))+-///00000ƤEƥEƤEƤEŤDģCĢBĢAĢAĢAâAĢAĢAâ@ĢAģBģBģBģBģBĢBâAâAâAĢAĢAĢAģBţCţCŤCţBţCţCţCţCŤDŤDŤDŤCģBĢAâAâAâAâAâAá@á?á@á@âAâAá@á@á@¡@ >==>>>=<<<:999975479;= >>;::= >á@¡?=<;987766667766667888888888888776654322100//-,++**+,-,,,+*)))((()**-//.00///ƤEƤEƤEŤDŤDģBĢBĢBĢAâAâAâ@á@á@á@âAĢAĢAĢAĢAâAá@á@âAâAâAá@âAâAâAģBĢAģBģBģBģCţCģBţCģBĢAá@á@á@¡? ? ? > ?¡?¡?¡?¡?¡?¡@¡@ ?==<> ? >>==<<;:7554466568777789::877776655667777888877888788887766643211100//-,****++,,,+*)()((((**+-...////.ŤDƤDŤDŤCģBģBĢBĢBĢAâ@á@á?¡?á?¡?á@á@â@á@á@á@á?¡?á?á@á@á@¡?á?á@â@âAâAĢAĢBģBģBĢAâ@â@á@¡? > >=<<<==>> > >¡? >=<;<= > > >==<<<;87768:7567778888878777666666666678878777777778766555421110//.-,+))))**+++))((((''())*,,,----.-ţCţCţCģBĢBĢBĢBģBĢAá@á?¡? ? ? > ?¡?á@á?á?¡? > >á?á@á@á@á?¡?¡?¡?á?á@á@á@âAâAá@ >==<;<;;::;;<<= > >==<=== = >===<=<;:988:866778888899888766777667677777787778776776554433110000/.-++))))*++*)(((('''''()+***+---,+ģCģCģBģBĢAâ@ĢAĢBâA¡@¡?¡? > > >>> > > >>> ?¡?á@âAá@¡? ?>> > ? ?¡?á@á@¡?=;:99999999::;===<<<===>>=====<;;:99:876788888889988877776767788877777788777766554432100000/.,+*))))*++*(((''('''(()*)(()*,,**ģBģBģBĢBĢAâAâ@â@¡?¡?¡? > > > >>=>>>>>¡?á@á@á@á@¡? >==>>>> >¡?¡?=;977889999:;<<<<<;<=====<==<;;;;::;:767788878889988876677777787788887777777775544321//////.-+*)((())*))'&''''''''((('&'()))()ģAĢBģAģBĢBâAâA¡? ?¡?¡? >> > >===> > > >¡?á@á@¡?¡? >>==<<<<=>==;99978:;;;;<<<<<<;;<<<=>====<;:;;;;98777788888899888767776788898888888777776655432210/////.-,+*))())*))''''''''''&'('&''(('')ĢBĢBĢBĢBĢBâAá@á@¡?¡? ? >> > >===>>> > >¡?á@¡? ? >>=<;;;;<<<;;:::9::;;<<=<<;<;;;;;<<=> >==<;:;;;:88877788888888887766776788899999888877776655432100////..-,++****))('''&'&&&''&''''&&&&&&'(ģBģCģBģBģBĢBâAá@¡?¡? >>> >>====>>== ? ? >==<;:::::;;;:;;:::::;;<<<;;:;:899:::;<<;;;;:;;;98878778888888777776667778988899987877777654432100//...--,++****))(&&&&&&&%%%%%%%%%&%$$$%''ģCţCţCţCţCģCģBâAá@á@ ?>>>>===>>>==>>=<;;::::::::::;;:::::;;<<<;;::9767889:9:99:::;;:98887888888887777777777788998999988877776653322000/..----,,,+**)('('&&%%&%%%%$$$$$%&%$$%%&'ţCŤDŤCŤDŤCŤDţCģBģBá@¡?>=========<<==<<;::99:::99::;:9::::::;;;::99865667888999::;;;:89987888888878776667788788999999998777765443221100.-.------,++*)('''&&&%%%%%$$##$%%$$$#%%&&ţCţCţCţCţCŤCŤCţCģBĢBá@ >=<===<<<<<<<<<;;:999999999999899999::9998876654467788899::::9888877887777777767766777789989998887775443321100/.----,,,,,+**)(''&%$$%$$$%$$##"###""##$%%&ţCţCŤCŤDŤDŤDţCţCģBģBâA¡? >===<<<<<<<;;;;:988888889999888888899988765544435678888999888888877877777766766667777788999998777664432221100/..---,,+++*)))('&%$$$$%%%%%%$$##$####$$%&'ģBģBģCţCŤDŤDţCģBĢBĢBâA¡? >>==<;<<<;:;:::9988777778988777788888876653333444667877788777777777778778767766778878888887777776653322221100/.-.-,,++***((('&&%$$$$%%%%&&%$$$$$$$$$$&'(¡? > ?>= >âAĢ@â@¡? ? >==<;::::::9:999887666666777665567776665554322233455556677777776666566777766666677787777777665655554322111100/.-,,+++**)))''''&%$$#$$$$$%&%$$#####$$#$%&(><;:87:>=<<<;;::8899877888776455556656665456766665555432122344455556677766665555566666665567777777776665544433321121010//.-,,++*)))('''('%%$$$$$$$%&&%$$#""###$$$%&(á@ ?=;8568999998776576545566543123445544544345555665554332223334444445666765654555566665655666667776665554444322121110000//.--,+*))))(&&&'&%%$$$$$$$&&&%##"#$##$%%%&&'ĢAâ@ >;7455555455445332212333210/0123333343333445555444322112233223334455554555444555555554455455565565554431111221221/00//..-,+*)((''&&%&&%%$###$$$%%%%$#""""###$$$&&&âAâA¡?:65654432233443100122210/--.01112223432223554343210111123233343344444555444445455444455554544456554433100111112100///.-,+*)(''''&&$$%&%%%$$%&%&&&%$$#$##$##$$$&&&á@á@ ?;766555433455421111110/.-,++-/00111221111233322210/0011222344433444445544554444444444555554434555444221011111111100/..-,***(&&&&&$$$$%%%%%%$%$%%%%%$$$$%%%%%%&&%% ? >=:756554444543211000/..--,*))+-./000/000//00000000////01122433323343444444444444444343444433223444331100//000000000/.--,+*)('&%%%%$#$$#$#$$$$###$%%$%%%%&&&&&%%%$%><:8645555445543111100/--,,+)((*,-./0/.../...---//0//////01223334333333454555444443444333443333223333210000//0///00//.--++*))(''&%%%$#####"#$$$#""#%%%%&&'''&&%&&&%%<965554455444442122100/.-,++)((*++,..---..--,++-..///..//00233434343322455555554444333323333332223322100//////../0/..-,+**)'''''&&%%%#""""""$$#""##$$%%%&'''&%%&'&&%:5444444555544323432100/.,+)))))))+-.-,-,++,+++,--./..--//02233222222222344445444333222222232211222100////..-,--.---,+**)('%%&&&&&&&$! !"!!!!!!!""######%%%%%$%&&%%%844443455566433454443210.,+))**)))*+----,**+++,--...----./022232222222223333454544442221111211112221/////..-,+,,,,+++*))('&&'&&%%%&&%#!"!!! !!!!!"#####%$#$$%&''&&'64443345645543456443321/-,,)(*)(()*+,,,-+***++,---.--,-../022222222321332112234554432211111211111110//...---,++++*++((('&&%%'%%&&%%%$$" !!!!!!!!!"""###"####$%''&''44333434444543445332211.,+*)()((())*,,,+**))*+,,,,---,,,-/011111111222221121124444321100110000110///.--,+++,,+**)**)'&&%$%%$#$#$%$###"  !!"""!""""##%%%%&34444433444444433433111.,+*)))))()))**++*****,,,-----,,,-/00011000111223222123333332210100000///0/..--,++++++**)))(&%%$$$$$$####"!"""" !!  !!!!!!"!!"##$$%&%24444443344444323442110.,++*)))))))))****)**,,,---------./000///0111222333322333233121000////////..--,++******))(''%$$######""""!!!""! ! ! ""##$%&%1234333333333422332210/-,+++))((())*)***))(*+,,,,,,--,--..////...0111222333322222211110///.//...-.-,,+*)))))((('&%%###"""!!! ! "!  !!!""#$$1112322222333322121210.--++++**())**)))**))*+,,,+,,,----.///0//..0111223343211211101110/...//.-..--,++*))((((('&%%$"##""!!  !!!!     !!""""#1111111222233211111100..-,,,,,+***))(()*****+,-,,,,,,-,,-./00/..///011233221110//0/0000/..../.----,,++*(('&&''&%$$#"#$#!!!  !      !!!!!!"0///0/111222220000000.-.--,,,,,+**))())))***+,,,,,,,--,,,-../....../112221100/....-.///...-----,,+***))('%%$%%%$#"!!!"! !     0///0111222221100////-...-,,-,,,,+++***++*+++,--------,,,-../.---.../1211100...--..//.------,,,,+*)))((('%#$%%$#""!!!! !     ///00111111100/.../.....-----,,,,,,++**++++,-.......--,,---..------...0000/..-,---./.------,,,,+*)('&''''%$###""! !""!!   ////0/00000//.--...---------,--,--,++**+++,,,-.....---,,,-...---------.....-,-,---...------,,++*)((&%&&&%%$#""! !""!     ! .....././//..-,,--,,+,,---,,,,,+,,+++***+,,,,--------,+,,,,,-,,,,,,,,,,+,+,+,,,,,-...------,+**(('&%$%%%$#"!!    ......./...---,,,,,++++,,,,,,,,,,,,+,*++++,,,----,--,,,,,++,-,,,,,,,***)*))*+,,,,-..---,,,-,*()('&%$##$$#"!!   -...--...--,,,,++*+++++,,,,,,+,,,,,,,+,,,,,,----,,,,,,,,-,,,,,,,,,,+**)('(()+++,--.-,,,,,+,,*(''&$$$####!!    -----,---,++***********++++++++,,+,,++++++++,-,,,+++,,,,,+++++++++***)''&''()***+,,,*++**+**)'&%$#"""##"  -.-..,,,,+**)))***))*++*+++*+++,,,,-,+,+++++,,,,+++++,,+++++********)(((''&'((()*,++*******))'&$#"""#$"!    ....-,,++**))))))())*+,+,,++,,+,,,,,,+,++++++,+++****++****))('())))())(('&'(''')*++*******)((&##""""#"   ...--,++*))((())('(((*,,,++++*+,+++,++++++*+*+****))))*)()(''&&&&''()))))(&&'&%&')**(('''''''&$"!! !!! /.---,,+**)))(()(''((*+,,,,,+*+++++,,++,++++****)))))))(('&&&$$%%%&())))))('(&%&()*)'&&%&&&&%$#!  0/.-,,-,+****)('''&'(*+++++++++++++++,,+++******)((((((''&&$$##$$$%'(('(()(('&&'())'%$##%$$##"!  0/..---,+*****((((''(()+****+**+++++,,+++++*****)(''''''&%$$##$##$%&&&&'((&&%%&'''(&%#""##"!!!!  //----,,,++++*)))('&''()**+*)**)***+**++++*))*)('''&&%%%$#"##$#####$$$$%&&%$#$$%%%&$!!! ! ./.-----,,,++++**)(&&'(())*))*)()*++*+*+******)('&&&%%%$###$$$######$$%%%$$#"####$#!  ///./.--,,,,+,,,+*)'&&&'((()))****++++*****)**)(&%%%%%%$#$#$%%$$$$$$$$$%%$####"!!!  0/../.-,,+,,,---,+*'$$$%&'''())))))***))))))))('&%$$$$$####$$%$%$#$$###$$$$#"!! 10//0/.,,--,--..-,*'#"##$&'''())(())))()())))((('&$$$$$$###$%$$$$$$%%$$$$##"!!! 110110/-----,-./.,*'#"""#%&'''(((((((('''()))(('''%$$$$$#$$$%$$%%$$%%$$$$#""!!  211210//.-.-,-...-*'$"!!#%&'&''&'''(('&&'(())(('('%%%%$$$%%%%$$%%%%&&%$#$$#!!! 322120/..--,-..//.+'$! "$%%%%%%%&&&'&%%&'''(((('''&%%%&$$$$%%%$%&%&%$$#"#"! 422220/...---.0//.+'$ "#$$$$%$$%%%%&%%%%&''())(''''&&&&%%%$$%%%%%&%$$$#"""!4322210/./.--.0//.+'$! #$%$###$$%%%%%$$$$%&'()))('((''&&%%%$$$%%%%&%$%$#"!! 44321011/./.../..,*&"!!#$$##!!""#%$$##"##$%&')(()(('(''%#####$%%%$%%$##"! 554321110////0//.,)%! "$$$#!!""#$$#""####%''((()((((('%#$$$$%%%%$$%$#""!  5544322110///////,($! !#$$$##"!###$#""#"""#%&(*((((((''%$$$$$$$%%$$%%$#!! 5443322210/.////.,($! !###$####""#$##""!!!#$&')()())(''&%%%%%$$%%$$%$$#"! 333222110/..////,)'# !""$$###""""$#! !!!#%&''(())'''&%%$$$$$$$$$##"!! 3332220//..../.-+)'$  !"#$#$#""""##""!!!!"$&&''''(('''&&&%$$$$$$$#"""! 221110/..-----,+*(&#  "##$$#""#$#$#""! !"#%&&''''((((''&%$$$######"!11000/.-,,,+,+**)'$#! !"""#$#$%$$#"!""" !"#%&&'&'(())'(('&%$$#####" jamulus-3.9.1+dfsg/src/res/CLEDRedSmall.png0000644000175000017500000000105114340334543017372 0ustar vimervimerPNG  IHDRRWiCCPICC Profile(ϕK(DQ#,$RCLiZ΃{Ml,,lZ*? w %wqw+{޼w۴{=_oo.X~߫__ \}cg>==ҟcw#ו}~9]R;N2ܯe~ iT8"i\shrt)F} u⛟A)qǗ2dćI\ܽnכr8;s|@t3V˫2ߜEBycn|n/ d00Wx}Vyl4i W;!ډɸ@l]vx_#tfC r搛2ɩ^;s}aDC!5-tc~JPO!ERʩZ9SιdaT/ĒJ.Jƚjjo ,܊i; vއađFeFό3<ˬ; _yjo)wy]wPk'xɧzY{=kG:k͚2y+k.c'8Iё P^996OS$O\RrS`Χ>s̛IʛW3J#sF{3{/ ubj8ak'}]QάkuښAByl|Z+ӯs~AnN!gU1YV.j7{yLFLA\q^s윎qQ䙷5y&|W3\թ2OGͥR@-SaOS)1üg9iton}0_fK{n*T Ŕ|zڳm\uf>9PS'tUBEQl}Œj؍s֡>*DQeT8-R]$$pVŪסJ{ro -gFs/pbXsYA҃dߡV8~E\nˀ ˭+iե9*7}_Q<$0QkNF'&@}M۪26'r*S26Ysj\'1@e/ s\G9>ŠP  1ǘ\LZ(Fc<Ѕ4)0>rn$fRuw{iQZهںB?)Ċh]5TVnvel~Xo 8^bL/W@ Bܔn\a.|k6;5oB.zzi;sf5ZL[!lӥތ+S4/"LY>pdveg 3`֚fѠ;u'v&j6YwDMpD3Ir@Z;3j̡)FJ:á2mrƍ:7RGE{4jqhk>/MkCt9!nMI*(7˼dP\ b=50|b*ٖL!^h@R"c}5$Й.((T^C_-{"ИhŖAg{d_DW dr1%f}泇}糤BXRܠ} ;2r,S &7)M&$NȻD9E }D~h"ǁ0{dI>$Ne~A#- MWх-3ccS,P#6#ܶ{ g%Hlߥǫ} ,Ur!u.AoY;/dadQjQ9 [~K ~1Y$6}e-hn2içP ,bt0h*_ E0)F&˹/E Ko WC[] ΤMOaJ1}P?:Q>qJQS 4 r!5OD ;nt#@ jp 6@ ;f-5×,ML-t~R,2^l?Z I<3 v{3YG%DpU'HFv w Bc.Cb\巜~ O[Zϱgm<;]pl;AC"2hSvE*V#3now4Pl!i: Z;c{!],G[Gm X+WM@^ILKq-*Gt;N­:ڞ%aPFFuD{wzd[}M!,M!aso%mGqK1zr!6w󡮅T:|ws/-dC2M+gR(@֤)j k /~p{[0DQp0G՞bzp|ݵQұΜ `e!fr!L}[x͜*tTz;sB A/ٌ0PGRڙ]BP f\TB)R|>4QF;iZrIAVz+]F4׼,2 X4~lZ_'׾H*` "m{3By˒ӟI0hG'f!:>iCv&noQ<ŽaUr@MA)%c_L(09ѹaB7*_p aiGwKR1q騥Wv8/|<͗]:zraՊah ;vx @u Q.#`=m d _f%D4⽌x.7=Z)-45E1' F;½;J7(ƻ;2Eݜ\+ci.HHe>{-ԾMct"'=IqV]a&~7>L9(h] f,`(ǽQTc}F 8 p0v)_6fA uTB_6dzzP'q[M AU^.BP6rd*aV4bD$=9Er}K X*FHt3/Ċ89 <@`s]ٹD 2 Uy!NW)׶ uajQ8\%# t: \nUaP-Rj0־z@ ǜ)y#4xmy6 l)#ۛ|JOqo"l5]mbKGD pHYs~uɍtIME X݈IDAT(mAkQf޴ Lj]Z("DH&uu\ݸfFfUhZ!Hi\Nk*=p8^8aHMD*@9}n+BZR^dh4"~~~z C}˲bRl6UوBwD7~Y|XY\\ I(2 }J~dXk=-˪i3BR5TZp:cYVMc*~mOR)cL6ƔE@HjF4 cL68Nz ,7{;mi{WygO6q0ƴm۶\.W><|fKttZjoo/ZgoFK}Iu$IfAU)1 fj#mNOtrrrubXW8*֓$ muZ":==]տtTM)u"Z%H_IENDB`jamulus-3.9.1+dfsg/src/res/IndicatorYellow.png0000644000175000017500000000164314340334543020356 0ustar vimervimerPNG  IHDRH-iCCPICC profile(}=H@_SE;8dNEEEP :\MGbYWWAqrtRtZxp܏ww^f1e$cQ1]^уĸL=ZLs|׻>Ur&|" xxf9XQRω #e8xfH'Cb6fEC%&+FBeg\e{sJ4H@*J(BVIڏz\2J`X@*$5SnR0 tе 4j}lۍ \i-~^ki#onip >!9gMY`5q-Pǻ{LyrGbKGD pHYs%%IR$tIME iqtEXtCommentCreated with GIMPW{IDAT(ύ/CaVbiJD j2H4! XlDh:h'IG>z *nly/=P%u& 5 mIG7- R haIDATxa#9,gt Cet AwBy;p1d&:+I# PUx{?*u1~[B:7_oM qM|7۽l~>~3O!v&㴽32 {|yPYFr9P?睂qy]DWq 0#>H2_tev?K=Zr`y̑ii]Av)bIɿ{4ϻឯ^E*#?m{\pWTɼM]NχQsJ|6]Z]?2\i?M*%1N8(ΖdDk227)os Q.|O^?'b9:G3_^\0W{_x';I8:c,s6K n>Q:q)#}L~x]?/p\e3,-83g@?X8;!(-:^!m'0cNDO2FnS7:8cgac'}zqC9$H$7r户p;smY5bT^M[p:PD >ccШFtndj\ "x0ʟGנ:$tZ +_9j}w#}8T( xљ72 0m5q"廊(L{8UϙՁʚ}g|o&hCg" D^B%A<ͷќtגxDDNL%~'84XY:nU?iꄵe6^oAxeiπOxsv d7@G߰>6eݚ.ܷ49 +sBH{ %46 ~(_?8RD"Y&TmnoՊjPY6JVdڄ;;x:ˑ()YEշ7Fdx_V}A׻y~S^>Aiگ-Z(b!G^S\?w. xlV҆Gb'Q}\Is*,s/; V.%;f1YqTp=rMyG*&x㧢Pz'<)Ky~Jv&[ \ukDUJ%qa Й%dL6uo&, Ձ:SǨ#.@Y^4Ì0q5h } *4YTAPKu*Gjk  znjYͿC-%yiʎ$ka񲦶@ 6jI sZ?_2]U!jH D?!w"ޥ|Ut_n UF*R mn<{dz< ՄLFNhQ3'_{Bd8iIZ8&)l}\Y*ɝd jʪ:ƙ.#Pr>Psu}^YZӘ3,IF`ᗭT"TvƯ#?h-1>o6E,쎳׆0SUr558 Gnh0-UC ywY grv_AOlaC&K=?e$ř_J7x%̌*xCx籪ȢO(#l(͖SR䚅j`m'6d(倐o꟢pqtwq] r>iË/>ZdŁ\ܨ_v"`FdDWRJwWeACu7E޲flOW9Rk fت+X+uPjᕰ d8υ^urʧa}bqqƀ1ߞ xcN ['El4*>`-H)`%ѭ(؁s'R&BLH!~e$꼗)ͤ1g=ia5+]54X][5.dE7 Q1 =xl˓DlN6*nYtڬ $,-įd,u1׳N'hf gT Y8x oii]LmR!MJȚ(3vwLMh8hBfSZ&ίn:copLH^6\-dh\Q×EJV#ka+.d+һ~$ĺYs+&oOO\W]\yJg_Z*B,y:UO+M>qޏ;!N}!;_~H1JTsP7=cmxoXdzms֣uh I>gңuziJ0(_ww!m?N$IìxAU 6}|{6){bעz7ID\T|Wc 﨡*ȶ\YeOV8FEp𩐠qo.|s,MWPɮZ~_V'ۅ m9^J'z.!7 To&Iװ4i.<,Zznj[veZX:m'qI};zݍ188͏އ:=ڿHcA|}ϱIW~EJ? Js_<SM;9ěLf=) :̑Qu6meZ'oWoBmL**.O4FK:ч]׺0ur )Ld  \Dk(50 }VCE: Q*c^n6L2X AiBZJخNS\# I6Q6"ϭHDpwcW."J|x@ ~DzG1%嫱f%3P/J~!Z=V_\&쒛U ^0?֦߮Ka #2Y1[4r۲;~. TRV}gM3͡LG~mpr)tr]3pC&|>:!t۩jF'i yk I<|8Wko@2_wMВt({Sl7{GH3O5N8!% pCihXg 0ΑeTJ~ A8;jh?LZsXW)vTXP1DC"QN1xپn5y]FA!]xÖTin08n]OVfiԆ2J Dn\d@<{+g_*Іl=*ȅ^H 1ۅoGKBKsۆE5]7g'uVXۿ\ Q]<TOy[gdTQq!;0>;(2MƘobʤq~OK.Lmx/?:l)OҟBeu٘ɢ(*E96q7UR\VD+X8fs7;-pq6u+j3uē݄ќ}ٷ4ll t07~a3M9̭ta4<3HޥWu$TJԪ e,@tZ||hp; & 7 } Y5;9U 8=>]@N3,4ޙ?iޏKϊw띃mb Ia%|z4!AzI`v LLJmR2;tvMB}QpD]`Ӓ뤯G#J]FTX-!A"2!vFRLXiƕIo[,}#2qK֦rʀgxm 7\)*\wl㭮aӲVDႰ]0w0weF6A;%|2լS:dup zɾyˇCbdQqs6 41^E]/䐹'$='yΧ2&͑֕(@UQh}{&uk2癝F.EtFFiZe2Rx:Ρ<\H3x[N;$n?;sa|;lrMG^^\eg&&EIq_©_2-*^`MW*\~n'I|?ʓͬXTWm ^&0 ±K+C$6ыː@~5;`HPܾu]W]7ZS).ѕ yG]2 P糧hiMYG02 l~ _To{EDZyڬL9{ܦ'44ja=^ }a!̽@"LT#@KAR}.T `M܉ET2PRɏb~E Oʕ|3k` LNLB yCnxxR5ףtKރ>ͻ ElV~JΚ7Dbq[]H HѹZ఻%OyE}#_aG,f|JK旖Ks)XLpMR7#zGsش(C%߄vJ\. H|Xg9낍0~uz }Ƚ&8*Z(Dǯ+oZ~^)an5dJ{!(آ'A_o RbےL B'W"'}r/Ho>rRv:g!\v>:H!Pښt;@|yxC'-ڝxzcκXg"+!AhcEcMz>'ࣗ'<=f9s̗ʂz%ko(-QX爤d1|5isrY/;Kj(Z,Hn%N =`3qdtZTmcEf(;<yPj,ullP̭ k*cv [4$iVKjt*o M"fJf'NQ Ъ@غEfe -e(5>Yo >x K9 ]OX,Ի׹"K}h]VTgWψ)D.$MOFfJYrs;:UO:!|+n7<}ɩl  NŃl>W;d(&qY#ov AwRB4H0Ev1&ߣtHn ]<Z?8:uV'uA$J'E ̫uß&]71(/@RhޕV@:'M4v2LK: . %8fEZieB>̛W4-s T(gKr[2c>]rQHѲFbN UVeH 馕aEQ m`{\\SV+(x+e$Q0V]͖nu͎Q> lRszEeR$%PS-l :'F`s9eSmSji}+7OGaq +O$Nܡh+jrcLLыo#8T:VrδAEaz1u֒XH;qns|hrwe$LqJmw}L PD>}EdU+hV7(tZd,SM-gUװ2@xw}$Ŏ? 4wb*M'r^%4ɂ_n 2rD_#uj4춚i.k:;;{?Cr:`)Py~kNwN7RLLDG7 -8cpÿuCFbPqɌT gՉLcPGpӣHOP$ 86r 9]U~,1?}fY Lz;^gW%9cK/Hg +7 w %-v,Xe0SLL MX%} IOR * Dk)^*yXb)on ŶnAON 86gMT:5 [OZ+/߁xn{t)]X =|/8R!{eZih=!A 'ˁHW3ݾi6I7|_YZKz(0Kz~T yzegdEfceoxzNG)1n판$kw~%|HCuX(j祾@V_ ~RxK~< 2թiz<)oFm^2Y{6r]c-xjT5 OK;r `Lc䧵:zL$pqIh4ZP$@fsǶLPxM@jjVEZ)dѤG< {y0DQ|d,Ѹڀy9llkɹ0EM`9^t^i>}@7z@U?8nW>_8UKV?("=\6O C@ŤMmv?|g KvhX[MHtc| ZKF^<艷r̤jߡPCV$Rx[85ï3)/O {v:ɇlDm/w^k8Gv@d##'<9dO}C#k C!aT!%g *UOtj~)M,͓8BլERLDr{L`(ݮ0c-leU(y\~5pQ*U݁M-]2cGwkn1cD3DW",'2{^n/MbWqKsnסB79B'Cu0L`wD'K'?B=shKmYOd| { F^S\iNwy{ʝ?,2"ډzWB6|w&B+X",½^N@ԮynT\e;қ&C3WI74Q~T8Mm3iڛ>D:V[WMTӦ^IYјeR;JWtq50@,6Yza1Dqi΄*Z,HM, !c+29n@-D- sYOg {TKSňZ0hg'*'@s L"W|QTFƧkkOrR߄¤ozQޫ3C,{|eď| b+:qhNSiҽ{ʿc|O \Mδ)f4}0p|8;2 !9hD/"es3lu?3-bg͎TrQY狦|-%eʌM/s/lDR^UXx0OG!B&}DZrl+nH2CFj z' ҋNA>LB 5ma4h S @aҾ+sBr-f6d|gږuR,_Y 1jTyKiV]k5Ʊ>!meZ-o8KK]|aG^ t ?:5CN-\^F*K@׌ԛ;>&:8_T_xTsHS[h6&ٳ pY_9%kKk&ykz2eGq1DW:ʤVY@$(۔B/,eޔ(L} cRܔOI0!^Z?Jh{I]͛gB>-7 ?ph,lbꩱ*)W#%Y`4:Ɋ\CpBea\鄼AoWB|x߾~}. yBpPcxǒ<8z~JTiR:qGx24.@ (Z~~_aIyOw^$ ;{i`hrf%`=Zg:uRd}Y|MPm돬\P]&vF[I(DDYQeBHY2eel~ 6Q#R'I 0vqzbr7.C W yM9ObB",B7.wn+ڤZ@nK8vL##3--tͦd].KءL;%ӒRjHM"Ks`C5e a#)LYfw _w!٫|uۣaGs~?!!C,'TXªtoDܔ* ~ˑ½w{Kl8EY<9:3x3,՝3S팯ogr&ȳ$Αl܄6rL J6ݐDGrpA- яDTdzsLS댝`QjjNԉVۑ_vctr^ 8`gㄡMڡN4(˃eιڵ'wzehԄDWHr.ğ;벺z~l;a9[ %g譖t1JnRg[V X҃ [xW/aae?%KrB(`@Y8n5@P'^#W= 4Ld]5: Jj[Usz?'9 9ȆjHRO?#x. \//ښ9]Oŏ>oFIl\>qʹ7|`y$nKa2/aRIAY"Uxҳe$w"*Zte_*b/F&Ȫ ãMqL~ٕ8G2[1c2e5*$*݈QγWxc_є3dy;U'AUwmB z4e|ijQ*jm1UǏIsQ!v@..NԔjԂr%V }Ӛ` F#AvL ~PJ4@e5{x1CV fǖ P*iD3=H)J %BMܺ@jtUkHf\ͺ֬MX$)"#ޙ!&+r0&s$OQ/ptjrxܒ &)sD%9űE5{l%.ބ{&?iq?-ѩ+jM]uws~E.m?G/4JIo<;㔡cTFMoCzA룑2˭' gOde+%ќ}60=-usDvcSG?#&T-5\*: qSE) Nmu:7 ZP~u92K& dľp+4uv'>P ؓdjc5;gʮ:D*VtAkW4rO9cJ̰ G#24ߵņUMZΎON4Ӑޱu$3" /b5 U FO8/3V~}W}5D»#͑%( #_RxYNDjʯ3<8eܘO :Twm= ~OOKIzÍز%̒罢O[ C+q1h;1YumKRqktsE '( }5~FM]:U6{ LsGܚɣ瓛5D*߉UjQG$ڂ!Z'Q PQV2"hwgRWl+琻^8@ۺ]sSWJŒus$a ֿ-]~?=ǗBk}38q29c @RS&kMZYtK]W~\f)_?w}Ɏ~'u{ ?HTU:5~HI k۸ť5d Tb;Kgb2fw"dXJuztA?x{:|'؅,C59ief 5JLQn P3=US0Ms'X- ţMgFOoӲՙ-k, zERy:-bsqw޼᨝ò_MZt|^W=r+@>>;xxO Zhg=P6Zڲ181-GjlL Jb6NsPtE:E^hƈ2FB8@ NM+EՔYS諢QFӜ F$P`,ڴ뉳N9I4w"2e-xL2;,9:s#>%FzySyCX~ !*CXtgP"~c7][K?MVb7o$^V.cZYqאJ[ *OT±UϛI۸nJ)KJ؉F#o c!1~0bl3?+7ˌ>mZ9FզGA Y>'q]ԖU:BR}7k-%nov6h& 0:D'm"nb6뀳 FfK)ÑEتCɞ}& ,NStCbjh&;kSIҭ 40Ά\`߭ǥ"Įa>Z=1Hv58kjHP m%+cs*|H(Tz"4)""+(fH{aUhCmZ#igmoR* ,/"dToջ g$a3tkgn ?x5sR 11H,wZ L5]ý,PRjY\xίp-{М LyL"ۄ 9OJ$d7\jגœJpӎ <:KJd@HTfȨ+MkXc]LGלbn!q9TjJcN,OAh8R*мc:yXPSp*D8&9SȎoy< :X;U-ƞGOysv"SQvw8r#kHR:.NT>5[w&bqEʘ$Sf;oZ=_E"=-F:[잶s\i紷{*7?3/opOFdxRl˷vKQƝةH*ROt%X363&dhլt58;GI:mv/Ro5UKLP=6* ̩T6Nҩׅj>ׯJ?/kḂSqyV*{R Nܺ#צ('WyKcNT:Q{SDp6=g|*)L ~475%N?j=IHN:ߧy# 5p^3NhEAhc'aYG`Ƹ^U"OFaur X)ulA4d6TXgr;a e!3Dԃ!d%r5GV+ Ngܾ8_-Gȍ@. f~p?:* uYqkty%MTᏔ&{%M%>u{x-=O)4ӌᰘrZ307^im"E&ܔ*J$z7Cb]:c@\d?m}t~.L(=0)7dz/߼k? Sk!xLN,'T%M* nb@\`: @ƢTo EqDV`O/&5!y]9Q)Rkwc ]&QX Z ÖB=,`50:_TUw]>)jw47"CMays0r󰇛]^TBs+ ,{Fhe*3 >PPJm2\`Uu0 Uǰk ξ73G7!=_7vbc/*)-o$~Bҧ섪Yn?{0i*{ 'h>;lSJL@lfo;t|:9[v4DN7Vf 9'T˽t=׸h*~|}E2;O#U,CkM|ȁFf4Tbj0ú; qXS"Km\G7+64aقxPF2 6Z&=V?1%rQR CMy\#-v^h>iRBaݝ  rFZ~"TYQ!1SxVpt4>MSd37D[*ɉS 6#Æ}KS~r UJL`5-J +RgyFf.Q`?88Ƌ eM5+ oDS !ƚH.KB*pDY"%џ_PyɰԆtME} &ͥӓo횷hlCԁt, q /RNO4"Ѹ! )A46h"|>esʲT YЩNQo2SSC4-IN./Ca 5,E@͖.Tly&g YhzP3n96so"Ӱ]E͐~b`5/ bo񪋕\"BRy~ě=i޸c!pஈͺLft%gRx:Q^e›r5jW$:Lj5rpxː/Q;u 0!,ٓ2 z__JII T┼R-R_MB!L]'?j֖m'|'[7inQ^{Vk:4\$hcK@fCNX-ʷ X Q:aeZQJ6/!UY|2R-W:kl^Tv%je*? GhJɨNHώKO/R(F2Օ +G*y].˜nD` D1lrmKUP}@i\/Dof++ZI{(<gm d?\%ܨz`d,H*A!`^MW(}!XV㗭:>8%{Hr(]xڕFd8bىOfffTNҷb~hpH̀eM7AZBΒ tø Ssö B6š{P>H o7ͮn #an~9O@?; ;y͉OdCVuˢV}\6hw+9p$49@…:%l;]fXk]vR#b?',NI\uZscST^B`{WkyBg(ު Q:.s  JnE!(_;fea<(g˒.K J)۝N;8(2%. Y$՜w}Q`$ղ뚋/AM&7i=y6[Fxf1v$L+ 4;}]oMgmkp.K5YB$Ur_IxŦHd5|o/4qG(.S: Z j?3ժ&S$[l`KhyFo7k J0zbZ ^1hl: (`1IP\AIm1Dg*bαt( ṟIH2GvZ2a?ƙh):[6Dͳ&M%{dKxCKW*nJdNT[GƲD!vUX%n'-ġ(9tj_QT>iKs.,"1ozZ)䃈<#+InU{}bo:MrX 1Î_Y' x v=3r:%YFZQfi؋r£#]:zb@=NpiIYt#1>Uf8BM8Z"_ !y,c_!uBAX/}I6)*^ ܐWbR=THtr{kh S:q995i%L704([w+V7ͻ-h)x7Ǹ&r̳שjv..`w"o%:wĩ+!{C]Jb|I͈]zJ|2-uDkP~}t)CpU99*Cd{pO^I-OMvjUL54o?uC~E?H2u+B2I.c[カI""'RZI(k&on?[s=ձ,"bR#tUV,WeQ ,kbKT H$9AIZ{MGo=Sv3-o('7H)U۞,=qaE)x'^ڡɹeń֌& bk6W1mZYbB), Jc-Z:l7)MM\T S[x;Z@()9@]MH# \ j"/ugP. {&ZtqIO0c7POXnM[vK7qJ-A wMbyK:˧ݠc/8AE%sx.hvkTʊcT7ކSy!]2LE"_6c%xx}ۺ-PR\NIFPavo Z`bqXWT;'db/F^p;p 1yB>:|)] r[{8lX0JWXsDM>yu.a؞j&(?>k 8a:s(mkh\k,L +NZ<ecSٞ6rZ+Q UTt"nΑiN9BhNj6 I4Ԡ0rEAوM1oxM 7po&ǡ gJI©uuܷ*n'X;mn -ZzY] yWnv۰@L2wʐoQTPY. rn j'Zz$_%!B"OF*n(\ri﨓:s>ȥ@W*5p<>S̬@)ab?PiyBH'Ha ӄA׎^,j-Jjg[%by,ϐ:X j|qbK3Ҍ8}M6&2cə\LjJ56pfXaYb=vzw{dk G/^HR(Y⫳9yGT5N"j+DG%]S3㢺W7hK*>fᕳ{9u4ԯʞ{i w~ DjSo6lzu֪^.7܌bWe5Á`X}bȸ7LJzJ|'L!*8ٕBO'|\O"yך2[:T.6Yԏtͣa?eچ9^11qD Q# iXK$pI ol(/-7r^ԦIA - ZA5 RxPLo^=*ym3Dm=#~ ͸j)qU ;C:>an&Ozu(>CuqKNo]gk:t夛 Db\'6fEV ˴U\9RE|ָ oݯMsfo"bةZP8 %\r&Y)q6t5i(r q5z\(On~ 0ē1RjbmSj[?Z&'=E\%#G-mG.U*gCFd7YaQ\|=ε6V ֭ -arAn5;pӐn!D%8)#D#@(ĶF_MF}%)v6VwnFz6× 4;҆])p3ݿ,A)IDB`_] J| f>^F+Pvs WK sM/-,e%"8oUAX>1e{61ر;@/a!so`;?]a:q]6dk|-쇮\S-_T>ad[<9e%Bov9qpE]]sU0m"ww1 r^1i-:DGdNj+S RCYV/"w)"ʻ.1[@yXv0cQyIɋu!i1jxj3iĪT,N~]ڳDibEm@c\7%޸˟4h /ȭ u= x"4I:]a%*6/) .m=Jת^Dg3g!~Og!M$Tbւ*S^xVh#C*q{N$b>:yЋ̱abI3-r Ӹؼy $")LΏ?}wܖw5hSy B#7h"M:lB~ n/j1aGg,݊V =i$0ulЅZrr2ҚG.V6?Yw+o)b*2G63XmZoR_52EXѫslrz`Iƥujq;D}=2uegPy@0n36CEӌ"9ŁD+O|ƑHwJգ%q tZߛnk؀$̀˺$.n9x1eд.b/Ym?c=M;0]bK=ǀT7o<#Ve Wq̽zy`M+L 7ђe\u{>v1@?2Qv[-z/R̝/v5Oә`N'552˩.%qFøwÞ2TՕ%ekGv\njk46h J9uoadZ$'PgZf22HDdRGVXB,?p*6VeM͎T%sPz|kb!{~LK)$֘<΁ܻ "RDumHM+i};{LM< ']#Ye~k]ekvQ"īd`I9! 71bGXJ[[5MaXot{ĄG7:" ~^/v??G ~,߭(|n|'U ï6WدF.' [6$+)=:+]M8 l Ⱥ,f;!98&CM|j smNg5 «抺Ru57ԚBkvDHvw^ C,,CHY)k|,Ibۉ7\{[DRͼR\$l"p]ç/D \Sş@vm* (e?~4W[`%Z䨉`-(ԣR݊UC,G^%jgOB;%XJ"AL5ّWk4N)Bmخk&T%E QwH}ëa'Hy5+ELk2(}jM-l~sK䤝զ DHD=R8zcJY4冴J7 .Tm;4MIKŲ<^2`}^Tɰ Xy<"#J1z muZqkQ)X4{+Yˠ]t%!^S{C\:u$d8jr J#6ߖM~JHH3 {hD H 2Fu3ͼw~ZFz ^UyMf<ê\.SJ:<KR]9參_FAsUWVd\#/[ݑ*lTQAQ&Βׁ tO}33LxǠ Gh!i14.L!O\yG/G3%^Di1(1?Fɍ(@,GCCAcRjɽS9M49 z3}\~a Sa⭠\ʽw5i5I$Yg*Z)A<"$Jd7S-Lo,l\Ux"crxJi2d rTzk3=^,&-{lRޒ4o)^TԋflP'5.˷nGTh5UԂc*Rhk`a.ĉ䗀UGTU?.IzmΉl߱(1hL!h&j_XK`7mCsI\Ms+ЂQ㰌x=6jWVa(ҟ32Jf 738/Wn w8E^҉Yߠ5^v vL{ XB5X2] z5&$v[NmoΏh-wd`\Ai2|Tz]z3;{CLBRvckӥw]w6 =lIVSIу]%dT %üi0A5c|2#WJ2egܕN,sm 8ee_ħmͫi!D e fD|y>"3t4VC7[[5Т^I"^{l%ii=0eBkK$dlӎ";PPZѴT!AӇls@@ge*\u`WJʩH,5;l$ L&9'}^ MYa24!Rɝ*\#_ )uNUPCX?%T.!ݛ5lY]F򻦊L餧n7&8I~5<.8r.IuH@y-FB6ZuM~5FgOrB]ozs^%EN1쎼<(5Y E'K4c憗$"$ l_!0y#nATWRfDϫš Uƨn"jH(Sb8:h6CG7KMD\5jekaz54SNkȎP D4Sج(jns% KqIU+C+^k>K9ؔm(޵>lݹ)P{R|tލ`aEhy/ʱB߸tKT\4߲FRDזp#~HO461f('^SuC=1̅^o|KjQ\1%,}@li{yi2Jyǰ|?0R>ڨؖXh&KEB^?P}1W'JژFpDj+T{WQeoXfKj\{O7.WP}v,"N. uxv%'^8ˡlPSȯIle&׵T(I )Vij0Ûv8Gvq$,qG>B?6-Sqj wt)6[%>>FW15˂{2SY)K lK* e6\6ҙ9:: Kִ 7bt>FI^5FgnGoӬMsa p o3Exf1{Ѭ~u5q5JFDZuOSk_k+.رn4\UТ?"iBk2;M$B $^j8j)Rφ\ -* LLEfHZO .F׾n)z:Y8LAVIN3pve\@{R!@H1, ݪD0EHS>dR4ws.ZJh7]DbS6#Rz41CMkVN QCx[FWN>CuOڈNck)(sT*ӫ _2}'Mf,8H6d uJfe: p,| R.unk FS'R%C5H$}+ΣfyOʀ qS] K i7UF/ =?ǟ!G35i\f-#+ͲyFײ&BK+tuoc FNJo`tqSY/sȓF92ˉay]YW]x1Q!O/%B'ƶ, 8Qq2>q: 6& w_b tt؜Ȫ5MwˋrCr}jKl(' Pޅ0ykY˭䒁pЋqO uk#͆4ag ltN %^Rg@Y` ӡ^եBSqlX*،zɚ,LlՒ5&5/'FJ(v4yӏ jFtGEDZj.YU_&b5$qS\jӌڦ7?6W6zD]kGDzZk=m3bӼuneR y*Hz'-`Mg|F,iʃ}5#WQM7Tճ~?z[ݹ[]7J#.-! +_* .ook8ԸW( +bu$ggo-X"-jf+eߜ a4cg)өUi\@ Mr1^s"]]~PW.)WKq%+ OQ s>u h uY@|;xZY0{R$SLj!UDw 2,d|JH^g}O,} Taݽ&IWZ:Y䡉rzSxsjwV-eR`)'ٹqԋti~mzL.;HeZ=ٗ~@/ Q<2XVR-:],rp'quMM?X;{[rUg{99IjrDPaq|3̛|c`7c o0BQu:ǛOWTWuιv%Nq?qTyгc\ԜT#AE?`ROsuh:"_].ɶp.&B3(OjO> @lDx@"Kf~$vM5p⿚I( kYN2+`|.&`8<2BFR)c9c1%֞c`J"u ;PgD4K{H{W,"n孖wiB;JcFx/n̖+4?D"~ia;ZcnaU\vHڹDP'D$ckzR1|Mãkkq.O=bP[#S lG` b0KdfjJ E3q0"T}w<JUDIU0xaSR{i/Ψ (I>U+ɬSEd^mYj'HΐTƾBJJk±Ց ܳ.Du= zP{2u }Yќ~2Iˆf3p[&~534x&+Ah&)1Ԗ! Y($y(1nJqљ44Q)UB02T0,afMծ) Ǫ24_ v0)rQ”o=N;H\Ø>DwQ 3]"]O sHG.rGV0aG"+Ҋ'"u1$/0ʇrd]!1[ˈQ #nRu$jk(K"S5ePʋ{Liv%E:O ݐJb'`;*fH"(S_. SXRd?ȝ-NS#UՊ[Oj6 Y\Ht]8v`ЁDqTDmcL& nJ9je@.sE&Tʅ褅?M2Nw^ftj+P:.>\ND&nE{Nr: Oi/  ub$KY (,vR#wP5:D`f:%kVZhJjAT-oIRPaRkԶȴC24EOT"C}-Z41@Ӆ18RVE`4-(WM e@9krY10@ !JKGSVa3G[lEN ѶМ ~I3)<3& 0ȓ i)8C~!:{v+FH7B/jJO_,%Wx*8AU R( f uҩq7%#tX*f~D(i;ݷ-e6-,xʒҁ5t$H)k +# ^ ڸ\knKaL+'(5Rt5 +AZ=6[;y2+ib!'FrE*#ZnLuO9IkAKDf ɝOˑ7E*I@sbo/D] _^]S!"(f=#FsgOuV]QԔ2W?C1GK@`5`1gMsD䚂ʜ>tީ)%h2$T˭h RBLheJ@rF L?aeKoSEuVk:ϣK o@ 39G[7iSǭgH*2ZQn+S6rIe/tly1 A.Fcklf_R@@@m31`4a;`+߷  ;~%N蠵DS.ղ0kwF(ˊqu>&iЀbuQ'H`\fZE;xOx #ٕӆ4x*SU֧O EUpD'Й\:`G`Z[>XxLIنΚuOu hE4s=Tft7 "oEy?ruj/Ar @{O2U_:+Jw@):i5iGI*5pk[o0xγǘENietD/ r,yb] uS"s@4PaDqH0(cRD>ejb9FnjVL>[cvxP12y$2&3@cYc1k2m@\L2HDZ%mŢBDȕi@r:>'z6.`N$̄4zJs^5)уxw3;o">hXU*DՁb1Ls$Z$EgŠԙ!Y,U0(rN!,C`hZaL (7^@$|1B,3PL8֛b,/w$+{oTFepJ,igxTEh8 :eF|\s`>snZyv紡(*j `*݆<_ =T%T :=Ԃb^BL뗡Fϫ4hCh4]!Yt+Epi $vY\[e-B).9X0Ow9ȺYWSJG/'B-J-D+\uˌ ld\j M DF"If2#gv(:2Ssh +;9 %kz/H?V=wnxMKl^:‘p)7:*~wfl׉>SaJIrtV9iaZ-gLB{@rFIdaHY"TkTFs?u( " uΩ^jJ|jpV]fOaEiN9+!`@/P*b PQʵ** jl0!r qB8`%B""Q43DAԄo`rbl{}zmQ o $Ri $\ C j{b@d!tAӺ z{)$ZbnBkG3*L.0 Шni8nM5NYq22ĥNn hwF\p K E`{b޸ P3?Y{1f@!gE00Ҡ~,!!tY.2"N[&BWi/yiNVBo1@i2.uPtxU4'*"1M $1ac4Xĕ43?vÆa}K݊?x};2i#e\XW,M`Pca5jOsru}N,h{R`5,&0tr*xPsP0:ݚ\1#Ӂ ]P$ŨҸZ#yX7Ė9"@Bl0DįzJj1b*,D3pᡡFÃj2'yeZqr4QusNd6Xk'ՠF?j!=@Ѭ$,!Hg lC& t#5N]lSHT.7|׭Za_xHSsώ?3Ǐ=5>e[߶&QʒvvvQlЋ.)%c\WGZF'}jt9{r|v4>]ʬ;a\2;@ΎY^oSk\) {9"fz3j6٨m}}\@ĜV4o#W>PXBRt0hnm7c,;x^ڽZ#Ӆ 1jqHgXu9N=@?t0A&c5-&~r: ]ʆ S`k%3fvP&0EF+`& tt>Z4SN6χOgFUBJVerSg^b]WjÊKNO\Jr*3',(j-C 5C1l:q 4ш5Xu1maQݦ[?7-޹H[)N)CObޢÍf"s[`Ѕ## D:- sb1 uU,zyx! jH ]Qk0@;{y&+nO! p,򁜻%G\p!Pi`'PBq zoN ~QJDXT@ுyzFv۷;!KG yXhQA2D)% ozj[~jg'S#V2KGV7MNZGG''[R#W鷪7k.{7,7'xǟzwi "Ddp_9h^hQQq8'ǦNOLP}Ѻ,)dTqJu"HjKQ#jK1+~kw,Zy8fO ~nyoMN/.fs^ʹm^&3E ;jFT3+v/n6~|e:xnuHPyƶjx@ {5if~N/ar0mDtP, .4ܹ@cJ$2^zwYi"lC0bԽɇ}G/v4OTTFjTmS[?"2!"G!2-]x L_b#o3's0{B<R!p(~c˚ }N/G_hVr+-i==C7Fdh#Z`'nξ@oӻcKt,69V-MżcG|i߉o<{Gr‘7m] O|cO8Oa]rW.]b~y93'Sg&b|˄-޹`Tr k("+8XEyʊw-&&΍l%:@GU;$VJǧ' <:l.)^Q8Rp (X(&toO= %Vw3F)eG*PqmXQՓ}׻Nm2l:6Cύ668`LvW(a&$Mv\ţt+.ڭ߿eق6腃=pv/8O:Dy-7n(~. o,tF)ߺb[oz8ߎCq~˛مnG80Ѧoۇ=WcJ-oU~ U”Aӷl'7f8H;x kL*VZo2:TI{(d_;e'ۘ՛\f J}rjz5]|Y$I6Zv>u0+z_jkQ] H":{%_@`v=fwYU2K/!gQ &!ҬTy5` ]Bt h4q@'E%?%S6uX 2; [TC} 26E4W0)hELȼVIF2EcYX uQʡU8y! jJgΛ/&vÇNJ}un[W_}ͪmg z /n>nM+K\}НW޴zltnsSNL# ]R1ѐ3 1ה] ՜+w^+)[u X:b샅bܡo#wνT9mIe4{ם9";zSi[4VK^QHq.x \fBX{1t~g*-j 4~СN.&  =M^ @U0?ނ5e@5քy'wMAY4!i;.05_;qʜsK]<2ƫ.n>tT vտyU sg5^ ;ф,yni͒[,yЩ2#_}֟e‹{/|YK|fKߴuΓ E0VKMm#&!a-:t٩$Q gg]VY qʆBҸv<:QExjTm-?=z֒/ZwsYj 9߁̜ɋ A a B9=?rV3-tu!Bl_6CT#)A^bw~K.tXVNPU^|߼ga=t&C/>7bY~7lY3Ҹ$Z3;<_|#W,[hW]lxߵitk8kDc*\x?|AF_!(OTGs>yW fՓd <1#Qwm^"\,=ӗq4egP unHt]rrCH?=mBT:D^Y"Q%HͰhUlS )\cY M צ&$(Xr8pg0m)ſ0)Vh߾5_{/!/;VeAW`~sDA Paݩ0ݰ q^ay ~E"'Omv"S=U!ۆvmǚ9*F@xĈ\*#H=-Ab<<fvB+$'ʖ-1p_6`CYaFe6. "3ΔD*-&ŵ6֦Z Չ+%I< j‚w\^4)^5 ji1.m:gF񤚭ELYBr9V8=EKt(ɹ&\O%eFi]d6ӅC~1؞oX7iӭT`H WB&,EAbGa,>0`/@,`d (=8QC%HfN@q@=S'?)I[Ӡ[|=G:vDLaQ%u72#y`,@Owǡ{" u =&<`:zq\L+6􌎚RI@Uc?XvO|ACzs+#GTUiX{ сg" ~.n-3'TB ʁ>'&W 58 @G.R,O@*>bKɛ9wAQ+H.9\ Yi#mbwnCoԲ`& 2>TMޒRLAvl#Da!8̓tGiWlĦѨyn*ÄĄ]$Dzșr &#Q$ @YֿMNuI?eSGX~An9nrX͢7Gf O'jV,SL'Q~p6[i v |wmy3gƌ:fr,Q$OEbA!ߋY *JL&[?}?q *wP6 1%@ RPՈ}ºWR+tH6Y*q(fw(N*B;ѳl)'*7Hs;dU[G'XC44F FX# "`az:Uf%İYDP*sb3H=1n`CJtңSA}oqѺcX2٩ebHW%R)|冕K `{ηFW]0XSx]`K<-ml=԰@X"!=,E#L~A3jcAόJ&4>ɾG؊ZPS4]XcW)8 ~V/>oD }C:EYmeOeFIU[{]zlm(AaLB4B0Uh5, *5,RY3B>7D$a#>mdIZ'!AM˽3'^Jh3'iqh:3e hTΧAOy#NK> >a"Lczoj t KdrقnǞ<Acs D&3g0FN'HStK2s>NN6s(o2\*UE|$r\rm#e6lXdw"XK;oa}PժKJ$I{oЩ>?gHCg|L;5;(,6. ?TC0vã'/xa[TYJ$ȑ#Zb긐" `ج;N>h(!'Eڻ<翇 x {jԴr2jR<Xi;'P2q^LzQKL3cW$P#mÊAl.̞GF'jc V"|ukcƴ(OQX-^R$(=^0n3G}1b:wE'GTWk΁R DIא5e)I 0΅0 EP$ڠj`lvS֐iPH4^fB]A L{ZIrWkz(tZ=4")2=s8s8j'r/908> bhM 3K"(ZNPψ (]jfc5ۥ 7|һezUj`-͑RhT! na؈h_C ^-`TQ+_`T ϪމxѲ5 اn=\@s=6W+w#@@b?_ǹ]ܨ;?Z`P(˙E{< `P7Ӄ^͕Q (jjP[4'"#}%ٵ͍ o<&P*~ ;U "P?B6fRd T3ؽ16^ 0" &N}qiu&;)FN9Wd! !R^JnYt;ۥ}Uk>gO8p)|==N6Aj`5F J*|rӽvu`R .)1d\'7>9&9F*҄S@CTO(TC! Z3` tBE\I=Y*!Ek XQ A mQ`< NHMib2`lHblOZCR.nt\!E{cu@ё86vqotv٘Xue}ȚM"O S껕[R2~-!UxA(8-/yR&ռ 4 "*+:ƀ>ڃS4HXaprO=dnvmEr[~*01vD@J9a9E+MtW+ǎG79w}dE>0a( әS}h284j*X{j;Hi [%1`X!ZDeED͠C楞@I=[P-ɑ$p"apNdJ}heQJ 03` 56,X DKځjM+_6H$4K5>(HuMb-BȘkWS%#M~@6eE(袵8 Vb"{V d5^5L{auRT # }kDv n ݼz7J1TS,.n#RA΁W~ޝ.Ѥت*U,ځCL8AM+k6`[.e uޝ9ԮMсs@v;6ӄPX7AÂgՎ :L/M8 ۥKv6wz4݊s¾cԂsFC9yOOs G ;uc=)2'rJPy;Ru֌ivyVtB <֍ܹ,tSsZBN3UTzJ[PA6ѱ|r@$1䨪H(YX`P;> ~R*y"R3X#zvڍh0 ԞI@My`e wR2P]v#Lv+Ih`?)0ip𫎾Pą.e=xT*rј8|^O։ɍK"`DW\)~979=d.RFptR{ǥES*B3'7>Xa M;%Le#fBGESyeďP0M *uaQ5$^ $*V&L Bna>B^A54]@d牸986ƅLp5XA Gޓ"efLE&\He T0(JdtJɃQ’CIV&d e ya"/.XNx`A@&h7^p5[^v|F%-n޵yesG8Xyh`;[tmd %iDWvAQQ_\}P$3YtR oN;3^{ݧŪI;4DI~;$E_,OTY'/u X*ޕ'ADfE:?.s8J4TBգҴtE/0"r&T߂)z19|+/ye=}61: .HIgq'" tҟ1b}A9*wDb6{C acRKÐSj5tQHX76U 5X6ޒ*#HUkC@#J#UbkbȞ`&) ys7_/̆ Zv崘@4cm%J IG-_$*l܋0. cC{9HH~4}oI\B9A' t9m V':hiLK0ZlcS3gvo ~[mu4F4j)I)<q[e^SᅼU7w(69e^NX5x?YjV[NxZU m(XHHl_q:kʹsN+@*KN*LŏaKitgI_04+X3W_$L8PHNBȨ~g8^V@VE{BSVl4M][g;ĈgwRQb򢕞UX$䮣2؞/ܲG_zWY.%\`U+=!(Ӆ5@b@;DflSZp$Lyh.* m @FFfDDB'CQ$L Z;Q&4Eb%/kMKR/9gB"z Q22R8;āh7JȌ>UcEۯQ8[3Oo97f܉ĸP'úKH[u|CLL? %;_vģX6Ė,.al YqQAH>_Qguva ׬\tϞc'ǧj=+-1 OBP1W&Y2iy)ZCg8bb׃O,+ tA6`Y8h=7¬ :e@xA3OT IKT,xv SM!l8S՛dt3?fV4/+ֈΑZPKahp4dc*z(C r/[1~V*怓&}GϗC(MQC{dS'$ )i']!֗OƕX-ͿU|=>r{Td _b8O9NK.[2?lϗW.7} KaT5I( [XDIq&iǤ5:@!_\y3'&U RwNHo %} FX*|=Qa23D3PQU\!}Ҿ!szu@^7&.f|ɬAJ`EZ:\PS@kD#CO# oe4=ORp0q !Jvgp?aJ"iW*m +'ZyݠHz4 =v( 1%ׁ7J~ *8-wՖ# J+V L)0 Ɂݷ"G'C" R}T:c]>;,= f} ቎NzR~'NkfwGWw/v(@|8 &j %c KH$w]?\"O 94FQx vg&=A$aJ|7j9?՟ <[&Дs <X U)5 H)~jQM&F|O CF5 w0%@3RQySVCR/ym0|z@*Su mRblOES 3a'~˖wAk[4 v)oEueKQ>ĻnFD\O4 ͚L"A5^-V"P;:t͔B;J/GwL4m|O3Mq-O.1cE>Ȓ C:)ZOkW \BC_&[ qkSq66^&q| Y:+cL.deH-U-9nsr"TrJUd UPEvcaXDM<09xhh^`z:~S^ѩXMtGxtF@v<%}]0i[</h(96m_)uj9uLV T.YhM|*iKTC|͆wl\Qy`lF/˫/B'D{K>]6fsИrsT~|,PA҄de tz1Ƕ4T~;u] <:)txo;gLy?K KvD:3x; &4PD4#,MO'ӊ&$Izn2X)JͺQ=Sj1^K':,E7l@ & pQgJV +K9s腐^LыI&JFpC `2K4u {COk<}$c4*]v/ֶ-wwq90hޮ5iNYm$ݹb xW͡#7G.I*}Mz9 ەAynߺΓۿ̉`4O9:/ڥ#CDƈ &DU F Dʎy:m鬮!D*!19:)Lb1EV`ͲK^ X-Aicn@K\E{.Ju_WԄ`@Ύ cS]zNhNXq^#)AB4^^ԗR3#)DzhD5XEQaAݼ_%#{Nq* ֞4Aip>w|NԀ,eЏB7" lt$Tt%]WQT6 -aVg]u4Dc_pp;*AsEr{+*2a2<՗ 3|+/vvN]ꉋ6{jXsQ:GJ83սl D}{#;tpgWw;v/Dc+?T=%hq=1kD= n9Df'l^L{Ysg3^ݸV)(ΐ1q&;r*zE~EW/|gxM29\#i %DW>2,LGǁa+GBs\`\D @˫IzA)ID/hqhnN͛A:B4Ϲ=6J\-3\5*V@aV:Ww ǧ["} 7o^aW>ġ0`i:ϑw|n;IɣO3kzcKںre]U뢾)Xߥ;^jpBF e9C%Hxӊڳ[{/uݪ!.rɚ+hdrvnD4:zk.[!;*p!*k4h.M^tMTVџn ~}2&LÁk2"#TJBM&)S{@ՌUJjJբla~鴹R(?Liw_O=u#g~koY4H#{ضCϞ#uՃ07fN 5Ї?T y%Wuyq5BJ | v9&Ϥ׭Հvq_CP-N2hkFb)߁}A]Qy?`8;T5/XaNKBXR+E f{ģ}.1PL DRI ЋYu6v=W`T 1ung]bd)#p#'?v)51Ի1JD =MYlIS+T AõP(K~QNP\Bꝗc5N["tcB)u*qaAxCL:AЅsK\p>srwo^yc3g6.?gŗx7ZeقuF2s*7='N q}nEd~ Q(+a6¯o"XFXkFU܏U J:n+$G !G 3c1@Qq&$0ٮ ICHWb-xͽ"ϷPA%m WHTa+QԘQdAC@ 肼$c7nh(:܌m4k'#B P1`OęI*"|"-?9ѲS_54՜؜dßs׬6l`叾 .&4+ LB S9;=6|n}`q;3V|˄-j43΃޴u͵+/PL' m~ZH:/0^t!6b<[e,)SPDCbIc"Bv裒"7T+j+Q-e=-+5:[<|cS9~;6߭:'۟>O,~S ]b /l ضCW,/(Zٿ|OV:^bܶ{#.ƺ:v'ԇ_qg*J2ņԏ,.#3FS ߣvBMͳ@ ހyy&5 ^JCtkXIxMΈވlUwvu@]}?] H;&. ρKpNcO+*D_JSTh枢)H',ď d GE{߰dɱ-:< \H<#?oӗk߸oǮS&k\ŏ/$X_H901,H~ v @G_6ޣ׮+yFfkz0ԍ!*tzA} &0Dי4P}Ri'F2sF}4=X 4wld i*FQ+NDZ=&;:k )pie8QihCp\ Yr ]]/b_ʐ3QMF/9L_[0gDRIBKQ;05T!ZF_&ѺK˿Či{%Bx6W *}-H,RJeF(L\j*4Py*녑ôCg_嚥fGVϞ)4:lg늅s95/<ı_;z^=kSO={j?gԭ>G+97}7^rߪx=WԿ|Ɵ}`Tl}TTDX߇)eUSQO9CIAln a-$BjT yVEYgA`5iӤrk}f/M{,XԜ}Ǻzg<)%GE[]^9/_lrP[qY_P}=&LF|5Sj{KJd)GF@g톈g? `T(.hTD=k3RС,c: Bڞ 8ԁh%Re"-k6VW-_p=~j!>tYpHst'~kO؞>=ՃnZxh}_yc)>cчqբΌO}o߉l^:y}z:@y͚S9P<+-k/۶\r}@B骦yg!3KKf*,|1Q<2nj)*~{3=}|?@_D9dtܞCw*+lxl`c [_  U$EE湆Uk:Bv[aS>|o\noSodAT.4@#G Zt_\|3Z gwb7X7Oea|gϼo^yŏ^n7jc?_3Iġ r?peC"-w^a9%zN7kfpo'[6"|vrÏnO\)4M عV)]hg4[}h'v>K((ui6\%4cvh.![պ޸J[@롪뺤s|z[MQ$AEf!wuĒc*A~(b k,SHyPԉy ox`=MM%9F?a>t"7-eCR/|W褢 AjsC{m/(B8 20}}c?3}%ۼ˗\|/>st[8]yǏ}8i‘ Zށ8gxLqp +ܴU{D8S}xq (Vaqbc7l zSpxf1ʞ!Ёաxe#Cr[3}+p;o5郟u75 Gk7,l,?}{zϱ7_[= v̭@o޺/7^c;qϞ.62w߼fArR~fϱ8vLL$Y;Wb..q1=2(Q8pNؔZH`T~4$~6!s CgF^̥=7-1hE ӌp[}dI=N ϿhW`=`]b~ƋTh3E.,o 1h/em0?4huqhkmN7*iu$?('#Bp@3*?@hx /]z .2d^dk}WGgIH-ko 3g&ŧL!^Z@x|Mo]V::_f;^}g]_U뗷}5/ n!:9ç~L,NSWwɛ'[[qE/ietg&"v)^Y/tμ#z̤qjGK=fն ~& ]N8tbnv7}7(|B'$v dp17czf!즖*(QhzQ,E}VDI~`zPBhW^V* .1(Uvi3LX2MMb贂xL7ؐ cRnk/r}W3vI]-JXjL]IV΀0NsT_ɌCsG,J̴\^ #; 7G*"rV2u1CHp|Q@i!w 1jiÿ~z>ԑq\^vEP/~+O߸jA,?x;< ^noF}'ࡧ/&8/+`7?c1D?oN#LnK@FkAvnOa=Q1JOeF̽ɍ(E,m+$b[s`e-<0G-ʖuft4q Gk#9TIFdՋcP)J0 :ُ$msQHBa'Z;.Z0b.KX/\D@XbYgNOLrÊ׮\xGF'kf{V-.`Oܸ~֟8zyйcCH]x+/3L|72%@cߺ}덫%5okk6,-w޷.R ]n+Jt6R['KrrN{Tm$홭 ZN侁'^7|C;yV#59uх^^nB9`Y hr1 Mo6C< / 9 2I{s!Ho]P%.K Gн`lBtIuc B UdnKu4B r''XaA˒ɨͽ#=\6JZ >`K0,N~!y(39 ҩn;~v׉ڰbȣE;7xeKOOL<7$l[oK/Rÿu߶6vrbϜxhIt+WM Է*zͯz_v# |˷my5Ittc'Ʀrī7\rɶ*>.k+PQŷ|i~T=˿uO߼a(I=_wRBc jO8 4>V*<j @{ZʌGuIKu8ŝɊR+H.I.%7r0W0 J[ nh'N8ObܓO+yv[L]+^3G,#0M9rg_U[C{(/W=?>hy )r6;ɭ2䴢:|(~N\\9%Jn@db~V[Eӎ~2q+c9>6}'vԶ#/^M+nXXb҆~}㍫w#z'vE?&:]_x#ԃ ]ݱqĹw߿X_9佯ZfU}{/v+.g (A?O+d໶#Y޿xb?iLlF{sihК#yG Xű*& h Df`K dw`(}w0KSKx=6D`= E.X)G<8]{V\!/ŮUDuJ><*m @u6:RЏ`QQ4&u\L>P;}VQHs F>?rԬ~>',rkG]N"on @R,{-~ d+}j3GF'FSCٲ\t #OΗu8IpCWuW=p_O>VBá).DJBbH/thIgjDҠbI-R$׺ah`Ы{_wC*mI/DcɁ@ X`HQc>K'4:˹Jj&SQGɥy˸=#=XSb:hɅ#v7=*)T!{i'>K'h~/%*k%dևT 1A"?Z [ F'¥C YžH?0BnճwuG}sPܧ4;6W_-۱cz=Ǿl:; u޴uͫyh+g71_W~+Z<С9C?{ouYvV橫깥j[jHD  1g Yda066!!x+BBb BRVK=Hzkz;{9x}.Up}lڄxw '=?4}{wO_M??8xʵU8#\g̟IWCSK^\lxӑTRlfǰO")*cf6b*BWe5&rC 9jhnE,a6+LT-RݜJ*:YcJ̗7f7{:5y,2"xHK}XUicd0Z BP)0t`)˹?!0/گ(laeUr ʗ3&uਿ ^D BMQk+A{+Vٵߺm7_{z >s Eȗ淿h=3>ء;8Nܽe:gsڙ/c}C3~ӏ>y씑JH]mzTGN~*vmb߮_skdfGyx?ѦŨDҫ˗]s`?gOw?[=pU0Ea ޙ SܠV,I9qJT7艳 F4g{mbvomqw8P[K_>>~IaVrNvW8h>?cϝԓgg6o|-wۯ]Ow}ឧH߼6y +^yiϜ>=JBF4 U8OєF)rQ*h$DRW' [E޲܆_[oSqs0_J=v刽5M\&4xR)`Im=ǀ DOe.Y gX%o/8dtPt`4LDZ0JZ*?& dA&^%Rd`[6yqTRf3W}dm PKfe=ح)2e9}Ӵ{˦qέo߼stmIgG{́O}Я~;8G,2]7>K!*:7{sshsR /f*Kl]Bˋ"!0mP$P>4XάeK)#IFRos>:pS $,W}DW?wF/<$ex4F݇SR)kO?{(V^->^< Br R@e,'*tىE2FV"f\C]iӐU0+**&P1ձR2׊W Ze($e BwL֌ZOh@taqA7r7txة?zߺGN:p ˒r~K6›Oo{')Iw’VL[Z Iu "J7PYp3Sjfv`P3HEdZ-CoH VڬB[x/ `?+'n:/ A*TG 6{*^AΆVR U56/k*W'FSS5~yr2VeUhgzLCfn35 QXC ɃZ]`zm5ho۷뫯UW]r˥;'w{>#Q/ֶ=BŔQ1RChr_;sޝf={'Cyhg `MCXqQSL>V9*JD(eB* y>Nx"R[oOUo TaH# 0J(1DrjEvB*{+2ڑhCH=4\jHnDZjumd_$Mb>m/0􏝆 Nmw( unvk`

eE̕I9 a%:1E*l,3ި_أ߉=֑1%`v#?zh#xj?,sC*{.~X6;M{;z-TkQNRnv50qf#WM&H&L&1TeaWg5//<,yF?ݼd[{YѼ uxV'/YDLá^:S,%2'- xCޠ]1sU r`@@{918\ vK 4DŐ]Û# eqɚ@ǎdn%2;ڶFfHxsNq'S ټ 2fȉ@w&@i] a;.V"QSNguN;զ,k!z!VDc`#ɫ%[< o=Y&ˌM0M 0Wa Ƭn=]r}uTllT@]> KASqmi S%'sg%*\B?L beseIP")*vG\b=ar'E0FrR\ҁSQ5C$ '< B-&Ző<%qiPB%YHmkAeе>˘aPP X1t#rsV4:B˟Μ]e׾!-kLyD&ݒ% Dm4>h2 eUM%+Y3d(܁@ /p"pU%8vvs2bs?t`o! kwTG՞.oX` :c0t)\T&Б:BҀܼE(Cpm[hnPf^K'%_-+T"o"2eY59PDZaś{&&e~Aq%Zr5ID{ F摒242]q ^YĵsvZ\S`:S$S-;K"#љD㙗!U 0Ch ~ ZT`5#5/hhf@O@j!M*-LDM7%CdYjҋxl4>Y]( /l78T7H.J !z4۴ؐ '$CV"A}%`h#nO$<̦6zqb~mV[]PQλDUWP5S>cnxj)|AbAx!`u(}:Yi"̚s[YoI[HΠ⺳喁&A%Y9Nb9y˙%sK)fJ8N7>UPLP3S0*NЫ迋cWJ;AY{P](e%)&,/sSDxI$9sޒdKD2oɶB~CxzLV蚉zu)̄TQU[o:c_*mBR{=,:Lvd~ģqqHZkGx q9++K~ 6X}W_Mfj XA85+&$wHPUV(F-,3 ѯ‚m4V˪w$"ƠpGT{5)MkdTĤAe]H$$-vӻ] &ͫ c3OZ *faxTW M*p6q=׿.'/z@o wv)1 D Igs[?b(b"`_v<=>gpgu<vNX1AM&#rIxմR$ChF蕂*>- tsנ~D506Nq2cJY$xALTM]|&AP@m2t&D99YNz崉{#!J?Bke"+ə!u /'@3?M銻 ДLE|RB +(%dK׾# _qO\dG"BT Ԗ%^O0 9@Ҍee}J;yb *.5%'v֥زtfgT T̑{Յ5d^ %g֮ΕS (ʧK IOncDsc*zjW=r֩pBCgH5@?THNGI 8kBNaK&dhƔFHJ ;L/*╷~:~Hv,M=.%3*5RZBt5e-Q|xg|[qd7F$&$Mߒ,!RBىU6$v=lIC^r?ĜЯDF^ N ] jKT6DRKnU(/ ~\5W`f Jd\GR8Z"XR#1͔[Ec*WnCt,7ҕ.x1< ™7=ț53m/7H~ʗ1uH,Qe\%T9M?׷&P"}֙1F,yA`ܿ]q8\J9 !BĎ$'@GԺQ꧖+Co eB2AU\v" Ĕ8psD$G=P%1SR!5_E\d$r@Gw,Ӻ b٬B!y?O25~%䚆 UKD3Kp1rKwb'BTyuYP@  p@*rOUgPiی@2ׁ'2;rSF:oTI>L,1d$efvKk;cIn׵dt\šZ>*Iq>@_0%jЯ:4YͧtZrT璓aZ7 rV (T6ExT{˲DTi 3ާL ~'n 'Lb+hP3[*0 CjJ[# a0R[[@jGjK=ý880!hD=ٛ$y!fYPjqPX+q*b RݝP9eBYCmwȅYIWuɑ vT-$kdQϣ L,`ਐ;;1؈1 ؃5e{B99!p PbȮ*A ̉Pl 'wj "xU9 p,POz`%+Ux'+yPǗ&$U!n6*C*C7`E!bl04ؕ)a1rjT440 xYtOs5L+k@gDbzd[X$ѽke=)Y<(,y^խlA}Ly3IgW!"* (iHѷ!Γ$D`Ay-21-Dyd]! G> \[4'o"ly{$ثӽvV!\R( J$cK*+ZLAJ]xB`܉ƏS#0~ 5#JH- YTG%ՕQ]5ŌϠ@Ŧԏȿ'g3"Ia`=I.SJ,aE#VLrߍyB!GЂ~Jx5gQ8uR|NkbU+闡m:c'>j˹jQl+@3q6 glbA)"0ԺBi,V1g+R2m>`.ɲx>/TSC"/T݌B)TQx)}3@O Bt <.1h뵦l8h9M^e%fđSqQ߳j2JKw] rs1UO '&՗ub9* @rġ70%IV˭ IW JI+bVwIC\s] GM6JU}K/ZG EA`((%ЫJ|vC&} kd]nQ Z/CQZ. DƱ 8 kMtHRa DMfGeV2ve(@6'u⾄¬$ٟASG"TtC .db8:DR[Gp HP),ULyLDap F=Z; *C]K'4c !MW%ݽk$۪6^VDZ4*ģ\t *EWGw8筛т:3{{㾲M`fYv`".& BrֽtZ0"_S^tqmq`%+fW:;[j-/E$LJsC칋.R"Æ|?77}4|۳ pomAITMeT4\ d\a+*6۞X5KNJ!GWݎ bbn6QT*VV߀aƷ1x%+0=Q|̵.:R6T׉]P޷ж)@m&+BB Ţ"~ &Ja}czG)*{ t&.e\9%iI/?wܱbHlf/HZbkX,Oqը!b/paΙ{:G&!+w2nRfae"AYvTv[O@bNFj@Hn,PDO0E")TAL^tHxw"Gj*# ЂNJRAEKv7Q`oI*24 {p ?1ejAMmo!r$SV@!ە$Wd^m 0# #޶0T.'}V QEv-@Gin j` Y@L=X4sւ'q34%yχ٢'ՠ%K~D9#׵bZ@}"u\KFMs M\IG<FA9*>;QanuMEvyQ#mFU=)6r^$t6%9:Y$ƂG2h|8V $HsLt"s7NbC & .-#7BjYP@a I5 K#5Jߨ9%leT$1vK2L즍 wBKr 1hu3iMtfɆޛ-N:aWn%+СH%a8qvF'"A~5F1\Z)6RKE#ᩴ=֧a,vKe34|LzCЙ'Q]:U5 .1p, 5_;f1.[hKҵʹ["T."+Q*Tݵ)(k5r:&8'KdC"IM"9.c"_S넫8 ,Sתdj1(w-Tg V\,I2Y)mAR=w,a.@dE2-'aĔd&!dbɀf6R]He)h "XjI#+Dae:b |kh` LocTkucƛ{,bhQt"8HU"4U6H^iW!AJ!,+N3Z>'?aSÖaC*s!,lXϤ( f׏Y"c_Azoس}38s8-Az{d}Wrǖϝ>ıw>qę6Kr'زcg;zO>un_hwFʎF2 Vi%u\~- *ln4[}=G 4g.F(T83u>gDXГ#'l= 2o((3XOJ8B=Ū/ '7MyUo{ѕ?3WK6жvMSIfLM哓 %/Q /kռr*1"52 Sϝ>#Հ6s{0$ _96M&o]y_/'>߸ $ ی]H:NIp$9DB*}\Z_Y-ν#,5,ڏHm|X)B[bȮʸDǜ% #JV4qT&a4 ƣb]+(M>@V2&u(րMIWʋLlbBͼ"l07d'1@})u~%b\^i5QK-ƗV`ius$F{ϯGH4ћo#I%:]oIuŘ{_}| B:c?iB?[ڭ%((Rv.-FsP(}ǂ/jH`Fhw6 鹛ZէU!36M.Ywש ?2*/Z&qUhrSTcUD~46 70CU0 bէr6^ 89sXM*cdt uC؀O n4^ʠ7Q躉Dg6DU,ic U@RXrS۔SQ2NJ'dZOG>z`rR&صe./s߁?{虧:]z5} \[>]B9yWݘ鳿z##2}5^yՍyOs}v#ݺ髮l@|x݋?$ҽ _>#oywq{?pfDbv2HzyUD;z' pׁgosxݯ<}Pgye77| ۟ӷdLj(zԷ.'uIR#ޡ;bkԁB Ie=Ϳyg#{l8q`IʒG`Bdsg1ԁ-'c/.k u R5V6Íy2bq#X$=KH:0Q FQ| eN އ-SN/e?2ީXQ@}>o?oͩ-NSBk]tϝߪ64{Y"·~򈊉>;?etߛ&x#/ sSG3KnvH9qo[n%JaB*N% pKt f@Q~mnUd?F^w63Mф%o<C3)Xy1g0CngA*}xMf/FQ~*2v/G7a$4d6vM'o7Mj>*l8mKfB!>wxp:$Q %YQ`j{nj9{s?~mWFF* \ =zέc|0 dpxn[ 3Ԧ r.MQ٬ B0H`p(r2-*ȥZ-Mw)U뙼!~sIC@D;گ۷R3Yzǜ%vAsg3$oXDpTd0RkgfHʈ@z߆ zsGR/{Ir]8\Ŧ/_I8#^1$NYS$7r:")Sضϫ_TSs%AU< D0.۶)ѣ'O?˶mY|Rmm[oyHZ'O?Uu%3OOnq࠿q1%!Ubk֖{JGU0P7T qE"5EOO>w*qDz$ OZEE`HJ2K4{~8sIV)I-$ 'uWHZ$s;H5I+ YxmV`E,prr,ܙ&][amjzg%"Қ ~zXV: [)2^ CHcLN4sRdqmDERN9S_ldit P/z*,]JNHv~ ŕ틦KR%kTLRyͷl-ؙ`f yE4i*O<9baW7ˌ:(`!k}r_}$S<+꣥ֆd6/wҝL7x H'3QEDgɂ, 9>FC"2)2$a]z{:FܰފjVSIɬ؞$bQcF$B߻gh`T JȊ+, KӋu L4`P=}(1R.j0%Ow ޜ"ScY"QڴϺ?AQrē\6JVh.Xq:j"hxï_$͜Ō)lq"5(Ϻ ST?~##o}ş~[/j蔔paHʲThbBM JX\wpZ"9K{2(]$PF5 uo>$ 0COғ0{` a $%M&?Q_5".vY g8B!U 7o83#M**,%KeQ BYSS56DDjo#g/ wN$ .8a>u|AW]\1ԙS[O-D(( 4nK*NWCP:7K_}i-7;v}_JjD(֕w##2[SR<̂E=)uJ5l ]"oyC($p粖u!Cl[4iP,8Md,UGȡU=20 k&%0w&0 $ ȉ8&+ʪ (S%( CHb(|F&HWtB|Ӟ{t.t!#'W?o>]q>vl77k^|NJC}q]xOX%RpZfZ%Მb&7hcW [W5K%eWz# `I \54PWfW ':U͏&E܈I,YJ' #H@\i*sh.]fHyUxb:%qr+;՛)L܎1lxUɻ5dG)G i-8}:ȕŷ e, | (]x.H!qQ$(%a(͘y`Q%Q5uH>9gowG!҆1!ziظ,rAZ%{ @W2 W#N**Uf$g@)jZ~ \ > Pԫs1I_@݄l<Ƀt Y-!6oxEgEQRt6흘˨$ȫaSf-w]YvݺS-Ŝ"b^1w׼G|C>] Da<PP%R1 um_3#&^e偗A, UAWqǷB)>l C6R/vZ"q0y }M";[tlT50>D (Di' L*lZ$ڭ,S摕?{S*P{kyTOPU%#ѣ'o^e 5?mIf knl|Մmguh"5?yGzo,_k_ֱsLֱ)oĝq>r»*G&A״$k?w\ƻ]Y=L_uEm %n?o7P64zn؄dy3gmdyӵtߵugcE09r2ayq!gCkD"IKh\?x+Ap@k/vZ44f$SvO)|\:&G $;\y9C͹ISkݝ䱘6bU XN$23Tgrö5!d"JV$9<}у/bwxus`[>!xLOG\#}{Wd?݉VWS#p]N$ȳ5_]tB} Oo1?w\ow;e^cx5O᧗*wiqi$xo}gf y@tەrc COrbe)TieW_csCĶ eti}.?{m_u<]mm]O~ӏv0B%gy{nWE{wp>z~;O$),FX,mkzwzWf!/w13O!hFjIb˾_vOM/uM_{?x 9]k6M6OhõIR[0O.~>!GMV^uv?E?3Y=^\n4?H=ʐV)];x|OԷE@YZwEXiOj6J}D("V# U< 8jJ-2UÒ[S77~~'}½<{,;K¼?/n~wчw_OgΕy/MyẓҖ[}uηi7uD]TE-;ko<ĎaRTg1e)L҅+bJT .kxǙ+CZ` L )1fL/QJҬҚqNVxSENRQ5>~_~϶o~=g? ~)ٞ$`+Ip? s(XDn #eVa_`EwIF uIV8SO+2f׶kvm}v=\}cï[/u+]Kw=8}+A?ߵu״9s${ sZ05\;ҝ|Kmn>m"7KǏg䭟s y 3[vD))N^OARs?O1u>7?:3[l7f)qlǡg~Oٿ\ HT]}]OJO#'w>Rˆ =O_8Py҃'Nz}7-0$^Xj4}ܴ̏A3x|h BĚ$Pl:hUWe(&$4׳ݵ c3E[eWafl ̲?d+=i r+F9J hE9p`Wd7+;7O閫xe\sMqZŠ#m־x_qP`Aև?(AWXXEl/F]57՗õtɎy93={]O9<7Cğǚ1GCƗ\.ѥ;ugSGO'h Wj (:Kc.\OϞ[D;=I&Kp,3c{&w L,g(.'}wJd?6\^5VMt]{5Q1286CgLV["UuXIx6z/җ#uTZub<)Ix 2r^^2|ɍ}I^wQ,MER 81T^(z~p|xxRaכֿA{tUS@/(SYdƴD2CѺQƛ'ϡ;O ί4muť?z; 5nMւQ&2kOh RI5uxSk*.fz<ŏ$၈i5+*qSI1B0>F2,PGZ׼;yf) rTI0i$j<,}7,Rj_~"L2G&+1PWGu  @lv́b !tX.Gr1)ޞ w&`/t<'摊IC6ǟӵER)c2$n6ahm&X1<i*lRt jģsX/"zMxTSd B-th4G:.m`7! a[MONU*(8n[B5:a!"Ѹ;rdYChcJc#Y|T󻓐~I"鵍BEd1#yzGg!Ƚ{`&b^氿C/^uR1oIXRde5`eZ0[xQYJahgmV퍚CQej(vyq(uT&ZtfNi2_X)AXQ i<ڋ % L\U׬oSJ:M4bPkɇ\ï !kbzM CSi^!*+ИE9¤7q (X:ԣ{;l`e힧:ab'Bb=>(=Ƚ䕦ڙIEMnz['o/Iv͕?;(A5-): 3e(́:iBC{K;;gu@9? ߯Gh\'D(0wY|aRg(>IQ}D3OcEW 2XFSEQ@A1ӤQDz}Y,e#2} 5X$؎M&ÖnHJ&Idj0Tbm4l6D޼O$zf9 "EkÅ{h[{n-:9đ=*&p=\&i--Ȇ`ri=$u"=1Ez})-%/+' nMꠅN)s&(F#aw5?. !ՅQCя 9ɸ!a>6x\~@85 )ovjD܁R (]ZgUrêThUGy?hMhw/A_D:Vz,"9#PLҊ@fiGr7x!2@-1=KUFΑ !dFN1h>IlUo6aB]/J JSEuDZvI"w@*jZHvR_ |S$(|&Mt} 4 .1HkkM(ss 0HM}aQջXAfCm{>БzdlQg;V,:_oZT?EN9;PH\׎x#=tp)"6T 'R@rvZrxR "%)$$bދb/+(PAFˋ(~E NU74 cLJOȱ`v{,dFbTgK |.#5JATrnQO6zPNC L҈k jI,[r'|wsh]yMa8>OZt'z߰/ڥx7O)7'xX7HtB 0ua̮rJIIh5E@,n3F%[IrD&M7'<͋c70#o`B`$y^!㱴l9 (T\Y?ɛ*t9N)9UTe ަjA@c07~)T#ilN[t"(tuQmDIIM i\^q1'p1u ak\{!w`qDmSiX݂̐TBu_}힝^ݵ Lzׅ˓w`(-Pj\LuL.1 (ՠST*4+>FP SHCl^m%9VNa҂u)xob]]WX&i1O"ԓZQC]us6AȟDGZ!#J {(Zbt?sᒵvuND;(v%hFiЖ.%-+rwug?ܹ  M֍H#ڐsl/㾃?k};#':ĕ" 飢?s $ͧNn$6Mi'h)GdUo*|+[c`*zZ*pT&?F{  $ӈY*YH O "@6cR&7xF`=L$A1Y&S󢽽#ξg߽M^wt; Xxj?vEh{IB' \>." PP>!/2@& S722rj*3q)(Z#|y(^~!C\pۋ~蕫W9C:lHu\ {l³)W;!B͌hy?.Ff %8TnQԽ4*SIt\B& tRqr7M6-qNb@W+ۆmN9@UCx$6AqlvT$hD*r `N; + "ڋ3Kr5`G'OA誅N=fIhj|B<Ϟ}9"VпzDʃmgȪ% .ѧK]Iގ2nvܤn*Bg-(ҚHb%Ւh  w'rf- un*WkBic43oIiĤcK@[|%/zVBВԋ_LwMGXpOvZ 1Ȃ!$Ez>!^J}(7"XPeʋB_ryI:bW$'4x%NO0uޑF }ۻU?) I`4 iTtp8Ε 6À !w@rHyG{뛛-CQ룒i${8-X@,)7NqrpP QHi(ժ$ vi5p.kPUe:I#58ՇaڊeҢ/K{ nT&4')CS&˟Ҹ-gw '&n"57' ƃU-m5c'xIBaLLNU oK%px>PVm 5mg[.MvoiZiḠ-:n|x;tݟ{F YM_Yo.;+]{0B-PRڡP_U0%@(C&O@j)񒤴F_)Z3<:bbI΅'p:ΎSPM=TbcTC3hXi36ݖ#U2{!D61$b\3(Sݤ\~T03R xJGwE'+u_=;&bTL$`t"YT {iK+#/%/`a(z()SGjX qD%15yԂ jhGaTuLjAbO Z\Jy+^yAˑO NUodyр<;?ҳl'%ku>WJ6,EBg&UgXV2TvVG8zjʕ DFFrwF"K/ţ$s Ԗ ``PcVW 7k!|XmЙm=8 aE_F$:/m|%׼ s!̦#Yǫ&4)OG'@ 25I2A[Ӄ5 p&Fgz+nGd Vn ufyTQDV-(8 7Qb*'ϔu˲+wWИFT԰'n3i ¥GY^;CH)S 2IM { A 1Sw h.DEU[8h,/Y vz)vfwepp\吽(r1u:yջo|'C(ڰRYiYhZBr)멫[Ĉg'b=f~FNĀ}BvY%5X57ٖ*ε>bJ~i9GVL' D5GHKg:qs4e:%6i>7R?YpJZ{ &#Ī`'dosVPuw/ RdkG.r"JnōɥdϑYHysD:GxpΨ]3buGY?sW#9[&IBٹY| =$Ma=U\Y<$R!C=5(mBO*$y1iw!TOxwd:\] "/ȞXgè=QΈ!{9hWmjJzqmyZF \@V_g{fۘɦNGM55U^Y]qNҼ3VLܐ,TB3Ԡ&GKNM/V|\l d(2=$G/'JrhwJ ^WBO=f,GEBJuUh)ԵAbźDX峦tUrG&)@QzCkS..HrT+ ju P"(bRAK~Kw "<c<&~ʎ&1sΆ֦ff s89Jpkn' 5K WuτF0DY{s%1Kphk$\=F k.M$I;Awˡpo<:[n4LL=ˤ o2Ac-YKgKLϥBnNyЮph4+1m~?R-ߘ7-P)Iwi)q*,J yJBChrtc<ㅌJ],tIZx2443J&(BUȻ"7Qq{7(I_K&Z5NɉHS#294^IUJEo9ٞsIuͦR7&=|v%)h0AT' pCZ7؍J7Ld8Cqv?9C|gT`&66/s $iO\mPwP/ؕ<A-sKdf Q!AɈ]{j.[@_k ^m;1qIlL 3WK߱x ]b'Q81aMOy#g)@V$ ȩ?BjF޶^©c| mCuN [&X 6B'&&`gn0.y>@;b6, 1Q-NX?{O=|)JH3Xb $j+"VNfJmRXfl2)u^K :sդkt5u*XOh6H/g'7?3r+Ū7s[ 0h*h~яxDž.5֦a!&Fyq{gFΜSCJVl(a@SW;TLJ=bk0|9x?-kZ) ~B0mT@ RFwJf J>w`ZWLz*Qwo[(B(OJn DY,Z.Oj:E>Rr),C8Q@]3š. lŲax(VF+r+RϸTT,{II) I']8^4? QuL2׎ ءwuTK!ILj(z9&r|/pmK9(Zn S1ºэ GA6rJr`jo};Y11~d+hnrADCIi{d7M{Z_Q9bm4"Z!=uT"|}|RzKnW&婆XW"$Gr!DWY) r!@s~iU߷ʪ^Ѓ'QTT>ߥ[q:/ɠet8lcBKJnO{d0 $]hQ|wNUuӨ}%O,@@eD2|JEpAWG(:1@ JE%ڕ I}:k4te>$yȤPF# ;iPhIg DEd,X94^Jڃ$2R7pB?i(n*AXms?@"P ?QyjX ұj%(v!>`eW9k hٹpW;(Vze @뎆sPpnBB܂r=+Wum=P!@}`xxG\?"P-π 㪼))LP$ o@ߊdOP&tz\Hx|5}cnnDpܴm*QV 2&UEܪDe,+-44)UK&~ddŠeǀm`'M n\OJM^ B<@CI۳yQǔ^qO'zUC#tڒfA38s^kXN(m<%]d% pF֝=6,V0'y++hp@=D?lF1kiVztb}$-B*;?@h=:̴*E{$OÚuT،tE ,S]t8Ljerooxx|M8$ҾYzũ<*&2)vDM;kR =RuY[^̜&t(4]r?VPs8." FR&VKzN[ԃի`Fm:a"7_ɝ(I#d6dREך%τ3Ր(Q?If$Ec<^3e|g>:5t $asS_OVS0JH z ӧX;/>;A U꼂KUu RkYmsÆ93̵޴=IaPQXO>QCd[V*3j~P s*4"U%Rz7dJә|I\z$j 7)iR>YM%UoUcVJT]W5gQ ޮru;$:HE^+k!<0K}֗0nPV Mtbu ɽ!_"th0r0L|޵(Ƒ8!v]ߢۙdbnJ }yQts^^HbOwgh eAU9Ry LT%VzHv@AZMܧz$EX>L Y A'ʷdHt#br^! /2w^ nѧ$[oF$O ~&2FBFǍ-w(n/tJnhB0/B|6Y~Csx0:6=xҧ1D*h~)+萋buR$ ;[hi4CĚ"aOyi;Z!jD d+cšKN-O @hY'.XaybȇUB^ &+Q?W`_l_Dɀh4xuǡfn_ȡ0罦֑>6bhKAC-}wnrt/ikȈThq~L9ts[FQ! 6;Jc~peeWe?WwBrz([[y*T!bgML*37}$C*DAI|D[DImBŸf5\؉rלz䢄-{XT mbsi˙L2[1T5,">|_vN5am5uPN5ޡK+ >dri6TqkN ŇU'vg__@=5iuvĥ^߇"<#™Ov;N:d۷'S~ FFJOq|JϯLz5oQ<_9 g] "Ct.he)ssbсgZit2APQvq }jݭQhj}ǫtJfè)8a 1E\anW ȓ5s%ɦ"DwϏ⸸3,?kY d"uoCctQ6![˜,Ooz 7ꌺnbHc/,i0l Xj%,=h/ZgXC\q Ѣ ,Va z~wP-)5< S 3*]BHC\KSa\dٍ7r^ >hPqɣrܾ uO@?~5H 0ڜW[[~Ǡ6h;Og=w t%O" )E;4H=/G @QC]KF/gSN%i9}X75p^~ N ep+k)b^sNwaP,yLG06!er"VԨXȚ Uev@3z4f) x29RN)F,cye,jm]kr$ &d$'B5P+{?yr '`xŅ$}j }NLQ[ϓLٙJ;Ki0 yƣAFBj5_j!tiQ=nxgJZH($Kn j#!ŔeFnƝ9*"+k=#YѦ[5)(pڹ')(:fg *M*6yfQ# j]y;}%tо11O@A #Qi?sV&D? !Ì3`Ƹ4M ,P!f;bhDYɈQYts)flW'\Q"}*P}v[d#!1!*$z%k~HU뀼X.Z)lCţRѺ(8Y@1]ytqcQf׾΋# Cّϴ_a2oD=T۔j} =L0UDmI6_{^'Cv.ZNPHί=uԎc "kіUX2IݨϠl1qhsU 6=F Vbۍ ~zu HYϨa%N ܹ:ki\!%q|,^uIgsb|-*&ldULԑN_ 1wcple2I @y7惡,hi_.-{V= aMMA*C~dWKg$KYL>y.bַ̡2D uY%_;q>y'F6hyۉuG>9E%U49}RNzD{v}g=A8W48ظD]B?,sxNk蕌:.xQh[S2g.F)E9V~}d)$S$f'$$|NtͫΤ)*5~Tve[}нaN$(Gp&4rk3^{nYy5hQY8`(`iC^㢲xk]vk a<p˧2&cXG1V  NYR t:.: JBtF£dž"  e#:YUVt5aOzk?Q&5.> 0$hOmn'5ryJ:=vE"D՞*,lm>Uda"0y!\nrH17#( ~~|2qՂϨ@ A@ dLF@s_^R5DNk%DŽTuLYQi=4d4L:{HhΈ%H`D"r[ZyӼAZ81 \xj!.ZO4=2ߠۘeqWq1lVaeXR qVg? ɧYD6k%H'Oon’eζ[@'s'QiMC&)|tFX]FlK 9}ƈ >W3(qCHt46B( CxO_i"5 +%"}iluo0t\amHEbd~5}s#2匪hBu5P .[4^遽-'!UKW $j"m0abEd4{-rqn!\+wvNm>@hsm OAEj0 /B#t"kiF?8DM1P@1: 94[jϸ:%(Q {R,VBcX;e hGAeN7kq+a$!J&Aꋐ;]}Dk' _(seam>D_:?Uo ϙ!nѮrN6{ xq(/fF<[[Wĕ(0 ۺ6㰩m4# F9JdMS UN0)R!xB xZޜ4,ҚJ=dhzJWvxCQ{Ō/>w@mp]7Õ< qBYTT,8k'8 ca4"#@&P]n@Ub0h5,2^i;HEb(r"0]5~A|B)?2;~9roqxaά0ZTxZTgQp蔁Ԍ+WH5BOJK:Xd H^k&qTgG'#.:Aܲx Q _8Q|c'xTGy)FsbDPZX:3IbmBEKnAS( ;b7I|W#(ִB{Vt$?>Oe.4[ n4 ̌49t#FW,a~>R\8Vͨi Ɯƨb[ț^|}c3՛O(b =/'K:8k_,ɰH7d(8%zHpeVY ~JJςl4Q`"24ݫ .Ў89 { zZ[vzBo0;۪LG UK~W5-4N0ԼVe1F4OrÒ?q'b_ ;ܩe|ɦl3۲hF;m\)zDwp'ngB9 덝= [C@JYSzm:YCitgU ]6?7+y d aHz_XY+jzxvzwjtw]Da>g~~V1H2RHp,沽̷-ՅByv(nvvbi?F & V€ Zt ²0xᔶZ q!2lIz8ڮZ+dSL}BJ d%DI6Bt\F'aYNQ%âP}#7]c)pu{3$ӻuG.K ~6i_33T= Ȉ\b lg: A^qy$r36/BF+4{7W#H*z,)/$jjQNF Ssl'r7؆}>īb_5A,-FjVqVjEM̝[ !aUjul~*Uz$"Cj(‰Ğl6WOd9*{RKv- i^s&cf)8ⶖ3wwRi;ϿF=OeZ>Xɖ\&)TuM5$-B;OMu~:vC S{~Xh4r,P7 ]^(YcOo;EGFDE* ho@)'5 qirEυ GN >&24\Ic^:4,,;+J< ܘ?͓`#`0SuQ\(6oRZM+P}CA#C%GGЧ\l\JǗ찢Ƣ٭  t؛ʆ7HtX'&\ic%*)cES,Dx&#_:EAHbRAjXWiDք%$@QIHQ>ɍ'M$PT)#4EXڀWADӯDpuݖΉQHiSP^cHFmp{Rs>8R2kMQGV+uTew$̹ aṬԝR8 MI9l0jɾFc'6r Lߔ3YvHf_W> 2F~_k;Yx6ap.JgHQ{ ²?'ęHtfRh?*OE )9=FKۊeA)~dR!dvlC;$dV=bQ2kAR8Z{@SO>l;6ǫĵ)'wOEF!FԒ_O;` V )nN@ӱ/oBaQ* tS,d`Ng.T E4<+g0 Hu˲/j-'ڸrȷæ%wvEQa o P**t錂HkV9h(ijjJ;7`0bt֚('E +pKgWkO J~]ʄuYfLw/vd۫Ky,_ΌՙLC?Rj#͖T 5E,8y0\5*ZPj(wFD  *:Ǹbl2Ʒ#$]ARMΑ7s^j`ԠU2Z'$~-4XK%x֖wrR92SF6uv$cI#@j;,銤 :5R:ci fr,+%욉QMr,CL%Z(p_<=%{:Έ[J2_ȫDL؞9i;7_TiB}Y.\[+aDroJa]ƍ}/0wzW$<}arBص4dQmiL)tޘ< ">LԔ.CTS 5x8\{^"yIJAϺQ9KJ%*̪MbO{GcEXD@D)q/R! pbIR0P"s8:hδLT5Jgv9P"$_ZvuP7Rnտ]ֻtGK YE?Xx43I$l^Ҵb"Ma0ʯ=%U]TP:ۏ0Q?>= v2Sn(PS(/V 9aBgwI)ޛٱŢIϻSc;vZR.O.$ab2z0txo0f$ktGW;'RudjDbtiU[tgwISGѯDJ[juY_Jp֋["xg5M^gI~{:}QvJ3ȡ ifZ5L##.$AX.9%xRŒfT) n|)4 QhoضQ[WlKzt=MrPOd('n2TA]AYI%@&oeh%;^(T"W+iJɜVv<,JG Ɯ}]ˀ=b/:QmuCYW'|! V70^$'nD;ϭ E"ryiCɎ~;$ddupsZA]nK1!!%L3'mqY/Q5Ň(?>U'̬>~{74+SRB[A1 O-ʡ- L'hG7x|T6/wMˍ=E ᭮ƆFX&@ ^W* x7 !.% ϡsd}1,-`ObL.dҴѺIX @#h4=CDm@3l4խHTL| #M$`hs~ss<`&$ e=Rg38("8k߼elG7:0* 25Kkjl;9i;Y'MS,Kl di}3<4^oVD -|H? m~40. 7A͗- )]'6< dpb4|>|af~C]W>\,9RV'eB@70idM ޭw[1bL&Z)ڛX:7Yi-6x$7l?*͍d3ShJXMn':b )JZtX. bԙ8A sh8NdH, ^h#vׄHAl#w'GGfgP2tgWlb, $}L鎓 3[t׏>ƍJG/>+]eƑ _quowO;,b䫪w!q2*X,P"Zue%]ݑaJWW+?l 0gk٠s|v)LLtvpXږl.9h/Jqs(Xnn9;1PXK{})@eluj6KqjDFLC@Sy#! O ְiǃӄ>8J_-hk (7 43I&{kK AfT>noEY #Ґ\\8$Pf^=TmFY^A=ur&[B*KR*m,VDL^YZ(w\Ux_q4UBZAG I'1Qj\͍|co7ϐ_D0m;RmfBC@CG[w;TBN_U.͑}K3pcy1Y4rLf.6 D(*9w(_1W%N ;&"WOV!+C s034*Q8scqT}[$:Bh\3.&r‰N}P1LfL+Us-R!=2)7L$AQӫ bi1܅P4;SyNV;PIܵoC*FL7q.a"^whӢy#et+u_8~+Pmĝq\l=nC ܲ`}_%GPyal& B#SԆ7)-% rkU&+3dW]GNa ucrQ^5Gۆ&1v) ϶Mlj,w wM'9T^# d>­;br{]XU^8&O=GDk2d4,{?@EώXk@0~&C& `7dOЍjOw"yn⎵//ŧf+w/_aa,M$:s/-MÃnw ;r*|ş/ 鿑wY7T^3HlF"i51K;fw5[Ñd ?<^YDg1<J;F/J_aO ݨ]:gYX=dN;ՏhNK Nvt73pТ{:fذL  #moaLfgI^^r ΀&JKu-:i3(dXǤ=@ut1&UnP,An Ћ@-ڬa@PB1ٻU4̖j)δ!8MesK껩Oz==4䉔cŲEh9U{TT$ʠ7ĺ4bflc@J1aS-q܆-ދtwZlCm+.YM"D;"BECfzښՀa^N 7>/lV%|'=ݜ⬎:$9t~[凉*zH\37OU8˙S`fdWƣuGsHşh%E%a3#W"ըYUiwfJhD8~k/\Đҝai-˴<e.I`mڶd [ X[H@oP-?؊E wQ'B8 `:}u|8ʥUU.k=X乸 zIˑrՇ@*ON{IʊuiCgJ78,f}ƛnK{:lt!£)x+HeY0+EGF;:M+BUD}8xNCT0RPU}*@˶_LAy&4`T# B$㳄Yt`|Ǿ7ᑔ^>&Bbڮ7$YH4]Y#/N+Ԝ#&My_PJtUy x4b$RCW=N>Qۣ-2Hȅ4#A Ԧk(ZAˍXAN64a0b(Nҝlvh%\=Dԥi!M2oDVǭK*8퍌¥Fx2.TN&lqsl&DaGofKd1k|Ά#6n(w]ۤW]E uόbx=t5MvS#\=J޾-խ`4 ?P~QEqLh6=b W>:*/k!*%k wD_οqW)D@?a"S}|eW}{sF|a3)܈=p~"վDQ`9ze>UE-0Sī#M!0Á Q}3-y#Eq.rz.iuIFW< l̡^|C$ԫ*ei@D솾I,}agY>mrf3nI>FmDZ;2z%IENDB`jamulus-3.9.1+dfsg/src/res/io.jamulus.jamulus.png0000644000175000017500000006512714340334543021022 0ustar vimervimerPNG  IHDRxtEXtSoftwareAdobe ImageReadyqe<uiTXtXML:com.adobe.xmp XfxIDATxx\ՆʪKJ\dʸwB(C  $!B!B@B\ wE[UϬ ;s~\sg9nCCCz'+'ϗ/lQv?GقkG~eakg_ZؚWa lllϹٙxB@5 :qiYؒf[ݩ 2Bb}0_m`!Q|KX% s|%gKAl>d;`] zqb}=mُY϶=wY[@ؖ"`р#loWMxkwm/<-lo#}p7gYlk&Wm+lp@2B+It R+3}!G s^b13}쯡zb{_,*srۗh8.p-S &,:%:L4|VP,v; pn|Yv}^@s,9~Q5Zop}FO߲8MG8ۛOP;ef@' J?w\/2la= t@;/6,}?f[hg{Q sHS "8|ymz(,~ wzVٞ`!ЅO/i8??zD$ ,s;KSDpnO;~QVB#le%!s<5 Bk.+QGÙ+E!8(\~?&w PoO 1ɃkN?7 ?@k?Ojk]OS ޫ`-,+ 0612LnnMIp_vl~^NMvXJ͝e>ʎ*kC,zp#gwS|(G ACNMBm[7մPek7u B|l_c8%|ymzc?O񧉡d 8@orww3go.*kSMt т"H+C<YnCWD_͎d .g΢J;D};o>WRY@o_T{-?GQzdM?/ QF pm+mFG7 齗U>- mm北խAM3k [0ap#Um+|p/OZcH&OmxM+l]1wy~K @5 _"K e|^qpk&Q b` u,j!}~`ٯap cU-NySFVEkYlS@O+lFl"oޒ(3-`t~i#m.?'l?c!0'?/c 0yE 9|P5uю:Pdo]"Og;~QQ>oh3J)1A[HR T}Ex8%m>O;]ƳUi8Bop6v|,h"x8OK.[?K2;Ӣh~r8yKSCNƪfl۝,x8_Ηg9})4+!ixh'kՒz>4$Ј' Xpݯ17ԟ.CqfBcgrwr3@]×6ݳ0b}8 }}[kZTm,z_D_`Bҽw-N8'SP%=SPbVu,O/ ,HflψdZlGdC$dDPg/UvݐE_0zNnQ[r)Eyٙu 6*m!;g&Ҳ x@;T*)_K?)边)p8`zxdZӖ8 J1,LIQx@8Ůt[ݔW`DtMۃ[1ִx22/OҞp/Oq%DCbj@`$ɗHuHv,D1f$EH@NŚXFq|y$Rj/I1*5|T/`/Ӌ4)p6ntZԞ{=mThw?@';$$9Q*ge/Iv[?t6bO#;OҾNU(xzv>I~98A ҉J2ݪ4G&n㹩'bx{MR)cCؗJ&7% q|%_.ݎtÜ$<t {]BwC@O_+| 'X>M#oe6@$ 偧|FzQp f_6SzѠG- @%/c/L8u>:vi@D]:hƜP[0LebOu0 DHFW)?g;p1LH/~ʓ#IBUf' hiZ$(9XL }o걢Ӂߒ{"HI̭l 2nF7gA l*~H]$ TI^ 'I8%1PC:yz$TH"%e}z'0j~h5 oZ?MRR!af"2--s,js67j~ߴPt>Ƃ0&-Aߕx@cȗ ]6m9IJ{%,ap(caoi㸫)1ft>ʍzrGs3 ʎ^GY 5A{ƀx?HM_Nʸ(=@giwͲ;|m8ۚ=EutBy5)8 ҌXZHR T}߹fg@_a-f[Ė櫗g p&c- N A%t%ЃȸXFǦ].m*9wrþ1O[[4%pfMYBifi:-ٙ98ϣ<8T$jrxqUƱ@qB7 H8s%-'IF_Ȉ[$dK5QF,u PzQkw~EJ$}M cvֵk~Ka&PxrfE jXiٙG Gxm.e--Ug&GcPEگ/JG/X}NNr֏4ump>"5}uNJu`^/mk܀n ?9GUoFg+J<NĠ#fjh~UaE9Q+wZ_h* g4_b'煔aS}(5/ pXDE(7p=_3 PE4ũH4IJq 09E2Hf>gr%q]Bwk CFbP&݈d?~v烝㧫o6U4i?O [@{2neZ7C@m/ROù(q||_H]گe l:IQzYGǏ?3.a߼ FfoCh=ZW7c/v*kS"\;6Ezȳt>0qfJ.M C@}ǟ1\8iҶj˛^AHɢ `2z1#xyX#LE4yXcG{Q;;(P6/Qo| YmP|yHI9xZ _,'+j~ ʊT)a_cX=C1ޔٿ$aϋ!I o*"5Sr0[0zd􈵳D?oJ/OEL0Hj{-6JI#NGvʗGo3O @_kp^3z8xPٿXYgo]L?`!aߧH!d b gg//k ^֠}Ņ7J[cI"ig]>):7;4<61;5ğRؒB(fjc5+SKõbju γ{~pxv?3"&RZd!'ޔٗ%L~ݴ.9~Z6 ov,4bBhzBA l/_sC!El; Eg0"o6j_.N '/O!EODr·p*D߰+Yd_NvvhWۗĢW,n6 &?`ai/MY0w X.ܸ@&&;xDL#a/`4%vLkڴUnc-fc9^ Z^_ɗ uXyAXNf|0oI/7LCflຈ sQӴK!FWA*&lMZ4!8<~U^A9/&Xkl ipe#f\FR6lgY@ZJz2@SDG+4mVvgCٓc(3!1a`p(% [VLj{5 9_^fuvf_";8TBu}|/ jy\pvUMӓY~)gd t"*iC-TI50Hʳ _DcB%Uɿpr`=z_3-& F@MkzL1=VNPKisyZ?vwKX ҋro8-Br3]>_d"[/^?5f'"F y 0t&V@6wߊ /{nfzr4 !*xv8,q2[K v DomUC&D`sC7+58~*>!b'OѮzzƙY'VщuA*r(@*-;9ǥ=ft=[NuⱮ¾Fj+oDw{%zon%iŠS"xREl\Oėmlqzj(3];;cM fRb(LfVZO:~{LB+@rAe;Ll"UKf$4㤨{4QO Ni#mjҺ4m_y4)*C2jr&fb{nvhxMSMuS:K[fb(:NCgwsYUt[tl VZJ\B 櫇 %۔!w6U5k~ "\~Ùh Gpk7nXM5i.!gE6i(gҴHrP-'|+\4ºzGj5sWIs -?toqD |v.:#=IӮj=g̮ӭt3&I"Ȱ@/ÝnH R$8c5T.ayg!^ZO5tm^rLD05Zea^8uT|SZ}տXe7,f)E}; L Ԉ4C vkTw"ҌXdNvj%Rm=]ŝ}LC(%WK2:7;a|yUe3PZdF4PHm@ R6]IWN(Jqg4dž&VRO[w$LKE5uj Q/bSfw?P-6%hjyܿGD/Oz^3@GL;gS?P^U߮}/8"^p!~grxtNDQڿةh bǯasfml0YzxizO)U|!?u`6i/Sf*"tND_+K0ڞTFĞcSb80y<~Uյl*k^+.Sd7:BG4]RB+=ͦDUfqfl,~8NqDBo;$" \?ib9e"]BCĎo,HE4M]tEr}"蟪m%Vu į􆧻@~I(1:ٗ$ ٲl/4f+iMe TՃJQGx{i{;_,xuDŹ{LAn6"aΆ&":W4kB_U?:M&;p<ٝNG'R jdQJ=f@]Pi2g|Ovch#~`d, 㰄 ԎCϰy;g&Ҕh6*CG(ϋ&K5vwvҎ)>4ϾG!k,dżb˔WFˀxKB?iE}~\(-ӄۑa͞"yiJ ?Ҟg^HWBZlz@ h;Y !0|YZ?f< |lRS2-HE+v }!B )쫖ߏVJkWAM] _×U2;Xd t;m!0J » f p1}.X5C+|$J HpU jPZeى!# ?H^~8ƏVu;- d,!cuE~ur۩ZiLBà@&gh8߿4D߫f'bQK5t#X 47)a grNL5a4"mjBG|f_ZA%JˈTm5DlRb"g@E+i!t5_]8TL' ġQ9.,9>|NĨ@&[ص7h1AJzEg%  MKU[6:#3Y(viJ}SE]}.3|i5;Ia^)U ^oYP|Y+># {*\k_&ҢpU"!s5R-h_JGGy+4#c@j4g/e<]n P|c(Skr/$Qt2&m~bٿ(q- PcϖC鋣l>hsWSb2phTfg:н:ډ ARkiIr%o\.Mβ:D^(Ӓ` _[/hZ\n+q6uѿ% t *wh*&괛f$/01<|h%I\h?Muj=CTj  ,gE]#()0ϡ^hroQgYZ$ .BCgֵ%M)1^3dD{ JQ|D vu?>R)u(RkԸUvA\%hǘW+ٶoZN-aޜ& mroQg ':-l{aomdOGZL`LKZ(NkCiir8YŒN?D^kQ(mѴD?[ɸſUFg})%p/N{ _GrK8͈qpfʓin?5 '[4o%ٙF.gOM0;]9+VE擧iKEf)/ea4+!?'oH+Hp jzDnvfxZw8("Lf%RIcUtRMG/EyQlEal4w"+2@צaT +'o"_jIć;gQo30>dvr, S}{_/NxDr9b}L\ Z2oLg⿽V֊ldq p#Y9yJ֭$5gpe+ >{LYeKErIa%2\B2-:H4j.@?.>|q<`/mVgUG7Եk}&7;hDZQp(ց!z昜re{ `MH#4]PhVDüZ"FĂ?_?ʻ5G-lH{6̆5,L@``ZDFEiő! [b QU٤-fgE\uK'c(;(ՓbPبi=Zvg'4 u%teY91 8Ty_-Y9y"f5S˖6;F aH-?Xo6lZtND F :Ƌet#ʡJҎn+?@!ʸ?5 EZtZg݆ug ji։Zf<-ϑ*k6P|~zFJgGrt|-MD=q'BO7%3FyMR?*#悴1 ff+,~^538WX顼Rgk>rLHf8V)qfgXu|RѲX@z;-pO!|I*ip|jyQ| ׯmv4 SN Ux zbw-d(?,OF !r N˸.xIH 混x0q]gz6Ù_sV{A-ݲ0m˚l d2L")IcoٙӴlP|y0oy6Gh C9P1Ou,wRekS!19.( #8:vAԂ?XPe3lq\??/oٙcVgN O$a ͫCr+}kP=% T'bm/QAtw7gVEa?H;&m֙oEVǚ!0 &Ognj,NwHSe2~=f[H<"WD) 'zVVfsr/x"X"@?=^- ?v8TC`8 $y&VZbCG p-?j`Ymلǝy#m"5VRct ^2͸gN]3@\]a]RK-m;a+ P?Fzv7WOVԉQ7^Nή;T݂MFe/wtp7q;?f ^Joe%2~E]Y\(a-n$"=CHapMKqtPԷүH_?n)uh[!O۞+o8LAtzO^ٿfG-> pG'|6v$Oһ 8:8Qd矣pIշc`<8+#ptPa--HF7&cA5)oV;Oxiچ~ "#GAl=ϲ99r@p Gy8մB@-n즈7_Ja##0. ߮F1ft>B EjZvu^U3]<5#'y8Z91 Qn rOQvT%"C]{/Eb {Ώ6ӵ) A1~1wДB?B4АJi2z_23ř1DcvUԳ]%g .eÕUiQtX8"jOǪTiνU'wU@U:OO?g+Jk~i҃Y9y >wJ0z!FʟU)6Uepp~^ڬBmgpIƼULe4!\7cRqWЇ͝*6ME8JcX}PֈQ  2XH<-[:6Bsf&-n&7#ʈSr 0!Fq>n6'Ț3D;':,L8 '{h,y;f؜'#Lr/Qj  j1:IM,HHc'ѽR[M!p@x[v8J jdo/DoMى!xcVBݿ`x()2,Lq^F^jd{+gL/=r }evK26:Sc觋&RTE|G*TJ멫o૓8p׌EЃK'Q)UAD:\L[;E|CWC/D1&wGVN-!4X=nE/J[E1C+'ƃE2Hh(NT<6gi&ck3(=& P=b-ѓj_!1e(PaXpjmZ@Oj2j@z`fUiX,4)8q[Q](*NVlќdg$ ƃg˃[1ִL'bUϓ8⨰m 'eq#5}4"~ǎ1JV@,Xx 7;t l@Dy{sSe)"{xy݋'RIvS.rt@WO:4DO}PdGb?%2pcVN^C@nvf)_ 0z=(IDQ8\k2doN|z~b?S{ЎP.8zܥeXa`W};|#Ɉ3Eq[@w:Jlg} ] #ӹzvS&/g27;/@~WJ(a}SFۋra38D[HM}ʒ[kI|3+'oD9]Bm4DJΔ!0q |)2C9CG@N$5ŸV˺^3CA[ʕmY1%&+'/%= -|^F'M[dm$Q}l5F{0.iWTcpǒ 7dyKfg]s/<}D/$˸=\0E>4.J*Gw SWw1J8% pQjYY9ye~yvBp<L& E}/7 xG(c9É1@z 7;_N!倍5ʚ Q2n{~VN^x#C}~5te8fyi}[/tx P"x$,ڬm ;BR[7wS]{/F/q,IJ}K-r3|=Ү>Ev^c&#.=5 p#"y~v!a1Fˣ䬜q LQKw+>8=z 'r8" xҕ^Ni=$v[1IQy -l]~Iwnͧ0 0R"r3E7j‚>iY9yfGDϱ5C!|~u _05F"r3_^#= 療ZtEWTEu;t:\AVl ibw#! ww9EO+E` q?Hk>YCrkGЩЈJi xvdZh{an;YB@~o8Bȯ&_,ʖnt00,'klb0}#F͑ ct >+)~ye'òQ 9|ZVNx2U3(*C.&WQIWL -HCC;@7yhL{dH~ p=QJ-tQz }M+_t]bC`ὒ_%@ ^(K+m;E~Mݷ5{XS/h+G*an:_ "F+ kzJZ4?1|L UE~liir%sY=g_~GBLѴlB$B;2K?]nKaYa7+Q#!O'Ol"{0>Ա*zd ]3Փm$/bpg&NqC'UXKZF\G%^+o) tſU֤M"(c mbqR8IH*X郲F\RO[^7#ȗ~.6bG *'֬2-8s)v ,f% QTI;ol՚sz G쳹kQ*RnMf.e#|`Zb A8Re@;z&zAM}ADZ7 `l̯WشVM]j_ưKV'܄P$X9m=.oT鈑ӹ8>>?(K3u <) /'jcq!4'>R"ɋ`e j}44J €Jw m]TEs`"E_1<#ۓS& dPJi-J&둁ϋ[3L8cy3ݿX6«lf[a.bL(ƌZ"vm5ʹtZ)gtuf:(CGݱ()cCD>|L LAR:0DEtշa[>1xqmc+*Bzt&"V(w`Ddaz!;4񃻞?FV p$ }=o86v=[>? Q{bX+e-G6!zgw8A %7Sa!tլ$ @gSR*qyP.e DY{צ P~ zE1@],_ @y3=sȩ|oYnhP|Z{C$q_e>J6|y'&77$1.C'4^ί;&@K@t gL`,0| 3/(hPDDqZKMp!Zjk֥Q-mjinF(` jiET " 1 }o:(˝$oyK$$xZ^S[\7 X?_$&`«R/1=K!}lm6}[]@B2g 3 k7;Y{{YbLVo975VZD7RiB0H7@B[B&lˎ8!){n3j#婔z4&Li4m Igv1{~] j7µ[lTe;h&`_ PFf#uN)nxSv[[Ssd07~u=$]I(7Fudʺذ>mpD7ҍնdS" L`+F6{h#U:!C0g d]:~v[U^cˤślqE9oޘ! 4(?0р OlNg w+Q:l@nb 7KN.6!53р Sɞo2YN:H` Fhc?l4T_}K#>,$89O/#cy,@.@aF:+, u #v-q@Eۯ04~)]j2_I[{hK=H@Vq=L]caF*-}l@/~X0`e G'aVHwHV3vVHRk>3hn%!VY07M{[G ZM4J" @7﷨ѽG$b[00~KLydt45I;M>ZL:Lc }F0 ^,%##HJ3|6|_H1@kl2 @2kt+ԩDKߑ쇿{ї^j,WndSu_H V[02M(TgaڪKXߖ1l30N "3I%>{'iF!}6Hl(klP;x)=en}"6}7">2ݨ$WOHW>O@Ǜ'=NcyM ؍kt?'` u*#ć_SR;0* 't=_'pih ;2I|פWhk^̨4R0θQ8łCXZX8#WjWx[G)W}x2 d::p4тy6d&g )jkbY?Z ]hI'Ea\hJGKL/;ף:)o_(FӀ] 1&\Ԟ|{wHn'>ciI1Nܗ́?>T`G.~QuW:2j?wT${F $c ^C!a<(|<Ȃ4YDC]̛[Vz[pkdـ3')ēc J f<+s&嗰M|HgzT(mj؋|,ӡM,e>7ـR~d}^^ F>)A{qoM=,wwH~>>B_$|B \PB6 <* BX G|,8  ( Ms/ HP1>0+ &@o9LXrc :?%*7 zdKEb &Y ߸B@M/M6  d|擥g,8ا&/I$n'G|UӋ@E YpF@.. $GNwA8%v0: dr,[7$}$ ‚ZoCcF0#p3ҁdZT$p R:w&LؤF +n/a4I1F /* x;Ibg  vpK6 J$IF /( "Q"cрd#ȗ~{15>2:YGMF *1{6n:Q--N{طptd$Yt iN 3#0܂c/Ē NK`INդZ#p$=,_ҁȶ 6kKW @\,]k#Pf{ї B-K AW236HK/#?k2$clP/jľWTH  fwQ-礗U+H  fP:XE'פ4-$3PӤS)NBo2H!d|-UpHBjcXzS=-!|e(Hކ<j>a dn FH|-KVZpĮ/[a 7Ơ(4~aO-"uO?__WѤq>)oTPȧ'Eh#0mIENDB`jamulus-3.9.1+dfsg/src/res/HLEDRedSrc.png0000644000175000017500000005215014340334543017064 0ustar vimervimerPNG  IHDRX,=͖sBIT|d pHYsS S MtEXtSoftwarewww.inkscape.org< IDATxw[}A+g؋((ZVHuJTxm$:$v7妬Inv헝W*H.YDuvrzAιC 3sX$ /9ϣh: 㗧腋R(k8y_3Euf`˼nZ-,M!Jpy{SV&!=͜p[XBIs1;lea$`x`3pÙ]@ !X( ̽{r$`x`-L !Ċ"cL5Xn$."!9J&l= {#!ˆ|AO@!~x{7se#>dBէBQ?{[]Ȑe| `rD B VG.f%ezLpY[B2'eVI*zsdU-.G!0Cf?}/Y]J!z=7E!Ċ2Յ; XC)G#De0-{/.  d=̠?Z\N)5!#r]wɢ&e~Cf|# !(-]JX]L9~ud@!m>?뮈Ŕ2 X9zᇫh!L_w]wM[]L)e?~Lu!yB$1pwVSJ$`o߾.!^ӝwyBJ,WCv/B!?ywNY]Ib߾}h!F߻;du!v&k =pյ!0F {BH+efEM!V wY X<# []BQBݻVbGyVkB!JoݻB#zBB x{bZ}Q/iiTU]tMX)c ]s1&弊( ¿T;#nu!Ű"֣> pյT*E<?+HJ$0`v-o}xsBeZ>a]~'.>`=裟$vRZ$ND Qt1|\cW>u#9G\t2tB l+`u-vL&=F%J,ɮoF!%JIEE~^[ 韀߹ۣVRe`w bsU<"Emdr=]][ ]v/Zm`~BVvk'VRLD)BR)K%oF!%J\z|>UR'p~BTVk;ȴ\5[]K1$I&'' [](v}S1 zcAW w Yc1~].@`0-,6 ٳg[Vb X <˹?{~˅>v$ GBU酪x<@\ٳY 1CY(xJ`rrP(du9D=H* Uv UVX"nT$B!Ob@"p$TZ磶|˲ ={~hu!(u?:̔NcddD=H* U+7T-P[[K0,um}"rUு߶$ >EVv$aEx۝~foW~GN't:M9mݦZ]Q%{1#VbY}7;rb,Dg"+g [\e4їɧ#4CAxH{g~^/C#Z_ObN( `Rgnb䥤c=V <lu-4Imw''rb-vEٓ DQmh ؐ/Lj.-yJfN XgZ$}}}_U15E}O==O΄X겄x0HY5kΆ.1@ @CC.ɓRi*c9R݂p^K[^*-Ei#!(9ۙ^Y_s.ERWzdDU)pH$c||>}L꥾O$rBU={zx9PgZ7ldb4Mc||JmzX]H6ozKr*t:OFUìz?9A$w J瓓ӨZ"h8Z<Obh8j,jisTEŲhMMMКr-[ v'<-.Ep8ɓ'pzO47do tjn؄gc#F\s_MA$,Xx81cFH#$O"]LG>u=]nR;ku-eu!*`=fkF4/ 앓lկXλ84k!Ƴf n܀wF<7YgBhN'O?yɓ$N$_u~xF/gv*GO`sշr) cO W뭮%x<ΩSB9~}_?^{'Px}55T켔.³aލqY"-PB"~#|ءChTQ?iw1yinnچdBi 'xxZ 2=W_vpc/FŇw߹YNBi8w%zM}mpaW{ js^6o2xst܌mછou,'JĄǮdSOQ7P`YG>BK܉B;zoy5"Z1]D]w3޽\+WMM vn߰֓O>I'E(ĉ$.T qq谩=RnMՍ7(y۾1~eBO?MIrѿ{}we]H`w~oX|MA 7L266ƩSLL&گگL򚫩ڽYScBH:E䍃>4&5l:#/>X-P^V.v|'*OzW~M=fǡCl{y|![pnM7 OIL&bCyaއjMUy݄["vYjn{U6pM7VlɳPUNL\vn`O?CА|]'xm(t(XITZ,FǙٿ{p0xtvyK豰tjn'$`=S?/uHR=zԴ)4۞o4xjwlh1BLߘyQF]O~hcCmN(o馢/SSOzb(G5mVQ>o?|[G.RuӍ(Bi(308iȥ;^Pci`M7U̓5`=Sn2^V4==I4!ܦ_±|Y:7Do-O'bRUBg?$ӝaF.{F?`x:pM7TeQZN)X c4| $p[wMB!\Z%?!']Nmm-ydy7nNVSO <\pii5l?zO>; Mp_SJ! VyQ&?.x= ]ueޥ444PcDE XO?t% ~29u*u!8<,G洿P}}~q57]B.f07:3cx9paw dMx㍹w3TQSUW= US9ݚ\yu4q]BI'{,G~ӤLN.#In+ ނO[AOb8Ǐ{UCW<:YC:ʫ!X"dpK3>Ys[ |w8]d>v7t~ 8ئyfbbcǎV9'^.9*oROs[!eHMę#4˴kkx5_R\.f|p -@A3< v8ru _ynl'E!p;8r%B!b;%{Iguk/Yrގ} 7{:x3z#^TQ***hm-p 7\_$`=3A,wk)yhouU|>U+ !`vP죌\!l6޽Gf3'tRUw}p81Ra-ip^yBb ꯙyXI&7oZZE _) dز{)3mRN8T?/(x8 o gmB,UU 3_Q(783fh`0h*uyPS[}ٝG ҙ aŃTT<Tݰ+s !V #]d5I~?---9i2ݻu@ֳ>^.3yy+_$IBG2Ŗ;VPIRLNNޯ5>,EQ>eB UOLrٳ/磜wftZN3jB~{a#}I:1|i ˛h9 ; sϻ\OT*oӔ D񰮉DݫWQeyB$}0To}㞏~c_E+++innιFt3'~ @gggNJ4xyfBY]h#cC^Da(N' _C_]#zv9E}XQ"h Sj:2YǹS ? Ӽ;9{or:u:i.BR_|on7f5h4>77Ŏۮ:a)br2rǀ95moO|轢r%t7 !jF7.ǪW~I5WxD"̲V2ߍSR囹g^"Sa.%] yG Q^y 8_o|cYieF.NXXәO&9,]/`%su?MD54#(K!ˉ?n7}бE!Аkyf;`d\Z,m:~xNjnZL&(}?eB!IJ_N7ek|?|)3k:y<[Wa(۝wy&`(`jz^4Xi8t8aXmw%RB"'e;;_<8s Њu^ލ `X2===9㵃xWΚHT!( Z]uʑQZ|*XX/bp.all,20S]㑁B!AUw!Y[V?c۶20ǕiP[[o_k6gc#-Xw+mxW*ek[w{;+Mytm]!㬫+۹b1V?"߲v fPSScBA2Y_ll$`}:rLkޥ2z2=(\B|Z{n%ʫ.X x&VUY4:Qf/b(*_^ՍMq]m C!D4*/gC_N&E/hk-fzz>&^ҕ u`) ۚmtt4֫A֏JBdMB!ȮjjO?:FQ݁dp8Leee>%Ef}¿ֳuz:8D蘮fh-Zm !0IR\--Idػ_q۳n7 2(K/]4"rm]T\}McMB!JRR|ٿ/v_O"P؉Dx<˳ʜ|//,Z 60D$z3Po6JlAUa@ť;ݷ?ki7Z~&V,d?\ne/()SKibbp8lx=Ί\NZ$D瓐ڵW5r IDAT$n]{%iǗ{/F&/zWl-X,Аm.B{uS%2iBQ&~y I㨝-fu7hF$Jע:dg [{0J1::6]=llnB!D9]Ѓtݥ[2TKa+d2/[40"ddOԴK.+!@~?R:z<;%>5+i݄+_ꪫ]:g=@05-o~BEӸ#(=kpj!|H>kbdņ ,*H{_,%(7aBV z&Jp67tz!<ۈ|S׶1#cDOM8)qNE4F0F.{u*[^WvB$O܌t^qv_cH//zW:T  Ea}w_fj]ՖÿG3۱JXP(?`eICۯ 8*+PK!IBf Ioڅs?UUIR\V,E)z V$1ܼ1AB&UxGhLऍH -˹]z`d2 [ @/kfff94MoPd&&o[BQJX\_ib5Υi$I<ON3,u6`)R."㡖KMc8T[deډ"'vsnB :`R`a@S^pR)n:$Cңcevk!IJ$tێD3J7 ek%KhfT `e\1{@KHOL[b2#BH6*=6nkwzTJRE4g3|pewη\ڬM}Lଭ1䓯'OҒT1bzt, Xs-XzacwfóŒՁĊ$|E*eCDPg#E8=s߳;Lz7}S4C\9qiB,BZ$Щ,>:f eVop8)EJ'L<ىwE$9 !tRl5` (HT*la !lBӘᙙEQU4׊֬9'.Bc;SӤp}U!NR yӢQR}99 6X<KK=NEs#8e^$B<e%Otv1XK UUq:EvWȻӢ1]7-Q,$[3h68,=4`pբ`$OulnQYQ Qh!#['ϖ\%Ot!:zv1XsiJ$y?3mLW<E!^lɅ:5Ej`Fe k!5"y Ko$CqIܶ$ER$+J/+2`9 .v:qVWg]-ڢW*Iܶ$ QPɓh(yUs:umJz-\\.C'].\"ʪ@1Dq{n!D-U.EBdTOX&E!q$M0fDx.BRT^TZ9nU#y8횧=nCho\tA VXINLõݚN^y( !CP @o(Vw\%?rUYlт(ʄgYÚ_L҄rmKrY  =hvN%[Eϒ|6NZqR?v =4\/XNz !D>YRVm~ЂBExҵ}{7. K<IS"Tg.5B;*ڙ|B鑹qBw.%*hY$#nBE]+HI#%zS^Ѻ d r? HbVv"l9\~6Z,HTpբx=VW$(W~*73S3~wlsAhHTuE: l)v%uuuY ,h8(~(f^!(0i.ufuj:3J=[0j{:mۖZ gXU[[K__y/XǪ+IjKDP*qQS2x䩲4Z*yDjiе\fA:;}%jjjPMt5HM"Tg=-!fV0Zɳ'_PJ*+NNOEP+8N'`tmQm Pt(RC T YF,Ao7x ϊT:s,GU%C!(C4l-9sW }:c6yw^xÇ 7A0t5԰e fuϗ͆IφQ^/}Zee`$2Z,hV-gE}TI^ARB*&׵[ :'`) Dzj-Yge&/բqp(nDLuA,nzȑ#|>x].JDh$$h$t{+{ؠk`֭,؄8%ڔEC5kF ]ZyJhgۅvg%!IB,$ORUd LZ f5X̻˄Ğ]blw6װfte4Z*=+3әE^%/~Ӥ5t54:J9BbP੨d :/`)r^ +OuuIGGkTx%ȃȬ ΙdőZtfBN!KO6*BZtҙP-;dMnEuQQ*** Xn[.GvRgDTE,K4H2sAQ12fϊ(gfryͲ!(hgO -󚦑ǖb}IY\ۖupa{\нyBAYBcc#'O44hWS ^qKܓE^(v{ P9ۿ)%OH]L5-\lz X.FFFn;< 4i_A @^`x Q|On AY(,e XK w4a(`Y~A( TB薵=\xI , X\pбcǎ%zΉ'NiV,!ʇ;!t)lc-@ktݲebX 2M^,ȴbPG퓳H!JWXf fi2XAȲ # 7d1EXYYY͛K}s,ca% >wqw4j*\҄Bo_qFAs[re/E徙>ìjZf _,NVzmRBBaG5QUdHe͛Ǐ2*fg?֌( 4`',[".Ts&׷p|dO6mڴ쬺z~ 2X^vkGWs G[S64Ead%m2 ty'N84466D"ӧɓ/Wکzzzս\ ;r*B&"'#bno8rU/oذ#;T{~mՌAI_nh#CU('B!tpgt-XNzaxGMNN.r63%I!0QL7yv9N2[6lN5Mmm- ~:a6ND9.-/BaIޝo0KZ 5Ma&''I_opu\@M$)S7f (B\uǃ/@E99B&S!@gg私崳̺ba:䆣C8U%@VXݰK6oSSuO.:_>3w `]0E[[Äwekb{x{M=;u3 { !(+r)\us܂E9D;5T-wF$ۖqMQ8"Mt: PYN~str>8uԢƮcD(M!L$Nඵ`uNPYYirE9֯[.PW_u;vQ@Xs|4|R,Dҗ|[ \nݟ{V5y$OɓB8Wʅ!t'Os88~6f9Mt֭[n:lsGǏ06qXB6$Ŧ0];71ޞ!Essflڵkssp>3x̔ N;d];agߤ٥ !%mt䴯(466_^Xv)L X;_yw(lm0BQP$e,7uin3Cf`0nQ]Y45`twweSN8{Z.fLD*m;/l]cWnE?CSSSN߯]+f8Goo_p{Cl16!DBRVs8455rRF-k֬2,穳Z;aG |1B$\S+.i++__f͏>hA@OOu9x; ; \1.뙐)VIBk.˷vN`]]~ĪLš5k/ā Feð͛7JʴҊ5T \5+]f!Kr:E3 AN^ՙk`Ў*Enj ρ9J:t: )]QDDL7pjF<ՙXif͚+ #@{Nd2O4kdNS0v: !Jz-t^͑Ux<466m2Q~`ի 6=@A@OO$9$ C-ET꜠:4°︐"z.YG0r\455i>zXD9D"R咴%3X~x!NBK2 Wot s_zm>IV B9rtH7_0z2ʇfC!&)N =V3ѐz&Te իWDE Xwd9D"9rDWwa`,GzN+蓯4%|N]pue^Qz|>I-ѱZS׊vB8GYtqhҥj\20CT̬lO$!%'TWũI8;Qpb \VL&9rp~KuQp,KBk`U^!-:puGGGF+j[Ti;ek՚~u4e=rBErKR/`-îK̙vttttEX}}}=2_qr5\9]B!'Q%+>餱mBesGGǿ,Sԛe12>1⁐ 7L#C)b9# onkM9%+Vʀ^.?1#jMch#%D$Jؒ\[Uz龰Pm~w q:vjq+NnY(]]]@e"%4I^!CSNmd`CK^Krhll{ ;OXU O,-BH$‰'^pS1. YF'_!0M8XADM7}V`yG VסG:qCe dƅaYj2E*: ofxu}/ ? <ӪU~êϱK^cg.9z~nSMe$LsH W y#*4M5J¼)fg"xjժUV"` tյ5e-=B :bh Z$G,S 76an7 vo5zժU.l6 YVעb]fϪ<"AK!VeRXlzYg0puB*` b\a.?O=hxqBJ71[/kjjl`תU޲lv.jH$Bgg'H$붹Σ4e&.o";%)0vS*Wduj N\(ikk{Be`{A4a U$UVOi5-z:L4iepͫ))}=l:rH$ebbB*>dTNվS!~`Ռ7Uv.nJjΗ~huKucO#Wtww?S>j1nڦtLƨbRiDbT9J7m!RU( ``0X*V[[w.b9XuJUUZtw ӴOhIKXQJR3~F[hr^/uuuv_y);VM,SVגX,Foo/ UKi 'iMRII7b-Katm%3uLVr;r^AMM UUUE9_+V۷D7[]K&&&#X|ʅ\×FS4fW0 (6~1K;jL$7ou~?8 s$$+*044T <@,MghhX,VPvi ' Si\i+~'l(%N^f+3.>R>ߓa ѫ޽8vp&L36`vl)>)ҭ"vQjiQъRDP|("*TԂ}XV-O/vծ%99{3I|83:,?;3Þp&1~p`0j 8f-Uǽ>Ntgd~CuSI,/|n,QH8վ,j~Hƶmz]Ƒ Hw{' Q{}Bd HslH8c^/YL+R9,HT/T*MYU@o0*jfB,U5vrחM5u&X|Rz+`jODZFZecccB ҉{*UQiXJŷ# V Z*2o,XF# |xt /lI}xX,ll6? """-b {K%th:fΔMg 'M h6i}VDD\uyo aDkf=;c:#dg|P ~u%YDDD||P(mX4GDDMMO$ϯD*X3,keu㈈U0A˲O#""2+8}4_5& T\fYV 9K8kÄ G,ˊn8Drk<< 6˩x@kZY.YDD$ <.v*XsjލNp8"" k\/D Vk p~tSiq.p >m9*XZ΢; кzT=fD ضvu/qDD$<\f/#,m;܉S'YYWux&d3*X>gpx/pVDDĐO.fY1mf Nٺ /"VWp Slj8L@+l~# t?bc*4{*l Vȴ۸6u'P4HDDFiϰ7Kd.#nR v]nN=_ $ FeL&S7LQv;~kp,a7&"DUW2nA*XI@gis."28Lhd2-~?Ώif,IENDB`jamulus-3.9.1+dfsg/src/res/HLEDGreen.png0000644000175000017500000000265714340334543016751 0ustar vimervimerPNG  IHDRvzTXtRaw profile type exifxڭV[k' gY433MLBtK`7s?#Z9F_!s|;='1T^0k_ W_?띵']G%CY+3k#ᣧ;v+vVbo`+ ;Bޫy 7ˆ$CᯱsO tr-3k0zү}"x_9] HEw7H-J"Qȶ[FKbclV(I:4vߨ! =scٺ$ƙ, j4@Fw5^7% LpFKs_)=͹RhVW z мw7B?+L7 ,U[yةL֯@~ "g \r'7H9ژcmYq(jP. +EXHȡjTӤYK-3X0hfɲ$)$M1YJ)9 01)\ -p]0UjZcj!}ZhbZnsﱛ^ CG6ȣLڔ8mgyvY13ktY[mg/֠6{u qm1řO/g>3B.r:-`:݋ysosnQ0u_y^"U S/ F*`1Cْ)t/{RP>7=H>p'YvEgծKzښ0or?F= O|P ghR]Z<\Gyڂ l 19# jNTG=J7L*Ƿxn@u`]3;D316 A [_? FA} á`~YnfI;!7֬Ջ$T?+wft=r9hѩ%yz& dXo !zi+yTq:]w-4=o_>wwo=7x'/Or9q Ҥi9z3NN{Bah4w: |p6T*Ţ@;v\,ϟ>ڀZO&YT*u]888xsBwxL6CB"kXdzڲ,,/10]FD4_ק=TmJD/wN$raRYjyKgU4MGy#^y1]i"в31+`0˺G!bD:# yFjOhk,.c:<|\S^,ݮ?E4'J^պ6߼FƩz{VprB+ 'tͦ/ x< lBXV2g迆@4 tȁ_̇wIENDB`jamulus-3.9.1+dfsg/src/res/win-mainicon.rc0000644000175000017500000000010314340334543017444 0ustar vimervimerIDI_MAINICON ICON DISCARDABLE "win-mainicon.ico" jamulus-3.9.1+dfsg/src/res/CLEDYellowSmall.png0000644000175000017500000000112614340334543020136 0ustar vimervimerPNG  IHDRRWiCCPICC Profile(ϕK(DQ#,$RCLiZ΃{Ml,,lZ*`v:~]k7_ ڟt3[OIENDB`jamulus-3.9.1+dfsg/src/res/IndicatorRed.png0000644000175000017500000000213414340334543017611 0ustar vimervimerPNG  IHDRH-iCCPICC profile(}=H@_SE;8dNEEEP :\MGbYWWAqrtRtZxp܏ww^f1e$cQ1]^уĸL=ZLs|׻>Ur&|" xxf9XQRω #e8xfH'Cb6fEC%&+FBeg\e{sJ4H@*J(BVIڏz\2J`X@*$5SnR0 tе 4j}lۍ \i-~^ki#onip >!9gMY`5q-Pǻ{LyrGbKGD pHYs%%IR$tIME  xtEXtCommentCreated with GIMPW4IDAT(mOaǿx)[?b0V@;=\\.E]Ni2Uwbځwv0$~I+GqSƫgNi('^/~%t뗢WxB6]m<^^NRB)v(}I ͍WW̶X.QQpi}i 8cfJMij*)4 ,YPUD"&E$ypDUm[eH7 4: 4 V З]]o!I- 1#гYxם qܿ-fY,38$H(;>VP< }}~.@wHM&aU*02苋hŎ]Q > s4 Vnn`hL]s]uJM_$R }n. (EFE<1])1?vΊܶD߯.u '++2vZ#DN$ cm3Aj>IENDB`jamulus-3.9.1+dfsg/src/res/mac-mainicon.icns0000644000175000017500000025724114340334543017760 0ustar vimervimericns^ic07zPNG  IHDR>atEXtSoftwareAdobe ImageReadyqe<IDATx]MG^9lDD(("lqٱ.H7P|pސbi6Xk `{,$HD&,Y .Q,b HO}*g^uwUwUO=5^U)_i~③?ǖ7](8Gdt^zuAL?Ə9!U:?hF/ ƷIU~=ƃًAu &4B//:4 1a>}$&w>#[|no&0ȯ£//}S{o]@c7ď2>zETvɘYR^@nwa6I<;>۾7~!6^]s^̀\S&|ȧ?r$ps}XE`7k7f>~YW4MÙhy~|gcU .p%p,%tgxsmpWk CvZUkoŎ DMg>l=Tp`7_eDo $<7t`{qbSbt`76[y$Ob}fM$1 <'4es 7ƕ9A m t'A>Hm߷h*PTuM+c iZW}h<*SaP?sDŽ?/q{SQY?^>k MHLeq]$D;-YQ?i ..cke Tcֻe:vj:GG!j9i!3v=4o2Ż<&5 K L=g BL3L|-xxNVMJNTqK=)# Z B>?PCg !&qܒ_3_GkC%c.hUxNWt<7,A5M fU@ lR46 >k@xKe7jћ/'qLwƮg=-gQf-̇Ӷ`8$Sb €TH&6-?ňmΓ_]UjV2h31ϱw2'jLJ>黺Nd+5{&|1mVл hIVIk cؓ?&/@fJi!mP3Ll3jM R*_4p_!6 ڍ $b  ZeTyE&l0_> f E/_޾8RE$FQn0C-$뙀<7՘i+^挞&@d18̄W9U5@ d3b_O5} nRū眸'-mLc'>m=sA]ݗs>LI1WEB0 t@q)9XnKئ\&j_mB_zۉƕZ:jnVsC=rԅ*M5m1J~N-JLP.BDIybU, ֺ9EHv$ܼ= ]1e+_{$0 /`Ɨ(8iu)}[ʎV50!]GuM(&5t8BD{c >k:'b I GϕFMYƶZ&@ju*c{ :(@$ԱBrPCZG) ҟ\kUUta"N`>@!" #Ջ(,rGŠ  HVPڦk suįڹm"PJKx t5X5>.!EdF6">>||-TXφ sV+9YfBYtV-DʺȧCY}ث@EE?@Mr;' .+X/z$զ{uE2K`wQ:SQoj=O Z2Ñ1%>2Mb%,L!cdH'`Z/[/h].fQ@:4%2T,b$eYaV a56 Ϩ3mi`:.Kn/7NU `9GnYtk|tɨ_ol[SUW0y~C։ GUS٣@f=/rbzCs YFRqç͈?}ڷYKMl'ۉ#DQ0 Ts|Fj*H[45nEAS\t Y&>hr@\JwECAs/SlT cX1X"}1{C,jLb35K4sꢆ? p ˡ'nB`!߽ɀ6vyIENDB`ic08PNG  IHDR\rftEXtSoftwareAdobe ImageReadyqe<IDATx]M\Uv~Sa@4h!A<.KcA.HY-A[0^5Hno 7Dl7HSG(@Ɉ&dry{߻ss9e}z?@O=:/;TW;ϺZ<ڨwj#Q65!qϊB$žw/9#1R FO`Ea aCˆ@~6nć upd@ 2l#uE$)165 3 4ۯ$fKrM‚#:D$1amDqZlD@hy6DH,D@q>AE@hwSW@^$?nF$ܫ#8`@O<_&o%{mS'__߾_z@oʨa0n| C?3ko)!|GTX@ׯMãøvk8ã& h>wߞP伏R { e(=Ye/:Q/6wգ2@n`K$U{<=fW}‘˻RP S*gpħ! wڭXh}QE(^! oxNU kpMCH$_ў/@s#F?X^% rQ6L{ŵ?w[$0J/SeƟɾ9֞|VxK^?0",9e' 0v\ @8`ipB$O,$h$X`PMO'l.:@qOIBĒ<) O^".X8II `O$:K*7^ѿgev (沠zA <=j #&5`nf$ DƥTh t_MQV߾`8CN] +ەą>&ִƣV$? &@}(;0 =җ9J"鏋Nx30?dFt&Iv?:49hlv}PHB$-;V0U@޿oz?2\PP ht #X;yv4d@NHPd7t̞;]ăJ%cOO#뗾H Qe fjc_].?_9QaąT@rmX~m=O~uo}`ظ`5w.;S=N:}MgjH^"ʎI7zeWҾ}NAܙƟ%2"ᛆxX1DPq?O$gMcEЛv*`04~ ^~rTn"ł3/|y_&}A"cHSa,>$}t߁i(2/S<܀*%wInXgC@bH @}O? @ja7g<G_g]VDєkk.iَg<$,24 +/GzUM {1a/GI8tOVJVxp,2kbÏ+F~8H?úd-o# >_*gy2f ? HWR66$,`O#8_QlLl-ᾅMmqgeuSJςt@ ~Y-paD ^:UbK~.~%d0m}M$~V_W748|xp@=0~́Y `?xeȦOZ$>$/3lCO%ק0n<=~Ao ?f)!@f> ?)!Y)$C~d@o;9DЛ|t.yWo^iOӽ q:ȾXI;4/miz "eSg?QG @"aOݥ[?Adj7y@kIOzf4xQQFEorc("6̮W# )?FKKφ;n?;(ٔ9kqA!XA91Bdq&f `NS.mkoo@[(i Q֘Eub.H?ƸW߾(]/cBYp/WR>YՇu{' P3+pDD{.r A "V T}ۺ?ab2:dÏجM? &zo~/Jǚf!@U,ɹo}rXwY% :')V82@x _B=6l!]BOO[' P ?!\g@=JB_(RJEa Pf-đhN2yB7żxϠDJIZQ/  WYaӈ,Eoyΐ:A/KyhS>Upx`6!Ceke!1>]~<0t`O0;!?-2k :<-4-KLdUrbB?kp@>,w.gMі3S[*1aO \VBCXa %W$ÀP,=T[U WdzD%؉M`@@4 qτUEf מx0*㇓}oHTJ!Z89~˂QkHByU^C皾;XHG%w8° 6~$5zɽ&5DBVt/R2 qTpI<$-lD5 $ 2iE`6\H 2QȽV`+3 @#F r@0`L*aI A8\;#0NTu0 .D9Tvp&QUU D9 ,S*Dq5GM#9(^ f^ X'@aNq`$(G,vTC'U&7a@Md!Wb KE`-82 C?Bu{o.=6>,/A:AA8##p^,%zz u: Qs47%$c0E5PcC>/} ûv_ Xf;P= y{>f@ppH S7/q ;ׁGk; /">wA?1~[Chڂ w1d*o!]VɤɌ >h[RS%^|ɇ821tE>FQ) Q* iDEO; yb90 1VٿDeM@t\Gr2~a9Ђ?E Kt-qH @P<<`+`PH_/C*Ƌ˦1pøS{&yL0`QOE >̼}}J=`Y@Gn,'7ГWCq9Uy"aPTYhI\'70aqۭ^)zG-=!(:xhI_ PG1ܥjpI 0txsWx#ǵ'dɶ@]Q$P䋔' ku3Ï 3s|@ $ⰹ7 VJt!^.b^ oF 5*XOFT aɮb_yE|̛[y5@oW'i8 p' 7Z'=Ht_R4a"p3j^mzeI^Vb*£7{*{Z._=a^4b*+#5B-H`U=M#;j "<~ӭ7U~Q9M4[(7Ɇ<>]dV"$ Eg%uNi2U;pD 9@IB>uU_IQyЪ]IޙOh$nGS=>xqK)աP ću=C3!$x. ug \+&A PZ x6s϶SUT rk9;D@T0;?{v2~*.%|qfTW ^L7o'T~B\G B%&0^THi[ u?=yz@@m?BLvx}0득}V1v}t: fH`)g{:U(sH bꆹnj/ bxHDBW?vꐡ[R- r>n/cIENDB`ic09>{PNG  IHDRxtEXtSoftwareAdobe ImageReadyqe<>IDATxM\ IDBl L0"!H E."hnhKnmoaa{[g3 Yh)Ƹa% [ǝ@&23_}qT*vUs<>"`ix|_ǯ%W]n~vg |b  v̀>F!0?rq0F#v A0!pQfϣ1(K~gD\) rA0!'`B! A3c A "?Sd'C ``Y~;p @AxDH3OfNKB LS@2E@s+0͡@@AWDq\EП$ۇ!\" ̾@NlV Y̰^X@gp ~pQ},2~!? s{ 8H#OfBfts4L>&G"ap8= ,"S)1?QH97}" o|7Y՟olú_٥/:~``,H"OG % U"!P =Z<?rzG`n y6_Cͮk ?E~]#ˬ>\ßn 0Q$ {ezN-ϸ0dZgG ?Rd)}߱iL_-eQ٫ WnN?J/+8uFA.TXb l.9(hߺxy(DXk?:_k}0#p*z!Ll?*'qaDr DDX@8 e7c݈ş+0ɵ hI`3+oʶom/AW W@DhgC]@2dl~~ Zhp.[\.PI?E_0{z u'CY߇^x@B,~? "`TԷa?T[F`:KW\}P Hr@o2 _|=$AJM z 'Bz%$$!@D ?e KT(B[ؗJ `?< /( P@@,N@"xr?koI@+@-AmP"@"W[yr@7H(n"XW'gS :_b惫 s|@@Ht'_kT8W߿@4"eNS[)$ϗg`$@@j-n>|?' K hK  >7mh)L `tO9wRNRؽ`y< ;g?]uֽê m#<d R_S}gS?~WDlL{9G ŁA@@2O _>"?~BgKk1؏ym)*f>5Zfpi bZuxb(Eb9KXԶ7x<- XW#9 8C)`^KSգߋu6?"`o@ٿFozsKjZG8rod)+ Y*! dX/'9˦A5??5 }OO> i^>LRk,(.! DXgK_DViв#-**"G٭ bf* _ۏr<bXs_7ʙ9xO?чb %?bS?_٥/~DA샫sy#d>o4 .f?+=EV@%p)L_>קfr,Vp:3MszGư^/}?\p <b̌,{7AŖ:-h9VpYsVA;es=C?oC||9/Ʒ |pf<ߣ!dU5 C>: _fPo^7ߏe''˞-3IpP]HX,mz0$HH1VMo /o.tC$ _?¢ \_%F[DkDpp8\tC! O.pZR@*ks3ö?}%_ejy~)@7,etUr`L-!̆ƒ:\OZ]SXrd&⟪א+*wlÜPz< UؐJg)_3r7}c<2_kTɅ pF;Zhb9o @H#OA@g/ 7S>wC>\oJ2d $ ??Nԕx"_f08?fC((0-9&A8qeR*1+fL6 ][aFq'6].CA. j&,e- de6MTCY1DŽIdO2 ù*0珲O5θfr.})Ob4؄p?Gp:-}&N;ձ?FK_{=s$7C}kVT܇4?f _}}/G?Ds/ZwWŠF./&>2Ho —&?~_@CY iND_v Od=DA4 Ci9\rh`tv<M֯bfqc/}_a#n(P Y}gg><,D(74WKYM#`O<_a2x׭6s{Zj*ۭZogڎ?6@bh(лL# ;K¿ ӎ7U޾ 0Z؉&+?FЇX΄!Q mD/E2A?_W`v@?Z_v֤TŚ~zߢ] e掿{ͬK; `寀T͛.6A R?RX>lW}}* f?D٢?ݤ}@'.0y]̢k,H Kڣ?D,R6\.`?-V,D5,˻Fs5p,-bW$C XUB}Bv|K-G箛:\k8^}uz'`sw6| K/~\?wl!y@޿!>ն B?׿k)ҵn|vmQ܊wsI (+a`b1_*UUky| Oͤ@ /чiAb[ yZЂSMOK `kѺo+?P,~`F!* NYiYgb.ulvvڱ4D@)UqDQ bosWF/,F%rr,Ľ1r7 ;7PF}2'5v-Zr)z{g1e @Q]XsYX+ڒ!E$i#rK'kk,ݴЀOٿѮuůo!pbBmd 8}wTU?|òuK,f](& +c6])TЦ@xx)|,#X &Ua *ϱ/x': ܢMs(A,K9jUws @kЏ739&_:T^QFrPFǻ)V'D\()Ӛ|b_oFi[%1Ù'lb/0YG_Z'lA_q5@y᪍ȃF;BoZ_~>|a3&B~&Sڣ\ a_ AnMFΈZ9~`^dֿz Xޠ*= f4@Q?iPvW߭NV _}81lPW_^ҝBp߰V/=3AQn l_ ufXfȳ~u2S~Ugy~_!8ֿl DE<+\?(zT_lZd DWXˡL˥kPn+[O-AfWz/_fԐDž.y*Z_1ſj˴ؓ u!i(;`y@e_ ˵6 Pտ?c ǀ?랉f?@E,&'7aByao(/2gßx4Ӟ)d$2,r, 3 6(jiue%Q5eEmn?PgrNX !tf/^ t_M'~\@OfmX:2?r3`et^blb@}Y[eluawm?[B M0_ d\gß1e h2?9ϩv|o,`p!2ٿn$X͍ ?C1;VY/#!c?w5@5EٿLi+3  R`2nC?h3PLP1fΡl/1"uTCl @ J~3fß00gh?3!VI+,`ppL fd+4 PŶԓ4:6@~`im/Ċm T rJv4k>t\k: Ćؑu.-~p_ #^ P_ ~+-r!U\\k(0~Df0/mm]J7b6ם:&!5$xKT%n&_j#T-?E7 ,ճ6 >u X+{ecmL!;l8ey2L^B@n:+7^A1ٽ߀,0(M_o?9aH%:>3?S,7,m?U,Su`Ꮒ??@( b _W! Xb?I-T?d{@"K"z^G8ߺ+j,ڿ5׷(QTUbmq$;0z5AW;G*?Nvd J vb790m^%"T@Ű+@-2la U†?ӵhL`99]g  {u܏ a#f\I8]ol`d[M 'N̠h~Peφ? BeP:\j/ ?T3/6*-68u-`* 'TgPAQ/ q^m7zGwvO @(Yy6ıoVs> xT򙏳W߿h5׋t v8Q+[@Wn=`"w߁7ZQgzkQ/[5glaHM6g%;e |V%~a;+#b QF;cpnҗҮg oʳ~RD@B@z +?[oTF+0~\;e?7aZ|?tv8 md ?={!(Niԍ2ga=ASg -kUφ?(5w_7p*XՄ@A6[xc)-sgYqiKKQ:5llԽC7[+a89NFfl0ޅ0LXkuNKZC R'@5St*"@ tT1b>ΠB DiE6H l, _j 1z6nX΢*XJq@7ͫBKB `)*3Si_ X,Efht0)nA]uoX%grW-˗:7>օ:~)cVEE^y{~Þ1W?/?\Q5 zh /u\Bş?]WZI gl/ԙBD!?:X7a ! KT/b"QPxZΆѰ 󾼙S ~*GD;֧7-2 |ӟ} 'fxW"%1O&$l~}ƔU[#0:b@BE~= Ѓy\ b@pz_G<$=m-$Z-x/\"@;Pg2 ԉ=- nww WrцӟεVNOQ-m)S TFJ6HOק-N@ 7}6:X8\ > 0w[DBi{`)Z,\Ξ~xǷ({ОL-za5r)`W-@+`cpAd!q'YR%h8qSq ҥL('Em׿+W'@dې Vـ .W&@DWO?"rAw*v ԃA{)U)3Sƨ phK BUh2 \O C0"sG*s! O4O@v?=V 8 2s}驭uwq@ X`־' Q~v t Ags ٽcA -EJOoʘ釘Pgv?Rh@[rUxB=+bHsжPO}?rU#_ܗ~1P-@T@h pKYv (,]@u% /ȃn"jg5з v d])T4ː\Ov d>\\ 'DSԍ\0îf?{Ǵ1P+z zv֮Q :nTk8R{z;-i`Ö/ph0wL mtW-L-ֈp\L' LsUwb;)L{ ԉ(U]^L'FX%pU0wl 01 މH{ DPhF 2`tѡ@=k!o|rJ@MlpKO -b 0h0Pce}N"FO/T!rP5{XllHdO֎o,v2w5 w@"S;YyB@d|Z3-# eU8OZ) ð}ӈ?y9;6?R =ý:g.hKa- Xf%*4i\D@o転Zk!U U,\`?-6!ipT `>4~Mօ_NLk-G9@(ׁs3`r P% ̍ONnW; i!5$*\[KDچTP-Qlw7A3*}A\/\H&1rwV2u Z(@ȁ_׿?@HSvb# \YabyBY*Pchv'jQ]xlú8 u ݍO68%rߴu"@)ߔ=o$'|j\*@51]kk țEkcW(Ѳq#|?_k.]wZL U*{eN 1_~}هNq QU[,~+f?F,D𻶅O?Z vpʇCвpes.}r$?rr xd˅5u$.eE!TÆ{n |?*C7ًM br.@?Pm繼`X%v̻"* ;0wL}o-T"(܄J_Z1|t$ 0X@k}}gE= _=k}~sP= _)kx _ (P"@L" &w:~dtؖl9P-ʓ5kzjsGDTԞ6wuLsy@Uh7m ^' N"@L*4-@< )A 2.*$ *Kh9(Lp ݕ-($9 ?s1e Ued]vFDvLM XC@]փ$ .D׆I8DABBa>}?zA@](X(hu*#P~~HL51}*@lvm-F H~rE~P8q Dblنuwq0B'g%AlMT|פx$rȟ\ؑ?R2HЯ\B|-F '^eo?IUaޯ"n*  Gr~MVt58?H@(B`㺻z0|HWZA_0U8Q  G 'ПU(+{ף {IWpC APEŁr0_J~ 4Y/ }@p?@"@.h@@? h,пPl^J пP59)SzD|!8r{ slqWAlY7`N;[s@5",ԃAh?P)܀idsjj ܀G_Pr4]&G|nd!hThe,w YpDYoHŵCP;86n@p\bBS2uZ~:c . si口M^T??D48 xZix~}>#_B`p|︮G XjhPgZk-!P[_r=S0<!NuX x, jU*kH!ff;UC)$djQn|_rF9}Q_r'4K-&=Zm8 o>ŀvƘkH P \2-\Q\/2b<뉢@Hn(F7̾E[\BHB" wD70-UA~[^+t@I.e}hϛk \ 2)[clޙ`@ # C ޞɌqB ܲ/oĂ?   @$H0#P}]01!Sdw7]kC8.KB" 6 8f:BzQɟs$?ڛF@"`p(l# f0Zj  v Xh@ELPB$"_fb0HI43ߊ! E!p$KzX.(~n$#n hr4c݅dF@(пPגAF?-'$hn tJ#Vhr4a.[S>ޅGCݼ`+&ptI7Lg ! F!d@,v>?b`2NFJ| He 6?w10Z @:y1w?GG(ؙ1vx{ hfŃ;,LOBB`[88Q]FS00P`o35 Rt m׃ʿV E/B_- TC IENDB`ic10҉PNG  IHDR+tEXtSoftwareAdobe ImageReadyqe<lIDATxM\(3Hcƶ6KE׹7vq4ws͢Y 䭳HW`e݌yhCq0yVR,C.v멮ZRTw9AQcK:oUu}޿h3SU{}o.wng.z,@mX xɂ˽__n,{H!_]/OY[=$r{~$VߪV*~&$UɁ`@zU H㿫mK%KHzl/MT+ I3 ݊~峞UI%H;؟* A 0`jUrx-N 8H /o۳O\\h 0XueUh%, V{Oi"p8CV* \'3g- G߯dV+.[@hR߯k뇭Y/!` .^p%H {eE`~a +Q/TtHX%թ  \ɀ h9@@[l UALIe Eqi  [҉nт˖$2n?@ he_?je^I[@hV?Um"\V 7W%D@WH5 UQX `b/TxDW@ 8AVJWEK~Gˊ5rZpR?}m@h,[ WMsxۜg6Yl=ࢥ `%_u8k)@[V w$?  HEA?@ GG K (RekH@̓T?  g;Ob/pR3H"eK0 ĝV:,^j۝lj̲@I;"ݠ@$MyfP  Z ƺK,Y $c>=Bxe?@N[ $ o? g@.V+/[ $ O JGmH@jeȟvoԮjO<2?i~uvɖn (/oUSc n"I7n]+b$J՟ ~ g՞][ ~R盫0&d{~-K47VM[ F)~ON!H@CYN` rɁOwvy " g-@?wb t MKJ7EK/Wg } ݣ DI Uq_oY 6#ȏ@$J70_՟un&b`$>%`  |*?D$I z*HU`? !@FOwޭTS~?) ]|'``JK?g.[ $`[J$ŧkH)@ e@v(_T_Guח]NH!`R  {*SSkl([n 9UvgC($g D?:B<р3wfX鰕7]Y ئ<& iGe V7=Ns3!WM FO¹WT&0$.,ȼc 2Ν!ݗe 0Bi+"*GQ>6%NN'Vų8l/7Zđ0࿮өc@c@)*kJ@%]9='ZaT>*nuE~^Q$7o!:(^_~|HD¤g St6T$.?Noӌaxe^VY@@ -0oe3B>o;bBt-$=ݳ{F`NoQ{,"v};q(qh^lpP8 Nʞ(D/{;8v@dfU i 2DV7eg/cRbm@ h^!kg\BJ\Âg{EK4qjrH4j*,׮q}>B VXhigb)eUg3^ƭlgVS$J[?ri>co~(Sq)P;Ǘq;VxT`߈. dh{5=_wP*nj ֶ2^{V=& S L;׾ @ h0nY5@Vy,=ƛsg$j(k71t}9TGge\W KYƭ}Fk]dgC/7ޚ@A~_M{ә%* X8/CZL8][O2^~tJ0WTVL—KsT#SXO-$:klLJ $@h/v]@]ՕYx^Lܫ?_v&+mpjILGm֔x `$qSJu쎾вLDi5莊.W]ztnϜ\ 1IH7:cBG; @qfY&"St Ƣ .eE AWP $;0 Lt%LIzzJ]5?&);3 z0H8% AA$*LJ`p^_௼~ϪMbpu`"n4s6bA]<ڞYS*a+RȪ Lmll]ܧDb.c[ Eg `^}[fT+%A? L1ݷ\钧: "OM!,ܷ6]I|[ :w;xG?,٦ν$`PNozrQLJAN1k `8 :2%;~y\@hvߪVZ"oY~$LL㜎xze^/?$_k\u}{ LIw=Ͱm\ߟ?k54j?xqu,tK@yA~ ?GMT Qƶ:RoY &M\O=j@4&⑷$`9.NTWyr4Btf|$G?EX g;_u~:IFv+͵g.>{=OՉO {~7k5{4׹TO4y:)FN}iˍ. u5<"*3ȩsWnsPyJ1/X"SA0+ #M2NԚ?uGg @ŜDZ~"[ eEhꢝ;]zC^t&Iu%>gMO]ܼu hH<zGK[JՠiTLH$O=r41VZixO]d:/@)~v'׆?߭V4? ݪ_\͓h`lo:OG+ixsW"SI [\R4dg+P$xy^ 2h˷,vX6%ǧxeOڟLshNbt{~fG]4-_Id/}E~5_%֖?Ώs$NGa=?$@uUi"[߬ NlS(G t=xB҂?+*wQNo>Lg @9ؼ,@I?ްݼܼuur=z܋PgN8g-@*Uz"F';?_vn(Kv9.u8+@SU~a_{E`$hjob? ar.tLj(Vm%TߪVV#~o`Dݳ(V$ylhEu{~MU$7*Sq_ ES&l;yHP/u~Ce:/ (K{ %W? [V̛ȴƞ+{9_RM{v /M`v;ߪ'j'#?I~@lnl4 Fluޭ'j)S$4-(@EU$9w30@Q;OǬDsEo`4K L\cz{~f 3oUZ-*15`'ʕnRStEi kohبG(_4_~||YqZxC # dj7 ύb/*2g/K?J*7`F6 1G~#tw\٧޴b+v{~fIQ~} 0~ OCLmms{i FGq+Qo_vRH/H?>=1ըxV4/~OxKӽ~J{R+v-wr)= @k3^hj+6`#ݪ_\o$E W>˜޶ht+<ǽwDl\+@a@)R71#p_5PCʺ_ {)<OHYG-X ?P~1j$|}$i{m: Rn5@`h(+=? o&OF5D%~Eg"-ǟńW|` q]ѸIpOo@>j`%*c6dߩ?=ᳺ`ϑ8+@??yzG?ӨN !ea?2ؿ\v; %}yS W ~[<0.Qw+Dߴ>3Blߵ{~$` >8o☞#6Z?gHgi-[ (gSrbz%r#IV+! Q}&խ_' ?&wA$Q7 v1X5:`ru?{c^iXg XGp@@Vdᳪ@cejskq=Z'P͒"3_q3 4X߶ɹyߙN@_q!R@EtQԮ\z|{ヂMIӊ@oo*2->HL9۞( O#Zc)@1^4{{D%EsPLC9-@E_[oǑO_"ͪrϬ #W?A@2G𯃫^ m- Qۧ(Y,=&D9H(p8- /tOn3u"9-;w?ewXC/?{{ZEjDDk/׾o}"DGNg.Kň؞Ze gvz4|)3/U  Vb{?2SJ쎁P 6(0{CIL?~I/h%5)xЩ [? LG֮‡1M5+je۸)Ȧ[Mj=E-7@ZJs߶9 l{  E^@Zo;SWurk?DQfTk`RFLڞYh ?Z@f`2[# tJ0` RIݣ%Fb 3`e_7!k(O?S|= u XWm0D뿢 "l7?y:n%iwڼ|g>Nj~kşa?ӝG'0?+XpWygş0&1 Y& ZbO2G=9c&Xܙc}Lš!+4t`;0-`?y:n%pʍTNfhS-r`$ +hߔqعL۝ `?m dv(Th?bnR,<Q9hONm:?A?l,& !/ع~D- udc`GJ+GGG7dN4/Zk"; l\M;y:m~7~`R V-G:C ʑ8:zG,N?'Za~= 0B6Mb&Q̓({v= ]ZEwG]L#`p#1<_73Nߪq6:)# 3ph_q?)eŇt#_+=wF+uء3+wDqs-⿞6T Q˽"&_w'ggDD\b?#'Zʍk?@`,v{Wj-1dψjf-9)05y#6`.]_6T⿞[gH DZΣe{dF/k2DAP"*,:/f39 ء3ӝ7+_,28JoZ^޾CB #YPQd~ 3 Yoݪ0z1J1D?k? ?Ӫ@YeSQo$&gk$}S_hӋ|0\v|;ݚG|&@`zeQ~::ϻ`L"{g#Yk&0 Kuhx0FOnZj/ ^|n?rW)_]"] >X>7Y1O--U V?eSGq\T3͌Ž4 PpwR)?$Ǒt/PDuhc ;تV&v23a^⿑8/k) Pg[,/G1`-}Y} Pxrsgg;O3A9 d.]_MSZ7u_jk ?7a o|xl&zMg~đQC`'oRFVcF? ?&?ɹpV!fV?ƨ##-~[jj@|ptfO'[R\>1?:8 M}Uf~SF`B7N[dxJl_Ot>TkM̱&v࿩/XTddpR[}f4 4Ѝ4+0wfyZ|`rbϾlIDvujf*gV{~b:R?ۍ@\l⿞lܟ]%kL`l`f"⿞sKƄY$^%MH[0y1/ 36ojW⛱=gMUUgX7u-Q區ߠ࿬< MM=d1 *q?Z}LV2>t[_-o_w3:B'2Wԃ?7-[ؿ(ژVVlH[VP 3{ ߺߵOdGYz 9);/|7X>q<2zM>+Y?/1h‡^u`Bi:MH܌0ye@?Z'xyA2^RYoH!t%:pV6(!-dfC<֭$@SgkN1;7((P~b[#nsض ./j<ȁ}`W=u)=:J\@ol9wFY۳a5Ca1U kwɊ}Fkw4{LTI`G Z7 ;SgѢjK6_/q:ƹ/@'4/.?O3 YO=Z=G e=/NlP,H̝YluɢK(/uqIyk]M%k\UJߗ@}GLSS~#9p&[^?&;S|g ԟL ˚@ o\@DZ#(߸ye^4P.-͖ulTr({ @:oO)@3t+՝eMZpڭ`&k;P%M?@DZ`Adu$@jAh3VZ‡dɶM(_|^ܙS+ӛ+!hfUDwۡ}{6l 6f`ʽ4STWnGoPb%}GbUnP38wfU%;/n 4;}vm-H|ep9|Tv:Th8p/"ᕵo&p#&;S2T/תMgIkOT+;ri.BD0FZ˺E(|X@]en429X?k_X<۶ Yh Dnh̓6rOS^wt<@Wg&I7J @"k\ 4-':[#D ?[ ?I:#f3Y+܀@a&8K'K3E/uaJYϱ gݵI'Rrv,@*qlX'Nt-D' cKd"?v@?^S$hO <@ & :D%VN]Ckęnj',g'6O~"}FuPZs$LsUH'~1Lo&O9t #mAP}xzG3HRe rJ0I&ܤUFC|0U%k͐R';8]%' VD IynFE)Ql&E&f6AnoXn,M*p8˛h=>I@cD 8] /ϑ%,.tRK-q@SӔ׭%D?&QL@SD,AlMGgy@b3QOYGQ-~.\o?{Q&~MtAV#WܲWG;Oy $8r{~f,0)@S\p/JċCIhxث tCP?kJoYQ׀ne̋NfXC/WY%YԞY[`b4]ۿv,>4m ʿ<z' nU7*uGU ;bܳ{|ZAWYǠH}9e^[`bW|WvvʍWSVh3[r E!{춯Hy_XH?ʰMj. κ~@T j~:l+u?rio О8ܙh*}Qu5GvtaUu Kp7@#l Pg'`,8;,:OW j+Jp՚$_j,-P%9Ϟ2β-4kIvvYTV֒M̖:;i`-I8o|sg#/7^?PWݪn~UWpgwo`6ChqͺGG^]Ru :wF뺔c_8ܙ苟.}Eu$-zڟp{߶U}S|Hd< )ZtFbVwȗ PC5#֕7pj(k؞ l(o)a9W_X<ıIFoWTvWS^wTyo@_jSљ};*h<l+eɺ`q[3 %:~ t}9m`3&Pz^2S~6W6 ZVnN־W;e7D74P}Sd`B N~$JTXOfoUسs`uʍx?I4oa3L&[ՁׯzGG$~!=b?HF|sMߏ೉Vg6$yz 2P?rj7egkͺȁM%y=?4lɫ{>JOd S'䙏Q&,OV_8@3n" _RqM#l&|ӣM7;,3[wRŽ1`3$Imόb7K :*nHt=f6lԿ7l@i^сYGG)$"ܞ9=@[td5ߧGf "M4M ֵC'Glt @xt` -Z$:=-@Y759:0Y U$:ݞYV+gÆ@Ru8:0ٞ{>7!f`l+[V d ;;?hjc}t`$2Vc?0Y|uvKŸϔC]';`P OH91@zFytHq g8jd,&[`>:0nhȁ$b 3S) +(A$P@'[ӣa?0ҷK@;Nl,\ vvZ 'l`+GF lb?0(Pld&6;:0KrIM$еRWxP;{ h_EImL&S;#gT+7RÑoIM{sggK^e.}}d[:>70ۤ~jo* Z2Թ+72Vߞ~lK j2uJ{FKTT# IOJ]ihF'- . ⴔ8I Gݕ@0ZV'x%DO",ym?ɝm\lz@WJ&`|GFB 4_>ͮSBL wt 4[|~[*!&t`$&Op!`сЌ,DUc&@}e#"@&?/\liAkb~GGݟM PDFq T'3KK{ert L}wDۥ]-Ԋari4aiA@ыb}w^}#fqt Nw?+.m_g8:/>Omt-u'J@lсs/vk%K1_ept l_ tKod|euс5QtE 2{-.qt Y3ew^zƒGºN:ŦLě] lvAW K }ax=?$ח%GB6I0.ZP ?E`~:ct~Ol+]d}cO_W{v={zej hWG 2E3~H?H/g_H**G~9N9VhOV߾m}(" `@Mxž^#u@O ٢?osOZ һpVuas qWeH| `_ ^|r::o^k*my؊=G: Z ;.}EwP 09gX[͐?+E;:-=b@즨Gp׿||]ՃI22i?`<ˏ[{ő-à Ȉ8>w@l=ޭ+bYs8-8@VϾ5C~/;eX-=`M`{#,@I&'fąk K[{pbLF{WT#) w71rUg=( dɄH"؋*m fk{K؋ujXr"R)#7VI;" K64DTWeꮏI7טt*ߺY# <-݃booiBmKf٣?`q)WVST|nnzexO{X~u=t'_T?{SN^@ʺ%}M?YiuzZއVo0PCrw/&N1<Mi.;MWj~yaâdEq6߰wh+*zXl™tNA!6?U 6'\@XXcsFmk=C"7?OU5N`1ُ&3Q}2۸dݿ`0!Wk׿6+ػk,yV?~}A0i(Vvl'y[&C#i" n@ g\+ҋ1rM@ w4we@Id?:G ?MMಡ?}f0&xTH^ُi0`2Yo2 ፋW  l&18d{B",՝ߓ//VL,k?},8!X󰺘(Vgm5ğUK6Hm1-Kk(xS*v?snة2>U`l I4&{w% &;!B-k? (e Ŗqq0@B<={6(؀W  @l?` (^#0Q ; XS%= 8U@d?&q7"\t}YƱ`T@~*Jm1Y2M8A6$qf {NJ@q,% =~!@vUX)} ?gFDOXĪ"MD@T)ӧ~;qoۛdB,ADm1!>6IqDsxwט7S.|#OUw˯?j :n~B\7N>hkz?7/z|(Ǥߞ@BvqGG5`b! [U`થ0b/nX|M+N"h[~ 0:}k?}̺U>ebY%+ 0K`bۿ` bBK&'8Umj,ϙgJQ5>Moius$d f3&1 `H&kY%K(~MԣG[ed)`ˉ ޣ}h (͖~O)S4 [4lmd6OUc !b9~/*-Ȧ,+y6zGڭ= >uɥ]Ld\\cg_c?*^ >gk@X&:*W~Va8<*Q *֐S7yhZbCXwP FL $O≿Q*hZ!7* ڄ#rr#(kPk{%Ud5xGt4~fvQ":죭&K/>=*9eн5TíC?⊀[ >U]LOK>e#;[%oP%_ 0*w|4GkqI? -CHT|),|4GJ Zഏ>4@x)@Ld*OUc9zEQYuނe6h M,`JhU M)R_d-Xq̖h x(~d2Jm1>U]dK)(񖰯d&h cb@,(!`TLf)Xq̞W>6@!<%t83@}0ઝˆ%t6ߨd"h;MO|a ܋{w `9슦ʼn+˞7|l*OU`G1bG@vw@&6 K-`ߖ# bȻn 8ѯ-U(= wQc=e{ٿDP. LdrU}iO?[> Tyet3~*r&g.f *a% f@n N<h`hJXf TUәSfzZ Kɪj 7u|:Qri麁rU?J`@N}%<!;%7F @0l%2A Ov_eTGv&ۿY `ǯ!<+Ky $E %k2j,X+!;ݝ5V2a U푝ez=-d0'~2m 2bzj/8ycdVey=-:F@d2i2ɬԙB bK^0>Um ybk@,Rp~}"2DjLjT,;J8dE~mGخ}U@dELf)@ 28s3܎mwDmQDnWKɯ/^1Dp6K䍋Wl]ceyOg&OUK6mLf&h+;+ˬKC+ @+2f}'އCWeOg&h Ģ9`Te SըhW,%R l@__`X0`.%` c߻ /LjL5%D5 -G-}'_$/cضJmQT`K@nG޹U ˱ `"S@f| *ә SՅ#bw`Tk_~jh%8K \7d'7.!w)xilֵ_v9;ߓPwט?*FU#;[!CT `kHUM'FF:fO咮@Yb(YGz0oI @EP;~sn+YD6U]lI @&/ə槙L9o ]w"P EO<]M Lrr#9?Tr`f3n:- Lǵ7 n횛%M]t,`xM5w/,7@*"J:0؉^5ȟ(/2|c"7*-5nؼxrwROJn,7@Xe7lLLcyUU #nY ԧ1eغxq5ȏ B+L ظ,Xy-|d[ɛu۝]! #7{Fnn6އcYC@lmf-jlO^o\Jvl`G)|(y> Uie WX>qWN8=$ "UCSC|l|02$j%?}mq6=MzA`_k'+ C,ٽU}%@LzgAk 2ߒ矾6x3=>"0]ضd= )m, 8* Lրֵ_|Xzz[I^5қCe@YnS FG8]x3q8=ƼAqD +x[^ӳKO=l0F QeK^Em1ڱVd5J4 OWu|KQ^Im!5[kGOGi~KX%(,S*nc'ϯm}ט>NjX Ew\|qg[bjSB$na`4D4X?|<_ B_X]{Am͖(̅,(%=`= 2:He~r#  nֶh/68Nxk)WR`% u[RW! e0>UPngҿ2iUKz)hp{M ?$e0]hn-E}eRF^h:_k /c?߇W ^J4bi/ٿ~9%1g7uYC@mઁ)o3efSgߥ8S `"nčgDȞ֤?=:<[6)ӻJ%KAJIš_3밆L7fK^dmq,=톕E5@T*XOi[k?5Z*L` zUz4=zaua<7.^3  wF~ ~nq#; @N6nK^lmq"=C: t `e-Iu]yQK!B#\lRA ݉o=lN0RSƄ^M`!db)U,TPtI?lƋ?d)*.CRN#M+JǁRN#kr΄ 6.Y hLm?[-5Q|~F=eQ}{@BK b@'_+eb~%d3{4VH^l+k`WȠh*8$o،'_eM|g L&@8ܨ&q䀼ٻk,y PZxBc#]) ,(DM)d P: +F/"ع {y׮_Cuw!Pȹz֌u*b Yk;z1'D{PV(uML@|#v8a$|:=k;- 2L528yCh8i$n KrÁ27%t=6=\,m\2h 7L )+Ka@`,7л׶Nqj"c\@ ǒ ӛF L|WO@S@P;U ς!@8b$,楚Evz 7j VVMOFȂxB7*y"&C$X]l d,hMo$g XE}Gq,r{ Y)!X;KOsFȊ+;n$vRݟ 2%n@^&k ֡>U> 40T@? sldYg?l%&6}z0@Vl_=d|l23NfG}ELl`Sf;p :u ͅ1Ǎ' FpdXSc0n2Sեv) p!9P q]9E@)CpHY \`}uڗ_[CӴpu<ٿ~l؟>"y["P*/42iq)+ؐ$'&BgMzdzW[!"@i~)nȧEC;xF#> '3iN>҂`x!Lz3@V& Biv~a!7LOe+$(hgqt w~m:a(uNvlۀ@D5Pt?E/ezKkg,#uP?Qo_8MhC+ .X_X cWZbil3^Xd$8d$</J@:%v|c:=2@^<2c?{U]2h7EN-7B̈F}zw>U=(ğb;Z0Sզ!0@Qi?NW(CFc՟OU AOvߟ{ 2+yɻğ:T O*@\Z?i~j0S%:}2F)M'3D!@qh 8m$2ڻkUgk׿N\m=폒1@Vi` f@諘蟿i?YD}(RDٌ.=Kr2biu/_'2fBSn&ӛ*a@l-h'~~rb b{BEπkW~Srd`h-}k@SΤ_~rP}:'` * zL 8 '{)? s ?`:O?Zgk)tBc#;ߓ;7}_@w0&``"΍_[:Л( ~t2_!(*bc>Ǔ]n_J!@%Cu ~w3nO5\/N!@TrF ASQ1jSlOMoz.Vp"=1 6DFj.ȿ(``:=E/OUO T9 -6/o5~%-X4#3YzCH {]0h6ǒvusi_z4Pn? `!@$O$MϽ+F` ˱7E~#%ojfzL h֧o[F%q}_ Dp,$`bNշ,.u:*7F'j_1 \IOOǢX~N 31k{suK|c2Y.ph|C߶ `UZ]#UoL' U$R}z *=,7\0*Ȍv$rZJ[\ѵ]JhvPLR } TI? @o@)`<=N =*ȕ|@\ P1@A#P@( z ? jd`h95. (%^{h8g4-PRoL&&aSc?T@#FdD e!= *Col.A@gYھ̜! fﴡ?³[@nōlzt$Jz}+LG,LAvP17,l~,YP6' Ȯ8-q-k%rrfݳl$t7L}u븖}$胑~wH`hDk"R:l @NF J-֖ǡS7JMT@^;Kt7&劀I001Gt{L蛹dfǵڶdU|=ѯ[Mo^Kl @6LOg ۮ՗\Ș&+?w]'Y@PNo>k@Vdw]`,QL4 PۮG o#/~\%tNIT<ɘ&]Ϻ0"ȃY0 pb*PLpHO0~W `7d"`h9Lrx >־L3OgpnBUIֺ>E@y6 ~`_^MD[(f&qt7 EZ X _)$7{ !>:OMQ7c ] w_ԗ7ӉL *:[h1_LMG{h X>vwbu\|b{@@An;A@'(>k.&Mk0B3Ѳx&ݽݩ(HV{y=[*:h_~b._9Tfp*aU4Oo}O?g&!=0 Il\qdF BN@p'1ѿxr(0t#)1ov&~Ӱ ˚#&'O& c]@' ^,tM/wMMAtR+g-w7֋__>1  HxIENDB`ic11PNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<IDATxڴWMHTQoz(ы~h"ʂDhӤ[rvB]V]dZhf( 2 ! h"F :|?wL\99:tޛХVV6iZF'/$4ѥVA~;sոY6U\^.09_d]CM}{?%uw~Q;DudI`1-ru@98r5UΉT#r8иq9Qx A vD|EQG<מ١cSQC-v{ 'oGJG<44!8?&.kGҁ , `t tQyLkzRk&O>\[ tB40V~8 +R#g,ݔk(^γ OO/V* A*ҏF1p {'jػ̘056ƁgV|v$"he-`k[4pZDíY3 +(!acʒ4:aVGPf@'Dq@? WOK9JIB qc:2SHTcFMbJpws`m!#/.hUƕ&;*@QF̀vrnbQz}(xB*wrQp|A[MD5bRiaAV!y=V\ ̂^m.@>-^0G᬴TTRmV ˎ12BQNt|00d!Z 8-%b'<1(&wR t*3{2V>Td Wvb?iiħY|5"0tlX7hLQ}<`Vv1 IENDB`ic12JPNG  IHDR@@iqtEXtSoftwareAdobe ImageReadyqe<IDATx[M[Uk _FBM֕4.*Ugu;ӭ.2]Jtm! ԅL62-DLڂ{7ܜw.?y;ιXFd+5~)Uע]:|Znܐ j Yn uiD/pa|M>lmg)wgkl P a>Sså]h k}nc7!xCQ{ñ?؇7n9W7Ja(מ8xĹ+kw!q(N;Fr *_1Xӏs}ePhN'|Z>M{E  /><\~*(Tqf (mo}[m {o8 \.lprkrY4 ɘ# #ZX'-ZJx!Jvn> @ӥmן ٖIwHMQڠp)ɋJ\| +PйBWo7|1W;y=\^# `BJ\r!XTJTS;@ۢiTV*I͟l_3c$ *a51{L0 WB'L# jb.?CC\&4;E%RL9Xg#!R\h{P$f'I\8- 0ePNaٕ $$ (P57GWBi$Fl[S4q7Gxpl WFf\]}::R2Lw⠽6b5 thCimBcV|$*ؚ:P2pFy4gm6/(U`TJԃ ] $4)@H#'ි@$!L*$8?IW p{|*{0[L;G~xW뿳{3JOIdBKq'lNAFNmv,^zP^6ō x@Ԑ H8 $0-nOB]eeƤ!:}2nTxPR-ežJN[dI,畤"(lѴQY@92(3Y򆘂s0#ʲH?-$X ԨC`wfANiŤf)2bd4FCXmP'AE@hwSW@^$?nF$ܫ#8`@O<_&o%{mS'__߾_z@oʨa0n| C?3ko)!|GTX@ׯMãøvk8ã& h>wߞP伏R { e(=Ye/:Q/6wգ2@n`K$U{<=fW}‘˻RP S*gpħ! wڭXh}QE(^! oxNU kpMCH$_ў/@s#F?X^% rQ6L{ŵ?w[$0J/SeƟɾ9֞|VxK^?0",9e' 0v\ @8`ipB$O,$h$X`PMO'l.:@qOIBĒ<) O^".X8II `O$:K*7^ѿgev (沠zA <=j #&5`nf$ DƥTh t_MQV߾`8CN] +ەą>&ִƣV$? &@}(;0 =җ9J"鏋Nx30?dFt&Iv?:49hlv}PHB$-;V0U@޿oz?2\PP ht #X;yv4d@NHPd7t̞;]ăJ%cOO#뗾H Qe fjc_].?_9QaąT@rmX~m=O~uo}`ظ`5w.;S=N:}MgjH^"ʎI7zeWҾ}NAܙƟ%2"ᛆxX1DPq?O$gMcEЛv*`04~ ^~rTn"ł3/|y_&}A"cHSa,>$}t߁i(2/S<܀*%wInXgC@bH @}O? @ja7g<G_g]VDєkk.iَg<$,24 +/GzUM {1a/GI8tOVJVxp,2kbÏ+F~8H?úd-o# >_*gy2f ? HWR66$,`O#8_QlLl-ᾅMmqgeuSJςt@ ~Y-paD ^:UbK~.~%d0m}M$~V_W748|xp@=0~́Y `?xeȦOZ$>$/3lCO%ק0n<=~Ao ?f)!@f> ?)!Y)$C~d@o;9DЛ|t.yWo^iOӽ q:ȾXI;4/miz "eSg?QG @"aOݥ[?Adj7y@kIOzf4xQQFEorc("6̮W# )?FKKφ;n?;(ٔ9kqA!XA91Bdq&f `NS.mkoo@[(i Q֘Eub.H?ƸW߾(]/cBYp/WR>YՇu{' P3+pDD{.r A "V T}ۺ?ab2:dÏجM? &zo~/Jǚf!@U,ɹo}rXwY% :')V82@x _B=6l!]BOO[' P ?!\g@=JB_(RJEa Pf-đhN2yB7żxϠDJIZQ/  WYaӈ,Eoyΐ:A/KyhS>Upx`6!Ceke!1>]~<0t`O0;!?-2k :<-4-KLdUrbB?kp@>,w.gMі3S[*1aO \VBCXa %W$ÀP,=T[U WdzD%؉M`@@4 qτUEf מx0*㇓}oHTJ!Z89~˂QkHByU^C皾;XHG%w8° 6~$5zɽ&5DBVt/R2 qTpI<$-lD5 $ 2iE`6\H 2QȽV`+3 @#F r@0`L*aI A8\;#0NTu0 .D9Tvp&QUU D9 ,S*Dq5GM#9(^ f^ X'@aNq`$(G,vTC'U&7a@Md!Wb KE`-82 C?Bu{o.=6>,/A:AA8##p^,%zz u: Qs47%$c0E5PcC>/} ûv_ Xf;P= y{>f@ppH S7/q ;ׁGk; /">wA?1~[Chڂ w1d*o!]VɤɌ >h[RS%^|ɇ821tE>FQ) Q* iDEO; yb90 1VٿDeM@t\Gr2~a9Ђ?E Kt-qH @P<<`+`PH_/C*Ƌ˦1pøS{&yL0`QOE >̼}}J=`Y@Gn,'7ГWCq9Uy"aPTYhI\'70aqۭ^)zG-=!(:xhI_ PG1ܥjpI 0txsWx#ǵ'dɶ@]Q$P䋔' ku3Ï 3s|@ $ⰹ7 VJt!^.b^ oF 5*XOFT aɮb_yE|̛[y5@oW'i8 p' 7Z'=Ht_R4a"p3j^mzeI^Vb*£7{*{Z._=a^4b*+#5B-H`U=M#;j "<~ӭ7U~Q9M4[(7Ɇ<>]dV"$ Eg%uNi2U;pD 9@IB>uU_IQyЪ]IޙOh$nGS=>xqK)աP ću=C3!$x. ug \+&A PZ x6s϶SUT rk9;D@T0;?{v2~*.%|qfTW ^L7o'T~B\G B%&0^THi[ u?=yz@@m?BLvx}0득}V1v}t: fH`)g{:U(sH bꆹnj/ bxHDBW?vꐡ[R- r>n/cIENDB`ic14>{PNG  IHDRxtEXtSoftwareAdobe ImageReadyqe<>IDATxM\ IDBl L0"!H E."hnhKnmoaa{[g3 Yh)Ƹa% [ǝ@&23_}qT*vUs<>"`ix|_ǯ%W]n~vg |b  v̀>F!0?rq0F#v A0!pQfϣ1(K~gD\) rA0!'`B! A3c A "?Sd'C ``Y~;p @AxDH3OfNKB LS@2E@s+0͡@@AWDq\EП$ۇ!\" ̾@NlV Y̰^X@gp ~pQ},2~!? s{ 8H#OfBfts4L>&G"ap8= ,"S)1?QH97}" o|7Y՟olú_٥/:~``,H"OG % U"!P =Z<?rzG`n y6_Cͮk ?E~]#ˬ>\ßn 0Q$ {ezN-ϸ0dZgG ?Rd)}߱iL_-eQ٫ WnN?J/+8uFA.TXb l.9(hߺxy(DXk?:_k}0#p*z!Ll?*'qaDr DDX@8 e7c݈ş+0ɵ hI`3+oʶom/AW W@DhgC]@2dl~~ Zhp.[\.PI?E_0{z u'CY߇^x@B,~? "`TԷa?T[F`:KW\}P Hr@o2 _|=$AJM z 'Bz%$$!@D ?e KT(B[ؗJ `?< /( P@@,N@"xr?koI@+@-AmP"@"W[yr@7H(n"XW'gS :_b惫 s|@@Ht'_kT8W߿@4"eNS[)$ϗg`$@@j-n>|?' K hK  >7mh)L `tO9wRNRؽ`y< ;g?]uֽê m#<d R_S}gS?~WDlL{9G ŁA@@2O _>"?~BgKk1؏ym)*f>5Zfpi bZuxb(Eb9KXԶ7x<- XW#9 8C)`^KSգߋu6?"`o@ٿFozsKjZG8rod)+ Y*! dX/'9˦A5??5 }OO> i^>LRk,(.! DXgK_DViв#-**"G٭ bf* _ۏr<bXs_7ʙ9xO?чb %?bS?_٥/~DA샫sy#d>o4 .f?+=EV@%p)L_>קfr,Vp:3MszGư^/}?\p <b̌,{7AŖ:-h9VpYsVA;es=C?oC||9/Ʒ |pf<ߣ!dU5 C>: _fPo^7ߏe''˞-3IpP]HX,mz0$HH1VMo /o.tC$ _?¢ \_%F[DkDpp8\tC! O.pZR@*ks3ö?}%_ejy~)@7,etUr`L-!̆ƒ:\OZ]SXrd&⟪א+*wlÜPz< UؐJg)_3r7}c<2_kTɅ pF;Zhb9o @H#OA@g/ 7S>wC>\oJ2d $ ??Nԕx"_f08?fC((0-9&A8qeR*1+fL6 ][aFq'6].CA. j&,e- de6MTCY1DŽIdO2 ù*0珲O5θfr.})Ob4؄p?Gp:-}&N;ձ?FK_{=s$7C}kVT܇4?f _}}/G?Ds/ZwWŠF./&>2Ho —&?~_@CY iND_v Od=DA4 Ci9\rh`tv<M֯bfqc/}_a#n(P Y}gg><,D(74WKYM#`O<_a2x׭6s{Zj*ۭZogڎ?6@bh(лL# ;K¿ ӎ7U޾ 0Z؉&+?FЇX΄!Q mD/E2A?_W`v@?Z_v֤TŚ~zߢ] e掿{ͬK; `寀T͛.6A R?RX>lW}}* f?D٢?ݤ}@'.0y]̢k,H Kڣ?D,R6\.`?-V,D5,˻Fs5p,-bW$C XUB}Bv|K-G箛:\k8^}uz'`sw6| K/~\?wl!y@޿!>ն B?׿k)ҵn|vmQ܊wsI (+a`b1_*UUky| Oͤ@ /чiAb[ yZЂSMOK `kѺo+?P,~`F!* NYiYgb.ulvvڱ4D@)UqDQ bosWF/,F%rr,Ľ1r7 ;7PF}2'5v-Zr)z{g1e @Q]XsYX+ڒ!E$i#rK'kk,ݴЀOٿѮuůo!pbBmd 8}wTU?|òuK,f](& +c6])TЦ@xx)|,#X &Ua *ϱ/x': ܢMs(A,K9jUws @kЏ739&_:T^QFrPFǻ)V'D\()Ӛ|b_oFi[%1Ù'lb/0YG_Z'lA_q5@y᪍ȃF;BoZ_~>|a3&B~&Sڣ\ a_ AnMFΈZ9~`^dֿz Xޠ*= f4@Q?iPvW߭NV _}81lPW_^ҝBp߰V/=3AQn l_ ufXfȳ~u2S~Ugy~_!8ֿl DE<+\?(zT_lZd DWXˡL˥kPn+[O-AfWz/_fԐDž.y*Z_1ſj˴ؓ u!i(;`y@e_ ˵6 Pտ?c ǀ?랉f?@E,&'7aByao(/2gßx4Ӟ)d$2,r, 3 6(jiue%Q5eEmn?PgrNX !tf/^ t_M'~\@OfmX:2?r3`et^blb@}Y[eluawm?[B M0_ d\gß1e h2?9ϩv|o,`p!2ٿn$X͍ ?C1;VY/#!c?w5@5EٿLi+3  R`2nC?h3PLP1fΡl/1"uTCl @ J~3fß00gh?3!VI+,`ppL fd+4 PŶԓ4:6@~`im/Ċm T rJv4k>t\k: Ćؑu.-~p_ #^ P_ ~+-r!U\\k(0~Df0/mm]J7b6ם:&!5$xKT%n&_j#T-?E7 ,ճ6 >u X+{ecmL!;l8ey2L^B@n:+7^A1ٽ߀,0(M_o?9aH%:>3?S,7,m?U,Su`Ꮒ??@( b _W! Xb?I-T?d{@"K"z^G8ߺ+j,ڿ5׷(QTUbmq$;0z5AW;G*?Nvd J vb790m^%"T@Ű+@-2la U†?ӵhL`99]g  {u܏ a#f\I8]ol`d[M 'N̠h~Peφ? BeP:\j/ ?T3/6*-68u-`* 'TgPAQ/ q^m7zGwvO @(Yy6ıoVs> xT򙏳W߿h5׋t v8Q+[@Wn=`"w߁7ZQgzkQ/[5glaHM6g%;e |V%~a;+#b QF;cpnҗҮg oʳ~RD@B@z +?[oTF+0~\;e?7aZ|?tv8 md ?={!(Niԍ2ga=ASg -kUφ?(5w_7p*XՄ@A6[xc)-sgYqiKKQ:5llԽC7[+a89NFfl0ޅ0LXkuNKZC R'@5St*"@ tT1b>ΠB DiE6H l, _j 1z6nX΢*XJq@7ͫBKB `)*3Si_ X,Efht0)nA]uoX%grW-˗:7>օ:~)cVEE^y{~Þ1W?/?\Q5 zh /u\Bş?]WZI gl/ԙBD!?:X7a ! KT/b"QPxZΆѰ 󾼙S ~*GD;֧7-2 |ӟ} 'fxW"%1O&$l~}ƔU[#0:b@BE~= Ѓy\ b@pz_G<$=m-$Z-x/\"@;Pg2 ԉ=- nww WrцӟεVNOQ-m)S TFJ6HOק-N@ 7}6:X8\ > 0w[DBi{`)Z,\Ξ~xǷ({ОL-za5r)`W-@+`cpAd!q'YR%h8qSq ҥL('Em׿+W'@dې Vـ .W&@DWO?"rAw*v ԃA{)U)3Sƨ phK BUh2 \O C0"sG*s! O4O@v?=V 8 2s}驭uwq@ X`־' Q~v t Ags ٽcA -EJOoʘ釘Pgv?Rh@[rUxB=+bHsжPO}?rU#_ܗ~1P-@T@h pKYv (,]@u% /ȃn"jg5з v d])T4ː\Ov d>\\ 'DSԍ\0îf?{Ǵ1P+z zv֮Q :nTk8R{z;-i`Ö/ph0wL mtW-L-ֈp\L' LsUwb;)L{ ԉ(U]^L'FX%pU0wl 01 މH{ DPhF 2`tѡ@=k!o|rJ@MlpKO -b 0h0Pce}N"FO/T!rP5{XllHdO֎o,v2w5 w@"S;YyB@d|Z3-# eU8OZ) ð}ӈ?y9;6?R =ý:g.hKa- Xf%*4i\D@o転Zk!U U,\`?-6!ipT `>4~Mօ_NLk-G9@(ׁs3`r P% ̍ONnW; i!5$*\[KDچTP-Qlw7A3*}A\/\H&1rwV2u Z(@ȁ_׿?@HSvb# \YabyBY*Pchv'jQ]xlú8 u ݍO68%rߴu"@)ߔ=o$'|j\*@51]kk țEkcW(Ѳq#|?_k.]wZL U*{eN 1_~}هNq QU[,~+f?F,D𻶅O?Z vpʇCвpes.}r$?rr xd˅5u$.eE!TÆ{n |?*C7ًM br.@?Pm繼`X%v̻"* ;0wL}o-T"(܄J_Z1|t$ 0X@k}}gE= _=k}~sP= _)kx _ (P"@L" &w:~dtؖl9P-ʓ5kzjsGDTԞ6wuLsy@Uh7m ^' N"@L*4-@< )A 2.*$ *Kh9(Lp ݕ-($9 ?s1e Ued]vFDvLM XC@]փ$ .D׆I8DABBa>}?zA@](X(hu*#P~~HL51}*@lvm-F H~rE~P8q Dblنuwq0B'g%AlMT|פx$rȟ\ؑ?R2HЯ\B|-F '^eo?IUaޯ"n*  Gr~MVt58?H@(B`㺻z0|HWZA_0U8Q  G 'ПU(+{ף {IWpC APEŁr0_J~ 4Y/ }@p?@"@.h@@? h,пPl^J пP59)SzD|!8r{ slqWAlY7`N;[s@5",ԃAh?P)܀idsjj ܀G_Pr4]&G|nd!hThe,w YpDYoHŵCP;86n@p\bBS2uZ~:c . si口M^T??D48 xZix~}>#_B`p|︮G XjhPgZk-!P[_r=S0<!NuX x, jU*kH!ff;UC)$djQn|_rF9}Q_r'4K-&=Zm8 o>ŀvƘkH P \2-\Q\/2b<뉢@Hn(F7̾E[\BHB" wD70-UA~[^+t@I.e}hϛk \ 2)[clޙ`@ # C ޞɌqB ܲ/oĂ?   @$H0#P}]01!Sdw7]kC8.KB" 6 8f:BzQɟs$?ڛF@"`p(l# f0Zj  v Xh@ELPB$"_fb0HI43ߊ! E!p$KzX.(~n$#n hr4c݅dF@(пPגAF?-'$hn tJ#Vhr4a.[S>ޅGCݼ`+&ptI7Lg ! F!d@,v>?b`2NFJ| He 6?w10Z @:y1w?GG(ؙ1vx{ hfŃ;,LOBB`[88Q]FS00P`o35 Rt m׃ʿV E/B_- TC IENDB`jamulus-3.9.1+dfsg/src/res/io.jamulus.jamulus.svg0000644000175000017500000000337314340334543021030 0ustar vimervimer jamulus-3.9.1+dfsg/src/res/HLEDGreySrc.png0000644000175000017500000004253314340334543017264 0ustar vimervimerPNG  IHDRX,=͖sBIT|d pHYsS S MtEXtSoftwarewww.inkscape.org< IDATxy[}'ž4z'j-qDzd[%JDR%ŞlO<$ؓq*)kLRq%N%8UyP"E-%lb&qBwc{. E}`os9RPQgWh|L/ %IxG_6YĀ՞{1-^vK#"jF\y-sGɉ,`jq=XV߷p ,duGydJdad,cmp]zDDD8(⸪r=,8^=+i X&x':DBDDm8orGd9ELT8xM'EBDDd|B x;CDD$ ΋.8x5^ѵY4?y +c.lm7iO? oኈh7xʵM O?7,fW( 2Bvf3f3ߓf|quk9$I$ 6m5Dx -3Ez駯n]K3rHL\Y=hߊK>".JiD]_kw:.k6"7}Ή.h-~ϠvR@t-VH$*|>/<+[5h=U_W#uԜCk=c]x@G,ݻw KC8`+g%.\NX=0TBU5. @@U/xx޽/.D-> ?В>!annx\t9$HP:Ö44>w]H>`>|(N^r033x<;H*0T~ ѲB{B ]|gѵ%`jj z a҇`;ߊ˨ϨnGgg'Bv.={Ȣ Q3<]0559w,թOiVN$Uݮz*3$ `piٓ]My?]K# 055e;KJ'"XR5ZfW9ٳi$ju)4yؘ%W yȲEd R*_P􄳁@p8$,-YMy1::*ŪR"""Va8$ID"KO|$4\e2!~Rb""l6l6X [ǔ (l;| ?]H=o:rHSNŐ111IȲyA[eyy*"&"In7^/n)w~J׋f~KO`uȑ/:ԚKfM9_/˵Dj&k""]-˵bNtuum/Բȑ#h1::D"a֎""$I<J˖c(aݍ@ K.cɀuȑ]Ie6\f UǪGϱ$2rJ+l6L7l6~|-M< m֬4w\zgop @Pp),//C*2*+lw%? !H`yyycsVX4v]ϮCӉf;k]w )g8Ot- LLLҥKG+VvB!tuuzVXH\.h4h4X,YDQ,,, ^ez|Jp}BJ,}~VѵԓN#rҝfwz^lܸ}}}+A* H\.X,h4icjjʴn~8--\>}}}V*DR,.\`HRiYߓ`07bӦMظq#"@(abb˗ t: 5_t]ywN.*=,rFFFt?Y-VH+ʈDP133qŋrԒx 5:Ue;+F, (f(-X=gPhuq;wN:ʧZ0$Iظq#1<{,@hzpeRfggmguӉ͛7cxx[nm?ތq;wNqv`p5(ۍ.pݻω*@Xz^/]K.zRwq5`ppЪv""Rajj 'Oɓ'Nu9F0ta%N7nx:{G^}jT*X,hZ_n݅3Odx /I'Q)ٳ *+-0N 5TQ=ccc8zYHdjZl66lؠ:7sE^xl2$*b19sFXr\[p7Zy '""j1|կp Uv;Z%pXmKv}KF.BI W\iܱcnv]a} ۷os=U_*%2("‴X|/_ƦM2&O:a-XGŁXoaa'OlxFB:\utt`ش2Yژ,xWo(G$]}J n76l`w8;H8uTJK0>O3\el6~طo\.} bs$YTR)|Ylk׮}PѣGCȲ~ G޽J""r^yHDsw$Iذa<: 2 `]O_]x$}W{5.ys 7#l6nKn;Doo/^z%Eׯ9tuu |Ws, cyP][^|ś ƎR8|CPv}nDDD"S{cݭj ߯Nnٵk [zm^s^\\o~Zxg|H266#G(l]sZ[>z]w5vGzv>,2 N>mZ޽{.A""j 6mqad2ʲ]/*@7eQ҂uرN#. o~iq-q}Ym"""]DQ>|x ո\.tuuijqr\شiUr]w5$j +olVƝwDDԲ"|A0my4pG榘^zkZC.MEi ø{E[׷jJD"T*إFh4jP|JѤi[ؿaϟ;?G5JWؽ{7\.[l6yx'^t:UMBZ gdRقbyTΚ`KwrR=,,,୷Ҵp%IكnM!""jU###xWnr^G+]Ksc v uU%]UGP|נp7x#Q[l`2 =_~]bu6h'G5M]$}]~zE"mz 5w ܹ݂DDDU|# t햖zUeh;"|8DzY^^Ɖ'4ͦ(`y^۷KqE?~v^W,$!X7i?jv҂%ٳ•qWz+)pUWattccc5K&uwmBp: ڀPTzop}4;;?V;wDoosov5Zg~߮fU-XW&ŋ+}zkrEDDÖ-[M@H$T7p8,z,Կm c~{Lj1xwT'Io7ߌ-[NEDDԔ:Ykng۫j9I T";#dc5-X (\ 4ى͛7H׋!NeyZ\\D(t,% XVCw oo3\QCND$Ν;qźR7,cii ,E]?{%IGCk믫X$)o&l>Qh̴A$QulөhrSlۧm(HimffFSqW$gmۦ(`R)r9UfY,//$#] 0=e앚[?{zzT +c=6c)eW^M +á8`mٲWDDD:ڴi J ˲2 4<O#%6Ǐ_{mv9aWDDvۍ~,"""mܸn \_{]_XXb6Z"<~$Ig4W&/"""y^ؗ+ΝUkd2Yw-}5D?11xқ (+"""mڴ sssM$P| / +2bFz rMddң[7 (LZz죳j ǽ>{9 LMMUm.FmՆ zEDDd˅@ s-,#L/`-X+ꮗ|>D"!r:}""WjjTe\.jm>X ,g zu=&5So7USkz𹰄R S4G___ 4:2nk"0U׿u@Ϯ6[$<%""k 7BT  "ήtzDDDb1ݎdS5Ϛj˵aʨYc8;4ɤn#j$IeYUz#ϸY)\&Ղ籰p8ڕ݃%,n+VͼY 4_J/}h4P(d񉈈ڍ`$IBZni%R)nSKDDԊ䪻 ]}kgY7K9L;/Q+b\k5Lc]Z]Z9ZXX2gv'""j@65{Dm8KL )n՚0scU1;;L&cʹVڦ"p^T?$Dޅ@DDdItsss]K3Jg$u% ,")󘚚† L?7U ӗSD9$I2kZa"X^^F,C8r~"""bt6Ϭ! $`5zhv齩DDDL&L?)loe*-cDf] lSSSBK.Zu"*,vEBDDd*Y199ze%IAq,ԂUi@$Ih>#͊.TBJ3.+MU*Vh8}X,d2)5y9B, FS%arr}}}ǓK""Eq5``)f ^RVR%"涴$J*}]+J-XX50&"w""j)V W@V)53r)n7&Y1==nx<YSҒcWKvJ׋D"QJA*JfggD84Q V푠,--a~~^th14X7ag5?e,C<.$""j>0Y!` ikvvV,[ɯd2BnA+RۂU$.BK4C VI2D&A$]+wQs+ C*%-т%I[U*8UC-,#"pBjX3AD##!ˉ.j{W<3W X<kBEd2tvvː,#Ncnn)V)g٬p}qL0ntZQTPhVT*l6P(.C""nyyYVF_v{T^&>K LX@q{&Qe &2b|>:::y,..*nܰj㩪oWg$p|>ͭ{7Y>$ R)ANDDIReYt)\ ,gETP>[Ɋز,[aZdY2 j+6hYX?^}B@݄j,-;JI%I`""nYW~^{W@1CXuŕ$(D"8}nB-J-[p8`?0U'Fe\n]"IxVZZkΝgO:5`%xP6MHDD<uZ*bVjھ}{R%IΫ'#""j6mei5V~KS۶mKVbɣy}Q.# W֐Vr9+,v8fvvVZ_W1cF!;U^^R7!IRũ c(fj&m۶PǂTZfkF$bYnW5ttTᕌT6G ɓ5YJbB""8j},2 =(X۶m;yܹnҥ$ zzzH$V=_ J*"""Qv=xk:]e&5 =XyN@DDd6 |Vi0Q:ԊUN-|6Y;%IJ`LTT(ܹsOx699sΩO$N@E~[$p8קgMW__Ɇj:@KɛߏQiV7-uvvj"S3*L)n$IIQa غu7Cikvkx@I+XW_}uOTu+ kH ]|Zs0Od!EF*W_'Nneٔ8n~_Xhi@E|_ƪ_}կ8x^ [ԺU^fij$ @49><<T/'I7,0E=U}jBO6UHP(HtOPW7Qgsss5n[eiNfzD"KNZ7`pݘU}7Je +c""anphh8`u3<lݺ昫ZTr9.CDDԀ`0˥iO(>c\$UPںuk79ӳzj-,""j6#$ GĠ~_w!ܲeK4E###>|o&U ^$$h"""p[P͆>+ әy˖-FR=^v;vQUUP(B"""l6"[+@uŷt~lݺuj !""C$D"+|>9dLӰKFFF,sGaٳg133jf٬t7 V @__/~i͚,b|7x̆ ciixj\Yk4R˗(f]ւ.\ _cÖo%$IbKQЌ``PNJ&e':AJa&V1[,khDDDri|Wp܂.\8W7hll U^5f;Le\""2lA͆^ }hhh^σ… t?pΟ?+ UkQJ$r\Y>! .^r9s4pIĐEDDmr5<(=X.^ӈFeo|նmۆ\.bKVB|>ϐEDd!` ˅p8 r(fCւ/^kl 4xwkj>@euZF(j(\|>D"7Ĩ:ɰhf; L6) |oNDDJ<OrNJKv^uU[Ztb-qCCCKj9r:kvU[>CȠJDDd&p`ih + 0dtt~" yU Yk섍8u}^},""jN$! j^\OO"pUW}"S>ISNA"Sdn[:l "f` t::$IѩAkĴt:SNU\Z7]DDdu. PfZoȬƜٴfq),//گ2$""+| f۪݂:fԀccc[@J8s jn'CYEiM6ͪK,qppp̓~տ`yհعs'}|J*}S9Uva]•nGoo|ph*6 ^/###qVNDF"9ix`iӦ8Ȁ¥KpҥUϩ]Rs6$""38ZJ-WMݴiSZɅ,t5Nh|fff022Y}ѥv'vq8ziӦMD 4`K>BP(Hܹs _vZcp:!ǃfM~$ .]KOAtv*@ڸqu,/WJqŊ]%J>\gODDjnvݎY]%tL&[7nܸ~pY"`x?n]R.T*UuFgvutJmƍ ,`|||Ő'*u9>Qr\0dχH$,נ) )T\*.C-.G""j-.ːP(:&Ypƍ]H9,0.jTI"H$n/d VgX099EA"&&&HRG6Ӆ[; U0TV-d_$J4}O!lBR((l[1XFm }a"l6|>:::rD4[r5Z"`.HF_a+tV/C6 UǃxVL,xr 7k2 &''op@Z177h42Vd%ZFm }|]fZ4ڋGGGG3aU}}}o.D/-`jjj,thX䥀u[`{=k0v?2TQ*lU՜p___ S,G%ѵ-H #ciiIT F*#zl@ A[m9Ε[ 7Ql]Z2`ԔZD) X^^^ \Dfbwf H0xZ}}}IхeVg|@@t-ɲtxJvzkڴPEfPy<Cϱ1K?]Z>`5meXK.C2D*B:F:F*Z Pe~#Y^#®wIDATS 6Ip8t:W=Zl:𻽽DbX0==7,+at:B`PȾz~X5h=_m\Ҭ;7-3M*ki6B||,C/w%z_ҵ#uu{$5X$FiAͶZn,BoooOF,ނ7S# 1[[,v+_] .lQ[_驿[ jۀU233 """V{zz.D@ѵ5#nhpkOؤIt-DDDMTt!VL?_^[""U^]0`U133ssv|\t-FD$Bkk!""iхXYrh;Yg$""j}2 WKٛOpR""j/O'D,T} ,"j4O|8*0`iF;|Ż {CDDvWWׂbVѨcCDDԈq𿺺if X:F.5[CDD~+#Vh4iw .S()qWWWNt1 hT;FP@n"Z H$ `,b(DBDDm8oD"â iu X&b8N!"D^]L` y{&""}('#HRp=mKX,֋prMp\^:bq8]L;ckQ Z0(""jc~p8|Rt1TĀeAsssP [ZYMqU8y1, w!"""4^p8s\1`5P [wQ/ XMnnnn3>\^ĕ@ .-b֭-p WZBY吞Z|m_yS`iDD <3^ PhJdad,65??@qV)p5 ?GBQnC X|"(N2p""m2(N{^(_6Y~=DžIENDB`jamulus-3.9.1+dfsg/src/res/mixerboardbackground.png0000644000175000017500000005360114340334543021443 0ustar vimervimerPNG  IHDR) zzTXtRaw profile type exifxڥX[g=ě\ĩsjubc io=T1Ɵ.Fȕ2E~5n]) ֝ e<@I{ldim^셬;\!xUaӾWhCF;"YL|]?cLfXZiIiKȝ:ғľZ2VyqFM=6~ua~^xݥ_[0HOD0Q)=9vR&+@^ D|=Q>wiXvF ShHQ 1 s_4@LJ6n@^3ڲeF ;wTCX?o&MK/ a7_1 Fbs'B/fNP躖NnYb}97ž, Ё@:` d3CH Nމ$s7QR\2l-9DwO>lp B nKEC1K%B)J6" w)\ ,XU0jk4| -r+t=SϽ pëFiQ&6t0L3B۾~mԌ 5ƸJE3 fІ1Ӊ3cWx!=cI )?݉ܯpS[CP뜶 m-oz6%gR IdB`9Z;)7 @ߙ)&Hy:堐V)o #W^i85sd"9b->+ ߿}ۋ&G)= ;,hPvPF{˓R@ [BR2 RQQ9Osy+n$Tسu7D .ymfɾ^„c, (F6W$.E\YFǼl\E;ռu;`)(@]#iV(i[7`T>կZgr-(4[,[^ #i?H9m Fd}-KA )OOQ*aeZKDUߕNT> &46!WJ4.@T'r>r#fnX9ܿAe; Ox7h _F0MNʋr/lm&j%UϾeV*sS.vC`cN!ePvQ(}a){xbCj7SJtlT|z'PBt5/\T儝6/,b&m%fq%<2ArQQ]{˓OO]h/pn.xK,>/`񬒸n'Pj ,0d7P/82T*iߜ%@[r*NO+ZFJAQ]V 5Ԕ c\|8 !JW]镐><\={EF* | X~GPA9rr Gchi ؁AKӡ?2 ֛'0XC|Wߨ[zbMؘ5yM$.J5һ$Xd7/ӸK~tC{ӌ0Ҙ/q>tU-1Z=OQUV#MKE ?k!%o\/wu>-h;X fjvA2-b(j 6Gw(ׂX{t^qNL 'TjO+] Qhp4ɱ ׉A̕u),|F.i=Xnow#g+c׃d67h\K|lZYTKtUr؝_8 r`|B# ߷~_NԻR{rSp{Ugk/dvqdrX(*CUaq>|u?v]y]S_){UgF#B \9;R@d@l.5O}}q.l>)DH3wB )yٳ}NniCCPICC profilex}=H@_SU;qP,8jP! :\!4iHR\ׂUg]\AIEJ_Rhq?{ܽziV鶙N&lnE B@=Of1+I){zYjb@@$aiOm}+*9I$~όqX,Ƭdjē1U)_zr⬕yOp^_^:!$EH a#NN4'|_"B 0ṛ Zq/):_c|;N>Wz_ӟZZ.[\'C6eW  ) ݫ^o}>*u#E^ywW{oirxF {bKGD pHYs.#.#x?vtIME -Kc tEXtCommentCreated with GIMPW IDATx[dIf9'"33=J o"8M|"@,) Ћh+vOwWeeF9CDveeeD_̀@uWEv󋹈SF6 |99999-vJX}<r4|pC?=NNNNN9!>qB<&9)ciNs=u*/z?x~(߁4Rx*[Bo3C_CNݟGEP`j~ 1M<x4=#*f9~Os89],+8!(Iʾew 0"H׶H۶2wn#(D_nBVK0ddC-1̮`%KR=;'Fm3՟_)"ۓ#< =_F Ýd<dN~qkZF鮮6Ҏtv]0E4f]4,3MMDuf+7Tv܆`O_JWyo|y8MBvgp9?H?݇{?a4m#@6d͍\Faپv3(h\R_)6ٹuBl8d7<>Q7r<5">oe( ҏ2Biҏ\dit\tO kBJh? ?t?<>YVԝANv{{ra' C#udy;R8r#eayq=BepԐPRL=ois|qr:;xkSYG'N0 I#4YE=~z4p|- s^A7{ WPnJ }Ph" }ǎilv|ROw}/80r8d( :FP} AFRж"-EZJ^F~/ L 5Cgtn:i&~ʆmx?dyՃyJD6OARF|v(NtP(H9rB B)"0"M[ 솚e>Ѭ~6| 8;z/Ro6rnKr뭼}yVH376mR cAl\( .u,Y6r҆?SMaM6rN~F+yv (BJӛk:dϠ0'W2-elhyM٦|1Æ9"h[~'Ç;FW4A S״bв`fQ:WFvkNOD$vD/w@ʊ GΪ9a^JPʇ@A:) #zx2-Z75Y f1ng`Yo['N %+c(61gLS8sѓEӉ4P ұ 3z\ӁiY.#pj.{xӨT`|n'E0 A@cI!q{(|d:STӴ8r㜵Y0߽$Y[ČU=Nix&FAvQlߌXA\\"\]#ZUfۥD b};@JBarb3s 3He=aC.F4JRt`,S Gg$4Oo|fU\?Lj1tX!'@V|S[R0Rh%QZ'f\ -[`^9c#ʕ~\#X=,3oG?+<ZAe|RM(uߝ2Wq2(,Xˈ )IL'jzψ{@\Uy(I1M4X8 e4K)JGXV"if`7}}DEMY5%7V"Rbt-jyysJL#J C=]%)Zs@=֌Yl0bʈFeH #Uˏfu)G% ∴ \1UΎƹ1Xs~ \X`s*y/ O^ |#BxruyfJH Ҧ9Ge2L?4 X%^KŊwNZy~i1tq`ԗ/9ZYDd8,5ZK+Qaځ} )ϔ̭`)ǡ?=Kwj}_4}L3"uė ܏y۰l/<]DN-HJdᙊ1V)=|fBw\,R\fQ-s'iRi)opcV<.Oshs\˴uG~ lJ . Ue?YkbDžSs7V2gK1p٘a{dݱߘc!vк:gUyD*AVgB R(KyMWT8:)\;+g#N,N%`pG~`ف~q?rRjXr]5VykȜTxZB1 ԌM.cdn8V` %BE5M|!ίf_/h=)9"օt(U?Wj@ fi j=K"]Q Lf!ĉwGf*pnoZ#IZ艅 .<kVYOBiiղWXT_X}qFdI9TG yi]~OՏfMӂ(;"hCk~׏B*=z\&0 EO$F[?'(rWn;GV\LL"[R1 ե.g:$#H0FV<vT#N̈&@d^ar,WkS帚f$D6"4.׃m,J͜|*CW4Ӄ=}RhF ;FhR]~|ۼ3Z?ց}P ꭮o{Nd3\RQYշP-'s-lT@Q^2$]x>VeDL*u&mh"6#V:fk+lWheH9=w L4XSzs q\술ɚ>7ѭހR!%(RȌ5,txNQE `Tǘ Zpˤ۽ΠjLD sH/:e2js b^ Ϩg)`,nO h[(҈2De{yqær/fguu Rg`R%Kp UNKQ܌Te|t\ɿ;>;HQ7AL ~q$6xiGZNFܬ> [k99Ća0kZRs3_2uEc=2uD܂Ů}g:MyLˎ?3ε) .eT!D"r&G4Ҟ2PzELkIrNu9Ry J"j&$QZߔʚ@ ԨN/n,|P[r/49pI= x9Z"vʕ#r[1`fBϼ?9yToutˀM 0Frʹ3iM#p eq~@+#Z񔟜 `ir6WJ藴D<<4TCVH"6b 둢I)~l4D[ !$] cЩZ=E+ !=u* W)GlգձSsOgeLnY<0]`SȒgAoXXѫchE^yg2섌#BX4c75CFyyr"#b—oIFQbV]:CUe|yOd`gN_@| qݥPw F +bKFz`Fpya%$UF<5"=k-,.$ rϖ"#){1@fJ6A6 "ZQFGDKJ^⺠2GI'cɧJ#ueN1W%S]H84QKuӞШF N}W[K_Z_C$CA=jD1 aEGt0Ri.K&٤qØQɔ@1qX=!t6)`f;Ϛjy@,*@e.DL<Oˢj+iF*,`Q`RZHERk`z !hGqZ/w9,':Ja"YGu1\\/2dh.|iq"*[Vkn$EGYE ;Уr821UGKP$pQ~'2E"s΁.O=IRKoe"PsfՂn@&5ܹ%5. +n˅doy:l?D@UE+NK1ɑr ;}FEUCMF,bC @^.z-X&1}|[Masu?ogʐ1HL~HcK9iG*LZNTZ 3jryeT5 uʖ)⫨P( /*ך Ǿy!*nBeD ZeS=^]'o4" 3ځjT8&`P 4>L~INLU0H"O*L:LiQV6֤"SYtTTJ|"miVpM+"P|aR"IqŬ9F3Z8a(?R$M07s; ]L*.:Ak0v,zrHE3_ͺũ0^PkI'&Fp-l8?g͕} ͤ;(I#䑎g\wD>sQR#b[<$@oldƗ:DۧǑӕ>#nP )sZݝ<3j$2v,X~/Q"{%.CrS-|&#*o23i{nIpko}G3U ف03ޝ#rx t+yO Hũ"#SQҋAdY?ui#W| '| -d9\QN*_j5l2QjsD~|;rekQ,7f>uN32!dTM+&ZT/3X=p2d/LbGb)uUơS2x?Td'+E4]\C(#: ̘Sj]he1M9f/uI`֖_2V`gzL4:Zx x`zN|I&^!–;"i`dƙIN,,^daHq-<4ZC>F/zkH >M>,ue\Ww3ď f ,\!S jރK5,B6LKpK-0TWT6lsZ##z*3C!3# *h3pT{Tֈl.h`0zY̳GxZ07/S&郳J*+XЕŋ ~#pՀ*CFdC2rVDu~\(b,crxIDm^5YBv/H(.Ah:9YJ1RXUI:G:iԨNNSQ:LOY 1̭g,uUbº2"mfQZU5pEH .4TnI;M]4לd_' 6 *dC]ApSdUFr0R 2/0 {BMAnqsl&z Y~:5hkq򚡒P,L)Z>Bũ27DwN۔dcPt]ңMOSUqJɫoOlU=aB{e0&aAmV-`t;"ΝB;d9eN;2Ccڻu+P +|tph0#kk~HGZO#ZX |Y'ƍ.\4;"9Qm]OVzՅtY INӺ$NzQ'UM D_= M ;ybjiCFGF#q77n(#rBu\d>lc # zrە*;-[6oWƔ:+1& ;AQ.E|'-f)F6'rO#MXSx!Պe *9 #-+O{Eǃ`QbPp-9am:hkc}!BjyG P+PxY'+QZ`U#qgi(=bYx+n}MRtaw3gjQT!LC50Na\!&'i΄ʅSsG\91)f8xd˗ʡʬ;ͩ #tjX Xo͑rkk3HUF+ޟi#C8"3ܑaC{w@Uaf !6lb_f[]k59N)t#j,hee"7dSj'#ʒ%&ʹwB~|8ta뱈Gp- +SMʏ=21Dq+x?!1+м&T`Q$J Ej TI6zԥI&5d3|t D`7u68W3x]0#h7U?Z, sUgh b$jo[7d6T9-(tZ2նO 钡WNhggfZx6֦?pjV¸ b(on&eD_PᄻSb@`4gI(|:sQAsP|@Q3D{E:L243YUFjg{Dq3 ñ gsW~ND;FH(1ٕ/}:W,fy9ԋLj odњpdɡcֵ?(ِwDўP \O+2l$;t1c "Q<%!ldF-IURBYԣ4܂`BI KwSxgJG4'21Y 7dsG)ny}h0 fZ:̅'S.׏ޛZxV5sQ]9Sts5#Uؠ-x.) Tf/תe]GCH/P$b.oI\E\#ۖlvOq0_Mt*Lx6<>t‰4*qT<ૠ43-ќx. 3I'֠ho:Erh ++jl :3 W[ ?vְlIWPHѿ'.YQ@ٽܨ+WTxKNv#>u tS3EڦUdKSlG=_1G4z?F/T@@K{_5√G6rvM.UO3:A#;=h"YiOFCd#zK>{Nt]<]@\ӭr~in1ɔ hHƼHtp}*BmpDHYaP#N8O!Yl2j ,%M3UE4 MIv;MnRkraЯjُt1<?wH5>\/fu(Fzs\6K0T߀) CuR`SC)_prtT EVkF3y1Ss!N}DʟP5[^a=<ϼ\Zӕzdq~p©B2h,E-Ö^+ HuNf꽐BRjl4>3OB_ó~ôͲMW\z-gzБK\Nɥ݌QrV[H.<Ȍ MvϢcOBl?1.iZ1;Z兤uҒfd#KzOC:4Fx4'ḀV wRBmIF L7PٔSeƻ$pjn\BH 憭&BsHHl-*iC#/dGf徏LrIyfT$8ٞ0L[L䎧U^X[؎ :t ~JKu:M:l:"A\,r녮`K+s f@J |Z~G*EA2i8)ȥiz/؟0'EsT(uDɎhPVdxn3H k_A$}I{F4rx|)$U7v9 CVp# F#Ń\ֶ8IV"ؕol. b4b_X[`m.9st:RZ†# ?a6P>|>U`2|$VCQ \].zj}>1YLrV6vSbªSsV?N.($tN=fu|cdEgnP^'b :fjUwaRO?l%{Lx٢}#e8"R}!hi*x)K*a:*tw6]mvNbUҸ~e_O;y%.̈p+#.aYzA1,!2#*4EPwez)Rf$4  -3Fj`Gd4kly]KrFZ̬Iu2ORkx4juJg<,f8Tl,v`XVi Ί~@ 3"(yCtp1S0pez3´Z*zN<"%+% 2![Hki [sDLG"d*%{N[G@%a, ґq-ܐvuitpP jE h4;![5*MD88iXXo9hqJڨטftP+JkZm5:E^NH QUp|{,pP; ~rjuyjV]yN}A0N9*AމrCjX` PٿB],0Pk7*ⓐ|*]+S,G4c/¥9 א+&wTc2r|z=d0PB] s쁼SItGݬrP8*" 7nY<ҝT4+\`N}J*T 4W'#\e3.B]}rxW""ATJ?Ri]Fv@d#0y<@2"Aڦ4iDN]1HvŵQx6& />:-pm'Va/Gi8Jŗru|;p+8ʦker8 j#d"JB1h" i(LJmQM1I=~F]xO(J'H F2 6V6S5W=q=>QqA.*QB1gs:6Pt ;/7dD/x+_G{9~/|iFnia lExL6Nnnnd{ʦF5~ 2 Ui~_ Z^|3+#%aVxF6ユ~:W4PfF޾}+o޼ C/FY6X#0vYjx8W9"Xi\o~O>gKOWM@{JozZ~|w+d?B9V޾B޼}+FBP9b+OTaY),R@v]h)՛?y.;zziNJD^_~g6͍l{z8EjDKqm6A1aB] YtR%hP3F6i6l_""D;FD~/""܊NDǎ깥i6M=Z[yx/MiV^_] ~ah J{`_sh`ծBȻww~_x淿):dHr)#)uqY/A񍗛E>RG&P9>@oo"AD~8e?NGy/"whxX ǥNDE䍈_4M3!2 <娟*2kP "7wͯ"rr4qiз=}!Si9G}W"|Oٿ?z66JڿSݙe׿"?eCOoNQCHsD|\9eE?/EO?'??ةEzzK}7'g?e9NS#'|\=HCVFD~~rF8z-elNNPA ǥ9w!>8QGOܟ#;{RF<ΒNA|ɩ=Yу3uw^h}8yO qH+<8i7>&gDx,uO>φʊFty\֧ǎ3zI)IGLsAeBz{{5x(Pu?g u+,;+CDB* X` E=8`gSeD~d֭Al@?H1 XV!:g%ʸͰ5?{zz #!p'ovR.K===quBtB9 uϴ.`cX$-+k4sEbf]YE { ]3,B |= iQDk.x==="ے!Ez{{=!P˔E׫===!%BfCN0>3E#!۵x7CWOOOے!,B]` B6lpq=X,Bt8;VD,8ӓb\!@ z@ۊEF6lDBClzl+"d^q3l8K[!ENm'Em:`/HHq(`@ooo5n"BTpd\!C<ݜjjۊE qdwP"dv"(a[!L%s{zz![EoovdCvn¥8Ȇ===q X8 T'Qsu1z,0.3xw˺BXE,W@vy!$AswwڳglP"w]!Jٳgu11{ڑ]sXa'8gq=h1{6cd[ZC ZgϞQ6 XT{'qМUA={..P"wulw "'xdG={N.bQ"w^CQϛ ٓa] !JP"w^?ym!hg={h Db(aݻ }"øBtg9B>y X{ < f+otwwu1̇־}V ƶBG$dW.P"ٷo_Gv;r!www_c] !Q"طoS@BH2~B Xk7^ueB akEٷo_O2.b g] & XDw @9r!>kEto߾d JB# ;ɺb .@'Z~,<1&u{ͺb~AaֵBMgݻͺb^&>$ |y4Q].w ! ޽{wu1<(`߿'u-RjYB́)/6Bt_޽BQ"߿)h@By'ݽ{wu1Ę(`E߿ٙ[YB!'w>ĺb<HAn>-c] !g@OBP"yۿ'3:ֵ% /wB1P" :p@`R!h׮]7XBF6d*hQfBɉ2oڵKb] ,2 d] !p"ڵw !Ef8p@ ONBo_ݵkWu1ȔGVB 2OڵXB@Z}\!J!?,B8 kYB!&Oڵku!;x oABT!AX+o<z;ԂeAmϳ&$[;wFXBEb< XʺBw||ΝYBC"?`] ɏ,zB!`V-c)oN7pg>\#,,LQk1Ӊ:աu9$?to߾Ϻ> X9|^u-dn,crr^pu9hV-`c]ɢʼnÇ?zֵe2x^LLLPkӉE=o1/]۷ou!>^+$I@bi6 uuuhhhC~پ}1օX,>#CO,Lex^uB 0t t /m-օX , !Y022T*źK$ (N2 DQ,3^ ZHl6M<_vv}E+sS3\.455m۶.J(`_:/dYuDE\xZ ^_Nsn.U5,ŋQ[[KAol۶_ ,oA-Yڠcԕ$IiKũ0{ѹAf.mJl6466Ɓ{>uV@f7AJW@rAeqDQDQ1Yft]pݖk$ ###|hmm (/.lKeGtߏH$ºݥ@F-jg6m*l[묲(++c]|c֭4(`ȑ#4N2 zY\G.P<^PRR2Lպߥ---p8E'_޺u+MF X*9r$z mYF D,Je!Iǒl6TVV񠼼۰f]v---Wmd^uVZVGTpȑ";W;H$C8f]r-UPe rPSSjTVVtrr-I=n,d2HRHRHӷlt:D"@ Ia6ݎ ]@WQQv0"duVZ HtȑgȲQ'"#sA@ee%QSSZLZCodܟap>eF,^ۀ$֭[º#U#G ӘFqigaO$S-)`ѢES*jjj,3.&]@~۹v;<jjjPZZʺMn,Y!2޺u^օ,9|,Jf2$ahhcccKQ$IBf:R hkkCCC, a``|>벦UUU_ͦq"`֭[.Ĉ(`)pȑGf]AnN\kU(bv:Z[[h" S*S+^/ӱ^6mU6eK\.,Yu9f~˖-.h(`ȑ#wzEe(bI`0I&*Smmm0D"1r`JKKQ]]jn[~hkkxx˖-.H(`ѣ^u-fDp5픻1$I~[l6۱rJ\8Do˸rZt{2Oc46Kxd˖- <<=z LdY~\>C4fYUU|Xr%VXa. e|2._~]yEE hjjBSSw9lbo:G ~ Xb&d׮]c̍Z_Y tiUrJ477kOX,+Wx toii)x>lryy9:::rsH*)oٲ(`ѣ_@k4󡯯O *ILF}UWWOu-_ܴߓɲ֭7nh޺p8PWWc=m6P[[RE䦯oٲoY; X 8zgЌ*E}}}ܟN199鍮Їj*455ib,x~wl6TWW^EY5554^}ݲeX3 X8zF/&Uly Md2|+//իU}x7qEܸqCZ9,B{{;***Xb۶lru!5G4 FGG188Ⱥ EDQ VZXvZ > VZE߲"x"x LNNj͆Z,ZȐǩ hnnFCCR"`͖-[~ϺQѣG#;ֵ(qR &I|>~&> V^MߪjdYƕ+W㷿&]6 3dЪF{{!kP?7o<ºPѣGpV)]-DW^f9|I4ޜڃ+**zj<hiiQuۄ*HLu!^~]e]]]: 7o.'9v@7Z.-`<Y199 ׫jݷvFDabb/^믿zZH_ v;Q]]ͺ3g*n5ͱcXad,cppK)H$c=F],㭷ɓ'U_RR&C L-mpȩݼyY X7;vl#yAL&{OIՐJ066hTj%I"غy ,ǎh6:(}]U[$"^/&''Ur֭ի"M exxN¯kMZ09NtuuL͛7`\sXǎ+p}k1*ϧjQ{U[[֯_ロ|>KxT[n555s<7 555K17>z˗/l2UG/0Ξ=ϫpII -(ŋip͟b]KXǎuF$2011E{iubzD.\3gUfuu5 1U]]ڸja3?ݼy.cǎ=ezDQ{ァJ`P(v;x]-*.B$_ӧ#z+Á&TUUP<:;; 9M^e] XǎkDvbfֵ HRxwY3t:1D"rJ޽ '"Μ9'N^YYŋVn7\}\aoڴiu!z\:~)OhbyMP$&&&th"޽+WT2B!_ŋ~ f|?t:tRn֥Y7mڤΓaŀM_`]A\?)J0::ZtZii)6mڄ{ ݫ2t(885`ƍ/.DKXǏ@vMk1YquU&QD.KxT0ߏ'E=mt:B̵Xd (pƍSX'N<Ϻ#e.@^?Ed|ϢN !őeOSFGG}ƍf]VLN8`]Hw}^ؖ(V%hٰqFlذ.zp`pp?PQQmaniƺƍɺlli IDAT-2`8qo԰w$իByGKp\__g}K,Ѣ LN8apZֵnzu ݻi0B8ve@8V~ )d%6nR! "(\-He{\+Q1888\S>яR"s+WEy睊/2קx\WADpj޻MT-X'N:\d] >%b <3T2B^{58pTJ.C-dVUUE]qcr4ȼYX 6u!2|:y qWg-ܜ*+z=܃}c !&ve?F2Ǩ K,j&Z zazcdnFطo$1Ђ `Ŋua]Ӊ˗餇jÆ )QG  f%"^MZz5N7lϏ@mm-~!H0(* Nòe˸zڑ#uu!2\ ɓ'w8Ⱥɲ׮]c]셎y'iͺAOr=b1EwhoobT{{;jjjX#ׯW6WΌ4m(_κ d2 *W<+e^&~3ohh>)*:8]Bّ`SNpud2tR:DQ:xڵK!Vp=lpp?_rɼ%ra$v_ݸXNr!2ֵDe;̟$ CCC[>ٳ!Gׇ^xAqkT1Yz' t]ׯgۺW5c|>N$ P{G>Z}WUUV\tIdLDGS>T*YQYYI V uu!ԩS &UZi@ w}Wmr1)f*+W駟f q6<]z?O dZKKK?U@UU&6eׯvw;w W3$zղeSOA 3pLҥKя~/dA8455iP]|rMʃlFCօ̅SN}XO:jJE\|x6),Յg}n BӍעb\3$Xnݺ_.d6A&(\pƍN9z_ BU]]~iZ[kǝwމ`0'O򹆎p0] :Hj 7<ɸYqقu%:x2::A5DQ(\.|e-3B>_|6TTT(zZ=nݺͺ[qN>]2Nֵ"ʕ+LoDkxꩧj** o:}dt:~[m6vU, `ҥ(//gVXn:ei.)(ڵkLoT ÊkxGrJ3=Q2}H/bNO?4\.K~œAe)~2Ҥ:\u&Qk׮3&2wvvgy\$`cʕ+w:T j3?:׭[n[6Ajcr+ WUUUS[BndZb֬Y SЅNNNТD6C7օpӂuP2d2zKfI.2(ns=ŋY!B?ɲg+8]nI‘6 +VP&Nˣ֮]<7P=_j*d<,E-#nJh>z{ܤ .jx<=F/7&lD9kӧO7xu O Ѣb 8oݺUŊ qM(^xC!*VU&s$k.1X 8WzD"fi& 80Fl޼VI\.fn*7u![^z%.̾1Qq%R)&EMfZVVOӴ{Xw;7|mL rb \ k,+=Y+Q1::Z66oތ 3[7n@ P!tuu1 9tCCCXd l9E0mz饗\A`0W20bqxꩧTD7_7>?/jhkkSvvvXvk `l$ }}} WN7nỈ-vZ omD"|>3ZBEEM9V0^z>j<b5H$75kZnJK{j||xɔT&Y G_`xhlDScբE}HC-DOtƇ?a?~ ;m<_^/jjj ٬,vd K/t߀Nu'2z-ųC #4hLqrv|#KEEA祥X|9{|c&-X | W@v;U'SnU1'?ABnGE6n܈^x$)F$e2?V"t7glCtozې]s҃.]ɫ淐D".xQRRZ]rsŋEmCfcl6,_' |=w"|~r Ȳ{mnU7'|.n̄zyqAېeX$M8zT_~`9`6-C]@GGzzzTz&4xq[6YjkkCmm-}s$'T\nICX<\颖)F]UHt%izBgg'VXwymF0<Kwy ukzȎRo[q^M$.:>L~pi|~x7!bQI^^; cҥc.sQܧǾxD z\,㮀z{o!d:Y "c˲2ZJO$}h4IǩΜ9NՂUУfy6l^T*߯ʶ.&Mt#hy,sҥK\&&&PQQU###xA$ v=***o#o= }Ǐ/ۍUU&466_?|I˝тpJR  WkYr%9 z3իW8jjjT^Q[[ ө~9" M>N4m#.|ٳx'Tjʴm`,>jK$էhmm6!$oV^tuu E^UUUx/Fn,E[.'ܨ˲}>d^?AUiBb01fջ EQu9T*@ ZəA倥 gVsF{tPHm "'F ]zC?1>>nsfQ-XpMCdz ---# _d,>sTWW\6eYTB_4~?Tۧ0XUy{bX,DtN!sinnFIIICDDDPQQ1Ϩ=f*4XYΞ=8=#|.)˲2v pK~ ;o{||L&@ `V;wS˲t_(B&QA㢛/!luvvjX >jYF sιAw^`PfasOefݥƥՃrŋkB$M=T*`08s9Rk;re(* !/=F`ٰd\zUmߏzUrWn.. *G6 Qi;Wk$I^}Yfdſ3!D}, ;amm-l6MM4E,CYY.3!`;w.,gllL׮I͚ip;!lyg G$[&&&tsΕ?EF NW+P(Ys`Rb 6 /QSS:PT .妷t#m~VFhkdOkzp8̀Nxz^Z>}'I|>jg-2MQ-XΝZlFdT9mEQ':r͜(A !z:Ib)4554'?c)^OhM4111gk]x@@ӛ߸KoVKa544? q~tE,A,=(YUWoU[[EбMTYY@w {<&u:V^-zϠx lR~ .Xz5iyM]~fU&ģnfEiFviKQ{|!I$aχnGuэh-󩭭-xBA66[^B6@ɛ XL& 5ZB#`ق5,O6׋e˖Y !s$?K(ح Z]-6o} E0s4 o.d6t\3bd2$ v]i< :1K`R$I6QUUź b2zR>x<^t +D"L&uY\ ^Iڨbҥ=xBԣjkյ5%IVn?SYr-Xz5` Q7bdI{VG_,ׂT,y^ X c1r _N:e?zo,=Qy^tuu6 ٭s \DOt݃̀5ȍ.^XT鴡/TMHv|m 3zetZ%sP_9@Ktـud2n_MH dž LRRW'_a!C6CG[['Ku5<>κ , ,ASSl6R!*c=odd$.C5Z,#`Ido||MMMK!gԛ11Q166<bsG$Xp%pUǰh6Q? Q| !Z]c "j ϵ;p,sŰdkR&4:a9eD:|@#UR7xCu5zc1 @(=MLLh-E}7l5L,˪+a])P0 FBk4We ݄vX{0Soրd[YAљ7D#6߯Rk,/zݻDQ|'-]]$U(" .?6=ZXh?FdLj u``wy'2TC7rBȭn.x^qFC齫{{yna fk6x͋EA艎7d2d]߻O˄(`gxx555p\K! :, 1*]ڣ,=NI,q$ Xt)R !f fz.瞴/d6w%lXdwZ;0z& "SMjeÁ 79AvVN葚Lxh!h0!3 L.CW(tj((a]eWӥi .J_ N^xKӝB#jkkQVV>DIU,h]Z VN?VX Bta|>DQe0`aEB ֥pnS&ȈeոvYw7 Xj566jHBG_a+uafcG{O^j/I088N]icB8BX,˚_'3}o\pccchlld] E.nElVs}t:W={ [ʻv+[PYYɺB F簾x}K>Kw hy<|:q9At aetJJL/!0h%kW8%3 ]Gi A0IBE;Y QnNd] />f4+lFq$I U}, addu\44 z po?V599 ۍ:K'l3DOF92 S^}XIBk,=zsq(JKKu]J.#^y``@i6z@uzAF-tEe !:1G$ H]3_\y#{I˴`vR}Xfz///K7fBH!r-Wj+Srexd.B8ZQ,BKK˼Ud١߽zrוx<κar XԷ'I044Vݦ~U1 } ?bK1$=za,t,3Ìr(--e]!2uPeR*^ˈeu4%u9Fs˅H$!z'-LM4jz~Z|vJmъ8Ւr~LB dYT"QRu`l6?X$ij өBUꨅ{mY]Z~O4äch@MԠś+x:PH J!"6C!W!FϳU{UZuԩǮךs51wַ9wd d]'&4 X"^8"n[6Vi~loo.3x>M~ch)V|h d{ Z--._0`٪0_8cVmdYiAnnI[5AoxOBԔ_s뇼^c}}E4L,[6eW!IjlszdNB=(*jRD-:OykFEnl0 |>G"2 CX3=l6\.7V_n5z=E[Irdvp톥lP6_ dW#8#^b5r42 N 4 0\Id);mF }ke@Af5"íJZl"+PVۊ2~h18`0z1d·.VWWJJdC{hvbnWv)fƩ`0Kn,-Eh 4LSi6&r'.QTdAL<ݸZh X"A(R5IrYæiq܆x =v(JN X:-6*Z>fL&SDpOީZ r+Z[ˀ`Cb!ˆjz֨UZ,r#x*R=T > V!aFwl^H$T*0b|ZbggGSTvoo5yu"R]&8Oll6QTxKTKQQ׀[몼: ^p\I *$WG$RM;Lu X?p_ԒH#RՐJ|m_;;;jJ3 C9O~FCRHBg""^vFH&:mJJSy ^c{{{JZOc8 BB"׬_XWIu,wh4H$bm:* :Rl{ݮuN)½e5)TZ? BjKTlooV!LrY]^;;;ܘ#&8uhu, çR'~rP(D"SC 4 Pg15i;GR a  j9z^LZhZhZBbQ$/~ZzD`i<@H||zIJV @,!FAVl= ><~![jW#XpHt{{A)xTA\G4E$Q3 ^8nw/X-37yFY X=P駟QHF'EpnۨVb ZDmuGIF#X[=Pk`R;C*:"(gcbj^{j GlwmoV$@i:FvoÈFBz`7XKĈi:z XZèj d~B" zZyɩ ,|>@0g"O8Ҁ r6C49EXUfS4 ȝ7ID"6Vr4F upiH%KT>::~^ⅈ6 t= 4ɹ#X4-C X./bqvVVBBZ, O:cJ,qփ>xgȪd898 l?ewjh0Ms/lyuK;/&njx' Dq4Z[>mUſ sݤS9~1-jx)v=J z5ՃpXzKEX,&$0`iuݽ~?gGdHUAӱ%itJ ;यQӐ,-?5jo6R [znMnNv˽jAVBM0G .U{yWC`078~oʮQ*\纥َ#`]Ps~?4NV84]Խ^^fsotzbQNQ*r\(;78y :W0;掀}gUńyDQG|>Is:QVz{SCQ<YK<fW<wISxh4rq"*ɟHdktb^|{rF?BոkS2"+.!639Sh:*`fְ,#YѓZk2MS $``["9tx[9ePuhf:nK PHȆ̆a p_tQUCWp{ɸMX#:J4Ύa/b&6e1MЇaa~~/D|rӃNW5N3}E 'a/^͚H!vLOuÂ~t'GW/ X|Jq %9SZ8FI^֚E/vBaAǃ&G܂Av<"8b:8EhBS"vD" XD E>]me݃G?|>x_\4ox<.dQ^v⅏F XX;(0&+kOb0Lmfo#׾WˉTc;CaFVAV Yҍv@W 'u},w2 v@auCZaݶ:jxPHȱ߿}'IJXs՜&tY1M Uuο_8F X_ӓxe b1׭E$B'QOcx<.\ہzG XژdӾܸ(yfDidYQӃC<`ן{%󶔤8ߏx<>viNXh>T>O݃-ϰt}]?FQ}  Lzp "91zuuP ifoԀYhLrN$ Xԇ DjJR#$KM?;'1Mx\H hێn c B 0b&)`w}7{g<0QI."rd)HX, 9 C> IDAT^ >/<{}G'Q6b(JzWiH&Be-7gNN" c4C%}I8cӃO XPdR4+?5!H'My*Yh$#s};^$|>lB^}Ad BD"Bew~{"},$ X^e86lv'r/Y1dN+yz8e:{A2%`Blv'":!rz8e:Uwڽ{s*8om|cV)ADDjK&5tM:N>Fv,`\+J KR53dK"W&9s:DZ17`_Z"V @$Ar9׹V<vT*ft"":ar®>Ov`38aqލ @:FTrX,-z!y "U~P]8_8=Sg|ܡ\&4Kf e2Ml7$#PO u (% evŽLC$9vMH{b/$`}NN,4H$mCDzauS!6J ta˾s=e* EU;6<)t4.͠qswX&M O UfM!dzwvv+8AD^JcOOh 5ʋ6NZ24'z$0 GF:gzÕϹ-L$D{'dqχT*#?C2DR9&diL&#qTU!3MdvDDt7l6+t4) 042铌}5y(=u[E $X>O5GS6+>6=kD"D"4 !dz;Mp/4'0ڹ7 !& XP\# X=7Y1d)>tϳmr˗/7o| $# nGQ7Z8HDYbsޫ@ ¢˗/2jbgc0`;O6?ݮcfY,// bBnak5zu@ c[˗7o~|^7q~,": K8~H:G>qwoN,4 X1T*5xf2TUnCD"m χ\.7׎| Dg\qyw\{S[雒SQqW0.=`}nL&t mҷADP(L&#iN~f[9uV̸Cn;d<]Dhj;0*p Xw} 45$R8} ‰gw4[\M)>8fҟəhG&M̌G2~\5h._Y&/^2kPE4ڐX(I#{-:;@Db1቞C~7cH]|o 6:yGqԛsu" X}W2nHBm TR{,W\wulbyyTvُe?cD|>?6hvbc-ŋ"T XsMZT<&vvvh\*HOTj%<>pŋ˲ QŋW\y/7ɮELFfSszb0.KmB W{ Pd \21ٵbqq~_VWW<""E",,, e-5/^.@W\:TQV.ur cyyYV>DD* 8{ԻsѨ+?\pdaQ-`\ vZdv"mTTz/~?Ν;'u(JmW .\(.ĢTW"ˮC~ӆN%iӕ-sNٳBwazzJK .H(*\]*&VVVN090j D$ߧ0M D"?$B%nw}.\h.d?\z_cuRT*I^cmm'o"ҎaC,v}XN7R)~(.\/8HoԟˮC%T7Ӣ(dF<wtD"; Pd#@(C>GFӑVC"@ߗ63"P( JIOG1 JRrr u`yyYzyTBRZ9GHLSSSRk0MSSS\N]pu8k 7p}jc:=DSK@22li?w@pXT0J,z:T3o$kFaek\,JaIE)!`<IG *`eZJKD4p83gH_g* P(HAQfD . ܐyg,BAaA0/ baaAz|\h?z\0evڧHviZ-ud# W@@jaP([-e>s.bn XZ [.>z=r<-HL8‚͛98p.d Xpڵ?dסr#^Դ߉h2EX sssҧ~?#Q-`%| ZTIJ JBDtd2i%zGc22T.dT)~c_/Ur9ae0 LMMb"RZ&̌*3\n WF,׮]WȮCE~hոBMes{ 2[ %(GΝE[S}^OjO;;;d GE0 ʌ|>LMMIoWXΝSv2`_PU= -zkkk߿ibnnXLv)nS^Bq>w܇d1,~pz24 .Dl6L#"}|>+ѧjJգO;w{d1.O$"TD] +aK_}qL&Q0ƻGo;PYR9v*Ոoq{dήv\j$o:wܻd1 /,|ZTV.QTdǺ۱l.r%`nnNd2d2) 5Gϝ;~,~C;Q*2"kkkK!/'eήWx'rb(DNڹW|>ܔ B!ywٳk ,q`G j7l6v!cffF)Aꔶ<|Eم+j?upk/,WXXX@4] )$ٳJp8pu:b<:eq ebQާrRi"\.rHljt8{쿑]S.pZܢX,N8ex;/wRyJ.Šb/¾ bf nܸm@W*]tx!sb1LOO+wZ={e$,q[MvnuEsʐ[{/>%Dߜ[Ϝ9벋p.%*JJE~Ny5% 8d2T*% ̙3=م8M7o<Q.eqqh"FJO @:F"]T̙3e"6 n޼r$VB dL)Ck"RafJO t:x<.7zř3g](Z,yAvnl6~t 튜^l8rez6e^155`PݭdMD.SzRa>se!Sv-nc^l_0+JDt<'VhQP( .ōw9sFYܼysɮmz666tdrn f),P(W{@ BtO–̙3k Mˀ7o|; VTGXtT\Z&z=߰B>|}Lp\ɝ/.Dmܼy:ܪT*)Q@xܺ^:DJ$,x\{Uk!酅ʬE&ܼyZvnJ"4 Em٥hK΂ [JL&ef\XXײ0iN&oK$R`kkӆY*}>٬Mkh4*7 ~XxNcjۮu(JVbDa L"ͺb:R.P.D6]/$w wK&6$Q4E>wՒlfE-,,|Zv!*`gqq:ܮ\.zh:677_~He@|ukܰ6vEkEDv-nh4\`0{-SNyN! L?4MdY4+~xaa'] X,..0\ukqNbQ~]p5MtTuSk@\UӘ 2\XXP8 8+ (h4K9~JJ EiHR VD\5ڦŠBTÀu|B2/30[IH${gȚ6oFv!*b:7joV R ݮ;z(\ځc-d\|>rBR Fv!b:k_v^e.*.94ͽ;Tߐ8hLƕә {㲋P~/ɮKj\fJ]^~V1n%a .k>??˲P #kn뉽**-`0T*x<ޤ`0\.7E}+N5ٵx5FJSh4T*ɤk>tx|Kv!nu KKKY_pYv-^jP,=3nQTPVb"xEtlnn q+ -//( {?*b0`gg[4 j5j5}Hb&bbʬzV?]1``yyxu]J%4M٥8j0lZ^3lѡLD4E<G8|f\y&bKv:V(Z`FzdPeTy=Ts:F<].877nExˮC^JZM`0@B^Gl_.  " it`,C*r.ߐ]W0`lyy~QvhnnFFf-2MpHHD)P(L&&v177=wmĀwu^\..E kt \\]^i ߏt:h4*ݼgnn ,,//ٵd0`{{;;;ڏ}Z-4MZ-Z-mRUbIDATgBB0B'ר: 4H$L& ='xCMGdע^rZ&e j\w{|T02DoaczD,-//| YRXY.;\ABFAb|BRR0D&=.ճB,BI:* A׻-pYyva셨0' HR쳒qȕXYY10\#1hjiw<G`x,/cheeK8(VRh{ǡ^زBXC3 i4M|VxvHRbK!\A,VVV"*a 6ga8 Q֟~?$W`W[fgg@ X{J7 &wK*hMF0,IVVV^ i j5hb VYn,D+++? Caz;;;ZnCtZPDx.DW X?Mjz.#0'D"H&\JMmBtƀq0"k;u]looV)s' a !Lj K4̟.Dw XX]]}'eB^kD"0ն gff$bR% eٵ*ͦrD8mog333. !:YEZEZyitxLIv!t VWWC>n*zZZht,Em \VZrRRC<G,h;[fffx!WVWW_w\hVhDRaD"bDxKu 1`1ZhZh2Vتjh6 [*2Ty |zzم\dmmmBٵ=>0 ?Y)_+ 0`Z xZ^Vj4h6l|>aD"*.FǀBkkk_6OvY$_+Ǭ=ᢤsk!u mmt:ܠYi"  } \Zp/.ÀAkkk> ;eBjvvn+lKA#/ljjjMv!d/,Z__x'7Ȯe0zN5 V^ $̻yjj{ǭHɮa:kMӄiw&?955B9 XX__?Xv-^~_~?04M|uدdN}MMM]]9K> WQ\㰰?LDxf׿ %""M| +Zv!$[] >+pKc/>ٵyMMMBH,ͭ/""Q)ރP(,.a" m6;RNDr; ;+!0`ўb}k!"rXPBH lr='G:rܠ9+ڏ#XtɮHQ ൅Biمz8E=a< Mj!"RI s Wt`щ666c%BD$ۧdP&RlccU~@Nv-DDlPBT666+dBD$xCPX]eccZ܀k"*r,foi>٥?|>#r',~dBD4xS>Vv!n Xd[] )}?]y"잘%CD4m Y2\8Eܜp׀A8yHc"Gmnn=Ȯhןxc>[مw1`o "U?BH!"}x-ŐHM@Lr9t.IQf.+.€E)’!"hbĿrl`')Hb8rȽ\.,)X,V_n5D"]m\Z0`EDt\.wEv1D1`=~J>\.w!: )X,>/t0X#=#0`k3ހa3|Rr9D$6r7eC4 ,rb:?r97r7'Wa"*~/s\)zW'lWv1D`"O(JD3wf.hR X)R ;|%rd- Zl6b€ET*fX\i~7ͮ.n XiRɇO2D2u| ;f=9Q*f8Z%C+V} ͮ.H,NT2|7Z/7&rB'0l6ņ€EZ+JyZJ. >f7eC$ ѮRj0rܤcf] (J _1Ա(&XÆ'|*4$C,clmmaHo-Ob$$C,,mmm% a`s< Of2 H4,1lmm1)yKa>dʒ!r, mmm[6ȓ;|'|<%Cj XD6 N }r+":sT= /2L[r=DE䠭s @\nE*TOx2\\g1` ;܊Hx PyRE$Y wvr+"79f %_YOŠ"= XD(0 Z!ԢHu}t~D `"RT\Nx?P] _a7LR:TD b"rrp+p# R"-K TN{rK"Q0`X\xDH0{Wt$*"ǔeEp%[/D~Ny2&,"MKC<<h{Ϛ38l6s?IENDB`jamulus-3.9.1+dfsg/src/res/CLEDGreenBig.png0000644000175000017500000001624514340334543017364 0ustar vimervimerPNG  IHDRH-zTXtRaw profile type exifxڭirvc^a9#/_IIsX5gs翏/콉r-6Pyw6~ ϡ{xq9~]P{||?n|S}zoxvb0. o-c?.%9&s׳ҹ>0Ђ#RȤJCgŘ+1SHѤr*z9s.YK(K)kkڛoK-bZmC;\9GqGu'3L32l/"W^ŬmBiǝvev? 't)v^~{&{^5q '8I"^>96OR$\s`Χ>}s777sF{=/ elj8ak'}_QάkuҚAB yl|Z+ӯs~oN[b(ufwxy?-게ty⸏>s윎qQ5x|~o3v=W|uj#(ss3P kXje;{0qNeAZ2{) ٗQ*p$/5C1%l6c]c/ ١mGn1]{v{aã!rQ|)AvuO᯺5DDorEbD1 fb.Ij}>#u8CsLLsFso_i,.0!Ax[p6ܖ[fҪKsUkE:xp`Xל 6m+B#duLL XfΩua~'9oJqeC(WXcr1I{!3+fCҤ 5I,)/Iw;kabN L?@rO3:äP=[]q4a1@pň^F ݸ\>Il!vk&8YvV̄k<2+s BZhe~qE !VN!v"0)#2 @-&gv,<]"`) z04yPw5tѺ]U.p6gκP YV (doϜoG]s=#o=zx1G!D֩xP l1l;kr<N@I~mrc3:@,aL MaF<>ʑ ';1cMkTAFB}ݳ䟁)簫Mh`X> M$p~26X8+s]-L/@*8Iq3cQ"oQ,'`ACa4d͝.&Z']%3!cUi S8B1žlKqdD؆Vu=B$lK͖Gi\DZ+ACk4Y; tL{X)n`EX_Y) Dj,H Hz4i01}4]9C `ҵBm{yE2l4;=*)wLzt| Q!jzpѡn=b㱃1VD3Cp^L̕8r]wiAzhaѸ ʆkWb bQ+en[hR=/2[_QS"5䆘6~:ppP1ANo*>` ' dFM31H+vR`HO;1ӼJj K*H<(M4$슩d1Q*""||0:XFhdlq`rIɉp0*DȔ%ڄp;W5; u58BX6=5)G]y61Yp'K2-NMHr%kցIk9PCׄd jSP(#+ݔR,`O@UFhTB={J NɓF'{%ɴ:6esf/C&] n㠏71 hC5\QA0xJ NuczB*;(1.*/]I.h.B@ }=gXc^&q8ZJviYeB.~Mv\LlQb7=_<38;1o3TWhc͸ǧKgq?JqDWr:P'X,H=@N&UM"m7!iI'PP])`dޝԏv ₲*j_( rIŨD0a]au}MPغ'8G8>yz$ m=P& qb2[آaFDpCF3HbfP|}\>_ep@uk2^#Qn36rSoQ[u^+4+P)-B DtL4$a (Sgہfֱ:QICBXgB%UES-:TSт:&$w$isap(trdJ E WyI$p+Y_ձ$C~Wg݊  *Ѿęp]DvH ym`Fԩ#<hT3VRcCȝ|Gc@\RU/ a.^(U BڷB`y™@F ‰+YPL8ݡs4r튞$E1t ! ? jCdZVq@w+  {AdxTZ|>>i%ʽtޡr\(EfZR:~+r=㑾??(CW ZpZ# ,t6Wt@)EOT+~G5 cxNrV'} 㻻5`bLm$7U&SF5;,nZ\-=< $du9IM-gZD~3"Qq/?:;a?P eS6C0d -3pQy|V;A 4z7@G[?nUy+YQc\OcMiXK/'z3P,>k읔 Ww&x"T.|#PNXHByQT7 zKsz0X ǽS:uz;LBmiYj%vHD. 0*]UmؓYH:Տ%PՏ|OxZ!G)`ycH`i-$brS]W(/SI3J |*IP0Pg@O {>@z|Bg?*EhRS"!}kMp%"PW ci5 wՉ }>Ѐ[TA::ܸހ.ZJX"h݅IܠVg=ɨAki_b$>A-iۀܝVuc-Dmb'\*ia+GG=iU%ߚO7G2_Z6DO ^%GG&/IHd>w&1sހZkN@NlM"jGhy]R#RY/]jpKZ?A84EEnD5W9kMrg3.Gp0LT\\쵸m%UaT{]snjR%d1 ha KŒ ɥ 7 |ݼ:u7\dy)p], GXZY VۡF ֡> 2l~Vþ+ԿAE'nxvӢ2dQk[$͒ p wاB]/; C.So>*զGZύFϭNFyul&׻Z|=_ȭAp= _T%n %Y\a),@=\ԷKxx1!` j2޿Jh^0ڧE/m {%vIG6* c/r8r ؀ M5JNoGu'J7Կ? Èt'ʇ{R PV]](nwBk(X5}J)Pc$x]hͪ[&S+4QT@t!uOB&J1N޴S>QMZ|@ o c˷>jԻЈۤMR'8R`TK6-)p&ଇBSs:@Z.SE"fN 5׊W+lRɧn9uG[d8er$pïG6>:r ezKB8Chfk`w}w]ame.HPi0jHR8=wd G%Z@$T'2tԞ9ȥW$eZ3(;5$0 AA/CT1ʆm;i9DZyw!DBN8#i;HR ^%摎jQRZNK3mNnĄ-y]e`?[/s~lHQqi I5>ǵrN̨ d1J$VPIu:27dZK;b~V2*dGJ] 8L0lMV׵½脭*5# sW\07l$|GC tHHvf) (Žgj-jҤ9.SB=tjBv $7,_;Ekm y *>"|e [AЖ%`&A{E9ӽrv#z^#(Csh*ƨn\N .pb 8mP!(F0aKKI"QG7U}}Խœ؎ԗ7QMQ_lPYxosFCIV6KSބk GaNچ|7*q$sAPQ+L$)6(~*ʙX3EV&? gS+y%ӎpI MY2zG d!4(/YA$^9U=V$1w57hg]b ϸ)8mQ;0NZ݅$ZK{^ZUͧ`c|O~V{3Ԇ$6`Aot|Vq<+jՊJ&m#M *cV+Gz63R_y6;-h.[Zq^U&/䌭c_xtr!;:1J~5㸛N,` U %LJ?ٽtaJ\oO˸D.N}&BAg>_=sw;#eSNo }m8J5ڥbKGD pHYs~uɍtIME:3}ǽIDAT(]MKQ{ܙLk3nЮ,[A+ Ku~?ڵqFEJ bZZB7Mih03 cx8WqϚf("5aj*Qunkm[4M^~yA1&QJ///7F{{{UvNDqr^ΗAPae?npLXLcL ȟ'>g-,#E!hȈcTJ1Xk N'Ny#t,OSNAik팈p4y1 {qhk-B\qQ%p]k-Z}  eL cP(Z'">55xUN*jJ"0r]IENDB`jamulus-3.9.1+dfsg/src/res/HLEDBlack.png0000644000175000017500000000061214340334543016712 0ustar vimervimerPNG  IHDRvbKGD pHYs B(xtIME 7"WAIDAT(ϕѱJPwohDn еB tp#j_]p :HԮM[{SELyvc&K وȳ~6h4VU5_Vj}6Ms8ߣ(VZIY~8bZ1c "nc^7,K%#I,{Akn s4M v8b__PJ A< @Qڇ.꺎D9q7p0"i"6 ::~~~3ww( 0%msH"!a`dkBBB.++0%o,#*%5p$IUD<^VVH0yN2{:F"sqvQm;ý)r}|V54n{DEX\9=DJ3'}(+Tn܄%S,TοGBjTT$1|sγ.A0m{ɡ]] Bg %glJz,9yBjՅf9 (UK._$w+pJ 0cEE `ܵkףL׎uІG/KQ H ɝI/,,8&l[PV>ng=*}ɦYHZx]f$=F<V/A[uu5VJʄq;i9t)-rm' XlS"///푢atUp=}o>'}/7ѣG $ŕPUqhl) z{{7crssݻw/.]$긪A@tFd5q;[^^PS̯"vRIgzvږ OmUSScWHp“=vH&ً5 Ea,Uw׽Q>8ִ9#]z"ևm?Uk& `dv${\|DQTӉT"HWi3ܳ_cIENDB`jamulus-3.9.1+dfsg/src/res/CLEDYellowSrc.png0000644000175000017500000012237214340334543017624 0ustar vimervimerPNG  IHDRXXfsBIT|d pHYs~uɍtEXtSoftwarewww.inkscape.org< IDATxwt}lG[^ M[ÎIVc;'.y$ǎ_NDZر]$ERdY]b@T `m~,Hٙ޹s:Bav (*> x.[.|]^,mmmr@BB%r`4\*2ʴEa 6taE5 !2,!Ӣ|-RSmM260!=H"Gˁs_N*UWYVux xxmFa]BH"j%n41$2ui%Dv%Dkoo/XK$m xKCmmm#JBL [% < <3U["v?w]HT~;빶 % !#Khooo0u}gJ,$FqBW[[[ڒ KeۛCUڊD!u)G$K{ ărp8kkk )G K]0<H$u@.' a XBhݼnP[ z<-[BGiox+'2֭=NoQH"%vÀKmEB*<6!2,!47.Vj-Q[[{d-!#K[ WmEB(5KmmmS¶$` q<`P S[4'(G[%ĜG6ɘځikk;!@i+.Gl&wچT#*Dioo׈OO;-iB ;vF X"gܹ0Uq9BoرOu1BXAj;wte*!ԉ/;vD#i$`sV5(.GqnZcǎ~a4 X"ܹs9IȘUBdY?ر5a X"+ܹA/J/r!2fǎO.FtIkΝ.⃁~ Eq9B*;vDT#D*$`sN?ǀF!s;;v9EF%2Ν;#Я!,cM۷o?!!Kޮ]Vޏ D.?}WU#B$` ڵku_V!l$FRrZ$l۶mBD摀%2ww7_U]BX俀݆"Dv[׀rյa& Uc֭[$`kڳgO Zť!juՅ{%jϞ=cZ52)B7|[T#Iמ={V ܩ!ݺu+ #K\bϞ=^7V\B]2[nU] X={ |Au-Ba~c֭/.D؃,qէQ\BdyXFf X9nϞ= wT"Y)෶nڭCuB={x WBaM4M^޻wT#ԑgϞBEC¶ |l˖-ՅkI1{O`Z"G>e˖.DXGVػw Kq9B$LubUp8Nd/mٲ%a> X9`޽ć_Wu-"N4%Dtr2uN'. ˵% ~c˖- 撀Edp8,P%_N|rx _=W\l2a, XYf޽ukŘ$L`fr8]K\xߖ-[S]0,w?Lw"SSSV)4< (,,Kݍҹ6B'6o Ɛ Z!tKD^%.I7oT]H o߾Eq)B333LNN^T&.B***"//OuIZ6oܡ: Xl߾}kekFLNN211pXuIBnߏ裡ө$a6oBDj$`e}iGe+d5==LMMI*/PTT'??_uI<1ρ/m޼YFVٷo_QٷE+^h~"!.B֭ ͛7O.D$NVٷo_-Uu-X1ƘV*MPRR"Ad͛7oS]H o߾~Iu-"=X JƢfp8Vqqlڼy &+۷o CkbLLL0::*JX|*--Kl6o|Xu!baln߾}!>ƕEJt]grr%T [p8SVVq2SM6}Ku!$`5ுϪE$' 1<<А lvSQQAyy̛|~ӦMr"! X6~/mT": 111!XZ2oڴIo X62ާqm 3<<,U"+n)//.G$}ӦM# e#_ < ,S]:]chhIa"***())V-{ظiӦS qlb=@Z"CCC Jk)nJ***p~nڴ9Յ XuN@ftYΝ; (rᠼ*|h_3M6R]Hw-<6355cccKV4Mj T#~uӦM;U$`)_qe+ccc 05%~ q-TUUQRRqM6}_u!J"(π lXaΝ;,D|>UUUH~oƍ\$K[r䮟ku!IvSSSCEEAxƍP]HeG}sGh 0}}}B!+33=33pD^w-ENbQWkPP(P8oy#>ſ 22y<jjj(//e߸qTK$`YG"u2]O.!?1|I|B|ELO0=]Lk(=7 8Z$h7keG}T|Lu-| K(`¡ !|Πx/wW PA`]W(륮Rե亿>qF9L}QM#kUccc233z P_OQ NGDuidbj&&a6RGmmuַݸq g" X&zG]wI={iեRa0g).笠h76;[\ftT9)Y4668Z7ʧ'H2\peP(DOO##2y-JIq/ee]vQVօ#|Ya6Th## 61>^GLw.6ʨv.% i2,䲠b6nwx*/뢤Shx=ã͌412D8w6:1ar緀G6l a`29+KݝC.hZ.+OR]ub?o8a:(/5\RFFlсJX>ihh0|\u!FZ vBtuu^ߡq+ORUySY{7_D -f`p)2,V]劊hhh ??_u)K6l! $@AD-DfhhHu)q8uR]yS]d*-cxX,{o]Wyy9\r"߰a Fj X9plj_&ٳDLGʓ׾Jm9Ji.t=J._D \Oo -m2ϐ餾 ) 6ȴ:e|XWr LNN.T-Jei^ *ǡ9p8|ZÇÑ} t]%A׃b >3 !3hpHHdL lᰏKLT9Daa!x^e5 6i:@nJחwjZ3PU:Ep*.(_qQY{ {{K$o5 뿑 /J|&ϥiTWWgT( L&+ 4SSStttd(%Ž47H]kwnwQh- CW\ 2|p[uyW ۿݷ36^S$+Æ ;U$`=@ne,a``@u)s4ԿLK TQ/o9> y+Y4.$c6W_%8*P.D8}cmUUUQWW'cg'lݰa!Յd" X)8pj Ou-h||άӪ榟S_A?N?>r|sA[r_av&BNTF파6+hxhjj.'[_9Յd XI:pby@ni1X4aե㙦%Z^p;)ߊ@Q”bW0*3]JٞUg*Ueee466t 7kTI$`%es2յd@ ӧ⅜?1dѳռapUOA{Khd1G #vXIo N kj1"}6z2k$`%^0pZۋN :Օ'Xz3tUMAѻ)(|pʥ25yQff~ u|hSge`p)Ɏ6c4MՖk֯_ٟ-"+Ԁ~Mu-dvvӧO+ƨe>CQk~MߦV,:T8SLM>M$bͨ*Nޛu%4|傂ZZZx>$%<\" zi#/g:TǽD2p咡1w[R؈g@@`KsLiiR2/׭[Yw8L֡C|Hu/cƷ,?M+6_`~=U Y;r=)ԋFwFXtҐuNx >RSSLu"TuС?AuHu:;;T] '`{7%ȿۀ urؗX461=[qrm–apݺuUr6`:th5pȬ[l r)MݎWY@.h Ie]Dogd蛄Cg}ߙ _iL&,ZH%MMڵϩ.D X&>0ZZ2iB!~mffhy nZ^WA}T|73.ma]16 Xc ^ǫo1l"ixb<<^ֵk.j9{1nյdi~ma3ҢqurwGBeg((zʄ C_e|t/F"^<;^s,Y<_ڴ֮]Q]r1`}:28'OEi/e^¸QHyRR!nAg^a X::˯mc2fD8N-ZW]J&ڵk?+Tz>:2͹sT]Ƃ> =Ñ>%;NWa &0x+D]Ŝu!NխYWi TT1"v.*9{f/ی݇axf]TWHk=yPYy3PiFз.C+5+m3 =tK5k׮'vDzǜWq)^c'5RyYN/y\j*?MQV+"wE= |ɉCi'/Ѧk>jjkk YW9NBc \w3HJJWWmÕi,[ ?b IDATMܢi>*%$\ a چ?Oy7;дj ,=q/sr{N@fLPGGD9y=zN*OPUpS^"z24𕴆u^KPs~@LaS#=k֬B̔+$>'յd]9s Æ7ryY'ҎϛGeQ\$H?af oUב t]ɓ&x" Ot纥GдW_ j꿂ӒbBѹNF}Ny7n SRRBKK}{͚5dm:|V]G&bUwp몝ɶ i/˿)cAhW"+3FQQ3 ܴf Xv25\Ԥi:˖cْS$/AUg+<@FR'N%C YIy xx͚5*$ Wפ:NbrrV pGqhzҷx%5|/p0qbaEy|)4βOqmtKwj "p$?wgj:|sLyjllLu),?mvv;w~=T}˾s e,/ͤP!/pk5Cfqqt|OLXf͚' XյӧQ]%_zeKtIPӼTT}IۑLug^Iqy񠴴fed7ݐ\K6Mo~ Wipbr^M.w u w !.fETxil>_b|I?_t->Ja(/]ǝã8=OUbh:|J;;{,vo$3̝`孠qdV{!2ZżFczAm?pj͘6wwuZn7{<Ӭ㇔VSaZ뾄52!]LSb)=lAB|+K]MML}m?V?}Wa6E1$\-6J4'RRқҝCP5 WBdw=\ꔞ_RwyyVWlN-X?x * ] n#EE|'inj2("!z!Sz~pL ,uTTHL+~Յ*[ WW5>>NgggOtDw}7ptS,WnĮ\[Dq*hh.E|ww~.+K]wwwR3h-X?oQ]]MOOo^9[kU;q:#I?ip{6g!2s_ct)=?u9{ut:Yt)yyyK=U]D*22`=U@Z( oU@S/YєƸ˿,62!D&1_Zt]׶pg %ne˖vMW1 S]H27p5h4ʉ'l.~[nڟRo(.yuYs5M{XzRV9uԼW?Cuȸ|3Wuvɛ`升imYJ-\"B=D©%}.^{s݂1Kw~rh>oC[z}HFFյQGGCCC˘}/ uS^ J઄(CD"]A_KlGӻcD0*//1dnƇz(ɨK}AӴDasiErBuǏh=*@•"anwuM™u5rǭ? ]0<<,cd]]E$#cZx/{L.e#Ü>t3Fxf⣳ҲߡW%ٓthJ͔ͨ.Î=k ID&`-055ř3gTA^JUIoHB]B]ӿp1;Mo\I;{,өMij@FȈOl֨n"'ODu+3w#)=_>*઄.~w0smVnbD"ɏe۳}z'r3?~qq:u Tڦ: lKUa7===Jc4 CvRbBzjDa$_=#.qFb՘H@ @i5dddжOT'Zdtt'Odm^RkXP _AnuBLO?G_ٔ۷^I|SưjiiX\vok$\]" &ݩ=[y܊*OQ]e WBS篦84wJӂ׾=fP bvvVp@6[itض'XCe(o333@򟖌:,i};s虜Cl\%O2')]扇8qU%l29%^$4뚦9lmttt /{bƆW#)uu{[+! )?OPK+J^0Ki 6ez' Guvؘ))QUX +pXZB~BF.=6%n8aFi 9v9R=svl|I/uI Gi =~nR/x\B$^|Sz5M疛)-K155\v,DQN>t,a) SR! 6*!HCQSU”98]anUu:;;FSObOQ]tvv*L47;=СϿ~!HUOYnw;o>q0j[l3s6l?TaÌ6 yɔrPU%췛 !rYA)-h&v )Mmb,UDu:#(+Myk7,O! 󿘞z655ӟhuǘy3Qg7]]N;5-53gdi1n_^RꨀFE՟ݘ]B z,)-ᖛwps5X YlтOZbNۛ]fԴ45mTT}DfRlZfgߢ)O{3/SSSCMMLX.-X}V4nUVϧW̥2.:*?:~E_jL  j멧jQ]An_vTNg9յ_Aí|!rꀗK _Y1׶lJ&X Wxd.[(<`g]]]ʆdxfm^4-:U啟n^;iZ {ڒz/Hm#B)멧j~[e v1>>z~|@/‡ H!i^*?Vc7+\WEFGGP7>\PFu _W5Gb1:;;mP]C^ÑOBd(,|ʊ3,^܂1oOOXjSe񌡌SO]|PG٥nXv85PقSmajjJ ߲=OkRKMAB*]?J鬺iXV>44̌;m85M˴^4( XO= *m'ѡd"gMӸiUErr&Q%E\߱߿ _*ҹTi>K[.vY%z#GVذO}gffu&^'TUIk[x}ˑ\gMt=ZO;VX[b TUUYmqAA$CΑ#G+ 4kdȲ_,|:s:+(-Ä>[1d1fQI.BdzieRZҝzR100l#geKhE8rKfIr5 ݲMK.Op nQM/KCOIqIèZ ثbtw w6"=,e\Ggnpʆev+ϤwQS5*"}0ɴ>8BśFʔlF&߲¬n]r<\ae(,ՕiGyZKTB?ƺż D-ϧTޗ,KgX9>f쪧G|Qeܸ왴LIهpH`f5CjC!).U||KDzeK?]Lb,b +[>XN|O wpHmC٧tSߑz4-ƪSP1 H4G^Z0OvE1l_+L]oW ߳j|^,YbɶlSZ!KZ9 p۲LyKZNuՙdiEEԜ]%y?ftQX #TV姖>:55ؘe۳[=< *kWT8˞1f]8E a&3| "a>]\&Ol -&0Uׇ鱾? dO yJ.,[rϲ/xd>geӘ݂mV `tt\$.W#:cޏݐs6|2_7l].W?f5::Ԕ۵/bѣGGZ&8{۬}ӆ {Yr땸0Y_Ա~llc݈w3F|ּi4^cdeSyzӖn#i˿g O."=~"ߧ%Fewu34B8Kyt-a||בgf̀= 4^ F]7?۫ﹲOo]Jh!xaSFC֗JJJ,ݦ駟5cŦ`iamw[~w\~*y[P' !_L~8~bQ'8ڞSd800@qqqVCaF~Z#; -fK+?Ei o>7^r6hH||7Y_2{I얡 Kg@ҊG沋̸DjzmOu^]nnQU%'Yd1|'2&D ?-egxf-d``]W~tVxv1+g;3;;c4rg1@~}BEdhJ~->M8~#~3,i5fDB!%6ڈЀOWۍ\g8 Fii26aMs:g?ɒ_߇TrF~ Rsr+ c[>x ^gF$ Y7Eҟb^8dƁUIE99Mk!K*K^4=e:1tC<;>j2B,mVWvP]ERN8ܛ &Mf^JbbqC[Q~ʊ ][}Ν;GYY; mWZa-XO?}F/ [:3Cc?ιIL"%E\J!KӉթi\ c/Kpv7X$att4;Xرc2#/lK2wF݌QhzPTYx&\&((b Z=1,;iZībOd\m{nWeK~'{ 9D*TTdIdlu.~8X9yy;5Mcpi^\zSmSȒ".˒<u9C̰%8bmj:vؐn&0<^^zYi#=V\EQ~wYܞE%:ng6d}et:-ٞl8~{MzoAb1#,]sΈ=Yd˃E"])1v,ZNgE-?ͷ0mb SUUelK<|/4M˹˃344dYO/@s㫦n&Kȥ"udr:M~^c/躝`К;|4V}?^MjttiqAE ~8&Q݇DT̷}ሲɸXDruѵsY'%trN|bt:zk_1$`%r^$p3!LI*`%ygrnx b#WR|uCAh(o>ӱdT.GV$N /՜M%e躞  XVr8Xh&Ngؒm]Lpa.-e}nT] ˄Ng]cb1&''-ٖ$ؔP ֳ>ۤiqeQu@E?#ς I\"]އ𼆺WYiɶrm>lwu&z0.FQ.^ށ?Hq)ZM"`}`>D. ľWcbҜ/>\p=k=(рPzdT.zGaS)=/]^ɉ95{Fi9Sl4! 5^+yLu&&&())I! XWKf9hNmT| 2*TaُD1f]":oߏ;|s-`%٦6i!(̱TQփ3cv`"wD%E\J!]i`]x<Ȇc\ dWSi@F!/.{M^ X&3U#:1jΤc zl͙SH)a>GOιS|uctz~8ފ9~N-Q@ X uP_G\28&.IM8pWe66Ӥ~4r(/bh5]$oFAֵEQRL⯭9vǦh duSq6=6g^SS}Ғ533C4L,-{9'pY/gt=#FuUvhe]Ydڧ`}v<ÑeT~t=s^zAjZSLLLXrDYi.W$BMI\dWEfuwr))ed1u$z~  gυV\_UVMbOsO(1Çj+91l#t&łKsހetÂU7=\%`-t`akZ*+&hsR]iL]sۉǹ.4Mb1Z$!OUB-XwP-Y| =֊ϧ"Edv`dr{ Fyg MT. pլ4ozʀʱ@ `v*+I gHWLI ٧n;]nvs ?|ٻcހiMd p\* Nbih9g2yDd2K,6i, K)n\ͫ]"\ij)6 'k՚'u-U]Hʣ'f "D"=-avi1'D"zMݎ$3-XSSS PZ207<}pXXld)ed,{qB3:V:=_NOOR73| e,mQFzѰRRD 盾pP??VJ'U'ߞG81} o eõ0 ނu!FγLߎC!JXi`u)Me?n$ҍdzgͣ$o,g־WuUIī̸qo[Ša&z >)9rZ"i-sVP c˯P8y ,%⯀;=!uuh4 "E۴Uh:&"gKp'y!pu].+q߂mԞ[߻^˃Hvf|-^1C ?r,^J: xsF- 1D6M jmN so< x`Z dv!Nt?@n Ӝ49BmSm&tM:'VX!5;@%5 <X# /L-:ſ='"7_M'X 뜿G^Z֢2@2:{^F,.@38b€[Å,R;ڧ^2 Xhբ>zn*#bxH J#:{anſ=D0xB &m k^{kl0Dh4bm߭h7|-,V(굗=hw J +M[xU 5>u#HaePQ^296Dbnmz_4Mm l]='%nzED5}#:Fo_7yr2$a_MB뺞ݯPKHauvh<@$z Amh C2 Dq0TX&4 Pdy]냏jM/OzED" LB@Oڰކ67 rǁig0(#x,@4Zk!qreyfKDu̾CO.ylο$BhΥQԪC~vHƺ0 \w&3Xjf!&\g۷#b۹SDžBqX,^" agſV%>LWF#n}-CsV%p{^{ezhSŷW":n&TI`MUI n'r@P7{>%>\'pZPJ`LAs?tC~ 5Xe"$\'S~guKxn$<%VDYV,R An, R~HΆu=[5Z9\, ,!ǑaPqqaY#}V)o< dv*,~Bh|Ev ,/NyaEZZ) a@0R}ɧW޴g ]k=y%xŒU&ȽׇN2:X1L};2rH}s^]=cL/:AZ]bm{K)D (>zo-ZUP̓Օ 塚y4GY+0QhS<@@a+sP|ҠmBw8*%e .A쑿i2T+A*VYOS  qj_l_^yu$i`yn0azrַZtOZ#zjXѰp/WV܃B%)6UڪnO|eywC4k3g xv+]H#y?uwDq1hhSNA.Ɔ'anʧx=fKm#x+P gqt6\k/0a>Cx Ma$V =?qhclH`^.BQt)O#е/ ٝAi$BU{kzV+"@&cU*F"|:&¹ȣf̀"'zm"p FomuP}#[‰|4-0^wQt}ѦASeV,/dg|0ePs0~Gzyh 3rA)mBs8SQ|[my9 H` ]}cW/@3q:jNgj~j"kӌ5P|Vf!B5Gel57| _"}#LsF9RS˽a@f`6jOqv 9p͓+:I ymZs'LcCy*qw=N!Fi8ΦhC֕yT5Ku9>w*Y߄a6W mj7m mZfW\W rK !<jylԪF ƪU?=]/Ķ`)$&h+xŃՈN^{nHiO?[xUuq=Ԫc`yJ# `8՜bm0h렁G~ə=!^G%0mĻvd}W9 E[ն#`L1^El{nX}4#RK6AD5G4Map2jo~ zF Ü`zbWe~M|Lwq!/;Z>^8N{>^{BP@`E"XVERJ32gػC\$Ρ47a q밂M j'{D0%DQT*P%B0VFyD"W`F!*!0#u`Y_sKzY^C /sԙFUY" ,%ݣQcn4L,?C6gBvah]4BmAnER$}D.Cb|2֪)|pj" #2/"tV`_xux!aX$p4ҙ ,uwLB&B۰㔄z`A 5 @Cc8 t/LsBs jA$, ïcv"7! %iQM G; ep#@40Z58ym`_aL M ꦄMG$= IDATUm/n y\SY^0v.֢8;r4U_q'jCPnŒ\ t=9Q@hQ=u [kOgnd..K!pgqv%,jpjԓ,^sBsa7W`F4g|-M!^@!5j*hX8oS;ZwoY3<dāVUdtݿcy ˜{ Mw -J~a`7L)j|O>/ 8g'\=X- 13?^㍫Th}IjHra7W^n{tߠpZ=RVj;p5Ѧ@_^{\i-8rnH{BO<(UC TvN*byZ7\ws"B`Aڅ(4,T*\XOzHMP}-T2PBuwPt}ft}؋,sR u8%,an%OC+@e.˲bhXqDva~y?FGIb"cU{ o]c5h4⾗Wh˄S, `xh{x%%q,+д< c ACdfKVRSX9}ª?hX,,ZN`=Ӆ7xcH  yv~_ R7Da~pq9 MSf[r[x;U{bNku`ۋG-lJ,Y<k;"H$]HYg0րm?m/0as4>^-ޯ>N00Nvcާ= 5abis]UXŲ$ RZFeP/4u ^c0aSЍ!F@X p50v]Fժ)<&4MqqTU)cttr|^`p'M0&hw#SQ3 Yz#r^c W^aY.e5p/P,"t1 C(V#27jos8Y8&%PRb4qu ̈́'oM`NH)z@\ww#MϖKMj\' ɞ'4>G`)rq멧\i:=2N ,\4 u:[д(tc1 MK Sņlur$)p%cB5M̐{O=cqG'%y ,]ۊuc: C>=@ Ig 1fƯ@0 8) h݅8m Xc-T'cJG~' 7|'JVߍW]`y2k YVc߃c߃g!zgV :\7uGp'9K\U%0aoR^PP`` Z-qKphj^Z[=u p<\'Jŋ: C Dl+_ hֶK ɤehd`@C0 hz)A؁u)nzlIA/tnY2Ti-e$ 4FaYVv2ELG#21pĻR>̪ϟlBTm7=~H$0|dNzꩧح[u<M*B𽜝qdaX WF8m@t:;p+t} +MK~fl0Vs:𸗊 N»~;ūX՛7o|b8Ƀ4]]Jd2=N~sw|/'pr3; iEOGbRTa6{\Q) -BZ , tBai- &*O2h.G#N+ ];t`\V'Ny{yԈ'}3)&NLy 0 8ω@(Ƃz.!Oh.\w~Kѥi hZ pVc5PT=.8B-d5ݽI0ytIQu2jM2DX|~\%TOдX3x৆Zb"`kBX; A !)GR{tyf֭[f|5IX'5|~2GhapX>@"11th0y\ÿ;Mt:FHN+LQ޼y3?+=rNk{izr?R6A^B`rW4oz*"P@#~EBX*~~W4E("b"l۫'Z@`)@CX^ǞS7 YwPaVp 4(t:)]8fg^z, nDDPMN^=OBNN jG`)C:Fz Ww`cYC=#XHp q&ć3mG Q`=~g%$i:֖帮ILN,m8G#,"T&^.BhB;Ӵ<.%7E2a|؜RhDGJDkhBSz|y|L>e'D@1 ,e8l$uީ:m\[ӘJ`'ب!NhD䳨]q)G4/֍7n߾@!4NQ*z'"k0F#HUY -cc !@B 41-*agzGڍV\B{B`dL. yLM( ӗZ-Xׯ_n߾iyš50 {YAJH?'ty Y wQ7^[P2ryKp*k>߮#?i +ht:Ss\~KY!ܓT {U53oڂ6;H+d2ΕSh{yP`uz0j!nnŋ_ v>upwBjg@ؓp]%5PGi׮][p#sN:F$iumGĉDDU]Gõ3 i=WuT=ggiz ,R%LNp)?!HA"ֳW|WKzR4.\Xƥ{ `wt]\nz'^Z.z 7%0,@E?yy:[=?pDQ$IT*.g07{AG{'x!@.&Ap&DԜ!}c/: :ʲrY-=\4ͭyv[z,4NWt-^ݾ?i[TW/uO{L{. AK^\W: @tE]΂a;/ٹu0"zW"Z_Q ES3=j^]1 }nBu{W;vy2&'W;ڛN13A%pP2k`um5i`2=!= W]'h~|ͲbX}$tӹûڡ 4vx~/%vL&a| ]rl^>XGE WV/ajr as+3H9wHiToH'dIOcbm{U+4M㚞H2zY`i+HD"iJ%.5Q]]. "f o !8l2םdRs^os+WY "\[]ۖ)`_҈n~O\Z8/+ɛcGMjWvmz«& ~;6z[y Q'87_5M;ŔڿvO4W?P~appj[yk^@$iWrDkHdơnh4br*WyrJyqNz&[FҍXW2. NGt 浶~ 9HDĢGg<%C+PtxYe=;J5ݫلոB r{b<2c޹lܹs5ncXXX;yhp O?"F{ K+16E(a95NYێbmPnŽWXh>WzX^o= ێ`qT٧Er^@?NvÇhjO\`]| }}}Dg8r'Ј#?rKҏ:H$TJpvU~Ï"._@@&%i Cq-'5.h<#\ˌF{@xA|R3<hıԙzP񝃀)*ːt:xHR>,7uȊF*945ʟus˗w~aQcccXYYZvv1."H;B_#l$!Zv&ߝ^2%×.];?=X4+1?ˑxJ[u\˔9(c? ^SC%§TE.B6all^n__ ^D04..]t >'{?AGUڇ1xi^d6>kW/r*GJ4MȈYygZKW<)K~D\Azժ79w188d=EhS@߽{^.Iꩯ߼hafoooyϙz>bK.GA"<9'###X]]^;_w E|ӇdIf= ,+ ͋t}{"\26b1P(xzv:mgvd[2sAU2D"cpsp]LXᠩ5-Iܿ#~Hi\ l[LR"=5!ge:v\՗h0099hօ ~XTB4M7~@ufB_]] l )d;а} c=^QЗ=oD *p…~S L&$޹4,c%Q /kV[DcWqV# O]u3 T LP~@cC:gXD"_hթm;> Ƽ2 `S /kV LÃ:'Qi.e Mm!… ˠKcccwHby2U4aCtP5Kz I^-):Bi|@M2& }Ќܜb=ثpL [۳X~k545pX.\X퐅gރKhE8V~,C__%W4pi8ʃ<m ضU͗їPmPZzwRioy\_:ǣa||yD .l6H`WRP*ɧh ϟ6( ,XXXh;dP( a``ׯ`h 0νwP=u~'zꇤ|?FGJ E!(Bm7-r >`xlKg$ zϝ?Eq2/C\]2022˲hڞD$ba~ma6x  YB:+7+4144$ q R"x9W|X29e_ zDW E6.Aup;0@||S+HK0.JS{rk~v;obtT-GFt ei?dxxط=,\"IH-`aa;vF>GP=^w$Mcz+8rQ  c90&Vd2 AR_miA`E 4[PVڠ.n^ԑDXvH4;wsX ZTDr ,X\\"p&!:/!1x䲆 P[ #pJ&z9??8@,X\\8omlQ`4Zk_F2A!'5Q }7c(ѨP;$*ڈv 5b}R.e)4v+dv{ !<ҍ5 {NJ4 !'xv~~hC!0 (nka+M]\:Np-A^a Cx@碍h MRQ*_4*>Cp6!-Ԉ [RE!+nE.XwH&666PDEf~!1(յkB>N<Ȉh3d;h#:!p CF\E.eɱ{urrswD!gDP ۖ/3- vߟCFAh,//h;c ;;;'ffzX2 o31ЈyKP%A>44D}~cvvm_]`LpI-Aagg^rtJӒw8 1xhgP*ə3LbhhHA)B{fZ,//m |d|3.Hd)skB,>% @IDE'X~VAbwwcux''h!q .c.!mJK2 9?sܹmߨ" ~BB m0 _DE;յKܜbFGGȻl)1 Ν;g6' ,XYY )Ѷ qF!ڔSFkmѦz]C^aKWaYr{"FGGahS:w;wnC!QR`{Y(u]Hyq607{%Bf;ĻJjQ,-_A>?=]ED,4w >/(+`eeDTTY[a ̞hS:DݾIloOby;IӔ@ _iHX~XAeB0v17{c /b ߏ>fw 8N's7o* <Ж4att S 0M" vk籵5 75MɤhŠ̫q$>y_@'uveYކȰslLFB|NX?Ӱ5 `kFFFRhnkfffQ!!ud W0{.OJ?OPejQ0'6DH`auu'h;^Ef!6%tZ+P( 6#f6BH`auuUGK-AZ"w]$0>%"Y8D>1ێ`=;`Y:H$D> q c:NѶF铒GLabbV/$ێ qnpF" Sfvox7#:I_0+ږժhS:0lLbbb D0; r3p~D"a 333mljSx@Xޞh34mLL`|| ]b1%8r`V000L&$zbm:o_s$z|>74\t=8eDX7vds~a`xxXL)aӟm: bwwJpwE"&W0:C"8I6Ρnnd2AJ-?:==aF 6X[[y?)ڎ0Q.0 #Y"6 866= VQ4M RhSJC 4E&l,mJOh&&VLDCHI0J%\nݱ@[8h4a&ExxoѨBMb>E6 E }=LNPf.Hrs/#f__EF>[ X[[<+m z;;;9, &&V1Z&_4= mcppŷDqLc'?C8(0hjjN0Xc~I*P* y߿m 0(8^e0v#(C/@u r|`jjEH`yO9v8( (ˡ]6<1d2 btjԮTI + XWBTT*~F%姧~^aǬOC,.u Gu `}{r{f21? AXzI3c)/055Egz ,X__e\*QTV3^I"w?%5 J T(:i@2mjԏ6"lu h[T1}E%N0ld2EddJ=Q.Q,XC UFnuL}}};??LMMX>m/p{{{(ɋs1R%dEd2HD(V?n6Tԇr9p:<⬄~prr} ,Y__7Hd 0>˲,ѦHI<^E:]D2QA"YF2Q&#Fj J jRrht08~MNNWX>fu4sdr * Bh{I$@"QF2QA2YF"YA"^cj-j%ʁVSh4"MH$~ˇ#\ ,dY Y.Zݡi x xhX Xg,Z{b8CUo[1j jq%z4 LNN3$8f)e ewziV,VG4VC$@l4m?5M1 m¶#m ;F#G{(l[s0MHRM!_T řl6KH%T*a' y(LOpk.4A];g p]i`ƴc::l;1e8S4MQvyIJ"Xf?߃.crp.uO x((0brr ,Adm!B\.G cJHXɃ ONN %l6>=$RX,*yAtJ,C&umL6nݒzbJϡʄ<l(XobbE2$$ ~?42JmG\Be4MC*B__LR!!% \h[q]b:$L&]Qϋ6 %\"h[0PVQ*PDCǑNH$hT~ !\.7^-ضRRD^-"躎t:t:Mˀkbb"/$$$@QTȫECo  NLLжg %)\NC3;k0lF\FT䥄t:T*Eު`A?=11A\.#~ ++TUeTUځHHiH$HRH$hr@6h m JCQL&)`>>C+ rYѶq(2j-d2I*,o68XbcccNѶ.-34MC<G9B+xV!D{ ) DBxˡتVj OaH$$GxY!D h4 )e=[z[*=U(cb\?i$ƷeH-ZPpٶ-$#i>TxTjm$rܱuS?[\{~lv/gΜÍڱ17k Vt:{CgxX366D [h? `},q:·ہV,4bzccc?DaX,:$MՐpq:±`Ns"p-psDC~Sp=pKݮ~%6,vLHR<|n1t kaUq$^g\i`鐺rNY$iH=\n D,R G8սqJ FuyHRhlχfҔu݋u@:$ X\n D`+vǀۀ"ICv Da1v, EPi铡htY4Y}X:z.MӟgdY60?pIͱX Ktg0j .˲jQgyS#bps$y0j | G?iKTZQTAH6'1\.Ep86wd2X(8j0]R( $-tpYLJh*@H$2BXGQ i"< x`Di՞ y /\fElt49rpp|DavS,4RZT{b 1eXNZGa8r̲٬u0ɘ_e>]yb{%<s[9|qwzԵ_570?+ >2^a,>=;๜qi$N0ZE 5sl} =&j5zws}z$s8knX^נXh4R4;~G8=vhb_n]+q EQ2g#: 4 *@2Z BGԚͦLpߐ6eY 9*05>IENDB`jamulus-3.9.1+dfsg/src/res/CLEDRedSrc.png0000644000175000017500000012701714340334543017064 0ustar vimervimerPNG  IHDRXXfsBIT|d pHYs~uɍtEXtSoftwarewww.inkscape.org< IDATxwx߀(QTlEvb[$w:dlI$~&yvS67TzoeɲDR{,$23 p^?P1Z8F!PYYy@[5۵7klKZ ! !tI%`20 ͉S!2aAHum" @UEEE6! "~f̲JYQQѩ*0!5H%D7  TȒR;o$\U DEEOa\BH%D5H"u? gcDK?I/!$XBXeee>W'Q qǹ::VQQѦ4*!D$&*++ӀہC۽A ***jCBDC,!,2 HT ъ.! !# QYYY\"}gJ&DiCIWEEEڐ TVVN $TF$D=dk7Vq J;~ ڵkOFH%ºu'(ȅ0 ڵkFDI%lkݺuN"~8!~^~qڵ"` Yn]6aS@pƩ~ڵke Da+` Xn]i"##Rx."#f͚: I_~4 BAOw֬Ys\u0BF,aYׯʡ6!$Z_[f몃b8` Y~DZHSºDx5kΩF+I%,cD~ |c͚5cKXK/nB k֬iPHm` e֯__#18!D?f͚I,a|P"y|͚5E,aקY' @p/k֬WH ` S_dձƚ[zO,a 6xPu,B1d?իW:$ذaCMqdP!zj/t' Ն Da ^o?Yzu@u0"yH%taÆcB>zMA, 6 +Pu,B߮^@I%aÆ,[Ǒ5#իU#I, 6 2Sձ!A[zfՁKdhtwE!L2PB, 6@u,BI&Hh>jժQIumܸq `PBGVZU:am`mܸAdNo"2 !%Z*:aM`amܸ?T" UV:a=`lܸ17\B|sժU! lƍwnTBIཫVzAu $Z}z\n!]%$Jq7n0Ou,B$_jyՁulܸm1$B]hi4M;iӦG#5X)hƍOT"!c aY>rՁsIb6mt[`X"E޳rgT"# VشiSીSq8BD- t4 !vnYrePu0x`M6~>ձ  2888/%NWnh\t]wiii8NNMޕ+W֨DK$iӦG#:'\ \NRrpWm\2M'+WQu 8`%M69VP(D?~MIT nR4M񐞞!E~ |~ʕ+ mڴX|>~Mix<^n++W6DK$iӦ9_RձB|)G($MpzJ^vk5o[rQՁHD6m1Gr7)opp^zzzIEh%##L222p: >bŊDC$i&scJU$b~UxT$o+VD$F,ۼy$8a"GwwjpP&y9IEbŊժ6o޼=:a`0Hww7]]]tuu100:$a"Evv6dee:$a6]+Vء:IlhYٿ,؝ꢻ^C%H{FFYYYdgg3f! ㄀YblF,ټysYרE+ ^f?yv+;;[jz+VU$X6yqfձ}B!:::蠫KjDB4M#;;\rsse:bŊё&6o< LTHL(rR%sQ #8VNN$[ɡXbŊ' l޼y!CU" ꢽ]*aKV^^ْl[+VT$Xyljqn&Bp8Lww7mmmtvvJR%,pC~~>2/= ]|DL,ڲe|XDlt \.Ⱥm˗/IeA[lI~Ku,":pNZZZR1Φղ-_\oI,f˖-Dޯ:q}*U")\. ((( ==]u8":5˗/oSx$Xe˖S ձa:::hii[u8B&++BrssVN˖/_~Vu "B,زe`#P:1AZZZhnn*R\.cǎSXX jGU"$-[,sEZ[[e$Hiк|˗oWHK-[աa)Cqq1o޹|uIe`)e˖wqe)455+~ q=:qA˗/@R$XlٲC/RB\x~,D<EEEL>lٲTH*K-[|Wa920---466Ju!b0rQRRBaa܃! e~:T# ɞz/](imm@ :q|{{q|p60#18yퟯPZ!3v9r 0f @F^/OºLn7%%%He _^lٷTJ$2SO=m Hep6)P'.13;@ m.rZ(-7x mYYҗw7yLpn7ƍ#??_-l2Y~$`੧ҀRK*X~ա؊ JfK${E2LDu0=r"),)aIOO<աYl< & z)cIU444Tby齽d_@VSMM?77TNǎb*)_) 42n8u^lLg I SO9AmV:TbI]NHQgf5lu^VFoASƌCYỴ/[L=D, \ILM= @~m-֒.|?#i+/}D:JK 2?~<.Ku({&``/fASB!pB/iJkkɭ'ME񴕗6q"'FAqq120 /KJ23A?B+SsrA ȯe3>M΅ _,)m`j#it<}:O}DKt7S(V&L 8 |Zu FjtuVD}}}ғ}g&hT3Nԩ\>tYYYL01cƨ%|gҥ2$֭[eQ ryZZZTbG0H~M EOSt4Y/I(R5cm儒 ?~߰|п]sO 440bۄm78kS22QT,>tRY :A`%h֭H^& \pƤBVUQz8^}'E4JK#oylQ9\N#[CU[^/7D-2yrL4?i7b[mC!}K.@Llݺu-'d4az{{NYs8bR9ƌsM'O~#s84[ulm}#x?yU& oR2qDX;.]Nu v% VnݺSdPzT;g?ihPL<7ߌw,`%Kn$֭[O2Eg`ZZ[[U_ɾprrJ<܂L){z"5\ TU)IJJ}[6-:|<)++#͢#+mgɒ%gUb'``۶mQ`XMOOΝGsu"SW]&-1NCxnY)lkAzA&thVΥȔ2ΤIo1Ns,Y"FI(m۶- ܯ:dill+> ϞeÌ=},.&|A24i*p(Hu_yk>sGԩ1j4MŖ ,Ybo&+ ۶mӀRK2ܹsʖ>lJ3tN2|̇3se s;:=t9pfS*)j\ol4{prFF&M"]M{=K,:$¶m۾M:jmmƐ(Y&=4'?ui{24pFBdF{jﺋ<^2uH %K::m8 3$ RSSWGvT{;;ze/`h@̙YCyOnX9^>L֭taDA;iiq^^t߇,Y_2IFm۶SD#Uh0ʟ}`{G>Hvuѵy3O> +'tRַr5Vn7dff%Y ˖,YSu V% m6 8 Ha\p:>:ĤՐIy>٨s|I:׭cA{20f!eI4JKK)2id .Y@Hal۶m& մ%fNG0Q4xnG!{*GD$ {0OVҵca LwS=w.UgٹFKyy4gōIm۶ pQeX*]/~ӧO7o$g f#/,( {ժH2O+Cז-t>$}?^{%hz)SahA/,^Z *& o߮ձ]{{;UUU4 2g~ /kN'GzM5 tTVYY@ >5wMFwZZ%*/^,II}/RaΟ?$inڶ̖CG'M2¡0={ wXN.]J YBӴˋFJ낁xo*$}EV@e gϞKu(Qli(:sF}:KJo{Q6,RGsӳom>˖;vVJۯMoKHezxu ZLeF7n%%%ð^xURJ'X۷oSqQ8fѾ|>nھ^J E(ȇ̚REfl-CGۯ~ۂwҥJ8VAAeeea/^gP%e۷ gϞr?[ INZ xI %! :U`.22xuroE茕ɓeR-ZtTu *d}b"N4M#p)|:O7oWlԩy}KۤiC~kZ~SB:w8rn I2uT6L";-ZԤ:\c'x@u,vǩS0`=>=MzYfڍ3I dΛSdB$f.t[ >C9aj ,r6m^4mZ`EUbTL~|Zuvə3g,=R0[7m&/& Gf&L (|ǎoӡcĉ_"5sgE#--ɓ':;E>:3TcǎG?n.^HMM0F5Qf݋c9|wk9k,,5>!V8L熍\vnBiiZ*iL0BG㝋- ̒2 ֎;ʁk7[էap|^Ӊ=/IF Po-?9mgL t3ց3~ܸq'Rn[h$%;v1xPla(;\'y?ϝ}dZopB:.~{tܙ~ټ>qu_gbƍ˾R!"# Y2R%2 qImm-MMiSa޽Cı߇E IDATt{|tZBw}Got;ZsͽnƎ㕔mc_Yh7UaOvqpn_glLKQORB({wjkGH 6^ZZp.޾p¿I`ܹsp SՅB!N>MW nf};˯'+tw~ׄ w1[Ȅ|\wS߁ټ^n&ì,L"IVtځ[.\ht Ν;.@7++UiO$v E_" #Bg^mmq?ppz|K6J .R!qH#y$p8ٳgTr{UcZ]v9Ku,Vf]~?w䝏odn֢η=:G&i{GYϿ] xs())`?lQ0SHr5F$WaoU_~(ɕW8,Ŷ`in]w_Ž.\`ȳl]k׮Iq@㏠jCˈ#ifK wxi._'׬"( 7~f?j\d{KXt'(++P7W$^v\|/ʫgowwdR\&dYM䮭`n*e}]5J1o:}B~+2^Mݿ5q֚12^{5,jrљ3Y87\Rlz- |3L hOhu|Kou,>iiiL>׫:+??-]vc@ ɓ'#1„cpۖhq-H6 2aWDb|t=Yo5_ v8xe òȢs]Ō3pdZ~ዪuƯHr5`0ӧ-\M}inܳ/?1Ve^E񗿄t; ˜G*pM@=W~anݰ>;G׸i!ٳL>4]IDRHlWk׮&qXQ8xܴkSy6~= 1f=1@U q9hᨯѻ[H8Uf ,ج:X*ڵkW cjZZZT q-?߈O}~@bdB$96P_}qYfaGbcH (++Kx?IƝ\]J"Ǖϱ'ԧ^ g,͌3p:mՓ,,X`nOv&5fp8̩SL q?kRȌB$jۙqB_3%0a:KKy{S,f-X@mu}k_Sèx8Vek#'QP _AKpN܆Y(,#gY\ٽbTCCNc#n6_4ː0YYY`c@ה)Sd4ڽ{wLUB{{;gΜ1d߱|Si O7CƃPFzV&D0}GH8Ήnű5~Q5M&M"Gq0 /X3[qHruOUUUL7wr5f=|kpH2 |s4}ZVdbjkk1cGiM$G@Fbݻw<(n?`0ɓ'|1S4> 3;dvcq59d6A3"=߀8C8|t^V'V3fPݥZBIu ñl i?BTWWJ8ܷ?ID](?\IqCX&9u|˜? ?*rgdp-q_~Z&M, r?Rǰ,}Ϟ=:+p/^|S'H3=7uKz);ԘEd/Dy=fb&bNk\ }q_~AFF,hRUUɓ'Tȵ,DgϞt$0Yu,V믿R^}ϤYJƃU,v 1CB>88s}7Y4Mcڴid] q>$WAΝ;4lm宿T68[ЖGxȃN&akm?dܬDg` [h<ub&E9pqtObb={Deҏ!Ν-fo~+̽w̦~-͊YzLj1u*;t}=͟|?l5*Mͥ\I L?UUUU`88NփgLFGg\Ōpxeh7\["kb?A<ghu!f+~zҁɓw`ٳ8H2ϫjz57mp'ۏE Y(XvS(̅/~ /Ľ y="8Je`$ 7܀6hYd9^`ʼy,1mIHAUUU,ߌP;o":]Q>{tTwiMJlla7s7McgqћˉRzn\#jP(Dmm-[ Ed%,5X{)nK2$jhh>ӭOmq?k2 ?)#ma29"F#ne:FJJJo1~`yk~ё%&4X<2KOO ʾL{&?7@'>fcK7[H6O}k}yS4{SSYYY2uC"IՁ(ڻwD" :oDV, r  |JDzOhqiۏI+,9$%`a&9Fo?{S#?M{YEvs 7| ͛W2+`}IȂ+{eO~ەֳS]:_da׿)jau&~1c700@}}='N4l r-PN{|Pe VIk;foنx;{ﺋ1sMz3bRHβw>˛7Py| }nnٸ=ɼ.]˷ʨEUQT(&Υ02:kf nZ)t}GBg.v*b~=tU7\S>hW__O(}II$PFY{R&%e3@@4}h7r72cxKK yyy3,.H.+ڻw,e7Q*yW|iwe]BMh]3fWҒocn_0%OnZNw]bx1c&U%C?c`iR<pUԿ>ꚸZxhvyL>3a69bRF& M`E³|iܣcd477STLI|xMo߾2fk5~'ճCd~}3M+3/~&XWѹL'WʾQL}湄+&ǭR,"59ԮCξwȈl(I )7mFYVFOK/^Քg_Dk2,V>'7ˍ4aSl#qbrrxA8q69&YG_Ooo/gQ?ߌ̪|,/Ng*k#Gu|Ҳ2~1w c.b={B(DIִi6‚Fq8Rz{.NxDFkll^߉IkhL, iy Kf-r[g9K1Ky}e_())8l. 03j>K 'W@j_:Kr0HKJo:ᛌheZIѿ&xDޛ[@ /Rw=h.^H~~>.r-D#-lQSڦO3kII0̽8l.VSSi1O`P}M߿3Ljhnn6ܴ̂nsOF5/Ȓ7)H##߳鶿ʹǗk|ҥf`0Hzz:kΒȴ,//Op73KӴnjڷՅaGgh0u̇@Eg X[o6w܎#3Ptf殽~s;JN1zXhp6~e;NVkn~Σ6tIǦSlnװ@o]6kÁٺ^șmLxUYeFߟK<>ʈZkypXW׻`\~f}a)ƌ1rR|I."kt=oރuvM7ό{".JZ)Dr]0"JGZNO?߯g~-wRLΩ`I[ 3 /)x.)WV<)3R+3̶vʏ g 7y 3z 8Áwm:rotėq~m\xTZsxE[}Bss3fOMB1k 7*a%!'AU/*7xC}j7ٯ>k``6ڌH?l! qS,alM5q7"[ł$f!:|3pddwrª U2eѻBЪk!zL3ڟ200`ZyZ(č{vpVہje6 ywaA&O"0gZA)((0%SI诖>c:1cadiӅ~5HeNdΞmؾ˟}%#/8%IdH)/+0 }?0oI!8¾/w)7'LyyiYfh"\ xu؏vgKǮ8Lª两9p.H맮x&wfk:]]]K$C";#JA3Gj_d2v,+7u!bu {CԜee~ژ}sz>]M LKK g32:x`64} '>ʏ_ӡkx"'0yt\ׄ Q1jz'1sI{{;%%%R,=tP}Z'inn&45Fɚ실 >$ IDATK,L%[1w5m0>4+B!Z[[)**2< I'&$`ir̓p:{{(?~e,u2T r̅y8^BQфS;geVƕZZZ;vsxi8tP.(U{{Lye#qN(U?i INjo "XW$+G0Ȥg_}#Ӵ,dPDjY}:躿Ѿ){uRsp1tgHMVRfń 6 %ׄΜoɔ?{acN/6rs5M$utP}`Mྲྀu!Z﷮}"5%獅X+iht/m˸Np7Zgw'?ycd5Efm5XҿDDEԶL>cp9KKNt}Ť_,'zS0l]ʳU`:t ̏}vwՓ>\*!5gQQj%Af-69z$XJ~Mme#Evrrrt۟M?|{ܹXO @Fﳭ@ @WWܓl򋯌/V:KJHo M0RsOUלop I9Դ IM)\.)YDgW,o'8dfjk Ӡ{QZ~Z\! 9 YVAu-mR^[[Ŧe!K1:4͖ V>WxEi5zSyz䣸| Io歔a௫4?%ϽīNQQQuv_ |.74>l@ f׸9JO3,MlgL}dzVvٌݬzhA:CWv+~~sUR8E-HU':K`}F8<o2X-tfor 2'%m0ȸSw-AIk!ZRѾXQB뮿gi٫p=CMT2nz|Kzovnyk׎U]hk݄B! Nrj3$XNB365ݢOmY4},B-=?jlF& WӼc7= ,)>ePT+bȌ/&{ҫy0+燦w<[3N9z8W^k9#:;;S-$ ű$XK ǦBis_9(=3ԹZ#y9R1hsa]2$XMb Gx^`T`04yN9ͭ4a,4MCKw47C>|?Y~v|H|ћ5r'i?:;;S-*'nuȑr`|D0۔ qůy}Ɣ+ӓj`bzji%j!`a(RDVљ*^a:a[$X=@+t":ݜ~c鳆%XW&T`χ5, u9s5ji e&6G(Dqu̓z6}>L%!_ERsO_B>MEgym~PZxkzzzR)rs#zMcp*6'-3CM aʃO$\+*n"p(e$fXc&7Hu}`޸KƯąMr$猈 1FE9 9gJRmQsGwE]ZZzwsBUvtG QsͫoHbaܷd0fxaz{{6 ѣis `LQWW)# p^%ZE IYcH%?'Er1| v6( ?gxǞTJ2J%X)<&'+M f6 Y ؙ71q_'SnKY\$c Z8"˳#QRے3La׸XPXSǙ^ ~cxY1p0Zu1XYNKr`-uXM%>ڎSt #J&XG_"zzzL)gl]\p\׿ڶP'I>bbŕ]|UL2:z5穟5( /B&tݧ 3)z5`XF3|t-'_7rS y9{ ٲ{*o=tϰIFX`# caْX&8 1 13a 3=ݯ^dܼȪի=w=~^=<,^/} mX֝ʇ?y+X 'n2 ^xel9hAA?}Zb#os=f<8^7`Fa0Mc_G;=9>dLzw`GuxRId[$9X e0ÅYW}zZ؜Ё T;2;t5)WTPauPXd§ yp@+=~*J >}rGixCm&uͷ~Cmq9^XbiOryz>`qX/x VPڶj QlÁ?>!'_Cs $& NÀ](pevsHjK>Z۶\^N7|3 799qn,4baC9X*E֑' zo&e$peQMɽ&_VaQ q曱7xz+Xj^(%so壏[1AEq)Cz{u HKEC}+0WZ:^wWmvZ#gX#o!}$y: vh]#!^6_-8V!s>up}֥8,7x{}q$ޜw nq) :k9 JVs=j _DZ X[>3MBj6#Mm0]Vpʘߚp\ifP4Xamﻟ"Zi#78  2~%w"'XY-+wQt q`&BBO8x@2lHkg8#x9H\B$̕rnCwp;%jA1X `[~VLe Rӆ '%YG!#8#SA EXG}~ G=^5zd<[o5Wёq񱱶_@Xm-}D9+lmi.~Ϯ`5,k;+W@`hwQSۇ>~v/!o9UM,1 smw)U•": S,U"1X Bpƶm.7E̕5c$;o1 J\~w](>ʉ5=8";;V:r!N,^N:yW:O9 ?ظ35]ijG,9FYs婗 OpuFY^|xb0FMH%z t?n0 .$|kFD`L [dI:.a1DT '4 .ŖgpWx,q7͍ K^:r`HBfHچc<ǁ(YF#1Xo0@$a"Traxj>WѕxЦ"·r zs)b2uZT.z~\jA//?(J rE' EWσZoKN:S{OéfM :7\T@-Ł4XYpxE PWxXdgƬ"wnCF`3K\L{s y7wNBKM{DKg:V(^Z O ֜@!0 KqXv 朝Al G|[&PL% 'WȇS\]`G^8,Ew]Aʙs w䓅Rۺ7/!|`t>'݇Tp%^xIo.8 y- ` V gJT Z uL'ݸ2r`4]>G{ pSu ḧ"M8H [`yqfWk<^c|bm9Iޜuz U,`zT{éh!tMj'1M4/+T u4"?9(nܓ6Pxv4>FxqP|0FJo,fo?Xz4^}X^0[AbG(hVzY14vT*ho 47 zqw~g %gq.dXBqݵ4]>!@EQ24MkWb]3P<ًVfI`ޭ:ZMbqtp"o>q=RZ\\.am@-ü&D?|q4=ۊ*Ǔeq lj:=ةsG5xv b { XB7kkNK1 m]cYt]oF3c{Be>?6g"|&0!*cXzN UݝN_i|p v!o}Ffr1I-'+^S8J}j=eEⰂcx=SۅGo!ۛ8 4?P =`^+R7HC7"cSPb1K:r5 ^t}NyOyїw{1X uqHlQb°-oȇ^cRJ s!җٓkֶh\Plр Zm^5L2# YY`]0†YjYXۻ&90Ɠ&`9m~Kƙp1U VuEQ͍O9\ZrK71Gld!>#h1l?AIGo<^Stuj߸(ͧ૩`Euax`F`g0`c5ǰe['zYbz9iLOq,ƻw*ZA%gr~n {gׅ[Lt v"c:vj0]*øEKqjU;O9Xa h<~B˦Z|B04p rL;:kwf* }fJvN7vax܉' ax `*Ǘx5: G7}6|{P'p CG, $Z1N|P"m|OA.ɑH:$8̥؅OEFYm°.ZP(aqxɕS]#~'X{07桱 %EShth!n<}mGWY5>XB2B/r9]DjGp{./Os8 AGwCWKӴͷO81RyKL}^*۰+{%0 ,_sr3ݾA7 mtDB!{]N#10޽ꢥLs# Ka@UUl[BF <5YGfQsC; p*U8vabcw[ySN6ʣqA#(7AͤEvN.5e8 >4]-“9T 0mԖb<"hxDdaҍ} UDjD"P;U8Ij.Y ]|hpub_8#WRV^+XgrUkمSC_cBYA]*iA|Uَ4>pH2duUM5C!8 Tx_z"tVCQ ԭ~po)WNh.`nlہ*pck'Q0Xd<ⱂF$HNp!'kruyJEI7nA= Vn{3U86`b1wF$xT 1X,]Eqbȵrzi4xS9@ V(a4^t!=jˮT}S@:s_mۈipl.lW`vԒ/JDCOaT*W˨Eu`8"uZI  0:u ->]؂swnE/3pPg+OI4!!zO~ԙ;],C85wiݲ{ Ąһ:&W ZpT[K 0P'AZ hccP3ir\Q# jK7ЪZj:0`nné֚w{8d%u ;Yr{~ RQT],fo-2q8_/6!iHoa B . sY|/P7xl@-73.`W'ǡ$xQSlmR&=R@:RÊPݥ` ֚@!89.qy51/{Dz`nlAM&@  <6j'.ןع\3ʲ7Vy=3jI6*X"\q:r:U[4 wbv56<7fbrF8 ݃SOz]doYmh 8T'kY VWLFN_|YoZ _рT_8Ia,k pg2pl^~/~EI8&l\dB30+l 2-X{ G0?U\ I'ac/+|mquD=tr?&5@ۃŗ_~D@sI%!r8#љ((H]-  $ԑa(:c/1ȺCxPlYrIIQJ`dt 2bxPJ"+( &؅"Rj& 5m\׶5 VonH<&4y ӐKQ!R8D\UNl2.9?l|1EIӂ}}vU rw3C-  F]j赁)3 z9sfvv ĠAqɠ4A쒶 ;_v@uz*A.[w2X/`! EA$Avi0ɰt|h]IN Rm XK 5&h;W](Ƀ;V]Ŋ_A^`0ha* iоj V%:4lγ,|a['Y_lҝ2b4ʻC`mBq9IdvMjMHH]vBP)(5yxx\>e;:dLTy(&[z饗!xe|J$w=.ziQ` j2A$+'pjuJ' vh襗^zlHŌ`o춪݆nZDGfT(-/pީ©Va pΆMHގjk_er"P(UUav7A~kkylѱ TTRHDǁ]4?<^ XsUUde?`h4Jjh:8,Eh189](DJ4>Ɵ2өuL NTy[oܦp9"'@ۃEKQ|#ZcG0z9SV*WMC \.BgoqTjpYhK9Zulr(pCnd[pjFPՍW$TN  mv 躎p8 >h7 (%._܄Fڕ h)Uin%F+\g1f>c4(ujk5ir|M)38M QF;= Ν;ݻwUh4.';1`1 3ZWxڀSé?IͭPpd"m8 y<рcrN^nj˪R޻} wU:w500\ΝN`t_D b>ۊ  =g~Y LNM~ z&8ig1.) -BZ,ΘHfX0ۿu~9^X9γ-œ6] l3qSu:zh5Э$+zD镱s=E+X @4X-QeqBsʔe5MEfʏ>t}nrNkn) \jE'F0z97ƾ29͕F&BSKU[ &L ́c;Mdpaͧ,<|(Rs:z=f_  ۷w0$"akG#才l}r#4eh>}<1`:6a4h@i޲wKӯqbΚv[mj2VPnZ۷ECD"ݎO DQN%/{F9S&Fv+?xeViug9vʐ/%ǁc\[&K+$|O<R?o" +  4@?c;)CG?=9)wȶhBGSlia4M Zg[C;iqЉDSa=Zk.b#' &4,=C+O aIOj*F1vX7$'\&'Hb}9 =6%[nRU(t]璮aovkl Ť2 | 6kyI.hH$¥,"w֭EoT?C@  v󮗓͠!d4\/+I#ZjnFNPhf8x^J`gЉ,ԿoH$\7X1L.oZV)+dƈh bs3B9@1On&W,ydqXOK?,9AT%hW u֭{mf"8#HT*ݘXHSY$5Ľ$ r} !F #?>̢ -=͛7W۽, @@*z`( 0OH#>e>xj5& xv:5Xd2 UUduo,_҅ǍH66Ȱ>VAg;~o? Nԩ>xUUH$P,]/NN!sg=|]E҅lBm龂JʙA.UACOQܼys ݾxd2ɭ)([x*Ka1H| ?^VV<V{tp7=#H0;chV3#d(j"M̑"1Kpw1X tś&t {3̏qfcGl9经4}T$P7Stǃ=N]S%y\ Jq1X}i[rR9]|F3}TQvO^#:6X7o4ݻ5{k2im C)I$jid/DVr:HKWU5O7:N\:(9˯(D"B0/ta/e 6/ h@'?/K!pE&REεy8*?<<] '}@RR$Ak-)'>xH660 7vJ[װ{y[yX P[yd؏4 5>nDt48 3t@D>5H"0MKyWf0եE&.>nDhBbcjsrAD I&0iE4U=# "1ӈv/rhjA"}^SϭkZنfIt*a v`a &DSU?ׄ,]nE᚞}m ( ﵼD(B"@TR^#=XR^[ Bl%&=19,9 \@H5wڵÇ7{-144`iL-mAoyBNid% a} u}^k> LRb-ܙ!W%UvjHHں6+f5IQh4H$Pϯa⌮PVyi K[ ner$&r5g0vζ}ˇzUF uڵÇ?`q=/H$alenQ쐎본``;\p%7$4=ykvH6JB&߸vUkC ̋}]l-Lary%~+g`7 o$'Hd3M1cu!al{n0Gp˰̎y[yGdy y:\%t?pO˗zM0==ġrs޿zMVf/I$(d2Vfv|ٱ 2{~*M r5+\M #?5µ}i* 9hXr*D66}J0(XUe꺎D"LBhzf05X׮];xѧ|3zEQ0<<ݞ~l_ĔKA3k/F$P^A5gt:sիWX^ЍC  fh4)x4sG`rp4 l_'Α>nDkBf8[z^着^ Op`%*V!kmhY> }#Z3t:wa HW:>^!J!wVl/Lh/_#rbﹸ/ϼYMB ?Ǐ S:'0vvv( ܹ?ô  Ĭ-ˊW`YzG~L&fgw vg0>iP>by~ IDATQH#_Wc,_@alkp8W}m7. P4W]g-,"C.Bb319~G6X>x0^}  Bp nDI$FjN xrg7NJL; ib;Fvի"aw8AQ~׭f^j=zn/nzll \ܟ>22KALF o#FvvkdI_rŵ3\ BW37ˡJ4E2DXZ.ٿf;oHN$EI@5?9aˍD95PsnCW\+nAn:e|LO_9(#;Tu ut{aHeo~\/$' 49AA^^n*i%7q9`<~w "8X]]}zлqꆁb;PlpMN5dI|fݹ GUW} cjj7=+W|ۅJR###̓ VoaU s "7QCVW^df1KCCCA7W@ӓ,x_xKaDDZ=n4oО_*?ȵ r(JMdK_j>A$8WW\yGA<cdd}' RY  o՜o%.ONȭ jF,tmf2z"\โyb,=mE|;J8!PJ3Wpgk{teGaV\b>ygK^eRdddJNV8ڍY[ʽt'Xل:+3A\m^|\ZMRU5:3w~Hq. axx{{̢#n\F*[~<'BF$P<`ۓN hznɀy˗ p`EJirv/V<' P =+8/EU,}HDBHرWuODG1nOcuimhFU~g<ەNJ6"4zϻP1X'o42iJ% 0xX~h}MIVYQIuߨUБP(d2JFspG 4N3ƒ׮Mj"(I z+E\zEoŠd2H$"drXhz !['Oo&m4<v-B% @TDQ !rs+SU^6;7UCV7H&}0?.,( ʧQCSt~Z(044jZ&/-@7LdwN{H#YII&2Xy {-DdK.m@| KKKcEki؀mBW-wzQIHBd'LoTʤm͝Puk%(tҥ=BB GT*J%i'mG w>w* }AK5u<*[Zbb\Vxو2uBNC` ED>G6ah/_xL`h:i"I߈kD7}nD2)hMhg!i`yyuPboorY\rOKIlEmU ˯]ܘP XL]7E8v~/@y*0 4 afF2L?w|#8{DLcd0"nٸ \.|M@+XHF-aNX]$nBl\ & )I~gAcd k #2M)岫:!K"DDARsΌbWh滊yjQđl(@"y6XOK:fIqxur͝ g ci( !cxeaah!+++?"\GGG-W jٸOd%~\'0]ߎ/]XXǢEt VfDkJhPW]Ȗأ}ᝮ&ib%"8. Z8.>'lP-S[D레mفaxzujy6Eː<>hBseJ @(|b56??EtW [s0M۰,KC\zoښJ"EE+p8K#i&8aܚ'4X~Ig_/Ch7WdIFdk*|it(C($6qc~~E,X]]=ȇ!j]2+Do?U7;qAV xu8??h! ? D!lm9*0Nbr9K p8 2K{?pS\okufm{+WDBbGQymW&܆ ˴psssuBXE'(T*/ס<*W5i݇(UhK^B)C+x<Ish!:`jk4eaW0xP`vM 7LhX%a:@|a_\=?D` {Pq<Z0-C$ פ/( 6Oc2-AD"3-nnO w f|(lÉɪmy'J-n_c <$isssƗ ־ -Z8.l%0qUe(s VG"-A@n ߛu" w)ZpS`jy[+!&|Jp ;'/b24Wssshnw@3uZa)XrzJʸβ-Cv '#In T LF /͔ |3r ^Y֒f]MFϷ;aһkHweK-!?:Wa:42hטlnn-B ~%>V2$#dKpҸh)-I&-mb4 )<3D5(H=p*H-" wU hʖ0` 7 j"(d Rh^fff3"D" zxߣ͛Jl6 /%q0 yU#9Aatl^0 ```@/Wtff&fo`cccȓ:{0 3 SK[?q{غ<@aYY-D4`|d/-1`ݝ/JA~8S#t fg h!?E:\냢E3xPܣmDuRCvxkצ2ffGE4XPoTUdٮ3Dqbje:ǴzyӞ Zެ7NPULXL?ǐHu8Yg_4 OJzͲ1vBK?0CvF;7[Z(Ά333pDsؘysxqpxxj*ZJhɵC@\ZOb؝,짉bOa gffE 4X-ظd"Er92zBoX\=F[F/dY=̰53l/zi$bĤ/~OHu_ w袵zl6 y!6PloE﷣*؛`{q 7CM0<B ZR2&1xX:/AI1ؙA!㏕T*A2ȟigd4X]9Dkz9˰rk+} Fb9ȎbgnUis2UtV Vlnn^F3Gֈh-~gL#;9n'XЕDSiNa rOD `Gy TUf5x\oZ)9A 5)M װiq7QUӟ-kH#_7Ek# ˡT:}4n[9ċrU $DQO pbǎD"t:d>맦~Ga~C>Fd"R0 lsvJXvbsetҐKa2r2*Z+ad2yjjSxidkkX,"{:oE(ʕ+b蠕Vc]IfHHٱ Cq8>]QH&\ LMMh!^F,lmm}7 {l6Zj uT^C%hb| 5$p8B!3UFd228gjjJ`'`1bkk{hAT*!v0xT^e"wlCq8Mt:D"!ZJP-HŐcu˲Q.}mxqUΖ1xTF)_0ܭj<|&\&@ LyCSSS?.Z_1[[[E az flV Q KWQj|&#-H$!Ηg2D,iX QT`^=t?AP{j%?NUDLLTTut^"4X.%H8BbLB|/֠ڲSVQcW*櫌꽠*$R|:?i\bkkKo|h-Aò,r9eRȠ8!Q"2E5BJT9 U+trč'F`֖!MN -$ѪDRr:BL J%ZH_SDki( (ːEdEA<G*˅wT|t"G&Z$c6Ţ.Z5`y޽Uan+e朹r F PT#(P 4܍{"*Z.1\I(.iD"4h$\J ew.;g۲ߜsOrr&}Ҥg ,4?#-Rl2mX.nNrOv=[n] <"{fl111%]1T-[L*6'r׬`H>x 8:tFRْb̼̪Py 89˽oDG+`rY8 /attT*rcAdT(ǀ=MC^ϔZ-UD"1Suik\NQ |>< :tWbbbbp5MHC3jddDTP垰"Kp|!`qF8ZZ׉!I$$ FGG$2pZ.{:, VYYXgFclj5u$f U"P{r8ڔq W^>Wu,W.r[P |>(YLMMQש4k&,H`P>Xgl6zNjWveJ"<fATBP( 7Xg`hh4h6Ⱦjbq]*LeQz6l6 V uoH8-[ X kǁ+PsKH|\f"ݣBa_"099I՚SSS30>bؼk3jG&s瀳;AT"P(_ ;*[s˔H@4lV"@+b QYDD" l6u1k{D= V Ӂ;ud?Z*XW(V_""X}ٙLfu% Jt.C]DlՁk2L0HǨ`Ɍbx$8CYL% ]f k 8""AfQ%;T,""ҧ^d2Z,١c-p0fGD?ת\hKvX,QDD=\d޶"MKX, YDDz.d2Y`PX,fۀoZg?d2u ,Ybx2p;:HhZ m.NӏYQ%+J{? č㈈t$kGtC0L*XJҡ/ZgCOMA$TcJ)|LHӏZp,i5p8blfVN tETq.*"Z>(%]U*ndEDot ^*XRYD$J"ᧂ%=S*^qD$:>u,Ro*8쀆bJHnt]׳#Ѣ%f<?.FHxL4su]L`9~ w?s]=0m*X7<[\|M#"~f," !DgM׻uToy: 4TDf\uQyjgW"Q/V]}:Ȯ`I`xp fqDwo^uwÈ, y+ y%p:@^EKA`p8 I iZY , r|,p%p"3lnri0"{JKB\.@8^ -l#)*XJrEJ8"-ojFT$rIh̃&8'7:3iGkT$2>wW2#%oV8aDzAK"\.ǀWNELtCx)qF"EK"\.s w:S#bEK\.u8Hw:u~%@\}֟`ORyD .T*)eD4[Kl/UR1<"}KKd* kex9^<_IR:PdTDR$? %_NRU<"%* |uXA^i xxs* HU*aZ'&٥TmIRu<"%EJefֱ'lIj!JcG$TDzu4~:86D&`#~zVT"%bR/Z_>eHd3 <<lL&{JDf`j?~њLCIkᗪɤ^,>UVWk-\CP1B2\*>%j5l<4tWm$Y ,Vp8j4c^9}O&eT"d*X"!SVcA/]=]Z)QdRcQj:?uKJm HmJ&ㆹDGTDj7~:p'l-PݓVD?`nUUٲ 9۾;@&@ l]ɤ]RiJ1|-,b#@^p-ގ~@}Uߛ`4htV!PfIENDB`jamulus-3.9.1+dfsg/src/res/CLEDRedBig.png0000644000175000017500000001676514340334543017045 0ustar vimervimerPNG  IHDRH-\zTXtRaw profile type exifxڭiv:rDc^a9|)T}\꧁I9DF$f-[S-bw~t6Ͽt߯<?g~@)}O}_1 =E?is=ť \|.$nr{g!lg{=|7!eKZ}UzX*wQKq>*ܯWe-9=>.;nߟMOo~ _B &^ \sqwvǛ2r/s34,6+,U̪&vi]vmCpI'rizw<^cWR>^'I>c>:<^g<'IKrrtܧ ~1>Y( ^U+D-;eVnҜkkƾZs+D+5'o&@yMۊ<6NuQ&g&m,VԺ'10@e@s\G9> % 1ǘ\L"g!++ gCҤ dH@$ӗӢ󻝵eb. L?@rO+:â5~k-߮|bx!3^- &t s$[YɮQ6) @͢'63b&\#$Ɂ8)G㸐  F#%&,XéN0&Ĭg ]܄#K=' []Y%4^x cu2+lœa8@ccN8ɴCe^G $9Y<-zqS&e&p`1+ݪs6$<妽?Njƒ)Qz5t{"<`L`쁖;ʋ zFB`ɀ Q\*>Bj<ocas=L@=E ҾA{Tm fhM j'JrT+~~Eԍ:Cޏr4#"!'gt1,jx Y`:~LK۠PmQ\.Sdž+rv ԠASjnη%EB:㱛ŧIH3k@٧< p ?%v:X`j~ú6x4|kDUR|8S:o 8h9"kk5y͈#B) v]Bk8cJ۔G8[9BYGT~;0K WgӻHE!YQ=_/)Ԍcs8Q",ҷx=j^RDR B Ph }ȌKAo ؏Po?&'^Uwfp$t&33dBQz;P]تՙ}(yk%nܑ.Ӗ@Ȫh'z)̋+}( G#>b;1:&TQ-bC) t(6fyQ rUqQbGE6Eel]u$u m|mz5XT!97x>f 9rނZo4mGh#Ko6&F@jAZLqr2PPE ״B_[LT5 -Y0ؼgTlߒۡZFL;" n~jQDBH?>;1E9Fah _aw^I٫sBo9Mj+C A_JxcXkSJy@$X)ōU'ʲ'@9h62@w &/_md|mUW&<%Q=]ԹN8$D(5vގVF OVDȬ_ 4H%F8AK֓ZLx^MG&ԦbIU&o$3,0TqC(<|37I*ǁF/0sō[)aH= PlQ+Q1ڠ7-cIxǥ`bV#RґFxHJXfJ*Mu JUbNC` =ѡ΄H MH ƦZP >ۉe*@(Ox6,ˈh'.v6\tݯv0Vwyſ5u}hHۛAa:U&f)6i0{(YS ';qDp dB2␯ ]"  ,6Eh:T?0"=JE 9??}o2@ *'g0)ysb|vh}xG^[AEu%VrJ=WîckZcomFq` Eg20i_z=PcGh4s.w (_CɀMOit`d CLhzjS5^&NQl"5Vp~KXVzH(K`4:UlI[VLs3@AE\{xݳJis4-{iGk*t(Z fxRze |h?e%Th|zIqqG<5:`ĩq Ug%7E[r` 轢\ IA(60y~تHNSV Xt8(fNIT` =ꘓލcb!$}3X3^Óe8ĭ <}{wejб7Gkz.l&2AFyM,R=شd,<"1(m E2qEh8ΘQlؠBf>8YL*z==;:9MRiK Pvc7H?jP?tf'pX:ua~`!rGYݱĪU(BA8-]8Vq(pFi t9$ rxNocMՁ@Q*N:mAMm\*m .MwS]ХZ v_D8^U)h0PwhCNRk 96=t-,ƤM`k 4++,-8dbzhO[g61`1 o_͹?f\ 5׉yRx:Ջ$"V LI6ί{agkЈY'*;+L=v 8Ԍ n^qu;m,=uzO*x#vh?hmf!,ݴaNzл o&m%Ԃ\=<I^tm#"lriFQRJ͇a} , ۶1 +"3LUfVJR}&OD2*IENDB`jamulus-3.9.1+dfsg/src/res/win-mainicon.ico0000644000175000017500000010324014340334543017620 0ustar vimervimer @V00 h&@  (Xg x h8PNG  IHDR\rfsRGBPeXIfMM*i&u74WYiTXtXML:com.adobe.xmp 1 L'Y>IDATx} |=a [dGHXDV%akkUk?h[X[kmmZ[ڄ(e5aHOK3޼|7s=sgQHD`{Q̉J"G-CQwEU;DQU%/&|EQUN*HQϐTJE-ut &:ta?FJ#03tg6%SQik ־(1ZT9) m#UݪMT|ָF& @=l]]HmX84f>_q(rM f@1sР?Z}#&J.0 vG4|٧)K L&Ԣ.Rm6ǪK )޷΄ZBHBqE圇)8Z.Bl vT&ED1{ٖ}M_N#ݨ2aJ$8ك<U$=@a:txa6hx\4޴ŠgªGVE ""ߘPc:~z !zP55U2Mpv׊+1*)GOڅvo<٩Bwgf+ dP|kvTc|ЦlB1-x"RAޠK!هf  {vP/F=\CsC2_FV &`5VTUTt>!v2`:eo,n:=9 ^Q_(x>}Lz[BUa aѳX~`xUdb]P_{k#S3}|Lm-GҚ @g>]/[d"t숣dP#P}}SYGHuO ۠Cg.Һ3j鋄Jof5wO$; kQ)"+-+.U?JJAH3`XٖjS\pebntہJjҊFFpƜ_q꘹*oԉdBZC=ً od1\rnܕu&<0u{N˻ѹSfe66ͼ;ii$0QaϡCλsP:M:yq#UL}s^֦@C+_@#>l=OzI"tkf׶4 5\I]soìoΊP[neZjx}6tofOQĕk8I/APXs \EyE(f 9_0;a/Ng>O[U&Q(& 9ߥ=F}MB>mmG镽' `903t<|YnhMo9kz˵7jq--3 @]u1KYH239Wd\_.1B`G `4 aC/#0?[b% ^w~s9-rM߉݋c^bOj:[-yм!;7?? ɬȤ(D:ISS8"ө/6rǕ=ϯ3Ɇs#Ne(@Ӹ$zhU+y^,oĄ&.(6,\Dw¿s0SoOyߏ5L|lz tU_)ۄ4ʳl)PV}_z[-^sxDCf)V5]d&쳟{IS(x_~=Z#/3_P_+@CIIA~~ De})NQobR/Z\4ߏq[XZ:{j@%/@8Tu9e'@]K&< 5~t|?9] =K#z @zF_sÏگe tt ݴRQY]M ryM}Xӱ??}s,89*vk267X:u^ ǛWk3Q#>q!OΒpu>/нڴ__vڇco?Uc55/f\Nqtb5ʓo~EC:੐z>/Կ[[kz}~Q 1>q S08YR>|ߋbH2Pr&7 "kb il`nZg̥*[z8< NzKodӾP~NAQ?b\&ޮ>]lu&pڍcB RtWl(W:Żf/>wW[WJD2hPTbHU^d@gΗc|rZZ67i0lX+ 8 qVYh5u\޿ ycd zӗ;nzjз]mMMB<ų*>qGfhO1F< Lׁ;Ie)@Cg-)͛G)oD,ݔ`Jʭ1έk;[>ºPX8 =2kJ_)94^? ~_MHĂIs3uDl*Ƕom uL.<ԍoLTRj~0Elps+GN { I#ۂL_D;w"#hAa7îk2ݽ85PHg$vXoDȽӸ+V|-"H;݋oPBJaٽddbHX͔^c=V4 `-)'y_b*Pm;NwjvW 9n0-@.Xag!g0͑k>໮sSu+ =5ofH2ܔt:sEUEiygtmG,,瞯/S 2 `fg6ϐi u~WltkGУcxJN|s ziK~ dl)\ Sp>2-q 㢗 ,GUZ?o[( MI񔎇 =lB*F>fC?zl}hbC3cV޷Ι 틔)My= Nx8}<-"Hӏ_ޑ SY܄F__ic1G#Fv7tnC3Ҩ?Y~׃х:8 g-EJyâ!hN[i79`;@~cvذb6WdVah gIdAC W;0y/% y!& ^vMg>( `f~< Cc1-e'7\Ց8̒$//bm#g5Yq_|4up1 l$Ȧ gpu7 5D ; 3{1gŕP!_>6MMaeb8]iްfd>P"E:/.87~è}l4{uw!]Qg6O,~cyK Fx3@( /b_;GfD^~oQ45NWZ)~)Ԕ? DZrCB9GP3SW }2h2*ki3DFhf6UbkkJi`l-m6T@(}Fj5gL9sayL?ۗ:H>L&jc~@)?}Mm3oT_|xxQ 4ҭ>,&csh3t)J+io>#N'}|F0edϯ{ǝAE)Mx]Vfo6-oc"ҝ'Yi(]93;!{ MIy )wyؿ%ǺHVLcm HVXuwlz󕷽 \36쩥;6A&׏2[Ϳgb0|P?B<!o8S b+mcq{j(8VT"P\ {8̢ ߷K\uFb.(RHZiBpX|(y\&V epR !O?g!`\n*pS|XEoTB\%fKǐC}K]_^RoWg/zXhNmQ*̝2v9b`*47t˼B0'k Қ݈B.D|C-h8RVp8I{.7Qe]6ЁE~7^q毂s@J&eκ݈9F@9*DH7hT%QlٙjB}<\IС7zPk%lSO-SajܸOߜEMd1vIbmB3\5C`ˏtm?8Qc>`g!6kL˛0Db(VU,N`撒;?QOk^yٸf%<2] a$6] wg>T~ۄя0^2 1[PR[੗1H28x<܄7z..iv|;˗ ,BB eLmH9*fƅ!Aƚ RBL b^53<} \1#9"(vc-I4F y3]90þ4|N! T@.jbQd%.3UPzfS(|-BuMIY3Ղj\X!;@Uydq 6@:KR`G[_S<ſ1-uҨWZ+l.A[E ~gR똔 F{&rl-`_z!lսm^}Y7}|272Og`g4~ _s_•e qOdonNr/8&:hl:}E ~FGRs ",]Ug,jA 90żW{?R$]'qE#;K9^] #F5n`9}jSh9Nh I-ȴ@?c-Ovb4șPcoם'Iuo}A ~xeH71AD{)%ǫgBU YΛZSL6<ks= ~zc#M7 N061ySz(H ~"90EPq[sv8kjH 74䭄XKB$Kg܆GOs\ m~@I犖X-58XyVG6kv33D4%@b ~]hpכ_UFHN? Xʸo`-[m;ZIb@1 Ʀ~r@D;+wj:w?,'4$`]_׆ߟ.|'&l)zU5qgQOoWNًziɶ ~4I@([^aЪ?wH'Lソ:]-}稘Њa%D_(no9AZLRւ9GOCjmLoN0~{;^rcСއG[̌gG*Xvkѿ؜@&D/9;]T1cmrF3c=O/N : ~BGc]5Nm1R//Tz޷]ko0E%:F]Í7#~P&"ym7,'m'ԂYn9MH˱7fDDXqOs6PVDq.Ac@GHI@ pWӫ[91_.Wy>)"SF jIjs\ IˠR TUqWق?u4!@l@[;mHlINS׭?±YZ_u-G1qQ3o.<_K~CJqPRgLo8&Y< `N8V}iuZ1eYbK-^=څyV-RL"` qz+-~j܈isR]TlÂ/Z.P((!/>A3M͇8 Ebo7)٧jR -RݽтpP\LjN@s(%a /6cӈxX7Oм$`Qoe6T!o: .Aٗi]Rh&Ah*MoROҚ~i6#柺f\F0%Ќ|e={Pz<;{Ρb #;գTOwF?kӔ'< VLցM _ 1Bh@x[N4p RU@۴_4C;}XoXOJt6T%8f<~:Y-Js϶Eb\j|t .i#*2pCPfONsbB b5E³v @9zA0  < psTz4Fs7@"!-^קfwʵ\yF$<tȞaMB4-ܟX (ڠApԈ?YEGZ н7^테R v%FQ *Sk VE|SJH3 " dC M;0ݟҿSH+h} hb$Y=%{I"O7}]O@_P7SI>u(=>~1p\u[KS:J/Ha6!T$5%"2/7 qnOߌg#3g[Η @ ZKX 6}Z;dPR|plBr1b&?,p@an|6ZW*9c>9~ e؄3@I%pl'4/<*f>GCl{C PI-{;ĸccg@ 2mdہG&]TUy,7G + Gfu=>~$ܬr@Ct[QLdH5]O4d]@zτ ]zG; =/w7֭9ЪM2hJi味Q%rWNxIb)b6aC5pۏ'rI*-}mEju7P[>]Q"XKכБ2D bԅg -\rcMjk! \]h`eyad/ n4Y=j.ThȌߧ_@SPd3&˔X6.Cs5 -@<)ySNp9cvI&D%>`U믉Uuk-@A^Kָ&2|H&`&²pC`LTj+Yx`75Df;$d6Ҳp@ Y= vEtE-hHLY@(`L*C\VLۡ(Q32Cʿu1k K>Wq}뙪)Upho$6b{ BOVťBuFGt:RWdg]j0! ut^+9LuÐ /^.,N\?fF"ǁpU^5OcCꥡ>Oeb ƁSt۩87I8WиҲ+_湶T^Kq1w d/N^];KYbUyw&5+٬x,(^9MklxR~:I:& JlEː|#9ɆzI&hJOPh/Z3 xPg6Y_˩.>]6~y@Dw*ύDЇTڥ/(&]03&ch@dl[0bi3Tg5O܉e0z{ z=F4f"~8DzfF%B$mBHWAZNYaBE"f } 8x=j7 : `C:!vԀ;Qo:|>8^i4o'L'K/w2!f-|?vDX%4KJXĻǗ T %%,zbl_rGCW,t_ءQ$ūiF5& U#``:& Gga*9*~zC:cw%H>=H!11lED-eRvi`$ծuCHg6\/A$oOE5mLYR@)9tA)h19Zuf:EVO]ءu<ᘌ/t7~~ԅZ:~wN=Ww}Bٖho9ށIj05B7ƅ\q:ñ5B8%usL4/F4ƾ|y]=<7bPZ\ӓcG>EM*CW?M 00Ao@+7ih3IC$3>朢Х}wSXzć_HB~>hzY>oD-W,BGdJ!sCs(Ra,7%R=wKޑPd/?0P FT`W`ٍ6$$2'4@11T!`8-$-WR30{E uvzf>J\" {q-*© Xm0#ߎzQ8k~g=ώT'Ekp/8V! $MMhBF{ӡup^b-fަ3[7Wf,):~-$Ag[&f&-Ӱo؁xb8g>W\ ʳ8nŤ1!I4=)=%P'-֝?v+ sr6^MT7ѫLP:gqj`#@CvB2 9z3wXj n)΃7hvzg^ j]^Z-g;!6>))9l;:x~YX()0w?d-F g ?z*+4fZ"/xpUfOc cp//.c@=,ov( It)GPqץ|}oJ}ï/sYT%]h;3NP,zĘ?ּg^%nw< F_y 8>"/됻ԯݓ,[†8;95cX.Z'uy?O2☷w(x[*jh%Yu6նc܏kelJ(˪jqÅRl!< kOa\;e|;qAIpl Wύؙ~.:t"piY~ #8e9~ nZ9 */+Ko:ߍKv[o N+~EpEXz8;#_7󲶹b`9fZR(O!?RG,p(~M ۉupl W7|k_8xMUǜ|ؿ2Y7fJA^ݿS IkF9jlv-c_<"(E}lSc䍭i-,(z !P֠FQkxC!ҒȡNr(C1؆Ng_YM_`J#|K:}Yػ25lIAnIU_+׼5?sH%A yX _ ŦfIt$(x/26:Nr€?FPiBmiT*"7jE-Zʔi]/jS\4 R]9WWaCtY5;~-:tt[LO+%Ѓi%inȋzre!i\X@P6sk difP//Fk|IDB Gm Ժ ZbxW` &eGqI# ˰7MtBxCG3oaYd7J¯3_D(dCgϐüg^?'gaY{^49:.h_6Vmb%۵XG2Qd>5_QP{݅O_{~ݖ @/2.Xi(JQ pæ/#*hʲ/QUP@zZ_r) xG ,QJ\)lV_2ۿCu{ed8\y#ے@ u-, D=D˱H>lPQzj6m@<,Zڊݤ]H5QS[!|e_p/̻Z'gV{"=^h MX9\o5qnev6#=Qhd@Ya m4 }7/BюU毎W/tɔN\d* #AՌ;I^ ~Ԛz o"13nX7IuZd+ &1F2莯s:3)_$v}Hr !Kq$ۣ]m/^7yr3C(?IENDB`(0` ЪL̫Md̫M̫M̫M̫M̫M̫M̫MͪLWɮQıN ̫Md̫N̫M̫M̫M̫M̫M̫M̫M̫M̫M̫MͫNR۶IϧP ̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M˫MɮQȤIϬL%˭N;˫MI˪NNͬKG˪L6̪MƪU ˭K"˫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M˫MɮQƪGͫML̫MͫL̫M̫M̫M̫M̫M̫M̫M̫M̪M~ΪL9ƪU ϯPͪM̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫MͫMժU̦M̬Lh̪M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫MˬLJ̪Mx̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫MͫNRU̫MF˪M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫L˪K˪J˪J˪J˪K̫L̫M̫M̫M̫M̫M̫M̪MɮQ̳M ͪLu̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̪K̫Lб\׼tŅȊăպoϰX̪K̪L̫M̫M̫M̫M̫MͪLWıN ̬N̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫L̫LԹk׬ѠҴb˪K̫M̫M̫M̫M̬M@ˬN̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫L̪K̪K̪L̫L̫M̫M̫M̫M̫M̫M̫M̫M̫LͭQ̖ă̫M̫M̫M̫M̫MͬLk̫M̫M̫M̫M̫M̫M̫M̪L˪J̫MήTѳ^Ӷfӷhҵdб[ͭR˪K˪J̫L̫M̫M̫M̫MͬPӤȍ̫L̫M̫M̫M̬O7̫N̫M̫M̫M̫M̫M˪K̫Mҵcȋ۵֪бZ˪K̪L̫M˪KNj׼s˪K̫M̫M̳M ͪM̫M̫M̫M̫M̫L̫LԹkدϛѳ_˩JҴaͭQ̫M̫MͬLM̫M̫M̫M̫M̪KϯWО͗ڳԷi̪K̫M۶IˬM̫M̫M̫M˪KҴbѳ_̪L̫MͪK3̫M̫M̫M̪Kҵc֪̫M̫M̫Md̫Mt̫M̫M̫LϰXӶf̪K˫MЪL̫M̫M̫M̫MҢ׼sݸă̪K̫M̫Md̫M̫M˪KչlήTͬPĄƉ̫M̫M̫NժU ̫M̫M̫L֫ήT̫L˪Kв]ӤȌ˪K̫MͫM̪M̫M̫Lв\ͭS̫M̫M̪L̫Lֻpը̬O̫MͫLıN ̫M˪KؾwͬQ̫M̫M̫MͬPֻpNj̪K̫MͬLk̫M˪JNj̬O̪L̪L˪K€Ըi̪K̪MɪM!̫M˪JÁ̫LҵcѴa˪KӶfܶͬO̫M̫Mw̫M̪Kӷhϛ޼ͭQ˪KϜּr˪K̫MȦN̬M̫MήT}˩IѲ^̪֫L̫M̬MPʪM?̫M˪KΚήT˪JʑϰY̫L̫MıN ̪N̪LҵdΙթņ˩JϰXֻp˪K˫M̬N_̫M̪Lџ׭˩I̪Lб[Ą޼ϰX˩JƇƇ˪J̫MɮQͫM̫Lб[ͭS̫M̫L˩I̬NӶg͗˓˪KήT͗˪J̫MͬLM̫M˪Kֻq׽u˪KͬOв\̬O˩I˩JήTؾwƉͭR˪J}П˪J̫M@̬M̫M̪K~ٰ̫MͬOթ޼ÁбZ˪K˩I̪L̫M̫MͭQ߾Κ˪J̫MƪGˬM̫M̪Lؿzҵc˩IĄԦֻqͭR˪J̪L˪J׾vȌ˪J̫MЪL̫N̫M˪KӶf޺̖˩JϰX˒ҵd̫Mֻp׾v˪K̪MȦN̫N̫M̪KͭQίV˪JϛѲ^̫L̫N̳M ̪Ni̫M̫M˪KͭQպn͗޻~˩IӶfݹ̫N̫MͫLaͨK)̬L̫N̫M˪K˪J̫MͭSֻpݹ̫N̫N۵€˪K̬NͪN$UͨK)̫Ns̪N̫N̫M̫L̪LӥԸi˩IzήU̫L̫MƪU ̨P#˫MIͪM̪LѴaџ˩IϯW{˪K̫M˪L6ͪLW̫M˪KăؿxŅӥ̫N̫M̬NUƪU ͫL̫M̫NϜ޻ίV̫L˫MέJɪM!˫M̫LͬQџ޻бZ̪L̫M̫MFʭM5̫M̫L̬OȌԥίV̪L̫M˫L^̬O7̪M̫M̪KԸjܷ{̫N̫L̫M˫L^˪N'ͪM̫M̪KͬOֻq֪ݹ€ήU˪K̫M̫N˪NE̪U˪Nl̫M̫M˪K̪LϰXպnŅ͖ПϚȌ׾vѳ^̫N˪K̫L̫M̬NέJ˭K"̫Ny˫M̫M̫L˪K˪J˪J˪J˪J˪J˪K̫L̫M̬N̫MʭM5@ȦNͪLQͬL̪M̫M̫M̫M̫M̫M̫M̫NͫLąP#U( @ ʬM+̫M̪M̫M̫M̫MͪL̬N_̪U̙f̬N_̬N̫M̫M̫M̫M̫M̫M̫MͪM̬M(̳M ήL/ˬMY̫Mw̫MͫMz̬N_ʭM5ȤI̫Mm̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫MͨK)ϯP˪M]̪N̫M̫M̫M̫M̫M̫M̫M̫N̪Ni̫NU̫M̫M̫M̫M̫M̫L̫L̫M̫M̫M̫M̫M̫NȤI̬O7˫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫L˪K̫NίVϰXͭR̪K̪K̫M̫M̫M̬N_̬MP̬M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̪LήTņ߼ԦԹk̫L̫M̫M̫MͬKG̫M̫M̫M̫M̫L˪J˪K̫M̬O̫N˪K˪J̪L̫M̫M̪LҴaʑ̬N̫M̫M˭K"̪M̫M̫M̫L̪LѲ]ăզ߼֪ƈҵb̫M˪KϯVƈ˪K̫M̬N̫M̫M˪Kв\џ׫ӷgΘбZ̫LˬN1̬M̫M̪KּqҴb̪K̬M̫M˪Kּr۴̬O̫M̪M̪LѲ]ٯӶe̪KʬM+̫M̪LџؿyϰYӣպo˪K˫L^̫LбZؾx˩I̫Lֻoݸ̬O˫LɮQ˪Jּr׽s˩I̪Lպmɍ̪KˬNb˪Jؾwֻpѳ_̬O̓Ӷe˪JΧN˪Kҵb{ϰYӣ̪K˪Mc̫MͬPͭQȍϰX̪L˭N;˪J€޻lj߽ņήTպn˪J̙f̬KͭR޻ОʨH̬NӶfΘίVĂÀ˩JͬN.̪KҵcϰWб[ֻoͭQͭRֻqб[ͭRņ˩JˬMY˪KԸiÁб[͕ҵd̫N˩Hؿy~˩JUͬLe˪Kв]֪̫Nԥ޻ĂljԸj̪K̪NK̪L̫MԸjОԸjԹkίU̬LȭI̪Mx˪L˪KͬPϰYܵӤ̫NΘ˪KͪLWΪI˪NE̫Ny˪JԹkϰXƇѲ]̪MƪGͫMp̪L˓۴߽˪KͫNR̪U̫MͬPҡɍ̫MͫMժUϧP ͪLͬPɎ̫M˫MɮQέJ̬L̪KӶeӣΙѲ]˪KͫMƪGժU ̫Md˪K̪KϰWպm€Ƈ~ԹkίU˪K̪LͪLQժUΧN̫MdͫL˪J˩J˩J˩J˪K̬LͪLWƪG(0 ժU ͬLe̫M̫M̫M̫N̫M̬M(̪UɨJ&̭M2̪O-ʪJ@ҥK̫N̫M̫M̫M̫M̫M̫M̫NͫK=ˮK,˫M̫M̫M̫M̫M̫MͬM̪NK̫M̫M̫M̫L˪K˪K̪L̫M̫M̫M̬M(ƪU ̫Mm̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̫M̪KϰYպn׼rҵb̬N̪L̫M̫M@˫M̫M̫M̫L˪J˪J˪K˪J˪J̪K̫M̫LͭQˑ۳ҵc̪L̬MͪNf̫M̫L˪Kб[~М֩ӣNJӷf̫N̪Lўѳ^̪L̬M(̫M̪LήT̓ڱɍΙ˪J̫M̫LϰXݸʑ˪I̪MͬOجбZʩIe˪K׽tѳ_ƇӶdʩJѢF ˪KըϰW˩I׼sӶe˩J̫M޺ҵbήTӢ޺ͭQ˩I;˩JННպo׾v˩IʩIջoӷg׫ӣ˪JʪJ0̬Oخб[ӷgΗҡӷg̬N̫Isѳ]ؾwҶdzѴaӷg̫MҠͬPժU ʪKѴ`޹ڲԸiџչk׽tݸ̫MȤI˩JͭR~ݷӶfܵ̓˪HU˩I;˨I̫MίVΙ͗ؾwӶe˩IvUȦN˨HgϰXÀΙ̪LέJ@˪IԹkٰήT˪LTʪJ˪KӶf߻ΙήT̩JnU̦M˫KͭQ׽uӣݸ̔Ӷe̪L˩JS@@˩I;˩J̪J̫NͬP̫M˩I˩Iv̪M(  ժU@ʬM+ͪM̫M̫M̫M̪NKժU ˫MO̫M̫M̫NͫMz˪NE˪M̪L˪J˪J˪K̬M̪NKϧP ̫M̫L˪K˪J˪J˪K̫M̫LӶfˑΗ׽s̬O̫MΪIͫL˪KϰXؿxȌƆԹj̫NؿyΗ̫NͫMz̫MÁҴa˪KĂܶήTϱYܶպnӶe˥G6պnܵήT׫ɎɧHcҵb߼˓г\̪KҡМϙăּqħEв\߻զؾv˒ԸjÀؾv˪H'б[͗ƈӶfå<ʩH\ίUĂ͖ٯˬN@̬MџҶf̦F(åKέSɎٯӸf̪H<@ ʩIeв[ּqؾvӶf̭OˣA'jamulus-3.9.1+dfsg/src/res/HLEDBlackSrc.png0000644000175000017500000004465414340334543017400 0ustar vimervimerPNG  IHDRX,=͖bKGD pHYs B(xtIME 7] IDATxyա7ߩfYfXEEAD!k1o&7UD&y<75Ax|DQ"FqAfefz!iz{z3MuwZ~}ΩsNZthkk+P(J#(R @%*e<|bID9F9{^>^N8"hRvJ);tTUUu EIp*sp%CDVI)w!^]vY, X~i|_ =Ҿ `*XZd G EQرXZYO<~?BLR~R^Ԉ,`r}!;wEQ.ضm[,gypB\EQc"""ɥ.,XP O?4K$`7oޕB?p4&\ꫯ2a1`݂ - /`ҥ Xa޼yŊ<2qM~kub*珐R~NDD4B)۶mk, /5H)Wrľ5B߶|>zzzӃ@ `0@ 2$Y#TYjY jJ'@$yhJ%ܥI*}.l_QU6 trv'.yLRܾ}|f'o/V~o(G G{{;|>t]UsCU=ЄLTk 4٬K3}0`g]pvnfbzPU[l٢mz|hmmEggg fc`2-Te(Ʉe3 q\.uI$ m\&#g3XGmL5}4MCww7Cp8PVVB:% |۠EUSQx^~eEXKZ󟕚!YlԖ  ɬG*_D2Q3j|FFVii)JJJ]d `fH6ZL%  TsaQ]] ˕1)巷o X&{饗d̟?Φ*҂~TQRReF&|mK3-tB|:5}NJ UUrxPRR2?f֭x,,X??Χ(z8z()]ʬTMkL /:g]FتΧ+=ւ )p1E?ך;fVMMM\?+\̀%Ơd , /lhiiAkkkoU.B8N j~v-U>@ٺ%{M6Ȅ1zd2$'2}ޱHeKdRfTE>tEEE9=eŭ[^/+_ PjhhPvZ_t]ESS-ӷ*|-hiiT9DDQ8՝rpvn;Xz mݺ5:@v}'ٹ~P9[%\)5ߏȑ#p8 JyWSȗx͆~;v `ȑsrָpnN\XM6aբ\+܌VAS\.W}xv$"ʢz@ooo&Xp:ڬt]ӟTυœi"\pzT^z2ft?~<%" F傮)J:JKKQQQݞkAO[n&V4'… sC{oo/oJ'C)%N83Q8Ӣ IUUUVTnj,^x,] .̹8pEEERg)"<0e&t8Zx|8,30*~?6mox<kˆ#,۶m;ʀŢEZB Ǝlf1cfaԨQf uy2EQl6(ߏf466B4SguVh TC;UUp8\ut˖-#NڴinUOu477gmfٳ!G0ٓ(ENxL4i V@>>G?v%vE裏2dgFS`MM .\Ț(""`ƍYy:8΄U#I)Q\\aÆYnٲfW´uw;ĢEVXmOIQMn;kUUUU¤IPZZ@ pEDd"c/8x N4V p8P[[k W`UUͪѣG3:hh6׿˅͈,tp'淺:\ `fÈ#/+i[n=` /^uj޽k'NČ38Qؿ?y睌nmm-nwڧBU׋6芢Tnڴӌ7WMj]UU ޽{חb>|xȾ5 'ND?Ą 0yd>|~an2欝4iR&5#GPYYR"`o-[`ѢE`whχ?83uHs٘2e ^/BDDyNǃ_~9[`+⥔\+כ7oK/%Kgŋh~i^/́ո袋XKEDDת{7{-#XDYYBic^~|Ϭ͛7WUj ?fIp &;eL> tDD{v;ڰk׮fL0!j2,8I)QVV*N);{K.yq!jz]2.7wQLOBU߆r[&KM6g9s%%%߿i+)%:::2͘1SLDD!/RZ3uԨףD:j5YvbÆ CFP͛%%%X)\ !o>l6N8v3g:L0ኈҢiJKKo|K.MuكS:GVE^ٙ$T[m-YxR۷'NH;\{.Ǝ˳ ?~aJ9r$JJJV'|555(**LyH)޼ys6`]z.MӺaEEqѴUII :KKKtRH)9eϧFa!]SFuimڴw|(^+@Ӵg`ڏ9•1>U_|1  BӴP+2CDD_uN]w<̔^cϞ=p:sǭToضmې`]r%ӄY$;;;w޴LNѣGsQNDDOȀ0Zѣ-S6휍73m6u]GP^~iZ*!."sP"" Ӊ 64i V,ÁZf*2bʕ]tHj/^ ?B~{PZCӝOkᝁDDdIƐJϝ:u*+#\E-cuӦMf<`]|ŵ4Y}]jՂ P\\̣,rOS;3 T—ÇLw)͛7dںu+.\ŋ ` lϞ=Ki0pe!31=a^x!N6픻 ᫮*3K/-z饗dk,XxT]J)Sjƒ%KxQQU6lHySNE  Vnȑ#2lڴ飌} ]{vK)MI1R7oQ#""Jݻh4PE ^%%%f:;;wڕ'5SkqԄ!Ñ#G9\.%HDDysᅬG&u 7{v]`}&^,c &LxY<:]{ %H)\]x(**DD7t]GMM =b---(++KOUww7< ۷yLȒ%KVXaf(O?)=? &($"'رo5kVJck igx ̞=mrDSSS直I=gG^}}=|>_•o) m̙3S&Œ%KBnfI)^UUqs2\QAٱcGR˟uY MoTU#GBS޸qzt|饗R6[)TܹsyQlxW^tbܸqqUcF%IqqU G)>VrEQؘrmR*w Q!4 >vڕ~^w{{{`=Ku]5s}>}ݔXHSrqe""*h. ۷oOxɓ'"1 5n=s)r g}!=)|>?Ohy?`X~x^@`-d%`mܸ^z)|լ 6}>_5Jv=M+**,HDD2ဵ~ >1UdBX"` w6l؀e˖%Ĕ.mNzHT9s&Qݎo /g?n _(//7֍7NII%K)cV2mmm /?k֬DDD4P23L2%f VF@(zꋕt( ¶6$]ɆiӦ!""EQȿ#Wgg'LŒR.! XB7k8x`*|j䝏DD4T̙_=eك3f  Ǽ^osf:dVRWޥK6aرcؿҁ!DG%""/OtR袢"~qCUxBvG$2wÆ '|5X?3k8t*--M*`;6ᝄI&>Hh^nE TReM?$|+amgEEEpqqttt$ܣG&6+tl$"-:8===(//z, 1iҤ_ݻ7p VMM%fm ɚ8q"kXgggԚ/Fe1fvi7/ʂDZlm߿ǎKftȑ#I!֌gGkkkRM3f̀i c}eee(++3wʕŋ-J?`}'я~4[flof:'۱}ɡ6^"""JHEh;AKKˀ!c mmmIWMM  &4̚5 `p H)Q[[kjgw]k6lLt@---2 :5eNDD44~D HՅ ӶQQ$_3c\%sa`ݝ遈LmbBXf̘p볕%tB|DŽ$3ѝpTrbg""2 NX:]XW\qRJ{R48q"d't6A6wjX~̈́Ǭ}yzJ(`I)7c-p>n̓DDa_nM9wuv IDATURʨ!񘹙H,`c'4(H9`5q>M"x4M XՌaLt!6yf\r%pFNJ9Sz/6 YO?=f@3QYm /.]u\+{NGg}uj[ }.{/l UD8묳NrUUUNI)>?6P]M( C*0X:B6Q (**Boood\+{{{QSSc]n~Rl(װtO"*|oڨR XT\y#^N|d(jZa -dZip9 Ua G&27̙B+vyS .2T?&āxFf9̑kٲefDDD'+v}(ʂlW)PEDDDUd31/XRʩ^s Ec2"""*1GVpKóB#p gDDDDCQS4rA\bf`4/Fp0` uJ " k.f+)%(J "H3aYVd54M;7k` .jŠ,@ =@EfCdV 0PАL <|:"""*!e‣ ,? I"}1^KJij]Ƭ׉*/""]w*MLZO1ԋ.H!抢m52PnYDDDU`<p8ZZYYYz  ѝ U˙V**"""&* EhNV0̈́DDD.!ED*1#}Fl"""%@KX)+d (`̈́XPlVD \ቔWDDD-/ -t]f3k5KT.3g*>"""hj&UYPEDDDɆf|6SL X UDDDh]KhRQU!D(-p$D43kH)U*k9tQ*L* &J%Qa5@䀣&WUlj;*"""JTxL N"̓DDDMdmhYnG T UDDDjO lN^ǠEDDD"31-jzT~W"DZ """SF &ڀQ^ +'k(Jxz=۔R;𕈙4X2]fFcZuuuܳ X24m*l+ " #'""oHU~W ]C*VmE+xYUpČvm&4=V ”1ަUEQ1,Bqq1zzz ܳ(jn'f3{RJoUJ*YEDDDRUUX.k`5X""""v~X݊Ìw7]NlhO%"""̝;wP>ēMREQp7P\5{Q*//§`+~Bq:`EI| `T"""2Q"wvӻP|I REEE1ic' ,""i)3DfpFs'1k.,)%*++$hԸ{Q)..F̼lvƉ5]НDDDTJJJbv! Ơ(%ѱiJKKaNcQDDDT8ch3}5XvMVrEwP$巺-[5X>PZn] 3V$|"X~ VDDD+֜FV0BxI?O? X'3Be4i4""P__`0e+ `xߌ5xC; Xw DI˘1cB-[؍XᏅ` ֔)S ¬´XhczXXnB/M60`SO=uTeVx<Z YDDD?z cb=3ן2#NOv#F/TJDDD0wS`݂NmA֮|7c3g5+5Mg=(]uUI-oFf:NyPwiZCUUh T^GDDD?-0(¤\Ӊ'TxjfzDDD9NC0L9EEEb]멧z@+*DEEv)Uv3WL. >{,Q6e{!ďmẀGatYƍ.C6lX"""1cƀ푡*|q)%uֽ駟&&OllJP]] 5TEm|`MDDD7jԨSƿ4ƱȈog| ۸'ފSD&$DDDֵxPU"/g{¸&wN:`=O!cǎ(Ll#L6{0h8q\nݺJ;`NڄO LDDd1ƝƸv-1U x!XofRl&LYfqO&""͖TUf8>,uEe7[*Ə?hF}G,b4-8~]wݵ{ĉ,ذaR-R:}le^}}=JJJ'!tG]]]B &<|UU8&aԨQ: vi>}:l"""Er0n*vyg *n"""եԇ*C3ؾf͚W$E78kzDDDY*9眤t:a- BL,O-7UUU-P ^F]%""khhHceeeV 44 E[)ĉj0C|hRTUeѵ'Yn;!pQ?K}Vz*,!kȑ8|p-`u]ODDf͂I%)4Mۚ쓒I={V~ԨQ(++/>J,}뉈ŋSz^YYeAJui>/逵~}@6ƍ4\`j3{?0aBJEfMh_–\ccEk貲2L2GQM<9UTTXfDFnO;`t] /D]]*#TE2U#e_w̏ʠBT OUBք Nkh;GQ2ZBׯg=` +X%ea„ tfd@މ4|ޔAQ+mΣ<9-yǏ*%Q]]R?'Zax4 3fADD??+eR?~̴;@U eɰlc5F%ĬYx%ꫯNzvlOX3a 1b)DDD Zl@ϓRjN֋dl }{A6+MMMhjj:h˅ȡԩ(8txq9砮.AӉ 7ܑdoJH)Q[[*I0Z-)%FmvDDD3z&s6黙z%҇>yd8SB5δi,5\?\ve)!9 'ֳ> EQ,C3τBUƏREDDDa괆VҀ',?9ci Xƣ>1-VnwJCi=(\y)=fYuhˣ>Isss^0ckƯ[)@UUjkkڎXD}Va(ipRUYYi~W?H8+$$3N̙3V*2|> Ug| ""BW騪:eJ_:n7fϞͣUW]V0lVgB;6wI)jŒsDDFGL+C1X8\麮/3ͅ[~ 7.;ؿ8qˣLii)-Z $( ]-*`C=tЬ0-`C tM7麾;>C HbϞ=< QF]|(++K{Pp8:`kVXn{0WvO>>/`k>8qg""JˤI2҉=FEE z衕fb 455\qu'5Wad'ߥR{.xv "Sg,I)QVVrˇ+!g8]\+Bn&+v>|`0 -`Ν<[QB.] ]3z+//ף>HjBlυYu~)z{{ T288̙@ zg""K/]2faذa1{u,K>M7t.7smokkO*'Zb-( o>tttlBDD9s&Ǝ M2^xPVV s|] XX|R !ۋ/nrG;vBDTϟaÆ?㯭( *++t:s)\>- ZZ7tqB;v MMMUS UBZGG>Cm\UUfϞ }膍̕!"c0ɐ+wbÇ6+@҂#Gg!"x4߀qi< w *ы*Z-/`_4Bf`vTӴi=PK^]Ӻ?0@ zN/5ZK"Щ^N-T UV T UCЕv;<O>]}|057go9#a!F¨QZ&Zsbp9|""~5%PxY5[nOfie]TS ^Y<^b\"gȡ,D*Z*)%t:a`**/qy{dX&]Wꁬ( Eoo/~̓~*F|37TjRؚqO)*S5U3U Nl9 ;LbUU*\.\.l6[ }ǏǰarՊ+꺾z{{꿕M^.ہ*\L^&CʬP5n.+ DBy}Ͽ9!pM7l,=$ y?jTf7E[&PZl@h@MZwFJUU8 b'_K)ߛ9˂~s?OY"DDt]f͚݅x`B7 `Ŋ5XR! eVEQ_jUs{{;*++Y" X[P-, ""* ^}EbDÇ#GK\u%W~,+ ?XGJDD ?W^Eef/}s\jժ[Y X2ܹ[B _ !\jՑfֲD?+*,""R?z<[~_Y X9[o*Y{z]C{ェR!"LHuP,4yokkcag"Ȟ[ou.K(g/lD9)/Y Xy[nP!"! kWZ%Y X[o.6KDD j*̀U&nkn0 lB$"x wVz׿/f0`Q+W/5EV¢`tttpmU`l*M[)s=mֆ*cʕp>3TR !s=oH(Kn[`-"\Bu{C6lXx.8]J9p,FK)Xj1?ǀEr TTTKNRs ?S"2K I;K)?B{キ)ֹ(Gvm(hR00 QZ!x kͱI)rrEQ*e<JRʑeBR)e 7/4(et !]RNmBv-BRy{:X3IeV(IENDB`jamulus-3.9.1+dfsg/src/res/fronticonserver.png0000644000175000017500000010032214340334543020470 0ustar vimervimerPNG  IHDRxtEXtSoftwareAdobe ImageReadyqe<uiTXtXML:com.adobe.xmp W |IDATxxT !!@hK # HG@ ((JHA4i{MofvQJ[λsϜ;ܙstAJGyKlv?3 dć○> 9:Ig~M.u}-&ט\el!w cI>KS+< $ _/09, кbL^KQ5&m oE(ږ=.Lb0yl dv)/GIer!&ؘ}";;6K%&5j!&x\frd5 P ɿgR.g{vnq<"=ge6L:ڝ~E&k,b}z :@إtT.C4d[="13 >8\2#HN2l㤒L۵]Z1I9oɷL&GAr]٥&v_";w`f*q5l"L>L ">#j$o`9_TB;3_L;F! ovq <%vL01VN&(륨LqB g'Yb~%/lg_癜drH{(0PUǝ-{VT ,eÏ5lmeB읯tKxG0i $ZiR$q iEEvyn͑Wd;{ašC4at"-FwfV'*ƣL6Yl~o'˃wsvӛHm <ڇLRJLVR {Gj؃A>w'/aov.t h?jg%m |&#!~~&o1;B=#xռ.Lö׃ /f4=/lP3{(P`ӭ[q? s3K^B _B!2 ww*ɪ611_viYi@=ǿg}"c>e7ԓcN^`g8ly  W'>^d cIhsu0i*~e9gg6ur>=`gU˼l&7ޝL+&0{A=z0 'm2oL= (ZHa=Ksٙpedr{d3G?e9t=/O:IE!S0G4dF3:xQAYa;K-MK9Ϲih–v}z!ox z'^V&?s?YF7*pGZs9`_S;NGVyy_ Ť-9\ve}]8~m-R8O<f 7|}|tmN狸x$'qTT4c$$#*:QQ?GG”D<<9/fj\0]95/f2J!JZ0=R[%7gWRhO Dș#BsD޼yP@~(a`0Jޮ;6p׮]+Wp]o޼ؘGyiOx|K{R45%u>03i LYaK1ÝgJ'lg=:\@X~.TŋGQ*+@ĭq8zN| +Uzp>|sy rj!Oݛ ۧ6FӣܿeD`t>+SϨ~-%`\$}:lK,",K-XDXMaUͨ;ziL%OuAC (ڹeDzZ冂??ҤQ ˢ˘Z&RL%`PpI~ ^*3py-(kLL2ܧWο Ԩ^o)SeįLBY\p2hKy:>)xmVQe7Si"s>JY[o9y*au[\\ITdJ&@NJzT_&ېOA%2ljpf(W2z|=zvNO չy&.U[^֙x3:fe zhPi嘮 r,<+J2Sd؞g¬=Ѳi |(Q8YF͘O8q()D}ovO+g?Q(6YeK!586=\r- 1 O=_Gc.ԩz=]yBk{$wTȦL.첏I%+4W0L|n\/&G`,deVض}>V-Xk4lfV~Q$nS!|J1)R" *oĕ+0|PO r29um[w@@ٜP;^J1\ʋt_3-2:sV+}}&"^IX|XbfwF&;fcR}*b:a#44u $"Á_G-irHb{FƤ?jKS@`{U²fçc>ǕiO8E aU8VI ?[,IV*I}Ci<%q^\=zVԶx~or>5\ػo'~Y !ȗE4lrl.IO >pGϗg>} Μ/o/©DD1nd%ȋ?`&=ET{T:Fˌ*E9 k7XgsEBHgFv`S%2ab /g據?HVxS9 cGٳ'ѰIB<%g^-Z"ôpHaˡMcTL0=_s^xYۿ X5UaJAH: @Ҿ$kp\\m T̟AB|VG;|Et=#cF:`At%'/܋M;|bWSNʿF &N\]G~bWlfcu榇{pxE{&+blSi?w+l.5hoe4*\g:> lҊ8nz6#-F~~-<[iBpU=?m--bcxe$IThζ0=5kXYnM\;y݀ ry@~Ǚ uɇѸϑ$,}+<jkWzڸt霢o|a:6J~_}lZi*@_W09P'٥\˗,Ef"\E\a] dE1p-S2~;y  iuÏ_dⷙnr>t֖lji/'oQ܍صkJ fbÔ d* A*X˴m6˥CsF~?#~sӕGx8r5!Ihزy#d43"';ThCݙӑή7_8=豣$ãӡVE 5LaŒֽ:2ǺK5˰CE6ϱf:K¶ yrV]uk7ol 'O=m&qx)7|'yJ`)*VSpPq&CFFοbujUu⮕w8D7Px1"྽Psrn?B?Oj2u8m\o] z4?rrhD6ɩ@Q@ھ ]U|%3eB'z=}5*Wh1#ٚ?5ׯA3򉝐zoȋ0y>cI i)I1Inϸ8?L>oU3&i-5,f. տ,覴b\g&`[/cQ ^xg$]9D6zژ6c4;- L e1sƷ>LW5nrear Y/e~4-ƾ (_(tx։fO\2~`5{8ן"K cqReXb\-ruVg}+ظK@:'ryx+a}'>/ҕ [1( nFlۼE ս> f3ʗG~ݔ*l/ō*跙E=tg8@;ED[z MΟ3Ѫs=5?'>x:Xn% ?}C+6[^ \Ws'$b=??6ԯ|O]CS.܃%|Sޟ HX +<uE~!X;@^ ‹:͔A~P!d ŒT9Y"]IT4o+짟(H#2-EoؒI,5 `pO?Mf(Dϒ0ۯQDMf*c z q~wv~$;BȠ;V&]H# xcŢ biM[bνa:crIh)Qɂg`ˋ(Z&~Z8՟If șTdx.}po nƷ̩ f&?N s9qcW7̝uA>z @X+؄bL_DiL_)gփ;=Vtc$d9uLR>ÖFsKӬ֞6J?'~QH\%~ )H»Cc?"N@WҶs|jj#0C@ӻSMW8"DY0#@qbΤ-VBP߆EDs blh$?@i*\P}f<'@?͘:%g&"FL?]`҉ ?Ʋe>9e|uDt6^ނ4?EnR.*WvD>_P `7؄|*xjCleҕ /e+Ǚ#UٌG֖%dKVVK&+w~\p...$3nU,:r\KTA?ĕ ŴU;_گd:lmb)5}PN -7*h{NK2"L2 z15k;ScV¶/@j ;vɄ$TnpqŔ&?^#5@4 W)H*O zqs&"^4»_k ghG 1ԠNEEPxiYF eQ+u:UdlCH?}5:oyGѬ k' д u:]s -ȌG(M[?tG}>~ҧ |ǢtOwcQNǿB= ×Μ:M?;[t-iOHF: }fo˭3 @:Wh҄:q3F7SsSװ359BRF~aRV2 R$5(?@šmi\ u&! ^~cv"nRU24xgu`I6+|_̟Lr0J^N sbrԠbEH9Ka=33OȆ!]iWI4 <^d"n].=/ to؏H7 rdρ9QV-;Ee^Jyȑ3/n\$mC@ ۦRԳz7gGّ+4͋ bEQT Y$l9!߷ްU*A6"7_Iy'{_D@iERX"҄s B"7sp(R0(B Xw=DO~pAE(P(?&I(oc K=D Ζ B%/2eQt)`.xܪV 2pRQ?tP.V#Kyd&G/':QZsLYh"Vg_R%ԭ_ۺ#' ۖ u|KX0\kѢp{-.E[KhצY#h1'oS&BcvL,J`h ?7,V"Kef׿rEb/s<# *}mc&dtc?2 PΝ"۠O(P0:\3b,0$-[JTabvLQ7zxyV&\|_LO_C$ށsw%w.|BtyUBq*~矇]3)*Ztϗ:Z,#= ~pڔOh\'O՘l οlyx^a{vݚ|*~߭7FBԭ]Gใ>}|~ܠ=¹sشWrUloUO۷_s;>I ?Khh>C ѝ:?)ɈF[T>kN?yT e;~}ҝ|0)r<]rHܳђ׻|S[j ?W g +CԡKY8_{|G`6!A$߆a|de kpP nCM)Öeu&S>gdMvxͮFtn׋M?ݕ3_K6t=c 5wesQP~)oy l_[vJlPP 2B945]|Vw !{wQ `y v/Hw!cgo³ ꓔ*#gύ[Jy<_y` l׻G/?s&]YzE?=MH> ~~o)<5G"`wX& /% ™h7}+Wtl &lA&aX'J~_vIit]%a?~AXb!˴lw%ˀjU@9|jj=9v٥4_tE&Od$[0 'hvq]X /DM/7+->Y`οOԴGқBd|~3)?^bbW-eX,m :xmҵ/SBYxy#6T,9ldU uquCN# "Ӄ2zX;ot]aPh[O kҦ@Pp:TW--Ma+gzSP1̛3*T*Oo 磻_Wzun g$\+lڕ%$ Lp)N&A:9yfİ! n,&HnKGwU* LV] 2b R߲T$_D,7%Jp,fbJ?>GT}7,F_rۛ 0LS2:Pws{'~Lol}IUxn] $n?Q7/i.P<oDG=8Xp>W,Go4b͓<pH^߂f %&Ib~?_)YPHs%e?O۱)ޭKHxLԧWKkr*ɒL/V`!nOZ,(s[ɵY1ѡs{xĭͼ>tnzxPQaxkd'Q @ba[u*!Uڝ6g[v%rNN8D]'m="@MٺXrw%;O C6(J<[fUܸ|?,ۧףGמoj! V|7VzX^C%])ф,PI:Ċi~e_M=`t-%*KQI|bYn[7kt0C\{8)BfJz"ßROEk/ EMȊ  b. &~moZ+|& 9I2@~OdRL?_Reϑ7GBI>WIC'YV.CcLY<ՅV)e, "Y5LeabǶ-M4!%sw(^p!}MDܚE왷|?:??)BI"9=g)` J,;" Lxn!~~g]n,CUH>v:="M{"d `pq)E= y"!%dݿ\Jذa tz=Y$![b.spI V v/H"u Q$~~pEf eRHIl߾&!ѽ,ل;z)W%>:G>(0ܤ9,'O޽ >>d]6[wz?EE]:DFX tBP 9`Ct#`5臈[Cz4$=G!W'v7*C~䯽h-|G&AȞ a~=nNŐm"&lsA2Mz= jթA@(`oF̜^(A^7|Q0O w>ٍ,PGw";9ͺݱ<w5Tr׵DP%c4J dߺU;|>S:B1,KJ:o7xFTgvp nKlo ? '::Zs7]dY,],P R@kWd$#uβkv(*Mٯ]Y׵YL2װٿI!O:4Gӎ0d2įߡj 11QIv+evqÂ9s;'YR3g5A«_ʇ!-!m?!.6N%K0ߠoͯ;ШiC4BY3`A9{l c,HcexDMNL \ɤȇmܰ9>d$:8b'%8 ~vޫ=_Chtإ3eCZ II6ƋT,O|b0BqASGI.hY^-lm6~ KD-&8y{ԙ*"6&VۥH0I(cт$ #G٤V%?ؗ.7fW0?L,TGuxmcNuN"vv!h϶UH?Ojkx(G/ɪmB (\shf٥(9 œkWėyG g#E*.);` A)]'+"OHMJëu;UjF 7Y7 kRގa -Y O^QfѰtf*CH7mb@|/N]P\i BXbU<϶uټ=\VPM?.W'^V8r(,fL$3}9qt!C2]DOGCh}di滱u$5ZFORxR<1CPgSRLFO>~H-"hOh CZBٻ}.«CSH^R3.V\.uau9vOoyd>{t:9&l;Μ:bo?a&gu|<[kɪ ܮW[lC:B[/K锧a~?>+եvV# !پb@/wV=kWv`NeS89-#\zQ[y33!eSD"bǧ A$?K 9Cfߟwv&( dۺrksK7I>c>H s>Vj%ժ^?A;ixnϡ?f]Rh48.Y AZg611<<nmQA Ȃ??&%%g t:]0ԗoHB`I u6$%JbyvX1sARp, ; hUH}=8tSvn:=Y&±-S%?ܪ5N8at W7\|!CRp \KV~0wnE!0K[2 y~?AFhfeXx濝zR+od%A8*CȀ7H}=5W+NW]JJR/]Y AEhuPF[IЦ YAz{ ua=mo7XcAd%A8F@L`R(MN.elie'on /3s{6:!-7Y^pU+VhMBC?سk/n\$m_U@=)[ד !Oʜ%oNwx`IT,_Y0q?-%DX,3Pۯ-Ю=YA rarԷ}i lJVBc\oTx7|'⶛2ԔʔY AAhapނ:b2~zo{t:.liFJpԈG_L76y{Rb @9&Rҭ3Y AAdcp-U:xʜDv٫‹ZRP(AApx߽wK}[gFIU֫]  O0N 2eHIN_~_}vd%P,Qi !dƼ DvYZVɶzjd%Pǟ 5mZwKѧL/x9]G>dC jI2Jfܮ13>%摐v-owwTLz $ݾZV-Pr`p^-ɈA©@R툞)Og*Csp[MsEYJzyd)3LA<F†3t4bRB>|%qɞ L$ crtpP2&2]y?6 W6Ah'Ga"n=hPEʖ x?uh;)'#~!!R$`::8%]G6-DB8 i3q%!bRTɒd-AGgvZHX?GYo4 /`)b REHj@eHmu[S-򗠎'R1m7!Qߙ Ih Aῒ/6{{KCDM'Q Go'MR@T5zxh"d5wivyzt0fW j}Iݳ9!4Q!ϵ+1vg"rF 'Ϝ!k"aPNycFԟD*:t茘nob2);I[=w Զ૞4wa{:.&fNq<I._BEԳW4AQNȀsg/`lB4N{mH4o\'"U_K| ,z;2O1w(Mo;3t;zEE2pAm$L 08z&lCSyIT TGh;!ibW){vń/Ƌn06Otv%SmYA$-uk{I!*Pw ɉ"9_3Ɏ9JVFZ3'{۝a$Jh۶#^( f&%yoHSde&4\1/~n?y ;ttP#݌lTOw?%k#xzi[m]1 `QqB v&#`0D.u;oHGߦ}G$%Ɖn 6,e+)w3/OR³ x8!94#- ]q B+nFRBZ܂A1\%eY1gOrh ? 7Yd$`Ud2;uL_ ǏoEi Cy 6* ^7wZ)F\l""۲,Jw= ȱgv QCaAӵBdxo94') e M: B+.g6nAGr2`ϰq:94j##'?^h1Y(A(9pD@P'Ȁqȡ)<ߑn'DAVJJFŀtnmQZdqmt)IrhXeWbD7ʕ VP{,l[@r2yܽsCMM?>}Y+A(6wnCd%&ͅ>(ـӫ?EL:>>!/SNf?t%~u0;uF^oقAYP[DpAڈDVKJM~t7|=#ˆݻ=GnũL v.YykNQo\^lAD}R!zO/ήz i5[V))p̖Slx8?<$wٳ'ǟVܫDK3Kxk`L56*lWwW7R&!;\uF /OLuxfռ%u?a-d@ 9}ç2}19H! -6?@:.gaf:dJA>SAF雎wް#Iyb+̓3!y~u+У; [|^LpAFM%zef.Rأch߱-Y'A|nUkن~G^ &gѲ-Vz>̏?v Ea (,f3[7oU/v"xKΟP CXXMD&(%vƃA+!)z] dEТi7 9HI0ze)kN qd]>tY&AH3%yunzk6õ|= ZJ*y{h&n*wrŚkФY#N S n.E?j< NPf}ܽU10巟؃R;#K`6y0Bs$$F͋`!'B-ܺyEwE5a"6%wдyKL&Lc M=>& `w ?~;t%$ NQzQ{e(>1GuAN+(Z8EܞzLV/ej萑cFbʵdASɓ77{Ky^ޙ^儩jokJ % FJJ | .q+L1n uj鐘hܬu&AA8 |9af8+USRT-Sh)q7xy{ANRj81<+UjӧDÆMx ATbj_4a<VS~۷ -ېuANBhڨ[sU镟I[aUѹc7_8 p OA0$K}k dfJ`ќw9]?OĨY#d1"* BjkVZա.5Z-Ujբv͚joB1 H=y6**>s6{?szmPvB%ojټ3-?Ls&L  /`F]HvNsOG?^ .U- L%;9F_ wz @uH99Ppf+/FqFT~`UCwt7{I:oVҿ_?gb)H4by1fu~PHg(66ч±~N+ YQ ϥt=x-Lcqqv8tp+J`< j֦ P|y2ED);"2S~4Sgۿ|kԢ3g2Eyw^ч-zIֳ"a'O'uhǶ]^k8lL'RnA10@ӯe{*F@wuޫ7Cx0 +w.[[bdtB3v$ܼ5<@ҹ)KV |o[f9TnN]^ٲ;$;o %ڵi?Ûy P×V'PgNyۃz܇D Gq^(%A6%Ǘ.YLeKUчmq}+!wn|J4p"L|5ó(Yч 6qJ@0UTбa#S|e5}*%ה$cZb1yU+ (lc3թ@-[J_0z>A^`ۼ}Z>ߒ@00-{w RFsTfohӆ-00nCz[,Y sS8qw'P`d7B6.$*xWc`8` dX~BtU8tQ xN:N͂sn}ۗȧZZne5a8~F `ْj g_tt㑛fQy Oa`8GS.=ȻbZd>%%`ףBEٳ8О&K{ϮԴq :yԧW@̤{2O4`T`hd\?;'VSJi𠷱%7oܴo2eiڌ)t:3XLkWa5s5uՇTRVvtq)V}>ӿ4$%0eu =H'a`m$7c կ,(&&,}7֢[w @HrR4|v l%IFsMl(A@y_~1͜a]Jș=B˔B]Sٗ=Y` `t2,ZukQ40 Hanh4a[שo7ZPwL@+,YvL7 AC,?nߜ zKhтߨmљ@WxxVP-Q$ʅ:7 SsQ;oQzu`#v["#u})UNH%Jbhp.S63}$L$`&7H @yWXjRg_u$d+oܰoICB(x9 {}jؤVG$-$2+ > HX;'TjUSV }oݼE{}{ӑ#GDX@wMcǍ!ùz*URG唯9=P@n62Q +ZJ*Eeʐ'yzyP2m\95{b.P؉p =z#tyKމYs酎` PѦtW4(I !wT@!*T-R .DnnVTPA EYRnZ{֬=>._N )%xQxb)6.{|%w:HWv؎Aa5xN;RK @VnN ȫۂFY\)) ^tc{wH3 s#&[2C֍X 8(}CESó99M_ 'u~ Bpjݶ^pMs8  _+ 8"z4kAq5:Au^ L= l Tzu lBΞW 99YYt(ժ[ q2Cc7PO+损(I z}p}Ņ ?|[5A@bb"}X?i";w y2G9W6M EPlr#LAoY*pl1.\@q`3[K$87Y>Vڶ~ y*VKV~ S⽻0Hi~)% '~ /rrq>ŗ߀>Qé4۱x2A2 VAwM(I@n'$S9nԾ];ٻ;ʝ69{M2XAG0}jc}G% pf"/d_M n֜tLJg]{ii)4X? É o4uorqr弩MjѢ=߶5̕0/:*-6nD;v ΡG"HM^f&+;E\dcOXq+Id)-,-knʖ2 $Z4A^dgOL$<~@V]VVi -qc{+5G3V̇t0( ]/x`nJr\?6\nf`&5׍5U~DHߝczV6Dc nf poE%{Yϛ#.d) ~W-s O9M?]@ s4.39#_we {}&*:`،cUF"Ym 0  Kd+v{|/ٚu+t#Xa&TE6vF?@xp3y_yzJOj7gS *0Nf.eП7v#͚$hn$nVc];a6Tc#_{0ỦN1V݇5O@CdcU`?JSݫgTA}MtA$7CMСyYߦa:UYKɄzmT~SiJP%jy '2寇:֏c_*v͇+8#/ s^3i|=4t7 /n\MԹk??&kV\ Nc6Yp07+ab2DS$׫aZ~ɂЌoOzeɶe\@%d9QZ},6Os3 LW3kAPV9Og*bJ5uVE\ u6U~[^q4ͪL5|&g2b~NVq'%9f 4LrjV_dj;zrVgQfN8f@*OȶzP8#+*7 𓁔,i_Z`:d5Ql$ fC}Ec(xo}"7Vv^ܤeJJR [5Fqgs)tL?_% ZMk#pBM:7IB {6Tbf)dS}4MOf` Xg쀼 F6ngZ}k Kq#%$G`_OqɱOs3%u%r#["M!k>PI_sv(l}&Fm6aa⑦_}Knv2S%p=%xA]OG3C@2w&x+SƇ?$n*)ܼjb[qLƪkHV?zo`;MTvrS,bjd)S7U@ֳq/L\khRlc U71[@u2AI!YV;11X]6N/RI:Td`>wV1ɶ`wyXĐ^侜r X-dnY4|Xd$f1z[Ya#I|O`j6B7ji}8q([{)k#d0H\kLWt w C&"'~w5 UX&).d{3 p53 `D R }< "&kk<$HqqMVo=kVTTdYa܋' a )xړm^l1lCp'LdᦵRh81`$@srĪ˪eLGaVmG^Mc7VXnēm`eG ]{13,Yizxm)*:JyiAZH"X'ʺ0 h6mX/ VI32Xdc&ِg #%IuV#Eȼ ZXkX[8>݆ %(*lЯ{'Vox@l)uOKڋyH?)($X,o-Ӓ0,{:±*z %2E%ɶ:BA:S${R1ٖԕs)?J{l%U/DHmIENDB`jamulus-3.9.1+dfsg/src/res/HLEDYellow.png0000644000175000017500000000262714340334543017161 0ustar vimervimerPNG  IHDRvzTXtRaw profile type exifxڭk& F,Ir0 þ{z&T_~rrA-/䐹`|X="A/1_ ׯ z;N:nǠLόKǐyv+rT`HFSv܅㾼Ⱦ ;-%aϹs-ywsѐT8B|ё~*1^] ,.5Tʚ ble%VkyUGQA}*B 3WdyʒgF+h4$Ks@@O,RFd1Œ$c.LfڹB\9gs Z%Ic\quXD~"(Hdh\NHژz! Z]@ !D%X|0kgaֹz⟷^KB ts~:xG,Lu桇 rv3hkAB!V3 a% X  $Pd\x^{ŐUazV(T[l.I!Dipu\a,{ᇃAVrj !1rax`z$`9??yS=B! ȇHr~"rs@! wo?G.FH?|\os9`c!.V.f#eGy$G.T xH!:!eVI*GyzUEm.G!0Kn??BV<#]B ukSvI*GyD~\rBX=| }'A$`YG=6TB8QE-$">̮./mw1"=!ׁGBQK]L%UG}MwFB!4w}1DLzG]Y\'D MSw{fw1D =~!{]  xj]ees9B!4Wq: Xyܟ].:~>iw!O_A[g/}ߵRZ' ݵ8A&a~~maaAZĪmf ǩ?*cn7``0H(;ũ{BJa]'|x %L& TԆEp3z\[1 ]`EG.j.`=ۀgvRNt星']N6BԟKBq D"rn݅Xi]'|rr-WvRLiv#*S?Tq:(*A+k,!F%=F|Bn֓O>yx쥡j~^.8=H* UVD"D":X~x/]Ezꩧ> |X>2554sssv#*ґP~Bj- [^T!|?bU|zꩧ~enT4 U#jjkk Ŗ݅SO=G]TUebb1O@"t$TmPGmm-htLwuBUdzꩧ\_ew-VIӌ211!}H$TYÎ+߉?W~Gn7v-9?.B̪Oo+3::USxi<4nw '}wi^o?-OQ.+1;inT͇PUGՖYjg,$us9퇢(DQjkk+}/u]RQ駟nb4KMQU5IUU)gv : T $YH6| 5vͥT8zx9*&`mz W;b|U(8C}P*4כ,!XR(D Vff2;u.t>]H<-{*%"O?Kw qlm'; UugcRٛQEq"yUEw0Ll+ds( uuuV`;?&""(It:M?e?wut\ U}IJ-*BT,EQFaSKB{92C8N",>[6m&pq{xxq{x~gonw(?bе:I6; @͎N8jvLf\}TH2U{~+^/͕0w,pw݅,娀n^%]f``d3پ'tu~]\) ;~v|m6R3 !DAt-I:M:utϤ(wuc?x3v dKtpQ;݅,rLzg[ȅvגO*͕u'PB_b{mx}]%Zt'GYHK*y]ϖ3;<5++ Ʌ,G LvDzgevג%Y;Im͐^F0qC"#W:"OYHKr}4o1n J;9jm_)_dYzzzuC\yJ |"򘛛ɓ. αoKl8\F~CSp#T4-E"#^ 12jfo}h&0AZ[[|nY X?E&&&8} oY>x 7vXz|!* w{ d;t=O\rb[~?N]8zs=:W rG"`ոZ@! evQ4՚ό6NuO~st5EQ9BuHLO=3S.#Bcx25F ~?mmm\%m1* \v-.K~9=ZTWU[= Wb3ڒ+7 7/Gsʲo,ZJeD:fttжe!UJ$-X/H&|E p㵏PU3 D,B!De2[ҩP8vS_fl—f{|Z^|8d i~!xcbƏ囹kx]W!(]O11ub᣿ע( mmmkOQ&cXyP˻E(MvhWSNB9n!JmBT EU nVϥh\ ,9B]-j莅Y}PK[^zO(ՉF ] `[n!a݂⣱?Rs !vϿ04C&CB/ `P괘\yw:e륗^roŜggg裏 !Opˍk-tkhn:%OP ,$btߢk yMjx ^}IZF>nfR" \}7[ҬfeKӗp@J;vp%GDg ]u}Q&7oBlPU.W|P_OxUerrL&Sо\%-X/r5zI|GbƯ[MqG7} xͭ˽zB!*U:uN66šlzhGGGGJ-7|saAb Z~@OOOpOP[3ȝ+!Ͽ֎X=î?,>`A*gE_~~EԩS/ q=7m0t-P!eU/ʲ{r_A%2=W++E%EQ(JIsbbꯎNq_Ș+`M-t !L2H[Mݯܕw[X,||+N[)lwyt:mz_7px6C !t=!0ﶇɩ݆eXUUEsss5ZyM7_K3p]PRkzp4BJ(^[3Cͭm'UD"`В \v!;Ԃ+(a`O!'B,>(hK=Pq{ :B^cb?.6GG~ ]_}TJ_-΍eotX*8\\LӴh?='^[m/BZBUo#DGknW=CG^>4k.S{eݱA|fH$L Ź m ]I#JqB!*[]rWo{gǫ}? %B_-d']ABNfx<λ[Z7],mysi;\BJ f!3$/*DZ4ulEQD"444ZU2C!]%98qpյ)44+-YP[C]SQU7zD5kl8f7w֬9jjjzm&髀eW_xdQæRsɼFk>CumQS_!gxg4Ǜy_h4Vnᆵ-aKQ[Ǚ3g cߟ"_]O3Ҕ Bv7Ryhm)ã7uyjkkqŔY/^{- 矘СCkmڶw aB!F͎22Xlw-Ys\)BMM ŖYYnX0)\r7 mm! iB!x J|~F 7Η9sp햏͚B3ʱt{q\USkg%%̮W_ >" -?edl?p4Mc~~y>ehk֤(ʝv-\HU}v╁ .5}!(r4 L>R햋b؝?яlhKQj^mHkBu/˔ B!D"H̿wS$ ;ǩ*bxȭOF64¶BZZ[hlH3?pO0B7FF8ۉϷL7orԽy[:* ]?я.[QY^]vÑKPBl`. ~ V`W~4Tʖ!Kgo_lFZlk1O{ u ?.BX'ٙ@ E-zܖgCV,#[f1>6X3`늢($1zJ(t3FBsN׬݀Ͽtxm[ާךaaaMpoϽxu׭ Uv3iiI vnSurB[,[![0t4-?8+n͟TI$_"2Ҫu=f_s}d>ܞfzP!ai#'o IDATr`*fg #pfx*4R8xp8\DEæ^@Bx:Ppat lDw?nk.hZ@ Ztm\o;BRo;̀- XL]~KQv.}ApnFBQz^& nBc _e2&&&V|lMD*tQ/Bs0P>s1V `? l)u5MNN7rp%FeK$\q~sWT*UhyVx5\ӻΕZlefj7CצAS/x%}&Dp)U_17o|d2i*CޱRelVM NXGB+ϼ ]7idY<|+- X+Hn۾BBvH 3B!JIq0y&k_Zɤk^ XoN`DLmZK)nBpBuTG.XkuR);Voꫯ>x,[Ojkh=l.W X(B(,htVU+ݗJu V{Z[(<'`I+B:JՑ!\.L a}s/,EQn.w5sssd٥5<^ЋkB!y~)BMIRBg\z뭷KX[dVvr:i<Һ$B'LO([o5_uUp~ N;Y=e @HB!C:'dxrC*B2,< \v MӘ14(mq֖q@k%B' 705p=V)]k`sEW;˟ [qsJ V3hM CN&t> R(e"\XXྵRgsnNQZBUEO!*')s;4ֹ,ek Vjaaa+Ry˾3~@CAs!(Tu+1 kn-*=U-X?1H:nO%f7_!((X9`,^m턟]EhK6-(ixB!8_63hq'%_~UUm ˶؂e /7:+,=B!r4mMQltϗ0Uwމ(R2S4TW[݂5Nv7XvL!BdRG }?f*3Zy睈nٍNѠ( ^o` Hc !Ö}l1Sg(/f:,!eqɤZv oktxE^od_S\%:V8|(S=/ml\(XE؂Z>jkB7 !0$~$uVX˳cβ/`^yK{e&slv9|Bh,锵>,#S,}R^Rd5‘O !K*6ϷR,sS/<ݞ1XF/z:`(q޲/(6nQi4mLH~wkt.Z+lU]Tz ޭ(-8= !8Rw@)M˽rjyB4n+> .¥J=}ϓN}1 &]B!6M'>F)`iY]6_Ehҩws !TTW>_a<1X@V ]ϰxPA`) P!PÖܾզiX-C,qR:A*Jp:$Di騤u67 X.W4wY[2x:x:z^!RSi"b,PZܦ",1}&){˄?|n!4ut#V^xpr\O4Zvf.TtK0h|GW (BH&_;M Lf{ˬQe/I`{2/vfH>Ԗ !NN}NآoU3&dUy[<)AC=~a}B8 B,UȤ?({4ߚ/)̎fv?QoReл`zY!"]%ٿ9`Z.B{1XK\ ߣ  ݎdw)B!Dy) / `)b wg`D(rv $^"bB2I.aWB R"<;ȽBRNi4 CwBv#%[;HY^"{Xv`Iu9oAQ.yIFމdN͜Eӌσe =hL=ijP]h[^)!fNN5-o< Ԃ Nxq$ɅnnoBQg}9)\B6*F1X>_J# 1*lg ɅWi!9_PӤ:7B6AaE! H$V}|TK2#TRqOň !B͜"~r9K*YmU|%`O:/`{fg2.B~2AO!oB8P&sL}՚LĄgghn"kd҇)|8e.!sl1XQ*ekq("27Aly!FUH.媵!buz67ϕ:S[ٌ`- ThRr Oҹɚ©/Jt=AjU}x.G!ϓJ9j咩JedI8jk'+6[e:Gh$>Z!:TȧI z%/裏rIRI|d3lZ/]bN{B' ƅ9'B=k,^o IKlx߾}sM*)s@t X %tt}Tu+EQ7P(44rѣe^Tuo.w! Tul\uN*9g#-S X ;*Xz%Gjپ}uNtf<޽(Jؠ*SFzlPEZ-H4T$'gTUUZChd]W*o*Tu U݉E Q뚕Tulz d_,[?I鴇uuN&WU#9媳B!6*]OFSS*XaFׂdN=z q QW7_ªiS?݉enY!BUll/Rj|AhȐTo߾Ç/WWW7`-}rGFjٻeFӦHnَ I!nt=]ajb~{޽Y8jkk00X'&dU7ZԴq ܞm(JzB8͞Bg難t93ֹ1K-jjjP] 5jX mmSf::vtIb e}aM͞DrCaaTw+n7hYvY뙦C\=2#L*6"MGUдݥTXoF׍rݎڢnŀt gǐ2M'Q*ܞv\Vl_sI!D ?Vt]ESPt=y|9f\𶊢8{EqXK0ggC$BƗYotd' ۍ݊.݇Ba4z27x]&wU TjY_- >u.Kk袋Fq;FnS}~6MEUH"UEBid2HDUY4Mvy/nV֓,6庈% [j\J5(n !B/i1tm K{r3tk"I` ٳ缋W0%SZZZ8sLm6]ͯx.: ((JUQ($p7_!O>KI'B>[^M"xע0HOIt&-%tυ.ŇVf h4:It-~6L%r-g}Śui{OE!t[v{ر`KYJZ\2H{x@)d Ň ^"\ggw-Oa-_N.,iNTtKTJ+]=lr0gݽ\mў_-i9hllԩSh=M;(_l /ŅY !Kp,Um[\z Xn/,c剒8mRAœGv0bE`e8,UjO#ttC!:#,y}k't*iŀ{ǏvU͉e$BVv!6oP!8g~x0>!݃v5`A˖V~S:nK-ظF.2琀 8kX_1---(bU ^ XB!*|*T*Lld/uk9 by9B!jjjYu#BQis0_kCZevڵpĉ_,EUFtuu4gB &!K8z~{PalTnM3]UUU*Ɍܹsyj66Z"sss_|q\0BI.<~'_|)o` _N1CJwz:P-mҊ%B8ajEQ%Ȕ~riUk;w'NZX)aݗQQm%Ć'-B8T5hJWqٱcǚcic66,ȵb9rdm*{ٺe !C吱W{ ;w9y~KJ*@cc#PD"qd-ѡN:fZsO/BKHMRvr;vXՇ*FMjmO=\X2{BTEnr[TŘ DF?4YgkRgb/&R܄wᑋfM(S2Q^9F뜓'O>|622ɓ'Mø\KVysB!) s]۷cdC3I|,#~---[qGbJB3b ]j:\NL 2EyTdEQغu+GͻrǎеiH$YB X잛o̻JS&5኷o߾pԩRHUVilldddti t7dQ!P=QuW]g9thrؾ};. +quBQpAn61dm#p85_n2AN:#:S;3g3bzUn8UUq !Rȑ;d( ͸\l۶m;5Ei&YXȵmdrˉeW k/QXN^!.3"S` ?.7Ŧ\z-۷M-H!*nQ3t\ez?MSSS&}o۶m3S|}-S[[KCC\Bn!Ng{!LbѨSzG=om۶1==+>zᄋ21B!o?٬~>[lt\1.B*hg ݝwVu4-Nvk(MMC #5>K ڷ kqE֭[ ZS`KǰD[[ 8;:ٿb㑏+!0& 30}CU\I-Xݿ|Xh~~>M򆪕>6wM "QB!Dat]'̯8-.Ae֭[Н X>0?} sn7$Ba"$ihx#; ڷ*+* u˖-BP[nM_/Vjmm.~Vq?vx+7Mnk߄X_IQP@I [W@q-X===!h̳iYnҵ$~ BTd2̱7O\.'0l޲eKzzz(x<~n;kws4?6`ui듣!Y&fN Ԯ( |gz/7ol,O(D+q>c( vwŕ !ir ?F-hp͛ߵꀖ,޿bA466ɓ' oR־}#akWIDATS+#k9v*tGSSU7oM+XU׷r8ku.>k8{/,!LEX('N^Y"ΐ ,7ꚱ,/d Umˆd¹$Gǫ9qʂǎoY}В,3gμXLLL:)!e~>TWWG(*KuS)\ʀxpT;9r\K`!X q %!(DҘhZ0;pP;@p)^p̙?~d'(>| 33Guu=#!XbFNu_>9@(HK]]]P:`@GNRL&áCXXX(jp8uRUUԚBIvi҂NL`سiӦ [Z,RҀp̙OZғ(Jq!ish/JkP]pBjt CSSq^7mR iΒDCvk\v6YzBQVcM1:âg6mtWORIn#;a8z(wy۴iK/B'MN#ƥ.a|jll[P妀6m_%` r8b坝=͒E!K&Canƒn's}ꎎ'-` o,qzzzд *t 4]:BC% O! ]WbphsQK,xhlltzwtt[gZAD'O~};:b;g~S!F$_D~x3I$–3P__o\GGw,000]䤩2W墋e!Β!Da4fFF;~ah4Ju l\ͮ/rJ oPq̙ ZMMu;ii.%!OETJ-;u,k/1[MBZZ2L&nShNk$-s'X93z7[2R^Z \>bw!ࠀ088\jV2r|Vuu;&ii%|XCǣ; QWWggWi Y䨀088x92`oK -v|FS9!A"Uě28|T8E]R X.jD"Aww7D"ﶅΣرc9a! 6;W`sYmv;}MR.d9G,O8ZХt]gtt 39r`MttʶvB24SS SSSS S0,Ҁ_hkk+28F86` M(D:)Cۯ:ghiv빾UƷ_!D#739ՄKvK]]]%Z-r[[]j3(T,T™ U+zuf옡f+bcrld$U%=(DQh d_E `hh诀߲Bi0+Epmsق/fgkofj޲%msBͫ붶߶|*%`b$Ib% U 46ilS_۽b5nDTtOlX EMM u϶:"xZ555E?tz _Fs{ .8\3d3LPVzyR|R[AYPQ[--J"ZQEDZEJZ˶ѧR/]+-gf$g6Nr. 3YN6d26::O۞{7hY^du-j۞sssd2QsI]<=7 \.&%k0`Yr۶]-UG}^<# `aBK,_ DDԩmR.5R;ϩ.x7_n7Li'ܜöloZ& ۂ.,r'lR.\RuxT[b}bsX?|/ )10`^/֣K%3??O*Vǩ痖7dRUk'MgneY4C/^qf$'OrqU 0@s2I+Xjs%,ӶAݦnt$,Un1$0q=lׯqD"Ε ȂPVLg1e0W666,\*UcS!Q?F{e*Ha~|fiiit7`V~ ,bZߧ*U&>ocmԱ*U7Hd U" wogP,n:BQj)Y항n`R1I_1ux ~׏A%Xb1zCbtiMUĹh: z^~O?2铒Wn>.N^NkH" {D[VŢF @V gw7"""`,WMP,Zo:lI}xP([`~d G B;AL eYDDD|2p6 tz.K4EDDG_(7+T^^^[ |-wLC76Yd2l:`cee^@t_e~38W^5SDD$83*W!-P*"",|> ~51@p | i.]!`ȲE86,#""2Iuw0˭G*Xc,k8㈈r aLkB,˚> <d80p.f:L`MeY1C8`8Q3\.m:L`IJ[ ǑDny_eY`MA8Sb:ڟ%ANk[qi6GDDa xx8tP2h$DJdmo~e!Fw@~{ѧ?_z@L@ 7u[u{ݏvM:fß? >T yZ4v0@1}!w F +--޽{@ ?UTT.^@`$P ( ?`0 @D20ϞJ* ҶIENDB`jamulus-3.9.1+dfsg/src/res/flags/tm.png0000644000175000017500000000112114340334543016751 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdd$?|!ѐ~10`? 1|s" u  Rss ?çO~>|u'ϥ7x۷ 1sn=xٽ?;3&ۇ{+ן߿~hobjϿ~_]LSyo  X~/+o_r'RTK({Ƿ@ K8 Xa_8~}/هW~؆?@o5 /ǯ\q/`j50ghn `~q0pi >߽"s)I?  Vl bdEğ 2 w A&IENDB`jamulus-3.9.1+dfsg/src/res/flags/st.png0000644000175000017500000000111014340334543016755 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb:c`#/@,V >Uz00Ͽ?Lu7 s>- T_0ׯ~-#@,@p}wҵ~r of[E `+8yw>_|쿙:1w/~_ld~k+W^.hɯ_~E @B\A~fgrLToN_!: X¿O"F?yW`?0y @[0 t! :ez ?=%$?#_/ ĸ!8"!E/hD?@^mI9џ\IENDB`jamulus-3.9.1+dfsg/src/res/flags/pl.png0000644000175000017500000000056614340334543016760 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb# ?l X@ 3300G_= Ȍ##?H)VFj0ģ X?{? Yi I_ !~_ 69vXd<"T00H3 pE5ei`ARl_? `# $ A@pĀE\Ǵ]IENDB`jamulus-3.9.1+dfsg/src/res/flags/ua.png0000644000175000017500000000067614340334543016754 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<PIDATxbdh1 ?(# rr1Pz(* jd!7nG3K,TCœ~KG00T??߿ !~!@lTd6H+ks X. l$P*  rJSߟ wHʖbc:@20?/WdbRz@C, HTE( @ P6  @uJDA:#B?bz@I8`@pAHnGIENDB`jamulus-3.9.1+dfsg/src/res/flags/gb.png0000644000175000017500000000112714340334543016727 0ustar vimervimerPNG  IHDR ntEXtSoftwareAdobe ImageReadyqe<IDATxb4sC^a``ߊ+mS[_wo~Ȫr:]v'E>л?FUE!5Cn_?+ yF[L5]^gw^ +TWy'##Ż Ogwxci7;N07z*mn0|;?f`׊+7>ݷGĀ\{re7; 3%?qp׿߿Eeѐy lmY@?'`Jk<7BtΫ>0{+%_my3gCsv͋Llnqa3;/Y0ϟ@0o\d>S\3}l7s!30jJ3jJ#.氦9mY~;-m0m?2z!9[ A K~IENDB`jamulus-3.9.1+dfsg/src/res/flags/me.png0000644000175000017500000000070014340334543016734 0ustar vimervimerPNG  IHDR 䅪tEXtSoftwareAdobe ImageReadyqe<bIDATxTR/CQ?#mc.!$"tb` `4u`"Hl 0T"b T{9ιy9y|~ET'fbD9"l}AcJ {́կmԛc=WV Ź,[ac0q9H`;/f{ Je;璐b,p#h~x#i;.F 饟U&oapӓC`A=~.'.*w|*#P_tZ락'ύ jKsm/_|h_2CgϐW ıýF4XڒI9MjRA)8=BOAj I~IENDB`jamulus-3.9.1+dfsg/src/res/flags/ly.png0000644000175000017500000000064314340334543016765 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<5IDATxbdɀ00ؿ$@b`BWZ\}`f6{jW&ɱ"4E} x_j "$296H! T/ *b9/ PE Ư_06H@lo`JAF im @W qfj ?,P9ӑ@6( (!!(@V* ` %"$ r(IENDB`jamulus-3.9.1+dfsg/src/res/flags/dm.png0000644000175000017500000000115414340334543016737 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdd@ @(fU?WD~1@_ T $2 Z\9+ ϟVX@,~{_PC̕_)=͍$@=@L 0×v?QVS~y?~1BI/\Α@X}q ש1|{v d+1\ N ߿@=t/2Kd?)Ծ({bdf(.~¢H9οvnt!n&@()j?@Lr~r1%fz~4D5P @,@[SD@Zcπ3/vPH5#C.JDB/>}*" $M,8̃IENDB`jamulus-3.9.1+dfsg/src/res/flags/mp.png0000644000175000017500000000112514340334543016751 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdmd~`Ə_ ?0/  U@1m,/O{I6w_/)KG>ddU~u Ϙ~+! ?PHGmml }/P@11?H5I㊭0HnM%NG? 6ZUm^!~6c1?'SYY P@m Ѐϟe\~W>8ACm `mL1~ox"Rv2 %9 ? otS9^>qn4}~S4 _Ƌr%G~٢7Y tP?bd`NDH0DB`0@ྭIENDB`jamulus-3.9.1+dfsg/src/res/flags/ec.png0000644000175000017500000000076414340334543016734 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbyS' @A0P D@0{,V@!@?nt g$BJ$#8zr V u n O?; ,8E-/? IL} @,oI= o4?L\ J$Ư?@_Py_P/ 6$eUR:{ @(00p|  RbYT/ou!Pl?H $@l#KIENDB`jamulus-3.9.1+dfsg/src/res/flags/ck.png0000644000175000017500000000111214340334543016726 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbܝ^K/:aaWG+坟Hm 2 ?~!#b47o\]@k~#&%"³޷33r߿ -/14 eH^i?MUB K]Q Tʩɿ~jt@1=0pƹ Sg Vx_z'N~OT<n߱g^_~nݏ:ue*Z?3= ۀ^IJ;e@,⏞ ;[̤A}_mmm 謿A2H t̞%y@R^B]2 H__ /e:P@5Y 1? @1[AF@ `?`_l vHn IENDB`jamulus-3.9.1+dfsg/src/res/flags/europeanunion.png0000644000175000017500000000073714340334543021234 0ustar vimervimerPNG  IHDR ntEXtSoftwareAdobe ImageReadyqe<IDATx,Q=KA݋1+!)$_`%Z[$""D'v4Dce!Q$ΌovΛyo[(y&&b5,3 %"K`0`p(@KViaYvZ'xh83Tck*UƉ{PbBĜ DNvcGJ-qQ|1<2T(dfw\xbrstGC!cbFvsϮ7Q2DylYJ׳v %  TJ}y"G} @cO$=i X f TR/ßd?UMBE~1@E SAe z/o ߿/@h@qfOOV9h:d0ؿؿ L/^ ./g_XI&&!>6bz$Uj?σO/$1*=!9HXωU +:I6F- jK Fd @#$8!\  hGIENDB`jamulus-3.9.1+dfsg/src/res/flags/dk.png0000644000175000017500000000075714340334543016745 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb zAR Q] VxyK}ϟ3I /7m 8(aٶ#"ϟo[%'ēߚNꯟ_~3X + /oWy>?@/0XQI  /Ԙ&y 6!j IENDB`jamulus-3.9.1+dfsg/src/res/flags/tv.png0000644000175000017500000000103014340334543016761 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd@ C`X T[Rÿ2 bo%KA9s?x%@1BFFO> D'^~Ͽ@Ȁ_6N]*0-@1\Bu|t/ R 3N7 І/l?Zd!=2HOB S ~ ,pI?@t܎)'ȱt+@1ןߗV/Qt[  ,0޾} @ io0_[N뗂gw^߿u ݑ"~2E'sր#?,5&SPɽIENDB`jamulus-3.9.1+dfsg/src/res/flags/ao.png0000644000175000017500000000065414340334543016742 0ustar vimervimerPNG  IHDR ntEXtSoftwareAdobe ImageReadyqe<NIDATx\QJA=/wp\qH! |~e`..;n82y3N~NH)DB!HI K!ELp((p0&/`ol(D\"M5d|о' ӱ[-4a-bݺğu`f#bo 5Će3X#:y\YUAkWe[+|u({^Q&aQ=GgčSPej7``y"o)7cvfR\^+)m^092v8Y% H@` @SR,0fd@,L9X;ܑ﯑mU #?_&Fضlk9O h ( T'bb;~,͵k_?b B`}) Zd ::~|ߟ?@#/q9@0a!_`00b  EE @I0?` !h?H"` }@'AUX#@@123ddw?~ D  UR:[p X~H_~AUH?  t@0b$$0Pf P/H@12X3 g@"m~gIENDB`jamulus-3.9.1+dfsg/src/res/flags/be.png0000644000175000017500000000070114340334543016722 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<SIDATxbd@31c'?q @,@j ? x@Ml'O~307~U3m JФ@տ ~h` @@!4Hß?B?j?6_j0N ~Y Í8 [(P_KbIII722}LeàN F} w0q0{B$p ZeIENDB`jamulus-3.9.1+dfsg/src/res/flags/vc.png0000644000175000017500000000110114340334543016737 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd`8߻  D?  Puu"Iղ/Pf?L'"~i&j~o8~-#  Vϟ`@\5ϟ xkF"Yx_ᗉ_@5@տgʻ'^2+؋_gfdt0tbHoZ~|~ qI7oйfLD~mï~RA6(X$/oTCD`a {$$؀>abd`e` #o,3e0 @ [q(h!PhEcO{Zέ IENDB`jamulus-3.9.1+dfsg/src/res/flags/au.png0000644000175000017500000000124114340334543016741 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<3IDATxb<^|CrǻXV*Dsg101KMy<"[M-ܣ1  =F;! 鐎>_aQY.3߲we~pkt ano!$AXx?]?mȼ߿wSzh??q}  PK<D?/ۀUt (lp C 20f H@5$) rLLb\A @$0*jDBH?p+ C IJwOI;WIENDB`jamulus-3.9.1+dfsg/src/res/flags/mq.png0000644000175000017500000000121714340334543016754 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<!IDATx1%xB& ɼvYoJ2.ucӡэLIYB^IT' gzp)ԅ#G?W_<~">O"\g`@, /UUZ ߾oE7o~ ٫ϛJ?}^nV#'}W6?I_w /Ͽ ,?| yk.K 𲳱2>y_@F$x{6VE1uzLgV.PBb ta4{?_>ySn.VN߿AFP ?m$/_ %! ɦ_bb+@%>4310b`ݗ/W}") G.!$@ :hIENDB`jamulus-3.9.1+dfsg/src/res/flags/il.png0000644000175000017500000000065714340334543016752 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<AIDATxb|%p.@1'*dALL  ##kYuߒ/Bq'@@\ Ua7g/?o5 @\5X?g+Uaޥ?w@ =)~ v\g Y ~@ $x 4@< @,.Z l ?e r?Êxmd J)yo~.IENDB`jamulus-3.9.1+dfsg/src/res/flags/lb.png0000644000175000017500000000100514340334543016727 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbπ`$cIbJHtT1_? @o dM3@i?a@~ٿ &)%1H```|ռS~h,',󟑑-<@11011 F ;w?0?btJw]_nƋȚrd21:@5@1oV$ʙ @r>z PO`8~yO 0.(  f&` LA ePb"e@`SD>|IENDB`jamulus-3.9.1+dfsg/src/res/flags/bd.png0000644000175000017500000000077014340334543016727 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdpf@ /D1XúLVwO²\9fgYdR'p5!t@,`?y/H_'ߏYׯ~-+, T @,@gMlwڥL~o/ _{Vj &s o'@$/{~/_ Ͽ?@UIC9H?F5 /67Bj@4Y@!À$A6 0t hV?5_% 9ʿWȀ @,  6(@DQbdDH _ak9IENDB`jamulus-3.9.1+dfsg/src/res/flags/pw.png0000644000175000017500000000104614340334543016765 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd c"?#Yp('E0 ) YHkps{2ǿRʈ)kRqQ{@, L OHv?P,#ÿ2@;0+WjedxAPhub/H @WP_~{Mddx01>T^> &02a >[Ǭ  7ߊp ' X_??ވ c@s eÜw?xʬsw>+$> ~cfK0\}v+(3/#0f! t@12e?@P?h :ZYIENDB`jamulus-3.9.1+dfsg/src/res/flags/kn.png0000644000175000017500000000113414340334543016745 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd 10@ D20aH* FVjjpp o'O|ߛ6m O>*o-!쿧Wk]\b:h2P@~5w_F<>fԙg  r0߳[~_t¯/{2^@ѿf`>- _?fP bh)?1Bwܶe׿~-!kZocOׯ3 @, L ! Yr/;VqpP @5@u`8K@m|ZZK u ӿ@?#g'7 ߬G~3 4l00+d_}< GAA@S- \0~IENDB`jamulus-3.9.1+dfsg/src/res/flags/fo.png0000644000175000017500000000073214340334543016744 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<lIDATxb3 ʽ^Ub/yYR $Bgb6D?>xlh@UV 1 vFu&hc'JHo `S(@3_{ϯ E/ 2l$r2@# qk~$L=}/G X _@ af!#+ 4P=Kx,>`ȰMC x0_i{IENDB`jamulus-3.9.1+dfsg/src/res/flags/yt.png0000644000175000017500000000112114340334543016765 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATx$A 0To{ֹBRR|:f tY\(c@ w&/\$vY \/镽m-̝ɜH@D\1aapq02?3?P'###b/xϜy:&jý?{4ZE]cܻ/_``3[/OOOϟ?淯_UUU8L6:0s?PVS[˗HzU##f&ʟS~g󻓙_fO22@4:_X@ק_?~I@YXX~32r$X998 * Ʒo-yׯ_Mݻwp Z t`&C WM$BIENDB`jamulus-3.9.1+dfsg/src/res/flags/tr.png0000644000175000017500000000075414340334543016771 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<~IDATxbπPX@ $-(ҼN33Ȗ\F8U@'?yT R;R߿d3m `ALMAꔕwtk` @ڨII7lZT @L ' uq1W/$͚ffP M 10kk%=oDIČ`K/ E2@40 hYYAN5Bi`ARl_':8  F$8;\FoIENDB`jamulus-3.9.1+dfsg/src/res/flags/nu.png0000644000175000017500000000107414340334543016762 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb,.2W݉"Y?~t'IK9 A_by%u'gb7?_>z?feLL*c1!3% 22ɚ F08(0Stګ'$“HMciSm9,3l Sμ 7X0h|:epkHP|ן?@5^'sq {ϼ 1hNyV *:yLVO~ 1pG U  .c ATCCh-$DA$ @@@ 30'+ I@e`wXhg?@F hc Hx|!IENDB`jamulus-3.9.1+dfsg/src/res/flags/no.png0000644000175000017500000000100014340334543016741 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb|rsE]D3?`A @,@Qj )FFF0~ "߿n@,`{H|σ@ ׿_,+  U@_ @=@$@W߿@g@c@e>#sdv@m@$ H 9 @ɂgqq&&=ffܬ? l줷v~|o7~aQVz@d@ g'D/ H'?f ?$A.,_P3@WaQމ̮ 1$`$ZlIENDB`jamulus-3.9.1+dfsg/src/res/flags/li.png0000644000175000017500000000103114340334543016735 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd]00 1J_0brB9Pso?H3Vl 6`Zo߿ T7X86H ;r}cgAAJ dm?=7uw_SZ/oo_~e~ X4?P'#?@N7 b\fˁy1|_$f&(򍁁Z?$7  ? AJ!M5l P߿LA@,$~oƿ L`0Ͽ ` x`$* @}a0IENDB`jamulus-3.9.1+dfsg/src/res/flags/az.png0000644000175000017500000000111514340334543016746 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdxÿ? @?@l XvU)DT߿? ? _ 4@0pq10< g߿@3_@ r1aFFI~x_@$$͜ @, LL M?EEJIU^߮^߿ ğaWTfUP|ed.,$00P#$~ak?ޗLK{f폻w8#P'H0@ gsf?^y"?_ŵ!*_B2? X>1GM_pЀl ߟ1#C)P(j$a0e#WIENDB`jamulus-3.9.1+dfsg/src/res/flags/tz.png0000644000175000017500000000120214340334543016766 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd 10@􍁁!ލ!3T @0|av)߿ȟ",,ߛ6m O>*;V)~gzP\b:h2PAD~*{_7ӯN2 @Oog/ά/ QQ--zIr]"@=t{_[_I1#E~26*|ӊbЋ^j<~@s+.aVضd/F%  CoY_Ӧٺ_bE +Yp$+_@?ߧz ¿kI|f9R_"B@" XURSppHJJBι\\/d: aqa r c!@q`u)=IENDB`jamulus-3.9.1+dfsg/src/res/flags/ye.png0000644000175000017500000000063514340334543016757 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe</IDATxb|π`$2IbJpV1?D7doŒM6OD~3 Vo0׿߿l&iY "ޞm$A:A @AFo,WNNN3!.#bD5Hn@YFFbi 5he„>ϟ?ȇpT  F3߿ ~D N8@`HHHHC -@ V3azDIENDB`jamulus-3.9.1+dfsg/src/res/flags/ae.png0000644000175000017500000000063014340334543016722 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<*IDATxbπk P V8)妛/F4e{/ђ"[@` ?y/=߿_ Ȑ@,`CTt^`dd| XNe;ȓI@f;/ NU~q: @Af kk_~JY篊ŋII?es!$=p$@ziٟ>IENDB`jamulus-3.9.1+dfsg/src/res/flags/th.png0000644000175000017500000000070414340334543016752 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<VIDATxbπPX@ a@oHRWZ"{ <"bd3c>} FG׍9:hAϿBe[e3"}$Ͽ߿ѯ__8)/ ~q'ȑ@z~@D(,߿ h/lfI 7/;8vЌ`6IISϟ8۷o;;SI č2FJmٻ F$8bͪIENDB`jamulus-3.9.1+dfsg/src/res/flags/lr.png0000644000175000017500000000072214340334543016754 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<dIDATxbd`f@(?`BP6z߿ڼrk D߿?~|bcc@߿Y$$/L@ {ܴQڸ?%Zzf)'w^g A 4Ͽ߿X%eNZ@߾f?n b$,*3y w]r1l0h/Ʌ뗬`ōkrIT\'`c r4@_v9c7ODaH_ @,$FԨEf@ng ’IENDB`jamulus-3.9.1+dfsg/src/res/flags/mr.png0000644000175000017500000000107114340334543016753 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd0c@?8P(60CSd5b`2Zt\=9cEoϧ^>{CABHJ*d1ba`*Sҿ@@T{@?~120)@ח_J#~ߟ<@Hat__~f_X~+JH'PH@1_ h׿8ׯ~?寵Ͻן ?5?~ei~זӿ  @@> _{wץ_U 4h.P@49@:k)@_@qc"k0 o @ _8vbi!zh]3IENDB`jamulus-3.9.1+dfsg/src/res/flags/cz.png0000644000175000017500000000073414340334543016756 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<nIDATxbd? & 8@+{_EB/^ & g/G+C3b!@s@4纋-Kß?o?ߟ+߾ZI d Q@!/ 6  s~ׯA߿I%??@5؝hwn#T ~1Ik@ X~>ķP1jd ĂQ_Y (@1O]h Eeal[ X.wZ;`80B&P2@lHBAEa%@o& ~(o`$1h?x@ _"(=v!Q /1blIENDB`jamulus-3.9.1+dfsg/src/res/flags/cl.png0000644000175000017500000000070214340334543016733 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<TIDATxbdH?&.b``00 ×?Qf N/'3#FFFfff&&H˗/!B?CУ?~ T  ;]x7?_P@0p|ڸ 9K5 ý;L8??ӿ8X&o_߿~ F"ޟ:@,@0AQ$0`"Lm2 @~aH'#H DBP1@1~.b@I@h9?9IENDB`jamulus-3.9.1+dfsg/src/res/flags/ro.png0000644000175000017500000000075714340334543016767 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd>010?`` !@0SݤTL?D~?߿_6m  O^L=b`o(_f@, 3U B@&C40 @, UxEtba0 Nbh@4P_$ `I`'H u `n@0I?@  TR䍿LL R0: 20K\|o0 ÿ?xC 'oEEIENDB`jamulus-3.9.1+dfsg/src/res/flags/hm.png0000644000175000017500000000124114340334543016740 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<3IDATxb<^|CrǻXV*Dsg101KMy<"[M-ܣ1  =F;! 鐎>_aQY.3߲we~pkt ano!$AXx?^!<,,)!V?7שc+T=Nd|ױ7r3/*E ?1ӫ ,@߿~?PC*/ۭ[d,@5uTݺ͡#ߟk9j@@ @IJrI?@ڀ.X2_ȑ􏁁 )CnIENDB`jamulus-3.9.1+dfsg/src/res/flags/gt.png0000644000175000017500000000075514340334543016757 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdNc`,$ߧo#8(." FϿ*  H@! Q@Ew_4_Zh@]21@s_6,a XcrT{~5b  P?}4 @I!N rҟ a s ï0E@E @4@#?&1>%?~102D!3#0nY \2No{ϟ`W{1p*1 sIENDB`jamulus-3.9.1+dfsg/src/res/flags/ws.png0000644000175000017500000000073414340334543016773 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<nIDATxbd`f@ `䏟 w9 XKDLLnd${W^߿F~ٴ X9Я_ QVh@1a?кzP?@`u?A/i޽7!~u  4/d @IX`Ԯwo` @'A!T X2g{ob ѿa$#IČ`!(PUd@ c+/߿@?H? `c2d!_* ƯɀR@`o] .oIENDB`jamulus-3.9.1+dfsg/src/res/flags/kz.png0000644000175000017500000000115014340334543016757 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd.? >Q ?`d0I @@ U1a@џ?ba``x w0qAr2n>_4/@113cmͿ֚@ $[/h0L~p| O/f ?'Ko_\o%B XaQ[]KO?/@ @"}?*{kKf tҿ? Rnk(0XSO+ =FPI@`2(r3Eix_d_q@ bdX_%;x\@0001iZsqIENDB`jamulus-3.9.1+dfsg/src/res/flags/is.png0000644000175000017500000000102414340334543016746 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdПϥcfVYaï? LD`Pm l#1QBaKwi^fz ,CtԮ ? ϣG@_T_ :94_@H`@=@@% [g&$ FU9~VoLxXvefxV+@;xf0NsY_tZ{VZv3+Bj|BɼY5IENDB`jamulus-3.9.1+dfsg/src/res/flags/cg.png0000644000175000017500000000101114340334543016720 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd8@R XՊ`? 'F &}@MSҿHUK6P/Zq,zbd0LRD[sA~ob* 4n_fh:@42ߟ4v @yR߯$?|k~/FhbDÔI_@U3 j럿B~ XgQ` CbaǏ_(oi0 !$bʰ'4"ݘ fv&RIENDB`jamulus-3.9.1+dfsg/src/res/flags/ci.png0000644000175000017500000000070514340334543016733 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<WIDATxb?cSG  Կ'āR  X00V?? {ӱM_ۿ,,*bTo4@/%~]@,@12e?P i WfK@? 4~1kIt`at̟@ @U"`˿ L@Mܒ =8^~1R@q D}PL3c vCIENDB`jamulus-3.9.1+dfsg/src/res/flags/it.png0000644000175000017500000000064414340334543016756 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<6IDATxbd10ax*RU baPZ RIJJbb e&ba`?￿@Po QVh@ TFW @` 5 B1bbzh￿%(@ f F ߿T @Wa` @JCv > @c?ܒ o BFFF8PR)#(AlY8@ 8.VwQrIENDB`jamulus-3.9.1+dfsg/src/res/flags/jm.png0000644000175000017500000000117514340334543016750 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb '_1?0~10``c 1U;{ MA%11=D26'. k 103<4 =[p ߿?~Y٫b*do _W[_@ۄ~* & o0zwR_ 0 l_b*~K׭?~Tj  @N}zbi;UWJ| 1FB1bKMG3I:.Q$^K0FGO_w_w@_2<`tc - >sw!IENDB`jamulus-3.9.1+dfsg/src/res/flags/so.png0000644000175000017500000000101714340334543016756 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbTߟ? 1 /B97hh&ȰO@Q]z7$a*8 W_AJ2`8#P@1*6vr? t@a f8gd; _ NR<%* ? `W+ g?$ϿAfd2@,@[e Ӱ_@vy / 3a -W  ` t@12~eHb@G < mxȮIENDB`jamulus-3.9.1+dfsg/src/res/flags/ps.png0000644000175000017500000000073014340334543016760 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<jIDATxb@ ow20\L@߿a$شi@50zt߿7Po8@dHuWo FFƇ?oA)L`j* ?~ht@,?_ I`K $~d!ϯ^XU t?ݪ'xז~_e~-G=۟5Y%H? `|P0_? P 1$@T1p4qIENDB`jamulus-3.9.1+dfsg/src/res/flags/sz.png0000644000175000017500000000120314340334543016766 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATx (>lк,~$ˡdöMC_,ίj ,2 0@OO߿woֿ]y3-fN6 o`@+_mu/0E3(. '1b P Fo>D$? <PKT`$aN::yIENDB`jamulus-3.9.1+dfsg/src/res/flags/tl.png0000644000175000017500000000100214340334543016746 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxLA ]=3=\$IfMNp :J!s#5^ 1|?@?$˦Mp¿Oc/ $ f@ ?/aJAC40 @L@ Gg 6biknn8syI_`?6Hm[CKh @߿@@ /1?P~'a(w#@шU;MlAƭG\Mˏo4{qr13c~$b9@?˿2KsojH/bat?~@]?Dv:\37P@@zn: _p @ @uBO3'_?2 >qE^~ibd@a c8ƒ:8.EiS^wIENDB`jamulus-3.9.1+dfsg/src/res/flags/bh.png0000644000175000017500000000071114340334543016726 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<[IDATxb n/*_1  xyy!*5ü_f? @6i@@._a5w ~ѿ_@ tu761CTĀ#fb/_f=x @@Lp'KKBb1ΜfXoà60@L@'#&j`pm1@AS{{?{P !5@1zJPP$Ç ?~+T=MWYɀwTmIENDB`jamulus-3.9.1+dfsg/src/res/flags/sh.png0000644000175000017500000000120514340334543016746 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb|k9-k۱7=P=CeAo ~10@1KWR)>*Dz5I%Ѯ&1 gK 1/W j1\?c3Z = 1P|8 H)#%wXO~-o.]{6#Ы}t{o8i ?0(g߿ߟ_{3Kq:/(h 0ԀP9xJ:?^)# ~OB ( >0JR ,"&y G9I٫h_xIENDB`jamulus-3.9.1+dfsg/src/res/flags/tc.png0000644000175000017500000000116014340334543016742 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbܟ_CsǧOXp`$0yf)7n0|OJO˃ߟ?~ "ߦN1 ɾ?4 eS6'_neeWVx5N/~SgIXkKj v~L\\>a{g1k2K@51Ȩ! Ƽ /e"l~8_7|ﯿw~b(? a>儕/_>n?bj( 5 h6 "3cϿr@5翤О?  oR_^qc?#C(j\+RL 2%>%IENDB`jamulus-3.9.1+dfsg/src/res/flags/mo.png0000644000175000017500000000111414340334543016746 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd 10` B0 jjed)ϟOJ,/8/~_@ղ<@; &?$)qj? d~D@=@W :?i_5~i &ofu1 Z)Z kVP./P)@1>6"6k,j;;/0  ռ  _%J8Y8wFw?޽h9P?  $ PP)n)]Am}a5bb0%%A~o|߿@#$@ t_ P `)!E?@A>wAIENDB`jamulus-3.9.1+dfsg/src/res/flags/ee.png0000644000175000017500000000065514340334543016735 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<?IDATxbdp~cF@?P(0 v`yS+4kvrOVȦܙR60 2 OA߿ (/ ?Yav?t?@AU R R$ tba״ϣG7B_`FIr4P @)|dFӧO @J/\@,^+%@P @i! 3ӓ/Abs㗿&I8/'fiA 49P{AzK8 (UX_120F8IRS]IENDB`jamulus-3.9.1+dfsg/src/res/flags/ki.png0000644000175000017500000000122014340334543016734 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<"IDATxb`? PL?0qb12g_ߟ?O?> H1=R@ P@o6 ֿ h6$ Csn'397ؖEHsP<T r 1׍EM w xn p` x1{qjDM9jP{R~eQ[wnUW O=>WRSW>_z;_}S# ]Ƞ<ށEz{}ɷK ”*s>H[E]@?@1gt5U9}PH߿/~?~{+}7 1wET(5M͵cq,S_2GW4  8IENDB`jamulus-3.9.1+dfsg/src/res/flags/cc.png0000644000175000017500000000116114340334543016722 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdef?I_0?lsA/oZ.߿W{8ξcT6 @|d&any5l+Ǐ?}?_μa@L "9~)7boV_jl_7L@1W1 Rg7lm"27^"1 } %  ,~ﯿש I'v_ 0~'6ٯEA@,@  ϗ9~/_`@,`H̀$LX ``@,=,/J0~ ~}Y,YY,|߯_pٷ X f ߿? ,qϯ jhF D߬'WR("r@22Pk\8Gd) h6B~@dAV/oEK~Ô/ @u@ RBmi XJp,:03 WE Ȑx= | ͯwKݵIENDB`jamulus-3.9.1+dfsg/src/res/flags/dj.png0000644000175000017500000000107414340334543016735 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb<|= /1p100??~Ͽ"~3~cca p1߿/? f@,@< f*Nf?Ha@ @K7/j@1a_ s3x&b0go'`F qt &A'';æg>_~&VbWb:@,@'1|W|<F"I O{_P?f >CL\22@u # !~1˴ӊ3|``0&` ` |^#iIENDB`jamulus-3.9.1+dfsg/src/res/flags/fj.png0000644000175000017500000000114214340334543016733 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb<[TkؘʟˤK~ 0T ?`?o@@1o]G\+}cvCC_  rҴ/2*ƫj2w6A,?bl/X $@l2HTzB ?xK!"^ 0W1@1=3rcXyoX}fW|~/?@61*( &%*.5WQ2Uo3ó1@\ Jտga~gr$ X  ׷)nۏO  ?F4B{)w{g_2 XI/IڀlF@ܳ/N  F̯ _`W @`8FIENDB`jamulus-3.9.1+dfsg/src/res/flags/by.png0000644000175000017500000000100214340334543016741 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxLA {$mYJ֚a&N 0tg!fKq(|qn@2$EO0|Ȱk| jP H(+ XP Q Rob5ƍ `?9 A?!@  *wRTyPmp@?6׭?i20O F'?H߯_߿Qs mnj)}f $?AOL>2,> X2|TS"'_a @譿@~0/I?x|ڴʔa@0  o7u[TbeIENDB`jamulus-3.9.1+dfsg/src/res/flags/to.png0000644000175000017500000000065214340334543016763 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<Kagdh6Б@~ ??rc0?~Qc@Aj@ Љ 6>f?f!ֿ~|r6  VEĘ!O0PȠ?@FX@1?`HBc ,0eB@Mv=IENDB`jamulus-3.9.1+dfsg/src/res/flags/gw.png0000644000175000017500000000100414340334543016746 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbπd``b?"?$\] $L2m'O30_`Qh@_F߿KAV !~5Щ- I) @l߿Ϛq@ϿdS @2'/ׯ?_aJ|c ~0T @ @@2Tj? S D _II?s /а?q @_ G <700@A aq%#aIENDB`jamulus-3.9.1+dfsg/src/res/flags/mx.png0000644000175000017500000000107614340334543016766 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdf`ba?^cb`$JQ$@25Fw200BLL ߬9 Ⱦ5o@ӫ~ ?7$b hȿ?f߻rY kf߿7a@hoxsꉭw:_~6 ï_ j`%- h?`26d6jwS!A]: l? /@50 L}y NT@@'1/ү_AA 5HyBLLr@O#-8m٘؀|yfkV@TLi)IENDB`jamulus-3.9.1+dfsg/src/res/flags/gf.png0000644000175000017500000000104114340334543016726 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb,zߟ??022*'b ¦$A@? ~mE@40g߿ _~@6x=|Ϟ "@K890Kt&8@[zM"-b봗bP߿@*)qm@@/A00q;^ 7Lh3 |Tt@P?zD_6ˏ_@A]T aUV j=I,$߿@|z?.Nf &H@ %1d@|m?~}ˏ_Ҝ@ǏzA {f uDIENDB`jamulus-3.9.1+dfsg/src/res/flags/gm.png0000644000175000017500000000075514340334543016750 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb<`0D v@?\9Uph2Ah20ߧ ?x47H@&N  f  @Q$ t@40S @~aH'#H DBP1@1~EHl ISf捧IENDB`jamulus-3.9.1+dfsg/src/res/flags/jo.png0000644000175000017500000000073114340334543016747 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<kIDATxb@ ow20\L@߿a$شi@50zt߿7Po8@dHuWo FFƇ?/Z @QQ?~iǢ;&?xYJ$9 d= ߿?j`' P?@=UO`w-+_?ϿJG[H{?k%)J@`@￿ /=P @ ?Hnԯp! S AM Ȇ߿n?4d#IvX*_g@V00H3ċ` P@ L0HJl$"pP1@1~EHY~a`bf!!?0 3ʅ3(OL< #6qL-AIENDB`jamulus-3.9.1+dfsg/src/res/flags/hk.png0000644000175000017500000000101714340334543016737 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb| Hd,fb`   0oN>޴ X@j{(/nOk_@L@V?T߿L@?9鿺:0#ÿ_ b ?9kj̓&q?5+ח/ A@j7;9ߴ?'7 `o5 q4^(8?[gN &PPuMb<d<6?+|XQ_?9c?/P1@?L cYTYP˫W,rr  P1@1>d`Ȍ?q`=歆bIENDB`jamulus-3.9.1+dfsg/src/res/flags/ke.png0000644000175000017500000000107114340334543016734 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb` 9 Law]2-$w>@U;;qX'O<~<-IIw?}[n޼ T @WOTտ%K%&Ȧg7P],}|߿?tܭ;P,9@07Bϔ8b۪dljuyd9#/5؇9FxAZK$3 (N;5,bG/ʟ# ƫ+)C>x0yӟ?$@b /gaf9pd%@1ylJm 3"+)ʈП8~D6!?~?P?bbdgR ~$a0[b=+ `iIENDB`jamulus-3.9.1+dfsg/src/res/flags/kh.png0000644000175000017500000000104514340334543016740 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbda` dC` _ }j@@d_aG _^**?D/ 7H5PWZ @ ZO6 wn3~lA2 tDud]-+/7)P/b_32 gp{x2pp2ppga X6a93' H>OO&&6V` `  1Fv rK0}^@#²Oua`/8X@nz^A{Utߧ"`9P<(LAa/>ڰyЈDC1 AL43UIENDB`jamulus-3.9.1+dfsg/src/res/flags/bv.png0000644000175000017500000000100014340334543016734 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb|rsE]D3?`A @,@Qj )FFF0~ "߿n@,`{H|σ@ ׿_,+  U@_ @=@$@W߿@g@c@e>#sdv@m@$ H 9 @ɂgqq&&=ffܬ? l줷v~|o7~aQVz@d@ g'D/ H'?f ?$A.,_P3@WaQމ̮ 1$`$ZlIENDB`jamulus-3.9.1+dfsg/src/res/flags/eg.png0000644000175000017500000000072114340334543016731 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<cIDATxb| pI anl%#eaw.;R! 09O2)P߿@Q 7H/ ׿_L@ԔISAT j}@LB]~~g-j0?Ĩ_XXkR_MZ]$mmmr}ZZڽ{~/00@$4EEEŋ V@)(0[b_* @NcHIENDB`jamulus-3.9.1+dfsg/src/res/flags/fam.png0000644000175000017500000000102414340334543017076 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd8a`ï ?X@BQ?_L܌Uec??5e {K@  o & ~rK0&%7i>O'*k@ Q T??0 ÿ3y:  r_ d? \zd6P 6:I4CV4I@O'%soH H(xc?/FN/nc 3IC7F)!~Fff!D@@ aWpci6TP ];T@ae/IENDB`jamulus-3.9.1+dfsg/src/res/flags/mg.png0000644000175000017500000000070514340334543016743 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<WIDATxb|= O@XƁ(' $Ra_6m yP@ӧ ϟT@/ _@6,bAQ dMJHR 5 @p @e 쿿_$P?c` j y!}@`/>%ߧ~2@_?QTߟ^1InP_ b@Pz9H?/@1>~H3<G)<&I$cݛxIENDB`jamulus-3.9.1+dfsg/src/res/flags/bm.png0000644000175000017500000000114314340334543016733 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb<^IzzK,L /eeDI}X:?0F@13kX:ɧƲeοu ׵8c,0Z]_/߿deV4U-7}(Ω([~]ʕ χ))@W3_< 31ۓ_?kM'I@ 1try!H kJe[\MMJyů}y_9t/? aT/ O/cֲsqp X@! 8P Q %Y rꟿ@4UR<߿_ ĸ,"X-$@5K]IENDB`jamulus-3.9.1+dfsg/src/res/flags/tt.png0000644000175000017500000000115114340334543016763 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxA0ڧr%tF~QWkf1xy8 \y)))DF2N?i@17{hooqҥ[n]s.,ׯzD<}@LB e߼тObBW 11>D5s-;;3g~?AIDATxb#L) @,@?DN!/^ Ld@1  PUcvOw?h?P m_N7n|"gbb_?p1@ 03 ֻo^a; Xƃۗ3ݼ0xW{e95Cݻ[>>>dc,HwAb0]/uTIENDB`jamulus-3.9.1+dfsg/src/res/flags/cf.png0000644000175000017500000000114614340334543016730 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbԿ/Vҿ9~axA/c 2L1ئ}2k m<n_9loO R? ). {2}RjL{D`bjX~ @AefxG/}cq@m4h}ݯ_ZU|~>}ûw޼yo/N<@, wofk ˟ -W~z+n `/_/Τ?WCrm~~Ѭׯ >~+W^|ݲe@d?[/i'7 GJJ-t΀!0eb^0#i/_2|t1_@K [.˫}feqQ?b`x?I U?(?A"?>30|`.D [0+IENDB`jamulus-3.9.1+dfsg/src/res/flags/za.png0000644000175000017500000000120214340334543016743 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb`hfh_~ 7O _>30|d`x 3bt#,G1?1MY3_>|yrDo_XHݯ(+ 1~!' s1h$ LGㅃ-Of A 7o4 Xqwxǟo? ' idxDxߝQC&,~}lS./xYde~3KI7_0.6Iؽu/^? @+HE]ϋ"7hyg}c0H] 2f/` F ` B._CIENDB`jamulus-3.9.1+dfsg/src/res/flags/gq.png0000644000175000017500000000103114340334543016740 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbA10da &~Ǘo&߿_0￿7@,@]|>< HI4 Y^Yo #? AH-@1aã?~0B˗']8& ~aOh` 0 ?D3/8X٘8>}(L| bb0ā~}@, L~ h?'Pϟ@:@, _>"&OX/H5p|,210 û71 `C&5aIENDB`jamulus-3.9.1+dfsg/src/res/flags/va.png0000644000175000017500000000105114340334543016741 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb|}^; #=&Ͽr?P5 H?E8/^`?Hϟg`??` ! u0 @fϗOP@16lzE]?ÿ``4g'O7 X}b<ٿ~.%>iFǎIɲ1 E +Ż7ؙߚ勗 u?P@<Y?n F&F&FVEb20 pN!!`xw?ÿe I ?hh0SF.7IENDB`jamulus-3.9.1+dfsg/src/res/flags/es.png0000644000175000017500000000072514340334543016751 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<gIDATxbπPX@_upɒ2ҒKF6hU wg@ տCH($ f@, 3}^_/03f`@1 T?'00t|}/jb@v_1bØUzW[Fz@L`EO?Zf]#l 7P@11Ęw/q?̆@7  200w,0Ɵ 2x XfARC!@T @_Q#OC@ ZGIENDB`jamulus-3.9.1+dfsg/src/res/flags/eh.png0000644000175000017500000000077414340334543016742 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb` ld`  U__$ ?~bZݸ X:?} (~$߯_s}@,JU @,"R"ܬ `̙'Oy9PCKKٟ?  b`  f+WϚ@j@P)@1셫-II׮/BB9?N) A߿u,aTRzs@(7(x70   "MϖxbIIџ@$0oЌ;@ ~j9v^f0 O :uIENDB`jamulus-3.9.1+dfsg/src/res/flags/gi.png0000644000175000017500000000071714340334543016742 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<aIDATxb|= B"3ϟ?@ X@m`8߿ MP1@A5@s-k޲UD(; UИݯ_jZ31!ԃm 3 00p3Z?Nv_vvS T @?EY;x D߿sͬx(/i Lׯ2o?*-@S~T=Z@_^AB@ ?Xj0R+7IENDB`jamulus-3.9.1+dfsg/src/res/flags/mh.png0000644000175000017500000000116414340334543016744 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdf~c~!61M2' &T vABF+w\з̜?8*") 11221CLZ7#`3+;y?Wqo/t@1 [ H'96^(1C^+*:)줆t$L 5oV]w9pы_@` @K~3{!/Q=&]'_:7?j5G &o O޴S{޿?P&ߠ ?iQ|f|C_?/1Na~@sg``xQ4lKIENDB`jamulus-3.9.1+dfsg/src/res/flags/nr.png0000644000175000017500000000101714340334543016754 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdg1$  P#x?׵W bR?4Hʈ @S2/0?j0 d @, \03?Ю ׀ā ޟ^@,gҰ՟`d07!qS/@(K>~a#{O_ϯ 7]ϟ`W)H @L @glӞ/p0~]zӗo?}Ǐa4`O  &9w a?0S f@i FK(-r 9IENDB`jamulus-3.9.1+dfsg/src/res/flags/sb.png0000644000175000017500000000116014340334543016740 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdf>"UYyZ߿10Br10<h1VVnn..J;>2 c1Þ'44 w_,+tgϯ_@b;⺗ 'ɉ @,"ISXÊo~fc4fn{ϯ`[1쾾ﱱ H8UFߺ_v}zq|l*goW|￿mz/j2~bKߩp/y[ 1h߿ ivU叿f ۾ρ.b~j* X"M$(9?YeEJr?Pdb<>Ôs {10|g  +9IENDB`jamulus-3.9.1+dfsg/src/res/flags/aw.png0000644000175000017500000000101414340334543016741 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATx, (}XUِ9 aJs9H ͗DQbykIϣk7G`` -?a1b`ҞAſ A< ӧ_Zg_@*TR/B@/,l~%߯PK"/!n &a}@,?Av1hd `j ߷yt< edse@NOCf[*v=KkU"`0Mb'(H =@60K!?çF$(:_h2\,hҪUIENDB`jamulus-3.9.1+dfsg/src/res/flags/cu.png0000644000175000017500000000106314340334543016745 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb긜7 0 H0DE?? ϟ"sgOϞ%%a`?`Ǐt9<}ׯ  a L22211Gvf3߳gcv0r %9n , ̿Nḑ]__@ b`@ v`?˫*ZTc b|& 00;ϟpehH`ËJ~ EzgM a߿?þ9xTt&4RS0 L ` SvepIENDB`jamulus-3.9.1+dfsg/src/res/flags/se.png0000644000175000017500000000103614340334543016745 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdpndu ?_~a Xs=1onߟD@Ml'3{@E07/bPba/_`P3йAF2_@0o&#0oFvO{  0 A!T I AEBHH#A8, ڒ`篲Ifد_@ՠ  0D O)@a`fԿ߲B<_9H FdxD@2B s$@ܹy'IENDB`jamulus-3.9.1+dfsg/src/res/flags/si.png0000644000175000017500000000077614340334543016763 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb+Df(?Ïsq05(|@,<~=󿿭 LLFFF%,xxBB,~? CB}CO~ԙg[s=bof_@ ~ɿ>f`x@@'aW"__`b B Xcl@@#0/ïPL@ӧ@gr2:ן@@%'3L /vo!.7A?T=L@JJ@ba@/#0!!T.^\1 Pp,IENDB`jamulus-3.9.1+dfsg/src/res/flags/pt.png0000644000175000017500000000105214340334543016757 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdd`Xn2"baPZ Reˠ?a?aM O '׿ٖ_/jFYY 6 MöXo߿ 访[e7uZ_h:@11b￿Y~' L~f)Bhh@5d9_"ro$F_GX''o|Wj`(@ ov_X5D`X X1G_@CA7 P/j /@ ~0L ?cc0Fv|IENDB`jamulus-3.9.1+dfsg/src/res/flags/gn.png0000644000175000017500000000074014340334543016743 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<rIDATxbπ5|c.c`F@ X@@@%\302af;&ϟMS7XO2 Df`o~T-#  Xf Q?` @Ư_ D@ t7#P?an6DÿH4I@f#i$!@`'i%6 NU~?=P@40Qdm@ `/@ L0HJ 00fd L @ +8*?1h4ѳo 8I313g!=IENDB`jamulus-3.9.1+dfsg/src/res/flags/io.png0000644000175000017500000000122214340334543016742 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<$IDATxb^ۻ\g 1la700a`As0@1[GI%$   &C1  >{Ue;UM.w~S_([gIYit ;?1BP" 1 ̷R=<.Ϻ.IÝw4LUg#,\4_ r[fέ F>?\?L[8)~Q#sdv@m@$ H 9 @ɂgqq&&=ffܬ? l줷v~|o7~aQVz@d@ g'D/ H'?f ?$A.,_P3@WaQމ̮ 1$`$ZlIENDB`jamulus-3.9.1+dfsg/src/res/flags/de.png0000644000175000017500000000104114340334543016722 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbqf?f_ pb{qq9 / ~^n5@011U8y $?A~N@" ,X_@:~"?~@Ne@b@ь7h4LVg2-K , z#2ׯP `@;D?H%@1??ڀ T /@b`PPI@҄ab_A*$B$b`.a ?FL A@@@ X~e3o?6fA1?`@03b21@wt_XIENDB`jamulus-3.9.1+dfsg/src/res/flags/pm.png0000644000175000017500000000126114340334543016752 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<CIDATxbTMf8#?K^ol``  0  1Pmf{5>w+G!:;!EE @ B?>~I$&/1WG Ƿ^dꬨЛo$E_h* 1sl!^P.'.TLARK@߿c￟n߾c{?_N10'/$ :*E9̎r1 nPx =N΃17 3qrɰJ x]r?'3c 30|GtwD?6ps c RIENDB`jamulus-3.9.1+dfsg/src/res/flags/co.png0000644000175000017500000000074314340334543016743 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<uIDATxb|?(b @,@ !j@ /P ۲ X&OJ@z@*~_`]h @ȼ` Xe`l0d0500#/!Ha(~hIba~Cd0ofk1 \~ XM($\>@)+g8@,l ~0I D a @w  DC@`k/|IENDB`jamulus-3.9.1+dfsg/src/res/flags/pg.png0000644000175000017500000000112114340334543016737 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxLA ?I6IL#9.&Ө 1 "X@0eݚ6p7g*|b")Ky*͞bjxSC__7?bjh߽mWi~w?H @ϟĘ%G_~_4bi`aa̜1}Vu~_~ 8@J}K 󤈰B5E)헮iWSS ЈMff ?  % 999wܙ1cP5 !Wٟߑ2F@4GRRׯ_ S/+@1 @g4IENDB`jamulus-3.9.1+dfsg/src/res/flags/kg.png0000644000175000017500000000077614340334543016751 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbȀ`$2p) 0أꊐ{3# pzU}ߓ @7_F ] ($+  XGfߌ~.` @T @L @΀ΤQŨYH/%@ ߟ(?/~}20'od/b˯O~BU-: ~bï_fd`]P1@5@<uկ~1ן}N %%A 1@7#ِ0$b|03v!f Tg_TIENDB`jamulus-3.9.1+dfsg/src/res/flags/tk.png0000644000175000017500000000117614340334543016761 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd> c&y?01{!4'0$ %+ dÓiϓW#X>Y)voEϝ)#X#6t@11?~{U|@wyp+e_Nj@@}?cvK~Sad%'@e@ e{ֺg~fxoxG@#\+z7V_=J'(U'P1@l ǯ xع??w P_.{0~J;ayI^@120FK/ π1000e@[%tIENDB`jamulus-3.9.1+dfsg/src/res/flags/am.png0000644000175000017500000000076114340334543016737 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbׯ0?1@1QW)'veýL02 OW001$T~joF ? t &B5&a2~: XDf51yۿ*_2HW7lWAouMp~ 8<Ý q 9^?(T_?o?/?[ŜH@9jp=X'2000#F F ?>0^o ~1 01 ?Hq ͦWIENDB`jamulus-3.9.1+dfsg/src/res/flags/sg.png0000644000175000017500000000072414340334543016752 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<fIDATxb|ׯ?s$  K)f_|I[ǏN1?|i@51kk>~Ϟ=,?,`cHݯ,+  @,/;vp VWT7P/@@ '>xښ~ 1HU3 XVrxx3qq l0ß?0JJxxLLLo |gp,?f0 @`! @, xB4`OVY}IENDB`jamulus-3.9.1+dfsg/src/res/flags/england.png0000644000175000017500000000076014340334543017751 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb#߷/礥10ܾ P?T'zQѿ?#gϞ D\5H߿߿@@,h!$P_J;@= Xdt89@yZ.a@j.S[3bi!/ 0 X̬@ ɩ`Ucga?@123x@ D߿UT.6] `f#' T?  ϟ@ PPƀ(c0eA IENDB`jamulus-3.9.1+dfsg/src/res/flags/nl.png0000644000175000017500000000070514340334543016751 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<WIDATxbπPX@`U 5/w9~LO)V*<'ρJ@~$(+  XD 3T j Ə??< AT40Ved@+o>Ƞ_^kן $߿ <{;g óOzH߯@u5@H?p20 _ uœ#@?`@hc`FDB2kgIENDB`jamulus-3.9.1+dfsg/src/res/flags/id.png0000644000175000017500000000065614340334543016741 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<@IDATxb//P_;P _ ߟ 7q{"ba`9H_4 տ,%  X2VT7Ͽ߿@_ ?@9b9׿_>jP~P@r`r2 ? @?0!n{b###H=>Y/ R4mhD d@@.H @~h0bvBIENDB`jamulus-3.9.1+dfsg/src/res/flags/lc.png0000644000175000017500000000101014340334543016724 0ustar vimervimerPNG  IHDR ntEXtSoftwareAdobe ImageReadyqe<IDATx4Q=kTA3o7Y7F0! M@Ơ؄P,&bh*kH*6@A,}o{sgހ|{>/b첌tm D&Jath# MHCy7 F$FQ H6ʭ|+8;B4yGsnJ[/dQ*0T+:1@ƕtatFQUՕ:& 5ʺF!T5qh̒Z%`YKoTy}^ +y}$ͳ, [놝 ~7O E;*+._ІP@,~ z̀ dEDtv˿י0/0"~3ˠt3@IIH(7#B bb b@I@sg_IENDB`jamulus-3.9.1+dfsg/src/res/flags/an.png0000644000175000017500000000075014340334543016736 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<zIDATxb#A DϟH$@,@ >>>  ϟR3b*2>7!FF? j ~!k;@1yvvNut.}}  h@nϿӵ5~__o_D?tҟ_ |T$mǓ@ze`@o߾燺>zs@<:jP !W 47t 7 QBÔ C_aK!H(@L _-X gcb 2A  :f @,L_= tr17㟿 7 *p4ҌB#G =4(d| %J:`7YOEIENDB`jamulus-3.9.1+dfsg/src/res/flags/scotland.png0000644000175000017500000000121114340334543020140 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb|C[\b`b?_`ýw w?H;@1|&ߦG/H xۤ0E.fM;@̇.[21 <o{Ǜ;lm$=eX 7=\ < D8|!#b l".)ճS*=g˹; XvgwbR̛@{=-[7boV\' 7ٻ/_l~c @60ϯd k8]kd_9~N0*s3aaG_(_V`X2ñ gT~OfF#=TxδF @1ο,F(ew<[7?ϣk1g @Ƿk0r0H0|fR P+@@)KӣiIENDB`jamulus-3.9.1+dfsg/src/res/flags/pa.png0000644000175000017500000000100714340334543016734 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb#L)aa @@,@y>>> 2^ }כ6 g9qfLR|{ϟ~U3 $/×@Q&C4"b^?8 X)Xo߿6VKWϿ2I?~b:$oF11>o BY*&&?ߟ 0u '׌&LxS/0?P_w^  XN't=0d3TfMMΞPtC \]ï? _@Pp?y] z-IENDB`jamulus-3.9.1+dfsg/src/res/flags/gu.png0000644000175000017500000000077514340334543016762 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbɀb„PdMR@ ?@ܿ7P ̨ /߂U_໥LD@=K3a` & `{pć @Dm: 79ǿ~#P@0h@mI߮?u_Fbv{& k7;/Y* & \_J y̯ߌjiwۘW1*z,T @ '{Ӂ0 kFjzbb? 0HsdIENDB`jamulus-3.9.1+dfsg/src/res/flags/bj.png0000644000175000017500000000074614340334543016740 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<xIDATxbd 10Æ Ck5H@ 3&J~ XX|}߿2cG"Fe Ȯ@7#єBH@ 2/P?HP4 yma^Ӏ"yf3up& z/Xc/$o`(HȨz~@ @9@A4@TC4j/HrK񗅉ߟ<@#߿t@1220|G/021T4$k<@+IENDB`jamulus-3.9.1+dfsg/src/res/flags/sl.png0000644000175000017500000000066414340334543016762 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<FIDATxbd8̀103` 0@1n⨷8T۫BdeX%Nt@ O?Q￿ TR׿_44bUaWd ߿@PiEYDJ Ư_sr2- qFFG˿  e@ybbսX\,a_,_\ @\|1{߯_ a@ zp20\ `JKJBC;"0 a%"?$1Rq}IENDB`jamulus-3.9.1+dfsg/src/res/flags/mv.png0000644000175000017500000000103614340334543016760 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb| p(6 й'$PdK|K m @b'O@@߿?$+  Xvÿi-j?X??PdQaYy?1e@r1H3Is 2 E:_@ '_S]]= `? r$t?cd<K.d+ ou@2wͿp߿_T NWqyP߯ j`Y8P1@QR jH$ @xb110iK0{IENDB`jamulus-3.9.1+dfsg/src/res/flags/ph.png0000644000175000017500000000103214340334543016741 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb\vzp7/  aP ʊʩ!\c3dҀH/(U#@߿۶ɚ5}/eeo@L |cbZR%+?4$bH=f`tm-z??!@ X>30<\ W}n?t՟_ ?NP2gcV?[) X.ka`)?kd P-@5|e`_afY/0 K/?yA@`# $ A@_ ` mL7!U_)IENDB`jamulus-3.9.1+dfsg/src/res/flags/lk.png0000644000175000017500000000116314340334543016745 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxDƱ 0%3 Rpqg ҈3O1v=ڼ- `g˟??\"bd _@K]7-S=!(ﯿ_{|{  ߿7_sAn;7'Bn&( & Hj/.7r3K%8hbZT / ` S/?W} XaP X_H?ٕ_h@؆~7I?~><ǟ16#bF \,L2300񑍕ֿX3{n#RDPe}`TsRS_IENDB`jamulus-3.9.1+dfsg/src/res/flags/la.png0000644000175000017500000000106314340334543016732 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbˀ 8a "[36:u${6kz?XB߿￿џ%61"p#YFϿ~cǟL2\@T(AH/@1 ab|̿`@ ïcx |? ? @~ TN{' ɫuC@ @ ) տ~@LA`rjeAG @@h1ÿ0p@@1"") Bzf?IENDB`jamulus-3.9.1+dfsg/src/res/flags/uy.png0000644000175000017500000000102414340334543016770 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb#"AL8(MX0 ,=Ͽ߿~2ڏ۷o611``XgN?8c011]q Xw&e`k߀ An\@q0?ln? t?YA3 ho?^p?X_ @,E;0}|%8Yf +Ɋ?y KA0ϕ"@!& 5#l}`87$? t? o-Z@>4!,?`?(YL ̓"K{IENDB`jamulus-3.9.1+dfsg/src/res/flags/fk.png0000644000175000017500000000121014340334543016730 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb_XCrɛL~10%?hTc%e< '? ?~@ 1;3A 1Q1<5e; 1H|z"'۞?_~ 1J^I 3 7M+ m׶E"A~ן.Uf?Y__9$j ~L~~|?a'ןoA6 C~7/{)aSH?;0oϿ>gxׯm=+ _Rhi@b`pbP? _@@lYy R\?iVo 4ᯜ0'8@iPڦ aF\(`T #X$H 2y4 6*)1 _?VIS FF0Pmb } (hBA o} 2C0%A  3jc@123E1gb0eWIENDB`jamulus-3.9.1+dfsg/src/res/flags/ie.png0000644000175000017500000000074114340334543016735 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<sIDATxbd10ax򔉁 ă??DTc 8 Ck5T⌌@ (ߟ11 XX@O>/|󅗕?|QXbh2P ?&_@Kj ?P_HP1@= 4b? lz0,rI`'HoA (t=@'1; 7aA XInI7eE###00)$bd(e`cP|`^]K @7dJr IENDB`jamulus-3.9.1+dfsg/src/res/flags/tf.png0000644000175000017500000000101714340334543016746 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd,g:b13 !/@,@~@ 322t2O߿?@?L@ xj |_߿JK0M0ᘷ4les {S+X~߿@b|/_"7` v P3w~޼Mj@?00 3ga;7?oj[}_ïܿj w,ވpQg}yo? 4?滏z>)Lexp/Li_?@,L< ?Vn?2|bg`?0 F| ?"CA@!#IENDB`jamulus-3.9.1+dfsg/src/res/flags/ug.png0000644000175000017500000000102314340334543016745 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb` #wt?0֟ V U?A 0fd}i;@c`J1 X_ ƿ_ 3f;@,L eo |;Q 12߿d ?? t@25{VQQQwg߿BS@,@ϟ_=ocbbbVy R D@90 _~ree =( 4 ߿?10˓'yBg: 2A9,ll ƿ222pF&>˛sed60@n ɓX}P8( P_I9bz  ?W@` X.II1E0B:0,"!E/hD?@|(IEPZIENDB`jamulus-3.9.1+dfsg/src/res/flags/ch.png0000644000175000017500000000055714340334543016737 0ustar vimervimerPNG  IHDR &qgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbπP@, ^u5###7Ï0gl`S-d:II$/T~7@hYe@ׯ@ 020q/@m,*~  fe֭PIssSeeR@_@q)@T0HQ|?ڀ)&ǏIENDB`jamulus-3.9.1+dfsg/src/res/flags/ar.png0000644000175000017500000000077214340334543016746 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb<a Ͽ?E@󏍉 X>aHU?@ÿg/\= X~a @@K@\([?b})& h6  `> $YD:?a6bZ }/2q{p f .T B?2@ f`cN93@\O 0r+T l, @,YJ^~<@C4A'yD Xcd`e_`Ȃt2@ t78N@~ ~} ?@H-(l pmA`IENDB`jamulus-3.9.1+dfsg/src/res/flags/cx.png0000644000175000017500000000114014340334543016744 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdgYDf@120nUa;O?? (gߛvl 6o\O85:~o@=~Do:e6 kV|4߿W۔I@1U*qs1y!kZrcįX_ݪ~vWҕ_wic)*IU~vO vR̯}$j`HIz_~_~>ʓ#kO?~ T߯@j1S__)) ﯩ="{ll! ??B0X@ d,? 3XTR"@Cux23$KK0 [+>$ڰRd"G/0   P=BeIENDB`jamulus-3.9.1+dfsg/src/res/flags/cn.png0000644000175000017500000000073014340334543016736 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<jIDATxb@@n", @,@D}5o,Xx? $}m&i,7۪f3˪ u~,@K/k붿fϯ/AJ~I( X@u8M~@Uk q8V7T@@ / : D UM@ @ĉ΀l0X X@$P (7xX_bb<Ȍ?Ha `:s056IENDB`jamulus-3.9.1+dfsg/src/res/flags/pk.png0000644000175000017500000000107114340334543016747 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb#|Ez4 f1XH1߿ߛfl 㯏? e_ ZGh@1ATC?U+[;F,,@A5%$v>>  $" ={@,A|aX ߿joaϟ?U D ?x߾KWl: nC ˖aj ƿ!!?|Лџ??VV z1Gͨ{bH=#GQT-fhbj`r~d8df/^4cP 2 ,@40 ) 2ft1Q66G>|` BBP1@1~(b@I@[JăIENDB`jamulus-3.9.1+dfsg/src/res/flags/gd.png0000644000175000017500000000117514340334543016734 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbπ:^10203_,?!1@@1e`X:^ ߿bu  X _qoz4&̿7H)_f@,L o˿<} 7?~-y{ś__~1@, [#-o;@2&ߌ#~-x߿?b4@3-o?12<_@ t?3 /L o{/ߌ @ '{ï? x~ fQ~p׿?3ی8_~˰n,_oM "4H2f/l@60~=_[wb` Ư XA>Oÿ Y0B/!iIENDB`jamulus-3.9.1+dfsg/src/res/flags/lt.png0000644000175000017500000000077414340334543016765 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb}D $l bb j&f2?P@ÿߟ. &Fg  BUh.@\ _@3B7`0beu@a(s˗? /_ 6? X~0i)Ii@h XϟB`~h@T @,k[t hֿ?e`/PN?.2?_J?0.?Y8z00/fKJ  $?`` #rāg%"wCݙIENDB`jamulus-3.9.1+dfsg/src/res/flags/ls.png0000644000175000017500000000116414340334543016756 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb|- ?@}r8@,@/Nգ3^ BԣOϯ~fV~mv_@?_[= @1 &:]'<^O䇗w Ji000>Fj?|׷b~o `1'@(@]ۯ>?z,o~ Ÿ@  @^6rgo~ϟ~1KϮ \`x տ1Mec`z<&I>mP!j&@IENDB`jamulus-3.9.1+dfsg/src/res/flags/qa.png0000644000175000017500000000070214340334543016736 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<TIDATxb?(/IB~10 ظCW߿&]|-@@^T" ~I!ibBV߿FZ `_  Xh[\U2/ PA^c & -? UL P_Rr/67H@1?l/ jo`5 Iq:? H%@1~| ep '޽@yY @k}[T^YIENDB`jamulus-3.9.1+dfsg/src/res/flags/rs.png0000644000175000017500000000064714340334543016771 0ustar vimervimerPNG  IHDR ntEXtSoftwareAdobe ImageReadyqe<IIDATxtPMK@m6\DZ؜{UQG7QDWգ TQ4"q6ff罙 Q3Ÿx">HvdyȘE>_+*7>ao $k ;iܘLZ=K/-]wT ڋQߩθŒ*vd2렌\4jMxo\EunF8%dQAserw^2 :DBWNomy T,+ C$۶azyhBV -? 0Xx<4IENDB`jamulus-3.9.1+dfsg/src/res/flags/km.png0000644000175000017500000000110114340334543016736 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb_0Cg@@.D€e{j7%- @ &pMg>J~ Ӓbg`FF @KȢ/?4+ ZW 1Y\]OQ͞NMGK//zzHY`Xٿ=@P FF>_N^aA_EVS̠y´˿oo_ ~1LX\@P*˾Xv[^ r99I? _ qasG_ ?0__6O FPq'k1|`tI0?$* Z4K.IENDB`jamulus-3.9.1+dfsg/src/res/flags/pr.png0000644000175000017500000000105414340334543016757 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd`@_ 0b1 XUa8t?o 2N[@ k=󪰚W@? 01u @6pXn,X?13ca 1FF0>PǀI6c+VP n0ڍ7~aP_ 7a@nWȯ4Guve;z ]x>PwYLB\FFg׮?0ݩ_$?`H-XP÷o{vSujc@2j'6_[7- -+1UIENDB`jamulus-3.9.1+dfsg/src/res/flags/hn.png0000644000175000017500000000103114340334543016736 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd_ݯ.[ ? T"ПW. _~ϿAa/?'+ X'x:J| A@V@1<Wϟ~Ǐ7_/_Ǐķ!YXŪ// N6F?>(_} d96 ?01'3sW   jE} p116(Ŝ5 1 ("$!! ,*WY"12: rz1$ "V'ԙںe'nu ßߌ~ɯ_<c@`UѲ h@00]ןʯgmXNy6P.@_o@5+ ([ @P矿 ح+~0@P? ~8 ~~b %bd`Ѕ(2  %WIENDB`jamulus-3.9.1+dfsg/src/res/flags/gr.png0000644000175000017500000000074714340334543016756 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<yIDATxb?pb4x (" P]L3S@  ?ÃGѣG q02Ttxb(nߟ/$R? @1[v3أ TuhҶ ZPW0@֭G̍7s%CH?'˅Cwŋ7""H"31н@{@,}eI!fT apq0 Xy$˯@_y=$"ڹ&@1޼QTH(… 0:{ 7C#??;0kPl~IENDB`jamulus-3.9.1+dfsg/src/res/flags/ru.png0000644000175000017500000000064414340334543016770 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<6IDATxb?BAX )̀l#/ dj?6 ==gd䌿 d@$$XX XoH7?_Iyy?|4D/ THRH\) @@,5|HӟD efE ?phU=L0HJ倢 `g1 H W*M  ?e8aIENDB`jamulus-3.9.1+dfsg/src/res/flags/ad.png0000644000175000017500000000120314340334543016716 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbL?~bZ1I?~Ea @?`d1\Oo04&@K M ;1㤭YL0"5bT_?s' *!@ͽn202 TMbar H1cd`Xy1Ph HHP@_CW~xPP?ДSނg m! tɏ/nV7/π2$bL^ @P6в@`IEt|rIENDB`jamulus-3.9.1+dfsg/src/res/flags/bn.png0000644000175000017500000000117714340334543016743 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbzPƿ? P0 bl0 07\Q :F+@BkW+PZ8&Ԛ/X 3D3տ~y'N_~f`/FV=aem [G~(?``߷~[1wyybhh" yhpQQÇ?V,T?-O`b|Q~fj$ׯߝ2Yu޿1u#u311cee555Ev?gA>w߿~篊ŋR@9Ff?LlV} O<@ӠXF_Pdbad4 paw p1iIENDB`jamulus-3.9.1+dfsg/src/res/flags/lu.png0000644000175000017500000000074114340334543016760 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<sIDATxbo??_ÿ  X>al 2/ӟ!0KS'@0ׯe? U"Aߌ@/俒*HP'O^ ߾}+((r ` 022~ X ޅX##0T@@ ; 9s cC pA;eO>_p0@A.:47ß@i=~c00b/`_`LA $@yk ߿IENDB`jamulus-3.9.1+dfsg/src/res/flags/mt.png0000644000175000017500000000064414340334543016762 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<6IDATxb#ÿ LL Hߛ7< @,@rMmm-FXX1?/6˿?ܿٳ?)g QVh@0hhh~)7P@{  oqUgj?J|$N W7P$ /߿@5Ăq 22 @A_ @ ޼yւWlAc0M[yvIENDB`jamulus-3.9.1+dfsg/src/res/flags/bi.png0000644000175000017500000000124314340334543016730 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<5IDATxb*/*~e1Ǐ?c` ?OĨ\J= ɓ_ae @m981<   , 39]`,-)%|yҵEOM`~C1xNIo=x0pM  Б <\~/(4!1# /ଜݢ! )  Hu?|PWz5%3_]Hƛ1e,i73feqp놅0Əϊa:@};~%"x߿C$n7`ee>3@aC얯& }h&tIENDB`jamulus-3.9.1+dfsg/src/res/flags/jp.png0000644000175000017500000000064414340334543016753 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<6IDATxb+Df($SHŋSط#of h @^…Ç?}?9Bb$ի/(ZpK@LG`˗YT @,@ gV h,))* &@ H :sqߵ L @@1}. e@?B޽ @ ޽{H &l争=IENDB`jamulus-3.9.1+dfsg/src/res/flags/fi.png0000644000175000017500000000075114340334543016737 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<{IDATxb|30I`2.?A0bab`*kƿePr!ڝ_l8Dٛ@S`dd@5_ ߟ?$d 15#o~ @m@w?Po Јa_հ tl@ 4Β*NW7T`S9bad%Pj" /c`dxqh*Ws'>~@0cfr @V@5:<Yƀz;@"rVQ_(@>}`iIENDB`jamulus-3.9.1+dfsg/src/res/flags/catalonia.png0000644000175000017500000000061614340334543020274 0ustar vimervimerPNG  IHDR ntEXtSoftwareAdobe ImageReadyqe<0IDATxTMKA UUŏPԛTxAUۃ+ Kw233;KLƘj,TbU9u f(fLjW'YBHZYer$3L +Lt؂1ç//P0?`dd@1Bdm^G {}הwl1EBEjk]]vzCƔ?__L?b @t-[=Gi ? lĸA뻽KFr?\{~20 aL@7JJs"YY@ $ A@pĀE\*=MIENDB`jamulus-3.9.1+dfsg/src/res/flags/ge.png0000644000175000017500000000112214340334543016725 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb|5 BH2e?0\ X^8Ϥo((?ï~KJhj )ubwgxgO><~ h@l*bua7p?; Y@tր?101߿s(P6v3ӿo?^ˏ3D?6o;Porr_ P&3UF?mI~&;G6032IPm.1YTRM瓋 ?6}k۷+ &ٷSw,v#37oͬ (.'###;$ЈCM_h'\: ҶNsKIENDB`jamulus-3.9.1+dfsg/src/res/flags/bs.png0000644000175000017500000000101614340334543016740 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdfb`ccc60 R18: Mǎ Ȱwܽ7$䯨 =1~D@m x?3wn +@5@ f1~3c@4x1Fz`!J {ˏ~_P@ma~ ~'5䷬"7P@lׯ?A~1$98 ^/xJIENDB`jamulus-3.9.1+dfsg/src/res/flags/cd.png0000644000175000017500000000102014340334543016715 0ustar vimervimerPNG  IHDR ntEXtSoftwareAdobe ImageReadyqe<IDATxt?LAƟRL !LU8 CL?,jX]+L,4ơ$~URЄ āW^ہ{{=V;ߵP(> P ҃/]͐n9ʲ<[r-%M뇻by,Aˈ0f3tg?M^q,zZ ,|ik` +yV3> BA 7`+rԁKhu) $%{}р᫩l@Ҧ 7j `:'F3[PePP\0L"j Х#5FxL:_zL1^Q+f~x&x5^IENDB`jamulus-3.9.1+dfsg/src/res/flags/bb.png0000644000175000017500000000111114340334543016713 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd`nds1u> Pz'?L2_ f?L,c/o0 X&߿bïe%6h?@3n~ϯ?~@, wUD/ _6oC_?/ ׯ`Kj ?_mp; 6 @@ lï̿x~1} /x@J;߿@~ b4 ` tOVa`GIAa X D o7/0cad` fg{5̽IENDB`jamulus-3.9.1+dfsg/src/res/flags/md.png0000644000175000017500000000106614340334543016741 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdre`a`?.yAHJP_Hf?of*_9?׿D^3mŮwaf20~l@K h˿ 0m.KOj @ Ts?8G?ϟ~AT Tq٫߻z'@?5_ @ l?_CN]?e`?6 ߟ?u¢w>A["``@s$>{ۀ @h:@l_Rhb2@{{ƏY3 ȱ@ ;@ Tj/ `@IENDB`jamulus-3.9.1+dfsg/src/res/flags/at.png0000644000175000017500000000062314340334543016743 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<%IDATxbπPX@_upɒ2ҒKF6hU wg@ տCH($ f@, 5DŁVY?~&.ovb|򥨨(ؖ `J!$77۷o$*8; BV?bXXk$_oeߴ˿4Xa%!?at@CIIPEr0@HT @_Q#OC@|WZ^IENDB`jamulus-3.9.1+dfsg/src/res/flags/hr.png0000644000175000017500000000101414340334543016743 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbπPX@$?߿~eJk`S(ZG;(\~ee6pտZqܔ~ R   ߿}/Gǟg03ӷo߾~ sj)/'N|@O>  65{jU@Ǐ!p{?}~|c:}$5" YL5*e 0q az@$ bȿ`$X@12dU@ Df08v%3%&IENDB`jamulus-3.9.1+dfsg/src/res/flags/om.png0000644000175000017500000000073614340334543016757 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<pIDATxbπ d`   PÇoqYZ>oh(?BϞ= ?{ףGXA##? (,&a66%R @'#*ee?f~/ ׿_`]^?7ï_ @CH$V 4o ~3Jz @_J~_ l[mg P(r7P'PBr뿿e@JJW /P {*T@1e L&20iyx9IENDB`jamulus-3.9.1+dfsg/src/res/flags/vi.png0000644000175000017500000000115014340334543016751 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb#L) @,@q]ƌL_ IE߿} 1Z@1 Y > L:ei  s 180 7 ioO^j=mQ}FX^q☙߀ &97o~ g;-W2WfvG޽?(۷k\AFOot߷9oOJIqܽ{ X A*LKz/̚_޿7^AԔBQ $995~|v劐_&&FFf $fhqhZ E v&[IENDB`jamulus-3.9.1+dfsg/src/res/flags/nf.png0000644000175000017500000000113214340334543016736 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb`pf{g~?~||ڽAsllxw)^)οNNMn{kH?|߿ ``AVBk V} t#ñǞ{ݳ ;&0g @  ??t!m~j &_@3UE-; ?`/~YPAm  (tȰ߿{˧߿yuo@=4_ bRY.Y7_ 2*@ I~I6VvMNMq@ʢ* $z@C86w_CGˏ/MZ >T GHIENDB`jamulus-3.9.1+dfsg/src/res/flags/gh.png0000644000175000017500000000075214340334543016740 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<|IDATxbπPX@_upɒ2ҒKF6hU wg@ տCH($ f@,`J̓( 7P@ ` >7:BSx+)% =Z FL<q_ڴJNh#@1}2?DWD/9_?㣁ܟ0 j 2?￿~߯ߎmDemd ? }" R7 j D #- 6N? /05c Fd=  !pB0br(IENDB`jamulus-3.9.1+dfsg/src/res/flags/ve.png0000644000175000017500000000102014340334543016741 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxba &!@# e æE^ y af/6 ? *(  ߌ@e !/P7P@1vv# JJ ? >PHUm>mެT A@e@ _/R=mګ_UV7!&3uvVo5?@SA$+$Rz X1e=!Cp?`@,@k~aEd0@H :+4f&Zt8IENDB`jamulus-3.9.1+dfsg/src/res/flags/sn.png0000644000175000017500000000102414340334543016753 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdhd@ @&@TVY R1e`?0̟"l@,`?e~_@Ռ@490sT7Z:pZ_XR+@2Uϟ~{?P%i￿+~mR\! /Xm0e.ۯ_v@? l`; @~/g C&n<h0I@_= b0PO@, ~#- 8X~32Iq àN Fd/z=O`,[XIENDB`jamulus-3.9.1+dfsg/src/res/flags/vu.png0000644000175000017500000000113414340334543016767 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxL @5k C$^u"b24bҗ'wXVu??0ϟ0˦MpoF2Mno?A* / QV@15K7.c߿JA~_P=@ !8w,Z'!?_~H20HÏ;V.Ms?~o7 Ic/+u o?2ׯ@;~ $ $PTr@4;_&:@ 1 ߿D'C c@'}?I02|a -?ArI  d$P=//bad`0'`$h)PĀLr0$QOJQIENDB`jamulus-3.9.1+dfsg/src/res/flags/pn.png0000644000175000017500000000122114340334543016747 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<#IDATxbLN<=\ 7QpN5700|c`L1Qo}h1%  10C0/ 1 #E <-&;1>+( H ܿ>81 ()̌ @ 516F23   po濿?~g{W;$ _ϿTܐKt@(!.?_?wS1>4@120#G$A$@/Z:YIENDB`jamulus-3.9.1+dfsg/src/res/flags/wales.png0000644000175000017500000000121414340334543017447 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb|9 `ɟ00bJKv~?"D٤.UMVA!i.Ii{H#˽;~Ywߘ߼_uD?? )Y_up~}7?y~TX#/_b: @.Zr]~rʷb}⟓ ӂ,C|6Qq1 wu  wo$*1 FzP  'bo) "1E%P$>ZRw1. [HS1$%x-ٟ= K^xP_! L20hzIENDB`jamulus-3.9.1+dfsg/src/res/flags/bw.png0000644000175000017500000000067314340334543016754 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<MIDATxbT=߯@H̀0,V@@$U0JN.%)s[҉z yX_0gxV$U@ b#///I@+ $Vx}b(++{ Q@R^^럿@>\DE9H߿ ſ~Rl6bb|-???~Cd~u@iQgx a!A HpcdXG X@I  0eF_ 0~G-@12l)R0@Z gu}a^eNIENDB`jamulus-3.9.1+dfsg/src/res/flags/readme.txt0000644000175000017500000000077314340334543017635 0ustar vimervimerFlag icons - http://www.famfamfam.com These icons are public domain, and as such are free for any use (attribution appreciated but not required). Note that these flags are named using the ISO3166-1 alpha-2 country codes where appropriate. A list of codes can be found at http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 If you find these icons useful, please donate via paypal to mjames@gmail.com (or click the donate button available at http://www.famfamfam.com/lab/icons/silk) Contact: mjames@gmail.comjamulus-3.9.1+dfsg/src/res/flags/mk.png0000644000175000017500000000123014340334543016741 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<*IDATx< 0TK"RDxiD{ybr2}1x{rf _(NAӧ Q7HY~?P8Oa1#@H*15+25(Ў?ρ ݯJf Xl'|@ ?ͨ$bwd a߯>7Wa` ?O͠wY_A`8a30/SǒfxA7ߌj0(nahP?Yb_ÿ @L?k T@DV;0IENDB`jamulus-3.9.1+dfsg/src/res/flags/ai.png0000644000175000017500000000120314340334543016723 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATx1]hP9J+ 71, G0XaD\emlz_#n^)ryOXϿg2120| ^6R=m/]"#cjghS gުk ?1+  ?  OMwԕ' X~;ﯿJX+k?Pwbd[jÏD_#yvF?|! ~/8q}gq@~ o`1%B_u￟h_Y~  @ym8 A2@9? @#P'RD~#ܿ@7$@YH@{IENDB`jamulus-3.9.1+dfsg/src/res/flags/tg.png0000644000175000017500000000106214340334543016747 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbπ` v `da |u5' >? ~0s@5pp`05eX  ~d_@o&vV/b=qd_?/.[ X\\ W?[_ן@aݷ N|E _ "[{ 2oRpL 6{)GQF?3З~Aٕ?@,70H70&k@,Ry!- ?L<pl|/a FbO1&y qnC1IENDB`jamulus-3.9.1+dfsg/src/res/flags/sa.png0000644000175000017500000000104714340334543016743 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdf@ H @#(,lg2EYi) i~P_~ˏ2B@tah,ǧ1132{NK Z@ `?})# y~~7 ̿]@L@on_|ڋklמ_`k; $  @a,WBڇroYZBc  3:%xXWdj  g-÷@ Xq > pEF+.ONHh'P@12(D$O 0z79NIENDB`jamulus-3.9.1+dfsg/src/res/flags/mw.png0000644000175000017500000000102114340334543016753 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd  &3`c"a>jN !Lgdl_s `K ~I0U@,`m*}bO@` @r `~Wh@4R \<nY_5*N@L@`dFnzA$zMbɆ[@eddcF#33Wu5{Pi_?g<-3ɽڵ  <e޼y@,JӘo'2puծ/TuuXPSf_@ fL\l /H..mƋ/gxj ;#W2Q 1A `B% [IENDB`jamulus-3.9.1+dfsg/src/res/flags/cr.png0000644000175000017500000000073514340334543016747 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<oIDATxbdoe1$ F?Ĺ A>*Wm1z;d*,!{@?gf+`X3 ?|@, 1?Ŀ`/:lkJA @ ؀_!(h\HD ӽdުO=t/PF4\L@)@@J*~# % XD[9} q(s7엿L||2'?YAr J Pz-@120΋: h0= d@qeԐExt¹$@yIENDB`jamulus-3.9.1+dfsg/src/res/flags/as.png0000644000175000017500000000120714340334543016741 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbTT`@Ʋr4l 1+! %12: =7l6P .ZemKݽH?8D X7.Ek9ٝs˞_>"$|lu{؟r2rqOڕ L |~}"# @1!;&  ; !6[1D# 0/JN&rH 鿿~ z:|5s6y,l\1YY21= ?X~`'0A?z11`?|MZyˋ` d.$1310H10 !IENDB`jamulus-3.9.1+dfsg/src/res/flags/et.png0000644000175000017500000000112014340334543016740 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdTda/_0_`ap0 çwթm ydޔ; X~1f| տE_/@VDh.@0(H?3139_~x@Hs321v̄> 2x:` ٿ@>1 ZϿNK|#@4!(#ӏB%scHNp 51jQ T"?f(W]su m`Xj9_j/9$ؘ ~342`T @_QPhR@`! =ڮIENDB`jamulus-3.9.1+dfsg/src/res/flags/sm.png0000644000175000017500000000076614340334543016766 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb??0!?`Ib)?#3G| `ƿU322- L~?nd  wۋ~|r~N\d=0#C>oD פO"͇x?K1-h@L tc <_zl @@ɯ9{2ߘ  @e2_5-k߿ /ba&n% 70(FͻßpcȐh!(. `DOaIENDB`jamulus-3.9.1+dfsg/src/res/flags/bg.png0000644000175000017500000000071614340334543016732 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<`IDATxb+Df($SHŋS`ddZ@,w>ݑa/B? 0DL, Ff2G~ B $ Dt c 5S d޲IU%sX Raf:%@a´f!|g W0aן b@s @,=q S@;JB~3˨򷎁 X$P(? $ A@H&1@B!C O.3~.ϿFg  e'|0l@Ҧ`YEa3?-}߶Q ܻwR &1|((12AP60 7,<ԃ lME"#VJQB]@,`8Ot̯߿vNL{h?`@$# l{?{'ٱPϟRR~7[ h?~eѿgO1 ЂB\p!xh֛Z|Lg_*! zH ̀AǏ$IENDB`jamulus-3.9.1+dfsg/src/res/flags/nz.png0000644000175000017500000000117714340334543016773 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb<\ظHKWؘ_JrP \0 X1-k]C 1*=1M $1 0$)#$0/]]#߲ZAESߏ_p2,~-@[O'@ 1( M * #ػe]|f?| '7_~~fV9 Ư@@Is(?bj_I"_`gE_< XR( xN 0ffr߿#C0_@'q:IENDB`jamulus-3.9.1+dfsg/src/res/flags/sv.png0000644000175000017500000000076514340334543016776 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdп c?(B PZ ?˜Qw XJcx?` ? u@ORh/@1?UYׯ3ur@4٘|@edd:?HXwcR>}@,B ׿ _L \5|CuOmk͉bةĸGU9@?@@yg~Kы_08~C/$I3O IQ?7H05(b 2eG$cCbtXlMIENDB`jamulus-3.9.1+dfsg/src/res/flags/cm.png0000644000175000017500000000101514340334543016732 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd X3Ȁ+ÿ0B97_`fSVEWֆl]LtkFXr]h@#S TO>_ƿfP_oFFY%8c`9T'Eu&.$l4eD| Jd*P[ 0߿ ~__ _PT @_~:??@,@ I@gd} =P@4$_!k:& <zI? `@ Ʌ J D dPIENDB`jamulus-3.9.1+dfsg/src/res/flags/bf.png0000644000175000017500000000076114340334543016731 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbπPX@_upɒ2ҒKF6hU wg@ տCH($ f@,`JCL7P@1#P5Pş? ~ 4 X10rq@_@bׯ {X\b` Z|?>ן~u\5 (7T} @ B.c^=VBzE҈Rf a,l@, @ԁLj D #- 6N f/@123@T$p<31ShBIENDB`jamulus-3.9.1+dfsg/src/res/flags/mn.png0000644000175000017500000000075414340334543016756 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<~IDATxbπ^20x@+?$U]`?j|?af'@>i@50/_w$E_FYY RA/C_? `AQ`bbTϟP!D !a\L?UgZRj$N PO 6 ?00H?f`j?@ : @fa"觿RL\ #I?L@J "" 3\f`@A‚N[YIENDB`jamulus-3.9.1+dfsg/src/res/flags/zw.png0000644000175000017500000000107614340334543017002 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbf&`fBb1_9gno `ߟ?@_~betW307Fe?}@, ;q:&_?@Ư~ "Y_@,&U1+0띧wU7H_ d{@1=y/ϟP D+**=z XXL^:R}{Ud`~~s@,EQ_X~12 @")yX~-b@L@'習 v>wG?%ytt"`eQ|!_GǓ?W`P~_@Wi &_^<?>dP}OoHog{P;^g ÿ?@,0__agr? W4;<{ S!@, ^1~ _,6=/@? H o _ 0b@f 0(t0IENDB`jamulus-3.9.1+dfsg/src/res/flags/pf.png0000644000175000017500000000076214340334543016750 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb"$6@a = )Bl9֬J )rE|@ @@A  f@_3\tc5#;!?FFƏ>?W?.:ϝ?}sb}󟷟2J^fW7 j /?z13AĂP+4Y9e@,%$w/W0Ƚa_v/(X$)7㟿@9߿ad"/q_Cb1/IENDB`jamulus-3.9.1+dfsg/src/res/flags/ga.png0000644000175000017500000000075114340334543016730 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<{IDATxbdhf@ `$!0 RA7DUFjo;͚v9ђɐ}M} y?￿ ~/ CG@ amTv)fTooZ<|?N+X002/00~32d@,`k SI5?i*!C!j Fr  l?i92@0h`?N)ba4?L`SCx90~#zo~3<A`#h_plIENDB`jamulus-3.9.1+dfsg/src/res/flags/mm.png0000644000175000017500000000074314340334543016753 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<uIDATxbd`8~10c``a`(VQ\MWǏ|o?0ϟ0˦Mʤ.+ g{ u~ee6`YnaG%jH$H@gO j`~3|wڏ31V5h:@;~ӧ?eo m K~ Ln6`' o},$0d pE5ei`ARl_? `# $ A@5".\  3V[YIENDB`jamulus-3.9.1+dfsg/src/res/flags/gs.png0000644000175000017500000000116614340334543016753 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbYYY{tA(IuݴA(@ O2~eÇB*U˞|9qׯ~BM1b~  T=q1`?MR ( <,ͮJJ/bb8 洴ѷCL0;!ُjZ(G98 fK12wPŒT!3y*$ŴTST1io@ m8%}p I~ {C"^} X~PXP3$.:xi ۷**@  ȗA/X3d_^ @f`f  $)OIENDB`jamulus-3.9.1+dfsg/src/res/flags/sr.png0000644000175000017500000000100114340334543016752 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbdg``/0 $YP(F0p4I\"=  fkJ7܁*1$ŠO1?0 0,$#w$9߿@C"?Ц߿ d0JI}\ Xf|S:@*~gk @ ?A԰_e~!;i߿@nOO߿$^`7Lo(Mk^6`?@4,?3#W!;?pHBй ` Bybd(f`_H pH0i hIENDB`jamulus-3.9.1+dfsg/src/res/flags/vn.png0000644000175000017500000000073214340334543016763 0ustar vimervimerPNG  IHDR ngAMA7tEXtSoftwareAdobe ImageReadyqe<lIDATxbπPX@_upɒ2ҒKF6hU wg@ տH_/8,bE5P 7P@1#P5?.'"4M /R Df{ $@ 䤿~;ͯ@ @ï~TIvo WM$w/o@C00H38ȀT3:9~P@ L0HJQd$ȗ@+jDc0RZ2IENDB`jamulus-3.9.1+dfsg/src/serverdlg.h0000644000175000017500000001115714340334543016116 0ustar vimervimer/******************************************************************************\ * Copyright (c) 2004-2022 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #if QT_VERSION >= QT_VERSION_CHECK( 5, 6, 0 ) # include #endif #include "global.h" #include "util.h" #include "server.h" #include "settings.h" #include "ui_serverdlgbase.h" /* Definitions ****************************************************************/ // update time for GUI controls #define GUI_CONTRL_UPDATE_TIME 1000 // ms // Strings used in multiple places #define SREC_NOT_INITIALISED CServerDlg::tr ( "Not initialised" ) #define SREC_NOT_ENABLED CServerDlg::tr ( "Not enabled" ) #define SREC_NOT_RECORDING CServerDlg::tr ( "Not recording" ) #define SREC_RECORDING CServerDlg::tr ( "Recording" ) /* Classes ********************************************************************/ class CServerDlg : public CBaseDlg, private Ui_CServerDlgBase { Q_OBJECT public: CServerDlg ( CServer* pNServP, CServerSettings* pNSetP, const bool bStartMinimized, QWidget* parent = nullptr ); protected: virtual void changeEvent ( QEvent* pEvent ); virtual void closeEvent ( QCloseEvent* Event ); void UpdateGUIDependencies(); void UpdateSystemTrayIcon ( const bool bIsActive ); void ShowWindowInForeground() { showNormal(); raise(); activateWindow(); } void ModifyAutoStartEntry ( const bool bDoAutoStart ); void UpdateRecorderStatus ( QString sessionDir ); QTimer Timer; CServer* pServer; CServerSettings* pSettings; CVector vecpListViewItems; QMutex ListViewMutex; QMenuBar* pMenu; bool bSystemTrayIconAvailable; QSystemTrayIcon SystemTrayIcon; QPixmap BitmapSystemTrayInactive; QPixmap BitmapSystemTrayActive; QMenu* pSystemTrayIconMenu; public slots: // From the GUI void OnDirectoryTypeCurrentIndexChanged ( int iTypeIdx ); void OnServerNameEditingFinished(); void OnLocationCityEditingFinished(); void OnLocationCountryCurrentIndexChanged ( int iCntryListItem ); void OnEnableRecorderStateChanged ( int value ) { pServer->SetEnableRecording ( Qt::CheckState::Checked == value ); } void OnNewRecordingClicked() { pServer->RequestNewRecording(); } void OnWelcomeMessageChanged() { pServer->SetWelcomeMessage ( tedWelcomeMessage->toPlainText() ); } void OnLanguageChanged ( QString strLanguage ) { pSettings->strLanguage = strLanguage; } void OnCustomDirectoryEditingFinished(); void OnRecordingDirClicked(); void OnClearRecordingDirClicked(); void OnServerListPersistenceClicked(); void OnClearServerListPersistenceClicked(); void OnStartOnOSStartStateChanged ( int value ); void OnEnableDelayPanningStateChanged ( int value ) { pServer->SetEnableDelayPanning ( Qt::CheckState::Checked == value ); } void OnSysTrayMenuOpen() { ShowWindowInForeground(); } void OnSysTrayMenuHide() { hide(); } void OnSysTrayMenuExit() { close(); } void OnSysTrayActivated ( QSystemTrayIcon::ActivationReason ActReason ); // From the Server void OnServerStarted(); void OnServerStopped(); void OnSvrRegStatusChanged() { UpdateGUIDependencies(); } void OnRecordingSessionStarted ( QString sessionDir ) { UpdateRecorderStatus ( sessionDir ); } void OnStopRecorder(); void OnCLVersionAndOSReceived ( CHostAddress, COSUtil::EOpSystemType, QString strVersion ); // Our timer void OnTimer(); }; jamulus-3.9.1+dfsg/Jamulus.pro0000644000175000017500000011316314340334543015323 0ustar vimervimerVERSION = 3.9.1 # use target name which does not use a capital letter at the beginning contains(CONFIG, "noupcasename") { message(The target name is jamulus instead of Jamulus.) TARGET = jamulus } # allow detailed version info for intermediate builds (#475) contains(VERSION, .*dev.*) { exists(".git/config") { GIT_DESCRIPTION=$$system(git describe --match=xxxxxxxxxxxxxxxxxxxx --always --abbrev --dirty) # the match should never match VERSION = "$$VERSION"-$$GIT_DESCRIPTION message("building version \"$$VERSION\" (intermediate in git repository)") } else { VERSION = "$$VERSION"-nogit message("building version \"$$VERSION\" (intermediate without git repository)") } } else { message("building version \"$$VERSION\" (release)") } CONFIG += qt \ thread \ lrelease QT += network \ xml \ concurrent contains(CONFIG, "nosound") { CONFIG -= "nosound" CONFIG += "serveronly" warning("\"nosound\" is deprecated: please use \"serveronly\" for a server-only build.") } contains(CONFIG, "headless") { message(Headless mode activated.) QT -= gui } else { QT += widgets QT += multimedia } # Hint: When adding new translations, make sure to update # DISTFILES (above) and src/resources.qrc as well. LRELEASE_DIR = src/translation TRANSLATIONS = src/translation/translation_de_DE.ts \ src/translation/translation_fr_FR.ts \ src/translation/translation_ko_KR.ts \ src/translation/translation_pt_PT.ts \ src/translation/translation_pt_BR.ts \ src/translation/translation_es_ES.ts \ src/translation/translation_nb_NO.ts \ src/translation/translation_nl_NL.ts \ src/translation/translation_pl_PL.ts \ src/translation/translation_sk_SK.ts \ src/translation/translation_it_IT.ts \ src/translation/translation_sv_SE.ts \ src/translation/translation_zh_CN.ts INCLUDEPATH += src INCLUDEPATH_OPUS = libs/opus/include \ libs/opus/celt \ libs/opus/silk \ libs/opus/silk/float \ libs/opus/silk/fixed \ libs/opus DEFINES += APP_VERSION=\\\"$$VERSION\\\" \ CUSTOM_MODES \ _REENTRANT # some depreciated functions need to be kept for older versions to build # TODO as soon as we drop support for the old Qt version, remove the following line DEFINES += QT_NO_DEPRECATED_WARNINGS win32 { DEFINES -= UNICODE # fixes issue with ASIO SDK (asiolist.cpp is not unicode compatible) DEFINES += NOMINMAX # solves a compiler error in qdatetime.h (Qt5) RC_FILE = src/res/win-mainicon.rc mingw* { LIBS += -lole32 \ -luser32 \ -ladvapi32 \ -lwinmm \ -lws2_32 } else { QMAKE_LFLAGS += /DYNAMICBASE:NO # fixes crash with libjack64.dll, see https://github.com/jamulussoftware/jamulus/issues/93 LIBS += ole32.lib \ user32.lib \ advapi32.lib \ winmm.lib \ ws2_32.lib greaterThan(QT_MAJOR_VERSION, 5) { # Qt5 had a special qtmain library which took care of forwarding the MSVC default WinMain() entrypoint to # the platform-agnostic main(). # Qt6 is still supposed to have that lib under the new name QtEntryPoint. As it does not seem # to be effective when building with qmake, we are rather instructing MSVC to use the platform-agnostic # main() entrypoint directly: QMAKE_LFLAGS += /subsystem:windows /ENTRY:mainCRTStartup } } contains(CONFIG, "serveronly") { message(Restricting build to server-only due to CONFIG+=serveronly.) DEFINES += SERVER_ONLY } else { contains(CONFIG, "jackonwindows") { message(Using JACK.) contains(QT_ARCH, "i386") { exists("C:/Program Files (x86)") { message("Cross compilation build") programfilesdir = "C:/Program Files (x86)" } else { message("Native i386 build") programfilesdir = "C:/Program Files" } libjackname = "libjack.lib" } else { message("Native x86_64 build") programfilesdir = "C:/Program Files" libjackname = "libjack64.lib" } !exists("$${programfilesdir}/JACK2/include/jack/jack.h") { error("Error: jack.h was not found in the expected location ($${programfilesdir}). Ensure that the right JACK2 variant is installed (32bit vs. 64bit).") } HEADERS += src/sound/jack/sound.h SOURCES += src/sound/jack/sound.cpp DEFINES += WITH_JACK DEFINES += JACK_ON_WINDOWS DEFINES += _STDINT_H # supposed to solve compilation error in systemdeps.h INCLUDEPATH += "$${programfilesdir}/JACK2/include" LIBS += "$${programfilesdir}/JACK2/lib/$${libjackname}" } else { message(Using ASIO.) message(Please review the ASIO SDK licence.) !exists(libs/ASIOSDK2/common) { error("Error: ASIOSDK2 must be placed in Jamulus \\libs folder such that e.g. \\libs\ASIOSDK2\common exists.") } # Important: Keep those ASIO includes local to this build target in # order to avoid poisoning other builds license-wise. HEADERS += src/sound/asio/sound.h SOURCES += src/sound/asio/sound.cpp \ libs/ASIOSDK2/common/asio.cpp \ libs/ASIOSDK2/host/asiodrivers.cpp \ libs/ASIOSDK2/host/pc/asiolist.cpp INCLUDEPATH += libs/ASIOSDK2/common \ libs/ASIOSDK2/host \ libs/ASIOSDK2/host/pc } } } else:macx { contains(CONFIG, "server_bundle") { message(The generated application bundle will run a server instance.) DEFINES += SERVER_BUNDLE TARGET = $${TARGET}Server MACOSX_BUNDLE_ICON.files = src/res/mac-jamulus-server.icns RC_FILE = src/res/mac-jamulus-server.icns } else { MACOSX_BUNDLE_ICON.files = src/res/mac-mainicon.icns RC_FILE = src/res/mac-mainicon.icns } HEADERS += src/mac/activity.h src/mac/badgelabel.h OBJECTIVE_SOURCES += src/mac/activity.mm src/mac/badgelabel.mm CONFIG += x86 QMAKE_TARGET_BUNDLE_PREFIX = io.jamulus OSX_ENTITLEMENTS.files = mac/Jamulus.entitlements OSX_ENTITLEMENTS.path = Contents/Resources QMAKE_BUNDLE_DATA += OSX_ENTITLEMENTS macx-xcode { QMAKE_INFO_PLIST = mac/Info-xcode.plist XCODE_ENTITLEMENTS.name = CODE_SIGN_ENTITLEMENTS XCODE_ENTITLEMENTS.value = mac/Jamulus.entitlements QMAKE_MAC_XCODE_SETTINGS += XCODE_ENTITLEMENTS MACOSX_BUNDLE_ICON.path = Contents/Resources QMAKE_BUNDLE_DATA += MACOSX_BUNDLE_ICON } else { equals(QT_VERSION, "5.9.9") { QMAKE_INFO_PLIST = mac/Info-make-legacy.plist } else { QMAKE_INFO_PLIST = mac/Info-make.plist } } LIBS += -framework CoreFoundation \ -framework CoreServices \ -framework CoreAudio \ -framework CoreMIDI \ -framework AudioToolbox \ -framework AudioUnit \ -framework Foundation \ -framework AppKit contains(CONFIG, "jackonmac") { message(Using JACK.) !exists(/usr/include/jack/jack.h) { !exists(/usr/local/include/jack/jack.h) { error("Error: jack.h was not found at the usual place, maybe JACK is not installed") } } HEADERS += src/sound/jack/sound.h SOURCES += src/sound/jack/sound.cpp DEFINES += WITH_JACK DEFINES += JACK_REPLACES_COREAUDIO INCLUDEPATH += /usr/local/include LIBS += /usr/local/lib/libjack.dylib } else { message(Using CoreAudio.) HEADERS += src/sound/coreaudio-mac/sound.h SOURCES += src/sound/coreaudio-mac/sound.cpp } } else:ios { QMAKE_INFO_PLIST = ios/Info.plist OBJECTIVE_SOURCES += src/ios/ios_app_delegate.mm HEADERS += src/ios/ios_app_delegate.h HEADERS += src/sound/coreaudio-ios/sound.h OBJECTIVE_SOURCES += src/sound/coreaudio-ios/sound.mm QMAKE_TARGET_BUNDLE_PREFIX = io.jamulus LIBS += -framework AVFoundation \ -framework AudioToolbox } else:android { ANDROID_ABIS = armeabi-v7a arm64-v8a x86 x86_64 ANDROID_VERSION_NAME = $$VERSION ANDROID_VERSION_CODE = $$system(git log --oneline | wc -l) message("Setting ANDROID_VERSION_NAME=$${ANDROID_VERSION_NAME} ANDROID_VERSION_CODE=$${ANDROID_VERSION_CODE}") # liboboe requires C++17 for std::timed_mutex CONFIG += c++17 QT += androidextras # enabled only for debugging on android devices DEFINES += ANDROIDDEBUG target.path = /tmp/your_executable # path on device INSTALLS += target HEADERS += src/sound/oboe/sound.h SOURCES += src/sound/oboe/sound.cpp \ src/android/androiddebug.cpp LIBS += -lOpenSLES ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android DISTFILES += android/AndroidManifest.xml # if compiling for android you need to use Oboe library which is included as a git submodule # make sure you git pull with submodules to pull the latest Oboe library OBOE_SOURCES = $$files(libs/oboe/src/*.cpp, true) OBOE_HEADERS = $$files(libs/oboe/src/*.h, true) INCLUDEPATH_OBOE = libs/oboe/include/ \ libs/oboe/src/ DISTFILES_OBOE += libs/oboe/AUTHORS \ libs/oboe/CONTRIBUTING \ libs/oboe/LICENSE \ libs/oboe/README INCLUDEPATH += $$INCLUDEPATH_OBOE HEADERS += $$OBOE_HEADERS SOURCES += $$OBOE_SOURCES DISTFILES += $$DISTFILES_OBOE } else:unix { # we want to compile with C++11 CONFIG += c++11 # --as-needed avoids linking the final binary against unnecessary runtime # libs. Most g++ versions already do that by default. # However, Debian buster does not and would link against libQt5Concurrent # unnecessarily without this workaround (#741): QMAKE_LFLAGS += -Wl,--as-needed # we assume to have lrintf() one moderately modern linux distributions # would be better to have that tested, though DEFINES += HAVE_LRINTF # we assume that stdint.h is always present in a Linux system DEFINES += HAVE_STDINT_H # only include JACK support if CONFIG serveronly is not set contains(CONFIG, "serveronly") { message(Restricting build to server-only due to CONFIG+=serveronly.) DEFINES += SERVER_ONLY } else { message(JACK Audio Interface Enabled.) HEADERS += src/sound/jack/sound.h SOURCES += src/sound/jack/sound.cpp contains(CONFIG, "raspijamulus") { message(Using JACK Audio in raspijamulus.sh mode.) LIBS += -ljack } else { CONFIG += link_pkgconfig PKGCONFIG += jack } DEFINES += WITH_JACK } isEmpty(PREFIX) { PREFIX = /usr/local } isEmpty(BINDIR) { BINDIR = bin } BINDIR = $$absolute_path($$BINDIR, $$PREFIX) target.path = $$BINDIR contains(CONFIG, "headless") { INSTALLS += target } else { isEmpty(APPSDIR) { APPSDIR = share/applications } APPSDIR = $$absolute_path($$APPSDIR, $$PREFIX) desktop.path = $$APPSDIR QMAKE_SUBSTITUTES += linux/jamulus.desktop.in linux/jamulus-server.desktop.in desktop.files = linux/jamulus.desktop linux/jamulus-server.desktop isEmpty(ICONSDIR) { ICONSDIR = share/icons/hicolor/512x512/apps } ICONSDIR = $$absolute_path($$ICONSDIR, $$PREFIX) icons.path = $$ICONSDIR icons.files = src/res/io.jamulus.jamulus.png isEmpty(ICONSDIR_SVG) { ICONSDIR_SVG = share/icons/hicolor/scalable/apps/ } ICONSDIR_SVG = $$absolute_path($$ICONSDIR_SVG, $$PREFIX) icons_svg.path = $$ICONSDIR_SVG icons_svg.files = src/res/io.jamulus.jamulus.svg src/res/io.jamulus.jamulusserver.svg isEmpty(MANDIR) { MANDIR = share/man/man1 } MANDIR = $$absolute_path($$MANDIR, $$PREFIX) man.path = $$MANDIR man.files = linux/Jamulus.1 INSTALLS += target desktop icons icons_svg man } } RCC_DIR = src/res RESOURCES += src/resources.qrc FORMS_GUI = src/aboutdlgbase.ui \ src/serverdlgbase.ui !contains(CONFIG, "serveronly") { FORMS_GUI += src/clientdlgbase.ui \ src/clientsettingsdlgbase.ui \ src/chatdlgbase.ui \ src/connectdlgbase.ui } HEADERS += src/buffer.h \ src/channel.h \ src/global.h \ src/protocol.h \ src/recorder/jamcontroller.h \ src/threadpool.h \ src/server.h \ src/serverlist.h \ src/serverlogging.h \ src/settings.h \ src/socket.h \ src/util.h \ src/recorder/jamrecorder.h \ src/recorder/creaperproject.h \ src/recorder/cwavestream.h \ src/signalhandler.h !contains(CONFIG, "serveronly") { HEADERS += src/client.h \ src/sound/soundbase.h \ src/testbench.h } HEADERS_GUI = src/serverdlg.h !contains(CONFIG, "serveronly") { HEADERS_GUI += src/audiomixerboard.h \ src/chatdlg.h \ src/clientsettingsdlg.h \ src/connectdlg.h \ src/clientdlg.h \ src/levelmeter.h \ src/analyzerconsole.h \ src/multicolorled.h } HEADERS_OPUS = libs/opus/celt/arch.h \ libs/opus/celt/bands.h \ libs/opus/celt/celt.h \ libs/opus/celt/celt_lpc.h \ libs/opus/celt/cpu_support.h \ libs/opus/celt/cwrs.h \ libs/opus/celt/ecintrin.h \ libs/opus/celt/entcode.h \ libs/opus/celt/entdec.h \ libs/opus/celt/entenc.h \ libs/opus/celt/float_cast.h \ libs/opus/celt/kiss_fft.h \ libs/opus/celt/laplace.h \ libs/opus/celt/mathops.h \ libs/opus/celt/mdct.h \ libs/opus/celt/mfrngcod.h \ libs/opus/celt/modes.h \ libs/opus/celt/os_support.h \ libs/opus/celt/pitch.h \ libs/opus/celt/quant_bands.h \ libs/opus/celt/rate.h \ libs/opus/celt/stack_alloc.h \ libs/opus/celt/static_modes_float.h \ libs/opus/celt/vq.h \ libs/opus/celt/_kiss_fft_guts.h \ libs/opus/include/opus.h \ libs/opus/include/opus_custom.h \ libs/opus/include/opus_defines.h \ libs/opus/include/opus_types.h \ libs/opus/silk/API.h \ libs/opus/silk/control.h \ libs/opus/silk/debug.h \ libs/opus/silk/define.h \ libs/opus/silk/errors.h \ libs/opus/silk/float/main_FLP.h \ libs/opus/silk/float/SigProc_FLP.h \ libs/opus/silk/float/structs_FLP.h \ libs/opus/silk/Inlines.h \ libs/opus/silk/MacroCount.h \ libs/opus/silk/MacroDebug.h \ libs/opus/silk/macros.h \ libs/opus/silk/main.h \ libs/opus/silk/NSQ.h \ libs/opus/silk/pitch_est_defines.h \ libs/opus/silk/PLC.h \ libs/opus/silk/resampler_private.h \ libs/opus/silk/resampler_rom.h \ libs/opus/silk/resampler_structs.h \ libs/opus/silk/SigProc_FIX.h \ libs/opus/silk/structs.h \ libs/opus/silk/tables.h \ libs/opus/silk/tuning_parameters.h \ libs/opus/silk/typedef.h \ libs/opus/src/analysis.h \ libs/opus/src/mlp.h \ libs/opus/src/opus_private.h \ libs/opus/src/tansig_table.h HEADERS_OPUS_ARM = libs/opus/celt/arm/armcpu.h \ libs/opus/silk/arm/biquad_alt_arm.h \ libs/opus/celt/arm/fft_arm.h \ libs/opus/silk/arm/LPC_inv_pred_gain_arm.h \ libs/opus/celt/arm/mdct_arm.h \ libs/opus/silk/arm/NSQ_del_dec_arm.h \ libs/opus/celt/arm/pitch_arm.h HEADERS_OPUS_X86 = libs/opus/celt/x86/celt_lpc_sse.h \ libs/opus/celt/x86/pitch_sse.h \ libs/opus/celt/x86/vq_sse.h \ libs/opus/celt/x86/x86cpu.h \ $$files(libs/opus/silk/x86/*.h) SOURCES += src/buffer.cpp \ src/channel.cpp \ src/main.cpp \ src/protocol.cpp \ src/recorder/jamcontroller.cpp \ src/server.cpp \ src/serverlist.cpp \ src/serverlogging.cpp \ src/settings.cpp \ src/signalhandler.cpp \ src/socket.cpp \ src/util.cpp \ src/recorder/jamrecorder.cpp \ src/recorder/creaperproject.cpp \ src/recorder/cwavestream.cpp !contains(CONFIG, "serveronly") { SOURCES += src/client.cpp \ src/sound/soundbase.cpp \ } SOURCES_GUI = src/serverdlg.cpp !contains(CONFIG, "serveronly") { SOURCES_GUI += src/audiomixerboard.cpp \ src/chatdlg.cpp \ src/clientsettingsdlg.cpp \ src/connectdlg.cpp \ src/clientdlg.cpp \ src/multicolorled.cpp \ src/levelmeter.cpp \ src/analyzerconsole.cpp } SOURCES_OPUS = libs/opus/celt/bands.c \ libs/opus/celt/celt.c \ libs/opus/celt/celt_decoder.c \ libs/opus/celt/celt_encoder.c \ libs/opus/celt/celt_lpc.c \ libs/opus/celt/cwrs.c \ libs/opus/celt/entcode.c \ libs/opus/celt/entdec.c \ libs/opus/celt/entenc.c \ libs/opus/celt/kiss_fft.c \ libs/opus/celt/laplace.c \ libs/opus/celt/mathops.c \ libs/opus/celt/mdct.c \ libs/opus/celt/modes.c \ libs/opus/celt/pitch.c \ libs/opus/celt/quant_bands.c \ libs/opus/celt/rate.c \ libs/opus/celt/vq.c \ libs/opus/silk/A2NLSF.c \ libs/opus/silk/ana_filt_bank_1.c \ libs/opus/silk/biquad_alt.c \ libs/opus/silk/bwexpander.c \ libs/opus/silk/bwexpander_32.c \ libs/opus/silk/check_control_input.c \ libs/opus/silk/CNG.c \ libs/opus/silk/code_signs.c \ libs/opus/silk/control_audio_bandwidth.c \ libs/opus/silk/control_codec.c \ libs/opus/silk/control_SNR.c \ libs/opus/silk/debug.c \ libs/opus/silk/decoder_set_fs.c \ libs/opus/silk/decode_core.c \ libs/opus/silk/decode_frame.c \ libs/opus/silk/decode_indices.c \ libs/opus/silk/decode_parameters.c \ libs/opus/silk/decode_pitch.c \ libs/opus/silk/decode_pulses.c \ libs/opus/silk/dec_API.c \ libs/opus/silk/encode_indices.c \ libs/opus/silk/encode_pulses.c \ libs/opus/silk/enc_API.c \ libs/opus/silk/float/apply_sine_window_FLP.c \ libs/opus/silk/float/autocorrelation_FLP.c \ libs/opus/silk/float/burg_modified_FLP.c \ libs/opus/silk/float/bwexpander_FLP.c \ libs/opus/silk/float/corrMatrix_FLP.c \ libs/opus/silk/float/encode_frame_FLP.c \ libs/opus/silk/float/energy_FLP.c \ libs/opus/silk/float/find_LPC_FLP.c \ libs/opus/silk/float/find_LTP_FLP.c \ libs/opus/silk/float/find_pitch_lags_FLP.c \ libs/opus/silk/float/find_pred_coefs_FLP.c \ libs/opus/silk/float/inner_product_FLP.c \ libs/opus/silk/float/k2a_FLP.c \ libs/opus/silk/float/LPC_analysis_filter_FLP.c \ libs/opus/silk/float/LTP_analysis_filter_FLP.c \ libs/opus/silk/float/LTP_scale_ctrl_FLP.c \ libs/opus/silk/float/noise_shape_analysis_FLP.c \ libs/opus/silk/float/pitch_analysis_core_FLP.c \ libs/opus/silk/float/process_gains_FLP.c \ libs/opus/silk/float/residual_energy_FLP.c \ libs/opus/silk/float/scale_copy_vector_FLP.c \ libs/opus/silk/float/scale_vector_FLP.c \ libs/opus/silk/float/schur_FLP.c \ libs/opus/silk/float/sort_FLP.c \ libs/opus/silk/float/warped_autocorrelation_FLP.c \ libs/opus/silk/float/wrappers_FLP.c \ libs/opus/silk/gain_quant.c \ libs/opus/silk/HP_variable_cutoff.c \ libs/opus/silk/init_decoder.c \ libs/opus/silk/init_encoder.c \ libs/opus/silk/inner_prod_aligned.c \ libs/opus/silk/interpolate.c \ libs/opus/silk/lin2log.c \ libs/opus/silk/log2lin.c \ libs/opus/silk/LPC_analysis_filter.c \ libs/opus/silk/LPC_fit.c \ libs/opus/silk/LPC_inv_pred_gain.c \ libs/opus/silk/LP_variable_cutoff.c \ libs/opus/silk/NLSF2A.c \ libs/opus/silk/NLSF_decode.c \ libs/opus/silk/NLSF_del_dec_quant.c \ libs/opus/silk/NLSF_encode.c \ libs/opus/silk/NLSF_stabilize.c \ libs/opus/silk/NLSF_unpack.c \ libs/opus/silk/NLSF_VQ.c \ libs/opus/silk/NLSF_VQ_weights_laroia.c \ libs/opus/silk/NSQ.c \ libs/opus/silk/NSQ_del_dec.c \ libs/opus/silk/pitch_est_tables.c \ libs/opus/silk/PLC.c \ libs/opus/silk/process_NLSFs.c \ libs/opus/silk/quant_LTP_gains.c \ libs/opus/silk/resampler.c \ libs/opus/silk/resampler_down2.c \ libs/opus/silk/resampler_down2_3.c \ libs/opus/silk/resampler_private_AR2.c \ libs/opus/silk/resampler_private_down_FIR.c \ libs/opus/silk/resampler_private_IIR_FIR.c \ libs/opus/silk/resampler_private_up2_HQ.c \ libs/opus/silk/resampler_rom.c \ libs/opus/silk/shell_coder.c \ libs/opus/silk/sigm_Q15.c \ libs/opus/silk/sort.c \ libs/opus/silk/stereo_decode_pred.c \ libs/opus/silk/stereo_encode_pred.c \ libs/opus/silk/stereo_find_predictor.c \ libs/opus/silk/stereo_LR_to_MS.c \ libs/opus/silk/stereo_MS_to_LR.c \ libs/opus/silk/stereo_quant_pred.c \ libs/opus/silk/sum_sqr_shift.c \ libs/opus/silk/tables_gain.c \ libs/opus/silk/tables_LTP.c \ libs/opus/silk/tables_NLSF_CB_NB_MB.c \ libs/opus/silk/tables_NLSF_CB_WB.c \ libs/opus/silk/tables_other.c \ libs/opus/silk/tables_pitch_lag.c \ libs/opus/silk/tables_pulses_per_block.c \ libs/opus/silk/table_LSF_cos.c \ libs/opus/silk/VAD.c \ libs/opus/silk/VQ_WMat_EC.c \ libs/opus/src/analysis.c \ libs/opus/src/mlp.c \ libs/opus/src/mlp_data.c \ libs/opus/src/opus.c \ libs/opus/src/opus_decoder.c \ libs/opus/src/opus_encoder.c \ libs/opus/src/repacketizer.c SOURCES_OPUS_ARM = libs/opus/celt/arm/armcpu.c \ libs/opus/celt/arm/arm_celt_map.c \ libs/opus/silk/arm/arm_silk_map.c \ libs/opus/silk/arm/arm_silk_map.c \ libs/opus/silk/arm/biquad_alt_neon_intr.c \ libs/opus/silk/arm/LPC_inv_pred_gain_neon_intr.c \ libs/opus/silk/arm/NSQ_del_dec_neon_intr.c \ libs/opus/silk/arm/NSQ_neon.c \ libs/opus/celt/arm/celt_neon_intr.c \ libs/opus/celt/arm/pitch_neon_intr.c \ libs/opus/celt/arm/celt_fft_ne10.c \ libs/opus/celt/arm/celt_mdct_ne10.c SOURCES_OPUS_X86_SSE = libs/opus/celt/x86/x86cpu.c \ libs/opus/celt/x86/x86_celt_map.c \ libs/opus/celt/x86/pitch_sse.c SOURCES_OPUS_X86_SSE2 = libs/opus/celt/x86/pitch_sse2.c \ libs/opus/celt/x86/vq_sse2.c SOURCES_OPUS_X86_SSE4 = libs/opus/celt/x86/celt_lpc_sse4_1.c \ libs/opus/celt/x86/pitch_sse4_1.c \ libs/opus/silk/x86/NSQ_sse4_1.c \ libs/opus/silk/x86/NSQ_del_dec_sse4_1.c \ libs/opus/silk/x86/x86_silk_map.c \ libs/opus/silk/x86/VAD_sse4_1.c \ libs/opus/silk/x86/VQ_WMat_EC_sse4_1.c contains(QT_ARCH, armeabi-v7a) | contains(QT_ARCH, arm64-v8a) { HEADERS_OPUS += $$HEADERS_OPUS_ARM SOURCES_OPUS_ARCH += $$SOURCES_OPUS_ARM DEFINES_OPUS += OPUS_ARM_PRESUME_NEON=1 OPUS_ARM_PRESUME_NEON_INTR=1 contains(QT_ARCH, arm64-v8a):DEFINES_OPUS += OPUS_ARM_PRESUME_AARCH64_NEON_INTR } else:contains(QT_ARCH, x86) | contains(QT_ARCH, x86_64) { HEADERS_OPUS += $$HEADERS_OPUS_X86 SOURCES_OPUS_ARCH += $$SOURCES_OPUS_X86_SSE $$SOURCES_OPUS_X86_SSE2 $$SOURCES_OPUS_X86_SSE4 DEFINES_OPUS += OPUS_X86_MAY_HAVE_SSE OPUS_X86_MAY_HAVE_SSE2 OPUS_X86_MAY_HAVE_SSE4_1 # x86_64 implies SSE2 contains(QT_ARCH, x86_64):DEFINES_OPUS += OPUS_X86_PRESUME_SSE=1 OPUS_X86_PRESUME_SSE2=1 DEFINES_OPUS += CPU_INFO_BY_C } DEFINES_OPUS += OPUS_BUILD=1 USE_ALLOCA=1 OPUS_HAVE_RTCD=1 HAVE_LRINTF=1 HAVE_LRINT=1 DISTFILES += ChangeLog \ COPYING \ CONTRIBUTING.md \ README.md \ linux/jamulus.desktop.in \ linux/jamulus-server.desktop.in \ src/res/io.jamulus.jamulus.png \ src/res/io.jamulus.jamulus.svg \ src/res/io.jamulus.jamulusserver.svg \ src/translation/translation_de_DE.qm \ src/translation/translation_fr_FR.qm \ src/translation/translation_ko_KR.qm \ src/translation/translation_pt_PT.qm \ src/translation/translation_pt_BR.qm \ src/translation/translation_es_ES.qm \ src/translation/translation_nb_NO.qm \ src/translation/translation_nl_NL.qm \ src/translation/translation_pl_PL.qm \ src/translation/translation_it_IT.qm \ src/translation/translation_sv_SE.qm \ src/translation/translation_sk_SK.qm \ src/translation/translation_zh_CN.qm \ src/res/CLEDBlack.png \ src/res/CLEDBlackSmall.png \ src/res/CLEDDisabledSmall.png \ src/res/CLEDGreen.png \ src/res/CLEDGreenSmall.png \ src/res/CLEDGrey.png \ src/res/CLEDGreySmall.png \ src/res/CLEDRed.png \ src/res/CLEDRedSmall.png \ src/res/CLEDYellow.png \ src/res/CLEDYellowSmall.png \ src/res/LEDBlackSmall.png \ src/res/LEDGreenSmall.png \ src/res/LEDRedSmall.png \ src/res/LEDYellowSmall.png \ src/res/IndicatorGreen.png \ src/res/IndicatorYellow.png \ src/res/IndicatorRed.png \ src/res/IndicatorYellowFancy.png \ src/res/IndicatorRedFancy.png \ src/res/faderbackground.png \ src/res/faderhandle.png \ src/res/faderhandlesmall.png \ src/res/HLEDGreen.png \ src/res/HLEDGreenSmall.png \ src/res/HLEDBlack.png \ src/res/HLEDBlackSmall.png \ src/res/HLEDRed.png \ src/res/HLEDRedSmall.png \ src/res/HLEDYellow.png \ src/res/HLEDYellowSmall.png \ src/res/ledbuttonnotpressed.png \ src/res/ledbuttonpressed.png \ src/res/fronticon.png \ src/res/fronticonserver.png \ src/res/mixerboardbackground.png \ src/res/transparent1x1.png \ src/res/mutediconorange.png \ src/res/servertrayiconactive.png \ src/res/servertrayiconinactive.png \ src/res/instruments/accordeon.png \ src/res/instruments/aguitar.png \ src/res/instruments/bassguitar.png \ src/res/instruments/cello.png \ src/res/instruments/clarinet.png \ src/res/instruments/conductor.png \ src/res/instruments/djembe.png \ src/res/instruments/doublebass.png \ src/res/instruments/drumset.png \ src/res/instruments/eguitar.png \ src/res/instruments/flute.png \ src/res/instruments/frenchhorn.png \ src/res/instruments/grandpiano.png \ src/res/instruments/harmonica.png \ src/res/instruments/keyboard.png \ src/res/instruments/listener.png \ src/res/instruments/microphone.png \ src/res/instruments/mountaindulcimer.png \ src/res/instruments/none.png \ src/res/instruments/rapping.png \ src/res/instruments/recorder.png \ src/res/instruments/saxophone.png \ src/res/instruments/scratching.png \ src/res/instruments/streamer.png \ src/res/instruments/synthesizer.png \ src/res/instruments/trombone.png \ src/res/instruments/trumpet.png \ src/res/instruments/tuba.png \ src/res/instruments/vibraphone.png \ src/res/instruments/violin.png \ src/res/instruments/vocal.png \ src/res/instruments/guitarvocal.png \ src/res/instruments/keyboardvocal.png \ src/res/instruments/bodhran.svg \ src/res/instruments/bodhran.png \ src/res/instruments/bassoon.svg \ src/res/instruments/bassoon.png \ src/res/instruments/oboe.svg \ src/res/instruments/oboe.png \ src/res/instruments/harp.svg \ src/res/instruments/harp.png \ src/res/instruments/viola.png \ src/res/instruments/congas.svg \ src/res/instruments/congas.png \ src/res/instruments/bongo.svg \ src/res/instruments/bongo.png \ src/res/instruments/ukulele.svg \ src/res/instruments/ukulele.png \ src/res/instruments/bassukulele.svg \ src/res/instruments/bassukulele.png \ src/res/instruments/vocalbass.png \ src/res/instruments/vocaltenor.png \ src/res/instruments/vocalalto.png \ src/res/instruments/vocalsoprano.png \ src/res/instruments/vocalbaritone.png \ src/res/instruments/vocallead.png \ src/res/instruments/banjo.png \ src/res/instruments/mandolin.png \ src/res/flags/flagnone.png \ src/res/flags/ad.png \ src/res/flags/ae.png \ src/res/flags/af.png \ src/res/flags/ag.png \ src/res/flags/ai.png \ src/res/flags/al.png \ src/res/flags/am.png \ src/res/flags/an.png \ src/res/flags/ao.png \ src/res/flags/ar.png \ src/res/flags/as.png \ src/res/flags/at.png \ src/res/flags/au.png \ src/res/flags/aw.png \ src/res/flags/ax.png \ src/res/flags/az.png \ src/res/flags/ba.png \ src/res/flags/bb.png \ src/res/flags/bd.png \ src/res/flags/be.png \ src/res/flags/bf.png \ src/res/flags/bg.png \ src/res/flags/bh.png \ src/res/flags/bi.png \ src/res/flags/bj.png \ src/res/flags/bm.png \ src/res/flags/bn.png \ src/res/flags/bo.png \ src/res/flags/br.png \ src/res/flags/bs.png \ src/res/flags/bt.png \ src/res/flags/bv.png \ src/res/flags/bw.png \ src/res/flags/by.png \ src/res/flags/bz.png \ src/res/flags/ca.png \ src/res/flags/cc.png \ src/res/flags/cd.png \ src/res/flags/cf.png \ src/res/flags/cg.png \ src/res/flags/ch.png \ src/res/flags/ci.png \ src/res/flags/ck.png \ src/res/flags/cl.png \ src/res/flags/cm.png \ src/res/flags/cn.png \ src/res/flags/co.png \ src/res/flags/cr.png \ src/res/flags/cs.png \ src/res/flags/cu.png \ src/res/flags/cv.png \ src/res/flags/cx.png \ src/res/flags/cy.png \ src/res/flags/cz.png \ src/res/flags/de.png \ src/res/flags/dj.png \ src/res/flags/dk.png \ src/res/flags/dm.png \ src/res/flags/do.png \ src/res/flags/dz.png \ src/res/flags/ec.png \ src/res/flags/ee.png \ src/res/flags/eg.png \ src/res/flags/eh.png \ src/res/flags/er.png \ src/res/flags/es.png \ src/res/flags/et.png \ src/res/flags/fam.png \ src/res/flags/fi.png \ src/res/flags/fj.png \ src/res/flags/fk.png \ src/res/flags/fm.png \ src/res/flags/fo.png \ src/res/flags/fr.png \ src/res/flags/ga.png \ src/res/flags/gb.png \ src/res/flags/gd.png \ src/res/flags/ge.png \ src/res/flags/gf.png \ src/res/flags/gh.png \ src/res/flags/gi.png \ src/res/flags/gl.png \ src/res/flags/gm.png \ src/res/flags/gn.png \ src/res/flags/gp.png \ src/res/flags/gq.png \ src/res/flags/gr.png \ src/res/flags/gs.png \ src/res/flags/gt.png \ src/res/flags/gu.png \ src/res/flags/gw.png \ src/res/flags/gy.png \ src/res/flags/hk.png \ src/res/flags/hm.png \ src/res/flags/hn.png \ src/res/flags/hr.png \ src/res/flags/ht.png \ src/res/flags/hu.png \ src/res/flags/id.png \ src/res/flags/ie.png \ src/res/flags/il.png \ src/res/flags/in.png \ src/res/flags/io.png \ src/res/flags/iq.png \ src/res/flags/ir.png \ src/res/flags/is.png \ src/res/flags/it.png \ src/res/flags/jm.png \ src/res/flags/jo.png \ src/res/flags/jp.png \ src/res/flags/ke.png \ src/res/flags/kg.png \ src/res/flags/kh.png \ src/res/flags/ki.png \ src/res/flags/km.png \ src/res/flags/kn.png \ src/res/flags/kp.png \ src/res/flags/kr.png \ src/res/flags/kw.png \ src/res/flags/ky.png \ src/res/flags/kz.png \ src/res/flags/la.png \ src/res/flags/lb.png \ src/res/flags/lc.png \ src/res/flags/li.png \ src/res/flags/lk.png \ src/res/flags/lr.png \ src/res/flags/ls.png \ src/res/flags/lt.png \ src/res/flags/lu.png \ src/res/flags/lv.png \ src/res/flags/ly.png \ src/res/flags/ma.png \ src/res/flags/mc.png \ src/res/flags/md.png \ src/res/flags/me.png \ src/res/flags/mg.png \ src/res/flags/mh.png \ src/res/flags/mk.png \ src/res/flags/ml.png \ src/res/flags/mm.png \ src/res/flags/mn.png \ src/res/flags/mo.png \ src/res/flags/mp.png \ src/res/flags/mq.png \ src/res/flags/mr.png \ src/res/flags/ms.png \ src/res/flags/mt.png \ src/res/flags/mu.png \ src/res/flags/mv.png \ src/res/flags/mw.png \ src/res/flags/mx.png \ src/res/flags/my.png \ src/res/flags/mz.png \ src/res/flags/na.png \ src/res/flags/nc.png \ src/res/flags/ne.png \ src/res/flags/nf.png \ src/res/flags/ng.png \ src/res/flags/ni.png \ src/res/flags/nl.png \ src/res/flags/no.png \ src/res/flags/np.png \ src/res/flags/nr.png \ src/res/flags/nu.png \ src/res/flags/nz.png \ src/res/flags/om.png \ src/res/flags/pa.png \ src/res/flags/pe.png \ src/res/flags/pf.png \ src/res/flags/pg.png \ src/res/flags/ph.png \ src/res/flags/pk.png \ src/res/flags/pl.png \ src/res/flags/pm.png \ src/res/flags/pn.png \ src/res/flags/pr.png \ src/res/flags/ps.png \ src/res/flags/pt.png \ src/res/flags/pw.png \ src/res/flags/py.png \ src/res/flags/qa.png \ src/res/flags/re.png \ src/res/flags/ro.png \ src/res/flags/rs.png \ src/res/flags/ru.png \ src/res/flags/rw.png \ src/res/flags/sa.png \ src/res/flags/sb.png \ src/res/flags/sc.png \ src/res/flags/sd.png \ src/res/flags/se.png \ src/res/flags/sg.png \ src/res/flags/sh.png \ src/res/flags/si.png \ src/res/flags/sj.png \ src/res/flags/sk.png \ src/res/flags/sl.png \ src/res/flags/sm.png \ src/res/flags/sn.png \ src/res/flags/so.png \ src/res/flags/sr.png \ src/res/flags/st.png \ src/res/flags/sv.png \ src/res/flags/sy.png \ src/res/flags/sz.png \ src/res/flags/tc.png \ src/res/flags/td.png \ src/res/flags/tf.png \ src/res/flags/tg.png \ src/res/flags/th.png \ src/res/flags/tj.png \ src/res/flags/tk.png \ src/res/flags/tl.png \ src/res/flags/tm.png \ src/res/flags/tn.png \ src/res/flags/to.png \ src/res/flags/tr.png \ src/res/flags/tt.png \ src/res/flags/tv.png \ src/res/flags/tw.png \ src/res/flags/tz.png \ src/res/flags/ua.png \ src/res/flags/ug.png \ src/res/flags/um.png \ src/res/flags/us.png \ src/res/flags/uy.png \ src/res/flags/uz.png \ src/res/flags/va.png \ src/res/flags/vc.png \ src/res/flags/ve.png \ src/res/flags/vg.png \ src/res/flags/vi.png \ src/res/flags/vn.png \ src/res/flags/vu.png \ src/res/flags/wf.png \ src/res/flags/ws.png \ src/res/flags/ye.png \ src/res/flags/yt.png \ src/res/flags/za.png \ src/res/flags/zm.png \ src/res/flags/zw.png DISTFILES_OPUS += libs/opus/AUTHORS \ libs/opus/ChangeLog \ libs/opus/COPYING \ libs/opus/INSTALL \ libs/opus/NEWS \ libs/opus/README \ libs/opus/celt/arm/armopts.s.in \ libs/opus/celt/arm/celt_pitch_xcorr_arm.s \ contains(CONFIG, "headless") { DEFINES += HEADLESS } else { HEADERS += $$HEADERS_GUI SOURCES += $$SOURCES_GUI FORMS += $$FORMS_GUI } contains(CONFIG, "nojsonrpc") { message(JSON-RPC support excluded from build.) DEFINES += NO_JSON_RPC } else { HEADERS += \ src/rpcserver.h \ src/serverrpc.h SOURCES += \ src/rpcserver.cpp \ src/serverrpc.cpp contains(CONFIG, "serveronly") { message("server only, skipping client rpc") } else { HEADERS += src/clientrpc.h SOURCES += src/clientrpc.cpp } } # use external OPUS library if requested contains(CONFIG, "opus_shared_lib") { message(OPUS codec is used from a shared library.) unix { !exists(/usr/include/opus/opus_custom.h) { !exists(/usr/local/include/opus/opus_custom.h) { message(Header opus_custom.h was not found at the usual place. Maybe the opus dev packet is missing.) } } LIBS += -lopus DEFINES += USE_OPUS_SHARED_LIB } } else { DEFINES += $$DEFINES_OPUS INCLUDEPATH += $$INCLUDEPATH_OPUS HEADERS += $$HEADERS_OPUS SOURCES += $$SOURCES_OPUS DISTFILES += $$DISTFILES_OPUS contains(QT_ARCH, x86) | contains(QT_ARCH, x86_64) { msvc { # According to opus/win32/config.h, "no special compiler # flags necessary" when using msvc. It always supports # SSE intrinsics, but does not auto-vectorize. SOURCES += $$SOURCES_OPUS_ARCH } else { # Arch-specific files need special compiler flags, but we # can't use those flags for other files because otherwise we # might end up with vectorized code that the CPU doesn't # support. For windows, libs/opus/win32/config.h says no # compiler flags are needed. sse_cc.name = sse_cc sse_cc.input = SOURCES_OPUS_X86_SSE sse_cc.dependency_type = TYPE_C sse_cc.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_IN_BASE}$${first(QMAKE_EXT_OBJ)} sse_cc.commands = ${CC} -msse $(CFLAGS) $(INCPATH) -c ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT} sse_cc.variable_out = OBJECTS sse2_cc.name = sse2_cc sse2_cc.input = SOURCES_OPUS_X86_SSE2 sse2_cc.dependency_type = TYPE_C sse2_cc.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_IN_BASE}$${first(QMAKE_EXT_OBJ)} sse2_cc.commands = ${CC} -msse2 $(CFLAGS) $(INCPATH) -c ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT} sse2_cc.variable_out = OBJECTS sse4_cc.name = sse4_cc sse4_cc.input = SOURCES_OPUS_X86_SSE4 sse4_cc.dependency_type = TYPE_C sse4_cc.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_IN_BASE}$${first(QMAKE_EXT_OBJ)} sse4_cc.commands = ${CC} -msse4 $(CFLAGS) $(INCPATH) -c ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT} sse4_cc.variable_out = OBJECTS QMAKE_EXTRA_COMPILERS += sse_cc sse2_cc sse4_cc } } } # disable version check if requested (#370) contains(CONFIG, "disable_version_check") { message(The version check is disabled.) DEFINES += DISABLE_VERSION_CHECK } # Enable formatting all code via `make clang_format`. # Note: When extending the list of file extensions or when adding new code directories, # be sure to update .github/workflows/coding-style-check.yml and .clang-format-ignore as well. CLANG_FORMAT_SOURCES = $$files(*.cpp, true) $$files(*.mm, true) $$files(*.h, true) CLANG_FORMAT_SOURCES = $$find(CLANG_FORMAT_SOURCES, ^\(android|ios|mac|linux|src|windows\)/) CLANG_FORMAT_SOURCES ~= s!^\(libs/.*/|src/res/qrc_resources\.cpp\)\S*$!!g clang_format.commands = 'clang-format -i $$CLANG_FORMAT_SOURCES' QMAKE_EXTRA_TARGETS += clang_format jamulus-3.9.1+dfsg/ChangeLog0000644000175000017500000016715214340334543014742 0ustar vimervimer ### 3.9.1 (2022-10-17) ### - Client: Improved performance of GUI when someone joins or leaves a server (#2738). (contributed by @ann0see) - Client: Bugfix: Removed channel number from saved fader tag when `--ctrlmidich` is in use. In this release `--cleanuplegacyfadersettings` can be used on any saved fader settings that have been corrupted to attempt recovery (#2839). (contributed by @pljones) - Bugfix: Correct new channel not being shown to others if it connects with null channel info (#2754, #2774). (contributed by @softins) - Server: Fixed --serverinfo country code misinterpretation introduced in Jamulus 3.9.0 on Qt6-based builds such as Mac (#2829). (contributed by @hoffie) - Server: Added support for ISO country codes (de, gb, nl, ...) in --serverinfo (#2841). (contributed by @hoffie) - Directory: Bug: Correct default "self" address for directory, enabling use as a server (#2812). (contributed by @pljones) - Directory: Bug: Use configured Directory Public IP for Client when hole-punching (#2819). (contributed by @pljones) - CLI: Rephrased recording options help text on the `--help` output for clearer description of their functionality (#2832). (contributed by @ann0see) - Windows: Upgraded JACK build to use JACK 1.9.21 (#2665). (contributed by @ann0see) - Translations have been updated (#2835, #2852, #2856, #2915): (mainly translated on @weblate by multiple translators) * Chinese, by @BLumia * Dutch, by @henkdegroot * French, by @trebmuh, @jujudusud, J. Lavoie * German, by @ann0see, Hans Spoerer * Korean, by @MarongHappy * Norwegian Bokmål, by @comradekingu * Polish, by @SeeLook * Portuguese European, by @mansil * Slovak, by @jose1711 * Spanish, by @ignotus666 * Swedish, by @tygyh, @comradekingu - Translation: Added nb_NO App translation (#2849, #2852). (contributed by @comradekingu, @ann0see) - Refactoring: Moved around files to clean up the repository (#2822, #2824, #2834, #2838). (contributed by @ann0see) - Build: Android: Export NDK root (#2764). (contributed by @pljones) - Build: Debian/Ubuntu: Fixed `.deb` Changelog generation (#2793). (contributed by @hoffie) - Build: Debian/Ubuntu: Fixed displayed version for non-release builds to removed incorrect -dirty suffixes (#2802). (contributed by @hoffie) - Build: Debian/Ubuntu: Renamed headless .deb file to `jamulus-headless_[version]_ubuntu_[arch].deb` for consistency with binary. This might need changes to scripts downloading this `.deb` file (#2821). (contributed by @ann0see) - Build: Debian/Ubuntu: Added .deb aarch64 (Raspberry) 64bit builds (#2895). (contributed by @hoffie) - Build: Mac: Combined Intel & M1 builds into a single Universal binary and improved M1 -dev build user-friendliness by introducing ad-hoc signing support (#2808, #2825). (contributed by @hoffie) - Build: Bump versions: actions/upload-artifact from 2 to 3 (#2796), actions/cache from 2 to 3 (#2798), DoozyX/clang-format-lint-action from 0.12 to 0.14 (#2797), actions/checkout from 2 to 3 (#2799). (contributed by @dependabot) - Build: Updated bundled Qt6 to version 6.3.2 (#2846). (contributed by @github-actions) - Internal: Enabled automated dependency updates via dependabot and custom automation (#2777, #2778, #2801, #2803). (contributed by @hoffie) - Internal: Hardened build scripts and tooling against silent failures (#2794). (contributed by @hoffie) ### 3.9.0 (2022-07-29) ### - Feature: Added **_EXPERIMENTAL_** new JSON-RPC interface to control client and server (see [docs/JSON-RPC.md](https://github.com/jamulussoftware/jamulus/blob/master/docs/JSON-RPC.md) for details) (#1975, #2505). (contributed by @dtinth, @Rob-NY) - GUI: Translations have been updated: * Chinese, by @BLumia (#2719) * Dutch, by @henkdegroot (#2708) * French, by @jujudusud (#2704, #2729) * German, by @ann0see (#2748) * Italian, by @dzpex (#2739) * Korean, by @bagjunggyu (assisted by @hoffie) (#2685, #2741) * Polish, by @SeeLook (#2735) * Portuguese Brazilian, by @melcon (#2728) * Portuguese European, by @melcon (#2747) * Slovak, by @jose1711 (#2732) * Spanish, by @ignotus666 (#2706) - GUI: Client: Added instructions for setting buffers when using Pipewire (#2645). (contributed by @gilgongo) - GUI: Client: Fix a bug where a blank line is shown after some client’s name in the mixer board in some conditions (#2542). (contributed by @dtinth) - GUI: Client: Include ASIO references in Windows ASIO version (#2605). (contributed by @henkdegroot) - GUI: Client: Removed wrongly mentioned "URL" from help texts (#2608). (contributed by @ann0see) - GUI: Client: Rephrase mute options in help text (#2673). (contributed by @pljones) - GUI: Client: Simplify device driver error message on Windows by removing unneeded HTML (#2496). (contributed by @ann0see) - GUI: Client: What's This Text and Tooltip updated for LEDs and Connection Status (#2644). (contributed by @henkdegroot) - GUI: Server: Amend server registration, added server list persistence (#2199). (contributed by @pljones) - GUI: Server: Adjust Server Language combo box length to fit into layout properly (#2424). (contributed by @pljones) - GUI: Server: Re-order Recorder widgets for better use of space (plus Qt6 compliance) (#2427). (contributed by @pljones) - GUI: Fix (hopefully) all remaining references to "directory server" in displayed messages to say "directory" (#2710). (contributed by @pljones) - GUI: Improved Country selection handling to work with Qt6 and cover 53 previously unsupported territories (#2409). (contributed by @hoffie) - GUI: Improved translator experience by using substitutions instead of concatenations (#2646). (contributed by @ann0see) - GUI: Removed occurrences of plain name "Jamulus" in translatable texts (#2609). (contributed by @ann0see) - Accessibility: Sound Alert for new person and new chat message (#2640). (contributed by @chigkim) - Accessibility: Combine all the client info, so screen reader users don't have to track down multiple places (#2638). (contributed by @chigkim) - Accessibility: Added name and instrument to accessibility labels for mute, solo, group (#2639). (contributed by @chigkim) - Client: Avoid losing gain changes (#2737). (contributed by @hoffie) - Client: Fix potential long delay in sending fader changes to the server (#2535). (contributed by @softins) - Client: Refactored JACK- and ASIO-related logic (#2443). (contributed by @hoffie) - Client: Removed the translation for the CLI version text output (#2602). (contributed by @henkdegroot) - Server: Fix loading of persistent server list entries (#2631). (contributed by @pljones) - Server: Headless Server now unregisters correctly (#2633). (contributed by @pljones) - Server: Clarify code for handling of requests for the server list (#2643). (contributed by @pljones) - Server: Improvements to the start up logging for the server list filter (#2647). (contributed by @pljones) - Server: Set default directory to "None" when not set in ini file or command line (#2442). (contributed by @softins) - Bug Fix: Build: .deb dependency fix to allow Jamulus being installed on Ubuntu 18.04 (#2423). (contributed by @hoffie) - Bug Fix: Client/Server: corrected operation of message ack timer (#2517). (contributed by @softins) - Windows: Create KR translation for installer (#2669). (contributed by @bagjunggyu) - Windows: The JACK build now no longer gives an ASIO related warning message on an incompatible state (#2494). (contributed by @ann0see) - Linux: Added the Jamulus Server desktop icon to the Debian/Ubuntu build and fixed SVG icon installation location (#2460). (contributed by @hoffie) - Linux: Removed unused `linux/deploy_linux.sh` script (#2512). (contributed by @ann0see) - Linux: Ubuntu: Added new runtime dependency. You will need to added the "universe" apt repository (on Ubuntu only) (#2721). (contributed by @pljones) - Linux: Updated package author information (#2652). (contributed by @hoffie) - Mac: Use latest Xcode version with SDK 10.15 support (#2266). (contributed by @hoffie) - Mac: Fixed non-working Save/Load Mixer Channel Setup (#2565). (contributed by @softins) - Mac: Upgraded create-dmg to the latest version (#2664). (contributed by @ann0see) - Android: Removed unneeded dependencies to speed up build (#2394). (contributed by @ann0see) - Android: Package version has been fixed to show the actual release version (#2398). (contributed by @hoffie) - Android: Improve sound driver to fix CodeQL warnings (#2457). (contributed by @softins) - Android: Improved compilation and updated liboboe to 1.6.1 (#2472). (contributed by @hoffie) - Android: Migrated to aqtinstall for Qt installation (#2497). (contributed by @hoffie) - Documentation: Updated the link to "Running a server" web page (#2419). (contributed by @jujudusud) - Documentation: Document compile time options to COMPILING.md (#2707). (contributed by @ann0see) - Documentation: Added high-level technical documentation for the Jamulus protocol (#2337). (contributed by @emlynmac) - Documentation: Made man page and help output more consistent. (#2448). (contributed by @gilgongo) - Documentation: Rewrite some parts of COMPILING.md and CONTRIBUTING.md to stay up to date and enable clearer contribution guidelines (#2561). (contributed by @ann0see) - Build: Added nojsonrpc qmake CONFIG option to remove JSON-RPC support (#2660). (contributed by @pljones) - Build: Make serveronly more comprehensive (#2551). (contributed by @pljones) - Build: Rename existing define to JACK_ON_WINDOWS (#2525). (contributed by @pljones) - Build: Moved CodeQL from Mac to Mac Legacy to work around signing incompatibility (#2564). (contributed by @softins) - Build: Provide unsigned iOS builds for easy install on iOS devices (#2355). (contributed by @ann0see) - Build: Added macOS M1 (arm64) support (#2682). (contributed by @hoffie) - Build: macOS will now be built with Qt 6.3.1 for better support of modern versions of macOS. Users of macOS 10.14 or earlier must from now use the legacy build or compile from source (#2672). (contributed by @ann0see) - Build: Improved grep usage in scripts #2421 (#2397). (contributed by @ann0see) - Build: Removed broken QMAKE_APPLICATION_BUNDLE_NAME. logic (#2477). (contributed by @hoffie) - Build: Initial support for building with Qt6 has been implemented (@dcorson-ticino-com, @softins) (#2299). (contributed by @hoffie) - Build: Updated aqt to v2.1.0 due to reliability reasons (#2597). (contributed by @ann0see) - Autobuild: Major overhaul, incorporating improvements in performance * Coding style and static checks for shell scripts are now enforced (#2635). * Build workflow download and cache optimisations (#2284, #2498, #2499, #2642). * Parallelisation of build processes (#2444, #2445) * Build script refactoring (#2284, #2451, #2470, #2473, #2476, #2489, #2501, #2502, #2509, #2514, #2527, #2540, #2584, #2642). (contributed by @hoffie) - Autobuild: Added experimental support for armhf (Raspberry-compatible) Linux .deb packages (#2526). (contributed by @hoffie) - Autobuild: Fix iOS artifact name (#2619). (contributed by @hoffie) - Autobuild: Build macOS .dmg files by create-dmg for building compatibility with further versions of macOS #2420 (#2207). (contributed by @ann0see) - Autobuild: Stop the build if the audio SDK is missing (#2536). (contributed by @pljones) - Autobuild: Stop running Autobuild if only documentation is updated to avoid wasting computation time (#2532). (contributed by @ann0see) - Autobuild: Build Windows version on latest build environment. This upgrades the Windows build process (#2649). (contributed by @ann0see) - Autobuild: Make Qt downloads on Windows more reliable by re-trying downloads (#2333). (contributed by @ann0see) - Autobuild: Backport Oboe's fixes CodeQl overflow warnings (#2548). (contributed by @ann0see) - Code: code restructuring to reduce cross-dependencies (CHighPrecisionTimer) (#2637). (contributed by @pljones) - Internal: Improved analyze_git_references.py script (#2471). (contributed by @hoffie) - Internal: Improved and reorganized git/Changelog scripts (#2656). (contributed by @hoffie) - Internal: Added .editorconfig for cross-language standardized indentation and line endings (#2585). (contributed by @hoffie) - Internal: Applied a consistent coding style to scripts (#2547, #2582). (contributed by @hoffie) - Internal: Added `make clang_format` helper command to simplify code formatting for contributors (#2258). (contributed by @hoffie) - Internal: Added debian/ folder to .gitignore file to ensure build files are not added to git (#2464). (contributed by @ann0see) - Internal: Check coding style on macOS/iOS code files (.mm extension) (#1871). (contributed by @ngocdh) - Internal: Use TODO and TEST comments instead of un-indenting with clang-format off/on (#2600). (contributed by @pgScorpio) - Internal: Removed unneeded white-space in all files and streamline line endings (#2402). (contributed by @ann0see) - Internal: Applied standard style to .md files (#2549). (contributed by @ann0see) - Internal: Move sound API files into src/sound folder. Contributors will now find the sound.cpp/sound.h/sound.mm in the src/sound folder for consistency (#2575). (contributed by @ann0see) - Internal: Move translation files one level up to make finding them easier for translators (#2576). (contributed by @ann0see) - Internal: Moved entitlements file to mac/ folder to clean up the repo root (#2529). (contributed by @ann0see) - Internal: Rename LED resources (#2621). (contributed by @henkdegroot) - Internal: Improved release contributor tooling (#2411). (contributed by @hoffie) - Internal: Improved Changelog release tooling (#2485, #2661). (contributed by @hoffie) - Internal: Moved outdated VST code on feature branch since there hasn't been any active development for a long time (#2461). (contributed by @ann0see) - Internal: Removed outdated qt-installer-windows.qs since we no longer use Travis CI (#2516). (contributed by @ann0see) ### 3.8.2 (2022-02-20) ### - Client: Added selection option for level meter style (#1688, #2352, #2356). (contributed by @henkdegroot, @hoffie, @pgScorpio, @pljones) - Client: On Windows, if no driver found while installing, the "Run Jamulus" option will not be checked (#2103). (contributed by @henkdegroot) - Client: on macOS, corrected minimum OS version number for Legacy installer from 10.13 to 10.10. Legacy installer will now install correctly on macOS Yosemite or newer (#2223). (contributed by @softins) - Client: Added Vibraphone to list of instruments (#2043, #2080, #2158). (contributed by @DavidSavinkoff, @softins, photo by @vibraphon) - Client: Added Conductor to list of instruments (#2140). (contributed by @henkdegroot) - Client: Fix wrong display of Unicode characters at line wrap and settings screen (#1994, #2274). (contributed by @djfun, @pljones, @hoffie) - Client: Fixed incorrect operation of feedback detection on first connect in run (#2120). (contributed by @softins) - Client: Added option always to show one's own fader first (#1809). (contributed by @ngocdh) - Client: Improved regex to highlight URLs in the chat window, avoiding terminating punctuation. Also migrated from deprecated QRegExp to QRegularExpression, for future compatibility with Qt6 (#2124, #2272, #2273). (contributed by @softins, @corrados, @hoffie) - Client: Improved keyboard control of the list of Custom Directories (#2129). (contributed by @pljones) - Client: Added the connected server name to the heading in the mixer panel (#2173). (contributed by @pljones) - Client: Enhanced the ASIO driver detection during installation on Windows (#2149). (contributed by @henkdegroot) - Client: On Windows, hide the ASIO button in the version that uses JACK instead (#2215). (contributed by @henkdegroot) - Client: Improved the "What's this?" text displayed for Buffer Delay (#2232). (contributed by @henkdegroot) - Client: Accelerator key clash between Settings button and Settings menu corrected (#2248). (contributed by @henkdegroot) - Client: Added option code 'o' in --ctrlmidich for "Mute Myself" (#2334). (contributed by @henkdegroot) - Client/Server: Output from --help and --version is now sent to StdOut instead of StdErr (#2244). (contributed by @henkdegroot) - Client/Server: Improved the version output on the command line to give more detail and Qt version (#2187). (contributed by @henkdegroot) - Client/Server: Added version and Jamulus URL to the Windows uninstall information registered when installing (#2201). (contributed by @henkdegroot) - Client/Server: Some improvements to text related to localisation (#2085). (Contributed by @BLumia) - GUI: Improved Connect Dialog help texts (#2121). (contributed by @pljones) - GUI: Translations have been updated: * Dutch, by @henkdegroot and @jerogee (#2371, #2314) * French, by @jujudusud (#2329, #2320, #2381) * German, by @ann0see, @rolamos and @hoffie (#2349, #2387) * Italian, by @dzpex (#2327) * Polish, by @SeeLook (#2375, #2331) * Portuguese Brazilian, by @melcon (#2369, #2358) * Portuguese European, by @melcon (#2368) * Simplified Chinese, by @BLumia (#2313, #2391) * Slovak, by @jose1711 (#2348) * Spanish, by @ignotus666 (#2378, #2326) * Swedish, by @softins (#2364) - Server: Fixed incorrect German translation (#2137). (contributed by @rolamos) - Server: Improved management and allocation of free channels, so that a new client always gets the lowest available channel number. Improves operation of clients with MIDI faders (#2151). (contributed by @softins) - Server: Improved the icon that is displayed in the Windows system tray for a server (#2231). (contributed by @henkdegroot) - Bugfix: IPv6 address formatting and obfuscation has been improved (#2343). (contributed by @rdica, @hoffie, @softins) - Windows Installer: Updated NSIS to v3.08 (#2208). (contributed by @ann0see) - Android: Some internal improvements to the experimental Android port buffer handling (#1528, #2237). (contributed by @j-santander, @softins) - Documentation: Enhanced the iOS compilation guide and signing instructions (#2139, #2315). (contributed by @ann0see, @RobyDati) - Documentation: Added a man page for Jamulus, from the Debian project (#2180). (contributed by @mirabilos) - Build: Raspijamulus build script has been improved to work with the latest Raspberry Pi OS releases and to include a newer JACK version (#2267). (contributed by @corrados, @softins) - Internal: Improved accelerator key detection (#2061). (contributed by @softins) - Internal: A hypothetical CodeQL-detected multiplication overflow in sound buffer handling has been fixed (#2292, #2297). (contributed by @softins) - Internal: Changed "Central" to "Directory" in names of variables and functions (#2079). (contributed by @pljones) - Internal: Corrected "Protcol" to "Protocol" in names of variables and functions (#2146). (contributed by @atsampson) - Internal: Some code reordering, particularly of the settings initialisation (#2174, #2177). (contributed by @pljones) - Internal: Removed unneeded submodules from tools directory, and replaced with a RELATED-PROJECTS document (#2196). (contributed by @softins) - Internal: Improved generation of the changelog for the Debian package, using dch (#2138). (contributed by @npostavs) - Internal: Improved powershell redirect handling when building for Windows in Github (#2225). (contributed by @henkdegroot) - Internal: Prepared autobuild logic for upcoming Qt6 compatibility (#2328). (contributed by @hoffie, @softins) - Internal: Release build process has been refactored and uses pinned dependencies for better reproducibility now (#2345, #2336). (contributed by @hoffie, @softins) - Internal: Moved documentation files into docs/ folder to clean up root folder (#2283). (contributed by @ann0see) ### 3.8.1 (2021-10-23) ### - Client: JACK support on Windows has been improved (#1718). (contributed by @jujudusud, @henkdegroot) - Client: Rewrote multiple error messages to improve UX (#1568, #1732). (contributed by @ann0see) - Client: Add custom directory servers to Connect Dialog (#1869, #1894). (contributed by @jp8) - Client: Rearrange existing UI menu bar items (#1915, #1926). (contributed by @jp8) - Bug Fix: Mute myself has been made more consistent (#1838). (contributed by @ngocdh) - Bug Fix: Fix ampersand not being shown correctly on mixer (#1886, #1893). (contributed by @HughePaul, @ann0see) - Bug Fix: A crash fix related to the way iOS handles sockets in idle mode (#1875). (contributed by @ngocdh) - Server: A single click on the server application in the systemtray now opens the Jamulus Server main window (#1722, #1731). (contributed by @henkdegroot) - Server: Jam Recorder's internal locking and initialization code has been made more robust (#1826). (contributed by @cdmahoney) - Server: The list of servers registered on a directory can now be saved during directory restart. Use the new --directoryfile CLI option to use this feature (#1867). (contributed by @pljones) - Server: Add link to website if a new version is available (#1980). (contributed by: @ann0see) - Bug Fix: Remove incorrect version of headless .service file (#2009). (contributed by @ann0see) - Client/Server: Add IPv6 support for direct connections (#1017, #1938). (contributed by @jardous, @softins) - CLI: Re-order and refactor help for client/server validation (#1896). (contributed by @pljones) - CLI: Jamulus now shows a link to the Website for translated content (#1759). (contributed by @henkdegroot) - Android: Add close button on Android to enhance UX (#1763, #1876). (contributed by @ngocdh) - iOS: Sound support, feature to allow switch between external device and the internal mic (#1875). (contributed by @ngocdh) - MacOS: Keyboard shortcuts now also work on macOS (#1726, #1873). (contributed by @henkdegroot) - Installer: Add zh_CN translation + for nsis win installer (#1922, #1954). (contributed by @BLumia) - Documentation: Move Demos, description of inputs options to Knowledge Base (#603, #551). (contributed by: @pcar75, @gilgongo) - Documentation: Add user experience section to CONTRIBUTING.md (#1885). (contributed by: @ann0see) - Documentation: Create Server Admin Manual (#527). (contributed by: @gilgongo) - Documentation: Update typo on links in compiling.md file (#1824). (contributed by @jujudusud) - Documentation: Number range command line error messages reworded accurately (#1978). (contributed by @DavidSavinkoff) - Website: switch to .po file format to make updating translations easier (various PRs) (contributed by: @ignotus666) - Website: Removed edit button from wiki layout file (#576). (contributed by: @DevRish) - Internal: Enable signing of macOS binaries (via build script and automatically via CI) (#1856, #1937). (contributed by @emlynmac) - Internal: Added Apple Appstore licence waiver (#1874) (contributed by @ann0see, @pljones, @gilgongo) - Internal: Add autobuild for Windows with JACK (#1829). (contributed by @henkdegroot) - Internal: Document release process on contribute page (#1594, #592). (contributed by: @hoffie, @ann0see) ### 3.8.0 (2021-06-02) ### - The term "Central server" has been replaced with "Directory server" (#1407, #1715, #1629). Note that the program will still accept the --centralserver option for backward compatibility with existing system startup scripts, but its usage is deprecated. (contributed by @pljones, @softins) - Mac: Generate build with Qt 5.15.2 for better compatibility with Big Sur (#1687, #1768). We still build a legacy version with Qt 5.9.9 to support older versions of macOS: * Users of 10.13 (High sierra) or newer should use the standard build with Qt 5.15.2 * Users of Yosemite, El Capitan or Sierra should use the legacy build with Qt 5.9.9 (contributed by @softins) - GUI: Settings window has been reorganized into tabs (#1415, #1554, #1542, #1588): * User Profile window has been integrated into the settings window. * Input Pan has been moved to the newly created Advanced tab and removed from main window. (contributed by @dcorson-ticino-com, @pljones) - GUI: Moved the Ping and Delay stats from the Settings window to the main window (#1762): This was partly to work around a Mac issue with updates to the settings window (#1643) and is actually an improvement anyway, as the settings window does not need to remain open. (contributed by @dcorson-ticino-com and @softins) - GUI: Added "About Qt" to the help menu to display version of Qt (#1685, #1692). (contributed by @softins) - GUI: Corrected the operation of What's This in the settings dialog (#1622, #1635). (contributed by @dcorson-ticino-com) - GUI: Improved the muted speaker icon display (#1691). (contributed by @henkdegroot) - Added new icons for Linux desktop use (#1672). (contributed by @jujudusud) - GUI: Corrected handling of custom directory server in the server, to prevent unintended registration with a directory server (#1624, #1627). (contributed by @softins) - GUI: Corrected alignment of Mute icon above fader (#811, #1312, #1640). (contributed by @vimpostor) - GUI: Support for more than two mixer rows has been added (#1549, #1560). (contributed by @pljones) - GUI: --clientname also works in dialog titles now (#1352, 1370). (contributed by @dcorson-ticino-com) - GUI: Translations have been updated * Dutch, by @henkdegroot (#1562, #1623, #1714, #1557) * French, by @jujudusud (#1648, #1708) * German, by @rolamos (#1677, #1810) * Italian, by @dzpex (#1620) * Polish, by @SeeLook (#1619) * Portuguese Brazilian, by @melcon (#1671, #1807) * Portuguese European, by @Snayler (#1689) * Slovak, by @jose1711 (#1647) * Spanish, by @ignotus666 (#1621, #1730, #1808) * Swedish, by @genesisproject2020 (#1664, #1696) - Network: Support for DSCP Quality of Service flags has been added (#1310). This is supposed to lead to improved network performance. It is enabled by default. On Windows, this requires additional configuration in order to work. Please see the Tips & Tricks page on the website for a setup guide for Windows. (contributed by @DavidSavinkoff) - Client: Automatic channel fader adjustment simplifies mixer setup by using the channel level meters (#1071). (contributed by @JohannesBrx) - Client: Basic audio feedback detection has been added (#1179). (contributed by @JohannesBrx) - Client: Support for input gain boost has been added (#1222, #1030) (contributed by @hoffie) - Client: Grouping support has been extended to allow for up to eight groups (#1551). (contributed by @pljones) - Client: A hint regarding non-default Jack support has been added (#1397, #1438). (contributed by @djfun) - Server: Support for Delay Panning has been added (#332, #567, #1151, #1417, #1744): This feature can be enabled on servers using the new --delaypan option. Enabling this feature will slightly increase server CPU usage. It can create a much more realistic spatial sound impression for clients that are set to Stereo or Mono-in/Stereo-out mode. (contributed by @DetlefHennings, @Hk1020, @softins, @henkdegroot) - Server: Multi-threading performance has been improved (#960). (contributed by @menzels, @softins) - Server: Half-connected clients will no longer receive audio (#1243, #1589): Note: This breaks compatibility with client versions before 3.3.0 (Feb 2013). If you update your server, ensure that all clients use 3.3.0 or later as well. (contributed by @softins) - Server: HTML status file is now emptied on exit (#1423, #1427). (contributed by @hoffie, @drummer1154) - Server: An explicit bind address can now be specified (#141, #1561). This can be done by the new --serverbindip option. (contributed by @buv) - Recorder: Compatibility with third-party tools such as Audacity has been improved (#1384, #1424, #1437). Non-ASCII characters are now stripped out when creating filenames. (contributed by @softins, @gilgongo, @reinhardwh) - Recorder: Failures to start recording no longer result in crashes (#1163, #1289, #1463). (contributed by @hoffie, @softins, @pljones) - Recorder: Logging has been improved (#1284, #1463). (contributed by @hoffie, @drummer1154) - Bug fix: The mute indicator is now also shown in mono mode (#1074). (contributed by @npostavs) - Bug fix: Channel mapping on Windows now only resets if the sound card or the numbers of channels changed (#1347). (contributed by @ann0see) - Bug fix: Jamulus client should now close itself correctly if a non-working device was selected (#872). (contributed by @npostavs) - Bug fix: Server no longer crashes while changing the recording directory (#1501, #1573). (contributed by @henkdegroot, @hoffie, @softins) - Bug fix: Example systemd unit has been fixed to avoid crashing when sending signals (#1515, #1518). (contributed by @softins, @helgeerbe, @gilgongo) - Bug fix: The Windows installer now correctly compiles in a path with spaces (#864, #1319). (contributed by @henkdegroot) - Performance: Opus encoding/decoding now uses machine-specific optimizations (#1105). (contributed by @npostavs) - Performance: Timer configuration for Windows servers has been improved (#1536). (contributed by @npostavs) - iOS support is being worked on (#1450). (contributed by @jeroenvv) - Github autobuild for Mac now uses Xcode 11.7 and SDK 10.15 for compatibility with Qt5 (#1655). (contributed by @softins) - Build: Creation of debug builds has been simplified (#1516). (contributed by @hoffie) - Internal: Constants for JACK usage have been renamed (#1429). (contributed by @djfun) - Internal: Legacy IP address variables have been cleaned up (#1400). (contributed by @wferi) - Internal: Added automatic code formatting with clang-format (#901, #1127, #1751). (contributed by @passing) - Internal: New pull requests will now be checked for coding style automatically (#1735). (contributed by @passing) - Internal: Windows deploy script has been aligned to autobuilds (#1720). (contributed by @henkdegroot) ### 3.7.0 (2021-03-17) ### - Server lists have been reorganized to make room for more servers (#875): * Default has been renamed to Any Genre 1. * Any Genre has been renamed to Any Genre 2. * Any Genre 3 has been added. * Choral/Barbershop has been added. * Classical/Folk/Choral has been renamed to Classical/Folk. - Central server addresses have been moved to the jamulus.io domain (#919). The fischvolk.de addresses are deprecated. - GUI: If a name is provided using --clientname, that name is shown first in the window title, to avoid clipping in the Windows task bar (#789). - GUI: Translations have been updated: * Dutch, by @jerogee (#1110) * French, by @trebmuh & @jujudusud (#1199 & #1113) * German, by @rolamos (#1097) * Italian, by @dzpex (#1112) * Polish, by @SeeLook (#1099) * Portugese, by @melcon & @Snayler (#1141 & #1168) * Slovak, by @jose1711 (#1104) * Spanish, by @ignotus666 (#1152) * Swedish, by @genesisproject2020 (#1182 & #1106) - Active recording state is now highlighted in the mixerboard title (#968). (contributed by @dcorson-ticino-com) - Client window makes it more obvious when not connected to a server by graying out input levels and showing a message (#847, #983). (contributed by @ann0see) - Screensaver and screen blanking are now prevented on Macs (#834). (contributed by @jerogee) - Windows installer has been improved (#792, #841). Note: If you are using ASIO4ALL, we strongly suggest that you take a screenshot of your ASIO4ALL settings before upgrading. The installer will try its best to migrate your settings, but it may fail to do so when using custom installation paths. (contributed by @ann0see and @doloopuntil) - Windows installer interface now supports English, Dutch, French, German, Italian, Polish, Portuguese, Spanish and Swedish. (contributed by @jerogee, @jujudusud, @ann0see, @dzpex, @SeeLook, @Snayler, @melcon, @ignotus666 and @genesisproject2020) - Windows ASIO Setup button placement has been improved to be below the driver selection (#977). (contributed by @mulyaj and @ann0see) - Chat dialog has gained support for auto-linking http addresses (#879). (contributed by @hoffie) - Chat messages no longer allow HTML-formatted chat messages due to security reasons (#939). HTML formatting in Welcome messages will continue to work. (contributed by @atsampson) - Mixerboard background image quality in the Fancy skin has been improved (#970). (contributed by @passing) - MIDI controller logic has been improved to support fader, pan, mute and solo buttons in --ctrlmidich syntax (#945). Mute & solo buttons are only for toggle-type controllers and do not support headless operation yet. (contributed by @dakhubgit) - Servers connected to central servers behind the same NAT can now be made accessible to public clients via the newly added --serverpublicip option (#954). (contributed by @hoffie) - External IP detection no longer generates traffic to Cloudflare (#633, #1092). (contributed by @atsampson and @hoffie) - Version update detection has been improved (#1155): * The check now uses two servers instead of one (updatecheck1.jamulus.io and updatecheck2.jamulus.io). * The server version is now ignored if it is not a release, due to a suffix such as dev, beta or rc. (contributed by @softins) - Official Ubuntu/Debian packages are now built and published as part of the release (#1100). The packages are compatible with Ubuntu 18.04 or later. (contributed by @ann0see) - Experimental .apk installation packages for Android are now provided (#880). (contributed by @nefarius2001) - Bug fix: A suspected memory leak has been solved by removing usage of ConsoleWriterFactory (#926). (contributed by @pljones) - Bug fix: Changing ASIO driver properties like switching input/outputs in ASIO4ALL now resets input/output channel mapping in Jamulus again (#796). This was done to solve a bug with ASIO4ALL introduced in the last version. - Bug fix: Fader levels, mute and solo state are now restored properly when reconnecting to a restarted server (#955, #1010). This is a server-side fix. (contributed by @hoffie) - Bug fix: Multiple memory leaks in the server's recording feature have been fixed (#1073). (contributed by @softins) - Bug fix: Menu accelerator keys have been fixed in multiple translations (#1165). (contributed by @softins) - Bug fix: Windows sound driver lacked driverInfo initialisation (#1194). (coded by @npostavs) - Internal build and release process have been re-designed, automated and moved to Github. (contributed by @pljones, @nefarius2001, @ann0see, @ranfdev) - Internal development builds now contain a detailed version number (#475). (contributed by @nefarius2001) ### 3.6.2 (2020-12-12) ### - change Clear All Stored Solo Settings to clear Mute as well (#731) - avoid selecting IPv6 results from hostname lookup, coded by jarmar (#722) - added possibility to set MIDI offset for fader control to --ctrlmidich (#95) - detect if no audio Device is selected before trying to connect a server (#129) - on MacOS if an audio device is no longer available, show a warning rather than switching to default automatically (#727) - bug fix: sliders move by themselves if fader groups are used on reconnect (#611) - bug fix: do not reset sound card channel selection on a device property change (#727) - bug fix: compiling Jamulus 3.6.1 is failing on Debian 9 Linode (#736) - bug fix: on MacOS Jamulus does not always select the previous sound card (#680) - bug fix: use new server icon on Mac server bundle and Windows installer (#737) - bug fix: ping times of servers which are further down the server list are too high (#49) ### 3.6.1 (2020-11-21) ### - added menu entry "Set All Faders to New Client Level" (#622) - isolate a channel from the group temporarily with shift-click-drag (#695) - on shift-click the pan reset to 0 L/R (#707) - support multiple custom central server addresses (#698) - the Jamulus server now has a different icon, created by geheimerEichkater (#700) - support two rows for the mixer panel (#720) - changed RYG indicator lights with colour-blind compensation, created by geheimerEichkater (#57) - saving and loading mixer settings is now possible during an active connection and a mixer settings file can be loaded with drag'n'drop (#706) - menu entry Clear All Stored Solo Settings is now enabled during an active connection - bug fix: the fader group property was not correctly loaded from the ini file ### 3.6.0 (2020-10-25) ### - handle audio packets received out of order, coded by softins (#619) - most recently connected users appear on the RH side on the fader panel (#673) - improvements for the server multithreading, coded by kraney (#653) - removed Display Channel Levels setting and --servername (#638) - removed support for further server infos in --serverinfo since the preferred way of registering a server is to do it using the protocol messages (#638) - removed -g, --pingservers since all Central servers must activate this function, now it is activated by default and no command line argument is needed (#638) - added --mutemyown command line argument to mute my own signal in my personal mix, only supported in headless client mode (#340) - added "Mountain Dulcimer" instrument icon, created by dora71 (#649) - added new instrument icons for "Scratching" and "Rapping" - replaced double types by floats for some of the signal processing, coded by hselasky (#544) - support permanent channel fader sorting (i.e., not only on request but always) (#666) - support sorting faders by channel city - if sorting the faders by instrument, we now sort by the name for the same instruments - improvements to the Android audio interface, coded by j-santander (#83) - bug fix: reduced server list is displayed instead of the normal list (#657) ### 3.5.12 (2020-10-03) ### - added hyperlink support for the chat window, coded by jc-Rosichini (#591) - added new menu entry "Clear All Stored Solo Settings" (#616) - fade in all clients at the server when entering a server to avoid the volume is at 100% when joining a server (#628) - added a qmake CONFIG flag for disabling the automatic version check (#370) - avoid confusion with the Server Address field on the connection setup window by no longer showing the server name in that field since it is only intended for entering IP addresses or valid server URLs (#365) - removed the "Show Creative Commons BY-NC-SA 4.0 Licence Dialog" setting from the server GUI and changed the -L/--licence text in the licence dialog to "Do you agree to the text in the chat window?" so that a licence text must now be given in the server welcome message (#587, #367, #81) - added a protocol message for a reduced server list to improve the situation caused by UDP packet fragmentation (#631, #255) - added translation: Slovak by jose1711 (#635) - bug fix: crash when using the jam recorder in the server, coded by pljones (#618) ### 3.5.11 (2020-09-19) ### - support a check for updates (#370) - added an optional server list whitelist filter (#413) - added a command line argument to enable multithreading in the server (#339) - added support for split protocol messages (fixes bug with large number of clients connected to a server, #547) - store recorder settings, coded by pljones (#313) - added a command line argument to disable recording on start up, coded by pljones (#574) - accessibility improvements, coded by chigkim (#498, #512) - added Jack audio latency calculation, coded by bflamig (#437) - show the server name in the title bar (#559) - bug fix: crash when using the Jack backend and quickly reconfiguring, coded by hselasky (#543) - bug fix: Alt+h shortcut to open the Chat dialog did not work, use Alt+c instead - bug fix: pan is not correctly initialized in the server on a new connection (#537) ### 3.5.10 (2020-08-16) ### - do not change the server list order if the mouse is over the table to avoid selecting an incorrect server on a mouse double click (#293) - if network name/address contains spaces, they are removed now, coded by dingodoppelt (#462) - improve Compact skin by using smaller font size - improve server audio mix processing for better clipping behavior - support MIDI control faders in headless build (#483) - option to set Mute Myself on with a command line argument (#495) - added a red message to indicate that Mute Myself is activated (#476) - manual clip LED reset by mouse click on the level meter (#421) - replacing internal history graph functionality by external scripts/tools (#501) - accessibility improvements, coded by chigkim (#499, #510, #514) - bug fix: fixed a stability issue in the server - bug fix: --showallservers ping column sort is alphabetic (#201) ### 3.5.9 (2020-07-19) ### - new app icon for Jamulus, created by geheimerEichkater (#410) - support up to four different groups for the channels (#202) - support sorting faders by channel group - add support to change the GUI language (#297) - add special server list filter for filtering occupied servers by using "#" (#397) - update server UI to allow setting the jam recorder directory (like -R) (#228, #405) - redesign of the server dialog (e.g. added welcome message setting) - save and restore mixer state (like fader, mute, etc.) (#377), note that saving/loading of settings only works if not connected - scale channel instrument picture in Compact skin mode - show maximum number of clients for servers in the serverlist, coded by dingodoppelt (#451) - log the number of connected clients on each new connection (#277) - move the Mute Myself button up to prevent accidentally disconnecting - bug fix: grouping faders in the client should be proportional (see discussion in #202, #419) ### 3.5.8 (2020-06-30) ### - bug fix: incorrect selection of UI language (#408) ### 3.5.7 (2020-06-28) ### - add new "compact" skin, intended for large ensembles (#339) - support sorting faders by channel instrument, coded by Alberstein8 (#356) - new group switch to change several faders in sync, coded by Alberstein8 (#202, #379) - support a clip LED, coded by fleutot (#220) - add server recording indicator, coded by pljones (#295) - support for storing/recovering the server window positions (#357) - add a headless build type which does not depend on QtGui/QtWidgets, coded by marcan (#322) - the local pan middle position is no longer attenuated in Mono-in/Stereo-out mode (#353) - added translation: Brazilian Portuguese by melcon (#372) - add send button to chat window (#384) - add some protections to the code, coded by atsampson (#380, #381, #382) - bug fix: server window stop updating after minimized, coded by AronVietti (#355, #383) ### 3.5.6 (2020-06-09) ### - support sorting faders by channel name (#178) - enable/disable recording from command line, coded by pljones (#228) - add Audacity "list of files" writer to jam recorder, by pljones (#315) - make level meter LED black when off, by fleutot (#318) - added ukulele/bass ukulele instrument icons created by dos1 (#319) - avoid showing IP address if no name in the musician profile is given (#316) - show channel numbers if --ctrlmidich is used (#241, #95) - added check in acknowledge message, coded by atsampson (#302) - bug fix: on MacOS declare an activity to ensure the process doesn't get throttled by OS level Nap, Sleep, and Thread Priority systems, coded by AronVietti (#23) ### 3.5.5 (2020-05-26) ### - added banjo/mandolin instrument icons created by atsampson (#283) - faster update of musicians list in the server list table - display recorder state and latest recording directory in the server GUI, allow a new recording to be requested, by pljones (#228) - New Client Level now also applies if you enter a server - bug fix: honour own fader and Mute button in Mute Myself (#148) - bug fix: audio fader sliders cannot be moved if the main windows is too small (#292) - bug fix: server gain calculations were incorrect (introduced in version 3.5.4) ### 3.5.4 (2020-05-24) ### - introduce genre-based server lists (#139) - implement panning for channels, coded by tarmoj (#52, #145) - added an indicator that another client has muted me (#257) - move central server type dropdown to connection setup (#157) - added vocal bass/tenor/alto/soprano instrument icons created by Alberstein8 (#131) - support intermediate Reaper RPP file while recording, coded by pljones (#170) - save client settings on Linux cmdline termination signal, coded by pljones (#70) - added translation: Italian by dzpex (#249) - bug fix: fixed misaligned tracks in recordings, coded by snayler, improved by pljones (#234) ### 3.5.3 (2020-05-15) ### - correct unregister of headless server and RPP file creation on SIGINT/SIGTERM, coded by pljones (Tickets #130, #168) - for CoreAudio and 4 channel input, support mixing channels 1&2 with 3&4 - added bassoon/oboe/harp instrument icons created by dszgit, congas/bongo created by bspeer (#131) - link to docs from application Help menu (#90) - support Mac CoreAudio aggregated devices (#138) - added translations: French by trebmuh, Portuguese by Snayler, Spanish by ignotus666, Dutch by jerogee, German by corrados (#77) - new design for the About dialog (#189) - new command line option -d to disconnect all clients on shutdown of the server (#161) - bug fix: for mono capture Jack audio interface Jamulus complains it cannot make connections (#137) - bug fix: fixed that Jamulus segfaults when jackd is restarted (#122, #127) - bug fix: better handling of disconnect message in the client - note: Jamulus is no longer compatible to Qt4 ### 3.5.2 (2020-04-24) ### - use audio level meter bars for normal skin - store Show All Musicians setting in the ini-file - improved Mac installer, coded by doloopuntil - support to open ASIO driver setup(s) if startup failed due to incorrect driver settings (#117) - added -v/--version command line argument to output version information (#121) - added bodhran and other instrument icons, bodhran created by bomm (#131) - bug fix: if small network buffers are used we get much better audio quality when drop outs occur - bug fix: if names given with the -o option were too long, the server registration failed (#91) - bug fix: audio level changes if Buffer Delay is changed (#106) - bug fix: do not reset fader level meters if number of clients change - bug fix: fixed a crash with JackRouter 64 bit ASIO driver (#93, thanks to elliotclee) ### 3.5.1 (2020-04-18) ### - added a Mute Stream button to hear your signal and the signal of the other clients but do not transmit your signal to the server so that the other clients cannot hear you - added Enable Small Network Buffers switch to enable small sound card buffers in combination with legacy OPUS packets since OPUS packets with 64 samples enable low latency but can increase audio drop outs - upgrade OPUS codec library to v1.3.1 by doloopuntil - server list registration status indicator added to the server GUI, coded by pljones - improved auto jitter buffer for 64 samples frame size - the ping times in the server list are now more stable ### 3.5.0 (2020-04-15) ### - added support for 64 samples OPUS packets in the client (if a sound card buffer size larger or equal than 128 samples is chosen, the legacy 128 samples OPUS packets are used) - added a filter for the server list to, e.g., filter a specific country or search for a musician - refresh server list if the Central Server address type is changed - the unit of the mixer faders is now dB using the range -50 dB to 0 dB - increased LED luminance (#71) - bug fix: the server welcome message may appear twice if the server list was double clicked ### 3.4.7 (2020-04-11) ### - added support for alternative Central Servers to solve the 200 server registration limit (#50) - added support for 64 samples frame size in the server (if server runs in 64 or 128 samples mode it is still compatible to both, 64 and 128 samples frame size clients) - added multichannel CoreAudio support, coded by emlynmac (#44) - fixed server not visible if in same local network, coded by pljones (#27) ### 3.4.6 (2020-04-09) ### - added support for channel meters, coded by pljones - added show licence switch in the server GUI - store fader mute state in the ini file, coded by doloopuntil - fixed low-res icon issue (#28) ### 3.4.5 (2020-04-04) ### - audio fade-in at the server if a new client connects - added a scroll bar to the mixer board to support large numbers of mixer faders (a thank you to doloopuntil for his help) - changed the maximum number of clients supported by the server from 20 to 50 - Windows installer now contains a 32 and 64 bit version of Jamulus (the version to be installed is selected automatically according to the detected operating system) - bug fix: server list ping times may not be accurate and client list may not be retrieved ### 3.4.4 (2020-03-25) ### - added support for controlling the audio mixer faders with a MIDI controller (MacOS and Linux) - added command line argument for disabling auto jack connection (#49) - audio recording for the server, coded by pljones - SVG server history graph, coded by pljones ### 3.4.3 (2018-05-17) ### - for ASIO and 4 channel input, support mixing channels 1&2 with 3&4 - bug fix: fixed a crash, running Jamulus on MacOS version "High Sierra" ### 3.4.2 (2017-08-11) ### - removed old CELT library (minimum compatible version is now 3.3.1) - show server name in the server list in bold font if it is a permanent server - Jack can be used instead of CoreAudio on MacOS (using qmake "CONFIG+=jackonmac") ### 3.4.1 (2016-02-10) ### - show the number of connected clients in the MacOS task bar if more than one client is connected - avoid a single jitter buffer for the auto detection - the Musicians value in the server list shows a warning if the server is full - automatic server setting for permanent server flag in the protocol - bug fix: ping time measurement may be invalid for the Linux OS ### 3.4.0 (2015-12-10) ### - show the names of the connected clients in the server list ### 3.3.11 (2015-11-26) ### - added a new client fader level setting - changed the MacOS audio interface to be future proof (do not use the Carbon Component Manager anymore) - added support for audio channel selection for MacOS ### 3.3.10 (2015-10-20) ### - changed the default central server URL - added support for server disconnection ### 3.3.9 (2015-07-12) ### - another improvement of auto jitter buffer detection in very bad network conditions - support client operation without using a GUI front end - bug fix: fixed a crash in the MacOS audio interface ### 3.3.8 (2015-03-15) ### - improved audio quality in bad network conditions - more realistic overall delay estimation - improvement of auto jitter buffer detection in bad network conditions - show info about sound card buffer size if not one of the standard sizes ### 3.3.7 (2015-02-05) ### - added a musician profile dialog (some settings in the main window were removed) - a tool tip for the fader tag shows the complete musician profile - the city and skill level can be set in the musician profile - added new instrument picture for "Guitar+Vocal" ### 3.3.6 (2015-01-25) ### - support for a country flag icon on the fader tag - a licence agreement dialog can be requested by the server ### 3.3.5 (2014-07-30) ### - new compile config options for disabling old CELT, use OPUS in a shared library and change the executable name - added a Linux jamulus.desktop file ### 3.3.4 (2014-02-25) ### - true stereo reverberation effect (previously it was a mono reverberation effect on both stereo channels) - added a mono-in/stereo-out mode to support special sound cards which have mono inputs for the instrument and a microphone but have stereo outputs - store fader solo state in the ini file - improved stability of the audio stream by reducing audio drop outs (by using a separate socket thread) - removed unnecessary settings and LED indicators - bug fix: the fader level could not be changed if the fader was on solo ### 3.3.3 (2013-12-30) ### - support for storing/recovering the window positions - added new instrument pictures for "Recorder", "Streamer" and "Listener" - the solo state of a mixer fader is not exclusive any more and the solo state is preserved if the number of mixer faders changes - more precise sound card latency estimation under Windows - integrated a new OPUS version: v1.1 - bug fix: support for correct utf-8 storage of names in the ini-file ### 3.3.2 (2013-08-24) ### - the connection setup dialog can now be opened during a connection - support for three audio quality settings: low, normal and high ### 3.3.1 (2013-03-24) ### - enabled the OPUS codec - store fader level settings - improved server performance under Linux - changed the network buffer for improved OPUS PLC performance - added protocol overhead for DSL line for upload rate calculation - fixed outstanding renaming from llcon to Jamulus - bug fix: the overall delay was not correctly calculated ### 3.3.0 (2013-02-24) ### - renamed the software from llcon to Jamulus - support for an instrument picture on the fader tag - a server welcome message can be shown on a connect to the server (the message is shown in the chat dialog of the client) - the source code is now compatible to Qt5 - bug fix: strings in the protocol are now utf-8 coded ### 3.2.2 (2012-07-15) ### - changed auto jitter buffer property to reduce audio drop outs - bug fix: mechanism to keep port in NAT of slave server open works now correctly - bug fix: slave server unregistering may not be successful ### 3.2.1 (2012-02-02) ### - support for audio device selection under Mac OS - connect dialog list is sorted by the ping time - software icon changed - bug fix: fixed distorted audio with USB sound cards on Mac OS - bug fix: fixed crash on slave server unregistering ### 3.2.0 (2011-07-23) ### - new GUI style of the main window, added switch for selecting the GUI style in the settings window - a list of available servers is shown on pressing the connect button, the list is managed by a central server, any private server is added automatically if the registering setting is enabled - the jitter buffer size can be independently set for client and server - improved auto jitter buffer algorithm - the Qt project file is now used for Linux, too - ini-file is stored in the home directory instead of the application directory - added server settings in the GUI for the server list and added ini file support to store the settings - bug fix: fixed Jack audio interface instability ### 3.1.2 (2011-03-02) ### - show warning in main window if audio delay is too long - added download link in help menu - bug fix: solo switch did not work correctly ### 3.1.1 (2010-07-01) ### - added stereo audio channel support - added input/output audio channel mapping for ASIO audio interface ### 3.1.0 (2010-03-16) ### - support for MacOS (using CoreAudio audio interface) - sound card frame size support for frame sizes other than 128, 256 and 512 samples - improvement of network buffer (jitter buffer) in case of small buffer sizes - all available ASIO sample formats supported - bug fix for M-Audio Delta ASIO driver ### 3.0.3 (2009-12-05) ### - accessibility improvements - show number of connected clients in window title (and therefore in OS task bar) - added "What's this" help text to the GUI controls in the general settings dialog, added Tool Tips to some GUI controls - server logging history grid lines of weekend days are now plotted with different line width - removed ALSA support since the ALSA interface implementation in llcon was buggy and will not be maintained in the future - bug fix: fix for server logging history graph x-axis - bug fix: fix for disconnect issue at the server ### 3.0.2 (2009-09-21) ### - new server features: for chat messages the time stamp is also shown, parsing of existing log file supported - updates for help texts - new design for fader tag - change for Jack Linux audio interface: ports are only registered and connected once when the software is started up - bug fix: under bad network conditions chat messages were randomly repeated - bug fix: in case the server was shutdown and restarted during a connection, the channel name was not updated correctly at the server ### 3.0.1 (2009-08-23) ### - use low complexity CELT encoder profile, this lowers audio dropout probability on slow computers - in case "Open Chat on New Message" is not enabled, a hint in the status bar is shown when a message is received - bug fix: buzzing occurred when audio stream was interrupted (e.g. in case of network trouble) ### 3.0.0 (2009-08-19) ### - introduced new audio codec "CELT", not compatible to old versions - only the sound card frame sizes 128, 256 and 512 are allowed (since other frame sizes require additional conversion buffers which introduce delay) - IMA-ADPCM, MS-ADPCM removed - since CELT works on 48 kHz sample rate, resampling was removed - various bug fixes (e.g. disconnecting did not work reliably) ### 2.3.0 (2009-07-09) ### - new system sample rate of 33 kHz to improve audio quality, not compatible to old versions - added history graph for server logging - added command line argument for connecting a server at software start-up ### 2.2.2 (2009-05-14) ### - "Mute" and "Solo" check boxes for each connected client fader - store previous server URLs - changes to the main GUI (grouped "local" and "server" settings) - LED status lights and LED input level meter - better behaviour on disconnection (introduced disconnection protocol message) ### 2.2.1 (2009-03-29) ### - bug fix and improvements for automatic jitter buffer size setting ### 2.2.0 (2009-03-13) ### - added Jack audio interface (Linux) - simplified settings dialog, complete redesign (removed sound card buffer settings, network block sizes settings, added upload rate display) - improved audio stability (audio interface is not callback based, removed intermediate audio buffers, client audio buffer size equals network buffer size now) - added upload rate limitation for server (server decides which network parameters to use depending on the upload limit and the number of connected clients) ### 2.1.4 (2009-02-15) ### - added automatic jitter buffer size setting - speed optimizations to improve audio interface stability - new default settings (e.g. turn off Reverb by default since it requires significant CPU) ### 2.1.3 (2008-11-02) ### - added sound card selection - improved ASIO configuration - added total delay display ### 2.1.2 (2008-08-15) ### - audio compression type can be selected (IMA ADPCM, MS ADPCM, None) - security checks for protocol messages (wrong messages could crash the software) - bug fix: ping time measurement problems on Windows OS fixed ### 2.1.1 (2008-08-03) ### - added a chat window - the client can select a port number of server additional to the URL - the server can be operated on an arbitrary port number - ping time information in general settings dialog added ### 2.1.0 (2008-07-17) ### - ASIO support ### 2.0.0 (2008-03-29) ### - first QT4 compatible release ### 0.9.9 (2007-09-10) ### - new client settings dialog - at each client a separate audio mix can be generated for all connected clients at the server ### 0.9.4 (2006-03-10) ### - added a protocol mechanism, now it is possible to set the jitter buffer in the server according to the setting in the client (they are coupled now) - removed sample rate offset estimation since it was not used anyway - internal audio processing in the server is now based on the minimum block size (improves latency) ### 0.9.1 (2006-01-28) ### - initial version jamulus-3.9.1+dfsg/android/0000755000175000017500000000000014340334543014574 5ustar vimervimerjamulus-3.9.1+dfsg/android/AndroidManifest.xml0000644000175000017500000001522514340334543020372 0ustar vimervimer jamulus-3.9.1+dfsg/android/res/0000755000175000017500000000000014340334543015365 5ustar vimervimerjamulus-3.9.1+dfsg/android/res/drawable-hdpi/0000755000175000017500000000000014340334543020070 5ustar vimervimerjamulus-3.9.1+dfsg/android/res/drawable-hdpi/icon.png0000644000175000017500000001004314340334543021524 0ustar vimervimerPNG  IHDRHHUGtEXtSoftwareAdobe ImageReadyqe<%iTXtXML:com.adobe.xmp _$ IDATx\ pFV$@&1G1.p\18IA9S $8Ďc . 9$.C2 @7BV>VRWbfhoڿ3~ =#nR 8zH 6K'S+~Q:Ǝ>rzй'bM֒0cPj_3['CF e%x-AlHz07ȓ>I[aϒq;D'@ 38Իs0 V2ҊaEL3sr@~c=s~Ҕ( [lr :Zi tƵ7z;}!> ,-=A6*,,FWqsݩ㵭K1V]ͰoPJ rPile!C% y $kƂ(r¿P.U&֐XX6 Y;(u ǥymC=BЦ4W͏Ϗ kȊ8S6TLˊ 0K څMi*\=`}jhp F^\[EdA30J ʷ\9z~fe/an'^1H}Wyم|[9xQ:x2i1A.w QLFy@Ȓ@|H\$!VF:f3{B-U/D0:״±ZOzT\xRaYevb(oz田ijUX6q.L7orK¼&@h(Y>J&MnDa9Đ^zkZ(O4J:<`kV>+B!ɋWz}bZgJ@٣Ys=5 hr %5T **՜tU/C,Fΰt1T@]bk-Zf]m;[ '>TOYC*g%q#dp-}kSwK-%+WrLܴ(o6%"Sz FVL?X(TazQ53' ,Ẉn  z5y<90I.8)Z]yAR艳BKh 'm/P*}p3 K &:$ćBy33ʊ6t*0")qFٌs޺vOa =FM!4EnյÛ=dQ #}Nr]VĚ*yM^p4Pч6*{Hn(:`Szzx(17 n# #{L7+ű"5BIC(P)s!5h'+H˧P VRWܝB{ nެ!N,zK&]|Ǣ׌'7+vFV'iMY[dkVh/ (S"L(za{ЦeV&1Ұ&yZU P&zHTU9)klCj\gTn"`d͓M]V-cG:D^|9<}`.f E,GBpf-<ϻl3O8@,H`O߶CPu 1C·:i )% ZݧbUY+if%^/_+!QIENDB`jamulus-3.9.1+dfsg/android/res/drawable-ldpi/0000755000175000017500000000000014340334543020074 5ustar vimervimerjamulus-3.9.1+dfsg/android/res/drawable-ldpi/icon.png0000644000175000017500000000464214340334543021540 0ustar vimervimerPNG  IHDR$$tEXtSoftwareAdobe ImageReadyqe<%iTXtXML:com.adobe.xmp .aIDATxڬXkLSg~{Bh LƉd1t[3fl.f=n~?6c]6%ySu(* pN-ʛ<;y{Ds-X: 4{*:x J 5%IPLF3\h %"Z u|^TJ9Z@ݾajK 7pJK|l1G܄@& 摫VQ]E>K{YF|_`H݋Ȥb8~(3VN'M"5n5:3 Z,iJȼ5]b|ZɣVkTfrgoR4G'*ުAS8h^.D8VO򵺊 pZUP MΧt D>֌%>_Lڠg%}:%Eaƹ:*d蛃w>5; }:WG@Y:cJT\^At2L*$ ,Z>3;㞿m'ʵ9G7)kx-͆G U)4S/NJH+]; e#h!JN^Q%Hdc5)I>.!FS9.NzTށ"U NiJQ;0lcپ8b2,_W{ڻ rM 抉rUڷ"[;k3S6} -/TNY4!sU,=%E4m)˜u݈d9e%i aR"Ud(1^E> ʼHiNj5CߵFS+H(m}\TNʑnoW-dv H ԳʘU^&nBieO/Q8ܺOJ!dL,nB̃]Ӊ hy|.»[hA#7lq(ft^u3]cdd;)5j sDj?,Ў1bW'wהBݸsЈthWKѮ!D2P]eQjЋ;Yu^VQ)PcNNHjkc=lY 㺍lWZdGuܚD1I^l-_FrEM"he^ϖ柌p-C?1?nlM\O:h퉊PgokV,lᬩ&2p&L22SBÜ>'!6{ip;h VK=ܭ`41GNOD b G/:PH y) 욐V  `Kl7X3-  |*mp2~{4bϱIENDB`jamulus-3.9.1+dfsg/android/res/drawable-xxhdpi/0000755000175000017500000000000014340334543020450 5ustar vimervimerjamulus-3.9.1+dfsg/android/res/drawable-xxhdpi/icon.png0000644000175000017500000001647214340334543022120 0ustar vimervimerPNG  IHDRFtEXtSoftwareAdobe ImageReadyqe<%iTXtXML:com.adobe.xmp ajIDATx] xU>I:d읅; iw,:s9OAǙAe|:0qQ\Tʒ@d!Kg# Ys;}|_nu9sӍ7@eXI<$DIC@ GB Dcm( (((QJPΡA)b8N "'&B2 ]4A9FBu+/i(6-nOQv"I4xj!R 9Z8Qj:r7B ˈCs(^n.6FPGK`WI ^7+ZC}

+U~t/HF@|d*33C}aHV/T5æW ɤՍ\yH2@3 [AE+< ᾲ{VP ϕAKߴe6X!@܊Q.Ka-Qrsעלb8V"Cl.@Hyy|0k_y~Im1BOh9әɓ(AsSzBhdb똊&xX!hшlIE $?蓰yNѨd?eP/{J ֞o@OgaD<99C Ow3R CAC@@Xu[u*G] /Cj 7gp'y3ts3]ѲG3g O0>gZV!xsg$A ? f9~P$Pv) Jt:ޜŵYU^5^c&VEװv##DŪfon7|rt'm5 q6@kdm{doa5*A8?}Pyem" XtR.2@H^(r*EI14+9-Ԝ$H,(sQę@ p.·Eأ|m.[Me+3`5: Ģ,Cd]r;^6-O :yWۊjFi\lI!jLnu9ۙ8#Qփ?Qn<0wDUU-Tt_q3Hj1\+j 9/j{'jwW{8';m\#6dF ߱=I*̱ejGlbC|fB08$q5oaS r3Yhk,SM\C8tŋ>S3Cm~ ԜrS|=!R!^nv <3tv˵sn׀ ϻ:m d0("٢72&Rpny߉hb0.*@lj,J=UV Y} VeoiA6|iQX K^Sj*BN%2yȒ RK#ɔ_g{hI {tQ V_7`=PmK.+񜅚2jׯCC:NAh:( l;hh6g>V(Ȍdw3ϙ/9˒8oX"tSl6Vux ƛ\eQw\gfrWB;#9Z]xr-(Ȉ˹rpuvY#BlˌF Ue#˝UYHj^|x|,zAVĞjLkawivv_H [vIhH3Dy(aH 83*9dwttuv,Pm8Ru-˵HRUfg9Gȹh>?1)"S$|;,da6 !}cpF/<'8IjچY׽ʵ]~nyojgK1_h䡨2m5b {D.?ZfK,PvpcH~KXPX%ۍ W@\c%zY3MIc촍EXΡtOQ,, ֭n*L@A!.B5cq72+׽*a"Z 'dAj]׍I@CIDw["[vs*.#to/>$k6C&bz|* .![69+x s!R)@!h $m\xC7[QPuc@%LC;̍ n8y7aVK^+ yVQY{v\5h=k^dL@t'tv߀_>7NECPܫ6K2}(1')z[ö)j:Ѷ bPW$t'=BAؚvfwc !M3%fFhQ $ͨA/V2ϙߙ*i r ڇ9+YNT mCwntn25v+z]0 iCHNx`迀F AX[rql2жx5PNp?IKFmR}Ι{.E7TgJM/4jM)J~R|rFӏtt H.`,R)aHj+^7Pozdd RŒV-46. PPT=:{AtUZGtDuB3phtaڳjp޹E &>13! Onyw͞ Ji/;Zw&[5P 6粵-Ͷv eb1Y fxI=7PI J=' VcgR"(0 T~[P_Vc)y$,ϐ[KlY0/=Br'.rwї@̔ Px_vx`JJ`?sK b=5_F`JnZ)w$?6L3v6]qȳpvr-%x|(+ijsLɫM`O=NP!$lhuw6 sl/=2RrFku;8I@_} :;)KaM 6P%~baBT|Y0'Ӿgӟ@Z<)a$^CN',Ѐ/ː^JeSl+j?Q)84 DZ0UKĦKx{]髗@F7mܟŀ?3cbͰ(Mziߗ66u>hzN>aZĆ3Wxk6֗D QKfiE2މު;>- ۨ[Np@-7ַt쉣u$7U?n0:iuA!Px,o1uU#^+y6#܌)2nE7qiJ?187]DA$J'~PO'B/J+wfhOe~Ig’QV6~9>^wP`pȔ~\T m ,zW,#}~yoB )m6A%с>;Cw#M F^G  PO@Wq10D/qn@ Ȑ6ٰÕ!G 9wgSS Bk vs.WcR<6>1s¡Ze;ۅNB t,UBF5>Z Z ao4Gd{dEu$:U *_@8nӫ5ap6+uR _[nqnۉy-~DVh}uZ#)9oqqO}ydj4^NC>`_)><;{NJG.j_=k4yi)s8p+72m%֍`UZ8LȺޞ:}[6q8e)d2T3_8c olmr"'QO8Ȕ|h *X˭c91Us;k,oA2=pNj^ L 38{xhyc* E@Zn[ʷW4+pRk.k2$}gZI (+[>il7 oZY+BM3lxl'UWrud#@O^E)>0" = \rj*zZ;t-T*G)^3(bf0ӓ%W‘:KLHPF9C,zRsX7>SktqIeYL+,0u@d_cC^29 K| ʟ}łK R(a-%\rEͣ5i(5Io+0 ]ԵZmnv#sz>j+jPdl-M`/gQu4@J vY,ӶNjMld 2^5Hp_\ ]-% Roj.g6 $حPqdz¤P%*}{ . vmit' G qL5[JkuU2"xo'uJ^g$a.Ih4eAFh3xQ48/- Xx) 9=t IDATx] pe~I&$rrr <`QRt=W]aUW]]-RjWP<< H@$ r'dr$L.NJLyU:};]v -s* S' ߑ<"5- !biZ54@{%YȡC|d'|Ch'1{-Ȼw"<(L9%|mN]W9}T 7%?֦t^ ~M8*T<͐a P-kD'+U|^ļL.U ?rWl (\g'KGd6 '`EZäI b6ihvQ>ޫ>^ nF8}|h@7J)VMNJU2xhن佞D=h݌F (>*V4m/%~&cD( z"Z{RA# Hn8K?\70EVacAaBfOJaj{zD&r^HMG&(|{*ɸ.B^c;kZtlѡ`NTG$-Y}X]JcMCO@ s wB&DIm7E3ScM!J/S /DOlM c23 }y?^J' C􉔓̏-50&a̬Q%FO lPz.pc?LP@R{W 3 (x2v 9$x?r7\% a0)b3V%*-knѡ`O4)@:Kf)95r=)I})~%d.iړv;EFlbw zˌ>{J3W qVq4n8P3:Ȩר퀜8EVAVONr[]]`7oxCdF$X*1arJTL Ʒ&8XZop]+c4:JYOcwL^4D6(0by7#8 eI^% +2(?(?-㐴"l9S~\ FY10-:|$A(~ʚ@'{AT#Q` "^g|ʇ*#h;Z.[}g4_5޾DaBV7b ukʤC*ڙ?zXd?  ]OK󪛙K.pLԉ.vXo*(mVa1alDuKι@Ctմr^ vW+Y`T:宎} U?rLQEPb8PP#:T̛pcёb+wE:)?#H `ܤꆷW_nDwBa 7a{kYvo&;^'3ӥpb0VP3RZKZhd&vwFZ%&]\X(cYr vc`y#|d: C \.qJWn||BlRh V 3\GsUb\A!%6>+o {r+gR%BDI0U:f6buD#?{6s"4p>lI!ZL6i5ّ[!VDY6_`vdf Te D޿ss&>|F=-sSRBs~C">m q,KR,D&AP({Fk9DmO[gy)޻. .\{`'*}Shy,5^J1y)Ds /e&skD'8n?-)ipdνF`n/ l2D tJXgcRkP>"] >l(Y~ԇʒu u`O qPUU89LO^NNJA9ypLH?MeR>VC̯&gEsSmdα$ vMDD#iKс(%ª>8 dvT {Qim]KY#luij7!|Zn ̸`h*"j] g\U Ew.a`0ՍA500%D j!Uޑ#}5͔6 pQ#B4AC!00Z:4 QRn( $ҪKZCmJ,f'X]Q&ywAc n9AH"v(ȇD ;&XoȿX1CkC?>gQd*#υ ,!|r>QI<Mc4{'*}TZh χfIAjd- |RB'cbEyK\%h%|I. ٞ1n%9C+F.iP{}]<}ᔧ! ) ] {5`G_T.j4L~]O0$*J6mfnU-p^ene$}6f>@܅Q$#d*@v J ITTFh9v^57dP%z5} Xֆ3y;Ell܄mv\ ǚV?mj^Dv߼*?%O!ۙX%cX00f|LTU!l;WE^v"|jK:GJhQr(*r92]7CoɍO#6`5_̻|6|~X$> 8mYP;bM@Rik\^qث =u /@K#[g ^xy{_5@DA5FQJE^l) "Oo^LxSжWTPr0 }H 0bh.IENDB`jamulus-3.9.1+dfsg/android/res/drawable-xxxhdpi/0000755000175000017500000000000014340334543020640 5ustar vimervimerjamulus-3.9.1+dfsg/android/res/drawable-xxxhdpi/icon.png0000644000175000017500000002305114340334543022277 0ustar vimervimerPNG  IHDRRltEXtSoftwareAdobe ImageReadyqe<%iTXtXML:com.adobe.xmp m"IDATx]tUUC$@BD"cA3ʯ.یXFqFǂC&U B*'e1/9}|ku]-;g}vphWm8bXd0b6&N:IPJQP Q΢n\cF@3 Y(i(()( drei$A%>E-FvM("JVPn@o(g$H|AcPVЀIP>A2  qxGR|_ z4RP^C"{O KH݂B/*VPD"d X+U؂( +EY (=zQFy P'`^E R@39#x:;s'{^hꅶh膺.j6JzACr?Lox?qh7v_7Gٮe硬rj[ǺS;V$d;Mw`/H _W]G 8CdW6ъ&[} N7l 0rŧx.5)-#Aj79٩y{ pvT6Ad$B 6<<@9bD:h.~ZGPT)r]B*()0^~cJG[QAٝfl%i[(w" %N}#t헎 @wy7rQ$ȍ)C(:\`yJ8${Zʯi'hCH/^ ̫kzchAşgA@ҬCEQrٷҺ]<Qs>Ivij8:Y;//jDI$r19;-aEnu+v`$kQIA͞/Q.7Ea>pKzUg^X|S0`\ { <8.2ċ4̼4n#Wʱ0 ^1FCyy(`&g'ޗX)Aӌp5sGCx uսdOcN FYit;8Ц3^)郵{E^>cA+?%B9o~77-lmmK4xslTcc~R~*Oׄ}Hu Q]1Q1_W{m6~5z1o:#;F __y o93\aʅ3@Vy(,'R|A?(=<( o WL5 A\ɯ]p|`b,L WGFEumȮX󋭖Rտb==R̳̚{iaߊ&c1)Tr%5(`/EEJZF~~4wX|]a\[3TlY0P#`g^U|[ӣ PS3((MwKlgT,yU\<{I?2Yp_HR)jK [>v :,=s8dž(>=+uU|E'.4o,^6DU `׏̊F@cz yx&L*ƣpw%O*˝){]P2 5鰷k͗>W"f)ԒW\edžX_h_H˯)(e UHG9 6f>WXe,=-ptSQeh4၂n1 R¼6o`襼֛vpQ 0ݚ$*=Ff9hSeI7Pot3,k;s#GpW AIfJ};7.T}Lm)zGqtLY9; Fݒ HWF rY~@تLP^#gd)4"EcB+ ܔ+BH9UͰÅO£SbUWOEyDO7A4 8/OEcBβ~R %Դv¾:|vȰxbo.6gRݡx,%'rcANwL֜G9P'ƚ0'Mc% }Q D3bXw;ϝJY%OcΧbOÌ8ˎscX~hʭjL4ö3bYܝF{Fi>pڕ:_Dn d_"c 8IAOADc(K<^&A_kqV޷ GB& |F\,Ze}]QOI8a -rIsHz4GYGe^ޤ#]dPr}&yqa-‹)hoq/&͉#&dO^? wrvDžEsLJC0fp*<{^#<9kU;W0:M@Yzd?姴π3ye.RVgBΪYA6i2h j`*h3Cye}מNjgofP3ʍhtwr"sj@d#} G x%F~+U~2SAeťJ9^is%)~NjM)~s(k~{Tw;{9Cam΋m)JwSŁټT~9'A6?6q?jI3cnvXc;9M $]Vi$?S)O4I!i`gO<7q?F#,i~v0KiGi#!O^ӎ̛<7qs|EZw _kg/l)7=np_&w1TE3MK\ñTyKSڱ͋>󴡝&Υ5PqyZ18s̈{eiǰџ#2wTdZeJu)h3TTzjf_zli{ReF4/>v T4}O8&89 fBSS=b]{?5^zےEղ TȖ.yțUVs;]џ\Բ/Vc7VȃqP8;gM2q{L\ЎF{Nw{{rWX6&T E\t^H_ ~~XD}[f{i#3N*l 'ӐNƋ1%{ k!^vЮRU^7_yf牍Kӻ{[Xp-,1 _4%J6_G'J7C8Z8[WFvC_j.mUf[Gh:୮0./ 7VrQKRfW4\lݓMlv*SK&؁rU,IvMK'|QgilEt9U`)l`"@}PҎ,B_][`R]`Mo%ǂ`?,g' TRUpϦthEP& A့ȯiɹ֑=DcՇAg=m=}o: / x[`!{x~?[ %^!EhB.^8Za`x3Ͱ9,A+қa-xYq[F <|!D2\H]v^H1e Rj\H=* 1HYFYTbTⓋS2uW^P}ͅ)03>@3k6r><#. 5T<&$+KWUIcf wMd;WNk"j>=$I PʿU%g&)^,Y whXhˀ+Do8؛2|#`#ܾ9,\jQKEQF0zgi,FFh]TTS qԤxdV"xXf5)d"d}$p)gP(eLrh!0Y׫7&'CZn 4hXwHə=]`psz8ZOz" ],Y`p79-jjPMS"y!:_;..sT >UU[`x:\ o3wTbj=Sbu QnY(-#1 Z{ _U Hx8tͲƁ+@,9nGΉ/$.W/KP/2 K9% vC3a7Fu[vv (dk*̈|Yuck z="-'7IJ7Fg78K^3t\7!걡8(F70yc]=A.k~Ӡ@3Nh v9"uMLpoJE3(gPs2shqZ&(A f7H,Y"xN@vGTzmh f$ug*gE2psf,Y(fwUmlUr}wBg6!a#Ajxe)o<+ִ$5\5Y}q 7fP/'{]}_SEM(?L1 0T4ʴ(H _QB][d|SZRk"ɒb0 Z>ԍw{r5][`'P] mN6i>v%LWA(MApYR0ZQ_KGl9S TC'CQ'&h_>=V&8kd )r*@}kN|Q zH `C s;Hx\ao Kb`nB :ZG){\ӈ?{YirR jb%8!ws>$-Xx\\d)^T㥍u5P֔70z/$:R Y4Ђx^%gBJ'xb?:j(MARbc `,y|`$N_$붨MKdm+oh{1V7Ѕ&u/ۜ  \ N ~nN⠋a/zvoQ<6ݺ^Ve-硴;t!F>pD7].BKyEllVW]|otӑY#7T@K,~=`g X2BA@uتe+CQ=pd+7.MRnn*W×'-lX#j6P7uo9xE%(~(ӹP4MZuS'>ȭZB"=kr +P7*Ny#<4Զi3|w7.!Z(<4 ,TN O`G k`(0y'B"MGIʼn2L|/ @ k Up hm 6*N'MJ~Dx* dpGq'rG;f[g_wB]g7TtWs#D?$HNHHVi L\rQ@`wQ%D QD$.-oLALFiVPo r,uGi68/ANjl3 />F'PPB߬3٠zw8&_{LԱNJ@]۟|~]xHGYrJ?^*`03h\U@"[$ze|j8 t֜GSimbK*܎ +y~@!@J?C?)AnG%F0ʻ(ixd\'LxO(\K"8'Pa~gLe>E|Z!mQ: 3b}>/K2>xMAPɸt|UPD9\a$PLg%J<-bɛuKgt(ӄ0ˏ-G"B"J$Q(~fG!WZ J 5塜Dަ3aJܮo VAFYVɋ$uT=a3V<'hx)H+Q=V̰(Vl0F,ԺK6^@rH@ :Y X> h~ci`MtVWX[xփ6vYA^ߣnW@H ,{-q(Ρ so7κ {<[^ {P2 1D+@e[7rko A%%\r7<`B*Cu;kc>[:MTyw& `N2,}x\i7˝) `*B>B*{Q5EHĠǀSkSBfLdd>l*JbmtIENDB`jamulus-3.9.1+dfsg/android/res/drawable-mdpi/0000755000175000017500000000000014340334543020075 5ustar vimervimerjamulus-3.9.1+dfsg/android/res/drawable-mdpi/icon.png0000644000175000017500000000571714340334543021545 0ustar vimervimerPNG  IHDR00WtEXtSoftwareAdobe ImageReadyqe<%iTXtXML:com.adobe.xmp 1@IDATxZyPTu. ,\ y!2]t19fSTLMMav955tڥyDf)Y !ewŷ=޾~~(FFF(tGׁ灳00 > \흳;"X @ kSx)U(r+Up|P1:5*ӝO5]}4< \" @D Ҵ8dh\{~jwQ6: |8T |>//4'h5"?fFB\g:.G^Op$( @\ ?iIb$=0;B5Jdhw79ֽJ謕.ϜHOOYV5uuovzGsRK—Xx$=;7Զ[ ,1 `xt{icģyI-_/}JII'Od 5[ e|xe n9!J;#;Do_#=+OPS `w5 יZ7|R?|f {B]^!xDt5gMo f8RaQzTpjt\VՎF%L+ԝ2:ω CœnZy45 {~s=7K l &S/];9g9BK0|\un#{k~T i)e:v'}?4/j@f[ݾ8@i1ai֏,V#F\Hi&:z֩<&T #`S>( T TD'Nٹ45'hZE: p9HyH qX kҫt$9l0$SƆ,KC,Vzo9|mPÆ>+x*:To&9U(9~SEV l%Өg3}}y)2l3]p\U/#nSkep|P)T'_ֶАu$;0*$#ŹlIB-̠ T38.=aDKP*_7#_%ԻVOX{ {awor%Ʒ' WPFlXbTW8kwWSPGJlwL_%8 3ލxFuy zpSضZ4 jegD nWԷu}[1Moi#jz-CT;wlx1Ad;PeȚCQ$bë#)3޸u*O<^u(X8'i" "C:\Qt\"`. 1. You can now find the Jamulus installer in the `.\deploy` directory. ### Compiling only 1. Create a folder under `\libs` called ASIOSDK2 1. Download the [ASIOSDK](https://www.steinberg.net/asiosdk), open the top level folder in the .zip file and copy the contents into `[\path\to\jamulus\source]\libs\ASIOSDK2` if not already done, open the top level folder in the .zip file and copy the contents into `[\path\to\jamulus\source]\libs\ASIOSDK2` so that, e.g., the folder `[\path\to\jamulus\source]\libs\ASIOSDK2\common` exists 1. Open Jamulus.pro in Qt Creator, configure the project with a default kit, then compile & run If you want to work with Visual Studio, run `qmake -tp vc Jamulus.pro` to generate the `vcxproj` file which enables you to test, debug and build Jamulus via Visual Studio. --- ## macOS ### Install dependencies You will need Xcode and Qt. First, install [Xcode from the Mac AppStore](https://apps.apple.com/us/app/xcode/id497799835?mt=12). Then [install homebrew](https://brew.sh/). After that you can install Qt via homebrew: ```shell brew install Qt@5 brew link Qt@5 --force ``` ### Generate Xcode Project file `qmake -spec macx-xcode Jamulus.pro` ### Print build targets and configuration in console `xcodebuild -list -project Jamulus.xcodeproj` will prompt ```shell Targets: Jamulus Qt Preprocess Build Configurations: Debug Release ``` If no build configuration is specified and `-scheme` is not passed then "Release" is used. ```shell Schemes: Jamulus ``` ### Build the project `xcodebuild build` Will build the file and make it available in `./Release/Jamulus.app` If you want to build the installer, please run the `deploy_mac.sh` script: `./mac/deploy_mac.sh`. You'll find the installer in the deploy/ folder. --- ## iOS 1. Install [Xcode from the Mac AppStore](https://apps.apple.com/us/app/xcode/id497799835?mt=12) 2. [Download and install Qt5 with the Qt Installer](https://www.qt.io/download) (not homebrew). Explicitly select iOS when choosing the Qt version 3. Go to the folder of the Jamulus source code via terminal and run `/path/to/qt/5.15.2/ios/bin/qmake -spec macx-xcode Jamulus.pro` to generate an .xcodeproject file 4. Open the generated .xcodeproject in Xcode 5. Go to the Signing & Capabilities tab and fix signing errors by setting a team. Xcode will tell you what you need to change. **Note:** - If have a free Apple Developer Account, you can use it as a "Personal Team": - Set it up under Xcode Menu->Preferences->Accounts. - Then choose a Bundle Identifier at your choice in the relevant field in the "General" Tab (in section "Identity") - Now click on the "Signing & Capabilities" tab. In the section "Signing", the "Automatically manage signing" option should be selected. - You should now see Team: (Your Name) (Personal Team), Bundle identifier: (the same you modified on General Tab), Provisioning Profile: Xcode Management Profile, Signing Certificate: Apple Development (your e-mail used for signing in to Apple) below 6. Connect your device via USB (or WiFi if you set it up for that) 7. Select your device next to the play button 8. Compile and run Jamulus by clicking on the play button 9. Before being able to start Jamulus on your device, you'll have trust your developer profile in the device's Settings under General>Profiles & Device Management. For more information [see the guide by osxdaily](https://osxdaily.com/2021/05/07/how-to-trust-an-app-on-iphone-ipad-to-fix-untrusted-developer-message/) 10. After a week you might need to restart from step 6 to continue to run Jamulus on iOS, unless you are paying for the Apple developer programme. --- ## Android - Install Qt, including the Android support from the Qt installer - Follow Qt's [Getting Started with Qt for Android](https://doc.qt.io/qt-5/android-getting-started.html) instructions - Make sure Jamulus submodules are present, notably oboe: `git submodule update --init` - Open Jamulus.pro in Qt Creator - Now you should be able to Build & Run for Android. ## Compile time arguments During compile time some CONFIG arguments can be given to enable or disable specific features. Just run `qmake "CONFIG+="`. The following table shows available compile time options: | Option | Description | | ----------------------- | ----------------------------------------------------------------------- | | `serveronly` | Only support running as Server | | `headless` | Disable GUI. Supports Client and Server. Usually used with serveronly | | `nojsonrpc` | Disable JSON-RPC support | | `jackonwindows` | Use JACK instead of ASIO on Windows | | `jackonmac` | Use JACK instead of CoreAudio on macOS (untested) | | `server_bundle` | macOS only: Create an application bundle which starts server by default | | `opus_shared_lib` | Use external OPUS library | | `disable_version_check` | Skip checks for version updates | | `noupcasename` | Compile Jamulus binary as lower case "jamulus" instead of "Jamulus" | | `raspijamulus` | Use raspijamulus.sh specific enhancements for build on Raspberry Pi | jamulus-3.9.1+dfsg/libs/0000755000175000017500000000000014341067650014110 5ustar vimervimerjamulus-3.9.1+dfsg/libs/opus/0000755000175000017500000000000014340334543015073 5ustar vimervimerjamulus-3.9.1+dfsg/libs/opus/m4/0000755000175000017500000000000014340334543015413 5ustar vimervimerjamulus-3.9.1+dfsg/libs/opus/m4/ltsugar.m40000644000175000017500000001044014340334543017335 0ustar vimervimer# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software # Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59, which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) jamulus-3.9.1+dfsg/libs/opus/m4/as-gcc-inline-assembly.m40000644000175000017500000000535714340334543022115 0ustar vimervimerdnl as-gcc-inline-assembly.m4 0.1.0 dnl autostars m4 macro for detection of gcc inline assembly dnl David Schleef dnl AS_COMPILER_FLAG(ACTION-IF-ACCEPTED, [ACTION-IF-NOT-ACCEPTED]) dnl Tries to compile with the given CFLAGS. dnl Runs ACTION-IF-ACCEPTED if the compiler can compile with the flags, dnl and ACTION-IF-NOT-ACCEPTED otherwise. AC_DEFUN([AS_GCC_INLINE_ASSEMBLY], [ AC_MSG_CHECKING([if compiler supports gcc-style inline assembly]) AC_TRY_COMPILE([], [ #ifdef __GNUC_MINOR__ #if (__GNUC__ * 1000 + __GNUC_MINOR__) < 3004 #error GCC before 3.4 has critical bugs compiling inline assembly #endif #endif __asm__ (""::) ], [flag_ok=yes], [flag_ok=no]) if test "X$flag_ok" = Xyes ; then $1 true else $2 true fi AC_MSG_RESULT([$flag_ok]) ]) AC_DEFUN([AS_ASM_ARM_NEON], [ AC_MSG_CHECKING([if assembler supports NEON instructions on ARM]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[__asm__("vorr d0,d0,d0")])], [AC_MSG_RESULT([yes]) $1], [AC_MSG_RESULT([no]) $2]) ]) AC_DEFUN([AS_ASM_ARM_NEON_FORCE], [ AC_MSG_CHECKING([if assembler supports NEON instructions on ARM]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[__asm__(".arch armv7-a\n.fpu neon\n.object_arch armv4t\nvorr d0,d0,d0")])], [AC_MSG_RESULT([yes]) $1], [AC_MSG_RESULT([no]) $2]) ]) AC_DEFUN([AS_ASM_ARM_MEDIA], [ AC_MSG_CHECKING([if assembler supports ARMv6 media instructions on ARM]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[__asm__("shadd8 r3,r3,r3")])], [AC_MSG_RESULT([yes]) $1], [AC_MSG_RESULT([no]) $2]) ]) AC_DEFUN([AS_ASM_ARM_MEDIA_FORCE], [ AC_MSG_CHECKING([if assembler supports ARMv6 media instructions on ARM]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[__asm__(".arch armv6\n.object_arch armv4t\nshadd8 r3,r3,r3")])], [AC_MSG_RESULT([yes]) $1], [AC_MSG_RESULT([no]) $2]) ]) AC_DEFUN([AS_ASM_ARM_EDSP], [ AC_MSG_CHECKING([if assembler supports EDSP instructions on ARM]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[__asm__("qadd r3,r3,r3")])], [AC_MSG_RESULT([yes]) $1], [AC_MSG_RESULT([no]) $2]) ]) AC_DEFUN([AS_ASM_ARM_EDSP_FORCE], [ AC_MSG_CHECKING([if assembler supports EDSP instructions on ARM]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[__asm__(".arch armv5te\n.object_arch armv4t\nqadd r3,r3,r3")])], [AC_MSG_RESULT([yes]) $1], [AC_MSG_RESULT([no]) $2]) ]) jamulus-3.9.1+dfsg/libs/opus/m4/opus-intrinsics.m40000644000175000017500000000154614340334543021034 0ustar vimervimerdnl opus-intrinsics.m4 dnl macro for testing for support for compiler intrinsics, either by default or with a compiler flag dnl OPUS_CHECK_INTRINSICS(NAME-OF-INTRINSICS, COMPILER-FLAG-FOR-INTRINSICS, VAR-IF-PRESENT, VAR-IF-DEFAULT, TEST-PROGRAM-HEADER, TEST-PROGRAM-BODY) AC_DEFUN([OPUS_CHECK_INTRINSICS], [ AC_MSG_CHECKING([if compiler supports $1 intrinsics]) AC_LINK_IFELSE( [AC_LANG_PROGRAM($5, $6)], [ $3=1 $4=1 AC_MSG_RESULT([yes]) ],[ $4=0 AC_MSG_RESULT([no]) AC_MSG_CHECKING([if compiler supports $1 intrinsics with $2]) save_CFLAGS="$CFLAGS"; CFLAGS="$CFLAGS $2" AC_LINK_IFELSE([AC_LANG_PROGRAM($5, $6)], [ AC_MSG_RESULT([yes]) $3=1 ],[ AC_MSG_RESULT([no]) $3=0 ]) CFLAGS="$save_CFLAGS" ]) ]) jamulus-3.9.1+dfsg/libs/opus/m4/libtool.m40000644000175000017500000112530614340334543017331 0ustar vimervimer# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. m4_define([_LT_COPYING], [dnl # Copyright (C) 2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program or library that is built # using GNU Libtool, you may include this file under the same # distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . ]) # serial 58 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl _LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_PREPARE_CC_BASENAME # ----------------------- m4_defun([_LT_PREPARE_CC_BASENAME], [ # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in @S|@*""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } ])# _LT_PREPARE_CC_BASENAME # _LT_CC_BASENAME(CC) # ------------------- # It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME, # but that macro is also expanded into generated libtool script, which # arranges for $SED and $ECHO to be set by different means. m4_defun([_LT_CC_BASENAME], [m4_require([_LT_PREPARE_CC_BASENAME])dnl AC_REQUIRE([_LT_DECL_SED])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl func_cc_basename $1 cc_basename=$func_cc_basename_result ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl _LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_WITH_SYSROOT])dnl m4_require([_LT_CMD_TRUNCATE])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a '.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld old_CC=$CC old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PREPARE_SED_QUOTE_VARS # -------------------------- # Define a few sed substitution that help us do robust quoting. m4_defun([_LT_PREPARE_SED_QUOTE_VARS], [# Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([["`\\]]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ]) # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from 'configure', and 'config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # 'config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain=$ac_aux_dir/ltmain.sh ])# _LT_PROG_LTMAIN ## ------------------------------------- ## ## Accumulate code for creating libtool. ## ## ------------------------------------- ## # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the 'libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) ## ------------------------ ## ## FIXME: Eliminate VARNAME ## ## ------------------------ ## # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to 'config.status' so that its # declaration there will have the same value as in 'configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags='_LT_TAGS'dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the 'libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into 'config.status', and then the shell code to quote escape them in # for loops in 'config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' _LT_CONFIG_STATUS_DECLARATIONS LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$[]1 _LTECHO_EOF' } # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done _LT_OUTPUT_LIBTOOL_INIT ]) # _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) # ------------------------------------ # Generate a child script FILE with all initialization necessary to # reuse the environment learned by the parent script, and make the # file executable. If COMMENT is supplied, it is inserted after the # '#!' sequence but before initialization text begins. After this # macro, additional text can be appended to FILE to form the body of # the child script. The macro ends with non-zero status if the # file could not be fully written (such as if the disk is full). m4_ifdef([AS_INIT_GENERATED], [m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], [m4_defun([_LT_GENERATED_FILE_INIT], [m4_require([AS_PREPARE])]dnl [m4_pushdef([AS_MESSAGE_LOG_FD])]dnl [lt_write_fail=0 cat >$1 <<_ASEOF || lt_write_fail=1 #! $SHELL # Generated by $as_me. $2 SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$1 <<\_ASEOF || lt_write_fail=1 AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 _ASEOF test 0 = "$lt_write_fail" && chmod +x $1[]dnl m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), incase it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) _LT_GENERATED_FILE_INIT(["$CONFIG_LT"], [# Run this file to recreate a libtool stub with the current configuration.]) cat >>"$CONFIG_LT" <<\_LTEOF lt_cl_silent=false exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ '$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files Report bugs to ." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2011 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." while test 0 != $[#] do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try '$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try '$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. lt_cl_success=: test yes = "$silent" && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. # Written by Gordon Matzigkeit, 1996 _LT_COPYING _LT_LIBTOOL_TAGS # Configured defaults for sys_lib_dlsearch_path munging. : \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF cat <<'_LT_EOF' >> "$cfgfile" # ### BEGIN FUNCTIONS SHARED WITH CONFIGURE _LT_PREPARE_MUNGE_PATH_LIST _LT_PREPARE_CC_BASENAME # ### END FUNCTIONS SHARED WITH CONFIGURE _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac _LT_PROG_LTMAIN # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], [cat <<_LT_EOF >> "$ofile" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Go], [_LT_LANG(GO)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG m4_ifndef([AC_PROG_GO], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_GO. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_GO], [AC_LANG_PUSH(Go)dnl AC_ARG_VAR([GOC], [Go compiler command])dnl AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl _AC_ARG_VAR_LDFLAGS()dnl AC_CHECK_TOOL(GOC, gccgo) if test -z "$GOC"; then if test -n "$ac_tool_prefix"; then AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) fi fi if test -z "$GOC"; then AC_CHECK_PROG(GOC, gccgo, gccgo, false) fi ])#m4_defun ])#m4_ifndef # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([AC_PROG_GO], [LT_LANG(GO)], [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) dnl AC_DEFUN([AC_LIBTOOL_RC], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS=$save_LDFLAGS ]) AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], [lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM ]) case $host_os in rhapsody* | darwin1.[[012]]) _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; 10.[[012]][[,.]]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES([TAG]) # --------------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported if test yes = "$lt_cv_ld_force_load"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" m4_if([$1], [CXX], [ if test yes != "$lt_cv_apple_cc_single_mod"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi ],[]) else _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX([TAGNAME]) # ---------------------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. # Store the results from the different compilers for each TAGNAME. # Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ lt_aix_libpath_sed='[ /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }]' _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib fi ]) aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [m4_divert_text([M4SH-INIT], [$1 ])])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Find how we can fake an echo command that does not interpret backslash. # In particular, with Autoconf 2.60 or later we add some code to the start # of the generated configure script that will find a shell with a builtin # printf (that we can use as an echo command). m4_defun([_LT_PROG_ECHO_BACKSLASH], [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO AC_MSG_CHECKING([how to print strings]) # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $[]1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } case $ECHO in printf*) AC_MSG_RESULT([printf]) ;; print*) AC_MSG_RESULT([print -r]) ;; *) AC_MSG_RESULT([cat]) ;; esac m4_ifdef([_AS_DETECT_SUGGESTED], [_AS_DETECT_SUGGESTED([ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test "X`printf %s $ECHO`" = "X$ECHO" \ || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], [AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], [Search for dependent libraries within DIR (or the compiler's sysroot if not specified).])], [], [with_sysroot=no]) dnl lt_sysroot will always be passed unquoted. We quote it here dnl in case the user passed a directory name. lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) AC_MSG_RESULT([$with_sysroot]) AC_MSG_ERROR([The sysroot must be an absolute path.]) ;; esac AC_MSG_RESULT([${lt_sysroot:-no}]) _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl [dependent libraries, and where our libraries should be installed.])]) # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out what ABI is being produced by ac_compile, and set mode # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; *ELF-64*) HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test yes = "$lt_cv_prog_gnu_ld"; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; mips64*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then emul=elf case `/usr/bin/file conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; *64-bit*) emul="${emul}64" ;; esac case `/usr/bin/file conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; *LSB*) emul="${emul}ltsmip" ;; esac case `/usr/bin/file conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; esac LD="${LD-ld} -m $emul" fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when # doing 32-bit compilation for a host where ld defaults to 64-bit, or # vice versa); the common cases where no linker options are needed do # not appear in the list. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `/usr/bin/file conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*linux*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD=${LD-ld}_sol2 fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks=$enable_libtool_lock ])# _LT_ENABLE_LOCK # _LT_PROG_AR # ----------- m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} : ${AR_FLAGS=cru} _LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [lt_cv_ar_at_file=no AC_COMPILE_IFELSE([AC_LANG_PROGRAM], [echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([lt_ar_try]) if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a AC_TRY_EVAL([lt_ar_try]) if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a ]) ]) if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi _LT_DECL([], [archiver_list_spec], [1], [How to feed a file listing to the archiver]) ])# _LT_PROG_AR # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [_LT_PROG_AR AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_CHECK_TOOL(RANLIB, ranlib, :) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) _LT_DECL([], [lock_old_archive_extraction], [0], [Whether to use a lock for old archive extraction]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi $RM conftest* ]) if test yes = "[$]$2"; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS ]) if test yes = "[$]$2"; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 teststring=ABCD case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac ]) if test -n "$lt_cv_sys_max_cmd_len"; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test yes = "$cross_compiling"; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF [#line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[ lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; tpf*) # Don't try to run any link tests for TPF. We know it's impossible # because TPF is a cross-compiler, and we know how we open DSOs. lt_cv_dlopen=dlopen lt_cv_dlopen_libs= lt_cv_dlopen_self=no ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen=shl_load], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen=dlopen], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld]) ]) ]) ]) ]) ]) ;; esac if test no = "$lt_cv_dlopen"; then enable_dlopen=no else enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS=$CPPFLAGS test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS=$save_CPPFLAGS LDFLAGS=$save_LDFLAGS LIBS=$save_LIBS ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links=nottested if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test no = "$hard_links"; then AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/", [Define to the sub-directory where libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then # We can hardcode non-existent directories. if test no != "$_LT_TAGVAR(hardcode_direct, $1)" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" && test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test relink = "$_LT_TAGVAR(hardcode_action, $1)" || test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP"; then striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_PREPARE_MUNGE_PATH_LIST # --------------------------- # Make sure func_munge_path_list() is defined correctly. m4_defun([_LT_PREPARE_MUNGE_PATH_LIST], [[# func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x@S|@2 in x) ;; *:) eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\" ;; x:*) eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\" ;; *::*) eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\" ;; *) eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\" ;; esac } ]])# _LT_PREPARE_PATH_LIST # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test yes = "$GCC"; then case $host_os in darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` # ...but if some path component already ends with the multilib dir we assume # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= ;; esac for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" elif test -n "$lt_multi_os_dir"; then test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS = " "; FS = "/|\n";} { lt_foo = ""; lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[[lt_foo]]++; } if (lt_freq[[lt_foo]] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi]) library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown AC_ARG_VAR([LT_SYS_LIBRARY_PATH], [User-defined run-time library search path.]) case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[[4-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a[(]lib.so.V[)]' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[[23]].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[[3-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], [lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [lt_cv_shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir ]) shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Add ABI-specific directories to the system library path. sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[List of archive names. First name is the real one, the rest are links. The last name is the one that the linker finds with -lNAME]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [install_override_mode], [1], [Permission mode override for installation of shared libraries]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2], [Detected run-time system search path for libraries]) _LT_DECL([], [configure_time_lt_sys_library_path], [2], [Explicit LT_SYS_LIBRARY_PATH set during ./configure time]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program that can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$1"; then lt_cv_path_MAGIC_CMD=$ac_dir/"$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac]) MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program that can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PROG_ECHO_BACKSLASH])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test no = "$withval" || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 conftest.i cat conftest.i conftest.i >conftest2.i : ${lt_DD:=$DD} AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd], [if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: fi]) rm -f conftest.i conftest2.i conftest.out]) ])# _LT_PATH_DD # _LT_CMD_TRUNCATE # ---------------- # find command to truncate a binary pipe m4_defun([_LT_CMD_TRUNCATE], [m4_require([_LT_PATH_DD]) AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin], [printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i lt_cv_truncate_bin= if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" fi rm -f conftest.i conftest2.i conftest.out test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"]) _LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1], [Command to truncate a binary pipe]) ])# _LT_CMD_TRUNCATE # _LT_CHECK_MAGIC_METHOD # ---------------------- # how to check for library dependencies # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_MAGIC_METHOD], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) AC_CACHE_CHECK([how to recognize dependent libraries], lt_cv_deplibs_check_method, [lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # that responds to the $file_magic_cmd with a given extended regex. # If you have 'file' or equivalent on your system and you're not sure # whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[[4-9]]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[[45]]*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[[3-9]]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd* | bitrig*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; os2*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method = "file_magic"]) _LT_DECL([], [file_magic_glob], [1], [How to find potential files when deplibs_check_method = "file_magic"]) _LT_DECL([], [want_nocaseglob], [1], [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM=$NM else lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. tmp_nm=$ac_dir/$lt_tmp_nm if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi]) if test no != "$lt_cv_path_NM"; then NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: ;; esac fi AC_SUBST([DUMPBIN]) if test : != "$DUMPBIN"; then NM=$DUMPBIN fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # _LT_CHECK_SHAREDLIB_FROM_LINKLIB # -------------------------------- # how to determine the name of the shared library # associated with a specific link library. # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) m4_require([_LT_DECL_DLLTOOL]) AC_CACHE_CHECK([how to associate runtime and link libraries], lt_cv_sharedlib_from_linklib_cmd, [lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac ]) sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO _LT_DECL([], [sharedlib_from_linklib_cmd], [1], [Command to associate shared and link libraries]) ])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB # _LT_PATH_MANIFEST_TOOL # ---------------------- # locate the manifest tool m4_defun([_LT_PATH_MANIFEST_TOOL], [AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], [lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&AS_MESSAGE_LOG_FD if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest*]) if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL # _LT_DLL_DEF_P([FILE]) # --------------------- # True iff FILE is a Windows DLL '.def' file. # Keep in sync with func_dll_def_p in the libtool script AC_DEFUN([_LT_DLL_DEF_P], [dnl test DEF = "`$SED -n dnl -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl -e q dnl Only consider the first "real" line $1`" dnl ])# _LT_DLL_DEF_P # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw) AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM=-lm) ;; esac AC_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test yes = "$GCC"; then case $cc_basename in nvcc*) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; *) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; esac _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) if test ia64 = "$host_cpu"; then symcode='[[ABCDEGRST]]' fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BDRT]]' ;; sco3.2v5*) symcode='[[DT]]' ;; sysv4.2uw2*) symcode='[[DT]]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[[ABDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" lt_c_name_lib_hook="\ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" else # Disable hooks by default. lt_cv_sys_global_symbol_to_import= lt_cdecl_hook= lt_c_name_hook= lt_c_name_lib_hook= fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ " /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ " /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ " {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ " s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT@&t@_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT@&t@_DLSYM_CONST #else # define LT@&t@_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT@&t@_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then nm_file_list_spec='@' fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1], [Transform the output of nm into a list of symbols to manually relocate]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) _LT_DECL([nm_interface], [lt_cv_nm_interface], [1], [The name lister interface]) _LT_DECL([], [nm_file_list_spec], [1], [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' if test ia64 != "$host_cpu"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64, which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL 8.0, 9.0 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd*) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test yes = "$GCC"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' case $cc_basename in nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; hpux9* | hpux10* | hpux11*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64, which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; tcc*) # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; *Sun\ F* | *Sun*Fortran*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; *Intel*\ [[CF]]*Compiler*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; *Portland\ Group*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_CACHE_CHECK([for $compiler option to produce PIC], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] ;; esac ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ' (' and ')$', so one must not match beginning or # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', # as well as any symbol that contains 'd'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd* | bitrig*) with_gnu_ld=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test ia64 != "$host_cpu"; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; nagfor*) # NAGFOR 5.3 tmp_sharedflag='-Wl,-shared' ;; xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # traditional, no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no ;; esac if test yes = "$GCC"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag="$shared_flag "'$wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; hpux10*) if test yes,no = "$GCC,$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) m4_if($1, [], [ # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) _LT_LINKER_OPTION([if $CC understands -b], _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ;; esac fi if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], [lt_cv_irix_exported_symbol], [save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" AC_LINK_IFELSE( [AC_LANG_SOURCE( [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], [C++], [[int foo (void) { return 0; }]], [Fortran 77], [[ subroutine foo end]], [Fortran], [[ subroutine foo end]])])], [lt_cv_irix_exported_symbol=yes], [lt_cv_irix_exported_symbol=no]) LDFLAGS=$save_LDFLAGS]) if test yes = "$lt_cv_irix_exported_symbol"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; linux*) case $cc_basename in tcc*) # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(ld_shlibs, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; osf3*) if test yes = "$GCC"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test yes = "$GCC"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test yes = "$GCC"; then wlarc='$wl' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='$wl' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test yes = "$GCC"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test yes,yes = "$GCC,$enable_shared"; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_CACHE_CHECK([whether -lc should be explicitly linked in], [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), [$RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no else lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* ]) _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary and the resulting library dependency is "absolute", i.e impossible to change by setting $shlibpath_var if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [postlink_cmds], [2], [Commands necessary for finishing linking programs]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to 'libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl lt_save_CC=$CC AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # Report what library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC=$lt_save_CC ])# _LT_LANG_C_CONFIG # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to 'libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl if test -n "$CXX" && ( test no != "$CXX" && ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || (test g++ != "$CXX"))); then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_caught_CXX_error"; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test yes = "$GXX"; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test yes = "$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='$wl' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no ;; esac if test yes = "$GXX"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag=$shared_flag' $wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. # The "-G" linker flag allows undefined symbols. _LT_TAGVAR(no_undefined_flag, $1)='-bernotok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl*) # Native MSVC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ func_to_tool_file "$lt_outputfile"~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ;; cxx*) # Compaq C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes,no = "$GXX,$with_gnu_ld"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' case $host in osf3*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test yes,no = "$GXX,$with_gnu_ld"; then _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ '"$_LT_TAGVAR(old_archive_cmds, $1)" _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ '"$_LT_TAGVAR(reload_cmds, $1)" ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no _LT_TAGVAR(GCC, $1)=$GXX _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test yes != "$_lt_caught_CXX_error" AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_FUNC_STRIPNAME_CNF # ---------------------- # func_stripname_cnf prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # # This function is identical to the (non-XSI) version of func_stripname, # except this one can be used by m4 code that may be executed by configure, # rather than the libtool script. m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl AC_REQUIRE([_LT_DECL_SED]) AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) func_stripname_cnf () { case @S|@2 in .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;; *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;; esac } # func_stripname_cnf ])# _LT_FUNC_STRIPNAME_CNF # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF package foo func foo() { } _LT_EOF ]) _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case $prev$p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test x-L = "$p" || test x-R = "$p"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test no = "$pre_test_object_deps_done"; then case $prev in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)=$prev$p else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test no = "$pre_test_object_deps_done"; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)=$p else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)=$p else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [case $host_os in interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_LANG_PUSH(Fortran 77) if test -z "$F77" || test no = "$F77"; then _lt_disable_F77=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_disable_F77"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} CFLAGS=$FFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)=$G77 _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test yes != "$_lt_disable_F77" AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_LANG_PUSH(Fortran) if test -z "$FC" || test no = "$FC"; then _lt_disable_FC=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_disable_FC"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} CFLAGS=$FCFLAGS compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test yes != "$_lt_disable_FC" AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_GO_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Go compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GO_CONFIG], [AC_REQUIRE([LT_PROG_GO])dnl AC_LANG_SAVE # Source file extension for Go test sources. ac_ext=go # Object file extension for compiled Go test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="package main; func main() { }" # Code to be used in simple link tests lt_simple_link_test_code='package main; func main() { }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GOC-"gccgo"} CFLAGS=$GOFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # Go did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GO_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code=$lt_simple_compile_test_code # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= CC=${RC-"windres"} CFLAGS= compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_GO # ---------- AC_DEFUN([LT_PROG_GO], [AC_CHECK_TOOL(GOC, gccgo,) ]) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_DLLTOOL # ---------------- # Ensure DLLTOOL variable is set. m4_defun([_LT_DECL_DLLTOOL], [AC_CHECK_TOOL(DLLTOOL, dlltool, false) test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program]) AC_SUBST([DLLTOOL]) ]) # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED m4_ifndef([AC_PROG_SED], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) AC_CACHE_VAL(lt_cv_path_SED, [# Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f "$lt_ac_sed" && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test 10 -lt "$lt_ac_count" && break lt_ac_count=`expr $lt_ac_count + 1` if test "$lt_ac_count" -gt "$lt_ac_max"; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ])#AC_PROG_SED ])#m4_ifndef # Old name: AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PATH_CONVERSION_FUNCTIONS # ----------------------------- # Determine what file name conversion functions should be used by # func_to_host_file (and, implicitly, by func_to_host_path). These are needed # for certain cross-compile configurations and native mingw. m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_MSG_CHECKING([how to convert $build file names to $host format]) AC_CACHE_VAL(lt_cv_to_host_file_cmd, [case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac ]) to_host_file_cmd=$lt_cv_to_host_file_cmd AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) _LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], [0], [convert $build file names to $host format])dnl AC_MSG_CHECKING([how to convert $build file names to toolchain format]) AC_CACHE_VAL(lt_cv_to_tool_file_cmd, [#assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac ]) to_tool_file_cmd=$lt_cv_to_tool_file_cmd AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) _LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], [0], [convert $build files to toolchain format])dnl ])# _LT_PATH_CONVERSION_FUNCTIONS jamulus-3.9.1+dfsg/libs/opus/m4/ltoptions.m40000644000175000017500000003426214340334543017717 0ustar vimervimer# Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software # Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 8 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option '$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl 'shared' nor 'disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], [_LT_WITH_AIX_SONAME([aix])]) ]) ])# _LT_SET_OPTIONS ## --------------------------------- ## ## Macros to handle LT_INIT options. ## ## --------------------------------- ## # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [1], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the 'shared' and # 'disable-shared' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS=$lt_save_ifs ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the 'static' and # 'disable-static' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS=$lt_save_ifs ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the 'fast-install' # and 'disable-fast-install' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS=$lt_save_ifs ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_AIX_SONAME([DEFAULT]) # ---------------------------------- # implement the --with-aix-soname flag, and support the `aix-soname=aix' # and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT # is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. m4_define([_LT_WITH_AIX_SONAME], [m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[[5-9]]*,yes) AC_MSG_CHECKING([which variant of shared library versioning to provide]) AC_ARG_WITH([aix-soname], [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], [case $withval in aix|svr4|both) ;; *) AC_MSG_ERROR([Unknown argument to --with-aix-soname]) ;; esac lt_cv_with_aix_soname=$with_aix_soname], [AC_CACHE_VAL([lt_cv_with_aix_soname], [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) with_aix_soname=$lt_cv_with_aix_soname]) AC_MSG_RESULT([$with_aix_soname]) if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac _LT_DECL([], [shared_archive_member_spec], [0], [Shared archive member basename, for filename based shared library versioning on AIX])dnl ])# _LT_WITH_AIX_SONAME LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the 'pic-only' and 'no-pic' # LT_INIT options. # MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac], [pic_mode=m4_default([$1], [default])]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) ## ----------------- ## ## LTDL_INIT Options ## ## ----------------- ## m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) jamulus-3.9.1+dfsg/libs/opus/m4/ax_add_fortify_source.m40000644000175000017500000000327114340334543022222 0ustar vimervimer# =========================================================================== # Modified from https://www.gnu.org/software/autoconf-archive/ax_add_fortify_source.html # =========================================================================== # # SYNOPSIS # # AX_ADD_FORTIFY_SOURCE # # DESCRIPTION # # Check whether -D_FORTIFY_SOURCE=2 can be added to CFLAGS without macro # redefinition warnings. Some distributions (such as Gentoo Linux) enable # _FORTIFY_SOURCE globally in their compilers, leading to unnecessary # warnings in the form of # # :0:0: error: "_FORTIFY_SOURCE" redefined [-Werror] # : note: this is the location of the previous definition # # which is a problem if -Werror is enabled. This macro checks whether # _FORTIFY_SOURCE is already defined, and if not, adds -D_FORTIFY_SOURCE=2 # to CFLAGS. # # LICENSE # # Copyright (c) 2017 David Seifert # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 1 AC_DEFUN([AX_ADD_FORTIFY_SOURCE],[ AC_MSG_CHECKING([whether to add -D_FORTIFY_SOURCE=2 to CFLAGS]) AC_LINK_IFELSE([ AC_LANG_SOURCE( [[ int main() { #ifndef _FORTIFY_SOURCE return 0; #else this_is_an_error; #endif } ]] )], [ AC_MSG_RESULT([yes]) CFLAGS="$CFLAGS -D_FORTIFY_SOURCE=2" ], [ AC_MSG_RESULT([no]) ]) ]) jamulus-3.9.1+dfsg/libs/opus/m4/lt~obsolete.m40000644000175000017500000001377414340334543020243 0ustar vimervimer# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software # Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 5 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) jamulus-3.9.1+dfsg/libs/opus/m4/ltversion.m40000644000175000017500000000127314340334543017705 0ustar vimervimer# ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # @configure_input@ # serial 4179 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.4.6]) m4_define([LT_PACKAGE_REVISION], [2.4.6]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.4.6' macro_revision='2.4.6' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) jamulus-3.9.1+dfsg/libs/opus/opus_functions.cmake0000644000175000017500000001751014340334543021157 0ustar vimervimer#[[Cmake helper function to parse source files from make files this is to avoid breaking existing make and auto make support but still have the option to use CMake with only lists at one place]] cmake_minimum_required(VERSION 3.1) function(get_library_version OPUS_LIBRARY_VERSION OPUS_LIBRARY_VERSION_MAJOR) file(STRINGS configure.ac opus_lt_current_string LIMIT_COUNT 1 REGEX "OPUS_LT_CURRENT=") string(REGEX MATCH "OPUS_LT_CURRENT=([0-9]*)" _ ${opus_lt_current_string}) set(OPUS_LT_CURRENT ${CMAKE_MATCH_1}) file(STRINGS configure.ac opus_lt_revision_string LIMIT_COUNT 1 REGEX "OPUS_LT_REVISION=") string(REGEX MATCH "OPUS_LT_REVISION=([0-9]*)" _ ${opus_lt_revision_string}) set(OPUS_LT_REVISION ${CMAKE_MATCH_1}) file(STRINGS configure.ac opus_lt_age_string LIMIT_COUNT 1 REGEX "OPUS_LT_AGE=") string(REGEX MATCH "OPUS_LT_AGE=([0-9]*)" _ ${opus_lt_age_string}) set(OPUS_LT_AGE ${CMAKE_MATCH_1}) math(EXPR OPUS_LIBRARY_VERSION_MAJOR "${OPUS_LT_CURRENT} - ${OPUS_LT_AGE}") set(OPUS_LIBRARY_VERSION_MINOR ${OPUS_LT_AGE}) set(OPUS_LIBRARY_VERSION_PATCH ${OPUS_LT_REVISION}) set( OPUS_LIBRARY_VERSION "${OPUS_LIBRARY_VERSION_MAJOR}.${OPUS_LIBRARY_VERSION_MINOR}.${OPUS_LIBRARY_VERSION_PATCH}" PARENT_SCOPE) set(OPUS_LIBRARY_VERSION_MAJOR ${OPUS_LIBRARY_VERSION_MAJOR} PARENT_SCOPE) endfunction() function(get_package_version PACKAGE_VERSION) find_package(Git) if(GIT_FOUND) execute_process(COMMAND ${GIT_EXECUTABLE} describe --tags --match "v*" OUTPUT_VARIABLE OPUS_PACKAGE_VERSION) if(OPUS_PACKAGE_VERSION) string(STRIP ${OPUS_PACKAGE_VERSION}, OPUS_PACKAGE_VERSION) string(REPLACE \n "" OPUS_PACKAGE_VERSION ${OPUS_PACKAGE_VERSION}) string(REPLACE , "" OPUS_PACKAGE_VERSION ${OPUS_PACKAGE_VERSION}) string(SUBSTRING ${OPUS_PACKAGE_VERSION} 1 -1 OPUS_PACKAGE_VERSION) set(PACKAGE_VERSION ${OPUS_PACKAGE_VERSION} PARENT_SCOPE) return() endif() endif() if(EXISTS "${CMAKE_SOURCE_DIR}/package_version") # Not a git repo, lets' try to parse it from package_version file if exists file(STRINGS package_version opus_package_version_string LIMIT_COUNT 1 REGEX "PACKAGE_VERSION=") string(REPLACE "PACKAGE_VERSION=" "" opus_package_version_string ${opus_package_version_string}) string(REPLACE "\"" "" opus_package_version_string ${opus_package_version_string}) set(PACKAGE_VERSION ${opus_package_version_string} PARENT_SCOPE) return() endif() # if all else fails set to 0 set(PACKAGE_VERSION 0 PARENT_SCOPE) endfunction() function(check_and_set_flag NAME FLAG) include(CheckCCompilerFlag) check_c_compiler_flag(${FLAG} ${NAME}_SUPPORTED) if(${NAME}_SUPPORTED) add_definitions(${FLAG}) endif() endfunction() function(check_flag NAME FLAG) include(CheckCCompilerFlag) check_c_compiler_flag(${FLAG} ${NAME}_SUPPORTED) endfunction() include(CheckIncludeFile) # function to check if compiler supports SSE, SSE2, SSE4.1 and AVX if target # systems may not have SSE support then use OPUS_MAY_HAVE_SSE option if target # system is guaranteed to have SSE support then OPUS_PRESUME_SSE can be used to # skip SSE runtime check function(opus_detect_sse COMPILER_SUPPORT_SIMD) message(STATUS "Check SIMD support by compiler") check_include_file(xmmintrin.h HAVE_XMMINTRIN_H) # SSE1 if(HAVE_XMMINTRIN_H) if(MSVC) # different arch options for 32 and 64 bit target for MSVC if(CMAKE_SIZEOF_VOID_P EQUAL 4) check_flag(SSE1 /arch:SSE) else() set(SSE1_SUPPORTED 1 PARENT_SCOPE) endif() else() check_and_set_flag(SSE1 -msse) endif() else() set(SSE1_SUPPORTED 0 PARENT_SCOPE) endif() check_include_file(emmintrin.h HAVE_EMMINTRIN_H) # SSE2 if(HAVE_EMMINTRIN_H) if(MSVC) if(CMAKE_SIZEOF_VOID_P EQUAL 4) check_flag(SSE2 /arch:SSE2) else() set(SSE2_SUPPORTED 1 PARENT_SCOPE) endif() else() check_and_set_flag(SSE2 -msse2) endif() else() set(SSE2_SUPPORTED 0 PARENT_SCOPE) endif() check_include_file(smmintrin.h HAVE_SMMINTRIN_H) # SSE4.1 if(HAVE_SMMINTRIN_H) if(MSVC) if(CMAKE_SIZEOF_VOID_P EQUAL 4) check_flag(SSE4_1 /arch:SSE2) # SSE2 and above else() set(SSE4_1_SUPPORTED 1 PARENT_SCOPE) endif() else() check_and_set_flag(SSE4_1 -msse4.1) endif() else() set(SSE4_1_SUPPORTED 0 PARENT_SCOPE) endif() check_include_file(immintrin.h HAVE_IMMINTRIN_H) # AVX if(HAVE_IMMINTRIN_H) if(MSVC) check_flag(AVX /arch:AVX) else() check_and_set_flag(AVX -mavx) endif() else() set(AVX_SUPPORTED 0 PARENT_SCOPE) endif() if(MSVC) # To avoid warning D9025 of overriding compiler options if(AVX_SUPPORTED) # on 64 bit and 32 bits add_definitions(/arch:AVX) elseif(CMAKE_SIZEOF_VOID_P EQUAL 4) # if AVX not supported then set SSE flag if(SSE4_1_SUPPORTED OR SSE2_SUPPORTED) add_definitions(/arch:SSE2) elseif(SSE1_SUPPORTED) add_definitions(/arch:SSE) endif() endif() endif() if(SSE1_SUPPORTED OR SSE2_SUPPORTED OR SSE4_1_SUPPORTED OR AVX_SUPPORTED) set(COMPILER_SUPPORT_SIMD 1 PARENT_SCOPE) else() message(STATUS "No SIMD support in compiler") endif() endfunction() function(opus_detect_neon COMPILER_SUPPORT_NEON) if(CMAKE_SYSTEM_PROCESSOR MATCHES "(armv7-a|aarch64)") message(STATUS "Check NEON support by compiler") check_include_file(arm_neon.h HAVE_ARM_NEON_H) if(HAVE_ARM_NEON_H) set(COMPILER_SUPPORT_NEON ${HAVE_ARM_NEON_H} PARENT_SCOPE) endif() endif() endfunction() function(opus_supports_cpu_detection RUNTIME_CPU_CAPABILITY_DETECTION) if(MSVC) check_include_file(intrin.h HAVE_INTRIN_H) else() check_include_file(cpuid.h HAVE_CPUID_H) endif() if(HAVE_INTRIN_H OR HAVE_CPUID_H) set(RUNTIME_CPU_CAPABILITY_DETECTION 1 PARENT_SCOPE) else() set(RUNTIME_CPU_CAPABILITY_DETECTION 0 PARENT_SCOPE) endif() endfunction() function(add_sources_group target group) target_sources(${target} PRIVATE ${ARGN}) source_group(${group} FILES ${ARGN}) endfunction() function(get_opus_sources SOURCE_GROUP MAKE_FILE SOURCES) # read file, each item in list is one group file(STRINGS ${MAKE_FILE} opus_sources) # add wildcard for regex match string(CONCAT SOURCE_GROUP ${SOURCE_GROUP} ".*$") # find group foreach(val IN LISTS opus_sources) if(val MATCHES ${SOURCE_GROUP}) list(LENGTH val list_length) if(${list_length} EQUAL 1) # for tests split by '=' and clean up the rest into a list string(FIND ${val} "=" index) math(EXPR index "${index} + 1") string(SUBSTRING ${val} ${index} -1 sources) string(REPLACE " " ";" sources ${sources}) else() # discard the group list(REMOVE_AT val 0) set(sources ${val}) endif() break() endif() endforeach() list(LENGTH sources list_length) if(${list_length} LESS 1) message( FATAL_ERROR "No files parsed successfully from ${SOURCE_GROUP} in ${MAKE_FILE}") endif() # remove trailing whitespaces set(list_var "") foreach(source ${sources}) string(STRIP "${source}" source) list(APPEND list_var "${source}") endforeach() set(${SOURCES} ${list_var} PARENT_SCOPE) endfunction() jamulus-3.9.1+dfsg/libs/opus/silk_sources.mk0000644000175000017500000000777214340334543020146 0ustar vimervimerSILK_SOURCES = \ silk/CNG.c \ silk/code_signs.c \ silk/init_decoder.c \ silk/decode_core.c \ silk/decode_frame.c \ silk/decode_parameters.c \ silk/decode_indices.c \ silk/decode_pulses.c \ silk/decoder_set_fs.c \ silk/dec_API.c \ silk/enc_API.c \ silk/encode_indices.c \ silk/encode_pulses.c \ silk/gain_quant.c \ silk/interpolate.c \ silk/LP_variable_cutoff.c \ silk/NLSF_decode.c \ silk/NSQ.c \ silk/NSQ_del_dec.c \ silk/PLC.c \ silk/shell_coder.c \ silk/tables_gain.c \ silk/tables_LTP.c \ silk/tables_NLSF_CB_NB_MB.c \ silk/tables_NLSF_CB_WB.c \ silk/tables_other.c \ silk/tables_pitch_lag.c \ silk/tables_pulses_per_block.c \ silk/VAD.c \ silk/control_audio_bandwidth.c \ silk/quant_LTP_gains.c \ silk/VQ_WMat_EC.c \ silk/HP_variable_cutoff.c \ silk/NLSF_encode.c \ silk/NLSF_VQ.c \ silk/NLSF_unpack.c \ silk/NLSF_del_dec_quant.c \ silk/process_NLSFs.c \ silk/stereo_LR_to_MS.c \ silk/stereo_MS_to_LR.c \ silk/check_control_input.c \ silk/control_SNR.c \ silk/init_encoder.c \ silk/control_codec.c \ silk/A2NLSF.c \ silk/ana_filt_bank_1.c \ silk/biquad_alt.c \ silk/bwexpander_32.c \ silk/bwexpander.c \ silk/debug.c \ silk/decode_pitch.c \ silk/inner_prod_aligned.c \ silk/lin2log.c \ silk/log2lin.c \ silk/LPC_analysis_filter.c \ silk/LPC_inv_pred_gain.c \ silk/table_LSF_cos.c \ silk/NLSF2A.c \ silk/NLSF_stabilize.c \ silk/NLSF_VQ_weights_laroia.c \ silk/pitch_est_tables.c \ silk/resampler.c \ silk/resampler_down2_3.c \ silk/resampler_down2.c \ silk/resampler_private_AR2.c \ silk/resampler_private_down_FIR.c \ silk/resampler_private_IIR_FIR.c \ silk/resampler_private_up2_HQ.c \ silk/resampler_rom.c \ silk/sigm_Q15.c \ silk/sort.c \ silk/sum_sqr_shift.c \ silk/stereo_decode_pred.c \ silk/stereo_encode_pred.c \ silk/stereo_find_predictor.c \ silk/stereo_quant_pred.c \ silk/LPC_fit.c SILK_SOURCES_SSE4_1 = \ silk/x86/NSQ_sse4_1.c \ silk/x86/NSQ_del_dec_sse4_1.c \ silk/x86/x86_silk_map.c \ silk/x86/VAD_sse4_1.c \ silk/x86/VQ_WMat_EC_sse4_1.c SILK_SOURCES_ARM_NEON_INTR = \ silk/arm/arm_silk_map.c \ silk/arm/biquad_alt_neon_intr.c \ silk/arm/LPC_inv_pred_gain_neon_intr.c \ silk/arm/NSQ_del_dec_neon_intr.c \ silk/arm/NSQ_neon.c SILK_SOURCES_FIXED = \ silk/fixed/LTP_analysis_filter_FIX.c \ silk/fixed/LTP_scale_ctrl_FIX.c \ silk/fixed/corrMatrix_FIX.c \ silk/fixed/encode_frame_FIX.c \ silk/fixed/find_LPC_FIX.c \ silk/fixed/find_LTP_FIX.c \ silk/fixed/find_pitch_lags_FIX.c \ silk/fixed/find_pred_coefs_FIX.c \ silk/fixed/noise_shape_analysis_FIX.c \ silk/fixed/process_gains_FIX.c \ silk/fixed/regularize_correlations_FIX.c \ silk/fixed/residual_energy16_FIX.c \ silk/fixed/residual_energy_FIX.c \ silk/fixed/warped_autocorrelation_FIX.c \ silk/fixed/apply_sine_window_FIX.c \ silk/fixed/autocorr_FIX.c \ silk/fixed/burg_modified_FIX.c \ silk/fixed/k2a_FIX.c \ silk/fixed/k2a_Q16_FIX.c \ silk/fixed/pitch_analysis_core_FIX.c \ silk/fixed/vector_ops_FIX.c \ silk/fixed/schur64_FIX.c \ silk/fixed/schur_FIX.c SILK_SOURCES_FIXED_SSE4_1 = \ silk/fixed/x86/vector_ops_FIX_sse4_1.c \ silk/fixed/x86/burg_modified_FIX_sse4_1.c SILK_SOURCES_FIXED_ARM_NEON_INTR = \ silk/fixed/arm/warped_autocorrelation_FIX_neon_intr.c SILK_SOURCES_FLOAT = \ silk/float/apply_sine_window_FLP.c \ silk/float/corrMatrix_FLP.c \ silk/float/encode_frame_FLP.c \ silk/float/find_LPC_FLP.c \ silk/float/find_LTP_FLP.c \ silk/float/find_pitch_lags_FLP.c \ silk/float/find_pred_coefs_FLP.c \ silk/float/LPC_analysis_filter_FLP.c \ silk/float/LTP_analysis_filter_FLP.c \ silk/float/LTP_scale_ctrl_FLP.c \ silk/float/noise_shape_analysis_FLP.c \ silk/float/process_gains_FLP.c \ silk/float/regularize_correlations_FLP.c \ silk/float/residual_energy_FLP.c \ silk/float/warped_autocorrelation_FLP.c \ silk/float/wrappers_FLP.c \ silk/float/autocorrelation_FLP.c \ silk/float/burg_modified_FLP.c \ silk/float/bwexpander_FLP.c \ silk/float/energy_FLP.c \ silk/float/inner_product_FLP.c \ silk/float/k2a_FLP.c \ silk/float/LPC_inv_pred_gain_FLP.c \ silk/float/pitch_analysis_core_FLP.c \ silk/float/scale_copy_vector_FLP.c \ silk/float/scale_vector_FLP.c \ silk/float/schur_FLP.c \ silk/float/sort_FLP.c jamulus-3.9.1+dfsg/libs/opus/silk_headers.mk0000644000175000017500000000210214340334543020054 0ustar vimervimerSILK_HEAD = \ silk/debug.h \ silk/control.h \ silk/errors.h \ silk/API.h \ silk/typedef.h \ silk/define.h \ silk/main.h \ silk/x86/main_sse.h \ silk/PLC.h \ silk/structs.h \ silk/tables.h \ silk/tuning_parameters.h \ silk/Inlines.h \ silk/MacroCount.h \ silk/MacroDebug.h \ silk/macros.h \ silk/NSQ.h \ silk/pitch_est_defines.h \ silk/resampler_private.h \ silk/resampler_rom.h \ silk/resampler_structs.h \ silk/SigProc_FIX.h \ silk/x86/SigProc_FIX_sse.h \ silk/arm/biquad_alt_arm.h \ silk/arm/LPC_inv_pred_gain_arm.h \ silk/arm/macros_armv4.h \ silk/arm/macros_armv5e.h \ silk/arm/macros_arm64.h \ silk/arm/SigProc_FIX_armv4.h \ silk/arm/SigProc_FIX_armv5e.h \ silk/arm/NSQ_del_dec_arm.h \ silk/arm/NSQ_neon.h \ silk/fixed/main_FIX.h \ silk/fixed/structs_FIX.h \ silk/fixed/arm/warped_autocorrelation_FIX_arm.h \ silk/fixed/mips/noise_shape_analysis_FIX_mipsr1.h \ silk/fixed/mips/warped_autocorrelation_FIX_mipsr1.h \ silk/float/main_FLP.h \ silk/float/structs_FLP.h \ silk/float/SigProc_FLP.h \ silk/mips/macros_mipsr1.h \ silk/mips/NSQ_del_dec_mipsr1.h \ silk/mips/sigproc_fix_mipsr1.h jamulus-3.9.1+dfsg/libs/opus/install-sh0000755000175000017500000003452414340334543017107 0ustar vimervimer#!/bin/sh # install - install a program, script, or datafile scriptversion=2016-01-11.22; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. tab=' ' nl=' ' IFS=" $tab$nl" # Set DOITPROG to "echo" to test this script. doit=${DOITPROG-} doit_exec=${doit:-exec} # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false is_target_a_directory=possibly usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) is_target_a_directory=always dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) is_target_a_directory=never;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done # We allow the use of options -d and -T together, by making -d # take the precedence; this is for compatibility with GNU install. if test -n "$dir_arg"; then if test -n "$dst_arg"; then echo "$0: target directory not allowed when installing a directory." >&2 exit 1 fi fi if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then if test $# -gt 1 || test "$is_target_a_directory" = always; then if test ! -d "$dst_arg"; then echo "$0: $dst_arg: Is not a directory." >&2 exit 1 fi fi fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test "$is_target_a_directory" = never; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else dstdir=`dirname "$dst"` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 if (umask $mkdir_umask && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/d" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac oIFS=$IFS IFS=/ set -f set fnord $dstdir shift set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: jamulus-3.9.1+dfsg/libs/opus/config.sub0000755000175000017500000010725714340334543017072 0ustar vimervimer#! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2017 Free Software Foundation, Inc. timestamp='2017-04-02' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright 1992-2017 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ kopensolaris*-gnu* | cloudabi*-eabi* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze*) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 ;; -lynx*5) os=-lynxos5 ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ | ba \ | be32 | be64 \ | bfin \ | c4x | c8051 | clipper \ | d10v | d30v | dlx | dsp16xx \ | e2k | epiphany \ | fido | fr30 | frv | ft32 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia16 | ia64 \ | ip2k | iq2000 \ | k1om \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa32r6 | mipsisa32r6el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64r6 | mipsisa64r6el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 | or1k | or1knd | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pru \ | pyramid \ | riscv32 | riscv64 \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | visium \ | wasm32 \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; leon|leon[3-9]) basic_machine=sparc-$basic_machine ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=-none ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | ba-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | c8051-* | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | e2k-* | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia16-* | ia64-* \ | ip2k-* | iq2000-* \ | k1om-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | microblaze-* | microblazeel-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa32r6-* | mipsisa32r6el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64r6-* | mipsisa64r6el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | or1k*-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pru-* \ | pyramid-* \ | riscv32-* | riscv64-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | visium-* \ | wasm32-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; asmjs) basic_machine=asmjs-unknown ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; e500v[12]) basic_machine=powerpc-unknown os=$os"spe" ;; e500v[12]-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` os=$os"spe" ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; leon-*|leon[3-9]-*) basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze*) basic_machine=microblaze-xilinx ;; mingw64) basic_machine=x86_64-pc os=-mingw64 ;; mingw32) basic_machine=i686-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; moxiebox) basic_machine=moxie-unknown os=-moxiebox ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i686-pc os=-msys ;; mvs) basic_machine=i370-ibm os=-mvs ;; nacl) basic_machine=le32-unknown os=-nacl ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; nsx-tandem) basic_machine=nsx-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-* | ppc64p7-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos | rdos64) basic_machine=x86_64-pc os=-rdos ;; rdos32) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; strongarm-* | thumb-*) basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tile*) basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; wasm32) basic_machine=wasm32-unknown ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* | -cloudabi* | -sortix* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -ios) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; c8051-*) os=-elf ;; hexagon-*) os=-elf ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; pru-*) os=-elf ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: jamulus-3.9.1+dfsg/libs/opus/opus_headers.mk0000644000175000017500000000026414340334543020107 0ustar vimervimerOPUS_HEAD = \ include/opus.h \ include/opus_multistream.h \ include/opus_projection.h \ src/opus_private.h \ src/analysis.h \ src/mapping_matrix.h \ src/mlp.h \ src/tansig_table.h jamulus-3.9.1+dfsg/libs/opus/win32/0000755000175000017500000000000014340334543016035 5ustar vimervimerjamulus-3.9.1+dfsg/libs/opus/win32/config.h0000644000175000017500000000516514340334543017462 0ustar vimervimer/*********************************************************************** Copyright (c) 2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef CONFIG_H #define CONFIG_H #define USE_ALLOCA 1 /* Comment out the next line for floating-point code */ /*#define FIXED_POINT 1 */ #define OPUS_BUILD 1 #if defined(_M_IX86) || defined(_M_X64) /* Can always compile SSE intrinsics (no special compiler flags necessary) */ #define OPUS_X86_MAY_HAVE_SSE #define OPUS_X86_MAY_HAVE_SSE2 #define OPUS_X86_MAY_HAVE_SSE4_1 /* Presume SSE functions, if compiled to use SSE/SSE2/AVX (note that AMD64 implies SSE2, and AVX implies SSE4.1) */ #if defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP >= 1)) || defined(__AVX__) #define OPUS_X86_PRESUME_SSE 1 #endif #if defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) || defined(__AVX__) #define OPUS_X86_PRESUME_SSE2 1 #endif #if defined(__AVX__) #define OPUS_X86_PRESUME_SSE4_1 1 #endif #if !defined(OPUS_X86_PRESUME_SSE4_1) || !defined(OPUS_X86_PRESUME_SSE2) || !defined(OPUS_X86_PRESUME_SSE) #define OPUS_HAVE_RTCD 1 #endif #endif #include "version.h" #endif /* CONFIG_H */ jamulus-3.9.1+dfsg/libs/opus/win32/VS2015/0000755000175000017500000000000014340334543016675 5ustar vimervimerjamulus-3.9.1+dfsg/libs/opus/win32/VS2015/test_opus_api.vcxproj0000644000175000017500000002313614340334543023175 0ustar vimervimer DebugDLL_fixed Win32 DebugDLL_fixed x64 DebugDLL Win32 DebugDLL x64 Debug Win32 Debug x64 ReleaseDLL_fixed Win32 ReleaseDLL_fixed x64 ReleaseDLL Win32 ReleaseDLL x64 Release Win32 Release x64 {219ec965-228a-1824-174d-96449d05f88a} {1D257A17-D254-42E5-82D6-1C87A6EC775A} Win32Proj test_opus_api Application v140 Application v140 Application v140 Application v140 Application v140 Application v140 Application v140 Application v140 Application v140 Application v140 Application v140 Application v140 jamulus-3.9.1+dfsg/libs/opus/win32/VS2015/opus_demo.vcxproj0000644000175000017500000002312414340334543022306 0ustar vimervimer DebugDLL_fixed Win32 DebugDLL_fixed x64 DebugDLL Win32 DebugDLL x64 Debug Win32 Debug x64 ReleaseDLL_fixed Win32 ReleaseDLL_fixed x64 ReleaseDLL Win32 ReleaseDLL x64 Release Win32 Release x64 {219ec965-228a-1824-174d-96449d05f88a} {016C739D-6389-43BF-8D88-24B2BF6F620F} Win32Proj opus_demo Application v140 Application v140 Application v140 Application v140 Application v140 Application v140 Application v140 Application v140 Application v140 Application v140 Application v140 Application v140 jamulus-3.9.1+dfsg/libs/opus/win32/VS2015/test_opus_api.vcxproj.filters0000644000175000017500000000101414340334543024633 0ustar vimervimer {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx Source Files jamulus-3.9.1+dfsg/libs/opus/win32/VS2015/opus.sln0000644000175000017500000003022114340334543020377 0ustar vimervimer Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opus", "opus.vcxproj", "{219EC965-228A-1824-174D-96449D05F88A}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opus_demo", "opus_demo.vcxproj", "{016C739D-6389-43BF-8D88-24B2BF6F620F}" ProjectSection(ProjectDependencies) = postProject {219EC965-228A-1824-174D-96449D05F88A} = {219EC965-228A-1824-174D-96449D05F88A} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_opus_api", "test_opus_api.vcxproj", "{1D257A17-D254-42E5-82D6-1C87A6EC775A}" ProjectSection(ProjectDependencies) = postProject {219EC965-228A-1824-174D-96449D05F88A} = {219EC965-228A-1824-174D-96449D05F88A} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_opus_decode", "test_opus_decode.vcxproj", "{8578322A-1883-486B-B6FA-E0094B65C9F2}" ProjectSection(ProjectDependencies) = postProject {219EC965-228A-1824-174D-96449D05F88A} = {219EC965-228A-1824-174D-96449D05F88A} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_opus_encode", "test_opus_encode.vcxproj", "{84DAA768-1A38-4312-BB61-4C78BB59E5B8}" ProjectSection(ProjectDependencies) = postProject {219EC965-228A-1824-174D-96449D05F88A} = {219EC965-228A-1824-174D-96449D05F88A} EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 DebugDLL_fixed|Win32 = DebugDLL_fixed|Win32 DebugDLL_fixed|x64 = DebugDLL_fixed|x64 DebugDLL|Win32 = DebugDLL|Win32 DebugDLL|x64 = DebugDLL|x64 Release|Win32 = Release|Win32 Release|x64 = Release|x64 ReleaseDLL_fixed|Win32 = ReleaseDLL_fixed|Win32 ReleaseDLL_fixed|x64 = ReleaseDLL_fixed|x64 ReleaseDLL|Win32 = ReleaseDLL|Win32 ReleaseDLL|x64 = ReleaseDLL|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {219EC965-228A-1824-174D-96449D05F88A}.Debug|Win32.ActiveCfg = Debug|Win32 {219EC965-228A-1824-174D-96449D05F88A}.Debug|Win32.Build.0 = Debug|Win32 {219EC965-228A-1824-174D-96449D05F88A}.Debug|x64.ActiveCfg = Debug|x64 {219EC965-228A-1824-174D-96449D05F88A}.Debug|x64.Build.0 = Debug|x64 {219EC965-228A-1824-174D-96449D05F88A}.DebugDLL_fixed|Win32.ActiveCfg = DebugDLL_fixed|Win32 {219EC965-228A-1824-174D-96449D05F88A}.DebugDLL_fixed|Win32.Build.0 = DebugDLL_fixed|Win32 {219EC965-228A-1824-174D-96449D05F88A}.DebugDLL_fixed|x64.ActiveCfg = DebugDLL_fixed|x64 {219EC965-228A-1824-174D-96449D05F88A}.DebugDLL_fixed|x64.Build.0 = DebugDLL_fixed|x64 {219EC965-228A-1824-174D-96449D05F88A}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 {219EC965-228A-1824-174D-96449D05F88A}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 {219EC965-228A-1824-174D-96449D05F88A}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 {219EC965-228A-1824-174D-96449D05F88A}.DebugDLL|x64.Build.0 = DebugDLL|x64 {219EC965-228A-1824-174D-96449D05F88A}.Release|Win32.ActiveCfg = Release|Win32 {219EC965-228A-1824-174D-96449D05F88A}.Release|Win32.Build.0 = Release|Win32 {219EC965-228A-1824-174D-96449D05F88A}.Release|x64.ActiveCfg = Release|x64 {219EC965-228A-1824-174D-96449D05F88A}.Release|x64.Build.0 = Release|x64 {219EC965-228A-1824-174D-96449D05F88A}.ReleaseDLL_fixed|Win32.ActiveCfg = ReleaseDLL_fixed|Win32 {219EC965-228A-1824-174D-96449D05F88A}.ReleaseDLL_fixed|Win32.Build.0 = ReleaseDLL_fixed|Win32 {219EC965-228A-1824-174D-96449D05F88A}.ReleaseDLL_fixed|x64.ActiveCfg = ReleaseDLL_fixed|x64 {219EC965-228A-1824-174D-96449D05F88A}.ReleaseDLL_fixed|x64.Build.0 = ReleaseDLL_fixed|x64 {219EC965-228A-1824-174D-96449D05F88A}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 {219EC965-228A-1824-174D-96449D05F88A}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 {219EC965-228A-1824-174D-96449D05F88A}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 {219EC965-228A-1824-174D-96449D05F88A}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 {016C739D-6389-43BF-8D88-24B2BF6F620F}.Debug|Win32.ActiveCfg = Debug|Win32 {016C739D-6389-43BF-8D88-24B2BF6F620F}.Debug|Win32.Build.0 = Debug|Win32 {016C739D-6389-43BF-8D88-24B2BF6F620F}.Debug|x64.ActiveCfg = Debug|x64 {016C739D-6389-43BF-8D88-24B2BF6F620F}.Debug|x64.Build.0 = Debug|x64 {016C739D-6389-43BF-8D88-24B2BF6F620F}.DebugDLL_fixed|Win32.ActiveCfg = DebugDLL_fixed|Win32 {016C739D-6389-43BF-8D88-24B2BF6F620F}.DebugDLL_fixed|Win32.Build.0 = DebugDLL_fixed|Win32 {016C739D-6389-43BF-8D88-24B2BF6F620F}.DebugDLL_fixed|x64.ActiveCfg = DebugDLL_fixed|x64 {016C739D-6389-43BF-8D88-24B2BF6F620F}.DebugDLL_fixed|x64.Build.0 = DebugDLL_fixed|x64 {016C739D-6389-43BF-8D88-24B2BF6F620F}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 {016C739D-6389-43BF-8D88-24B2BF6F620F}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 {016C739D-6389-43BF-8D88-24B2BF6F620F}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 {016C739D-6389-43BF-8D88-24B2BF6F620F}.DebugDLL|x64.Build.0 = DebugDLL|x64 {016C739D-6389-43BF-8D88-24B2BF6F620F}.Release|Win32.ActiveCfg = Release|Win32 {016C739D-6389-43BF-8D88-24B2BF6F620F}.Release|Win32.Build.0 = Release|Win32 {016C739D-6389-43BF-8D88-24B2BF6F620F}.Release|x64.ActiveCfg = Release|x64 {016C739D-6389-43BF-8D88-24B2BF6F620F}.Release|x64.Build.0 = Release|x64 {016C739D-6389-43BF-8D88-24B2BF6F620F}.ReleaseDLL_fixed|Win32.ActiveCfg = ReleaseDLL_fixed|Win32 {016C739D-6389-43BF-8D88-24B2BF6F620F}.ReleaseDLL_fixed|Win32.Build.0 = ReleaseDLL_fixed|Win32 {016C739D-6389-43BF-8D88-24B2BF6F620F}.ReleaseDLL_fixed|x64.ActiveCfg = ReleaseDLL_fixed|x64 {016C739D-6389-43BF-8D88-24B2BF6F620F}.ReleaseDLL_fixed|x64.Build.0 = ReleaseDLL_fixed|x64 {016C739D-6389-43BF-8D88-24B2BF6F620F}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 {016C739D-6389-43BF-8D88-24B2BF6F620F}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 {016C739D-6389-43BF-8D88-24B2BF6F620F}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 {016C739D-6389-43BF-8D88-24B2BF6F620F}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 {1D257A17-D254-42E5-82D6-1C87A6EC775A}.Debug|Win32.ActiveCfg = Debug|Win32 {1D257A17-D254-42E5-82D6-1C87A6EC775A}.Debug|Win32.Build.0 = Debug|Win32 {1D257A17-D254-42E5-82D6-1C87A6EC775A}.Debug|x64.ActiveCfg = Debug|x64 {1D257A17-D254-42E5-82D6-1C87A6EC775A}.Debug|x64.Build.0 = Debug|x64 {1D257A17-D254-42E5-82D6-1C87A6EC775A}.DebugDLL_fixed|Win32.ActiveCfg = DebugDLL_fixed|Win32 {1D257A17-D254-42E5-82D6-1C87A6EC775A}.DebugDLL_fixed|Win32.Build.0 = DebugDLL_fixed|Win32 {1D257A17-D254-42E5-82D6-1C87A6EC775A}.DebugDLL_fixed|x64.ActiveCfg = DebugDLL_fixed|x64 {1D257A17-D254-42E5-82D6-1C87A6EC775A}.DebugDLL_fixed|x64.Build.0 = DebugDLL_fixed|x64 {1D257A17-D254-42E5-82D6-1C87A6EC775A}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 {1D257A17-D254-42E5-82D6-1C87A6EC775A}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 {1D257A17-D254-42E5-82D6-1C87A6EC775A}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 {1D257A17-D254-42E5-82D6-1C87A6EC775A}.DebugDLL|x64.Build.0 = DebugDLL|x64 {1D257A17-D254-42E5-82D6-1C87A6EC775A}.Release|Win32.ActiveCfg = Release|Win32 {1D257A17-D254-42E5-82D6-1C87A6EC775A}.Release|Win32.Build.0 = Release|Win32 {1D257A17-D254-42E5-82D6-1C87A6EC775A}.Release|x64.ActiveCfg = Release|x64 {1D257A17-D254-42E5-82D6-1C87A6EC775A}.Release|x64.Build.0 = Release|x64 {1D257A17-D254-42E5-82D6-1C87A6EC775A}.ReleaseDLL_fixed|Win32.ActiveCfg = ReleaseDLL_fixed|Win32 {1D257A17-D254-42E5-82D6-1C87A6EC775A}.ReleaseDLL_fixed|Win32.Build.0 = ReleaseDLL_fixed|Win32 {1D257A17-D254-42E5-82D6-1C87A6EC775A}.ReleaseDLL_fixed|x64.ActiveCfg = ReleaseDLL_fixed|x64 {1D257A17-D254-42E5-82D6-1C87A6EC775A}.ReleaseDLL_fixed|x64.Build.0 = ReleaseDLL_fixed|x64 {1D257A17-D254-42E5-82D6-1C87A6EC775A}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 {1D257A17-D254-42E5-82D6-1C87A6EC775A}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 {1D257A17-D254-42E5-82D6-1C87A6EC775A}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 {1D257A17-D254-42E5-82D6-1C87A6EC775A}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 {8578322A-1883-486B-B6FA-E0094B65C9F2}.Debug|Win32.ActiveCfg = Debug|Win32 {8578322A-1883-486B-B6FA-E0094B65C9F2}.Debug|Win32.Build.0 = Debug|Win32 {8578322A-1883-486B-B6FA-E0094B65C9F2}.Debug|x64.ActiveCfg = Debug|x64 {8578322A-1883-486B-B6FA-E0094B65C9F2}.Debug|x64.Build.0 = Debug|x64 {8578322A-1883-486B-B6FA-E0094B65C9F2}.DebugDLL_fixed|Win32.ActiveCfg = DebugDLL_fixed|Win32 {8578322A-1883-486B-B6FA-E0094B65C9F2}.DebugDLL_fixed|Win32.Build.0 = DebugDLL_fixed|Win32 {8578322A-1883-486B-B6FA-E0094B65C9F2}.DebugDLL_fixed|x64.ActiveCfg = DebugDLL_fixed|x64 {8578322A-1883-486B-B6FA-E0094B65C9F2}.DebugDLL_fixed|x64.Build.0 = DebugDLL_fixed|x64 {8578322A-1883-486B-B6FA-E0094B65C9F2}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 {8578322A-1883-486B-B6FA-E0094B65C9F2}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 {8578322A-1883-486B-B6FA-E0094B65C9F2}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 {8578322A-1883-486B-B6FA-E0094B65C9F2}.DebugDLL|x64.Build.0 = DebugDLL|x64 {8578322A-1883-486B-B6FA-E0094B65C9F2}.Release|Win32.ActiveCfg = Release|Win32 {8578322A-1883-486B-B6FA-E0094B65C9F2}.Release|Win32.Build.0 = Release|Win32 {8578322A-1883-486B-B6FA-E0094B65C9F2}.Release|x64.ActiveCfg = Release|x64 {8578322A-1883-486B-B6FA-E0094B65C9F2}.Release|x64.Build.0 = Release|x64 {8578322A-1883-486B-B6FA-E0094B65C9F2}.ReleaseDLL_fixed|Win32.ActiveCfg = ReleaseDLL_fixed|Win32 {8578322A-1883-486B-B6FA-E0094B65C9F2}.ReleaseDLL_fixed|Win32.Build.0 = ReleaseDLL_fixed|Win32 {8578322A-1883-486B-B6FA-E0094B65C9F2}.ReleaseDLL_fixed|x64.ActiveCfg = ReleaseDLL_fixed|x64 {8578322A-1883-486B-B6FA-E0094B65C9F2}.ReleaseDLL_fixed|x64.Build.0 = ReleaseDLL_fixed|x64 {8578322A-1883-486B-B6FA-E0094B65C9F2}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 {8578322A-1883-486B-B6FA-E0094B65C9F2}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 {8578322A-1883-486B-B6FA-E0094B65C9F2}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 {8578322A-1883-486B-B6FA-E0094B65C9F2}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 {84DAA768-1A38-4312-BB61-4C78BB59E5B8}.Debug|Win32.ActiveCfg = Debug|Win32 {84DAA768-1A38-4312-BB61-4C78BB59E5B8}.Debug|Win32.Build.0 = Debug|Win32 {84DAA768-1A38-4312-BB61-4C78BB59E5B8}.Debug|x64.ActiveCfg = Debug|x64 {84DAA768-1A38-4312-BB61-4C78BB59E5B8}.Debug|x64.Build.0 = Debug|x64 {84DAA768-1A38-4312-BB61-4C78BB59E5B8}.DebugDLL_fixed|Win32.ActiveCfg = DebugDLL_fixed|Win32 {84DAA768-1A38-4312-BB61-4C78BB59E5B8}.DebugDLL_fixed|Win32.Build.0 = DebugDLL_fixed|Win32 {84DAA768-1A38-4312-BB61-4C78BB59E5B8}.DebugDLL_fixed|x64.ActiveCfg = DebugDLL_fixed|x64 {84DAA768-1A38-4312-BB61-4C78BB59E5B8}.DebugDLL_fixed|x64.Build.0 = DebugDLL_fixed|x64 {84DAA768-1A38-4312-BB61-4C78BB59E5B8}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 {84DAA768-1A38-4312-BB61-4C78BB59E5B8}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 {84DAA768-1A38-4312-BB61-4C78BB59E5B8}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 {84DAA768-1A38-4312-BB61-4C78BB59E5B8}.DebugDLL|x64.Build.0 = DebugDLL|x64 {84DAA768-1A38-4312-BB61-4C78BB59E5B8}.Release|Win32.ActiveCfg = Release|Win32 {84DAA768-1A38-4312-BB61-4C78BB59E5B8}.Release|Win32.Build.0 = Release|Win32 {84DAA768-1A38-4312-BB61-4C78BB59E5B8}.Release|x64.ActiveCfg = Release|x64 {84DAA768-1A38-4312-BB61-4C78BB59E5B8}.Release|x64.Build.0 = Release|x64 {84DAA768-1A38-4312-BB61-4C78BB59E5B8}.ReleaseDLL_fixed|Win32.ActiveCfg = ReleaseDLL_fixed|Win32 {84DAA768-1A38-4312-BB61-4C78BB59E5B8}.ReleaseDLL_fixed|Win32.Build.0 = ReleaseDLL_fixed|Win32 {84DAA768-1A38-4312-BB61-4C78BB59E5B8}.ReleaseDLL_fixed|x64.ActiveCfg = ReleaseDLL_fixed|x64 {84DAA768-1A38-4312-BB61-4C78BB59E5B8}.ReleaseDLL_fixed|x64.Build.0 = ReleaseDLL_fixed|x64 {84DAA768-1A38-4312-BB61-4C78BB59E5B8}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 {84DAA768-1A38-4312-BB61-4C78BB59E5B8}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 {84DAA768-1A38-4312-BB61-4C78BB59E5B8}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 {84DAA768-1A38-4312-BB61-4C78BB59E5B8}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal jamulus-3.9.1+dfsg/libs/opus/win32/VS2015/common.props0000644000175000017500000001055114340334543021254 0ustar vimervimer $(Platform)\$(Configuration)\ $(Platform)\$(Configuration)\$(ProjectName)\ Unicode true true false false false true Level3 false false ..\..;..\..\include;..\..\silk;..\..\celt;..\..\win32;%(AdditionalIncludeDirectories) HAVE_CONFIG_H;WIN32;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) false false Console true Console Guard ProgramDatabase NoExtensions false true false Disabled false false Disabled MultiThreadedDebug MultiThreadedDebugDLL true false true false None true true false Speed Fast Precise true true true MaxSpeed MultiThreaded MultiThreadedDLL 16Bytes false jamulus-3.9.1+dfsg/libs/opus/win32/VS2015/opus_demo.vcxproj.filters0000644000175000017500000000170614340334543023757 0ustar vimervimer {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files jamulus-3.9.1+dfsg/libs/opus/win32/VS2015/test_opus_encode.vcxproj0000644000175000017500000002324414340334543023661 0ustar vimervimer DebugDLL_fixed Win32 DebugDLL_fixed x64 DebugDLL Win32 DebugDLL x64 Debug Win32 Debug x64 ReleaseDLL_fixed Win32 ReleaseDLL_fixed x64 ReleaseDLL Win32 ReleaseDLL x64 Release Win32 Release x64 {219ec965-228a-1824-174d-96449d05f88a} {84DAA768-1A38-4312-BB61-4C78BB59E5B8} Win32Proj test_opus_api Application v140 Application v140 Application v140 Application v140 Application v140 Application v140 Application v140 Application v140 Application v140 Application v140 Application v140 Application v140 jamulus-3.9.1+dfsg/libs/opus/win32/VS2015/test_opus_decode.vcxproj0000644000175000017500000002314114340334543023643 0ustar vimervimer DebugDLL_fixed Win32 DebugDLL_fixed x64 DebugDLL Win32 DebugDLL x64 Debug Win32 Debug x64 ReleaseDLL_fixed Win32 ReleaseDLL_fixed x64 ReleaseDLL Win32 ReleaseDLL x64 Release Win32 Release x64 {219ec965-228a-1824-174d-96449d05f88a} {8578322A-1883-486B-B6FA-E0094B65C9F2} Win32Proj test_opus_api Application v140 Application v140 Application v140 Application v140 Application v140 Application v140 Application v140 Application v140 Application v140 Application v140 Application v140 Application v140 jamulus-3.9.1+dfsg/libs/opus/win32/VS2015/test_opus_encode.vcxproj.filters0000644000175000017500000000120714340334543025323 0ustar vimervimer {546c8d9a-103e-4f78-972b-b44e8d3c8aba} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx Source Files Source Files jamulus-3.9.1+dfsg/libs/opus/win32/VS2015/opus.vcxproj0000644000175000017500000005300714340334543021305 0ustar vimervimer DebugDLL_fixed Win32 DebugDLL_fixed x64 DebugDLL Win32 DebugDLL x64 Debug Win32 Debug x64 ReleaseDLL_fixed Win32 ReleaseDLL_fixed x64 ReleaseDLL Win32 ReleaseDLL x64 Release Win32 Release x64 Win32Proj opus {219EC965-228A-1824-174D-96449D05F88A} StaticLibrary v140 DynamicLibrary v140 DynamicLibrary v140 StaticLibrary v140 DynamicLibrary v140 DynamicLibrary v140 StaticLibrary v140 DynamicLibrary v140 DynamicLibrary v140 StaticLibrary v140 DynamicLibrary v140 DynamicLibrary v140 ..\..\silk\fixed;..\..\silk\float;%(AdditionalIncludeDirectories) DLL_EXPORT;%(PreprocessorDefinitions) FIXED_POINT;%(PreprocessorDefinitions) /arch:IA32 %(AdditionalOptions) /ignore:4221 %(AdditionalOptions) "$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION Generating version.h 4244;%(DisableSpecificWarnings) false false true true true false jamulus-3.9.1+dfsg/libs/opus/win32/VS2015/test_opus_decode.vcxproj.filters0000644000175000017500000000101714340334543025310 0ustar vimervimer {4a0dd677-931f-4728-afe5-b761149fc7eb} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx Source Files jamulus-3.9.1+dfsg/libs/opus/win32/VS2015/opus.vcxproj.filters0000644000175000017500000005111014340334543022745 0ustar vimervimer {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files jamulus-3.9.1+dfsg/libs/opus/win32/genversion.bat0000644000175000017500000000147214340334543020710 0ustar vimervimer@echo off setlocal enableextensions enabledelayedexpansion for /f %%v in ('cd "%~dp0.." ^&^& git status ^>NUL 2^>NUL ^&^& git describe --tags --match "v*" --dirty 2^>NUL') do set version=%%v if not "%version%"=="" set version=!version:~1! && goto :gotversion if exist "%~dp0..\package_version" goto :getversion echo Git cannot be found, nor can package_version. Generating unknown version. set version=unknown goto :gotversion :getversion for /f "delims== tokens=2" %%v in (%~dps0..\package_version) do set version=%%v set version=!version:"=! :gotversion set version=!version: =! set version_out=#define %~2 "%version%" echo %version_out%> "%~1_temp" echo n | comp "%~1_temp" "%~1" > NUL 2> NUL if not errorlevel 1 goto exit copy /y "%~1_temp" "%~1" :exit del "%~1_temp" jamulus-3.9.1+dfsg/libs/opus/celt_sources.mk0000644000175000017500000000156714340334543020127 0ustar vimervimerCELT_SOURCES = \ celt/bands.c \ celt/celt.c \ celt/celt_encoder.c \ celt/celt_decoder.c \ celt/cwrs.c \ celt/entcode.c \ celt/entdec.c \ celt/entenc.c \ celt/kiss_fft.c \ celt/laplace.c \ celt/mathops.c \ celt/mdct.c \ celt/modes.c \ celt/pitch.c \ celt/celt_lpc.c \ celt/quant_bands.c \ celt/rate.c \ celt/vq.c CELT_SOURCES_SSE = \ celt/x86/x86cpu.c \ celt/x86/x86_celt_map.c \ celt/x86/pitch_sse.c CELT_SOURCES_SSE2 = \ celt/x86/pitch_sse2.c \ celt/x86/vq_sse2.c CELT_SOURCES_SSE4_1 = \ celt/x86/celt_lpc_sse4_1.c \ celt/x86/pitch_sse4_1.c CELT_SOURCES_ARM = \ celt/arm/armcpu.c \ celt/arm/arm_celt_map.c CELT_SOURCES_ARM_ASM = \ celt/arm/celt_pitch_xcorr_arm.s CELT_AM_SOURCES_ARM_ASM = \ celt/arm/armopts.s.in CELT_SOURCES_ARM_NEON_INTR = \ celt/arm/celt_neon_intr.c \ celt/arm/pitch_neon_intr.c CELT_SOURCES_ARM_NE10 = \ celt/arm/celt_fft_ne10.c \ celt/arm/celt_mdct_ne10.c jamulus-3.9.1+dfsg/libs/opus/Makefile.am0000644000175000017500000002666414340334543017145 0ustar vimervimer# Provide the full test output for failed tests when using the parallel # test suite (which is enabled by default with automake 1.13+). export VERBOSE = yes AUTOMAKE_OPTIONS = subdir-objects ACLOCAL_AMFLAGS = -I m4 lib_LTLIBRARIES = libopus.la DIST_SUBDIRS = doc AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/celt -I$(top_srcdir)/silk \ -I$(top_srcdir)/silk/float -I$(top_srcdir)/silk/fixed $(NE10_CFLAGS) include celt_sources.mk include silk_sources.mk include opus_sources.mk if FIXED_POINT SILK_SOURCES += $(SILK_SOURCES_FIXED) if HAVE_SSE4_1 SILK_SOURCES += $(SILK_SOURCES_SSE4_1) $(SILK_SOURCES_FIXED_SSE4_1) endif if HAVE_ARM_NEON_INTR SILK_SOURCES += $(SILK_SOURCES_FIXED_ARM_NEON_INTR) endif else SILK_SOURCES += $(SILK_SOURCES_FLOAT) if HAVE_SSE4_1 SILK_SOURCES += $(SILK_SOURCES_SSE4_1) endif endif if DISABLE_FLOAT_API else OPUS_SOURCES += $(OPUS_SOURCES_FLOAT) endif if HAVE_SSE CELT_SOURCES += $(CELT_SOURCES_SSE) endif if HAVE_SSE2 CELT_SOURCES += $(CELT_SOURCES_SSE2) endif if HAVE_SSE4_1 CELT_SOURCES += $(CELT_SOURCES_SSE4_1) endif if CPU_ARM CELT_SOURCES += $(CELT_SOURCES_ARM) SILK_SOURCES += $(SILK_SOURCES_ARM) if HAVE_ARM_NEON_INTR CELT_SOURCES += $(CELT_SOURCES_ARM_NEON_INTR) SILK_SOURCES += $(SILK_SOURCES_ARM_NEON_INTR) endif if HAVE_ARM_NE10 CELT_SOURCES += $(CELT_SOURCES_ARM_NE10) endif if OPUS_ARM_EXTERNAL_ASM noinst_LTLIBRARIES = libarmasm.la libarmasm_la_SOURCES = $(CELT_SOURCES_ARM_ASM:.s=-gnu.S) BUILT_SOURCES = $(CELT_SOURCES_ARM_ASM:.s=-gnu.S) \ $(CELT_AM_SOURCES_ARM_ASM:.s.in=.s) \ $(CELT_AM_SOURCES_ARM_ASM:.s.in=-gnu.S) endif endif CLEANFILES = $(CELT_SOURCES_ARM_ASM:.s=-gnu.S) \ $(CELT_AM_SOURCES_ARM_ASM:.s.in=-gnu.S) include celt_headers.mk include silk_headers.mk include opus_headers.mk libopus_la_SOURCES = $(CELT_SOURCES) $(SILK_SOURCES) $(OPUS_SOURCES) libopus_la_LDFLAGS = -no-undefined -version-info @OPUS_LT_CURRENT@:@OPUS_LT_REVISION@:@OPUS_LT_AGE@ libopus_la_LIBADD = $(NE10_LIBS) $(LIBM) if OPUS_ARM_EXTERNAL_ASM libopus_la_LIBADD += libarmasm.la endif pkginclude_HEADERS = include/opus.h include/opus_multistream.h include/opus_types.h include/opus_defines.h include/opus_projection.h noinst_HEADERS = $(OPUS_HEAD) $(SILK_HEAD) $(CELT_HEAD) if EXTRA_PROGRAMS noinst_PROGRAMS = celt/tests/test_unit_cwrs32 \ celt/tests/test_unit_dft \ celt/tests/test_unit_entropy \ celt/tests/test_unit_laplace \ celt/tests/test_unit_mathops \ celt/tests/test_unit_mdct \ celt/tests/test_unit_rotation \ celt/tests/test_unit_types \ opus_compare \ opus_demo \ repacketizer_demo \ silk/tests/test_unit_LPC_inv_pred_gain \ tests/test_opus_api \ tests/test_opus_decode \ tests/test_opus_encode \ tests/test_opus_padding \ tests/test_opus_projection TESTS = celt/tests/test_unit_cwrs32 \ celt/tests/test_unit_dft \ celt/tests/test_unit_entropy \ celt/tests/test_unit_laplace \ celt/tests/test_unit_mathops \ celt/tests/test_unit_mdct \ celt/tests/test_unit_rotation \ celt/tests/test_unit_types \ silk/tests/test_unit_LPC_inv_pred_gain \ tests/test_opus_api \ tests/test_opus_decode \ tests/test_opus_encode \ tests/test_opus_padding \ tests/test_opus_projection opus_demo_SOURCES = src/opus_demo.c opus_demo_LDADD = libopus.la $(NE10_LIBS) $(LIBM) repacketizer_demo_SOURCES = src/repacketizer_demo.c repacketizer_demo_LDADD = libopus.la $(NE10_LIBS) $(LIBM) opus_compare_SOURCES = src/opus_compare.c opus_compare_LDADD = $(LIBM) tests_test_opus_api_SOURCES = tests/test_opus_api.c tests/test_opus_common.h tests_test_opus_api_LDADD = libopus.la $(NE10_LIBS) $(LIBM) tests_test_opus_encode_SOURCES = tests/test_opus_encode.c tests/opus_encode_regressions.c tests/test_opus_common.h tests_test_opus_encode_LDADD = libopus.la $(NE10_LIBS) $(LIBM) tests_test_opus_decode_SOURCES = tests/test_opus_decode.c tests/test_opus_common.h tests_test_opus_decode_LDADD = libopus.la $(NE10_LIBS) $(LIBM) tests_test_opus_padding_SOURCES = tests/test_opus_padding.c tests/test_opus_common.h tests_test_opus_padding_LDADD = libopus.la $(NE10_LIBS) $(LIBM) CELT_OBJ = $(CELT_SOURCES:.c=.lo) SILK_OBJ = $(SILK_SOURCES:.c=.lo) OPUS_OBJ = $(OPUS_SOURCES:.c=.lo) tests_test_opus_projection_SOURCES = tests/test_opus_projection.c tests/test_opus_common.h tests_test_opus_projection_LDADD = $(OPUS_OBJ) $(SILK_OBJ) $(CELT_OBJ) $(NE10_LIBS) $(LIBM) if OPUS_ARM_EXTERNAL_ASM tests_test_opus_projection_LDADD += libarmasm.la endif silk_tests_test_unit_LPC_inv_pred_gain_SOURCES = silk/tests/test_unit_LPC_inv_pred_gain.c silk_tests_test_unit_LPC_inv_pred_gain_LDADD = $(SILK_OBJ) $(CELT_OBJ) $(NE10_LIBS) $(LIBM) if OPUS_ARM_EXTERNAL_ASM silk_tests_test_unit_LPC_inv_pred_gain_LDADD += libarmasm.la endif celt_tests_test_unit_cwrs32_SOURCES = celt/tests/test_unit_cwrs32.c celt_tests_test_unit_cwrs32_LDADD = $(LIBM) celt_tests_test_unit_dft_SOURCES = celt/tests/test_unit_dft.c celt_tests_test_unit_dft_LDADD = $(CELT_OBJ) $(NE10_LIBS) $(LIBM) if OPUS_ARM_EXTERNAL_ASM celt_tests_test_unit_dft_LDADD += libarmasm.la endif celt_tests_test_unit_entropy_SOURCES = celt/tests/test_unit_entropy.c celt_tests_test_unit_entropy_LDADD = $(LIBM) celt_tests_test_unit_laplace_SOURCES = celt/tests/test_unit_laplace.c celt_tests_test_unit_laplace_LDADD = $(LIBM) celt_tests_test_unit_mathops_SOURCES = celt/tests/test_unit_mathops.c celt_tests_test_unit_mathops_LDADD = $(CELT_OBJ) $(NE10_LIBS) $(LIBM) if OPUS_ARM_EXTERNAL_ASM celt_tests_test_unit_mathops_LDADD += libarmasm.la endif celt_tests_test_unit_mdct_SOURCES = celt/tests/test_unit_mdct.c celt_tests_test_unit_mdct_LDADD = $(CELT_OBJ) $(NE10_LIBS) $(LIBM) if OPUS_ARM_EXTERNAL_ASM celt_tests_test_unit_mdct_LDADD += libarmasm.la endif celt_tests_test_unit_rotation_SOURCES = celt/tests/test_unit_rotation.c celt_tests_test_unit_rotation_LDADD = $(CELT_OBJ) $(NE10_LIBS) $(LIBM) if OPUS_ARM_EXTERNAL_ASM celt_tests_test_unit_rotation_LDADD += libarmasm.la endif celt_tests_test_unit_types_SOURCES = celt/tests/test_unit_types.c celt_tests_test_unit_types_LDADD = $(LIBM) endif if CUSTOM_MODES pkginclude_HEADERS += include/opus_custom.h if EXTRA_PROGRAMS noinst_PROGRAMS += opus_custom_demo opus_custom_demo_SOURCES = celt/opus_custom_demo.c opus_custom_demo_LDADD = libopus.la $(LIBM) endif endif EXTRA_DIST = opus.pc.in \ opus-uninstalled.pc.in \ opus.m4 \ Makefile.mips \ Makefile.unix \ CMakeLists.txt \ config.h.cmake.in \ opus_config.cmake \ opus_functions.cmake \ opus_sources.cmake \ OpusConfig.cmake.in \ tests/run_vectors.sh \ celt/arm/arm2gnu.pl \ celt/arm/celt_pitch_xcorr_arm.s \ win32/VS2015/opus.vcxproj \ win32/VS2015/test_opus_encode.vcxproj.filters \ win32/VS2015/test_opus_encode.vcxproj \ win32/VS2015/opus_demo.vcxproj \ win32/VS2015/test_opus_api.vcxproj.filters \ win32/VS2015/test_opus_api.vcxproj \ win32/VS2015/test_opus_decode.vcxproj.filters \ win32/VS2015/opus_demo.vcxproj.filters \ win32/VS2015/opus.vcxproj.filters \ win32/VS2015/test_opus_decode.vcxproj \ win32/VS2015/opus.sln \ win32/VS2015/common.props \ win32/genversion.bat \ win32/config.h pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = opus.pc m4datadir = $(datadir)/aclocal m4data_DATA = opus.m4 # Targets to build and install just the library without the docs opus check-opus install-opus: export NO_DOXYGEN = 1 opus: all check-opus: check install-opus: install # Or just the docs docs: ( cd doc && $(MAKE) $(AM_MAKEFLAGS) ) install-docs: ( cd doc && $(MAKE) $(AM_MAKEFLAGS) install ) # Or everything (by default) all-local: @[ -n "$(NO_DOXYGEN)" ] || ( cd doc && $(MAKE) $(AM_MAKEFLAGS) ) install-data-local: @[ -n "$(NO_DOXYGEN)" ] || ( cd doc && $(MAKE) $(AM_MAKEFLAGS) install ) clean-local: -( cd doc && $(MAKE) $(AM_MAKEFLAGS) clean ) uninstall-local: ( cd doc && $(MAKE) $(AM_MAKEFLAGS) uninstall ) # We check this every time make is run, with configure.ac being touched to # trigger an update of the build system files if update_version changes the # current PACKAGE_VERSION (or if package_version was modified manually by a # user with either AUTO_UPDATE=no or no update_version script present - the # latter being the normal case for tarball releases). # # We can't just add the package_version file to CONFIGURE_DEPENDENCIES since # simply running autoconf will not actually regenerate configure for us when # the content of that file changes (due to autoconf dependency checking not # knowing about that without us creating yet another file for it to include). # # The MAKECMDGOALS check is a gnu-make'ism, but will degrade 'gracefully' for # makes that don't support it. The only loss of functionality is not forcing # an update of package_version for `make dist` if AUTO_UPDATE=no, but that is # unlikely to be a real problem for any real user. $(top_srcdir)/configure.ac: force @case "$(MAKECMDGOALS)" in \ dist-hook) exit 0 ;; \ dist-* | dist | distcheck | distclean) _arg=release ;; \ esac; \ if ! $(top_srcdir)/update_version $$_arg 2> /dev/null; then \ if [ ! -e $(top_srcdir)/package_version ]; then \ echo 'PACKAGE_VERSION="unknown"' > $(top_srcdir)/package_version; \ fi; \ . $(top_srcdir)/package_version || exit 1; \ [ "$(PACKAGE_VERSION)" != "$$PACKAGE_VERSION" ] || exit 0; \ fi; \ touch $@ force: # Create a minimal package_version file when make dist is run. dist-hook: echo 'PACKAGE_VERSION="$(PACKAGE_VERSION)"' > $(top_distdir)/package_version .PHONY: opus check-opus install-opus docs install-docs # automake doesn't do dependency tracking for asm files, that I can tell $(CELT_SOURCES_ARM_ASM:%.s=%-gnu.S): celt/arm/armopts-gnu.S $(CELT_SOURCES_ARM_ASM:%.s=%-gnu.S): $(top_srcdir)/celt/arm/arm2gnu.pl # convert ARM asm to GNU as format %-gnu.S: $(top_srcdir)/%.s $(top_srcdir)/celt/arm/arm2gnu.pl @ARM2GNU_PARAMS@ < $< > $@ # For autoconf-modified sources (e.g., armopts.s) %-gnu.S: %.s $(top_srcdir)/celt/arm/arm2gnu.pl @ARM2GNU_PARAMS@ < $< > $@ OPT_UNIT_TEST_OBJ = $(celt_tests_test_unit_mathops_SOURCES:.c=.o) \ $(celt_tests_test_unit_rotation_SOURCES:.c=.o) \ $(celt_tests_test_unit_mdct_SOURCES:.c=.o) \ $(celt_tests_test_unit_dft_SOURCES:.c=.o) \ $(silk_tests_test_unit_LPC_inv_pred_gain_SOURCES:.c=.o) if HAVE_SSE SSE_OBJ = $(CELT_SOURCES_SSE:.c=.lo) $(SSE_OBJ): CFLAGS += $(OPUS_X86_SSE_CFLAGS) endif if HAVE_SSE2 SSE2_OBJ = $(CELT_SOURCES_SSE2:.c=.lo) $(SSE2_OBJ): CFLAGS += $(OPUS_X86_SSE2_CFLAGS) endif if HAVE_SSE4_1 SSE4_1_OBJ = $(CELT_SOURCES_SSE4_1:.c=.lo) \ $(SILK_SOURCES_SSE4_1:.c=.lo) \ $(SILK_SOURCES_FIXED_SSE4_1:.c=.lo) $(SSE4_1_OBJ): CFLAGS += $(OPUS_X86_SSE4_1_CFLAGS) endif if HAVE_ARM_NEON_INTR ARM_NEON_INTR_OBJ = $(CELT_SOURCES_ARM_NEON_INTR:.c=.lo) \ $(SILK_SOURCES_ARM_NEON_INTR:.c=.lo) \ $(SILK_SOURCES_FIXED_ARM_NEON_INTR:.c=.lo) $(ARM_NEON_INTR_OBJ): CFLAGS += \ $(OPUS_ARM_NEON_INTR_CFLAGS) $(NE10_CFLAGS) endif jamulus-3.9.1+dfsg/libs/opus/ltmain.sh0000755000175000017500000117077114340334543016734 0ustar vimervimer#! /bin/sh ## DO NOT EDIT - This file generated from ./build-aux/ltmain.in ## by inline-source v2014-01-03.01 # libtool (GNU libtool) 2.4.6 # Provide generalized library-building support services. # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996-2015 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . PROGRAM=libtool PACKAGE=libtool VERSION=2.4.6 package_revision=2.4.6 ## ------ ## ## Usage. ## ## ------ ## # Run './libtool --help' for help with using this script from the # command line. ## ------------------------------- ## ## User overridable command paths. ## ## ------------------------------- ## # After configure completes, it has a better idea of some of the # shell tools we need than the defaults used by the functions shared # with bootstrap, so set those here where they can still be over- # ridden by the user, but otherwise take precedence. : ${AUTOCONF="autoconf"} : ${AUTOMAKE="automake"} ## -------------------------- ## ## Source external libraries. ## ## -------------------------- ## # Much of our low-level functionality needs to be sourced from external # libraries, which are installed to $pkgauxdir. # Set a version string for this script. scriptversion=2015-01-20.17; # UTC # General shell script boiler plate, and helper functions. # Written by Gary V. Vaughan, 2004 # Copyright (C) 2004-2015 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # As a special exception to the GNU General Public License, if you distribute # this file as part of a program or library that is built using GNU Libtool, # you may include this file under the same distribution terms that you use # for the rest of that program. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Please report bugs or propose patches to gary@gnu.org. ## ------ ## ## Usage. ## ## ------ ## # Evaluate this file near the top of your script to gain access to # the functions and variables defined here: # # . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh # # If you need to override any of the default environment variable # settings, do that before evaluating this file. ## -------------------- ## ## Shell normalisation. ## ## -------------------- ## # Some shells need a little help to be as Bourne compatible as possible. # Before doing anything else, make sure all that help has been provided! DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # NLS nuisances: We save the old values in case they are required later. _G_user_locale= _G_safe_locale= for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test set = \"\${$_G_var+set}\"; then save_$_G_var=\$$_G_var $_G_var=C export $_G_var _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\" _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" fi" done # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Make sure IFS has a sensible default sp=' ' nl=' ' IFS="$sp $nl" # There are apparently some retarded systems that use ';' as a PATH separator! if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi ## ------------------------- ## ## Locate command utilities. ## ## ------------------------- ## # func_executable_p FILE # ---------------------- # Check that FILE is an executable regular file. func_executable_p () { test -f "$1" && test -x "$1" } # func_path_progs PROGS_LIST CHECK_FUNC [PATH] # -------------------------------------------- # Search for either a program that responds to --version with output # containing "GNU", or else returned by CHECK_FUNC otherwise, by # trying all the directories in PATH with each of the elements of # PROGS_LIST. # # CHECK_FUNC should accept the path to a candidate program, and # set $func_check_prog_result if it truncates its output less than # $_G_path_prog_max characters. func_path_progs () { _G_progs_list=$1 _G_check_func=$2 _G_PATH=${3-"$PATH"} _G_path_prog_max=0 _G_path_prog_found=false _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:} for _G_dir in $_G_PATH; do IFS=$_G_save_IFS test -z "$_G_dir" && _G_dir=. for _G_prog_name in $_G_progs_list; do for _exeext in '' .EXE; do _G_path_prog=$_G_dir/$_G_prog_name$_exeext func_executable_p "$_G_path_prog" || continue case `"$_G_path_prog" --version 2>&1` in *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;; *) $_G_check_func $_G_path_prog func_path_progs_result=$func_check_prog_result ;; esac $_G_path_prog_found && break 3 done done done IFS=$_G_save_IFS test -z "$func_path_progs_result" && { echo "no acceptable sed could be found in \$PATH" >&2 exit 1 } } # We want to be able to use the functions in this file before configure # has figured out where the best binaries are kept, which means we have # to search for them ourselves - except when the results are already set # where we skip the searches. # Unless the user overrides by setting SED, search the path for either GNU # sed, or the sed that truncates its output the least. test -z "$SED" && { _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for _G_i in 1 2 3 4 5 6 7; do _G_sed_script=$_G_sed_script$nl$_G_sed_script done echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed _G_sed_script= func_check_prog_sed () { _G_path_prog=$1 _G_count=0 printf 0123456789 >conftest.in while : do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo '' >> conftest.nl "$_G_path_prog" -f conftest.sed conftest.out 2>/dev/null || break diff conftest.out conftest.nl >/dev/null 2>&1 || break _G_count=`expr $_G_count + 1` if test "$_G_count" -gt "$_G_path_prog_max"; then # Best one so far, save it but keep looking for a better one func_check_prog_result=$_G_path_prog _G_path_prog_max=$_G_count fi # 10*(2^10) chars as input seems more than enough test 10 -lt "$_G_count" && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out } func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin rm -f conftest.sed SED=$func_path_progs_result } # Unless the user overrides by setting GREP, search the path for either GNU # grep, or the grep that truncates its output the least. test -z "$GREP" && { func_check_prog_grep () { _G_path_prog=$1 _G_count=0 _G_path_prog_max=0 printf 0123456789 >conftest.in while : do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo 'GREP' >> conftest.nl "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' conftest.out 2>/dev/null || break diff conftest.out conftest.nl >/dev/null 2>&1 || break _G_count=`expr $_G_count + 1` if test "$_G_count" -gt "$_G_path_prog_max"; then # Best one so far, save it but keep looking for a better one func_check_prog_result=$_G_path_prog _G_path_prog_max=$_G_count fi # 10*(2^10) chars as input seems more than enough test 10 -lt "$_G_count" && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out } func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin GREP=$func_path_progs_result } ## ------------------------------- ## ## User overridable command paths. ## ## ------------------------------- ## # All uppercase variable names are used for environment variables. These # variables can be overridden by the user before calling a script that # uses them if a suitable command of that name is not already available # in the command search PATH. : ${CP="cp -f"} : ${ECHO="printf %s\n"} : ${EGREP="$GREP -E"} : ${FGREP="$GREP -F"} : ${LN_S="ln -s"} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} ## -------------------- ## ## Useful sed snippets. ## ## -------------------- ## sed_dirname='s|/[^/]*$||' sed_basename='s|^.*/||' # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='s|\([`"$\\]\)|\\\1|g' # Same as above, but do not quote variable references. sed_double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution that turns a string into a regex matching for the # string literally. sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g' # Sed substitution that converts a w32 file name or path # that contains forward slashes, into one that contains # (escaped) backslashes. A very naive implementation. sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' # Re-'\' parameter expansions in output of sed_double_quote_subst that # were '\'-ed in input to the same. If an odd number of '\' preceded a # '$' in input to sed_double_quote_subst, that '$' was protected from # expansion. Since each input '\' is now two '\'s, look for any number # of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'. _G_bs='\\' _G_bs2='\\\\' _G_bs4='\\\\\\\\' _G_dollar='\$' sed_double_backslash="\ s/$_G_bs4/&\\ /g s/^$_G_bs2$_G_dollar/$_G_bs&/ s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g s/\n//g" ## ----------------- ## ## Global variables. ## ## ----------------- ## # Except for the global variables explicitly listed below, the following # functions in the '^func_' namespace, and the '^require_' namespace # variables initialised in the 'Resource management' section, sourcing # this file will not pollute your global namespace with anything # else. There's no portable way to scope variables in Bourne shell # though, so actually running these functions will sometimes place # results into a variable named after the function, and often use # temporary variables in the '^_G_' namespace. If you are careful to # avoid using those namespaces casually in your sourcing script, things # should continue to work as you expect. And, of course, you can freely # overwrite any of the functions or variables defined here before # calling anything to customize them. EXIT_SUCCESS=0 EXIT_FAILURE=1 EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. # Allow overriding, eg assuming that you follow the convention of # putting '$debug_cmd' at the start of all your functions, you can get # bash to show function call trace with: # # debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name debug_cmd=${debug_cmd-":"} exit_cmd=: # By convention, finish your script with: # # exit $exit_status # # so that you can set exit_status to non-zero if you want to indicate # something went wrong during execution without actually bailing out at # the point of failure. exit_status=$EXIT_SUCCESS # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath=$0 # The name of this program. progname=`$ECHO "$progpath" |$SED "$sed_basename"` # Make sure we have an absolute progpath for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) progdir=`$ECHO "$progpath" |$SED "$sed_dirname"` progdir=`cd "$progdir" && pwd` progpath=$progdir/$progname ;; *) _G_IFS=$IFS IFS=${PATH_SEPARATOR-:} for progdir in $PATH; do IFS=$_G_IFS test -x "$progdir/$progname" && break done IFS=$_G_IFS test -n "$progdir" || progdir=`pwd` progpath=$progdir/$progname ;; esac ## ----------------- ## ## Standard options. ## ## ----------------- ## # The following options affect the operation of the functions defined # below, and should be set appropriately depending on run-time para- # meters passed on the command line. opt_dry_run=false opt_quiet=false opt_verbose=false # Categories 'all' and 'none' are always available. Append any others # you will pass as the first argument to func_warning from your own # code. warning_categories= # By default, display warnings according to 'opt_warning_types'. Set # 'warning_func' to ':' to elide all warnings, or func_fatal_error to # treat the next displayed warning as a fatal error. warning_func=func_warn_and_continue # Set to 'all' to display all warnings, 'none' to suppress all # warnings, or a space delimited list of some subset of # 'warning_categories' to display only the listed warnings. opt_warning_types=all ## -------------------- ## ## Resource management. ## ## -------------------- ## # This section contains definitions for functions that each ensure a # particular resource (a file, or a non-empty configuration variable for # example) is available, and if appropriate to extract default values # from pertinent package files. Call them using their associated # 'require_*' variable to ensure that they are executed, at most, once. # # It's entirely deliberate that calling these functions can set # variables that don't obey the namespace limitations obeyed by the rest # of this file, in order that that they be as useful as possible to # callers. # require_term_colors # ------------------- # Allow display of bold text on terminals that support it. require_term_colors=func_require_term_colors func_require_term_colors () { $debug_cmd test -t 1 && { # COLORTERM and USE_ANSI_COLORS environment variables take # precedence, because most terminfo databases neglect to describe # whether color sequences are supported. test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"} if test 1 = "$USE_ANSI_COLORS"; then # Standard ANSI escape sequences tc_reset='' tc_bold=''; tc_standout='' tc_red=''; tc_green='' tc_blue=''; tc_cyan='' else # Otherwise trust the terminfo database after all. test -n "`tput sgr0 2>/dev/null`" && { tc_reset=`tput sgr0` test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold` tc_standout=$tc_bold test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso` test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1` test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2` test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4` test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5` } fi } require_term_colors=: } ## ----------------- ## ## Function library. ## ## ----------------- ## # This section contains a variety of useful functions to call in your # scripts. Take note of the portable wrappers for features provided by # some modern shells, which will fall back to slower equivalents on # less featureful shells. # func_append VAR VALUE # --------------------- # Append VALUE onto the existing contents of VAR. # We should try to minimise forks, especially on Windows where they are # unreasonably slow, so skip the feature probes when bash or zsh are # being used: if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then : ${_G_HAVE_ARITH_OP="yes"} : ${_G_HAVE_XSI_OPS="yes"} # The += operator was introduced in bash 3.1 case $BASH_VERSION in [12].* | 3.0 | 3.0*) ;; *) : ${_G_HAVE_PLUSEQ_OP="yes"} ;; esac fi # _G_HAVE_PLUSEQ_OP # Can be empty, in which case the shell is probed, "yes" if += is # useable or anything else if it does not work. test -z "$_G_HAVE_PLUSEQ_OP" \ && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \ && _G_HAVE_PLUSEQ_OP=yes if test yes = "$_G_HAVE_PLUSEQ_OP" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_append () { $debug_cmd eval "$1+=\$2" }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_append () { $debug_cmd eval "$1=\$$1\$2" } fi # func_append_quoted VAR VALUE # ---------------------------- # Quote VALUE and append to the end of shell variable VAR, separated # by a space. if test yes = "$_G_HAVE_PLUSEQ_OP"; then eval 'func_append_quoted () { $debug_cmd func_quote_for_eval "$2" eval "$1+=\\ \$func_quote_for_eval_result" }' else func_append_quoted () { $debug_cmd func_quote_for_eval "$2" eval "$1=\$$1\\ \$func_quote_for_eval_result" } fi # func_append_uniq VAR VALUE # -------------------------- # Append unique VALUE onto the existing contents of VAR, assuming # entries are delimited by the first character of VALUE. For example: # # func_append_uniq options " --another-option option-argument" # # will only append to $options if " --another-option option-argument " # is not already present somewhere in $options already (note spaces at # each end implied by leading space in second argument). func_append_uniq () { $debug_cmd eval _G_current_value='`$ECHO $'$1'`' _G_delim=`expr "$2" : '\(.\)'` case $_G_delim$_G_current_value$_G_delim in *"$2$_G_delim"*) ;; *) func_append "$@" ;; esac } # func_arith TERM... # ------------------ # Set func_arith_result to the result of evaluating TERMs. test -z "$_G_HAVE_ARITH_OP" \ && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \ && _G_HAVE_ARITH_OP=yes if test yes = "$_G_HAVE_ARITH_OP"; then eval 'func_arith () { $debug_cmd func_arith_result=$(( $* )) }' else func_arith () { $debug_cmd func_arith_result=`expr "$@"` } fi # func_basename FILE # ------------------ # Set func_basename_result to FILE with everything up to and including # the last / stripped. if test yes = "$_G_HAVE_XSI_OPS"; then # If this shell supports suffix pattern removal, then use it to avoid # forking. Hide the definitions single quotes in case the shell chokes # on unsupported syntax... _b='func_basename_result=${1##*/}' _d='case $1 in */*) func_dirname_result=${1%/*}$2 ;; * ) func_dirname_result=$3 ;; esac' else # ...otherwise fall back to using sed. _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`' _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"` if test "X$func_dirname_result" = "X$1"; then func_dirname_result=$3 else func_append func_dirname_result "$2" fi' fi eval 'func_basename () { $debug_cmd '"$_b"' }' # func_dirname FILE APPEND NONDIR_REPLACEMENT # ------------------------------------------- # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. eval 'func_dirname () { $debug_cmd '"$_d"' }' # func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT # -------------------------------------------------------- # Perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # For efficiency, we do not delegate to the functions above but instead # duplicate the functionality here. eval 'func_dirname_and_basename () { $debug_cmd '"$_b"' '"$_d"' }' # func_echo ARG... # ---------------- # Echo program name prefixed message. func_echo () { $debug_cmd _G_message=$* func_echo_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_IFS $ECHO "$progname: $_G_line" done IFS=$func_echo_IFS } # func_echo_all ARG... # -------------------- # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } # func_echo_infix_1 INFIX ARG... # ------------------------------ # Echo program name, followed by INFIX on the first line, with any # additional lines not showing INFIX. func_echo_infix_1 () { $debug_cmd $require_term_colors _G_infix=$1; shift _G_indent=$_G_infix _G_prefix="$progname: $_G_infix: " _G_message=$* # Strip color escape sequences before counting printable length for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan" do test -n "$_G_tc" && { _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"` _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"` } done _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes func_echo_infix_1_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_infix_1_IFS $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2 _G_prefix=$_G_indent done IFS=$func_echo_infix_1_IFS } # func_error ARG... # ----------------- # Echo program name prefixed message to standard error. func_error () { $debug_cmd $require_term_colors func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2 } # func_fatal_error ARG... # ----------------------- # Echo program name prefixed message to standard error, and exit. func_fatal_error () { $debug_cmd func_error "$*" exit $EXIT_FAILURE } # func_grep EXPRESSION FILENAME # ----------------------------- # Check whether EXPRESSION matches any line of FILENAME, without output. func_grep () { $debug_cmd $GREP "$1" "$2" >/dev/null 2>&1 } # func_len STRING # --------------- # Set func_len_result to the length of STRING. STRING may not # start with a hyphen. test -z "$_G_HAVE_XSI_OPS" \ && (eval 'x=a/b/c; test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ && _G_HAVE_XSI_OPS=yes if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_len () { $debug_cmd func_len_result=${#1} }' else func_len () { $debug_cmd func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` } fi # func_mkdir_p DIRECTORY-PATH # --------------------------- # Make sure the entire path to DIRECTORY-PATH is available. func_mkdir_p () { $debug_cmd _G_directory_path=$1 _G_dir_list= if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then # Protect directory names starting with '-' case $_G_directory_path in -*) _G_directory_path=./$_G_directory_path ;; esac # While some portion of DIR does not yet exist... while test ! -d "$_G_directory_path"; do # ...make a list in topmost first order. Use a colon delimited # list incase some portion of path contains whitespace. _G_dir_list=$_G_directory_path:$_G_dir_list # If the last portion added has no slash in it, the list is done case $_G_directory_path in */*) ;; *) break ;; esac # ...otherwise throw away the child directory and loop _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"` done _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'` func_mkdir_p_IFS=$IFS; IFS=: for _G_dir in $_G_dir_list; do IFS=$func_mkdir_p_IFS # mkdir can fail with a 'File exist' error if two processes # try to create one of the directories concurrently. Don't # stop in that case! $MKDIR "$_G_dir" 2>/dev/null || : done IFS=$func_mkdir_p_IFS # Bail out if we (or some other process) failed to create a directory. test -d "$_G_directory_path" || \ func_fatal_error "Failed to create '$1'" fi } # func_mktempdir [BASENAME] # ------------------------- # Make a temporary directory that won't clash with other running # libtool processes, and avoids race conditions if possible. If # given, BASENAME is the basename for that directory. func_mktempdir () { $debug_cmd _G_template=${TMPDIR-/tmp}/${1-$progname} if test : = "$opt_dry_run"; then # Return a directory name, but don't create it in dry-run mode _G_tmpdir=$_G_template-$$ else # If mktemp works, use that first and foremost _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null` if test ! -d "$_G_tmpdir"; then # Failing that, at least try and use $RANDOM to avoid a race _G_tmpdir=$_G_template-${RANDOM-0}$$ func_mktempdir_umask=`umask` umask 0077 $MKDIR "$_G_tmpdir" umask $func_mktempdir_umask fi # If we're not in dry-run mode, bomb out on failure test -d "$_G_tmpdir" || \ func_fatal_error "cannot create temporary directory '$_G_tmpdir'" fi $ECHO "$_G_tmpdir" } # func_normal_abspath PATH # ------------------------ # Remove doubled-up and trailing slashes, "." path components, # and cancel out any ".." path components in PATH after making # it an absolute path. func_normal_abspath () { $debug_cmd # These SED scripts presuppose an absolute path with a trailing slash. _G_pathcar='s|^/\([^/]*\).*$|\1|' _G_pathcdr='s|^/[^/]*||' _G_removedotparts=':dotsl s|/\./|/|g t dotsl s|/\.$|/|' _G_collapseslashes='s|/\{1,\}|/|g' _G_finalslash='s|/*$|/|' # Start from root dir and reassemble the path. func_normal_abspath_result= func_normal_abspath_tpath=$1 func_normal_abspath_altnamespace= case $func_normal_abspath_tpath in "") # Empty path, that just means $cwd. func_stripname '' '/' "`pwd`" func_normal_abspath_result=$func_stripname_result return ;; # The next three entries are used to spot a run of precisely # two leading slashes without using negated character classes; # we take advantage of case's first-match behaviour. ///*) # Unusual form of absolute path, do nothing. ;; //*) # Not necessarily an ordinary path; POSIX reserves leading '//' # and for example Cygwin uses it to access remote file shares # over CIFS/SMB, so we conserve a leading double slash if found. func_normal_abspath_altnamespace=/ ;; /*) # Absolute path, do nothing. ;; *) # Relative path, prepend $cwd. func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath ;; esac # Cancel out all the simple stuff to save iterations. We also want # the path to end with a slash for ease of parsing, so make sure # there is one (and only one) here. func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"` while :; do # Processed it all yet? if test / = "$func_normal_abspath_tpath"; then # If we ascended to the root using ".." the result may be empty now. if test -z "$func_normal_abspath_result"; then func_normal_abspath_result=/ fi break fi func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_pathcar"` func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_pathcdr"` # Figure out what to do with it case $func_normal_abspath_tcomponent in "") # Trailing empty path component, ignore it. ;; ..) # Parent dir; strip last assembled component from result. func_dirname "$func_normal_abspath_result" func_normal_abspath_result=$func_dirname_result ;; *) # Actual path component, append it. func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent" ;; esac done # Restore leading double-slash if one was found on entry. func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result } # func_notquiet ARG... # -------------------- # Echo program name prefixed message only when not in quiet mode. func_notquiet () { $debug_cmd $opt_quiet || func_echo ${1+"$@"} # A bug in bash halts the script if the last line of a function # fails when set -e is in force, so we need another command to # work around that: : } # func_relative_path SRCDIR DSTDIR # -------------------------------- # Set func_relative_path_result to the relative path from SRCDIR to DSTDIR. func_relative_path () { $debug_cmd func_relative_path_result= func_normal_abspath "$1" func_relative_path_tlibdir=$func_normal_abspath_result func_normal_abspath "$2" func_relative_path_tbindir=$func_normal_abspath_result # Ascend the tree starting from libdir while :; do # check if we have found a prefix of bindir case $func_relative_path_tbindir in $func_relative_path_tlibdir) # found an exact match func_relative_path_tcancelled= break ;; $func_relative_path_tlibdir*) # found a matching prefix func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" func_relative_path_tcancelled=$func_stripname_result if test -z "$func_relative_path_result"; then func_relative_path_result=. fi break ;; *) func_dirname $func_relative_path_tlibdir func_relative_path_tlibdir=$func_dirname_result if test -z "$func_relative_path_tlibdir"; then # Have to descend all the way to the root! func_relative_path_result=../$func_relative_path_result func_relative_path_tcancelled=$func_relative_path_tbindir break fi func_relative_path_result=../$func_relative_path_result ;; esac done # Now calculate path; take care to avoid doubling-up slashes. func_stripname '' '/' "$func_relative_path_result" func_relative_path_result=$func_stripname_result func_stripname '/' '/' "$func_relative_path_tcancelled" if test -n "$func_stripname_result"; then func_append func_relative_path_result "/$func_stripname_result" fi # Normalisation. If bindir is libdir, return '.' else relative path. if test -n "$func_relative_path_result"; then func_stripname './' '' "$func_relative_path_result" func_relative_path_result=$func_stripname_result fi test -n "$func_relative_path_result" || func_relative_path_result=. : } # func_quote_for_eval ARG... # -------------------------- # Aesthetically quote ARGs to be evaled later. # This function returns two values: # i) func_quote_for_eval_result # double-quoted, suitable for a subsequent eval # ii) func_quote_for_eval_unquoted_result # has all characters that are still active within double # quotes backslashified. func_quote_for_eval () { $debug_cmd func_quote_for_eval_unquoted_result= func_quote_for_eval_result= while test 0 -lt $#; do case $1 in *[\\\`\"\$]*) _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;; *) _G_unquoted_arg=$1 ;; esac if test -n "$func_quote_for_eval_unquoted_result"; then func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg" else func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg" fi case $_G_unquoted_arg in # Double-quote args containing shell metacharacters to delay # word splitting, command substitution and variable expansion # for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") _G_quoted_arg=\"$_G_unquoted_arg\" ;; *) _G_quoted_arg=$_G_unquoted_arg ;; esac if test -n "$func_quote_for_eval_result"; then func_append func_quote_for_eval_result " $_G_quoted_arg" else func_append func_quote_for_eval_result "$_G_quoted_arg" fi shift done } # func_quote_for_expand ARG # ------------------------- # Aesthetically quote ARG to be evaled later; same as above, # but do not quote variable references. func_quote_for_expand () { $debug_cmd case $1 in *[\\\`\"]*) _G_arg=`$ECHO "$1" | $SED \ -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;; *) _G_arg=$1 ;; esac case $_G_arg in # Double-quote args containing shell metacharacters to delay # word splitting and command substitution for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") _G_arg=\"$_G_arg\" ;; esac func_quote_for_expand_result=$_G_arg } # func_stripname PREFIX SUFFIX NAME # --------------------------------- # strip PREFIX and SUFFIX from NAME, and store in func_stripname_result. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_stripname () { $debug_cmd # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary variable first. func_stripname_result=$3 func_stripname_result=${func_stripname_result#"$1"} func_stripname_result=${func_stripname_result%"$2"} }' else func_stripname () { $debug_cmd case $2 in .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;; *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;; esac } fi # func_show_eval CMD [FAIL_EXP] # ----------------------------- # Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { $debug_cmd _G_cmd=$1 _G_fail_exp=${2-':'} func_quote_for_expand "$_G_cmd" eval "func_notquiet $func_quote_for_expand_result" $opt_dry_run || { eval "$_G_cmd" _G_status=$? if test 0 -ne "$_G_status"; then eval "(exit $_G_status); $_G_fail_exp" fi } } # func_show_eval_locale CMD [FAIL_EXP] # ------------------------------------ # Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. Use the saved locale for evaluation. func_show_eval_locale () { $debug_cmd _G_cmd=$1 _G_fail_exp=${2-':'} $opt_quiet || { func_quote_for_expand "$_G_cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || { eval "$_G_user_locale $_G_cmd" _G_status=$? eval "$_G_safe_locale" if test 0 -ne "$_G_status"; then eval "(exit $_G_status); $_G_fail_exp" fi } } # func_tr_sh # ---------- # Turn $1 into a string suitable for a shell variable name. # Result is stored in $func_tr_sh_result. All characters # not in the set a-zA-Z0-9_ are replaced with '_'. Further, # if $1 begins with a digit, a '_' is prepended as well. func_tr_sh () { $debug_cmd case $1 in [0-9]* | *[!a-zA-Z0-9_]*) func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'` ;; * ) func_tr_sh_result=$1 ;; esac } # func_verbose ARG... # ------------------- # Echo program name prefixed message in verbose mode only. func_verbose () { $debug_cmd $opt_verbose && func_echo "$*" : } # func_warn_and_continue ARG... # ----------------------------- # Echo program name prefixed warning message to standard error. func_warn_and_continue () { $debug_cmd $require_term_colors func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2 } # func_warning CATEGORY ARG... # ---------------------------- # Echo program name prefixed warning message to standard error. Warning # messages can be filtered according to CATEGORY, where this function # elides messages where CATEGORY is not listed in the global variable # 'opt_warning_types'. func_warning () { $debug_cmd # CATEGORY must be in the warning_categories list! case " $warning_categories " in *" $1 "*) ;; *) func_internal_error "invalid warning category '$1'" ;; esac _G_category=$1 shift case " $opt_warning_types " in *" $_G_category "*) $warning_func ${1+"$@"} ;; esac } # func_sort_ver VER1 VER2 # ----------------------- # 'sort -V' is not generally available. # Note this deviates from the version comparison in automake # in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a # but this should suffice as we won't be specifying old # version formats or redundant trailing .0 in bootstrap.conf. # If we did want full compatibility then we should probably # use m4_version_compare from autoconf. func_sort_ver () { $debug_cmd printf '%s\n%s\n' "$1" "$2" \ | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n } # func_lt_ver PREV CURR # --------------------- # Return true if PREV and CURR are in the correct order according to # func_sort_ver, otherwise false. Use it like this: # # func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..." func_lt_ver () { $debug_cmd test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q` } # Local variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: #! /bin/sh # Set a version string for this script. scriptversion=2014-01-07.03; # UTC # A portable, pluggable option parser for Bourne shell. # Written by Gary V. Vaughan, 2010 # Copyright (C) 2010-2015 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Please report bugs or propose patches to gary@gnu.org. ## ------ ## ## Usage. ## ## ------ ## # This file is a library for parsing options in your shell scripts along # with assorted other useful supporting features that you can make use # of too. # # For the simplest scripts you might need only: # # #!/bin/sh # . relative/path/to/funclib.sh # . relative/path/to/options-parser # scriptversion=1.0 # func_options ${1+"$@"} # eval set dummy "$func_options_result"; shift # ...rest of your script... # # In order for the '--version' option to work, you will need to have a # suitably formatted comment like the one at the top of this file # starting with '# Written by ' and ending with '# warranty; '. # # For '-h' and '--help' to work, you will also need a one line # description of your script's purpose in a comment directly above the # '# Written by ' line, like the one at the top of this file. # # The default options also support '--debug', which will turn on shell # execution tracing (see the comment above debug_cmd below for another # use), and '--verbose' and the func_verbose function to allow your script # to display verbose messages only when your user has specified # '--verbose'. # # After sourcing this file, you can plug processing for additional # options by amending the variables from the 'Configuration' section # below, and following the instructions in the 'Option parsing' # section further down. ## -------------- ## ## Configuration. ## ## -------------- ## # You should override these variables in your script after sourcing this # file so that they reflect the customisations you have added to the # option parser. # The usage line for option parsing errors and the start of '-h' and # '--help' output messages. You can embed shell variables for delayed # expansion at the time the message is displayed, but you will need to # quote other shell meta-characters carefully to prevent them being # expanded when the contents are evaled. usage='$progpath [OPTION]...' # Short help message in response to '-h' and '--help'. Add to this or # override it after sourcing this library to reflect the full set of # options your script accepts. usage_message="\ --debug enable verbose shell tracing -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] -v, --verbose verbosely report processing --version print version information and exit -h, --help print short or long help message and exit " # Additional text appended to 'usage_message' in response to '--help'. long_help_message=" Warning categories include: 'all' show all warnings 'none' turn off all the warnings 'error' warnings are treated as fatal errors" # Help message printed before fatal option parsing errors. fatal_help="Try '\$progname --help' for more information." ## ------------------------- ## ## Hook function management. ## ## ------------------------- ## # This section contains functions for adding, removing, and running hooks # to the main code. A hook is just a named list of of function, that can # be run in order later on. # func_hookable FUNC_NAME # ----------------------- # Declare that FUNC_NAME will run hooks added with # 'func_add_hook FUNC_NAME ...'. func_hookable () { $debug_cmd func_append hookable_fns " $1" } # func_add_hook FUNC_NAME HOOK_FUNC # --------------------------------- # Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must # first have been declared "hookable" by a call to 'func_hookable'. func_add_hook () { $debug_cmd case " $hookable_fns " in *" $1 "*) ;; *) func_fatal_error "'$1' does not accept hook functions." ;; esac eval func_append ${1}_hooks '" $2"' } # func_remove_hook FUNC_NAME HOOK_FUNC # ------------------------------------ # Remove HOOK_FUNC from the list of functions called by FUNC_NAME. func_remove_hook () { $debug_cmd eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`' } # func_run_hooks FUNC_NAME [ARG]... # --------------------------------- # Run all hook functions registered to FUNC_NAME. # It is assumed that the list of hook functions contains nothing more # than a whitespace-delimited list of legal shell function names, and # no effort is wasted trying to catch shell meta-characters or preserve # whitespace. func_run_hooks () { $debug_cmd case " $hookable_fns " in *" $1 "*) ;; *) func_fatal_error "'$1' does not support hook funcions.n" ;; esac eval _G_hook_fns=\$$1_hooks; shift for _G_hook in $_G_hook_fns; do eval $_G_hook '"$@"' # store returned options list back into positional # parameters for next 'cmd' execution. eval _G_hook_result=\$${_G_hook}_result eval set dummy "$_G_hook_result"; shift done func_quote_for_eval ${1+"$@"} func_run_hooks_result=$func_quote_for_eval_result } ## --------------- ## ## Option parsing. ## ## --------------- ## # In order to add your own option parsing hooks, you must accept the # full positional parameter list in your hook function, remove any # options that you action, and then pass back the remaining unprocessed # options in '_result', escaped suitably for # 'eval'. Like this: # # my_options_prep () # { # $debug_cmd # # # Extend the existing usage message. # usage_message=$usage_message' # -s, --silent don'\''t print informational messages # ' # # func_quote_for_eval ${1+"$@"} # my_options_prep_result=$func_quote_for_eval_result # } # func_add_hook func_options_prep my_options_prep # # # my_silent_option () # { # $debug_cmd # # # Note that for efficiency, we parse as many options as we can # # recognise in a loop before passing the remainder back to the # # caller on the first unrecognised argument we encounter. # while test $# -gt 0; do # opt=$1; shift # case $opt in # --silent|-s) opt_silent=: ;; # # Separate non-argument short options: # -s*) func_split_short_opt "$_G_opt" # set dummy "$func_split_short_opt_name" \ # "-$func_split_short_opt_arg" ${1+"$@"} # shift # ;; # *) set dummy "$_G_opt" "$*"; shift; break ;; # esac # done # # func_quote_for_eval ${1+"$@"} # my_silent_option_result=$func_quote_for_eval_result # } # func_add_hook func_parse_options my_silent_option # # # my_option_validation () # { # $debug_cmd # # $opt_silent && $opt_verbose && func_fatal_help "\ # '--silent' and '--verbose' options are mutually exclusive." # # func_quote_for_eval ${1+"$@"} # my_option_validation_result=$func_quote_for_eval_result # } # func_add_hook func_validate_options my_option_validation # # You'll alse need to manually amend $usage_message to reflect the extra # options you parse. It's preferable to append if you can, so that # multiple option parsing hooks can be added safely. # func_options [ARG]... # --------------------- # All the functions called inside func_options are hookable. See the # individual implementations for details. func_hookable func_options func_options () { $debug_cmd func_options_prep ${1+"$@"} eval func_parse_options \ ${func_options_prep_result+"$func_options_prep_result"} eval func_validate_options \ ${func_parse_options_result+"$func_parse_options_result"} eval func_run_hooks func_options \ ${func_validate_options_result+"$func_validate_options_result"} # save modified positional parameters for caller func_options_result=$func_run_hooks_result } # func_options_prep [ARG]... # -------------------------- # All initialisations required before starting the option parse loop. # Note that when calling hook functions, we pass through the list of # positional parameters. If a hook function modifies that list, and # needs to propogate that back to rest of this script, then the complete # modified list must be put in 'func_run_hooks_result' before # returning. func_hookable func_options_prep func_options_prep () { $debug_cmd # Option defaults: opt_verbose=false opt_warning_types= func_run_hooks func_options_prep ${1+"$@"} # save modified positional parameters for caller func_options_prep_result=$func_run_hooks_result } # func_parse_options [ARG]... # --------------------------- # The main option parsing loop. func_hookable func_parse_options func_parse_options () { $debug_cmd func_parse_options_result= # this just eases exit handling while test $# -gt 0; do # Defer to hook functions for initial option parsing, so they # get priority in the event of reusing an option name. func_run_hooks func_parse_options ${1+"$@"} # Adjust func_parse_options positional parameters to match eval set dummy "$func_run_hooks_result"; shift # Break out of the loop if we already parsed every option. test $# -gt 0 || break _G_opt=$1 shift case $_G_opt in --debug|-x) debug_cmd='set -x' func_echo "enabling shell trace mode" $debug_cmd ;; --no-warnings|--no-warning|--no-warn) set dummy --warnings none ${1+"$@"} shift ;; --warnings|--warning|-W) test $# = 0 && func_missing_arg $_G_opt && break case " $warning_categories $1" in *" $1 "*) # trailing space prevents matching last $1 above func_append_uniq opt_warning_types " $1" ;; *all) opt_warning_types=$warning_categories ;; *none) opt_warning_types=none warning_func=: ;; *error) opt_warning_types=$warning_categories warning_func=func_fatal_error ;; *) func_fatal_error \ "unsupported warning category: '$1'" ;; esac shift ;; --verbose|-v) opt_verbose=: ;; --version) func_version ;; -\?|-h) func_usage ;; --help) func_help ;; # Separate optargs to long options (plugins may need this): --*=*) func_split_equals "$_G_opt" set dummy "$func_split_equals_lhs" \ "$func_split_equals_rhs" ${1+"$@"} shift ;; # Separate optargs to short options: -W*) func_split_short_opt "$_G_opt" set dummy "$func_split_short_opt_name" \ "$func_split_short_opt_arg" ${1+"$@"} shift ;; # Separate non-argument short options: -\?*|-h*|-v*|-x*) func_split_short_opt "$_G_opt" set dummy "$func_split_short_opt_name" \ "-$func_split_short_opt_arg" ${1+"$@"} shift ;; --) break ;; -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; esac done # save modified positional parameters for caller func_quote_for_eval ${1+"$@"} func_parse_options_result=$func_quote_for_eval_result } # func_validate_options [ARG]... # ------------------------------ # Perform any sanity checks on option settings and/or unconsumed # arguments. func_hookable func_validate_options func_validate_options () { $debug_cmd # Display all warnings if -W was not given. test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" func_run_hooks func_validate_options ${1+"$@"} # Bail if the options were screwed! $exit_cmd $EXIT_FAILURE # save modified positional parameters for caller func_validate_options_result=$func_run_hooks_result } ## ----------------- ## ## Helper functions. ## ## ----------------- ## # This section contains the helper functions used by the rest of the # hookable option parser framework in ascii-betical order. # func_fatal_help ARG... # ---------------------- # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { $debug_cmd eval \$ECHO \""Usage: $usage"\" eval \$ECHO \""$fatal_help"\" func_error ${1+"$@"} exit $EXIT_FAILURE } # func_help # --------- # Echo long help message to standard output and exit. func_help () { $debug_cmd func_usage_message $ECHO "$long_help_message" exit 0 } # func_missing_arg ARGNAME # ------------------------ # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { $debug_cmd func_error "Missing argument for '$1'." exit_cmd=exit } # func_split_equals STRING # ------------------------ # Set func_split_equals_lhs and func_split_equals_rhs shell variables after # splitting STRING at the '=' sign. test -z "$_G_HAVE_XSI_OPS" \ && (eval 'x=a/b/c; test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ && _G_HAVE_XSI_OPS=yes if test yes = "$_G_HAVE_XSI_OPS" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_split_equals () { $debug_cmd func_split_equals_lhs=${1%%=*} func_split_equals_rhs=${1#*=} test "x$func_split_equals_lhs" = "x$1" \ && func_split_equals_rhs= }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_split_equals () { $debug_cmd func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` func_split_equals_rhs= test "x$func_split_equals_lhs" = "x$1" \ || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` } fi #func_split_equals # func_split_short_opt SHORTOPT # ----------------------------- # Set func_split_short_opt_name and func_split_short_opt_arg shell # variables after splitting SHORTOPT after the 2nd character. if test yes = "$_G_HAVE_XSI_OPS" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_split_short_opt () { $debug_cmd func_split_short_opt_arg=${1#??} func_split_short_opt_name=${1%"$func_split_short_opt_arg"} }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_split_short_opt () { $debug_cmd func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'` func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` } fi #func_split_short_opt # func_usage # ---------- # Echo short help message to standard output and exit. func_usage () { $debug_cmd func_usage_message $ECHO "Run '$progname --help |${PAGER-more}' for full usage" exit 0 } # func_usage_message # ------------------ # Echo short help message to standard output. func_usage_message () { $debug_cmd eval \$ECHO \""Usage: $usage"\" echo $SED -n 's|^# || /^Written by/{ x;p;x } h /^Written by/q' < "$progpath" echo eval \$ECHO \""$usage_message"\" } # func_version # ------------ # Echo version message to standard output and exit. func_version () { $debug_cmd printf '%s\n' "$progname $scriptversion" $SED -n ' /(C)/!b go :more /\./!{ N s|\n# | | b more } :go /^# Written by /,/# warranty; / { s|^# || s|^# *$|| s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| p } /^# Written by / { s|^# || p } /^warranty; /q' < "$progpath" exit $? } # Local variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: # Set a version string. scriptversion='(GNU libtool) 2.4.6' # func_echo ARG... # ---------------- # Libtool also displays the current mode in messages, so override # funclib.sh func_echo with this custom definition. func_echo () { $debug_cmd _G_message=$* func_echo_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_IFS $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line" done IFS=$func_echo_IFS } # func_warning ARG... # ------------------- # Libtool warnings are not categorized, so override funclib.sh # func_warning with this simpler definition. func_warning () { $debug_cmd $warning_func ${1+"$@"} } ## ---------------- ## ## Options parsing. ## ## ---------------- ## # Hook in the functions to make sure our own options are parsed during # the option parsing loop. usage='$progpath [OPTION]... [MODE-ARG]...' # Short help message in response to '-h'. usage_message="Options: --config show all configuration variables --debug enable verbose shell tracing -n, --dry-run display commands without modifying any files --features display basic configuration information and exit --mode=MODE use operation mode MODE --no-warnings equivalent to '-Wnone' --preserve-dup-deps don't remove duplicate dependency libraries --quiet, --silent don't print informational messages --tag=TAG use configuration variables from tag TAG -v, --verbose print more informational messages than default --version print version information -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] -h, --help, --help-all print short, long, or detailed help message " # Additional text appended to 'usage_message' in response to '--help'. func_help () { $debug_cmd func_usage_message $ECHO "$long_help_message MODE must be one of the following: clean remove files from the build directory compile compile a source file into a libtool object execute automatically set library path, then run a program finish complete the installation of libtool libraries install install libraries or executables link create a library or an executable uninstall remove libraries from an installed directory MODE-ARGS vary depending on the MODE. When passed as first option, '--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that. Try '$progname --help --mode=MODE' for a more detailed description of MODE. When reporting a bug, please describe a test case to reproduce it and include the following information: host-triplet: $host shell: $SHELL compiler: $LTCC compiler flags: $LTCFLAGS linker: $LD (gnu? $with_gnu_ld) version: $progname (GNU libtool) 2.4.6 automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` Report bugs to . GNU libtool home page: . General help using GNU software: ." exit 0 } # func_lo2o OBJECT-NAME # --------------------- # Transform OBJECT-NAME from a '.lo' suffix to the platform specific # object suffix. lo2o=s/\\.lo\$/.$objext/ o2lo=s/\\.$objext\$/.lo/ if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_lo2o () { case $1 in *.lo) func_lo2o_result=${1%.lo}.$objext ;; * ) func_lo2o_result=$1 ;; esac }' # func_xform LIBOBJ-OR-SOURCE # --------------------------- # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise) # suffix to a '.lo' libtool-object suffix. eval 'func_xform () { func_xform_result=${1%.*}.lo }' else # ...otherwise fall back to using sed. func_lo2o () { func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"` } func_xform () { func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'` } fi # func_fatal_configuration ARG... # ------------------------------- # Echo program name prefixed message to standard error, followed by # a configuration failure hint, and exit. func_fatal_configuration () { func__fatal_error ${1+"$@"} \ "See the $PACKAGE documentation for more information." \ "Fatal configuration error." } # func_config # ----------- # Display the configuration for all the tags in this script. func_config () { re_begincf='^# ### BEGIN LIBTOOL' re_endcf='^# ### END LIBTOOL' # Default configuration. $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" # Now print the configurations for the tags. for tagname in $taglist; do $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" done exit $? } # func_features # ------------- # Display the features supported by this script. func_features () { echo "host: $host" if test yes = "$build_libtool_libs"; then echo "enable shared libraries" else echo "disable shared libraries" fi if test yes = "$build_old_libs"; then echo "enable static libraries" else echo "disable static libraries" fi exit $? } # func_enable_tag TAGNAME # ----------------------- # Verify that TAGNAME is valid, and either flag an error and exit, or # enable the TAGNAME tag. We also add TAGNAME to the global $taglist # variable here. func_enable_tag () { # Global variable: tagname=$1 re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" sed_extractcf=/$re_begincf/,/$re_endcf/p # Validate tagname. case $tagname in *[!-_A-Za-z0-9,/]*) func_fatal_error "invalid tag name: $tagname" ;; esac # Don't test for the "default" C tag, as we know it's # there but not specially marked. case $tagname in CC) ;; *) if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then taglist="$taglist $tagname" # Evaluate the configuration. Be careful to quote the path # and the sed script, to avoid splitting on whitespace, but # also don't use non-portable quotes within backquotes within # quotes we have to do it in 2 steps: extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` eval "$extractedcf" else func_error "ignoring unknown tag $tagname" fi ;; esac } # func_check_version_match # ------------------------ # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { if test "$package_revision" != "$macro_revision"; then if test "$VERSION" != "$macro_version"; then if test -z "$macro_version"; then cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF fi else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF fi exit $EXIT_MISMATCH fi } # libtool_options_prep [ARG]... # ----------------------------- # Preparation for options parsed by libtool. libtool_options_prep () { $debug_mode # Option defaults: opt_config=false opt_dlopen= opt_dry_run=false opt_help=false opt_mode= opt_preserve_dup_deps=false opt_quiet=false nonopt= preserve_args= # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) shift; set dummy --mode clean ${1+"$@"}; shift ;; compile|compil|compi|comp|com|co|c) shift; set dummy --mode compile ${1+"$@"}; shift ;; execute|execut|execu|exec|exe|ex|e) shift; set dummy --mode execute ${1+"$@"}; shift ;; finish|finis|fini|fin|fi|f) shift; set dummy --mode finish ${1+"$@"}; shift ;; install|instal|insta|inst|ins|in|i) shift; set dummy --mode install ${1+"$@"}; shift ;; link|lin|li|l) shift; set dummy --mode link ${1+"$@"}; shift ;; uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; esac # Pass back the list of options. func_quote_for_eval ${1+"$@"} libtool_options_prep_result=$func_quote_for_eval_result } func_add_hook func_options_prep libtool_options_prep # libtool_parse_options [ARG]... # --------------------------------- # Provide handling for libtool specific options. libtool_parse_options () { $debug_cmd # Perform our own loop to consume as many options as possible in # each iteration. while test $# -gt 0; do _G_opt=$1 shift case $_G_opt in --dry-run|--dryrun|-n) opt_dry_run=: ;; --config) func_config ;; --dlopen|-dlopen) opt_dlopen="${opt_dlopen+$opt_dlopen }$1" shift ;; --preserve-dup-deps) opt_preserve_dup_deps=: ;; --features) func_features ;; --finish) set dummy --mode finish ${1+"$@"}; shift ;; --help) opt_help=: ;; --help-all) opt_help=': help-all' ;; --mode) test $# = 0 && func_missing_arg $_G_opt && break opt_mode=$1 case $1 in # Valid mode arguments: clean|compile|execute|finish|install|link|relink|uninstall) ;; # Catch anything else as an error *) func_error "invalid argument for $_G_opt" exit_cmd=exit break ;; esac shift ;; --no-silent|--no-quiet) opt_quiet=false func_append preserve_args " $_G_opt" ;; --no-warnings|--no-warning|--no-warn) opt_warning=false func_append preserve_args " $_G_opt" ;; --no-verbose) opt_verbose=false func_append preserve_args " $_G_opt" ;; --silent|--quiet) opt_quiet=: opt_verbose=false func_append preserve_args " $_G_opt" ;; --tag) test $# = 0 && func_missing_arg $_G_opt && break opt_tag=$1 func_append preserve_args " $_G_opt $1" func_enable_tag "$1" shift ;; --verbose|-v) opt_quiet=false opt_verbose=: func_append preserve_args " $_G_opt" ;; # An option not handled by this hook function: *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; esac done # save modified positional parameters for caller func_quote_for_eval ${1+"$@"} libtool_parse_options_result=$func_quote_for_eval_result } func_add_hook func_parse_options libtool_parse_options # libtool_validate_options [ARG]... # --------------------------------- # Perform any sanity checks on option settings and/or unconsumed # arguments. libtool_validate_options () { # save first non-option argument if test 0 -lt $#; then nonopt=$1 shift fi # preserve --debug test : = "$debug_cmd" || func_append preserve_args " --debug" case $host in # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452 # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788 *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; *) opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps ;; esac $opt_help || { # Sanity checks first: func_check_version_match test yes != "$build_libtool_libs" \ && test yes != "$build_old_libs" \ && func_fatal_configuration "not configured to build any kind of library" # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Only execute mode is allowed to have -dlopen flags. if test -n "$opt_dlopen" && test execute != "$opt_mode"; then func_error "unrecognized option '-dlopen'" $ECHO "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help=$help help="Try '$progname --help --mode=$opt_mode' for more information." } # Pass back the unparsed argument list func_quote_for_eval ${1+"$@"} libtool_validate_options_result=$func_quote_for_eval_result } func_add_hook func_validate_options libtool_validate_options # Process options as early as possible so that --help and --version # can return quickly. func_options ${1+"$@"} eval set dummy "$func_options_result"; shift ## ----------- ## ## Main. ## ## ----------- ## magic='%%%MAGIC variable%%%' magic_exe='%%%MAGIC EXE variable%%%' # Global variables. extracted_archives= extracted_serial=0 # If this variable is set in any of the actions, the command in it # will be execed at the end. This prevents here-documents from being # left over by shells. exec_cmd= # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } # func_generated_by_libtool # True iff stdin has been generated by Libtool. This function is only # a basic sanity check; it will hardly flush out determined imposters. func_generated_by_libtool_p () { $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 } # func_lalib_p file # True iff FILE is a libtool '.la' library or '.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () { test -f "$1" && $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p } # func_lalib_unsafe_p file # True iff FILE is a libtool '.la' library or '.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be # fatal anyway. Works if 'file' does not exist. func_lalib_unsafe_p () { lalib_p=no if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then for lalib_p_l in 1 2 3 4 do read lalib_p_line case $lalib_p_line in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi test yes = "$lalib_p" } # func_ltwrapper_script_p file # True iff FILE is a libtool wrapper script # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_script_p () { test -f "$1" && $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p } # func_ltwrapper_executable_p file # True iff FILE is a libtool wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_executable_p () { func_ltwrapper_exec_suffix= case $1 in *.exe) ;; *) func_ltwrapper_exec_suffix=.exe ;; esac $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 } # func_ltwrapper_scriptname file # Assumes file is an ltwrapper_executable # uses $file to determine the appropriate filename for a # temporary ltwrapper_script. func_ltwrapper_scriptname () { func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper } # func_ltwrapper_p file # True iff FILE is a libtool wrapper script or wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_p () { func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" } # func_execute_cmds commands fail_cmd # Execute tilde-delimited COMMANDS. # If FAIL_CMD is given, eval that upon failure. # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { $debug_cmd save_ifs=$IFS; IFS='~' for cmd in $1; do IFS=$sp$nl eval cmd=\"$cmd\" IFS=$save_ifs func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs } # func_source file # Source FILE, adding directory component if necessary. # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing # 'FILE.' does not work on cygwin managed mounts. func_source () { $debug_cmd case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; esac } # func_resolve_sysroot PATH # Replace a leading = in PATH with a sysroot. Store the result into # func_resolve_sysroot_result func_resolve_sysroot () { func_resolve_sysroot_result=$1 case $func_resolve_sysroot_result in =*) func_stripname '=' '' "$func_resolve_sysroot_result" func_resolve_sysroot_result=$lt_sysroot$func_stripname_result ;; esac } # func_replace_sysroot PATH # If PATH begins with the sysroot, replace it with = and # store the result into func_replace_sysroot_result. func_replace_sysroot () { case $lt_sysroot:$1 in ?*:"$lt_sysroot"*) func_stripname "$lt_sysroot" '' "$1" func_replace_sysroot_result='='$func_stripname_result ;; *) # Including no sysroot. func_replace_sysroot_result=$1 ;; esac } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { $debug_cmd if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case "$@ " in " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" func_fatal_error "specify a tag with '--tag'" # else # func_verbose "using $tagname tagged configuration" fi ;; esac fi } # func_write_libtool_object output_name pic_name nonpic_name # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. func_write_libtool_object () { write_libobj=$1 if test yes = "$build_libtool_libs"; then write_lobj=\'$2\' else write_lobj=none fi if test yes = "$build_old_libs"; then write_oldobj=\'$3\' else write_oldobj=none fi $opt_dry_run || { cat >${write_libobj}T </dev/null` if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | $SED -e "$sed_naive_backslashify"` else func_convert_core_file_wine_to_w32_result= fi fi } # end: func_convert_core_file_wine_to_w32 # func_convert_core_path_wine_to_w32 ARG # Helper function used by path conversion functions when $build is *nix, and # $host is mingw, cygwin, or some other w32 environment. Relies on a correctly # configured wine environment available, with the winepath program in $build's # $PATH. Assumes ARG has no leading or trailing path separator characters. # # ARG is path to be converted from $build format to win32. # Result is available in $func_convert_core_path_wine_to_w32_result. # Unconvertible file (directory) names in ARG are skipped; if no directory names # are convertible, then the result may be empty. func_convert_core_path_wine_to_w32 () { $debug_cmd # unfortunately, winepath doesn't convert paths, only file names func_convert_core_path_wine_to_w32_result= if test -n "$1"; then oldIFS=$IFS IFS=: for func_convert_core_path_wine_to_w32_f in $1; do IFS=$oldIFS func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" if test -n "$func_convert_core_file_wine_to_w32_result"; then if test -z "$func_convert_core_path_wine_to_w32_result"; then func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result else func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" fi fi done IFS=$oldIFS fi } # end: func_convert_core_path_wine_to_w32 # func_cygpath ARGS... # Wrapper around calling the cygpath program via LT_CYGPATH. This is used when # when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) # $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or # (2), returns the Cygwin file name or path in func_cygpath_result (input # file name or path is assumed to be in w32 format, as previously converted # from $build's *nix or MSYS format). In case (3), returns the w32 file name # or path in func_cygpath_result (input file name or path is assumed to be in # Cygwin format). Returns an empty string on error. # # ARGS are passed to cygpath, with the last one being the file name or path to # be converted. # # Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH # environment variable; do not put it in $PATH. func_cygpath () { $debug_cmd if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` if test "$?" -ne 0; then # on failure, ensure result is empty func_cygpath_result= fi else func_cygpath_result= func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'" fi } #end: func_cygpath # func_convert_core_msys_to_w32 ARG # Convert file name or path ARG from MSYS format to w32 format. Return # result in func_convert_core_msys_to_w32_result. func_convert_core_msys_to_w32 () { $debug_cmd # awkward: cmd appends spaces to result func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"` } #end: func_convert_core_msys_to_w32 # func_convert_file_check ARG1 ARG2 # Verify that ARG1 (a file name in $build format) was converted to $host # format in ARG2. Otherwise, emit an error message, but continue (resetting # func_to_host_file_result to ARG1). func_convert_file_check () { $debug_cmd if test -z "$2" && test -n "$1"; then func_error "Could not determine host file name corresponding to" func_error " '$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: func_to_host_file_result=$1 fi } # end func_convert_file_check # func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH # Verify that FROM_PATH (a path in $build format) was converted to $host # format in TO_PATH. Otherwise, emit an error message, but continue, resetting # func_to_host_file_result to a simplistic fallback value (see below). func_convert_path_check () { $debug_cmd if test -z "$4" && test -n "$3"; then func_error "Could not determine the host path corresponding to" func_error " '$3'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This is a deliberately simplistic "conversion" and # should not be "improved". See libtool.info. if test "x$1" != "x$2"; then lt_replace_pathsep_chars="s|$1|$2|g" func_to_host_path_result=`echo "$3" | $SED -e "$lt_replace_pathsep_chars"` else func_to_host_path_result=$3 fi fi } # end func_convert_path_check # func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG # Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT # and appending REPL if ORIG matches BACKPAT. func_convert_path_front_back_pathsep () { $debug_cmd case $4 in $1 ) func_to_host_path_result=$3$func_to_host_path_result ;; esac case $4 in $2 ) func_append func_to_host_path_result "$3" ;; esac } # end func_convert_path_front_back_pathsep ################################################## # $build to $host FILE NAME CONVERSION FUNCTIONS # ################################################## # invoked via '$to_host_file_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # Result will be available in $func_to_host_file_result. # func_to_host_file ARG # Converts the file name ARG from $build format to $host format. Return result # in func_to_host_file_result. func_to_host_file () { $debug_cmd $to_host_file_cmd "$1" } # end func_to_host_file # func_to_tool_file ARG LAZY # converts the file name ARG from $build format to toolchain format. Return # result in func_to_tool_file_result. If the conversion in use is listed # in (the comma separated) LAZY, no conversion takes place. func_to_tool_file () { $debug_cmd case ,$2, in *,"$to_tool_file_cmd",*) func_to_tool_file_result=$1 ;; *) $to_tool_file_cmd "$1" func_to_tool_file_result=$func_to_host_file_result ;; esac } # end func_to_tool_file # func_convert_file_noop ARG # Copy ARG to func_to_host_file_result. func_convert_file_noop () { func_to_host_file_result=$1 } # end func_convert_file_noop # func_convert_file_msys_to_w32 ARG # Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_file_result. func_convert_file_msys_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_to_host_file_result=$func_convert_core_msys_to_w32_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_w32 # func_convert_file_cygwin_to_w32 ARG # Convert file name ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_file_cygwin_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then # because $build is cygwin, we call "the" cygpath in $PATH; no need to use # LT_CYGPATH in this case. func_to_host_file_result=`cygpath -m "$1"` fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_cygwin_to_w32 # func_convert_file_nix_to_w32 ARG # Convert file name ARG from *nix to w32 format. Requires a wine environment # and a working winepath. Returns result in func_to_host_file_result. func_convert_file_nix_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_file_wine_to_w32 "$1" func_to_host_file_result=$func_convert_core_file_wine_to_w32_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_w32 # func_convert_file_msys_to_cygwin ARG # Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_file_msys_to_cygwin () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_cygpath -u "$func_convert_core_msys_to_w32_result" func_to_host_file_result=$func_cygpath_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_cygwin # func_convert_file_nix_to_cygwin ARG # Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed # in a wine environment, working winepath, and LT_CYGPATH set. Returns result # in func_to_host_file_result. func_convert_file_nix_to_cygwin () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. func_convert_core_file_wine_to_w32 "$1" func_cygpath -u "$func_convert_core_file_wine_to_w32_result" func_to_host_file_result=$func_cygpath_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_cygwin ############################################# # $build to $host PATH CONVERSION FUNCTIONS # ############################################# # invoked via '$to_host_path_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # The result will be available in $func_to_host_path_result. # # Path separators are also converted from $build format to $host format. If # ARG begins or ends with a path separator character, it is preserved (but # converted to $host format) on output. # # All path conversion functions are named using the following convention: # file name conversion function : func_convert_file_X_to_Y () # path conversion function : func_convert_path_X_to_Y () # where, for any given $build/$host combination the 'X_to_Y' value is the # same. If conversion functions are added for new $build/$host combinations, # the two new functions must follow this pattern, or func_init_to_host_path_cmd # will break. # func_init_to_host_path_cmd # Ensures that function "pointer" variable $to_host_path_cmd is set to the # appropriate value, based on the value of $to_host_file_cmd. to_host_path_cmd= func_init_to_host_path_cmd () { $debug_cmd if test -z "$to_host_path_cmd"; then func_stripname 'func_convert_file_' '' "$to_host_file_cmd" to_host_path_cmd=func_convert_path_$func_stripname_result fi } # func_to_host_path ARG # Converts the path ARG from $build format to $host format. Return result # in func_to_host_path_result. func_to_host_path () { $debug_cmd func_init_to_host_path_cmd $to_host_path_cmd "$1" } # end func_to_host_path # func_convert_path_noop ARG # Copy ARG to func_to_host_path_result. func_convert_path_noop () { func_to_host_path_result=$1 } # end func_convert_path_noop # func_convert_path_msys_to_w32 ARG # Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_path_result. func_convert_path_msys_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # Remove leading and trailing path separator characters from ARG. MSYS # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; # and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result=$func_convert_core_msys_to_w32_result func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_msys_to_w32 # func_convert_path_cygwin_to_w32 ARG # Convert path ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_path_cygwin_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_cygwin_to_w32 # func_convert_path_nix_to_w32 ARG # Convert path ARG from *nix to w32 format. Requires a wine environment and # a working winepath. Returns result in func_to_host_file_result. func_convert_path_nix_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result=$func_convert_core_path_wine_to_w32_result func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_nix_to_w32 # func_convert_path_msys_to_cygwin ARG # Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_path_msys_to_cygwin () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_msys_to_w32_result" func_to_host_path_result=$func_cygpath_result func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_msys_to_cygwin # func_convert_path_nix_to_cygwin ARG # Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a # a wine environment, working winepath, and LT_CYGPATH set. Returns result in # func_to_host_file_result. func_convert_path_nix_to_cygwin () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them # into '.;' and ';.', and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" func_to_host_path_result=$func_cygpath_result func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_nix_to_cygwin # func_dll_def_p FILE # True iff FILE is a Windows DLL '.def' file. # Keep in sync with _LT_DLL_DEF_P in libtool.m4 func_dll_def_p () { $debug_cmd func_dll_def_p_tmp=`$SED -n \ -e 's/^[ ]*//' \ -e '/^\(;.*\)*$/d' \ -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \ -e q \ "$1"` test DEF = "$func_dll_def_p_tmp" } # func_mode_compile arg... func_mode_compile () { $debug_cmd # Get the compilation command and the source file. base_compile= srcfile=$nonopt # always keep a non-empty value in "srcfile" suppress_opt=yes suppress_output= arg_mode=normal libobj= later= pie_flag= for arg do case $arg_mode in arg ) # do not "continue". Instead, add this to base_compile lastarg=$arg arg_mode=normal ;; target ) libobj=$arg arg_mode=normal continue ;; normal ) # Accept any command-line options. case $arg in -o) test -n "$libobj" && \ func_fatal_error "you cannot specify '-o' more than once" arg_mode=target continue ;; -pie | -fpie | -fPIE) func_append pie_flag " $arg" continue ;; -shared | -static | -prefer-pic | -prefer-non-pic) func_append later " $arg" continue ;; -no-suppress) suppress_opt=no continue ;; -Xcompiler) arg_mode=arg # the next one goes into the "base_compile" arg list continue # The current "srcfile" will either be retained or ;; # replaced later. I would guess that would be a bug. -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result lastarg= save_ifs=$IFS; IFS=, for arg in $args; do IFS=$save_ifs func_append_quoted lastarg "$arg" done IFS=$save_ifs func_stripname ' ' '' "$lastarg" lastarg=$func_stripname_result # Add the arguments to base_compile. func_append base_compile " $lastarg" continue ;; *) # Accept the current argument as the source file. # The previous "srcfile" becomes the current argument. # lastarg=$srcfile srcfile=$arg ;; esac # case $arg ;; esac # case $arg_mode # Aesthetically quote the previous argument. func_append_quoted base_compile "$lastarg" done # for arg case $arg_mode in arg) func_fatal_error "you must specify an argument for -Xcompile" ;; target) func_fatal_error "you must specify a target with '-o'" ;; *) # Get the name of the library object. test -z "$libobj" && { func_basename "$srcfile" libobj=$func_basename_result } ;; esac # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo case $libobj in *.[cCFSifmso] | \ *.ada | *.adb | *.ads | *.asm | \ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) func_xform "$libobj" libobj=$func_xform_result ;; esac case $libobj in *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; *) func_fatal_error "cannot determine name of library object from '$libobj'" ;; esac func_infer_tag $base_compile for arg in $later; do case $arg in -shared) test yes = "$build_libtool_libs" \ || func_fatal_configuration "cannot build a shared library" build_old_libs=no continue ;; -static) build_libtool_libs=no build_old_libs=yes continue ;; -prefer-pic) pic_mode=yes continue ;; -prefer-non-pic) pic_mode=no continue ;; esac done func_quote_for_eval "$libobj" test "X$libobj" != "X$func_quote_for_eval_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ && func_warning "libobj name '$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" objname=$func_basename_result xdir=$func_dirname_result lobj=$xdir$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. if test yes = "$build_old_libs"; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2* | cegcc*) pic_mode=default ;; esac if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test no = "$compiler_c_o"; then output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext lockfile=$output_obj.lock else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test yes = "$need_locks"; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done elif test warn = "$need_locks"; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi func_append removelist " $output_obj" $ECHO "$srcfile" > "$lockfile" fi $opt_dry_run || $RM $removelist func_append removelist " $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 srcfile=$func_to_tool_file_result func_quote_for_eval "$srcfile" qsrcfile=$func_quote_for_eval_result # Only build a PIC object if we are building libtool libraries. if test yes = "$build_libtool_libs"; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test no != "$pic_mode"; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code command="$base_compile $qsrcfile" fi func_mkdir_p "$xdir$objdir" if test -z "$output_obj"; then # Place PIC objects in $objdir func_append command " -o $lobj" fi func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' if test warn = "$need_locks" && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then func_show_eval '$MV "$output_obj" "$lobj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi # Allow error messages only from the first compilation. if test yes = "$suppress_opt"; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. if test yes = "$build_old_libs"; then if test yes != "$pic_mode"; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi if test yes = "$compiler_c_o"; then func_append command " -o $obj" fi # Suppress compiler output if we already did a PIC compilation. func_append command "$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' if test warn = "$need_locks" && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then func_show_eval '$MV "$output_obj" "$obj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi fi $opt_dry_run || { func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked if test no != "$need_locks"; then removelist=$lockfile $RM "$lockfile" fi } exit $EXIT_SUCCESS } $opt_help || { test compile = "$opt_mode" && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. case $opt_mode in "") # Generic help is extracted from the usage comments # at the start of this file. func_help ;; clean) $ECHO \ "Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $ECHO \ "Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to build PIC objects only -prefer-non-pic try to build non-PIC objects only -shared do not build a '.o' file suitable for static linking -static only build a '.o' file suitable for static linking -Wc,FLAG pass FLAG directly to the compiler COMPILE-COMMAND is a command to be used in creating a 'standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix '.c' with the library object suffix, '.lo'." ;; execute) $ECHO \ "Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to '-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $ECHO \ "Usage: $progname [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the '--dry-run' option if you just want to see what would be executed." ;; install) $ECHO \ "Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the 'install' or 'cp' program. The following components of INSTALL-COMMAND are treated specially: -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $ECHO \ "Usage: $progname [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -bindir BINDIR specify path to binaries directory (for systems where libraries must be found in the PATH setting at runtime) -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE use a list of object files found in FILE to specify objects -os2dllname NAME force a short DLL name on OS/2 (no effect on other OSes) -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -shared only do dynamic linking of libtool libraries -shrext SUFFIX override the standard shared library file extension -static do not do any dynamic linking of uninstalled libtool libraries -static-libtool-libs do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] -weak LIBNAME declare that the target provides the LIBNAME interface -Wc,FLAG -Xcompiler FLAG pass linker-specific FLAG directly to the compiler -Wl,FLAG -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) All other options (arguments beginning with '-') are ignored. Every other argument is treated as a filename. Files ending in '.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in '.la', then a libtool library is created, only library objects ('.lo' files) may be specified, and '-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created using 'ar' and 'ranlib', or on Windows using 'lib'. If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $ECHO \ "Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) func_fatal_help "invalid operation mode '$opt_mode'" ;; esac echo $ECHO "Try '$progname --help' for more information about other modes." } # Now that we've collected a possible --mode arg, show help if necessary if $opt_help; then if test : = "$opt_help"; then func_mode_help else { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do func_mode_help done } | $SED -n '1p; 2,$s/^Usage:/ or: /p' { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do echo func_mode_help done } | $SED '1d /^When reporting/,/^Report/{ H d } $x /information about other modes/d /more detailed .*MODE/d s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' fi exit $? fi # func_mode_execute arg... func_mode_execute () { $debug_cmd # The first argument is the command name. cmd=$nonopt test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $opt_dlopen; do test -f "$file" \ || func_fatal_help "'$file' is not a file" dir= case $file in *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "'$lib' is not a valid libtool archive" # Read the libtool library. dlname= library_names= func_source "$file" # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ func_warning "'$file' was not linked with '-export-dynamic'" continue fi func_dirname "$file" "" "." dir=$func_dirname_result if test -f "$dir/$objdir/$dlname"; then func_append dir "/$objdir" else if test ! -f "$dir/$dlname"; then func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'" fi fi ;; *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." dir=$func_dirname_result ;; *) func_warning "'-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir=$absdir # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic=$magic # Check if any of the arguments is a wrapper script. args= for file do case $file in -* | *.la | *.lo ) ;; *) # Do a test to see if this is really a libtool program. if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. file=$progdir/$program elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. file=$progdir/$program fi ;; esac # Quote arguments (to preserve shell metacharacters). func_append_quoted args "$file" done if $opt_dry_run; then # Display what would be done. if test -n "$shlibpath_var"; then eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" echo "export $shlibpath_var" fi $ECHO "$cmd$args" exit $EXIT_SUCCESS else if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${save_$lt_var+set}\" = set; then $lt_var=\$save_$lt_var; export $lt_var else $lt_unset $lt_var fi" done # Now prepare to actually exec the command. exec_cmd=\$cmd$args fi } test execute = "$opt_mode" && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $debug_cmd libs= libdirs= admincmds= for opt in "$nonopt" ${1+"$@"} do if test -d "$opt"; then func_append libdirs " $opt" elif test -f "$opt"; then if func_lalib_unsafe_p "$opt"; then func_append libs " $opt" else func_warning "'$opt' is not a valid libtool archive" fi else func_fatal_error "invalid argument '$opt'" fi done if test -n "$libs"; then if test -n "$lt_sysroot"; then sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" else sysroot_cmd= fi # Remove sysroot references if $opt_dry_run; then for lib in $libs; do echo "removing references to $lt_sysroot and '=' prefixes from $lib" done else tmpdir=`func_mktempdir` for lib in $libs; do $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ > $tmpdir/tmp-la mv -f $tmpdir/tmp-la $lib done ${RM}r "$tmpdir" fi fi if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. func_execute_cmds "$finish_cmds" 'admincmds="$admincmds '"$cmd"'"' fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $opt_dry_run || eval "$cmds" || func_append admincmds " $cmds" fi done fi # Exit here if they wanted silent mode. $opt_quiet && exit $EXIT_SUCCESS if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then echo "----------------------------------------------------------------------" echo "Libraries have been installed in:" for libdir in $libdirs; do $ECHO " $libdir" done echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" echo "specify the full pathname of the library, or use the '-LLIBDIR'" echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then echo " - add LIBDIR to the '$shlibpath_var' environment variable" echo " during execution" fi if test -n "$runpath_var"; then echo " - add LIBDIR to the '$runpath_var' environment variable" echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $ECHO " - use the '$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'" fi echo echo "See any operating system documentation about shared libraries for" case $host in solaris2.[6789]|solaris2.1[0-9]) echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" echo "pages." ;; *) echo "more information, such as the ld(1) and ld.so(8) manual pages." ;; esac echo "----------------------------------------------------------------------" fi exit $EXIT_SUCCESS } test finish = "$opt_mode" && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { $debug_cmd # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" || # Allow the use of GNU shtool's install command. case $nonopt in *shtool*) :;; *) false;; esac then # Aesthetically quote it. func_quote_for_eval "$nonopt" install_prog="$func_quote_for_eval_result " arg=$1 shift else install_prog= arg=$nonopt fi # The real first argument should be the name of the installation program. # Aesthetically quote it. func_quote_for_eval "$arg" func_append install_prog "$func_quote_for_eval_result" install_shared_prog=$install_prog case " $install_prog " in *[\\\ /]cp\ *) install_cp=: ;; *) install_cp=false ;; esac # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=false stripme= no_mode=: for arg do arg2= if test -n "$dest"; then func_append files " $dest" dest=$arg continue fi case $arg in -d) isdir=: ;; -f) if $install_cp; then :; else prev=$arg fi ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then if test X-m = "X$prev" && test -n "$install_override_mode"; then arg2=$install_override_mode no_mode=false fi prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. func_quote_for_eval "$arg" func_append install_prog " $func_quote_for_eval_result" if test -n "$arg2"; then func_quote_for_eval "$arg2" fi func_append install_shared_prog " $func_quote_for_eval_result" done test -z "$install_prog" && \ func_fatal_help "you must specify an install program" test -n "$prev" && \ func_fatal_help "the '$prev' option requires an argument" if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else func_quote_for_eval "$install_override_mode" func_append install_shared_prog " -m $func_quote_for_eval_result" fi fi if test -z "$files"; then if test -z "$dest"; then func_fatal_help "no file or destination specified" else func_fatal_help "you must specify a destination" fi fi # Strip any trailing slash from the destination. func_stripname '' '/' "$dest" dest=$func_stripname_result # Check to see that the destination is a directory. test -d "$dest" && isdir=: if $isdir; then destdir=$dest destname= else func_dirname_and_basename "$dest" "" "." destdir=$func_dirname_result destname=$func_basename_result # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ func_fatal_help "'$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) func_fatal_help "'$destdir' must be an absolute directory name" ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic=$magic staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. func_append staticlibs " $file" ;; *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "'$file' is not a valid libtool archive" library_names= old_library= relink_command= func_source "$file" # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) func_append current_libdirs " $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) func_append future_libdirs " $libdir" ;; esac fi func_dirname "$file" "/" "" dir=$func_dirname_result func_append dir "$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi func_warning "relinking '$file'" func_show_eval "$relink_command" \ 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then realname=$1 shift srcname=$realname test -n "$relink_command" && srcname=${realname}T # Install the shared library and build the symlinks. func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ 'exit $?' tstripme=$stripme case $host_os in cygwin* | mingw* | pw32* | cegcc*) case $realname in *.dll.a) tstripme= ;; esac ;; os2*) case $realname in *_dll.a) tstripme= ;; esac ;; esac if test -n "$tstripme" && test -n "$striplib"; then func_show_eval "$striplib $destdir/$realname" 'exit $?' fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. # Try 'ln -sf' first, because the 'ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname do test "$linkname" != "$realname" \ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" done fi # Do each command in the postinstall commands. lib=$destdir/$realname func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" name=$func_basename_result instname=$dir/${name}i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. test -n "$old_library" && func_append staticlibs " $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile=$destdir/$destname else func_basename "$file" destfile=$func_basename_result destfile=$destdir/$destfile fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) func_lo2o "$destfile" staticdest=$func_lo2o_result ;; *.$objext) staticdest=$destfile destfile= ;; *) func_fatal_help "cannot copy a libtool object to '$destfile'" ;; esac # Install the libtool object if requested. test -n "$destfile" && \ func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. if test yes = "$build_old_libs"; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile=$destdir/$destname else func_basename "$file" destfile=$func_basename_result destfile=$destdir/$destfile fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext= case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result stripped_ext=.exe fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin* | *mingw*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result else func_stripname '' '.exe' "$file" wrapper=$func_stripname_result fi ;; *) wrapper=$file ;; esac if func_ltwrapper_script_p "$wrapper"; then notinst_deplibs= relink_command= func_source "$wrapper" # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ func_fatal_error "invalid libtool wrapper script '$wrapper'" finalize=: for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'` if test -n "$libdir" && test ! -f "$libfile"; then func_warning "'$lib' has not been installed in '$libdir'" finalize=false fi done relink_command= func_source "$wrapper" outputname= if test no = "$fast_install" && test -n "$relink_command"; then $opt_dry_run || { if $finalize; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" file=$func_basename_result outputname=$tmpdir/$file # Replace the output file specification. relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` $opt_quiet || { func_quote_for_expand "$relink_command" eval "func_echo $func_quote_for_expand_result" } if eval "$relink_command"; then : else func_error "error: relink '$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi file=$outputname else func_warning "cannot relink '$file'" fi } else # Install the binary that we compiled earlier. file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyway case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) func_stripname '' '.exe' "$destfile" destfile=$func_stripname_result ;; esac ;; esac func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' $opt_dry_run || if test -n "$outputname"; then ${RM}r "$tmpdir" fi ;; esac done for file in $staticlibs; do func_basename "$file" name=$func_basename_result # Set up the ranlib parameters. oldlib=$destdir/$name func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then func_show_eval "$old_striplib $tool_oldlib" 'exit $?' fi # Do each command in the postinstall commands. func_execute_cmds "$old_postinstall_cmds" 'exit $?' done test -n "$future_libdirs" && \ func_warning "remember to run '$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } test install = "$opt_mode" && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p # Extract symbols from dlprefiles and create ${outputname}S.o with # a dlpreopen symbol table. func_generate_dlsyms () { $debug_cmd my_outputname=$1 my_originator=$2 my_pic_p=${3-false} my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then if test -n "$NM" && test -n "$global_symbol_pipe"; then my_dlsyms=${my_outputname}S.c else func_error "not configured to extract global symbols from dlpreopened files" fi fi if test -n "$my_dlsyms"; then case $my_dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist=$output_objdir/$my_outputname.nm func_show_eval "$RM $nlist ${nlist}S ${nlist}T" # Parse the name list into a source file. func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ /* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */ /* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif #if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) #pragma GCC diagnostic ignored \"-Wstrict-prototypes\" #endif /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) /* External symbol declarations for the compiler. */\ " if test yes = "$dlself"; then func_verbose "generating symbol list for '$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` for progfile in $progfiles; do func_to_tool_file "$progfile" func_convert_file_msys_to_w32 func_verbose "extracting global C symbols from '$func_to_tool_file_result'" $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $opt_dry_run || { eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi if test -n "$export_symbols_regex"; then $opt_dry_run || { eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols=$output_objdir/$outputname.exp $opt_dry_run || { $RM $export_symbols eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; esac } else $opt_dry_run || { eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; esac } fi fi for dlprefile in $dlprefiles; do func_verbose "extracting global C symbols from '$dlprefile'" func_basename "$dlprefile" name=$func_basename_result case $host in *cygwin* | *mingw* | *cegcc* ) # if an import library, we need to obtain dlname if func_win32_import_lib_p "$dlprefile"; then func_tr_sh "$dlprefile" eval "curr_lafile=\$libfile_$func_tr_sh_result" dlprefile_dlbasename= if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then # Use subshell, to avoid clobbering current variable values dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` if test -n "$dlprefile_dlname"; then func_basename "$dlprefile_dlname" dlprefile_dlbasename=$func_basename_result else # no lafile. user explicitly requested -dlpreopen . $sharedlib_from_linklib_cmd "$dlprefile" dlprefile_dlbasename=$sharedlib_from_linklib_result fi fi $opt_dry_run || { if test -n "$dlprefile_dlbasename"; then eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' else func_warning "Could not compute DLL name from $name" eval '$ECHO ": $name " >> "$nlist"' fi func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" } else # not an import lib $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } fi ;; *) $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } ;; esac done $opt_dry_run || { # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $MV "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if $GREP -v "^: " < "$nlist" | if sort -k 3 /dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else $GREP -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' else echo '/* NONE */' >> "$output_objdir/$my_dlsyms" fi func_show_eval '$RM "${nlist}I"' if test -n "$global_symbol_to_import"; then eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I' fi echo >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ typedef struct { const char *name; void *address; } lt_dlsymlist; extern LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[];\ " if test -s "$nlist"I; then echo >> "$output_objdir/$my_dlsyms" "\ static void lt_syminit(void) { LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols; for (; symbol->name; ++symbol) {" $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms" echo >> "$output_objdir/$my_dlsyms" "\ } }" fi echo >> "$output_objdir/$my_dlsyms" "\ LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = { {\"$my_originator\", (void *) 0}," if test -s "$nlist"I; then echo >> "$output_objdir/$my_dlsyms" "\ {\"@INIT@\", (void *) <_syminit}," fi case $need_lib_prefix in no) eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; *) eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; esac echo >> "$output_objdir/$my_dlsyms" "\ {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_${my_prefix}_LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " } # !$opt_dry_run pic_flag_for_symtable= case "$compile_command " in *" -static "*) ;; *) case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) $my_pic_p && pic_flag_for_symtable=" $pic_flag" ;; esac ;; esac symtab_cflags= for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; *) func_append symtab_cflags " $arg" ;; esac done # Now compile the dynamic symbol file. func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"' # Transform the symbol file into the correct name. symfileobj=$output_objdir/${my_outputname}S.$objext case $host in *cygwin* | *mingw* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` else compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` fi ;; *) compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` ;; esac ;; *) func_fatal_error "unknown suffix for '$my_dlsyms'" ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` fi } # func_cygming_gnu_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is a GNU/binutils-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_gnu_implib_p () { $debug_cmd func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` test -n "$func_cygming_gnu_implib_tmp" } # func_cygming_ms_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is an MS-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_ms_implib_p () { $debug_cmd func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` test -n "$func_cygming_ms_implib_tmp" } # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. # Despite the name, also deal with 64 bit binaries. func_win32_libid () { $debug_cmd win32_libid_type=unknown win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then case $nm_interface in "MS dumpbin") if func_cygming_ms_implib_p "$1" || func_cygming_gnu_implib_p "$1" then win32_nmres=import else win32_nmres= fi ;; *) func_to_tool_file "$1" func_convert_file_msys_to_w32 win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | $SED -n -e ' 1,100{ / I /{ s|.*|import| p q } }'` ;; esac case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; esac fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $ECHO "$win32_libid_type" } # func_cygming_dll_for_implib ARG # # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib () { $debug_cmd sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` } # func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs # # The is the core of a fallback implementation of a # platform-specific function to extract the name of the # DLL associated with the specified import library LIBNAME. # # SECTION_NAME is either .idata$6 or .idata$7, depending # on the platform and compiler that created the implib. # # Echos the name of the DLL associated with the # specified import library. func_cygming_dll_for_implib_fallback_core () { $debug_cmd match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` $OBJDUMP -s --section "$1" "$2" 2>/dev/null | $SED '/^Contents of section '"$match_literal"':/{ # Place marker at beginning of archive member dllname section s/.*/====MARK====/ p d } # These lines can sometimes be longer than 43 characters, but # are always uninteresting /:[ ]*file format pe[i]\{,1\}-/d /^In archive [^:]*:/d # Ensure marker is printed /^====MARK====/p # Remove all lines with less than 43 characters /^.\{43\}/!d # From remaining lines, remove first 43 characters s/^.\{43\}//' | $SED -n ' # Join marker and all lines until next marker into a single line /^====MARK====/ b para H $ b para b :para x s/\n//g # Remove the marker s/^====MARK====// # Remove trailing dots and whitespace s/[\. \t]*$// # Print /./p' | # we now have a list, one entry per line, of the stringified # contents of the appropriate section of all members of the # archive that possess that section. Heuristic: eliminate # all those that have a first or second character that is # a '.' (that is, objdump's representation of an unprintable # character.) This should work for all archives with less than # 0x302f exports -- but will fail for DLLs whose name actually # begins with a literal '.' or a single character followed by # a '.'. # # Of those that remain, print the first one. $SED -e '/^\./d;/^.\./d;q' } # func_cygming_dll_for_implib_fallback ARG # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # # This fallback implementation is for use when $DLLTOOL # does not support the --identify-strict option. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib_fallback () { $debug_cmd if func_cygming_gnu_implib_p "$1"; then # binutils import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` elif func_cygming_ms_implib_p "$1"; then # ms-generated import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` else # unknown sharedlib_from_linklib_result= fi } # func_extract_an_archive dir oldlib func_extract_an_archive () { $debug_cmd f_ex_an_ar_dir=$1; shift f_ex_an_ar_oldlib=$1 if test yes = "$lock_old_archive_extraction"; then lockfile=$f_ex_an_ar_oldlib.lock until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done fi func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ 'stat=$?; rm -f "$lockfile"; exit $stat' if test yes = "$lock_old_archive_extraction"; then $opt_dry_run || rm -f "$lockfile" fi if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" fi } # func_extract_archives gentop oldlib ... func_extract_archives () { $debug_cmd my_gentop=$1; shift my_oldlibs=${1+"$@"} my_oldobjs= my_xlib= my_xabs= my_xdir= for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" my_xlib=$func_basename_result my_xlib_u=$my_xlib while :; do case " $extracted_archives " in *" $my_xlib_u "*) func_arith $extracted_serial + 1 extracted_serial=$func_arith_result my_xlib_u=lt$extracted_serial-$my_xlib ;; *) break ;; esac done extracted_archives="$extracted_archives $my_xlib_u" my_xdir=$my_gentop/$my_xlib_u func_mkdir_p "$my_xdir" case $host in *-darwin*) func_verbose "Extracting $my_xabs" # Do not bother doing anything if just a dry run $opt_dry_run || { darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` func_basename "$darwin_archive" darwin_base_archive=$func_basename_result darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches; do func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch" $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive" cd "unfat-$$/$darwin_base_archive-$darwin_arch" func_extract_an_archive "`pwd`" "$darwin_base_archive" cd "$darwin_curdir" $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` $LIPO -create -output "$darwin_file" $darwin_files done # $darwin_filelist $RM -rf unfat-$$ cd "$darwin_orig_dir" else cd $darwin_orig_dir func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches } # !$opt_dry_run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` done func_extract_archives_result=$my_oldobjs } # func_emit_wrapper [arg=no] # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to # incorporate the script contents within a cygwin/mingw # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory where it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () { func_emit_wrapper_arg1=${1-no} $ECHO "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM (GNU $PACKAGE) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='$sed_quote_subst' # Be Bourne compatible if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variables: generated_by_libtool_version='$macro_version' notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$ECHO are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then file=\"\$0\"" qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` $ECHO "\ # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } ECHO=\"$qECHO\" fi # Very basic option parsing. These options are (a) specific to # the libtool wrapper, (b) are identical between the wrapper # /script/ and the wrapper /executable/ that is used only on # windows platforms, and (c) all begin with the string "--lt-" # (application programs are unlikely to have options that match # this pattern). # # There are only two supported options: --lt-debug and # --lt-dump-script. There is, deliberately, no --lt-help. # # The first argument to this parsing function should be the # script's $0 value, followed by "$@". lt_option_debug= func_parse_lt_options () { lt_script_arg0=\$0 shift for lt_opt do case \"\$lt_opt\" in --lt-debug) lt_option_debug=1 ;; --lt-dump-script) lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` cat \"\$lt_dump_D/\$lt_dump_F\" exit 0 ;; --lt-*) \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 exit 1 ;; esac done # Print the debug banner immediately: if test -n \"\$lt_option_debug\"; then echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2 fi } # Used when --lt-debug. Prints its arguments to stdout # (redirection is the responsibility of the caller) func_lt_dump_args () { lt_dump_args_N=1; for lt_arg do \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\" lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` done } # Core function for launching the target application func_exec_program_core () { " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $ECHO "\ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 exit 1 } # A function to encapsulate launching the target application # Strips options in the --lt-* namespace from \$@ and # launches target application with the remaining arguments. func_exec_program () { case \" \$* \" in *\\ --lt-*) for lt_wr_arg do case \$lt_wr_arg in --lt-*) ;; *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; esac shift done ;; esac func_exec_program_core \${1+\"\$@\"} } # Parse options func_parse_lt_options \"\$0\" \${1+\"\$@\"} # Find the directory that this script lives in. thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` done # Usually 'no', except on cygwin/mingw when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then # special case for '.' if test \"\$thisdir\" = \".\"; then thisdir=\`pwd\` fi # remove .libs from thisdir case \"\$thisdir\" in *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; $objdir ) thisdir=. ;; esac fi # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test yes = "$fast_install"; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $MKDIR \"\$progdir\" else $RM \"\$progdir/\$file\" fi" $ECHO "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else \$ECHO \"\$relink_command_output\" >&2 $RM \"\$progdir/\$file\" exit 1 fi fi $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $RM \"\$progdir/\$program\"; $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } $RM \"\$progdir/\$file\" fi" else $ECHO "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $ECHO "\ if test -f \"\$progdir/\$program\"; then" # fixup the dll searchpath if we need to. # # Fix the DLL searchpath if we need to. Do this before prepending # to shlibpath, because on Windows, both are PATH and uninstalled # libraries must come first. if test -n "$dllsearchpath"; then $ECHO "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi # Export our shlibpath_var if we have one. if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` export $shlibpath_var " fi $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. func_exec_program \${1+\"\$@\"} fi else # The program doesn't exist. \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " } # func_emit_cwrapperexe_src # emit the source code for a wrapper executable on stdout # Must ONLY be called from within func_mode_link because # it depends on a number of variable set therein. func_emit_cwrapperexe_src () { cat < #include #ifdef _MSC_VER # include # include # include #else # include # include # ifdef __CYGWIN__ # include # endif #endif #include #include #include #include #include #include #include #include #define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) /* declarations of non-ANSI functions */ #if defined __MINGW32__ # ifdef __STRICT_ANSI__ int _putenv (const char *); # endif #elif defined __CYGWIN__ # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif /* #elif defined other_platform || defined ... */ #endif /* portability defines, excluding path handling macros */ #if defined _MSC_VER # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv # define S_IXUSR _S_IEXEC #elif defined __MINGW32__ # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv #elif defined __CYGWIN__ # define HAVE_SETENV # define FOPEN_WB "wb" /* #elif defined other platforms ... */ #endif #if defined PATH_MAX # define LT_PATHMAX PATH_MAX #elif defined MAXPATHLEN # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef S_IXOTH # define S_IXOTH 0 #endif #ifndef S_IXGRP # define S_IXGRP 0 #endif /* path handling portability macros */ #ifndef DIR_SEPARATOR # define DIR_SEPARATOR '/' # define PATH_SEPARATOR ':' #endif #if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \ defined __OS2__ # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 # define DIR_SEPARATOR_2 '\\' # endif # ifndef PATH_SEPARATOR_2 # define PATH_SEPARATOR_2 ';' # endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #ifndef PATH_SEPARATOR_2 # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) #else /* PATH_SEPARATOR_2 */ # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) #endif /* PATH_SEPARATOR_2 */ #ifndef FOPEN_WB # define FOPEN_WB "w" #endif #ifndef _O_BINARY # define _O_BINARY 0 #endif #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free (stale); stale = 0; } \ } while (0) #if defined LT_DEBUGWRAPPER static int lt_debug = 1; #else static int lt_debug = 0; #endif const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ void *xmalloc (size_t num); char *xstrdup (const char *string); const char *base_name (const char *name); char *find_executable (const char *wrapper); char *chase_symlinks (const char *pathspec); int make_executable (const char *path); int check_executable (const char *path); char *strendzap (char *str, const char *pat); void lt_debugprintf (const char *file, int line, const char *fmt, ...); void lt_fatal (const char *file, int line, const char *message, ...); static const char *nonnull (const char *s); static const char *nonempty (const char *s); void lt_setenv (const char *name, const char *value); char *lt_extend_str (const char *orig_value, const char *add, int to_end); void lt_update_exe_path (const char *name, const char *value); void lt_update_lib_path (const char *name, const char *value); char **prepare_spawn (char **argv); void lt_dump_script (FILE *f); EOF cat <= 0) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return 1; else return 0; } int make_executable (const char *path) { int rval = 0; struct stat st; lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", nonempty (path)); if ((!path) || (!*path)) return 0; if (stat (path, &st) >= 0) { rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); } return rval; } /* Searches for the full path of the wrapper. Returns newly allocated full path name if found, NULL otherwise Does not chase symlinks, even on platforms that support them. */ char * find_executable (const char *wrapper) { int has_slash = 0; const char *p; const char *p_next; /* static buffer for getcwd */ char tmp[LT_PATHMAX + 1]; size_t tmp_len; char *concat_name; lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", nonempty (wrapper)); if ((wrapper == NULL) || (*wrapper == '\0')) return NULL; /* Absolute path? */ #if defined HAVE_DOS_BASED_FILE_SYSTEM if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } else { #endif if (IS_DIR_SEPARATOR (wrapper[0])) { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } #if defined HAVE_DOS_BASED_FILE_SYSTEM } #endif for (p = wrapper; *p; p++) if (*p == '/') { has_slash = 1; break; } if (!has_slash) { /* no slashes; search PATH */ const char *path = getenv ("PATH"); if (path != NULL) { for (p = path; *p; p = p_next) { const char *q; size_t p_len; for (q = p; *q; q++) if (IS_PATH_SEPARATOR (*q)) break; p_len = (size_t) (q - p); p_next = (*q == '\0' ? q : q + 1); if (p_len == 0) { /* empty path: current directory */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); } else { concat_name = XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, p, p_len); concat_name[p_len] = '/'; strcpy (concat_name + p_len + 1, wrapper); } if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } } /* not found in PATH; assume curdir */ } /* Relative path | not found in path: prepend cwd */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); return NULL; } char * chase_symlinks (const char *pathspec) { #ifndef S_ISLNK return xstrdup (pathspec); #else char buf[LT_PATHMAX]; struct stat s; char *tmp_pathspec = xstrdup (pathspec); char *p; int has_symlinks = 0; while (strlen (tmp_pathspec) && !has_symlinks) { lt_debugprintf (__FILE__, __LINE__, "checking path component for symlinks: %s\n", tmp_pathspec); if (lstat (tmp_pathspec, &s) == 0) { if (S_ISLNK (s.st_mode) != 0) { has_symlinks = 1; break; } /* search backwards for last DIR_SEPARATOR */ p = tmp_pathspec + strlen (tmp_pathspec) - 1; while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) p--; if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) { /* no more DIR_SEPARATORS left */ break; } *p = '\0'; } else { lt_fatal (__FILE__, __LINE__, "error accessing file \"%s\": %s", tmp_pathspec, nonnull (strerror (errno))); } } XFREE (tmp_pathspec); if (!has_symlinks) { return xstrdup (pathspec); } tmp_pathspec = realpath (pathspec, buf); if (tmp_pathspec == 0) { lt_fatal (__FILE__, __LINE__, "could not follow symlinks for %s", pathspec); } return xstrdup (tmp_pathspec); #endif } char * strendzap (char *str, const char *pat) { size_t len, patlen; assert (str != NULL); assert (pat != NULL); len = strlen (str); patlen = strlen (pat); if (patlen <= len) { str += len - patlen; if (STREQ (str, pat)) *str = '\0'; } return str; } void lt_debugprintf (const char *file, int line, const char *fmt, ...) { va_list args; if (lt_debug) { (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); va_start (args, fmt); (void) vfprintf (stderr, fmt, args); va_end (args); } } static void lt_error_core (int exit_status, const char *file, int line, const char *mode, const char *message, va_list ap) { fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *file, int line, const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); va_end (ap); } static const char * nonnull (const char *s) { return s ? s : "(null)"; } static const char * nonempty (const char *s) { return (s && !*s) ? "(empty)" : nonnull (s); } void lt_setenv (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_setenv) setting '%s' to '%s'\n", nonnull (name), nonnull (value)); { #ifdef HAVE_SETENV /* always make a copy, for consistency with !HAVE_SETENV */ char *str = xstrdup (value); setenv (name, str, 1); #else size_t len = strlen (name) + 1 + strlen (value) + 1; char *str = XMALLOC (char, len); sprintf (str, "%s=%s", name, value); if (putenv (str) != EXIT_SUCCESS) { XFREE (str); } #endif } } char * lt_extend_str (const char *orig_value, const char *add, int to_end) { char *new_value; if (orig_value && *orig_value) { size_t orig_value_len = strlen (orig_value); size_t add_len = strlen (add); new_value = XMALLOC (char, add_len + orig_value_len + 1); if (to_end) { strcpy (new_value, orig_value); strcpy (new_value + orig_value_len, add); } else { strcpy (new_value, add); strcpy (new_value + add_len, orig_value); } } else { new_value = xstrdup (add); } return new_value; } void lt_update_exe_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); /* some systems can't cope with a ':'-terminated path #' */ size_t len = strlen (new_value); while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { new_value[--len] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); } } void lt_update_lib_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); } } EOF case $host_os in mingw*) cat <<"EOF" /* Prepares an argument vector before calling spawn(). Note that spawn() does not by itself call the command interpreter (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&v); v.dwPlatformId == VER_PLATFORM_WIN32_NT; }) ? "cmd.exe" : "command.com"). Instead it simply concatenates the arguments, separated by ' ', and calls CreateProcess(). We must quote the arguments since Win32 CreateProcess() interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a special way: - Space and tab are interpreted as delimiters. They are not treated as delimiters if they are surrounded by double quotes: "...". - Unescaped double quotes are removed from the input. Their only effect is that within double quotes, space and tab are treated like normal characters. - Backslashes not followed by double quotes are not special. - But 2*n+1 backslashes followed by a double quote become n backslashes followed by a double quote (n >= 0): \" -> " \\\" -> \" \\\\\" -> \\" */ #define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" #define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" char ** prepare_spawn (char **argv) { size_t argc; char **new_argv; size_t i; /* Count number of arguments. */ for (argc = 0; argv[argc] != NULL; argc++) ; /* Allocate new argument vector. */ new_argv = XMALLOC (char *, argc + 1); /* Put quoted arguments into the new argument vector. */ for (i = 0; i < argc; i++) { const char *string = argv[i]; if (string[0] == '\0') new_argv[i] = xstrdup ("\"\""); else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) { int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); size_t length; unsigned int backslashes; const char *s; char *quoted_string; char *p; length = 0; backslashes = 0; if (quote_around) length++; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') length += backslashes + 1; length++; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) length += backslashes + 1; quoted_string = XMALLOC (char, length + 1); p = quoted_string; backslashes = 0; if (quote_around) *p++ = '"'; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') { unsigned int j; for (j = backslashes + 1; j > 0; j--) *p++ = '\\'; } *p++ = c; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) { unsigned int j; for (j = backslashes; j > 0; j--) *p++ = '\\'; *p++ = '"'; } *p = '\0'; new_argv[i] = quoted_string; } else new_argv[i] = (char *) string; } new_argv[argc] = NULL; return new_argv; } EOF ;; esac cat <<"EOF" void lt_dump_script (FILE* f) { EOF func_emit_wrapper yes | $SED -n -e ' s/^\(.\{79\}\)\(..*\)/\1\ \2/ h s/\([\\"]\)/\\\1/g s/$/\\n/ s/\([^\n]*\).*/ fputs ("\1", f);/p g D' cat <<"EOF" } EOF } # end: func_emit_cwrapperexe_src # func_win32_import_lib_p ARG # True if ARG is an import lib, as indicated by $file_magic_cmd func_win32_import_lib_p () { $debug_cmd case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in *import*) : ;; *) false ;; esac } # func_suncc_cstd_abi # !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!! # Several compiler flags select an ABI that is incompatible with the # Cstd library. Avoid specifying it if any are in CXXFLAGS. func_suncc_cstd_abi () { $debug_cmd case " $compile_command " in *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*) suncc_use_cstd_abi=no ;; *) suncc_use_cstd_abi=yes ;; esac } # func_mode_link arg... func_mode_link () { $debug_cmd case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # what system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll that has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes ;; *) allow_undefined=yes ;; esac libtool_args=$nonopt base_compile="$nonopt $@" compile_command=$nonopt finalize_command=$nonopt compile_rpath= finalize_rpath= compile_shlibpath= finalize_shlibpath= convenience= old_convenience= deplibs= old_deplibs= compiler_flags= linker_flags= dllsearchpath= lib_search_path=`pwd` inst_prefix_dir= new_inherited_linker_flags= avoid_version=no bindir= dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= os2dllname= non_pic_objects= precious_files_regex= prefer_static_libs=no preload=false prev= prevarg= release= rpath= xrpath= perm_rpath= temp_rpath= thread_safe=no vinfo= vinfo_number=no weak_libs= single_module=$wl-single_module func_infer_tag $base_compile # We need to know -static, to get the right output filenames. for arg do case $arg in -shared) test yes != "$build_libtool_libs" \ && func_fatal_configuration "cannot build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; -static) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=built ;; -static-libtool-libs) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; esac build_libtool_libs=no build_old_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg=$1 shift func_quote_for_eval "$arg" qarg=$func_quote_for_eval_unquoted_result func_append libtool_args " $func_quote_for_eval_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) func_append compile_command " @OUTPUT@" func_append finalize_command " @OUTPUT@" ;; esac case $prev in bindir) bindir=$arg prev= continue ;; dlfiles|dlprefiles) $preload || { # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" preload=: } case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test no = "$dlself"; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test dlprefiles = "$prev"; then dlself=yes elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test dlfiles = "$prev"; then func_append dlfiles " $arg" else func_append dlprefiles " $arg" fi prev= continue ;; esac ;; expsyms) export_symbols=$arg test -f "$arg" \ || func_fatal_error "symbol file '$arg' does not exist" prev= continue ;; expsyms_regex) export_symbols_regex=$arg prev= continue ;; framework) case $host in *-*-darwin*) case "$deplibs " in *" $qarg.ltframework "*) ;; *) func_append deplibs " $qarg.ltframework" # this is fixed later ;; esac ;; esac prev= continue ;; inst_prefix) inst_prefix_dir=$arg prev= continue ;; mllvm) # Clang does not use LLVM to link, so we can simply discard any # '-mllvm $arg' options when doing the link step. prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat "$save_arg"` do # func_append moreargs " $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test none = "$pic_object" && test none = "$non_pic_object"; then func_fatal_error "cannot find name of object for '$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result if test none != "$pic_object"; then # Prepend the subdirectory the object is found in. pic_object=$xdir$pic_object if test dlfiles = "$prev"; then if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test dlprefiles = "$prev"; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg=$pic_object fi # Non-PIC object. if test none != "$non_pic_object"; then # Prepend the subdirectory the object is found in. non_pic_object=$xdir$non_pic_object # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test none = "$pic_object"; then arg=$non_pic_object fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object=$pic_object func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "'$arg' is not a valid libtool object" fi fi done else func_fatal_error "link input file '$arg' does not exist" fi arg=$save_arg prev= continue ;; os2dllname) os2dllname=$arg prev= continue ;; precious_regex) precious_files_regex=$arg prev= continue ;; release) release=-$arg prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac if test rpath = "$prev"; then case "$rpath " in *" $arg "*) ;; *) func_append rpath " $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) func_append xrpath " $arg" ;; esac fi prev= continue ;; shrext) shrext_cmds=$arg prev= continue ;; weak) func_append weak_libs " $arg" prev= continue ;; xcclinker) func_append linker_flags " $qarg" func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xcompiler) func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xlinker) func_append linker_flags " $qarg" func_append compiler_flags " $wl$qarg" prev= func_append compile_command " $wl$qarg" func_append finalize_command " $wl$qarg" continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg=$arg case $arg in -all-static) if test -n "$link_static_flag"; then # See comment for -static flag below, for more details. func_append compile_command " $link_static_flag" func_append finalize_command " $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. func_fatal_error "'-allow-undefined' must not be used because it is the default" ;; -avoid-version) avoid_version=yes continue ;; -bindir) prev=bindir continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi if test X-export-symbols = "X$arg"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=framework continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) func_append compile_command " $arg" func_append finalize_command " $arg" ;; esac continue ;; -L*) func_stripname "-L" '' "$arg" if test -z "$func_stripname_result"; then if test "$#" -gt 0; then func_fatal_error "require no space between '-L' and '$1'" else func_fatal_error "need path for '-L' option" fi fi func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ func_fatal_error "cannot determine absolute directory name of '$dir'" dir=$absdir ;; esac case "$deplibs " in *" -L$dir "* | *" $arg "*) # Will only happen for absolute or sysroot arguments ;; *) # Preserve sysroot, but never include relative directories case $dir in [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; *) func_append deplibs " -L$dir" ;; esac func_append lib_search_path " $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; ::) dllsearchpath=$dir;; *) func_append dllsearchpath ":$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac continue ;; -l*) if test X-lc = "X$arg" || test X-lm = "X$arg"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) # These systems don't actually have a C or math library (as such) continue ;; *-*-os2*) # These systems don't actually have a C library (as such) test X-lc = "X$arg" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) # Do not include libc due to us having libc/libc_r. test X-lc = "X$arg" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework func_append deplibs " System.ltframework" continue ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype test X-lc = "X$arg" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work test X-lc = "X$arg" && continue ;; esac elif test X-lc_r = "X$arg"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi func_append deplibs " $arg" continue ;; -mllvm) prev=mllvm continue ;; -module) module=yes continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. -model|-arch|-isysroot|--sysroot) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" prev=xcompiler continue ;; -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) func_append new_inherited_linker_flags " $arg" ;; esac continue ;; -multi_module) single_module=$wl-multi_module continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. func_warning "'-no-install' is ignored for $host" func_warning "assuming '-no-fast-install' instead" fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -os2dllname) prev=os2dllname continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) func_stripname '-R' '' "$arg" dir=$func_stripname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; =*) func_stripname '=' '' "$dir" dir=$lt_sysroot$func_stripname_result ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac continue ;; -shared) # The effects of -shared are defined in a previous loop. continue ;; -shrext) prev=shrext continue ;; -static | -static-libtool-libs) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -weak) prev=weak continue ;; -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= save_ifs=$IFS; IFS=, for flag in $args; do IFS=$save_ifs func_quote_for_eval "$flag" func_append arg " $func_quote_for_eval_result" func_append compiler_flags " $func_quote_for_eval_result" done IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Wl,*) func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= save_ifs=$IFS; IFS=, for flag in $args; do IFS=$save_ifs func_quote_for_eval "$flag" func_append arg " $wl$func_quote_for_eval_result" func_append compiler_flags " $wl$func_quote_for_eval_result" func_append linker_flags " $func_quote_for_eval_result" done IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # -msg_* for osf cc -msg_*) func_quote_for_eval "$arg" arg=$func_quote_for_eval_result ;; # Flags to be passed through unchanged, with rationale: # -64, -mips[0-9] enable 64-bit mode for the SGI compiler # -r[0-9][0-9]* specify processor for the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler # +DA*, +DD* enable 64-bit mode for the HP compiler # -q* compiler args for the IBM compiler # -m*, -t[45]*, -txscale* architecture-specific flags for GCC # -F/path path to uninstalled frameworks, gcc on darwin # -p, -pg, --coverage, -fprofile-* profiling flags for GCC # -fstack-protector* stack protector flags for GCC # @file GCC response files # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization # -stdlib=* select c++ std lib with clang -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*) func_quote_for_eval "$arg" arg=$func_quote_for_eval_result func_append compile_command " $arg" func_append finalize_command " $arg" func_append compiler_flags " $arg" continue ;; -Z*) if test os2 = "`expr $host : '.*\(os2\)'`"; then # OS/2 uses -Zxxx to specify OS/2-specific options compiler_flags="$compiler_flags $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case $arg in -Zlinker | -Zstack) prev=xcompiler ;; esac continue else # Otherwise treat like 'Some other compiler flag' below func_quote_for_eval "$arg" arg=$func_quote_for_eval_result fi ;; # Some other compiler flag. -* | +*) func_quote_for_eval "$arg" arg=$func_quote_for_eval_result ;; *.$objext) # A standard object. func_append objs " $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test none = "$pic_object" && test none = "$non_pic_object"; then func_fatal_error "cannot find name of object for '$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result test none = "$pic_object" || { # Prepend the subdirectory the object is found in. pic_object=$xdir$pic_object if test dlfiles = "$prev"; then if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test dlprefiles = "$prev"; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg=$pic_object } # Non-PIC object. if test none != "$non_pic_object"; then # Prepend the subdirectory the object is found in. non_pic_object=$xdir$non_pic_object # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test none = "$pic_object"; then arg=$non_pic_object fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object=$pic_object func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "'$arg' is not a valid libtool object" fi fi ;; *.$libext) # An archive. func_append deplibs " $arg" func_append old_deplibs " $arg" continue ;; *.la) # A libtool-controlled library. func_resolve_sysroot "$arg" if test dlfiles = "$prev"; then # This library was specified with -dlopen. func_append dlfiles " $func_resolve_sysroot_result" prev= elif test dlprefiles = "$prev"; then # The library was specified with -dlpreopen. func_append dlprefiles " $func_resolve_sysroot_result" prev= else func_append deplibs " $func_resolve_sysroot_result" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. func_quote_for_eval "$arg" arg=$func_quote_for_eval_result ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then func_append compile_command " $arg" func_append finalize_command " $arg" fi done # argument parsing loop test -n "$prev" && \ func_fatal_help "the '$prevarg' option requires an argument" if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" func_append compile_command " $arg" func_append finalize_command " $arg" fi oldlibs= # calculate the name of the file, without its directory func_basename "$output" outputname=$func_basename_result libobjs_save=$libobjs if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" # Definition is injected by LT_CONFIG during libtool generation. func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH" func_dirname "$output" "/" "" output_objdir=$func_dirname_result$objdir func_to_tool_file "$output_objdir/" tool_output_objdir=$func_to_tool_file_result # Create the object directory. func_mkdir_p "$output_objdir" # Determine the type of output case $output in "") func_fatal_help "you must specify an output file" ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if $opt_preserve_dup_deps; then case "$libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append libs " $deplib" done if test lib = "$linkmode"; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if $opt_duplicate_compiler_generated_deps; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; esac func_append pre_post_deps " $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv dlpreopen link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) func_fatal_help "libraries can '-dlopen' only libtool libraries: $file" ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=false newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... if test lib,link = "$linkmode,$pass"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done deplibs=$tmp_deplibs fi if test lib,link = "$linkmode,$pass" || test prog,scan = "$linkmode,$pass"; then libs=$deplibs deplibs= fi if test prog = "$linkmode"; then case $pass in dlopen) libs=$dlfiles ;; dlpreopen) libs=$dlprefiles ;; link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; esac fi if test lib,dlpreopen = "$linkmode,$pass"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs dependency_libs= func_resolve_sysroot "$lib" case $lib in *.la) func_source "$func_resolve_sysroot_result" ;; esac # Collect preopened libtool deplibs, except any this library # has declared as weak libs for deplib in $dependency_libs; do func_basename "$deplib" deplib_base=$func_basename_result case " $weak_libs " in *" $deplib_base "*) ;; *) func_append deplibs " $deplib" ;; esac done done libs=$dlprefiles fi if test dlopen = "$pass"; then # Collect dlpreopened libraries save_deplibs=$deplibs deplibs= fi for deplib in $libs; do lib= found=false case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append compiler_flags " $deplib" if test lib = "$linkmode"; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -l*) if test lib != "$linkmode" && test prog != "$linkmode"; then func_warning "'-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result if test lib = "$linkmode"; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" fi for searchdir in $searchdirs; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib=$searchdir/lib$name$search_ext if test -f "$lib"; then if test .la = "$search_ext"; then found=: else found=false fi break 2 fi done done if $found; then # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $deplib "*) if func_lalib_p "$lib"; then library_names= old_library= func_source "$lib" for l in $old_library $library_names; do ll=$l done if test "X$ll" = "X$old_library"; then # only static version available found=false func_dirname "$lib" "" "." ladir=$func_dirname_result lib=$ladir/$old_library if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi else # deplib doesn't seem to be a libtool library if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" fi continue fi ;; # -l *.ltframework) if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" if test lib = "$linkmode"; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test conv = "$pass" && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; prog) if test conv = "$pass"; then deplibs="$deplib $deplibs" continue fi if test scan = "$pass"; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; *) func_warning "'-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) if test link = "$pass"; then func_stripname '-R' '' "$deplib" func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) func_resolve_sysroot "$deplib" lib=$func_resolve_sysroot_result ;; *.$libext) if test conv = "$pass"; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) # Linking convenience modules into shared libraries is allowed, # but linking other static libraries is non-portable. case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) valid_a_lib=false case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=: fi ;; pass_all) valid_a_lib=: ;; esac if $valid_a_lib; then echo $ECHO "*** Warning: Linking the shared library $output against the" $ECHO "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" else echo $ECHO "*** Warning: Trying to link with static lib archive $deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because the file extensions .$libext of this argument makes me believe" echo "*** that it is just a static archive that I should not use here." fi ;; esac continue ;; prog) if test link != "$pass"; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test conv = "$pass"; then deplibs="$deplib $deplibs" elif test prog = "$linkmode"; then if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then # If there is no dlopen support or we're linking statically, # we need to preload. func_append newdlprefiles " $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append newdlfiles " $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=: continue ;; esac # case $deplib $found || test -f "$lib" \ || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'" # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ || func_fatal_error "'$lib' is not a valid libtool archive" func_dirname "$lib" "" "." ladir=$func_dirname_result dlname= dlopen= dlpreopen= libdir= library_names= old_library= inherited_linker_flags= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file func_source "$lib" # Convert "-framework foo" to "foo.ltframework" if test -n "$inherited_linker_flags"; then tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do case " $new_inherited_linker_flags " in *" $tmp_inherited_linker_flag "*) ;; *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; esac done fi dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` if test lib,link = "$linkmode,$pass" || test prog,scan = "$linkmode,$pass" || { test prog != "$linkmode" && test lib != "$linkmode"; }; then test -n "$dlopen" && func_append dlfiles " $dlopen" test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" fi if test conv = "$pass"; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then func_fatal_error "cannot find name of link library for '$lib'" fi # It is a libtool convenience library, so add in its objects. func_append convenience " $ladir/$objdir/$old_library" func_append old_convenience " $ladir/$objdir/$old_library" elif test prog != "$linkmode" && test lib != "$linkmode"; then func_fatal_error "'$lib' is not a convenience library" fi tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done continue fi # $pass = conv # Get the name of the library we link against. linklib= if test -n "$old_library" && { test yes = "$prefer_static_libs" || test built,no = "$prefer_static_libs,$installed"; }; then linklib=$old_library else for l in $old_library $library_names; do linklib=$l done fi if test -z "$linklib"; then func_fatal_error "cannot find name of link library for '$lib'" fi # This library was specified with -dlopen. if test dlopen = "$pass"; then test -z "$libdir" \ && func_fatal_error "cannot -dlopen a convenience library: '$lib'" if test -z "$dlname" || test yes != "$dlopen_support" || test no = "$build_libtool_libs" then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. func_append dlprefiles " $lib $dependency_libs" else func_append newdlfiles " $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then func_warning "cannot determine absolute directory name of '$ladir'" func_warning "passing it literally to the linker, although it might fail" abs_ladir=$ladir fi ;; esac func_basename "$lib" laname=$func_basename_result # Find the relevant object directory and library name. if test yes = "$installed"; then if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then func_warning "library '$lib' was moved." dir=$ladir absdir=$abs_ladir libdir=$abs_ladir else dir=$lt_sysroot$libdir absdir=$lt_sysroot$libdir fi test yes = "$hardcode_automatic" && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir=$ladir absdir=$abs_ladir # Remove this search path later func_append notinst_path " $abs_ladir" else dir=$ladir/$objdir absdir=$abs_ladir/$objdir # Remove this search path later func_append notinst_path " $abs_ladir" fi fi # $installed = yes func_stripname 'lib' '.la' "$laname" name=$func_stripname_result # This library was specified with -dlpreopen. if test dlpreopen = "$pass"; then if test -z "$libdir" && test prog = "$linkmode"; then func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'" fi case $host in # special handling for platforms with PE-DLLs. *cygwin* | *mingw* | *cegcc* ) # Linker will automatically link against shared library if both # static and shared are present. Therefore, ensure we extract # symbols from the import library if a shared library is present # (otherwise, the dlopen module name will be incorrect). We do # this by putting the import library name into $newdlprefiles. # We recover the dlopen module name by 'saving' the la file # name in a special purpose variable, and (later) extracting the # dlname from the la file. if test -n "$dlname"; then func_tr_sh "$dir/$linklib" eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" func_append newdlprefiles " $dir/$linklib" else func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" fi ;; * ) # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then func_append newdlprefiles " $dir/$dlname" else func_append newdlprefiles " $dir/$linklib" fi ;; esac fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test lib = "$linkmode"; then deplibs="$dir/$old_library $deplibs" elif test prog,link = "$linkmode,$pass"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test prog = "$linkmode" && test link != "$pass"; then func_append newlib_search_path " $ladir" deplibs="$lib $deplibs" linkalldeplibs=false if test no != "$link_all_deplibs" || test -z "$library_names" || test no = "$build_libtool_libs"; then linkalldeplibs=: fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; esac # Need to link against all dependency_libs? if $linkalldeplibs; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done # for deplib continue fi # $linkmode = prog... if test prog,link = "$linkmode,$pass"; then if test -n "$library_names" && { { test no = "$prefer_static_libs" || test built,yes = "$prefer_static_libs,$installed"; } || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then # Make sure the rpath contains only unique directories. case $temp_rpath: in *"$absdir:"*) ;; *) func_append temp_rpath "$absdir:" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi # $linkmode,$pass = prog,link... if $alldeplibs && { test pass_all = "$deplibs_check_method" || { test yes = "$build_libtool_libs" && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs if test built = "$use_static_libs" && test yes = "$installed"; then use_static_libs=no fi if test -n "$library_names" && { test no = "$use_static_libs" || test -z "$old_library"; }; then case $host in *cygwin* | *mingw* | *cegcc* | *os2*) # No point in relinking DLLs because paths are not encoded func_append notinst_deplibs " $lib" need_relink=no ;; *) if test no = "$installed"; then func_append notinst_deplibs " $lib" need_relink=yes fi ;; esac # This is a shared library # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! dlopenmodule= for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then dlopenmodule=$dlpremoduletest break fi done if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then echo if test prog = "$linkmode"; then $ECHO "*** Warning: Linking the executable $output against the loadable module" else $ECHO "*** Warning: Linking the shared library $output against the loadable module" fi $ECHO "*** $linklib is not portable!" fi if test lib = "$linkmode" && test yes = "$hardcode_into_libs"; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names shift realname=$1 shift libname=`eval "\\$ECHO \"$libname_spec\""` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname=$dlname elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw* | *cegcc* | *os2*) func_arith $current - $age major=$func_arith_result versuffix=-$major ;; esac eval soname=\"$soname_spec\" else soname=$realname fi # Make a new name for the extract_expsyms_cmds to use soroot=$soname func_basename "$soroot" soname=$func_basename_result func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else func_verbose "extracting exported symbol list from '$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else func_verbose "generating import library for '$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test prog = "$linkmode" || test relink != "$opt_mode"; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test no = "$hardcode_direct"; then add=$dir/$linklib case $host in *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;; *-*-sysv4*uw2*) add_dir=-L$dir ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ *-*-unixware7*) add_dir=-L$dir ;; *-*-darwin* ) # if the lib is a (non-dlopened) module then we cannot # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | $GREP ": [^:]* bundle" >/dev/null; then if test "X$dlopenmodule" != "X$lib"; then $ECHO "*** Warning: lib $linklib is a module, not a shared library" if test -z "$old_library"; then echo echo "*** And there doesn't seem to be a static archive available" echo "*** The link will probably fail, sorry" else add=$dir/$old_library fi elif test -n "$old_library"; then add=$dir/$old_library fi fi esac elif test no = "$hardcode_minus_L"; then case $host in *-*-sunos*) add_shlibpath=$dir ;; esac add_dir=-L$dir add=-l$name elif test no = "$hardcode_shlibpath_var"; then add_shlibpath=$dir add=-l$name else lib_linked=no fi ;; relink) if test yes = "$hardcode_direct" && test no = "$hardcode_direct_absolute"; then add=$dir/$linklib elif test yes = "$hardcode_minus_L"; then add_dir=-L$absdir # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add=-l$name elif test yes = "$hardcode_shlibpath_var"; then add_shlibpath=$dir add=-l$name else lib_linked=no fi ;; *) lib_linked=no ;; esac if test yes != "$lib_linked"; then func_fatal_configuration "unsupported hardcode properties" fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) func_append compile_shlibpath "$add_shlibpath:" ;; esac fi if test prog = "$linkmode"; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test yes != "$hardcode_direct" && test yes != "$hardcode_minus_L" && test yes = "$hardcode_shlibpath_var"; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac fi fi fi if test prog = "$linkmode" || test relink = "$opt_mode"; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test yes = "$hardcode_direct" && test no = "$hardcode_direct_absolute"; then add=$libdir/$linklib elif test yes = "$hardcode_minus_L"; then add_dir=-L$libdir add=-l$name elif test yes = "$hardcode_shlibpath_var"; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac add=-l$name elif test yes = "$hardcode_automatic"; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib"; then add=$inst_prefix_dir$libdir/$linklib else add=$libdir/$linklib fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir=-L$libdir # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add=-l$name fi if test prog = "$linkmode"; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test prog = "$linkmode"; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test unsupported != "$hardcode_direct"; then test -n "$old_library" && linklib=$old_library compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test yes = "$build_libtool_libs"; then # Not a shared library if test pass_all != "$deplibs_check_method"; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. echo $ECHO "*** Warning: This system cannot link to static lib archive $lib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have." if test yes = "$module"; then echo "*** But as you try to build a module library, libtool will still create " echo "*** a static module, that should work as long as the dlopening application" echo "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using 'nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** 'nm' from GNU binutils and a full rebuild may help." fi if test no = "$build_old_libs"; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test lib = "$linkmode"; then if test -n "$dependency_libs" && { test yes != "$hardcode_into_libs" || test yes = "$build_old_libs" || test yes = "$link_static"; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) func_stripname '-R' '' "$libdir" temp_xrpath=$func_stripname_result case " $xrpath " in *" $temp_xrpath "*) ;; *) func_append xrpath " $temp_xrpath";; esac;; *) func_append temp_deplibs " $libdir";; esac done dependency_libs=$temp_deplibs fi func_append newlib_search_path " $absdir" # Link against this library test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result";; *) func_resolve_sysroot "$deplib" ;; esac if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $func_resolve_sysroot_result "*) func_append specialdeplibs " $func_resolve_sysroot_result" ;; esac fi func_append tmp_libs " $func_resolve_sysroot_result" done if test no != "$link_all_deplibs"; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do path= case $deplib in -L*) path=$deplib ;; *.la) func_resolve_sysroot "$deplib" deplib=$func_resolve_sysroot_result func_dirname "$deplib" "" "." dir=$func_dirname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then func_warning "cannot determine absolute directory name of '$dir'" absdir=$dir fi ;; esac if $GREP "^installed=no" $deplib > /dev/null; then case $host in *-*-darwin*) depdepl= eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names"; then for tmp in $deplibrary_names; do depdepl=$tmp done if test -f "$absdir/$objdir/$depdepl"; then depdepl=$absdir/$objdir/$depdepl darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl" func_append linker_flags " -dylib_file $darwin_install_name:$depdepl" path= fi fi ;; *) path=-L$absdir/$objdir ;; esac else eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "'$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ func_warning "'$deplib' seems to be moved" path=-L$absdir fi ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs if test link = "$pass"; then if test prog = "$linkmode"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi dependency_libs=$newdependency_libs if test dlpreopen = "$pass"; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test dlopen != "$pass"; then test conv = "$pass" || { # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) func_append lib_search_path " $dir" ;; esac done newlib_search_path= } if test prog,link = "$linkmode,$pass"; then vars="compile_deplibs finalize_deplibs" else vars=deplibs fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) func_append tmp_libs " $deplib" ;; esac ;; *) func_append tmp_libs " $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Add Sun CC postdeps if required: test CXX = "$tagname" && { case $host_os in linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 func_suncc_cstd_abi if test no != "$suncc_use_cstd_abi"; then func_append postdeps ' -library=Cstd -library=Crun' fi ;; esac ;; solaris*) func_cc_basename "$CC" case $func_cc_basename_result in CC* | sunCC*) func_suncc_cstd_abi if test no != "$suncc_use_cstd_abi"; then func_append postdeps ' -library=Cstd -library=Crun' fi ;; esac ;; esac } # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i= ;; esac if test -n "$i"; then func_append tmp_libs " $i" fi done dependency_libs=$tmp_libs done # for pass if test prog = "$linkmode"; then dlfiles=$newdlfiles fi if test prog = "$linkmode" || test lib = "$linkmode"; then dlprefiles=$newdlprefiles fi case $linkmode in oldlib) if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then func_warning "'-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "'-l' and '-L' are ignored for archives" ;; esac test -n "$rpath" && \ func_warning "'-rpath' is ignored for archives" test -n "$xrpath" && \ func_warning "'-R' is ignored for archives" test -n "$vinfo" && \ func_warning "'-version-info/-version-number' is ignored for archives" test -n "$release" && \ func_warning "'-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ func_warning "'-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no oldlibs=$output func_append objs "$old_deplibs" ;; lib) # Make sure we only generate libraries of the form 'libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) test no = "$module" \ && func_fatal_help "libtool library '$output' must begin with 'lib'" if test no != "$need_lib_prefix"; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else func_stripname '' '.la' "$outputname" libname=$func_stripname_result fi ;; esac if test -n "$objs"; then if test pass_all != "$deplibs_check_method"; then func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs" else echo $ECHO "*** Warning: Linking the shared library $output against the non-libtool" $ECHO "*** objects $objs is not portable!" func_append libobjs " $objs" fi fi test no = "$dlself" \ || func_warning "'-dlopen self' is ignored for libtool libraries" set dummy $rpath shift test 1 -lt "$#" \ && func_warning "ignoring multiple '-rpath's for a libtool library" install_libdir=$1 oldlibs= if test -z "$rpath"; then if test yes = "$build_libtool_libs"; then # Building a libtool convenience library. # Some compilers have problems with a '.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi test -n "$vinfo" && \ func_warning "'-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ func_warning "'-release' is ignored for convenience libraries" else # Parse the version information argument. save_ifs=$IFS; IFS=: set dummy $vinfo 0 0 0 shift IFS=$save_ifs test -n "$7" && \ func_fatal_help "too many parameters to '-version-info'" # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major=$1 number_minor=$2 number_revision=$3 # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # that has an extra 1 added just for fun # case $version_type in # correct linux to gnu/linux during the next big refactor darwin|freebsd-elf|linux|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age=$number_minor revision=$number_revision ;; freebsd-aout|qnx|sunos) current=$number_major revision=$number_minor age=0 ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result age=$number_minor revision=$number_minor lt_irix_increment=no ;; esac ;; no) current=$1 revision=$2 age=$3 ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "CURRENT '$current' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "REVISION '$revision' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "AGE '$age' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then func_error "AGE '$age' is greater than the current interface number '$current'" func_fatal_error "'$vinfo' is not valid version information" fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" # On Darwin other compilers case $CC in nagfor*) verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" ;; *) verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" ;; esac ;; freebsd-aout) major=.$current versuffix=.$current.$revision ;; freebsd-elf) func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision ;; irix | nonstopux) if test no = "$lt_irix_increment"; then func_arith $current - $age else func_arith $current - $age + 1 fi major=$func_arith_result case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring=$verstring_prefix$major.$revision # Add in all the interfaces that we are compatible with. loop=$revision while test 0 -ne "$loop"; do func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring=$verstring_prefix$major.$iface:$verstring done # Before this point, $major must not contain '.'. major=.$major versuffix=$major.$revision ;; linux) # correct to gnu/linux during the next big refactor func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision ;; osf) func_arith $current - $age major=.$func_arith_result versuffix=.$current.$age.$revision verstring=$current.$age.$revision # Add in all the interfaces that we are compatible with. loop=$age while test 0 -ne "$loop"; do func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring=$verstring:$iface.0 done # Make executables depend on our current version. func_append verstring ":$current.0" ;; qnx) major=.$current versuffix=.$current ;; sco) major=.$current versuffix=.$current ;; sunos) major=.$current versuffix=.$current.$revision ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 file systems. func_arith $current - $age major=$func_arith_result versuffix=-$major ;; *) func_fatal_configuration "unknown library version type '$version_type'" ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring=0.0 ;; esac if test no = "$need_version"; then versuffix= else versuffix=.0.0 fi fi # Remove version info from name if versioning should be avoided if test yes,no = "$avoid_version,$need_version"; then major= versuffix= verstring= fi # Check to see if the archive will have undefined symbols. if test yes = "$allow_undefined"; then if test unsupported = "$allow_undefined_flag"; then if test yes = "$build_old_libs"; then func_warning "undefined symbols not allowed in $host shared libraries; building static only" build_libtool_libs=no else func_fatal_error "can't build $host shared library unless -no-undefined is specified" fi fi else # Don't allow undefined symbols. allow_undefined_flag=$no_undefined_flag fi fi func_generate_dlsyms "$libname" "$libname" : func_append libobjs " $symfileobj" test " " = "$libobjs" && libobjs= if test relink != "$opt_mode"; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$ECHO "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext | *.gcno) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*) if test -n "$precious_files_regex"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi func_append removelist " $p" ;; *) ;; esac done test -n "$removelist" && \ func_show_eval "${RM}r \$removelist" fi # Now set the variables for building old libraries. if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then func_append oldlibs " $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP` fi # Eliminate all temporary directories. #for path in $notinst_path; do # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` #done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do func_replace_sysroot "$libdir" func_append temp_xrpath " -R$func_replace_sysroot_result" case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles=$dlfiles dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) func_append dlfiles " $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles=$dlprefiles dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) func_append dlprefiles " $lib" ;; esac done if test yes = "$build_libtool_libs"; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework func_append deplibs " System.ltframework" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work ;; *) # Add libc to deplibs on all other systems if necessary. if test yes = "$build_libtool_need_lc"; then func_append deplibs " -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release= versuffix= major= newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $opt_dry_run || $RM conftest.c cat > conftest.c </dev/null` $nocaseglob else potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` fi for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null | $GREP " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib=$potent_lib while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | $SED 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;; *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib= break 2 fi done done fi if test -n "$a_deplib"; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib"; then $ECHO "*** with $libname but no candidates were found. (...for file magic test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a file magic. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` for a_deplib in $deplibs; do case $a_deplib in -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $a_deplib "*) func_append newdeplibs " $a_deplib" a_deplib= ;; esac fi if test -n "$a_deplib"; then libname=`eval "\\$ECHO \"$libname_spec\""` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib=$potent_lib # see symlink-check above in file_magic test if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib= break 2 fi done done fi if test -n "$a_deplib"; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib"; then $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a regex pattern. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; none | unknown | *) newdeplibs= tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` if test yes = "$allow_libtool_libs_with_static_runtimes"; then for i in $predeps $postdeps; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"` done fi case $tmp_deplibs in *[!\ \ ]*) echo if test none = "$deplibs_check_method"; then echo "*** Warning: inter-library dependencies are not supported in this platform." else echo "*** Warning: inter-library dependencies are not known to be supported." fi echo "*** All declared inter-library dependencies are being dropped." droppeddeps=yes ;; esac ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library with the System framework newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac if test yes = "$droppeddeps"; then if test yes = "$module"; then echo echo "*** Warning: libtool could not satisfy all declared inter-library" $ECHO "*** dependencies of module $libname. Therefore, libtool will create" echo "*** a static module, that should work as long as the dlopening" echo "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using 'nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** 'nm' from GNU binutils and a full rebuild may help." fi if test no = "$build_old_libs"; then oldlibs=$output_objdir/$libname.$libext build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else echo "*** The inter-library dependencies that have been dropped here will be" echo "*** automatically added whenever a program is linked with this library" echo "*** or is declared to -dlopen it." if test no = "$allow_undefined"; then echo echo "*** Since this library must not contain undefined symbols," echo "*** because either the platform does not support them or" echo "*** it was explicitly requested with -no-undefined," echo "*** libtool will only create a static version of it." if test no = "$build_old_libs"; then oldlibs=$output_objdir/$libname.$libext build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" case $host in *-*-darwin*) newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done deplibs=$new_libs # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test yes = "$build_libtool_libs"; then # Remove $wl instances when linking with ld. # FIXME: should test the right _cmds variable. case $archive_cmds in *\$LD\ *) wl= ;; esac if test yes = "$hardcode_into_libs"; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath=$finalize_rpath test relink = "$opt_mode" || rpath=$compile_rpath$rpath for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then func_replace_sysroot "$libdir" libdir=$func_replace_sysroot_result if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append dep_rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath=$finalize_shlibpath test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names shift realname=$1 shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname=$realname fi if test -z "$dlname"; then dlname=$soname fi lib=$output_objdir/$realname linknames= for link do func_append linknames " $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` test "X$libobjs" = "X " && libobjs= delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" export_symbols=$output_objdir/$libname.uexp func_append delfiles " $export_symbols" fi orig_export_symbols= case $host_os in cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile func_dll_def_p "$export_symbols" || { # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. orig_export_symbols=$export_symbols export_symbols= always_export_symbols=yes } fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then func_verbose "generating symbol list for '$libname.la'" export_symbols=$output_objdir/$libname.exp $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds save_ifs=$IFS; IFS='~' for cmd1 in $cmds; do IFS=$save_ifs # Take the normal branch if the nm_file_list_spec branch # doesn't work or if tool conversion is not needed. case $nm_file_list_spec~$to_tool_file_cmd in *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) try_normal_branch=yes eval cmd=\"$cmd1\" func_len " $cmd" len=$func_len_result ;; *) try_normal_branch=no ;; esac if test yes = "$try_normal_branch" \ && { test "$len" -lt "$max_cmd_len" \ || test "$max_cmd_len" -le -1; } then func_show_eval "$cmd" 'exit $?' skipped_export=false elif test -n "$nm_file_list_spec"; then func_basename "$output" output_la=$func_basename_result save_libobjs=$libobjs save_output=$output output=$output_objdir/$output_la.nm func_to_tool_file "$output" libobjs=$nm_file_list_spec$func_to_tool_file_result func_append delfiles " $output" func_verbose "creating $NM input file list: $output" for obj in $save_libobjs; do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > "$output" eval cmd=\"$cmd1\" func_show_eval "$cmd" 'exit $?' output=$save_output libobjs=$save_libobjs skipped_export=false else # The command line is too long to execute in one step. func_verbose "using reloadable object file for export list..." skipped_export=: # Break out early, otherwise skipped_export may be # set to false by a later but shorter cmd. break fi done IFS=$save_ifs if test -n "$export_symbols_regex" && test : != "$skipped_export"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols=$export_symbols test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test : != "$skipped_export" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for '$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands, which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) func_append tmp_deplibs " $test_deplib" ;; esac done deplibs=$tmp_deplibs if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && test yes = "$compiler_needs_object" && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. whole_archive_flag_spec= fi if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $convenience func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi fi if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" func_append linker_flags " $flag" fi # Make a backup of the uninstalled library when relinking if test relink = "$opt_mode"; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test yes = "$module" && test -n "$module_cmds"; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test : != "$skipped_export" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise # or, if using GNU ld and skipped_export is not :, use a linker # script. # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output func_basename "$output" output_la=$func_basename_result # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= last_robj= k=1 if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then output=$output_objdir/$output_la.lnkscript func_verbose "creating GNU ld script: $output" echo 'INPUT (' > $output for obj in $save_libobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done echo ')' >> $output func_append delfiles " $output" func_to_tool_file "$output" output=$func_to_tool_file_result elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then output=$output_objdir/$output_la.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= if test yes = "$compiler_needs_object"; then firstobj="$1 " shift fi for obj do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done func_append delfiles " $output" func_to_tool_file "$output" output=$firstobj\"$file_list_spec$func_to_tool_file_result\" else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." output=$output_objdir/$output_la-$k.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 # Loop over the list of objects to be linked. for obj in $save_libobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result if test -z "$objlist" || test "$len" -lt "$max_cmd_len"; then func_append objlist " $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test 1 -eq "$k"; then # The first file doesn't have a previous command to add. reload_objs=$objlist eval concat_cmds=\"$reload_cmds\" else # All subsequent reloadable object files will link in # the last one created. reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" fi last_robj=$output_objdir/$output_la-$k.$objext func_arith $k + 1 k=$func_arith_result output=$output_objdir/$output_la-$k.$objext objlist=" $obj" func_len " $last_robj" func_arith $len0 + $func_len_result len=$func_arith_result fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds$reload_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi func_append delfiles " $output" else output= fi ${skipped_export-false} && { func_verbose "generating symbol list for '$libname.la'" export_symbols=$output_objdir/$libname.exp $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi } test -n "$save_libobjs" && func_verbose "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs=$IFS; IFS='~' for cmd in $concat_cmds; do IFS=$save_ifs $opt_quiet || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test relink = "$opt_mode"; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS=$save_ifs if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi ${skipped_export-false} && { if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols=$export_symbols test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for '$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands, which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi } libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test yes = "$module" && test -n "$module_cmds"; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi fi if test -n "$delfiles"; then # Append the command to remove temporary files to $cmds. eval cmds=\"\$cmds~\$RM $delfiles\" fi # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi save_ifs=$IFS; IFS='~' for cmd in $cmds; do IFS=$sp$nl eval cmd=\"$cmd\" IFS=$save_ifs $opt_quiet || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test relink = "$opt_mode"; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS=$save_ifs # Restore the uninstalled library and exit if test relink = "$opt_mode"; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then if test -z "$whole_archive_flag_spec"; then func_show_eval '${RM}r "$gentop"' fi fi exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' fi done # If -module or -export-dynamic was specified, set the dlname. if test yes = "$module" || test yes = "$export_dynamic"; then # On all known operating systems, these are identical. dlname=$soname fi fi ;; obj) if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then func_warning "'-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "'-l' and '-L' are ignored for objects" ;; esac test -n "$rpath" && \ func_warning "'-rpath' is ignored for objects" test -n "$xrpath" && \ func_warning "'-R' is ignored for objects" test -n "$vinfo" && \ func_warning "'-version-info' is ignored for objects" test -n "$release" && \ func_warning "'-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ func_fatal_error "cannot build library object '$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" obj=$func_lo2o_result ;; *) libobj= obj=$output ;; esac # Delete the old objects. $opt_dry_run || $RM $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # if reload_cmds runs $LD directly, get rid of -Wl from # whole_archive_flag_spec and hope we can get by with turning comma # into space. case $reload_cmds in *\$LD[\ \$]*) wl= ;; esac if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags else gentop=$output_objdir/${obj}x func_append generated " $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # If we're not building shared, we need to use non_pic_objs test yes = "$build_libtool_libs" || libobjs=$non_pic_objects # Create the old-style object. reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs output=$obj func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS fi test yes = "$build_libtool_libs" || { if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS } if test -n "$pic_flag" || test default != "$pic_mode"; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output=$libobj func_execute_cmds "$reload_cmds" 'exit $?' fi if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) func_stripname '' '.exe' "$output" output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ func_warning "'-version-info' is ignored for programs" test -n "$release" && \ func_warning "'-release' is ignored for programs" $preload \ && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \ && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac case $host in *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). if test CXX = "$tagname"; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) func_append compile_command " $wl-bind_at_load" func_append finalize_command " $wl-bind_at_load" ;; esac fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $compile_deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $compile_deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done compile_deplibs=$new_libs func_append compile_command " $compile_deplibs" func_append finalize_command " $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; *) func_append dllsearchpath ":$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath=$rpath rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) func_append finalize_perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath=$rpath if test -n "$libobjs" && test yes = "$build_old_libs"; then # Transform all the library objects into standard objects. compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` fi func_generate_dlsyms "$outputname" "@PROGRAM@" false # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi wrappers_required=: case $host in *cegcc* | *mingw32ce*) # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. wrappers_required=false ;; *cygwin* | *mingw* ) test yes = "$build_libtool_libs" || wrappers_required=false ;; *) if test no = "$need_relink" || test yes != "$build_libtool_libs"; then wrappers_required=false fi ;; esac $wrappers_required || { # Replace the output file specification. compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` link_command=$compile_command$compile_rpath # We have no uninstalled library dependencies, so finalize right now. exit_status=0 func_show_eval "$link_command" 'exit_status=$?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Delete the generated files. if test -f "$output_objdir/${outputname}S.$objext"; then func_show_eval '$RM "$output_objdir/${outputname}S.$objext"' fi exit $exit_status } if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do func_append rpath "$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test yes = "$no_install"; then # We don't need to create a wrapper script. link_command=$compile_var$compile_command$compile_rpath # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $opt_dry_run || $RM $output # Link the executable and exit func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi exit $EXIT_SUCCESS fi case $hardcode_action,$fast_install in relink,*) # Fast installation is not supported link_command=$compile_var$compile_command$compile_rpath relink_command=$finalize_var$finalize_command$finalize_rpath func_warning "this platform does not like uninstalled shared libraries" func_warning "'$output' will be relinked during installation" ;; *,yes) link_command=$finalize_var$compile_command$finalize_rpath relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` ;; *,no) link_command=$compile_var$compile_command$compile_rpath relink_command=$finalize_var$finalize_command$finalize_rpath ;; *,needless) link_command=$finalize_var$compile_command$finalize_rpath relink_command= ;; esac # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output_objdir/$outputname" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Now create the wrapper script. func_verbose "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done relink_command="(cd `pwd`; $relink_command)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` fi # Only actually do things if not in dry run mode. $opt_dry_run || { # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) func_stripname '' '.exe' "$output" output=$func_stripname_result ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe func_stripname '' '.exe' "$outputname" outputname=$func_stripname_result ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result cwrappersource=$output_path/$objdir/lt-$output_name.c cwrapper=$output_path/$output_name.exe $RM $cwrappersource $cwrapper trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 func_emit_cwrapperexe_src > $cwrappersource # The wrapper executable is built using the $host compiler, # because it contains $host paths and files. If cross- # compiling, it, like the target executable, must be # executed on the $host or under an emulation environment. $opt_dry_run || { $LTCC $LTCFLAGS -o $cwrapper $cwrappersource $STRIP $cwrapper } # Now, create the wrapper script for func_source use: func_ltwrapper_scriptname $cwrapper $RM $func_ltwrapper_scriptname_result trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. if test "x$build" = "x$host"; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result fi } ;; * ) $RM $output trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 func_emit_wrapper no > $output chmod +x $output ;; esac } exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do case $build_libtool_libs in convenience) oldobjs="$libobjs_save $symfileobj" addlibs=$convenience build_libtool_libs=no ;; module) oldobjs=$libobjs_save addlibs=$old_convenience build_libtool_libs=no ;; *) oldobjs="$old_deplibs $non_pic_objects" $preload && test -f "$symfileobj" \ && func_append oldobjs " $symfileobj" addlibs=$old_convenience ;; esac if test -n "$addlibs"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $addlibs func_append oldobjs " $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then cmds=$old_archive_from_new_cmds else # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append oldobjs " $func_extract_archives_result" fi # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do func_basename "$obj" $ECHO "$func_basename_result" done | sort | sort -uc >/dev/null 2>&1); then : else echo "copying selected object files to avoid basename conflicts..." gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do func_basename "$obj" objbase=$func_basename_result case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase func_arith $counter + 1 counter=$func_arith_result case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" func_append oldobjs " $gentop/$newobj" ;; *) func_append oldobjs " $obj" ;; esac done fi func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result eval cmds=\"$old_archive_cmds\" func_len " $cmds" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds elif test -n "$archiver_list_spec"; then func_verbose "using command file archive linking..." for obj in $oldobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > $output_objdir/$libname.libcmd func_to_tool_file "$output_objdir/$libname.libcmd" oldobjs=" $archiver_list_spec$func_to_tool_file_result" cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts func_verbose "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs oldobjs= # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done eval test_cmds=\"$old_archive_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 for obj in $save_oldobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result func_append objlist " $obj" if test "$len" -lt "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj"; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$old_archive_cmds\" objlist= len=$len0 fi done RANLIB=$save_RANLIB oldobjs=$objlist if test -z "$oldobjs"; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi func_execute_cmds "$cmds" 'exit $?' done test -n "$generated" && \ func_show_eval "${RM}r$generated" # Now create the libtool archive. case $output in *.la) old_library= test yes = "$build_old_libs" && old_library=$libname.$libext func_verbose "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done # Quote the link command for shipping. relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` if test yes = "$hardcode_automatic"; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do if test yes = "$installed"; then if test -z "$install_libdir"; then break fi output=$output_objdir/${outputname}i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) func_basename "$deplib" name=$func_basename_result func_resolve_sysroot "$deplib" eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` test -z "$libdir" && \ func_fatal_error "'$deplib' is not a valid libtool archive" func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" ;; -L*) func_stripname -L '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -L$func_replace_sysroot_result" ;; -R*) func_stripname -R '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -R$func_replace_sysroot_result" ;; *) func_append newdependency_libs " $deplib" ;; esac done dependency_libs=$newdependency_libs newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" name=$func_basename_result eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "'$lib' is not a valid libtool archive" func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" ;; *) func_append newdlfiles " $lib" ;; esac done dlfiles=$newdlfiles newdlprefiles= for lib in $dlprefiles; do case $lib in *.la) # Only pass preopened files to the pseudo-archive (for # eventual linking with the app. that links it) if we # didn't already link the preopened objects directly into # the library: func_basename "$lib" name=$func_basename_result eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "'$lib' is not a valid libtool archive" func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" ;; esac done dlprefiles=$newdlprefiles else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlfiles " $abs" done dlfiles=$newdlfiles newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlprefiles " $abs" done dlprefiles=$newdlprefiles fi $RM $output # place dlname in correct position for cygwin # In fact, it would be nice if we could use this code for all target # systems that can't hard-code library paths into their executables # and that have no shared library path variable independent of PATH, # but it turns out we can't easily determine that from inspecting # libtool variables, so we have to hard-code the OSs to which it # applies here; at the moment, that means platforms that use the PE # object format with DLL files. See the long comment at the top of # tests/bindir.at for full details. tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) # If a -bindir argument was supplied, place the dll there. if test -n "$bindir"; then func_relative_path "$install_libdir" "$bindir" tdlname=$func_relative_path_result/$dlname else # Otherwise fall back on heuristic. tdlname=../bin/$dlname fi ;; esac $ECHO > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM (GNU $PACKAGE) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Linker flags that cannot go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Names of additional weak libraries provided by this library weak_library_names='$weak_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test no,yes = "$installed,$need_relink"; then $ECHO >> $output "\ relink_command=\"$relink_command\"" fi done } # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' ;; esac exit $EXIT_SUCCESS } if test link = "$opt_mode" || test relink = "$opt_mode"; then func_mode_link ${1+"$@"} fi # func_mode_uninstall arg... func_mode_uninstall () { $debug_cmd RM=$nonopt files= rmforce=false exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic=$magic for arg do case $arg in -f) func_append RM " $arg"; rmforce=: ;; -*) func_append RM " $arg" ;; *) func_append files " $arg" ;; esac done test -z "$RM" && \ func_fatal_help "you must specify an RM program" rmdirs= for file in $files; do func_dirname "$file" "" "." dir=$func_dirname_result if test . = "$dir"; then odir=$objdir else odir=$dir/$objdir fi func_basename "$file" name=$func_basename_result test uninstall = "$opt_mode" && odir=$dir # Remember odir for removal later, being careful to avoid duplicates if test clean = "$opt_mode"; then case " $rmdirs " in *" $odir "*) ;; *) func_append rmdirs " $odir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if { test -L "$file"; } >/dev/null 2>&1 || { test -h "$file"; } >/dev/null 2>&1 || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif $rmforce; then continue fi rmfiles=$file case $name in *.la) # Possibly a libtool archive, so verify it. if func_lalib_p "$file"; then func_source $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do func_append rmfiles " $odir/$n" done test -n "$old_library" && func_append rmfiles " $odir/$old_library" case $opt_mode in clean) case " $library_names " in *" $dlname "*) ;; *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; esac test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" ;; uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; esac fi ;; *.lo) # Possibly a libtool object, so verify it. if func_lalib_p "$file"; then # Read the .lo file func_source $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" && test none != "$pic_object"; then func_append rmfiles " $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" && test none != "$non_pic_object"; then func_append rmfiles " $dir/$non_pic_object" fi fi ;; *) if test clean = "$opt_mode"; then noexename=$name case $file in *.exe) func_stripname '' '.exe' "$file" file=$func_stripname_result func_stripname '' '.exe' "$name" noexename=$func_stripname_result # $file with .exe has already been added to rmfiles, # add $file without .exe func_append rmfiles " $file" ;; esac # Do a test to see if this is a libtool program. if func_ltwrapper_p "$file"; then if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" relink_command= func_source $func_ltwrapper_scriptname_result func_append rmfiles " $func_ltwrapper_scriptname_result" else relink_command= func_source $dir/$noexename fi # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles func_append rmfiles " $odir/$name $odir/${name}S.$objext" if test yes = "$fast_install" && test -n "$relink_command"; then func_append rmfiles " $odir/lt-$name" fi if test "X$noexename" != "X$name"; then func_append rmfiles " $odir/lt-$noexename.c" fi fi fi ;; esac func_show_eval "$RM $rmfiles" 'exit_status=1' done # Try to remove the $objdir's in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" fi done exit $exit_status } if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then func_mode_uninstall ${1+"$@"} fi test -z "$opt_mode" && { help=$generic_help func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ func_fatal_help "invalid operation mode '$opt_mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" exit $EXIT_FAILURE fi exit $exit_status # The TAGs below are defined such that we never get into a situation # where we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: jamulus-3.9.1+dfsg/libs/opus/configure.ac0000644000175000017500000010236314340334543017366 0ustar vimervimerdnl Process this file with autoconf to produce a configure script. -*-m4-*- dnl The package_version file will be automatically synced to the git revision dnl by the update_version script when configured in the repository, but will dnl remain constant in tarball releases unless it is manually edited. m4_define([CURRENT_VERSION], m4_esyscmd([ ./update_version 2>/dev/null || true if test -e package_version; then . ./package_version printf "$PACKAGE_VERSION" else printf "unknown" fi ])) AC_INIT([opus],[CURRENT_VERSION],[opus@xiph.org]) AC_CONFIG_SRCDIR(src/opus_encoder.c) AC_CONFIG_MACRO_DIR([m4]) dnl enable silent rules on automake 1.11 and later m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) # For libtool. dnl Please update these for releases. OPUS_LT_CURRENT=8 OPUS_LT_REVISION=0 OPUS_LT_AGE=8 AC_SUBST(OPUS_LT_CURRENT) AC_SUBST(OPUS_LT_REVISION) AC_SUBST(OPUS_LT_AGE) AM_INIT_AUTOMAKE([no-define]) AM_MAINTAINER_MODE([enable]) AC_CANONICAL_HOST AC_MINGW32 AM_PROG_LIBTOOL AM_PROG_CC_C_O AC_PROG_CC_C99 AC_C_CONST AC_C_INLINE AM_PROG_AS AC_DEFINE([OPUS_BUILD], [], [This is a build of OPUS]) #Use a hacked up version of autoconf's AC_C_RESTRICT because it's not #strong enough a test to detect old buggy versions of GCC (e.g. 2.95.3) #Note: Both this and the test for variable-size arrays below are also # done by AC_PROG_CC_C99, but not thoroughly enough apparently. AC_CACHE_CHECK([for C/C++ restrict keyword], ac_cv_c_restrict, [ac_cv_c_restrict=no # The order here caters to the fact that C++ does not require restrict. for ac_kw in __restrict __restrict__ _Restrict restrict; do AC_COMPILE_IFELSE([AC_LANG_PROGRAM( [[typedef int * int_ptr; int foo (int_ptr $ac_kw ip, int * $ac_kw baz[]) { return ip[0]; }]], [[int s[1]; int * $ac_kw t = s; t[0] = 0; return foo(t, (void *)0)]])], [ac_cv_c_restrict=$ac_kw]) test "$ac_cv_c_restrict" != no && break done ]) AH_VERBATIM([restrict], [/* Define to the equivalent of the C99 'restrict' keyword, or to nothing if this is not supported. Do not define if restrict is supported directly. */ #undef restrict /* Work around a bug in Sun C++: it does not support _Restrict or __restrict__, even though the corresponding Sun C compiler ends up with "#define restrict _Restrict" or "#define restrict __restrict__" in the previous line. Perhaps some future version of Sun C++ will work with restrict; if so, hopefully it defines __RESTRICT like Sun C does. */ #if defined __SUNPRO_CC && !defined __RESTRICT # define _Restrict # define __restrict__ #endif]) case $ac_cv_c_restrict in restrict) ;; no) AC_DEFINE([restrict], []) ;; *) AC_DEFINE_UNQUOTED([restrict], [$ac_cv_c_restrict]) ;; esac AC_MSG_CHECKING(for C99 variable-size arrays) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[static int x; char a[++x]; a[sizeof a - 1] = 0; int N; return a[0];]])], [ has_var_arrays=yes use_alloca="no (using var arrays)" AC_DEFINE([VAR_ARRAYS], [1], [Use C99 variable-size arrays]) ],[ has_var_arrays=no ]) AC_MSG_RESULT([$has_var_arrays]) AS_IF([test "$has_var_arrays" = "no"], [ AC_CHECK_HEADERS([alloca.h]) AC_MSG_CHECKING(for alloca) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[int foo=10; int *array = alloca(foo);]])], [ use_alloca=yes; AC_DEFINE([USE_ALLOCA], [], [Make use of alloca]) ],[ use_alloca=no ]) AC_MSG_RESULT([$use_alloca]) ]) LT_LIB_M AC_ARG_ENABLE([fixed-point], [AS_HELP_STRING([--enable-fixed-point], [compile without floating point (for machines without a fast enough FPU)])],, [enable_fixed_point=no]) AS_IF([test "$enable_fixed_point" = "yes"],[ enable_float="no" AC_DEFINE([FIXED_POINT], [1], [Compile as fixed-point (for machines without a fast enough FPU)]) PC_BUILD="fixed-point" ],[ enable_float="yes"; PC_BUILD="floating-point" ]) AM_CONDITIONAL([FIXED_POINT], [test "$enable_fixed_point" = "yes"]) AC_ARG_ENABLE([fixed-point-debug], [AS_HELP_STRING([--enable-fixed-point-debug], [debug fixed-point implementation])],, [enable_fixed_point_debug=no]) AS_IF([test "$enable_fixed_point_debug" = "yes"],[ AC_DEFINE([FIXED_DEBUG], [1], [Debug fixed-point implementation]) ]) AC_ARG_ENABLE([float_api], [AS_HELP_STRING([--disable-float-api], [compile without the floating point API (for machines with no float library)])],, [enable_float_api=yes]) AM_CONDITIONAL([DISABLE_FLOAT_API], [test "$enable_float_api" = "no"]) AS_IF([test "$enable_float_api" = "no"],[ AC_DEFINE([DISABLE_FLOAT_API], [1], [Do not build the float API]) ]) AC_ARG_ENABLE([custom-modes], [AS_HELP_STRING([--enable-custom-modes], [enable non-Opus modes, e.g. 44.1 kHz & 2^n frames])],, [enable_custom_modes=no]) AS_IF([test "$enable_custom_modes" = "yes"],[ AC_DEFINE([CUSTOM_MODES], [1], [Custom modes]) PC_BUILD="$PC_BUILD, custom modes" ]) AM_CONDITIONAL([CUSTOM_MODES], [test "$enable_custom_modes" = "yes"]) has_float_approx=no #case "$host_cpu" in #i[[3456]]86 | x86_64 | powerpc64 | powerpc32 | ia64) # has_float_approx=yes # ;; #esac AC_ARG_ENABLE([float-approx], [AS_HELP_STRING([--enable-float-approx], [enable fast approximations for floating point])], [if test "$enable_float_approx" = "yes"; then AC_WARN([Floating point approximations are not supported on all platforms.]) fi ], [enable_float_approx=$has_float_approx]) AS_IF([test "$enable_float_approx" = "yes"],[ AC_DEFINE([FLOAT_APPROX], [1], [Float approximations]) ]) AC_ARG_ENABLE([asm], [AS_HELP_STRING([--disable-asm], [Disable assembly optimizations])],, [enable_asm=yes]) AC_ARG_ENABLE([rtcd], [AS_HELP_STRING([--disable-rtcd], [Disable run-time CPU capabilities detection])],, [enable_rtcd=yes]) AC_ARG_ENABLE([intrinsics], [AS_HELP_STRING([--disable-intrinsics], [Disable intrinsics optimizations])],, [enable_intrinsics=yes]) rtcd_support=no cpu_arm=no AS_IF([test x"${enable_asm}" = x"yes"],[ inline_optimization="No inline ASM for your platform, please send patches" case $host_cpu in arm*) dnl Currently we only have asm for fixed-point AS_IF([test "$enable_float" != "yes"],[ cpu_arm=yes AC_DEFINE([OPUS_ARM_ASM], [], [Make use of ARM asm optimization]) AS_GCC_INLINE_ASSEMBLY( [inline_optimization="ARM"], [inline_optimization="disabled"] ) AS_ASM_ARM_EDSP([OPUS_ARM_INLINE_EDSP=1],[OPUS_ARM_INLINE_EDSP=0]) AS_ASM_ARM_MEDIA([OPUS_ARM_INLINE_MEDIA=1], [OPUS_ARM_INLINE_MEDIA=0]) AS_ASM_ARM_NEON([OPUS_ARM_INLINE_NEON=1],[OPUS_ARM_INLINE_NEON=0]) AS_IF([test x"$inline_optimization" = x"ARM"],[ AM_CONDITIONAL([OPUS_ARM_INLINE_ASM],[true]) AC_DEFINE([OPUS_ARM_INLINE_ASM], 1, [Use generic ARMv4 inline asm optimizations]) AS_IF([test x"$OPUS_ARM_INLINE_EDSP" = x"1"],[ AC_DEFINE([OPUS_ARM_INLINE_EDSP], [1], [Use ARMv5E inline asm optimizations]) inline_optimization="$inline_optimization (EDSP)" ]) AS_IF([test x"$OPUS_ARM_INLINE_MEDIA" = x"1"],[ AC_DEFINE([OPUS_ARM_INLINE_MEDIA], [1], [Use ARMv6 inline asm optimizations]) inline_optimization="$inline_optimization (Media)" ]) AS_IF([test x"$OPUS_ARM_INLINE_NEON" = x"1"],[ AC_DEFINE([OPUS_ARM_INLINE_NEON], 1, [Use ARM NEON inline asm optimizations]) inline_optimization="$inline_optimization (NEON)" ]) ]) dnl We need Perl to translate RVCT-syntax asm to gas syntax. AC_CHECK_PROG([HAVE_PERL], perl, yes, no) AS_IF([test x"$HAVE_PERL" = x"yes"],[ AM_CONDITIONAL([OPUS_ARM_EXTERNAL_ASM],[true]) asm_optimization="ARM" AS_IF([test x"$OPUS_ARM_INLINE_EDSP" = x"1"], [ OPUS_ARM_PRESUME_EDSP=1 OPUS_ARM_MAY_HAVE_EDSP=1 ], [ OPUS_ARM_PRESUME_EDSP=0 OPUS_ARM_MAY_HAVE_EDSP=0 ]) AS_IF([test x"$OPUS_ARM_INLINE_MEDIA" = x"1"], [ OPUS_ARM_PRESUME_MEDIA=1 OPUS_ARM_MAY_HAVE_MEDIA=1 ], [ OPUS_ARM_PRESUME_MEDIA=0 OPUS_ARM_MAY_HAVE_MEDIA=0 ]) AS_IF([test x"$OPUS_ARM_INLINE_NEON" = x"1"], [ OPUS_ARM_PRESUME_NEON=1 OPUS_ARM_MAY_HAVE_NEON=1 ], [ OPUS_ARM_PRESUME_NEON=0 OPUS_ARM_MAY_HAVE_NEON=0 ]) AS_IF([test x"$enable_rtcd" = x"yes"],[ AS_IF([test x"$OPUS_ARM_MAY_HAVE_EDSP" != x"1"],[ AC_MSG_NOTICE( [Trying to force-enable armv5e EDSP instructions...]) AS_ASM_ARM_EDSP_FORCE([OPUS_ARM_MAY_HAVE_EDSP=1]) ]) AS_IF([test x"$OPUS_ARM_MAY_HAVE_MEDIA" != x"1"],[ AC_MSG_NOTICE( [Trying to force-enable ARMv6 media instructions...]) AS_ASM_ARM_MEDIA_FORCE([OPUS_ARM_MAY_HAVE_MEDIA=1]) ]) AS_IF([test x"$OPUS_ARM_MAY_HAVE_NEON" != x"1"],[ AC_MSG_NOTICE( [Trying to force-enable NEON instructions...]) AS_ASM_ARM_NEON_FORCE([OPUS_ARM_MAY_HAVE_NEON=1]) ]) ]) rtcd_support= AS_IF([test x"$OPUS_ARM_MAY_HAVE_EDSP" = x"1"],[ AC_DEFINE(OPUS_ARM_MAY_HAVE_EDSP, 1, [Define if assembler supports EDSP instructions]) AS_IF([test x"$OPUS_ARM_PRESUME_EDSP" = x"1"],[ AC_DEFINE(OPUS_ARM_PRESUME_EDSP, 1, [Define if binary requires EDSP instruction support]) asm_optimization="$asm_optimization (EDSP)" ], [rtcd_support="$rtcd_support (EDSP)"] ) ]) AC_SUBST(OPUS_ARM_MAY_HAVE_EDSP) AS_IF([test x"$OPUS_ARM_MAY_HAVE_MEDIA" = x"1"],[ AC_DEFINE(OPUS_ARM_MAY_HAVE_MEDIA, 1, [Define if assembler supports ARMv6 media instructions]) AS_IF([test x"$OPUS_ARM_PRESUME_MEDIA" = x"1"],[ AC_DEFINE(OPUS_ARM_PRESUME_MEDIA, 1, [Define if binary requires ARMv6 media instruction support]) asm_optimization="$asm_optimization (Media)" ], [rtcd_support="$rtcd_support (Media)"] ) ]) AC_SUBST(OPUS_ARM_MAY_HAVE_MEDIA) AS_IF([test x"$OPUS_ARM_MAY_HAVE_NEON" = x"1"],[ AC_DEFINE(OPUS_ARM_MAY_HAVE_NEON, 1, [Define if compiler supports NEON instructions]) AS_IF([test x"$OPUS_ARM_PRESUME_NEON" = x"1"], [ AC_DEFINE(OPUS_ARM_PRESUME_NEON, 1, [Define if binary requires NEON instruction support]) asm_optimization="$asm_optimization (NEON)" ], [rtcd_support="$rtcd_support (NEON)"] ) ]) AC_SUBST(OPUS_ARM_MAY_HAVE_NEON) dnl Make sure turning on RTCD gets us at least one dnl instruction set. AS_IF([test x"$rtcd_support" != x""], [rtcd_support=ARM"$rtcd_support"], [rtcd_support="no"] ) AC_MSG_CHECKING([for apple style tools]) AC_PREPROC_IFELSE([AC_LANG_PROGRAM([ #ifndef __APPLE__ #error 1 #endif],[])], [AC_MSG_RESULT([yes]); ARM2GNU_PARAMS="--apple"], [AC_MSG_RESULT([no]); ARM2GNU_PARAMS=""]) AC_SUBST(ARM2GNU_PARAMS) ], [ AC_MSG_WARN( [*** ARM assembly requires perl -- disabling optimizations]) asm_optimization="(missing perl dependency for ARM)" ]) ]) ;; esac ],[ inline_optimization="disabled" asm_optimization="disabled" ]) AM_CONDITIONAL([OPUS_ARM_INLINE_ASM], [test x"${inline_optimization%% *}" = x"ARM"]) AM_CONDITIONAL([OPUS_ARM_EXTERNAL_ASM], [test x"${asm_optimization%% *}" = x"ARM"]) AM_CONDITIONAL([HAVE_SSE], [false]) AM_CONDITIONAL([HAVE_SSE2], [false]) AM_CONDITIONAL([HAVE_SSE4_1], [false]) AM_CONDITIONAL([HAVE_AVX], [false]) m4_define([DEFAULT_X86_SSE_CFLAGS], [-msse]) m4_define([DEFAULT_X86_SSE2_CFLAGS], [-msse2]) m4_define([DEFAULT_X86_SSE4_1_CFLAGS], [-msse4.1]) m4_define([DEFAULT_X86_AVX_CFLAGS], [-mavx]) m4_define([DEFAULT_ARM_NEON_INTR_CFLAGS], [-mfpu=neon]) # With GCC on ARM32 softfp architectures (e.g. Android, or older Ubuntu) you need to specify # -mfloat-abi=softfp for -mfpu=neon to work. However, on ARM32 hardfp architectures (e.g. newer Ubuntu), # this option will break things. # As a heuristic, if host matches arm*eabi* but not arm*hf*, it's probably soft-float. m4_define([DEFAULT_ARM_NEON_SOFTFP_INTR_CFLAGS], [-mfpu=neon -mfloat-abi=softfp]) AS_CASE([$host], [arm*hf*], [AS_VAR_SET([RESOLVED_DEFAULT_ARM_NEON_INTR_CFLAGS], "DEFAULT_ARM_NEON_INTR_CFLAGS")], [arm*eabi*], [AS_VAR_SET([RESOLVED_DEFAULT_ARM_NEON_INTR_CFLAGS], "DEFAULT_ARM_NEON_SOFTFP_INTR_CFLAGS")], [AS_VAR_SET([RESOLVED_DEFAULT_ARM_NEON_INTR_CFLAGS], "DEFAULT_ARM_NEON_INTR_CFLAGS")]) AC_ARG_VAR([X86_SSE_CFLAGS], [C compiler flags to compile SSE intrinsics @<:@default=]DEFAULT_X86_SSE_CFLAGS[@:>@]) AC_ARG_VAR([X86_SSE2_CFLAGS], [C compiler flags to compile SSE2 intrinsics @<:@default=]DEFAULT_X86_SSE2_CFLAGS[@:>@]) AC_ARG_VAR([X86_SSE4_1_CFLAGS], [C compiler flags to compile SSE4.1 intrinsics @<:@default=]DEFAULT_X86_SSE4_1_CFLAGS[@:>@]) AC_ARG_VAR([X86_AVX_CFLAGS], [C compiler flags to compile AVX intrinsics @<:@default=]DEFAULT_X86_AVX_CFLAGS[@:>@]) AC_ARG_VAR([ARM_NEON_INTR_CFLAGS], [C compiler flags to compile ARM NEON intrinsics @<:@default=]DEFAULT_ARM_NEON_INTR_CFLAGS / DEFAULT_ARM_NEON_SOFTFP_INTR_CFLAGS[@:>@]) AS_VAR_SET_IF([X86_SSE_CFLAGS], [], [AS_VAR_SET([X86_SSE_CFLAGS], "DEFAULT_X86_SSE_CFLAGS")]) AS_VAR_SET_IF([X86_SSE2_CFLAGS], [], [AS_VAR_SET([X86_SSE2_CFLAGS], "DEFAULT_X86_SSE2_CFLAGS")]) AS_VAR_SET_IF([X86_SSE4_1_CFLAGS], [], [AS_VAR_SET([X86_SSE4_1_CFLAGS], "DEFAULT_X86_SSE4_1_CFLAGS")]) AS_VAR_SET_IF([X86_AVX_CFLAGS], [], [AS_VAR_SET([X86_AVX_CFLAGS], "DEFAULT_X86_AVX_CFLAGS")]) AS_VAR_SET_IF([ARM_NEON_INTR_CFLAGS], [], [AS_VAR_SET([ARM_NEON_INTR_CFLAGS], ["$RESOLVED_DEFAULT_ARM_NEON_INTR_CFLAGS"])]) AC_DEFUN([OPUS_PATH_NE10], [ AC_ARG_WITH(NE10, AC_HELP_STRING([--with-NE10=PFX],[Prefix where libNE10 is installed (optional)]), NE10_prefix="$withval", NE10_prefix="") AC_ARG_WITH(NE10-libraries, AC_HELP_STRING([--with-NE10-libraries=DIR], [Directory where libNE10 library is installed (optional)]), NE10_libraries="$withval", NE10_libraries="") AC_ARG_WITH(NE10-includes, AC_HELP_STRING([--with-NE10-includes=DIR], [Directory where libNE10 header files are installed (optional)]), NE10_includes="$withval", NE10_includes="") if test "x$NE10_libraries" != "x" ; then NE10_LIBS="-L$NE10_libraries" elif test "x$NE10_prefix" = "xno" || test "x$NE10_prefix" = "xyes" ; then NE10_LIBS="" elif test "x$NE10_prefix" != "x" ; then NE10_LIBS="-L$NE10_prefix/lib" elif test "x$prefix" != "xNONE" ; then NE10_LIBS="-L$prefix/lib" fi if test "x$NE10_prefix" != "xno" ; then NE10_LIBS="$NE10_LIBS -lNE10" fi if test "x$NE10_includes" != "x" ; then NE10_CFLAGS="-I$NE10_includes" elif test "x$NE10_prefix" = "xno" || test "x$NE10_prefix" = "xyes" ; then NE10_CFLAGS="" elif test "x$NE10_prefix" != "x" ; then NE10_CFLAGS="-I$NE10_prefix/include" elif test "x$prefix" != "xNONE"; then NE10_CFLAGS="-I$prefix/include" fi AC_MSG_CHECKING(for NE10) save_CFLAGS="$CFLAGS"; CFLAGS="$CFLAGS $NE10_CFLAGS" save_LIBS="$LIBS"; LIBS="$LIBS $NE10_LIBS $LIBM" AC_LINK_IFELSE( [ AC_LANG_PROGRAM( [[#include ]], [[ ne10_fft_cfg_float32_t cfg; cfg = ne10_fft_alloc_c2c_float32_neon(480); ]] ) ],[ HAVE_ARM_NE10=1 AC_MSG_RESULT([yes]) ],[ HAVE_ARM_NE10=0 AC_MSG_RESULT([no]) NE10_CFLAGS="" NE10_LIBS="" ] ) CFLAGS="$save_CFLAGS"; LIBS="$save_LIBS" #Now we know if libNE10 is installed or not AS_IF([test x"$HAVE_ARM_NE10" = x"1"], [ AC_DEFINE([HAVE_ARM_NE10], 1, [NE10 library is installed on host. Make sure it is on target!]) AC_SUBST(HAVE_ARM_NE10) AC_SUBST(NE10_CFLAGS) AC_SUBST(NE10_LIBS) ] ) ] ) AS_IF([test x"$enable_intrinsics" = x"yes"],[ intrinsics_support="" AS_CASE([$host_cpu], [arm*|aarch64*], [ cpu_arm=yes OPUS_CHECK_INTRINSICS( [ARM Neon], [$ARM_NEON_INTR_CFLAGS], [OPUS_ARM_MAY_HAVE_NEON_INTR], [OPUS_ARM_PRESUME_NEON_INTR], [[#include ]], [[ static float32x4_t A0, A1, SUMM; SUMM = vmlaq_f32(SUMM, A0, A1); return (int)vgetq_lane_f32(SUMM, 0); ]] ) AS_IF([test x"$OPUS_ARM_MAY_HAVE_NEON_INTR" = x"1" && test x"$OPUS_ARM_PRESUME_NEON_INTR" != x"1"], [ OPUS_ARM_NEON_INTR_CFLAGS="$ARM_NEON_INTR_CFLAGS" AC_SUBST([OPUS_ARM_NEON_INTR_CFLAGS]) ] ) AS_IF([test x"$OPUS_ARM_MAY_HAVE_NEON_INTR" = x"1"], [ AC_DEFINE([OPUS_ARM_MAY_HAVE_NEON_INTR], 1, [Compiler supports ARMv7/Aarch64 Neon Intrinsics]) intrinsics_support="$intrinsics_support (NEON)" AS_IF([test x"$enable_rtcd" != x"no" && test x"$OPUS_ARM_PRESUME_NEON_INTR" != x"1"], [AS_IF([test x"$rtcd_support" = x"no"], [rtcd_support="ARM (NEON Intrinsics)"], [rtcd_support="$rtcd_support (NEON Intrinsics)"])]) AS_IF([test x"$OPUS_ARM_PRESUME_NEON_INTR" = x"1"], [AC_DEFINE([OPUS_ARM_PRESUME_NEON_INTR], 1, [Define if binary requires NEON intrinsics support])]) OPUS_PATH_NE10() AS_IF([test x"$NE10_LIBS" != x""], [ intrinsics_support="$intrinsics_support (NE10)" AS_IF([test x"enable_rtcd" != x"" \ && test x"$OPUS_ARM_PRESUME_NEON_INTR" != x"1"], [rtcd_support="$rtcd_support (NE10)"]) ]) OPUS_CHECK_INTRINSICS( [Aarch64 Neon], [$ARM_NEON_INTR_CFLAGS], [OPUS_ARM_MAY_HAVE_AARCH64_NEON_INTR], [OPUS_ARM_PRESUME_AARCH64_NEON_INTR], [[#include ]], [[ static int32_t IN; static int16_t OUT; OUT = vqmovns_s32(IN); ]] ) AS_IF([test x"$OPUS_ARM_PRESUME_AARCH64_NEON_INTR" = x"1"], [ AC_DEFINE([OPUS_ARM_PRESUME_AARCH64_NEON_INTR], 1, [Define if binary requires Aarch64 Neon Intrinsics]) intrinsics_support="$intrinsics_support (NEON [Aarch64])" ]) AS_IF([test x"$intrinsics_support" = x""], [intrinsics_support=no], [intrinsics_support="ARM$intrinsics_support"]) ], [ AC_MSG_WARN([Compiler does not support ARM intrinsics]) intrinsics_support=no ]) ], [i?86|x86_64], [ OPUS_CHECK_INTRINSICS( [SSE], [$X86_SSE_CFLAGS], [OPUS_X86_MAY_HAVE_SSE], [OPUS_X86_PRESUME_SSE], [[#include #include ]], [[ __m128 mtest; mtest = _mm_set1_ps((float)time(NULL)); mtest = _mm_mul_ps(mtest, mtest); return _mm_cvtss_si32(mtest); ]] ) AS_IF([test x"$OPUS_X86_MAY_HAVE_SSE" = x"1" && test x"$OPUS_X86_PRESUME_SSE" != x"1"], [ OPUS_X86_SSE_CFLAGS="$X86_SSE_CFLAGS" AC_SUBST([OPUS_X86_SSE_CFLAGS]) ] ) OPUS_CHECK_INTRINSICS( [SSE2], [$X86_SSE2_CFLAGS], [OPUS_X86_MAY_HAVE_SSE2], [OPUS_X86_PRESUME_SSE2], [[#include #include ]], [[ __m128i mtest; mtest = _mm_set1_epi32((int)time(NULL)); mtest = _mm_mul_epu32(mtest, mtest); return _mm_cvtsi128_si32(mtest); ]] ) AS_IF([test x"$OPUS_X86_MAY_HAVE_SSE2" = x"1" && test x"$OPUS_X86_PRESUME_SSE2" != x"1"], [ OPUS_X86_SSE2_CFLAGS="$X86_SSE2_CFLAGS" AC_SUBST([OPUS_X86_SSE2_CFLAGS]) ] ) OPUS_CHECK_INTRINSICS( [SSE4.1], [$X86_SSE4_1_CFLAGS], [OPUS_X86_MAY_HAVE_SSE4_1], [OPUS_X86_PRESUME_SSE4_1], [[#include #include ]], [[ __m128i mtest; mtest = _mm_set1_epi32((int)time(NULL)); mtest = _mm_mul_epi32(mtest, mtest); return _mm_cvtsi128_si32(mtest); ]] ) AS_IF([test x"$OPUS_X86_MAY_HAVE_SSE4_1" = x"1" && test x"$OPUS_X86_PRESUME_SSE4_1" != x"1"], [ OPUS_X86_SSE4_1_CFLAGS="$X86_SSE4_1_CFLAGS" AC_SUBST([OPUS_X86_SSE4_1_CFLAGS]) ] ) OPUS_CHECK_INTRINSICS( [AVX], [$X86_AVX_CFLAGS], [OPUS_X86_MAY_HAVE_AVX], [OPUS_X86_PRESUME_AVX], [[#include #include ]], [[ __m256 mtest; mtest = _mm256_set1_ps((float)time(NULL)); mtest = _mm256_addsub_ps(mtest, mtest); return _mm_cvtss_si32(_mm256_extractf128_ps(mtest, 0)); ]] ) AS_IF([test x"$OPUS_X86_MAY_HAVE_AVX" = x"1" && test x"$OPUS_X86_PRESUME_AVX" != x"1"], [ OPUS_X86_AVX_CFLAGS="$X86_AVX_CFLAGS" AC_SUBST([OPUS_X86_AVX_CFLAGS]) ] ) AS_IF([test x"$rtcd_support" = x"no"], [rtcd_support=""]) AS_IF([test x"$OPUS_X86_MAY_HAVE_SSE" = x"1"], [ AC_DEFINE([OPUS_X86_MAY_HAVE_SSE], 1, [Compiler supports X86 SSE Intrinsics]) intrinsics_support="$intrinsics_support SSE" AS_IF([test x"$OPUS_X86_PRESUME_SSE" = x"1"], [AC_DEFINE([OPUS_X86_PRESUME_SSE], 1, [Define if binary requires SSE intrinsics support])], [rtcd_support="$rtcd_support SSE"]) ], [ AC_MSG_WARN([Compiler does not support SSE intrinsics]) ]) AS_IF([test x"$OPUS_X86_MAY_HAVE_SSE2" = x"1"], [ AC_DEFINE([OPUS_X86_MAY_HAVE_SSE2], 1, [Compiler supports X86 SSE2 Intrinsics]) intrinsics_support="$intrinsics_support SSE2" AS_IF([test x"$OPUS_X86_PRESUME_SSE2" = x"1"], [AC_DEFINE([OPUS_X86_PRESUME_SSE2], 1, [Define if binary requires SSE2 intrinsics support])], [rtcd_support="$rtcd_support SSE2"]) ], [ AC_MSG_WARN([Compiler does not support SSE2 intrinsics]) ]) AS_IF([test x"$OPUS_X86_MAY_HAVE_SSE4_1" = x"1"], [ AC_DEFINE([OPUS_X86_MAY_HAVE_SSE4_1], 1, [Compiler supports X86 SSE4.1 Intrinsics]) intrinsics_support="$intrinsics_support SSE4.1" AS_IF([test x"$OPUS_X86_PRESUME_SSE4_1" = x"1"], [AC_DEFINE([OPUS_X86_PRESUME_SSE4_1], 1, [Define if binary requires SSE4.1 intrinsics support])], [rtcd_support="$rtcd_support SSE4.1"]) ], [ AC_MSG_WARN([Compiler does not support SSE4.1 intrinsics]) ]) AS_IF([test x"$OPUS_X86_MAY_HAVE_AVX" = x"1"], [ AC_DEFINE([OPUS_X86_MAY_HAVE_AVX], 1, [Compiler supports X86 AVX Intrinsics]) intrinsics_support="$intrinsics_support AVX" AS_IF([test x"$OPUS_X86_PRESUME_AVX" = x"1"], [AC_DEFINE([OPUS_X86_PRESUME_AVX], 1, [Define if binary requires AVX intrinsics support])], [rtcd_support="$rtcd_support AVX"]) ], [ AC_MSG_WARN([Compiler does not support AVX intrinsics]) ]) AS_IF([test x"$intrinsics_support" = x""], [intrinsics_support=no], [intrinsics_support="x86$intrinsics_support"] ) AS_IF([test x"$rtcd_support" = x""], [rtcd_support=no], [rtcd_support="x86$rtcd_support"], ) AS_IF([test x"$enable_rtcd" = x"yes" && test x"$rtcd_support" != x""],[ get_cpuid_by_asm="no" AC_MSG_CHECKING([How to get X86 CPU Info]) AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include ]],[[ unsigned int CPUInfo0; unsigned int CPUInfo1; unsigned int CPUInfo2; unsigned int CPUInfo3; unsigned int InfoType; __asm__ __volatile__ ( "cpuid": "=a" (CPUInfo0), "=b" (CPUInfo1), "=c" (CPUInfo2), "=d" (CPUInfo3) : "a" (InfoType), "c" (0) ); ]])], [get_cpuid_by_asm="yes" AC_MSG_RESULT([Inline Assembly]) AC_DEFINE([CPU_INFO_BY_ASM], [1], [Get CPU Info by asm method])], [AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include ]],[[ unsigned int CPUInfo0; unsigned int CPUInfo1; unsigned int CPUInfo2; unsigned int CPUInfo3; unsigned int InfoType; __get_cpuid(InfoType, &CPUInfo0, &CPUInfo1, &CPUInfo2, &CPUInfo3); ]])], [AC_MSG_RESULT([C method]) AC_DEFINE([CPU_INFO_BY_C], [1], [Get CPU Info by c method])], [AC_MSG_ERROR([no supported Get CPU Info method, please disable run-time CPU capabilities detection or intrinsics])])])]) ], [ AC_MSG_WARN([No intrinsics support for your architecture]) intrinsics_support="no" ]) ], [ intrinsics_support="no" ]) AM_CONDITIONAL([CPU_ARM], [test "$cpu_arm" = "yes"]) AM_CONDITIONAL([HAVE_ARM_NEON_INTR], [test x"$OPUS_ARM_MAY_HAVE_NEON_INTR" = x"1"]) AM_CONDITIONAL([HAVE_ARM_NE10], [test x"$HAVE_ARM_NE10" = x"1"]) AM_CONDITIONAL([HAVE_SSE], [test x"$OPUS_X86_MAY_HAVE_SSE" = x"1"]) AM_CONDITIONAL([HAVE_SSE2], [test x"$OPUS_X86_MAY_HAVE_SSE2" = x"1"]) AM_CONDITIONAL([HAVE_SSE4_1], [test x"$OPUS_X86_MAY_HAVE_SSE4_1" = x"1"]) AM_CONDITIONAL([HAVE_AVX], [test x"$OPUS_X86_MAY_HAVE_AVX" = x"1"]) AS_IF([test x"$enable_rtcd" = x"yes"],[ AS_IF([test x"$rtcd_support" != x"no"],[ AC_DEFINE([OPUS_HAVE_RTCD], [1], [Use run-time CPU capabilities detection]) OPUS_HAVE_RTCD=1 AC_SUBST(OPUS_HAVE_RTCD) ]) ],[ rtcd_support="disabled" ]) AC_ARG_ENABLE([assertions], [AS_HELP_STRING([--enable-assertions],[enable additional software error checking])],, [enable_assertions=no]) AS_IF([test "$enable_assertions" = "yes"], [ AC_DEFINE([ENABLE_ASSERTIONS], [1], [Assertions]) ]) AC_ARG_ENABLE([hardening], [AS_HELP_STRING([--disable-hardening],[disable run-time checks that are cheap and safe for use in production])],, [enable_hardening=yes]) AS_IF([test "$enable_hardening" = "yes"], [ AC_DEFINE([ENABLE_HARDENING], [1], [Hardening]) ]) AC_ARG_ENABLE([fuzzing], [AS_HELP_STRING([--enable-fuzzing],[causes the encoder to make random decisions (do not use in production)])],, [enable_fuzzing=no]) AS_IF([test "$enable_fuzzing" = "yes"], [ AC_DEFINE([FUZZING], [1], [Fuzzing]) ]) AC_ARG_ENABLE([check-asm], [AS_HELP_STRING([--enable-check-asm], [enable bit-exactness checks between optimized and c implementations])],, [enable_check_asm=no]) AS_IF([test "$enable_check_asm" = "yes"], [ AC_DEFINE([OPUS_CHECK_ASM], [1], [Run bit-exactness checks between optimized and c implementations]) ]) AC_ARG_ENABLE([doc], [AS_HELP_STRING([--disable-doc], [Do not build API documentation])],, [enable_doc=yes]) AS_IF([test "$enable_doc" = "yes"], [ AC_CHECK_PROG(HAVE_DOXYGEN, [doxygen], [yes], [no]) AC_CHECK_PROG(HAVE_DOT, [dot], [yes], [no]) ],[ HAVE_DOXYGEN=no ]) AM_CONDITIONAL([HAVE_DOXYGEN], [test "$HAVE_DOXYGEN" = "yes"]) AC_ARG_ENABLE([extra-programs], [AS_HELP_STRING([--disable-extra-programs], [Do not build extra programs (demo and tests)])],, [enable_extra_programs=yes]) AM_CONDITIONAL([EXTRA_PROGRAMS], [test "$enable_extra_programs" = "yes"]) AC_ARG_ENABLE([rfc8251], AS_HELP_STRING([--disable-rfc8251], [Disable bitstream fixes from RFC 8251]),, [enable_rfc8251=yes]) AS_IF([test "$enable_rfc8251" = "no"], [ AC_DEFINE([DISABLE_UPDATE_DRAFT], [1], [Disable bitstream fixes from RFC 8251]) ]) saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -fvisibility=hidden" AC_MSG_CHECKING([if ${CC} supports -fvisibility=hidden]) AC_COMPILE_IFELSE([AC_LANG_SOURCE([[char foo;]])], [ AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) CFLAGS="$saved_CFLAGS" ]) on_x86=no case "$host_cpu" in i[[3456]]86 | x86_64) on_x86=yes ;; esac on_windows=no case $host in *cygwin*|*mingw*) on_windows=yes ;; esac dnl Enable stack-protector-all only on x86 where it's well supported. dnl on some platforms it causes crashes. Hopefully the OS's default's dnl include this on platforms that work but have been missed here. AC_ARG_ENABLE([stack-protector], [AS_HELP_STRING([--disable-stack-protector],[Disable compiler stack hardening])],, [ AS_IF([test "$ac_cv_c_compiler_gnu" = "yes" && test "$on_x86" = "yes" && test "$on_windows" = "no"], [enable_stack_protector=yes],[enable_stack_protector=no]) ]) AS_IF([test "$enable_stack_protector" = "yes"], [ saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -fstack-protector-strong" AC_MSG_CHECKING([if ${CC} supports -fstack-protector-strong]) AC_LINK_IFELSE([AC_LANG_PROGRAM([],[[char foo;]])], [ AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) enable_stack_protector=no CFLAGS="$saved_CFLAGS" ]) ]) AS_IF([test x$ac_cv_c_compiler_gnu = xyes], [AX_ADD_FORTIFY_SOURCE] ) CFLAGS="$CFLAGS -W" warn_CFLAGS="-Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes" saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $warn_CFLAGS" AC_MSG_CHECKING([if ${CC} supports ${warn_CFLAGS}]) AC_COMPILE_IFELSE([AC_LANG_SOURCE([[char foo;]])], [ AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) CFLAGS="$saved_CFLAGS" ]) saved_LIBS="$LIBS" LIBS="$LIBS $LIBM" AC_CHECK_FUNCS([lrintf]) AC_CHECK_FUNCS([lrint]) LIBS="$saved_LIBS" AC_CHECK_FUNCS([__malloc_hook]) AC_SUBST([PC_BUILD]) AC_CONFIG_FILES([ Makefile opus.pc opus-uninstalled.pc celt/arm/armopts.s doc/Makefile doc/Doxyfile ]) AC_CONFIG_HEADERS([config.h]) AC_OUTPUT AC_MSG_NOTICE([ ------------------------------------------------------------------------ $PACKAGE_NAME $PACKAGE_VERSION: Automatic configuration OK. Compiler support: C99 var arrays: ................ ${has_var_arrays} C99 lrintf: .................... ${ac_cv_func_lrintf} Use alloca: .................... ${use_alloca} General configuration: Floating point support: ........ ${enable_float} Fast float approximations: ..... ${enable_float_approx} Fixed point debugging: ......... ${enable_fixed_point_debug} Inline Assembly Optimizations: . ${inline_optimization} External Assembly Optimizations: ${asm_optimization} Intrinsics Optimizations: ...... ${intrinsics_support} Run-time CPU detection: ........ ${rtcd_support} Custom modes: .................. ${enable_custom_modes} Assertion checking: ............ ${enable_assertions} Hardening: ..................... ${enable_hardening} Fuzzing: ....................... ${enable_fuzzing} Check ASM: ..................... ${enable_check_asm} API documentation: ............. ${enable_doc} Extra programs: ................ ${enable_extra_programs} ------------------------------------------------------------------------ Type "make; make install" to compile and install Type "make check" to run the test suite ]) jamulus-3.9.1+dfsg/libs/opus/compile0000755000175000017500000001632614340334543016461 0ustar vimervimer#! /bin/sh # Wrapper for compilers which do not understand '-c -o'. scriptversion=2016-01-11.22; # UTC # Copyright (C) 1999-2017 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . nl=' ' # We need space, tab and new line, in precisely that order. Quoting is # there to prevent tools from complaining about whitespace usage. IFS=" "" $nl" file_conv= # func_file_conv build_file lazy # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. If the determined conversion # type is listed in (the comma separated) LAZY, no conversion will # take place. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv/,$2, in *,$file_conv,*) ;; mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_cl_dashL linkdir # Make cl look for libraries in LINKDIR func_cl_dashL () { func_file_conv "$1" if test -z "$lib_path"; then lib_path=$file else lib_path="$lib_path;$file" fi linker_opts="$linker_opts -LIBPATH:$file" } # func_cl_dashl library # Do a library search-path lookup for cl func_cl_dashl () { lib=$1 found=no save_IFS=$IFS IFS=';' for dir in $lib_path $LIB do IFS=$save_IFS if $shared && test -f "$dir/$lib.dll.lib"; then found=yes lib=$dir/$lib.dll.lib break fi if test -f "$dir/$lib.lib"; then found=yes lib=$dir/$lib.lib break fi if test -f "$dir/lib$lib.a"; then found=yes lib=$dir/lib$lib.a break fi done IFS=$save_IFS if test "$found" != yes; then lib=$lib.lib fi } # func_cl_wrapper cl arg... # Adjust compile command to suit cl func_cl_wrapper () { # Assume a capable shell lib_path= shared=: linker_opts= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. eat=1 case $2 in *.o | *.[oO][bB][jJ]) func_file_conv "$2" set x "$@" -Fo"$file" shift ;; *) func_file_conv "$2" set x "$@" -Fe"$file" shift ;; esac ;; -I) eat=1 func_file_conv "$2" mingw set x "$@" -I"$file" shift ;; -I*) func_file_conv "${1#-I}" mingw set x "$@" -I"$file" shift ;; -l) eat=1 func_cl_dashl "$2" set x "$@" "$lib" shift ;; -l*) func_cl_dashl "${1#-l}" set x "$@" "$lib" shift ;; -L) eat=1 func_cl_dashL "$2" ;; -L*) func_cl_dashL "${1#-L}" ;; -static) shared=false ;; -Wl,*) arg=${1#-Wl,} save_ifs="$IFS"; IFS=',' for flag in $arg; do IFS="$save_ifs" linker_opts="$linker_opts $flag" done IFS="$save_ifs" ;; -Xlinker) eat=1 linker_opts="$linker_opts $2" ;; -*) set x "$@" "$1" shift ;; *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) func_file_conv "$1" set x "$@" -Tp"$file" shift ;; *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) func_file_conv "$1" mingw set x "$@" "$file" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -n "$linker_opts"; then linker_opts="-link$linker_opts" fi exec "$@" $linker_opts exit 1 } eat= case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand '-c -o'. Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file 'INSTALL'. Report bugs to . EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac ofile= cfile= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. # Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then test "$cofile" = "$ofile" || mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: jamulus-3.9.1+dfsg/libs/opus/config.h.in0000644000175000017500000001263014340334543017120 0ustar vimervimer/* config.h.in. Generated from configure.ac by autoheader. */ /* Get CPU Info by asm method */ #undef CPU_INFO_BY_ASM /* Get CPU Info by c method */ #undef CPU_INFO_BY_C /* Custom modes */ #undef CUSTOM_MODES /* Do not build the float API */ #undef DISABLE_FLOAT_API /* Disable bitstream fixes from RFC 8251 */ #undef DISABLE_UPDATE_DRAFT /* Assertions */ #undef ENABLE_ASSERTIONS /* Hardening */ #undef ENABLE_HARDENING /* Debug fixed-point implementation */ #undef FIXED_DEBUG /* Compile as fixed-point (for machines without a fast enough FPU) */ #undef FIXED_POINT /* Float approximations */ #undef FLOAT_APPROX /* Fuzzing */ #undef FUZZING /* Define to 1 if you have the header file. */ #undef HAVE_ALLOCA_H /* NE10 library is installed on host. Make sure it is on target! */ #undef HAVE_ARM_NE10 /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `lrint' function. */ #undef HAVE_LRINT /* Define to 1 if you have the `lrintf' function. */ #undef HAVE_LRINTF /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the `__malloc_hook' function. */ #undef HAVE___MALLOC_HOOK /* Define to the sub-directory where libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Make use of ARM asm optimization */ #undef OPUS_ARM_ASM /* Use generic ARMv4 inline asm optimizations */ #undef OPUS_ARM_INLINE_ASM /* Use ARMv5E inline asm optimizations */ #undef OPUS_ARM_INLINE_EDSP /* Use ARMv6 inline asm optimizations */ #undef OPUS_ARM_INLINE_MEDIA /* Use ARM NEON inline asm optimizations */ #undef OPUS_ARM_INLINE_NEON /* Define if assembler supports EDSP instructions */ #undef OPUS_ARM_MAY_HAVE_EDSP /* Define if assembler supports ARMv6 media instructions */ #undef OPUS_ARM_MAY_HAVE_MEDIA /* Define if compiler supports NEON instructions */ #undef OPUS_ARM_MAY_HAVE_NEON /* Compiler supports ARMv7/Aarch64 Neon Intrinsics */ #undef OPUS_ARM_MAY_HAVE_NEON_INTR /* Define if binary requires Aarch64 Neon Intrinsics */ #undef OPUS_ARM_PRESUME_AARCH64_NEON_INTR /* Define if binary requires EDSP instruction support */ #undef OPUS_ARM_PRESUME_EDSP /* Define if binary requires ARMv6 media instruction support */ #undef OPUS_ARM_PRESUME_MEDIA /* Define if binary requires NEON instruction support */ #undef OPUS_ARM_PRESUME_NEON /* Define if binary requires NEON intrinsics support */ #undef OPUS_ARM_PRESUME_NEON_INTR /* This is a build of OPUS */ #undef OPUS_BUILD /* Run bit-exactness checks between optimized and c implementations */ #undef OPUS_CHECK_ASM /* Use run-time CPU capabilities detection */ #undef OPUS_HAVE_RTCD /* Compiler supports X86 AVX Intrinsics */ #undef OPUS_X86_MAY_HAVE_AVX /* Compiler supports X86 SSE Intrinsics */ #undef OPUS_X86_MAY_HAVE_SSE /* Compiler supports X86 SSE2 Intrinsics */ #undef OPUS_X86_MAY_HAVE_SSE2 /* Compiler supports X86 SSE4.1 Intrinsics */ #undef OPUS_X86_MAY_HAVE_SSE4_1 /* Define if binary requires AVX intrinsics support */ #undef OPUS_X86_PRESUME_AVX /* Define if binary requires SSE intrinsics support */ #undef OPUS_X86_PRESUME_SSE /* Define if binary requires SSE2 intrinsics support */ #undef OPUS_X86_PRESUME_SSE2 /* Define if binary requires SSE4.1 intrinsics support */ #undef OPUS_X86_PRESUME_SSE4_1 /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Make use of alloca */ #undef USE_ALLOCA /* Use C99 variable-size arrays */ #undef VAR_ARRAYS /* Define to empty if `const' does not conform to ANSI C. */ #undef const /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus #undef inline #endif /* Define to the equivalent of the C99 'restrict' keyword, or to nothing if this is not supported. Do not define if restrict is supported directly. */ #undef restrict /* Work around a bug in Sun C++: it does not support _Restrict or __restrict__, even though the corresponding Sun C compiler ends up with "#define restrict _Restrict" or "#define restrict __restrict__" in the previous line. Perhaps some future version of Sun C++ will work with restrict; if so, hopefully it defines __RESTRICT like Sun C does. */ #if defined __SUNPRO_CC && !defined __RESTRICT # define _Restrict # define __restrict__ #endif jamulus-3.9.1+dfsg/libs/opus/celt/0000755000175000017500000000000014340334543016022 5ustar vimervimerjamulus-3.9.1+dfsg/libs/opus/celt/os_support.h0000644000175000017500000000613314340334543020413 0ustar vimervimer/* Copyright (C) 2007 Jean-Marc Valin File: os_support.h This is the (tiny) OS abstraction layer. Aside from math.h, this is the only place where system headers are allowed. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef OS_SUPPORT_H #define OS_SUPPORT_H #ifdef CUSTOM_SUPPORT # include "custom_support.h" #endif #include "opus_types.h" #include "opus_defines.h" #include #include #include /** Opus wrapper for malloc(). To do your own dynamic allocation, all you need to do is replace this function and opus_free */ #ifndef OVERRIDE_OPUS_ALLOC static OPUS_INLINE void *opus_alloc (size_t size) { return malloc(size); } #endif /** Same as celt_alloc(), except that the area is only needed inside a CELT call (might cause problem with wideband though) */ #ifndef OVERRIDE_OPUS_ALLOC_SCRATCH static OPUS_INLINE void *opus_alloc_scratch (size_t size) { /* Scratch space doesn't need to be cleared */ return opus_alloc(size); } #endif /** Opus wrapper for free(). To do your own dynamic allocation, all you need to do is replace this function and opus_alloc */ #ifndef OVERRIDE_OPUS_FREE static OPUS_INLINE void opus_free (void *ptr) { free(ptr); } #endif /** Copy n elements from src to dst. The 0* term provides compile-time type checking */ #ifndef OVERRIDE_OPUS_COPY #define OPUS_COPY(dst, src, n) (memcpy((dst), (src), (n)*sizeof(*(dst)) + 0*((dst)-(src)) )) #endif /** Copy n elements from src to dst, allowing overlapping regions. The 0* term provides compile-time type checking */ #ifndef OVERRIDE_OPUS_MOVE #define OPUS_MOVE(dst, src, n) (memmove((dst), (src), (n)*sizeof(*(dst)) + 0*((dst)-(src)) )) #endif /** Set n elements of dst to zero */ #ifndef OVERRIDE_OPUS_CLEAR #define OPUS_CLEAR(dst, n) (memset((dst), 0, (n)*sizeof(*(dst)))) #endif /*#ifdef __GNUC__ #pragma GCC poison printf sprintf #pragma GCC poison malloc free realloc calloc #endif*/ #endif /* OS_SUPPORT_H */ jamulus-3.9.1+dfsg/libs/opus/celt/celt.h0000644000175000017500000001762214340334543017132 0ustar vimervimer/* Copyright (c) 2007-2008 CSIRO Copyright (c) 2007-2009 Xiph.Org Foundation Copyright (c) 2008 Gregory Maxwell Written by Jean-Marc Valin and Gregory Maxwell */ /** @file celt.h @brief Contains all the functions for encoding and decoding audio */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef CELT_H #define CELT_H #include "opus_types.h" #include "opus_defines.h" #include "opus_custom.h" #include "entenc.h" #include "entdec.h" #include "arch.h" #ifdef __cplusplus extern "C" { #endif #define CELTEncoder OpusCustomEncoder #define CELTDecoder OpusCustomDecoder #define CELTMode OpusCustomMode #define LEAK_BANDS 19 typedef struct { int valid; float tonality; float tonality_slope; float noisiness; float activity; float music_prob; float music_prob_min; float music_prob_max; int bandwidth; float activity_probability; float max_pitch_ratio; /* Store as Q6 char to save space. */ unsigned char leak_boost[LEAK_BANDS]; } AnalysisInfo; typedef struct { int signalType; int offset; } SILKInfo; #define __celt_check_mode_ptr_ptr(ptr) ((ptr) + ((ptr) - (const CELTMode**)(ptr))) #define __celt_check_analysis_ptr(ptr) ((ptr) + ((ptr) - (const AnalysisInfo*)(ptr))) #define __celt_check_silkinfo_ptr(ptr) ((ptr) + ((ptr) - (const SILKInfo*)(ptr))) /* Encoder/decoder Requests */ #define CELT_SET_PREDICTION_REQUEST 10002 /** Controls the use of interframe prediction. 0=Independent frames 1=Short term interframe prediction allowed 2=Long term prediction allowed */ #define CELT_SET_PREDICTION(x) CELT_SET_PREDICTION_REQUEST, __opus_check_int(x) #define CELT_SET_INPUT_CLIPPING_REQUEST 10004 #define CELT_SET_INPUT_CLIPPING(x) CELT_SET_INPUT_CLIPPING_REQUEST, __opus_check_int(x) #define CELT_GET_AND_CLEAR_ERROR_REQUEST 10007 #define CELT_GET_AND_CLEAR_ERROR(x) CELT_GET_AND_CLEAR_ERROR_REQUEST, __opus_check_int_ptr(x) #define CELT_SET_CHANNELS_REQUEST 10008 #define CELT_SET_CHANNELS(x) CELT_SET_CHANNELS_REQUEST, __opus_check_int(x) /* Internal */ #define CELT_SET_START_BAND_REQUEST 10010 #define CELT_SET_START_BAND(x) CELT_SET_START_BAND_REQUEST, __opus_check_int(x) #define CELT_SET_END_BAND_REQUEST 10012 #define CELT_SET_END_BAND(x) CELT_SET_END_BAND_REQUEST, __opus_check_int(x) #define CELT_GET_MODE_REQUEST 10015 /** Get the CELTMode used by an encoder or decoder */ #define CELT_GET_MODE(x) CELT_GET_MODE_REQUEST, __celt_check_mode_ptr_ptr(x) #define CELT_SET_SIGNALLING_REQUEST 10016 #define CELT_SET_SIGNALLING(x) CELT_SET_SIGNALLING_REQUEST, __opus_check_int(x) #define CELT_SET_TONALITY_REQUEST 10018 #define CELT_SET_TONALITY(x) CELT_SET_TONALITY_REQUEST, __opus_check_int(x) #define CELT_SET_TONALITY_SLOPE_REQUEST 10020 #define CELT_SET_TONALITY_SLOPE(x) CELT_SET_TONALITY_SLOPE_REQUEST, __opus_check_int(x) #define CELT_SET_ANALYSIS_REQUEST 10022 #define CELT_SET_ANALYSIS(x) CELT_SET_ANALYSIS_REQUEST, __celt_check_analysis_ptr(x) #define OPUS_SET_LFE_REQUEST 10024 #define OPUS_SET_LFE(x) OPUS_SET_LFE_REQUEST, __opus_check_int(x) #define OPUS_SET_ENERGY_MASK_REQUEST 10026 #define OPUS_SET_ENERGY_MASK(x) OPUS_SET_ENERGY_MASK_REQUEST, __opus_check_val16_ptr(x) #define CELT_SET_SILK_INFO_REQUEST 10028 #define CELT_SET_SILK_INFO(x) CELT_SET_SILK_INFO_REQUEST, __celt_check_silkinfo_ptr(x) /* Encoder stuff */ int celt_encoder_get_size(int channels); int celt_encode_with_ec(OpusCustomEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc); int celt_encoder_init(CELTEncoder *st, opus_int32 sampling_rate, int channels, int arch); /* Decoder stuff */ int celt_decoder_get_size(int channels); int celt_decoder_init(CELTDecoder *st, opus_int32 sampling_rate, int channels); int celt_decode_with_ec(OpusCustomDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_val16 * OPUS_RESTRICT pcm, int frame_size, ec_dec *dec, int accum); #define celt_encoder_ctl opus_custom_encoder_ctl #define celt_decoder_ctl opus_custom_decoder_ctl #ifdef CUSTOM_MODES #define OPUS_CUSTOM_NOSTATIC #else #define OPUS_CUSTOM_NOSTATIC static OPUS_INLINE #endif static const unsigned char trim_icdf[11] = {126, 124, 119, 109, 87, 41, 19, 9, 4, 2, 0}; /* Probs: NONE: 21.875%, LIGHT: 6.25%, NORMAL: 65.625%, AGGRESSIVE: 6.25% */ static const unsigned char spread_icdf[4] = {25, 23, 2, 0}; static const unsigned char tapset_icdf[3]={2,1,0}; #ifdef CUSTOM_MODES static const unsigned char toOpusTable[20] = { 0xE0, 0xE8, 0xF0, 0xF8, 0xC0, 0xC8, 0xD0, 0xD8, 0xA0, 0xA8, 0xB0, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x80, 0x88, 0x90, 0x98, }; static const unsigned char fromOpusTable[16] = { 0x80, 0x88, 0x90, 0x98, 0x40, 0x48, 0x50, 0x58, 0x20, 0x28, 0x30, 0x38, 0x00, 0x08, 0x10, 0x18 }; static OPUS_INLINE int toOpus(unsigned char c) { int ret=0; if (c<0xA0) ret = toOpusTable[c>>3]; if (ret == 0) return -1; else return ret|(c&0x7); } static OPUS_INLINE int fromOpus(unsigned char c) { if (c<0x80) return -1; else return fromOpusTable[(c>>3)-16] | (c&0x7); } #endif /* CUSTOM_MODES */ #define COMBFILTER_MAXPERIOD 1024 #define COMBFILTER_MINPERIOD 15 extern const signed char tf_select_table[4][8]; #if defined(ENABLE_HARDENING) || defined(ENABLE_ASSERTIONS) void validate_celt_decoder(CELTDecoder *st); #define VALIDATE_CELT_DECODER(st) validate_celt_decoder(st) #else #define VALIDATE_CELT_DECODER(st) #endif int resampling_factor(opus_int32 rate); void celt_preemphasis(const opus_val16 * OPUS_RESTRICT pcmp, celt_sig * OPUS_RESTRICT inp, int N, int CC, int upsample, const opus_val16 *coef, celt_sig *mem, int clip); void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N, opus_val16 g0, opus_val16 g1, int tapset0, int tapset1, const opus_val16 *window, int overlap, int arch); #ifdef NON_STATIC_COMB_FILTER_CONST_C void comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N, opus_val16 g10, opus_val16 g11, opus_val16 g12); #endif #ifndef OVERRIDE_COMB_FILTER_CONST # define comb_filter_const(y, x, T, N, g10, g11, g12, arch) \ ((void)(arch),comb_filter_const_c(y, x, T, N, g10, g11, g12)) #endif void init_caps(const CELTMode *m,int *cap,int LM,int C); #ifdef RESYNTH void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, const opus_val16 *coef, celt_sig *mem); void celt_synthesis(const CELTMode *mode, celt_norm *X, celt_sig * out_syn[], opus_val16 *oldBandE, int start, int effEnd, int C, int CC, int isTransient, int LM, int downsample, int silence); #endif #ifdef __cplusplus } #endif #endif /* CELT_H */ jamulus-3.9.1+dfsg/libs/opus/celt/arch.h0000644000175000017500000002035114340334543017111 0ustar vimervimer/* Copyright (c) 2003-2008 Jean-Marc Valin Copyright (c) 2007-2008 CSIRO Copyright (c) 2007-2009 Xiph.Org Foundation Written by Jean-Marc Valin */ /** @file arch.h @brief Various architecture definitions for CELT */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef ARCH_H #define ARCH_H #include "opus_types.h" #include "opus_defines.h" # if !defined(__GNUC_PREREQ) # if defined(__GNUC__)&&defined(__GNUC_MINOR__) # define __GNUC_PREREQ(_maj,_min) \ ((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min)) # else # define __GNUC_PREREQ(_maj,_min) 0 # endif # endif #if OPUS_GNUC_PREREQ(3, 0) #define opus_likely(x) (__builtin_expect(!!(x), 1)) #define opus_unlikely(x) (__builtin_expect(!!(x), 0)) #else #define opus_likely(x) (!!(x)) #define opus_unlikely(x) (!!(x)) #endif #define CELT_SIG_SCALE 32768.f #define CELT_FATAL(str) celt_fatal(str, __FILE__, __LINE__); #if defined(ENABLE_ASSERTIONS) || defined(ENABLE_HARDENING) #ifdef __GNUC__ __attribute__((noreturn)) #endif void celt_fatal(const char *str, const char *file, int line); #if defined(CELT_C) && !defined(OVERRIDE_celt_fatal) #include #include #ifdef __GNUC__ __attribute__((noreturn)) #endif void celt_fatal(const char *str, const char *file, int line) { fprintf (stderr, "Fatal (internal) error in %s, line %d: %s\n", file, line, str); abort(); } #endif #define celt_assert(cond) {if (!(cond)) {CELT_FATAL("assertion failed: " #cond);}} #define celt_assert2(cond, message) {if (!(cond)) {CELT_FATAL("assertion failed: " #cond "\n" message);}} #define MUST_SUCCEED(call) celt_assert((call) == OPUS_OK) #else #define celt_assert(cond) #define celt_assert2(cond, message) #define MUST_SUCCEED(call) do {if((call) != OPUS_OK) {RESTORE_STACK; return OPUS_INTERNAL_ERROR;} } while (0) #endif #if defined(ENABLE_ASSERTIONS) #define celt_sig_assert(cond) {if (!(cond)) {CELT_FATAL("signal assertion failed: " #cond);}} #else #define celt_sig_assert(cond) #endif #define IMUL32(a,b) ((a)*(b)) #define MIN16(a,b) ((a) < (b) ? (a) : (b)) /**< Minimum 16-bit value. */ #define MAX16(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 16-bit value. */ #define MIN32(a,b) ((a) < (b) ? (a) : (b)) /**< Minimum 32-bit value. */ #define MAX32(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 32-bit value. */ #define IMIN(a,b) ((a) < (b) ? (a) : (b)) /**< Minimum int value. */ #define IMAX(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum int value. */ #define UADD32(a,b) ((a)+(b)) #define USUB32(a,b) ((a)-(b)) /* Set this if opus_int64 is a native type of the CPU. */ /* Assume that all LP64 architectures have fast 64-bit types; also x86_64 (which can be ILP32 for x32) and Win64 (which is LLP64). */ #if defined(__x86_64__) || defined(__LP64__) || defined(_WIN64) #define OPUS_FAST_INT64 1 #else #define OPUS_FAST_INT64 0 #endif #define PRINT_MIPS(file) #ifdef FIXED_POINT typedef opus_int16 opus_val16; typedef opus_int32 opus_val32; typedef opus_int64 opus_val64; typedef opus_val32 celt_sig; typedef opus_val16 celt_norm; typedef opus_val32 celt_ener; #define celt_isnan(x) 0 #define Q15ONE 32767 #define SIG_SHIFT 12 /* Safe saturation value for 32-bit signals. Should be less than 2^31*(1-0.85) to avoid blowing up on DC at deemphasis.*/ #define SIG_SAT (300000000) #define NORM_SCALING 16384 #define DB_SHIFT 10 #define EPSILON 1 #define VERY_SMALL 0 #define VERY_LARGE16 ((opus_val16)32767) #define Q15_ONE ((opus_val16)32767) #define SCALEIN(a) (a) #define SCALEOUT(a) (a) #define ABS16(x) ((x) < 0 ? (-(x)) : (x)) #define ABS32(x) ((x) < 0 ? (-(x)) : (x)) static OPUS_INLINE opus_int16 SAT16(opus_int32 x) { return x > 32767 ? 32767 : x < -32768 ? -32768 : (opus_int16)x; } #ifdef FIXED_DEBUG #include "fixed_debug.h" #else #include "fixed_generic.h" #ifdef OPUS_ARM_PRESUME_AARCH64_NEON_INTR #include "arm/fixed_arm64.h" #elif defined (OPUS_ARM_INLINE_EDSP) #include "arm/fixed_armv5e.h" #elif defined (OPUS_ARM_INLINE_ASM) #include "arm/fixed_armv4.h" #elif defined (BFIN_ASM) #include "fixed_bfin.h" #elif defined (TI_C5X_ASM) #include "fixed_c5x.h" #elif defined (TI_C6X_ASM) #include "fixed_c6x.h" #endif #endif #else /* FIXED_POINT */ typedef float opus_val16; typedef float opus_val32; typedef float opus_val64; typedef float celt_sig; typedef float celt_norm; typedef float celt_ener; #ifdef FLOAT_APPROX /* This code should reliably detect NaN/inf even when -ffast-math is used. Assumes IEEE 754 format. */ static OPUS_INLINE int celt_isnan(float x) { union {float f; opus_uint32 i;} in; in.f = x; return ((in.i>>23)&0xFF)==0xFF && (in.i&0x007FFFFF)!=0; } #else #ifdef __FAST_MATH__ #error Cannot build libopus with -ffast-math unless FLOAT_APPROX is defined. This could result in crashes on extreme (e.g. NaN) input #endif #define celt_isnan(x) ((x)!=(x)) #endif #define Q15ONE 1.0f #define NORM_SCALING 1.f #define EPSILON 1e-15f #define VERY_SMALL 1e-30f #define VERY_LARGE16 1e15f #define Q15_ONE ((opus_val16)1.f) /* This appears to be the same speed as C99's fabsf() but it's more portable. */ #define ABS16(x) ((float)fabs(x)) #define ABS32(x) ((float)fabs(x)) #define QCONST16(x,bits) (x) #define QCONST32(x,bits) (x) #define NEG16(x) (-(x)) #define NEG32(x) (-(x)) #define NEG32_ovflw(x) (-(x)) #define EXTRACT16(x) (x) #define EXTEND32(x) (x) #define SHR16(a,shift) (a) #define SHL16(a,shift) (a) #define SHR32(a,shift) (a) #define SHL32(a,shift) (a) #define PSHR32(a,shift) (a) #define VSHR32(a,shift) (a) #define PSHR(a,shift) (a) #define SHR(a,shift) (a) #define SHL(a,shift) (a) #define SATURATE(x,a) (x) #define SATURATE16(x) (x) #define ROUND16(a,shift) (a) #define SROUND16(a,shift) (a) #define HALF16(x) (.5f*(x)) #define HALF32(x) (.5f*(x)) #define ADD16(a,b) ((a)+(b)) #define SUB16(a,b) ((a)-(b)) #define ADD32(a,b) ((a)+(b)) #define SUB32(a,b) ((a)-(b)) #define ADD32_ovflw(a,b) ((a)+(b)) #define SUB32_ovflw(a,b) ((a)-(b)) #define MULT16_16_16(a,b) ((a)*(b)) #define MULT16_16(a,b) ((opus_val32)(a)*(opus_val32)(b)) #define MAC16_16(c,a,b) ((c)+(opus_val32)(a)*(opus_val32)(b)) #define MULT16_32_Q15(a,b) ((a)*(b)) #define MULT16_32_Q16(a,b) ((a)*(b)) #define MULT32_32_Q31(a,b) ((a)*(b)) #define MAC16_32_Q15(c,a,b) ((c)+(a)*(b)) #define MAC16_32_Q16(c,a,b) ((c)+(a)*(b)) #define MULT16_16_Q11_32(a,b) ((a)*(b)) #define MULT16_16_Q11(a,b) ((a)*(b)) #define MULT16_16_Q13(a,b) ((a)*(b)) #define MULT16_16_Q14(a,b) ((a)*(b)) #define MULT16_16_Q15(a,b) ((a)*(b)) #define MULT16_16_P15(a,b) ((a)*(b)) #define MULT16_16_P13(a,b) ((a)*(b)) #define MULT16_16_P14(a,b) ((a)*(b)) #define MULT16_32_P16(a,b) ((a)*(b)) #define DIV32_16(a,b) (((opus_val32)(a))/(opus_val16)(b)) #define DIV32(a,b) (((opus_val32)(a))/(opus_val32)(b)) #define SCALEIN(a) ((a)*CELT_SIG_SCALE) #define SCALEOUT(a) ((a)*(1/CELT_SIG_SCALE)) #define SIG2WORD16(x) (x) #endif /* !FIXED_POINT */ #ifndef GLOBAL_STACK_SIZE #ifdef FIXED_POINT #define GLOBAL_STACK_SIZE 120000 #else #define GLOBAL_STACK_SIZE 120000 #endif #endif #endif /* ARCH_H */ jamulus-3.9.1+dfsg/libs/opus/celt/vq.h0000644000175000017500000000604514340334543016626 0ustar vimervimer/* Copyright (c) 2007-2008 CSIRO Copyright (c) 2007-2009 Xiph.Org Foundation Written by Jean-Marc Valin */ /** @file vq.h @brief Vector quantisation of the residual */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef VQ_H #define VQ_H #include "entenc.h" #include "entdec.h" #include "modes.h" #if (defined(OPUS_X86_MAY_HAVE_SSE2) && !defined(FIXED_POINT)) #include "x86/vq_sse.h" #endif void exp_rotation(celt_norm *X, int len, int dir, int stride, int K, int spread); opus_val16 op_pvq_search_c(celt_norm *X, int *iy, int K, int N, int arch); #if !defined(OVERRIDE_OP_PVQ_SEARCH) #define op_pvq_search(x, iy, K, N, arch) \ (op_pvq_search_c(x, iy, K, N, arch)) #endif /** Algebraic pulse-vector quantiser. The signal x is replaced by the sum of * the pitch and a combination of pulses such that its norm is still equal * to 1. This is the function that will typically require the most CPU. * @param X Residual signal to quantise/encode (returns quantised version) * @param N Number of samples to encode * @param K Number of pulses to use * @param enc Entropy encoder state * @ret A mask indicating which blocks in the band received pulses */ unsigned alg_quant(celt_norm *X, int N, int K, int spread, int B, ec_enc *enc, opus_val16 gain, int resynth, int arch); /** Algebraic pulse decoder * @param X Decoded normalised spectrum (returned) * @param N Number of samples to decode * @param K Number of pulses to use * @param dec Entropy decoder state * @ret A mask indicating which blocks in the band received pulses */ unsigned alg_unquant(celt_norm *X, int N, int K, int spread, int B, ec_dec *dec, opus_val16 gain); void renormalise_vector(celt_norm *X, int N, opus_val16 gain, int arch); int stereo_itheta(const celt_norm *X, const celt_norm *Y, int stereo, int N, int arch); #endif /* VQ_H */ jamulus-3.9.1+dfsg/libs/opus/celt/cpu_support.h0000644000175000017500000000450414340334543020561 0ustar vimervimer/* Copyright (c) 2010 Xiph.Org Foundation * Copyright (c) 2013 Parrot */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef CPU_SUPPORT_H #define CPU_SUPPORT_H #include "opus_types.h" #include "opus_defines.h" #if defined(OPUS_HAVE_RTCD) && \ (defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)) #include "arm/armcpu.h" /* We currently support 4 ARM variants: * arch[0] -> ARMv4 * arch[1] -> ARMv5E * arch[2] -> ARMv6 * arch[3] -> NEON */ #define OPUS_ARCHMASK 3 #elif (defined(OPUS_X86_MAY_HAVE_SSE) && !defined(OPUS_X86_PRESUME_SSE)) || \ (defined(OPUS_X86_MAY_HAVE_SSE2) && !defined(OPUS_X86_PRESUME_SSE2)) || \ (defined(OPUS_X86_MAY_HAVE_SSE4_1) && !defined(OPUS_X86_PRESUME_SSE4_1)) || \ (defined(OPUS_X86_MAY_HAVE_AVX) && !defined(OPUS_X86_PRESUME_AVX)) #include "x86/x86cpu.h" /* We currently support 5 x86 variants: * arch[0] -> non-sse * arch[1] -> sse * arch[2] -> sse2 * arch[3] -> sse4.1 * arch[4] -> avx */ #define OPUS_ARCHMASK 7 int opus_select_arch(void); #else #define OPUS_ARCHMASK 0 static OPUS_INLINE int opus_select_arch(void) { return 0; } #endif #endif jamulus-3.9.1+dfsg/libs/opus/celt/entenc.h0000644000175000017500000001246114340334543017453 0ustar vimervimer/* Copyright (c) 2001-2011 Timothy B. Terriberry Copyright (c) 2008-2009 Xiph.Org Foundation */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(_entenc_H) # define _entenc_H (1) # include # include "entcode.h" /*Initializes the encoder. _buf: The buffer to store output bytes in. _size: The size of the buffer, in chars.*/ void ec_enc_init(ec_enc *_this,unsigned char *_buf,opus_uint32 _size); /*Encodes a symbol given its frequency information. The frequency information must be discernible by the decoder, assuming it has read only the previous symbols from the stream. It is allowable to change the frequency information, or even the entire source alphabet, so long as the decoder can tell from the context of the previously encoded information that it is supposed to do so as well. _fl: The cumulative frequency of all symbols that come before the one to be encoded. _fh: The cumulative frequency of all symbols up to and including the one to be encoded. Together with _fl, this defines the range [_fl,_fh) in which the decoded value will fall. _ft: The sum of the frequencies of all the symbols*/ void ec_encode(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _ft); /*Equivalent to ec_encode() with _ft==1<<_bits.*/ void ec_encode_bin(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _bits); /* Encode a bit that has a 1/(1<<_logp) probability of being a one */ void ec_enc_bit_logp(ec_enc *_this,int _val,unsigned _logp); /*Encodes a symbol given an "inverse" CDF table. _s: The index of the symbol to encode. _icdf: The "inverse" CDF, such that symbol _s falls in the range [_s>0?ft-_icdf[_s-1]:0,ft-_icdf[_s]), where ft=1<<_ftb. The values must be monotonically non-increasing, and the last value must be 0. _ftb: The number of bits of precision in the cumulative distribution.*/ void ec_enc_icdf(ec_enc *_this,int _s,const unsigned char *_icdf,unsigned _ftb); /*Encodes a raw unsigned integer in the stream. _fl: The integer to encode. _ft: The number of integers that can be encoded (one more than the max). This must be at least 2, and no more than 2**32-1.*/ void ec_enc_uint(ec_enc *_this,opus_uint32 _fl,opus_uint32 _ft); /*Encodes a sequence of raw bits in the stream. _fl: The bits to encode. _ftb: The number of bits to encode. This must be between 1 and 25, inclusive.*/ void ec_enc_bits(ec_enc *_this,opus_uint32 _fl,unsigned _ftb); /*Overwrites a few bits at the very start of an existing stream, after they have already been encoded. This makes it possible to have a few flags up front, where it is easy for decoders to access them without parsing the whole stream, even if their values are not determined until late in the encoding process, without having to buffer all the intermediate symbols in the encoder. In order for this to work, at least _nbits bits must have already been encoded using probabilities that are an exact power of two. The encoder can verify the number of encoded bits is sufficient, but cannot check this latter condition. _val: The bits to encode (in the least _nbits significant bits). They will be decoded in order from most-significant to least. _nbits: The number of bits to overwrite. This must be no more than 8.*/ void ec_enc_patch_initial_bits(ec_enc *_this,unsigned _val,unsigned _nbits); /*Compacts the data to fit in the target size. This moves up the raw bits at the end of the current buffer so they are at the end of the new buffer size. The caller must ensure that the amount of data that's already been written will fit in the new size. _size: The number of bytes in the new buffer. This must be large enough to contain the bits already written, and must be no larger than the existing size.*/ void ec_enc_shrink(ec_enc *_this,opus_uint32 _size); /*Indicates that there are no more symbols to encode. All reamining output bytes are flushed to the output buffer. ec_enc_init() must be called before the encoder can be used again.*/ void ec_enc_done(ec_enc *_this); #endif jamulus-3.9.1+dfsg/libs/opus/celt/rate.h0000644000175000017500000000632414340334543017133 0ustar vimervimer/* Copyright (c) 2007-2008 CSIRO Copyright (c) 2007-2009 Xiph.Org Foundation Written by Jean-Marc Valin */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef RATE_H #define RATE_H #define MAX_PSEUDO 40 #define LOG_MAX_PSEUDO 6 #define CELT_MAX_PULSES 128 #define MAX_FINE_BITS 8 #define FINE_OFFSET 21 #define QTHETA_OFFSET 4 #define QTHETA_OFFSET_TWOPHASE 16 #include "cwrs.h" #include "modes.h" void compute_pulse_cache(CELTMode *m, int LM); static OPUS_INLINE int get_pulses(int i) { return i<8 ? i : (8 + (i&7)) << ((i>>3)-1); } static OPUS_INLINE int bits2pulses(const CELTMode *m, int band, int LM, int bits) { int i; int lo, hi; const unsigned char *cache; LM++; cache = m->cache.bits + m->cache.index[LM*m->nbEBands+band]; lo = 0; hi = cache[0]; bits--; for (i=0;i>1; /* OPT: Make sure this is implemented with a conditional move */ if ((int)cache[mid] >= bits) hi = mid; else lo = mid; } if (bits- (lo == 0 ? -1 : (int)cache[lo]) <= (int)cache[hi]-bits) return lo; else return hi; } static OPUS_INLINE int pulses2bits(const CELTMode *m, int band, int LM, int pulses) { const unsigned char *cache; LM++; cache = m->cache.bits + m->cache.index[LM*m->nbEBands+band]; return pulses == 0 ? 0 : cache[pulses]+1; } /** Compute the pulse allocation, i.e. how many pulses will go in each * band. @param m mode @param offsets Requested increase or decrease in the number of bits for each band @param total Number of bands @param pulses Number of pulses per band (returned) @return Total number of bits allocated */ int clt_compute_allocation(const CELTMode *m, int start, int end, const int *offsets, const int *cap, int alloc_trim, int *intensity, int *dual_stereo, opus_int32 total, opus_int32 *balance, int *pulses, int *ebits, int *fine_priority, int C, int LM, ec_ctx *ec, int encode, int prev, int signalBandwidth); #endif jamulus-3.9.1+dfsg/libs/opus/celt/entcode.h0000644000175000017500000001245714340334543017625 0ustar vimervimer/* Copyright (c) 2001-2011 Timothy B. Terriberry Copyright (c) 2008-2009 Xiph.Org Foundation */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "opus_types.h" #include "opus_defines.h" #if !defined(_entcode_H) # define _entcode_H (1) # include # include # include "ecintrin.h" extern const opus_uint32 SMALL_DIV_TABLE[129]; #ifdef OPUS_ARM_ASM #define USE_SMALL_DIV_TABLE #endif /*OPT: ec_window must be at least 32 bits, but if you have fast arithmetic on a larger type, you can speed up the decoder by using it here.*/ typedef opus_uint32 ec_window; typedef struct ec_ctx ec_ctx; typedef struct ec_ctx ec_enc; typedef struct ec_ctx ec_dec; # define EC_WINDOW_SIZE ((int)sizeof(ec_window)*CHAR_BIT) /*The number of bits to use for the range-coded part of unsigned integers.*/ # define EC_UINT_BITS (8) /*The resolution of fractional-precision bit usage measurements, i.e., 3 => 1/8th bits.*/ # define BITRES 3 /*The entropy encoder/decoder context. We use the same structure for both, so that common functions like ec_tell() can be used on either one.*/ struct ec_ctx{ /*Buffered input/output.*/ unsigned char *buf; /*The size of the buffer.*/ opus_uint32 storage; /*The offset at which the last byte containing raw bits was read/written.*/ opus_uint32 end_offs; /*Bits that will be read from/written at the end.*/ ec_window end_window; /*Number of valid bits in end_window.*/ int nend_bits; /*The total number of whole bits read/written. This does not include partial bits currently in the range coder.*/ int nbits_total; /*The offset at which the next range coder byte will be read/written.*/ opus_uint32 offs; /*The number of values in the current range.*/ opus_uint32 rng; /*In the decoder: the difference between the top of the current range and the input value, minus one. In the encoder: the low end of the current range.*/ opus_uint32 val; /*In the decoder: the saved normalization factor from ec_decode(). In the encoder: the number of outstanding carry propagating symbols.*/ opus_uint32 ext; /*A buffered input/output symbol, awaiting carry propagation.*/ int rem; /*Nonzero if an error occurred.*/ int error; }; static OPUS_INLINE opus_uint32 ec_range_bytes(ec_ctx *_this){ return _this->offs; } static OPUS_INLINE unsigned char *ec_get_buffer(ec_ctx *_this){ return _this->buf; } static OPUS_INLINE int ec_get_error(ec_ctx *_this){ return _this->error; } /*Returns the number of bits "used" by the encoded or decoded symbols so far. This same number can be computed in either the encoder or the decoder, and is suitable for making coding decisions. Return: The number of bits. This will always be slightly larger than the exact value (e.g., all rounding error is in the positive direction).*/ static OPUS_INLINE int ec_tell(ec_ctx *_this){ return _this->nbits_total-EC_ILOG(_this->rng); } /*Returns the number of bits "used" by the encoded or decoded symbols so far. This same number can be computed in either the encoder or the decoder, and is suitable for making coding decisions. Return: The number of bits scaled by 2**BITRES. This will always be slightly larger than the exact value (e.g., all rounding error is in the positive direction).*/ opus_uint32 ec_tell_frac(ec_ctx *_this); /* Tested exhaustively for all n and for 1<=d<=256 */ static OPUS_INLINE opus_uint32 celt_udiv(opus_uint32 n, opus_uint32 d) { celt_sig_assert(d>0); #ifdef USE_SMALL_DIV_TABLE if (d>256) return n/d; else { opus_uint32 t, q; t = EC_ILOG(d&-d); q = (opus_uint64)SMALL_DIV_TABLE[d>>t]*(n>>(t-1))>>32; return q+(n-q*d >= d); } #else return n/d; #endif } static OPUS_INLINE opus_int32 celt_sudiv(opus_int32 n, opus_int32 d) { celt_sig_assert(d>0); #ifdef USE_SMALL_DIV_TABLE if (n<0) return -(opus_int32)celt_udiv(-n, d); else return celt_udiv(n, d); #else return n/d; #endif } #endif jamulus-3.9.1+dfsg/libs/opus/celt/kiss_fft.c0000644000175000017500000004115414340334543020003 0ustar vimervimer/*Copyright (c) 2003-2004, Mark Borgerding Lots of modifications by Jean-Marc Valin Copyright (c) 2005-2007, Xiph.Org Foundation Copyright (c) 2008, Xiph.Org Foundation, CSIRO All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/ /* This code is originally from Mark Borgerding's KISS-FFT but has been heavily modified to better suit Opus */ #ifndef SKIP_CONFIG_H # ifdef HAVE_CONFIG_H # include "config.h" # endif #endif #include "_kiss_fft_guts.h" #include "arch.h" #include "os_support.h" #include "mathops.h" #include "stack_alloc.h" /* The guts header contains all the multiplication and addition macros that are defined for complex numbers. It also declares the kf_ internal functions. */ static void kf_bfly2( kiss_fft_cpx * Fout, int m, int N ) { kiss_fft_cpx * Fout2; int i; (void)m; #ifdef CUSTOM_MODES if (m==1) { celt_assert(m==1); for (i=0;itwiddles; /* m is guaranteed to be a multiple of 4. */ for (j=0;jtwiddles[fstride*m]; #endif for (i=0;itwiddles; /* For non-custom modes, m is guaranteed to be a multiple of 4. */ k=m; do { C_MUL(scratch[1],Fout[m] , *tw1); C_MUL(scratch[2],Fout[m2] , *tw2); C_ADD(scratch[3],scratch[1],scratch[2]); C_SUB(scratch[0],scratch[1],scratch[2]); tw1 += fstride; tw2 += fstride*2; Fout[m].r = SUB32_ovflw(Fout->r, HALF_OF(scratch[3].r)); Fout[m].i = SUB32_ovflw(Fout->i, HALF_OF(scratch[3].i)); C_MULBYSCALAR( scratch[0] , epi3.i ); C_ADDTO(*Fout,scratch[3]); Fout[m2].r = ADD32_ovflw(Fout[m].r, scratch[0].i); Fout[m2].i = SUB32_ovflw(Fout[m].i, scratch[0].r); Fout[m].r = SUB32_ovflw(Fout[m].r, scratch[0].i); Fout[m].i = ADD32_ovflw(Fout[m].i, scratch[0].r); ++Fout; } while(--k); } } #ifndef OVERRIDE_kf_bfly5 static void kf_bfly5( kiss_fft_cpx * Fout, const size_t fstride, const kiss_fft_state *st, int m, int N, int mm ) { kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4; int i, u; kiss_fft_cpx scratch[13]; const kiss_twiddle_cpx *tw; kiss_twiddle_cpx ya,yb; kiss_fft_cpx * Fout_beg = Fout; #ifdef FIXED_POINT ya.r = 10126; ya.i = -31164; yb.r = -26510; yb.i = -19261; #else ya = st->twiddles[fstride*m]; yb = st->twiddles[fstride*2*m]; #endif tw=st->twiddles; for (i=0;ir = ADD32_ovflw(Fout0->r, ADD32_ovflw(scratch[7].r, scratch[8].r)); Fout0->i = ADD32_ovflw(Fout0->i, ADD32_ovflw(scratch[7].i, scratch[8].i)); scratch[5].r = ADD32_ovflw(scratch[0].r, ADD32_ovflw(S_MUL(scratch[7].r,ya.r), S_MUL(scratch[8].r,yb.r))); scratch[5].i = ADD32_ovflw(scratch[0].i, ADD32_ovflw(S_MUL(scratch[7].i,ya.r), S_MUL(scratch[8].i,yb.r))); scratch[6].r = ADD32_ovflw(S_MUL(scratch[10].i,ya.i), S_MUL(scratch[9].i,yb.i)); scratch[6].i = NEG32_ovflw(ADD32_ovflw(S_MUL(scratch[10].r,ya.i), S_MUL(scratch[9].r,yb.i))); C_SUB(*Fout1,scratch[5],scratch[6]); C_ADD(*Fout4,scratch[5],scratch[6]); scratch[11].r = ADD32_ovflw(scratch[0].r, ADD32_ovflw(S_MUL(scratch[7].r,yb.r), S_MUL(scratch[8].r,ya.r))); scratch[11].i = ADD32_ovflw(scratch[0].i, ADD32_ovflw(S_MUL(scratch[7].i,yb.r), S_MUL(scratch[8].i,ya.r))); scratch[12].r = SUB32_ovflw(S_MUL(scratch[9].i,ya.i), S_MUL(scratch[10].i,yb.i)); scratch[12].i = SUB32_ovflw(S_MUL(scratch[10].r,yb.i), S_MUL(scratch[9].r,ya.i)); C_ADD(*Fout2,scratch[11],scratch[12]); C_SUB(*Fout3,scratch[11],scratch[12]); ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4; } } } #endif /* OVERRIDE_kf_bfly5 */ #endif #ifdef CUSTOM_MODES static void compute_bitrev_table( int Fout, opus_int16 *f, const size_t fstride, int in_stride, opus_int16 * factors, const kiss_fft_state *st ) { const int p=*factors++; /* the radix */ const int m=*factors++; /* stage's fft length/p */ /*printf ("fft %d %d %d %d %d %d\n", p*m, m, p, s2, fstride*in_stride, N);*/ if (m==1) { int j; for (j=0;j32000 || (opus_int32)p*(opus_int32)p > n) p = n; /* no more factors, skip to end */ } n /= p; #ifdef RADIX_TWO_ONLY if (p!=2 && p != 4) #else if (p>5) #endif { return 0; } facbuf[2*stages] = p; if (p==2 && stages > 1) { facbuf[2*stages] = 4; facbuf[2] = 2; } stages++; } while (n > 1); n = nbak; /* Reverse the order to get the radix 4 at the end, so we can use the fast degenerate case. It turns out that reversing the order also improves the noise behaviour. */ for (i=0;i= memneeded) st = (kiss_fft_state*)mem; *lenmem = memneeded; } if (st) { opus_int16 *bitrev; kiss_twiddle_cpx *twiddles; st->nfft=nfft; #ifdef FIXED_POINT st->scale_shift = celt_ilog2(st->nfft); if (st->nfft == 1<scale_shift) st->scale = Q15ONE; else st->scale = (1073741824+st->nfft/2)/st->nfft>>(15-st->scale_shift); #else st->scale = 1.f/nfft; #endif if (base != NULL) { st->twiddles = base->twiddles; st->shift = 0; while (st->shift < 32 && nfft<shift != base->nfft) st->shift++; if (st->shift>=32) goto fail; } else { st->twiddles = twiddles = (kiss_twiddle_cpx*)KISS_FFT_MALLOC(sizeof(kiss_twiddle_cpx)*nfft); compute_twiddles(twiddles, nfft); st->shift = -1; } if (!kf_factor(nfft,st->factors)) { goto fail; } /* bitrev */ st->bitrev = bitrev = (opus_int16*)KISS_FFT_MALLOC(sizeof(opus_int16)*nfft); if (st->bitrev==NULL) goto fail; compute_bitrev_table(0, bitrev, 1,1, st->factors,st); /* Initialize architecture specific fft parameters */ if (opus_fft_alloc_arch(st, arch)) goto fail; } return st; fail: opus_fft_free(st, arch); return NULL; } kiss_fft_state *opus_fft_alloc(int nfft,void * mem,size_t * lenmem, int arch) { return opus_fft_alloc_twiddles(nfft, mem, lenmem, NULL, arch); } void opus_fft_free_arch_c(kiss_fft_state *st) { (void)st; } void opus_fft_free(const kiss_fft_state *cfg, int arch) { if (cfg) { opus_fft_free_arch((kiss_fft_state *)cfg, arch); opus_free((opus_int16*)cfg->bitrev); if (cfg->shift < 0) opus_free((kiss_twiddle_cpx*)cfg->twiddles); opus_free((kiss_fft_state*)cfg); } } #endif /* CUSTOM_MODES */ void opus_fft_impl(const kiss_fft_state *st,kiss_fft_cpx *fout) { int m2, m; int p; int L; int fstride[MAXFACTORS]; int i; int shift; /* st->shift can be -1 */ shift = st->shift>0 ? st->shift : 0; fstride[0] = 1; L=0; do { p = st->factors[2*L]; m = st->factors[2*L+1]; fstride[L+1] = fstride[L]*p; L++; } while(m!=1); m = st->factors[2*L-1]; for (i=L-1;i>=0;i--) { if (i!=0) m2 = st->factors[2*i-1]; else m2 = 1; switch (st->factors[2*i]) { case 2: kf_bfly2(fout, m, fstride[i]); break; case 4: kf_bfly4(fout,fstride[i]<scale_shift-1; #endif scale = st->scale; celt_assert2 (fin != fout, "In-place FFT not supported"); /* Bit-reverse the input */ for (i=0;infft;i++) { kiss_fft_cpx x = fin[i]; fout[st->bitrev[i]].r = SHR32(MULT16_32_Q16(scale, x.r), scale_shift); fout[st->bitrev[i]].i = SHR32(MULT16_32_Q16(scale, x.i), scale_shift); } opus_fft_impl(st, fout); } void opus_ifft_c(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout) { int i; celt_assert2 (fin != fout, "In-place FFT not supported"); /* Bit-reverse the input */ for (i=0;infft;i++) fout[st->bitrev[i]] = fin[i]; for (i=0;infft;i++) fout[i].i = -fout[i].i; opus_fft_impl(st, fout); for (i=0;infft;i++) fout[i].i = -fout[i].i; } jamulus-3.9.1+dfsg/libs/opus/celt/celt_lpc.h0000644000175000017500000000425514340334543017766 0ustar vimervimer/* Copyright (c) 2009-2010 Xiph.Org Foundation Written by Jean-Marc Valin */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef PLC_H #define PLC_H #include "arch.h" #include "cpu_support.h" #if defined(OPUS_X86_MAY_HAVE_SSE4_1) #include "x86/celt_lpc_sse.h" #endif #define LPC_ORDER 24 void _celt_lpc(opus_val16 *_lpc, const opus_val32 *ac, int p); void celt_fir_c( const opus_val16 *x, const opus_val16 *num, opus_val16 *y, int N, int ord, int arch); #if !defined(OVERRIDE_CELT_FIR) #define celt_fir(x, num, y, N, ord, arch) \ (celt_fir_c(x, num, y, N, ord, arch)) #endif void celt_iir(const opus_val32 *x, const opus_val16 *den, opus_val32 *y, int N, int ord, opus_val16 *mem, int arch); int _celt_autocorr(const opus_val16 *x, opus_val32 *ac, const opus_val16 *window, int overlap, int lag, int n, int arch); #endif /* PLC_H */ jamulus-3.9.1+dfsg/libs/opus/celt/laplace.h0000644000175000017500000000413614340334543017600 0ustar vimervimer/* Copyright (c) 2007 CSIRO Copyright (c) 2007-2009 Xiph.Org Foundation Written by Jean-Marc Valin */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "entenc.h" #include "entdec.h" /** Encode a value that is assumed to be the realisation of a Laplace-distributed random process @param enc Entropy encoder state @param value Value to encode @param fs Probability of 0, multiplied by 32768 @param decay Probability of the value +/- 1, multiplied by 16384 */ void ec_laplace_encode(ec_enc *enc, int *value, unsigned fs, int decay); /** Decode a value that is assumed to be the realisation of a Laplace-distributed random process @param dec Entropy decoder state @param fs Probability of 0, multiplied by 32768 @param decay Probability of the value +/- 1, multiplied by 16384 @return Value decoded */ int ec_laplace_decode(ec_dec *dec, unsigned fs, int decay); jamulus-3.9.1+dfsg/libs/opus/celt/mdct.c0000644000175000017500000002522214340334543017120 0ustar vimervimer/* Copyright (c) 2007-2008 CSIRO Copyright (c) 2007-2008 Xiph.Org Foundation Written by Jean-Marc Valin */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* This is a simple MDCT implementation that uses a N/4 complex FFT to do most of the work. It should be relatively straightforward to plug in pretty much and FFT here. This replaces the Vorbis FFT (and uses the exact same API), which was a bit too messy and that was ending up duplicating code (might as well use the same FFT everywhere). The algorithm is similar to (and inspired from) Fabrice Bellard's MDCT implementation in FFMPEG, but has differences in signs, ordering and scaling in many places. */ #ifndef SKIP_CONFIG_H #ifdef HAVE_CONFIG_H #include "config.h" #endif #endif #include "mdct.h" #include "kiss_fft.h" #include "_kiss_fft_guts.h" #include #include "os_support.h" #include "mathops.h" #include "stack_alloc.h" #if defined(MIPSr1_ASM) #include "mips/mdct_mipsr1.h" #endif #ifdef CUSTOM_MODES int clt_mdct_init(mdct_lookup *l,int N, int maxshift, int arch) { int i; kiss_twiddle_scalar *trig; int shift; int N2=N>>1; l->n = N; l->maxshift = maxshift; for (i=0;i<=maxshift;i++) { if (i==0) l->kfft[i] = opus_fft_alloc(N>>2>>i, 0, 0, arch); else l->kfft[i] = opus_fft_alloc_twiddles(N>>2>>i, 0, 0, l->kfft[0], arch); #ifndef ENABLE_TI_DSPLIB55 if (l->kfft[i]==NULL) return 0; #endif } l->trig = trig = (kiss_twiddle_scalar*)opus_alloc((N-(N2>>maxshift))*sizeof(kiss_twiddle_scalar)); if (l->trig==NULL) return 0; for (shift=0;shift<=maxshift;shift++) { /* We have enough points that sine isn't necessary */ #if defined(FIXED_POINT) #if 1 for (i=0;i>= 1; N >>= 1; } return 1; } void clt_mdct_clear(mdct_lookup *l, int arch) { int i; for (i=0;i<=l->maxshift;i++) opus_fft_free(l->kfft[i], arch); opus_free((kiss_twiddle_scalar*)l->trig); } #endif /* CUSTOM_MODES */ /* Forward MDCT trashes the input array */ #ifndef OVERRIDE_clt_mdct_forward void clt_mdct_forward_c(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out, const opus_val16 *window, int overlap, int shift, int stride, int arch) { int i; int N, N2, N4; VARDECL(kiss_fft_scalar, f); VARDECL(kiss_fft_cpx, f2); const kiss_fft_state *st = l->kfft[shift]; const kiss_twiddle_scalar *trig; opus_val16 scale; #ifdef FIXED_POINT /* Allows us to scale with MULT16_32_Q16(), which is faster than MULT16_32_Q15() on ARM. */ int scale_shift = st->scale_shift-1; #endif SAVE_STACK; (void)arch; scale = st->scale; N = l->n; trig = l->trig; for (i=0;i>= 1; trig += N; } N2 = N>>1; N4 = N>>2; ALLOC(f, N2, kiss_fft_scalar); ALLOC(f2, N4, kiss_fft_cpx); /* Consider the input to be composed of four blocks: [a, b, c, d] */ /* Window, shuffle, fold */ { /* Temp pointers to make it really clear to the compiler what we're doing */ const kiss_fft_scalar * OPUS_RESTRICT xp1 = in+(overlap>>1); const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+N2-1+(overlap>>1); kiss_fft_scalar * OPUS_RESTRICT yp = f; const opus_val16 * OPUS_RESTRICT wp1 = window+(overlap>>1); const opus_val16 * OPUS_RESTRICT wp2 = window+(overlap>>1)-1; for(i=0;i<((overlap+3)>>2);i++) { /* Real part arranged as -d-cR, Imag part arranged as -b+aR*/ *yp++ = MULT16_32_Q15(*wp2, xp1[N2]) + MULT16_32_Q15(*wp1,*xp2); *yp++ = MULT16_32_Q15(*wp1, *xp1) - MULT16_32_Q15(*wp2, xp2[-N2]); xp1+=2; xp2-=2; wp1+=2; wp2-=2; } wp1 = window; wp2 = window+overlap-1; for(;i>2);i++) { /* Real part arranged as a-bR, Imag part arranged as -c-dR */ *yp++ = *xp2; *yp++ = *xp1; xp1+=2; xp2-=2; } for(;ibitrev[i]] = yc; } } /* N/4 complex FFT, does not downscale anymore */ opus_fft_impl(st, f2); /* Post-rotate */ { /* Temp pointers to make it really clear to the compiler what we're doing */ const kiss_fft_cpx * OPUS_RESTRICT fp = f2; kiss_fft_scalar * OPUS_RESTRICT yp1 = out; kiss_fft_scalar * OPUS_RESTRICT yp2 = out+stride*(N2-1); const kiss_twiddle_scalar *t = &trig[0]; /* Temp pointers to make it really clear to the compiler what we're doing */ for(i=0;ii,t[N4+i]) - S_MUL(fp->r,t[i]); yi = S_MUL(fp->r,t[N4+i]) + S_MUL(fp->i,t[i]); *yp1 = yr; *yp2 = yi; fp++; yp1 += 2*stride; yp2 -= 2*stride; } } RESTORE_STACK; } #endif /* OVERRIDE_clt_mdct_forward */ #ifndef OVERRIDE_clt_mdct_backward void clt_mdct_backward_c(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out, const opus_val16 * OPUS_RESTRICT window, int overlap, int shift, int stride, int arch) { int i; int N, N2, N4; const kiss_twiddle_scalar *trig; (void) arch; N = l->n; trig = l->trig; for (i=0;i>= 1; trig += N; } N2 = N>>1; N4 = N>>2; /* Pre-rotate */ { /* Temp pointers to make it really clear to the compiler what we're doing */ const kiss_fft_scalar * OPUS_RESTRICT xp1 = in; const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+stride*(N2-1); kiss_fft_scalar * OPUS_RESTRICT yp = out+(overlap>>1); const kiss_twiddle_scalar * OPUS_RESTRICT t = &trig[0]; const opus_int16 * OPUS_RESTRICT bitrev = l->kfft[shift]->bitrev; for(i=0;ikfft[shift], (kiss_fft_cpx*)(out+(overlap>>1))); /* Post-rotate and de-shuffle from both ends of the buffer at once to make it in-place. */ { kiss_fft_scalar * yp0 = out+(overlap>>1); kiss_fft_scalar * yp1 = out+(overlap>>1)+N2-2; const kiss_twiddle_scalar *t = &trig[0]; /* Loop to (N4+1)>>1 to handle odd N4. When N4 is odd, the middle pair will be computed twice. */ for(i=0;i<(N4+1)>>1;i++) { kiss_fft_scalar re, im, yr, yi; kiss_twiddle_scalar t0, t1; /* We swap real and imag because we're using an FFT instead of an IFFT. */ re = yp0[1]; im = yp0[0]; t0 = t[i]; t1 = t[N4+i]; /* We'd scale up by 2 here, but instead it's done when mixing the windows */ yr = ADD32_ovflw(S_MUL(re,t0), S_MUL(im,t1)); yi = SUB32_ovflw(S_MUL(re,t1), S_MUL(im,t0)); /* We swap real and imag because we're using an FFT instead of an IFFT. */ re = yp1[1]; im = yp1[0]; yp0[0] = yr; yp1[1] = yi; t0 = t[(N4-i-1)]; t1 = t[(N2-i-1)]; /* We'd scale up by 2 here, but instead it's done when mixing the windows */ yr = ADD32_ovflw(S_MUL(re,t0), S_MUL(im,t1)); yi = SUB32_ovflw(S_MUL(re,t1), S_MUL(im,t0)); yp1[0] = yr; yp0[1] = yi; yp0 += 2; yp1 -= 2; } } /* Mirror on both sides for TDAC */ { kiss_fft_scalar * OPUS_RESTRICT xp1 = out+overlap-1; kiss_fft_scalar * OPUS_RESTRICT yp1 = out; const opus_val16 * OPUS_RESTRICT wp1 = window; const opus_val16 * OPUS_RESTRICT wp2 = window+overlap-1; for(i = 0; i < overlap/2; i++) { kiss_fft_scalar x1, x2; x1 = *xp1; x2 = *yp1; *yp1++ = SUB32_ovflw(MULT16_32_Q15(*wp2, x2), MULT16_32_Q15(*wp1, x1)); *xp1-- = ADD32_ovflw(MULT16_32_Q15(*wp1, x2), MULT16_32_Q15(*wp2, x1)); wp1++; wp2--; } } } #endif /* OVERRIDE_clt_mdct_backward */ jamulus-3.9.1+dfsg/libs/opus/celt/celt_decoder.c0000644000175000017500000012364214340334543020612 0ustar vimervimer/* Copyright (c) 2007-2008 CSIRO Copyright (c) 2007-2010 Xiph.Org Foundation Copyright (c) 2008 Gregory Maxwell Written by Jean-Marc Valin and Gregory Maxwell */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define CELT_DECODER_C #include "cpu_support.h" #include "os_support.h" #include "mdct.h" #include #include "celt.h" #include "pitch.h" #include "bands.h" #include "modes.h" #include "entcode.h" #include "quant_bands.h" #include "rate.h" #include "stack_alloc.h" #include "mathops.h" #include "float_cast.h" #include #include "celt_lpc.h" #include "vq.h" /* The maximum pitch lag to allow in the pitch-based PLC. It's possible to save CPU time in the PLC pitch search by making this smaller than MAX_PERIOD. The current value corresponds to a pitch of 66.67 Hz. */ #define PLC_PITCH_LAG_MAX (720) /* The minimum pitch lag to allow in the pitch-based PLC. This corresponds to a pitch of 480 Hz. */ #define PLC_PITCH_LAG_MIN (100) #if defined(SMALL_FOOTPRINT) && defined(FIXED_POINT) #define NORM_ALIASING_HACK #endif /**********************************************************************/ /* */ /* DECODER */ /* */ /**********************************************************************/ #define DECODE_BUFFER_SIZE 2048 /** Decoder state @brief Decoder state */ struct OpusCustomDecoder { const OpusCustomMode *mode; int overlap; int channels; int stream_channels; int downsample; int start, end; int signalling; int disable_inv; int arch; /* Everything beyond this point gets cleared on a reset */ #define DECODER_RESET_START rng opus_uint32 rng; int error; int last_pitch_index; int loss_count; int skip_plc; int postfilter_period; int postfilter_period_old; opus_val16 postfilter_gain; opus_val16 postfilter_gain_old; int postfilter_tapset; int postfilter_tapset_old; celt_sig preemph_memD[2]; celt_sig _decode_mem[1]; /* Size = channels*(DECODE_BUFFER_SIZE+mode->overlap) */ /* opus_val16 lpc[], Size = channels*LPC_ORDER */ /* opus_val16 oldEBands[], Size = 2*mode->nbEBands */ /* opus_val16 oldLogE[], Size = 2*mode->nbEBands */ /* opus_val16 oldLogE2[], Size = 2*mode->nbEBands */ /* opus_val16 backgroundLogE[], Size = 2*mode->nbEBands */ }; #if defined(ENABLE_HARDENING) || defined(ENABLE_ASSERTIONS) /* Make basic checks on the CELT state to ensure we don't end up writing all over memory. */ void validate_celt_decoder(CELTDecoder *st) { #ifndef CUSTOM_MODES celt_assert(st->mode == opus_custom_mode_create(48000, 960, NULL)); celt_assert(st->overlap == 120); celt_assert(st->end <= 21); #else /* From Section 4.3 in the spec: "The normal CELT layer uses 21 of those bands, though Opus Custom (see Section 6.2) may use a different number of bands" Check if it's within the maximum number of Bark frequency bands instead */ celt_assert(st->end <= 25); #endif celt_assert(st->channels == 1 || st->channels == 2); celt_assert(st->stream_channels == 1 || st->stream_channels == 2); celt_assert(st->downsample > 0); celt_assert(st->start == 0 || st->start == 17); celt_assert(st->start < st->end); #ifdef OPUS_ARCHMASK celt_assert(st->arch >= 0); celt_assert(st->arch <= OPUS_ARCHMASK); #endif celt_assert(st->last_pitch_index <= PLC_PITCH_LAG_MAX); celt_assert(st->last_pitch_index >= PLC_PITCH_LAG_MIN || st->last_pitch_index == 0); celt_assert(st->postfilter_period < MAX_PERIOD); celt_assert(st->postfilter_period >= COMBFILTER_MINPERIOD || st->postfilter_period == 0); celt_assert(st->postfilter_period_old < MAX_PERIOD); celt_assert(st->postfilter_period_old >= COMBFILTER_MINPERIOD || st->postfilter_period_old == 0); celt_assert(st->postfilter_tapset <= 2); celt_assert(st->postfilter_tapset >= 0); celt_assert(st->postfilter_tapset_old <= 2); celt_assert(st->postfilter_tapset_old >= 0); } #endif int celt_decoder_get_size(int channels) { const CELTMode *mode = opus_custom_mode_create(48000, 960, NULL); return opus_custom_decoder_get_size(mode, channels); } OPUS_CUSTOM_NOSTATIC int opus_custom_decoder_get_size(const CELTMode *mode, int channels) { int size = sizeof(struct CELTDecoder) + (channels*(DECODE_BUFFER_SIZE+mode->overlap)-1)*sizeof(celt_sig) + channels*LPC_ORDER*sizeof(opus_val16) + 4*2*mode->nbEBands*sizeof(opus_val16); return size; } #ifdef CUSTOM_MODES CELTDecoder *opus_custom_decoder_create(const CELTMode *mode, int channels, int *error) { int ret; CELTDecoder *st = (CELTDecoder *)opus_alloc(opus_custom_decoder_get_size(mode, channels)); ret = opus_custom_decoder_init(st, mode, channels); if (ret != OPUS_OK) { opus_custom_decoder_destroy(st); st = NULL; } if (error) *error = ret; return st; } #endif /* CUSTOM_MODES */ int celt_decoder_init(CELTDecoder *st, opus_int32 sampling_rate, int channels) { int ret; ret = opus_custom_decoder_init(st, opus_custom_mode_create(48000, 960, NULL), channels); if (ret != OPUS_OK) return ret; st->downsample = resampling_factor(sampling_rate); if (st->downsample==0) return OPUS_BAD_ARG; else return OPUS_OK; } OPUS_CUSTOM_NOSTATIC int opus_custom_decoder_init(CELTDecoder *st, const CELTMode *mode, int channels) { if (channels < 0 || channels > 2) return OPUS_BAD_ARG; if (st==NULL) return OPUS_ALLOC_FAIL; OPUS_CLEAR((char*)st, opus_custom_decoder_get_size(mode, channels)); st->mode = mode; st->overlap = mode->overlap; st->stream_channels = st->channels = channels; st->downsample = 1; st->start = 0; st->end = st->mode->effEBands; st->signalling = 1; #ifndef DISABLE_UPDATE_DRAFT st->disable_inv = channels == 1; #else st->disable_inv = 0; #endif st->arch = opus_select_arch(); opus_custom_decoder_ctl(st, OPUS_RESET_STATE); return OPUS_OK; } #ifdef CUSTOM_MODES void opus_custom_decoder_destroy(CELTDecoder *st) { opus_free(st); } #endif /* CUSTOM_MODES */ #ifndef CUSTOM_MODES /* Special case for stereo with no downsampling and no accumulation. This is quite common and we can make it faster by processing both channels in the same loop, reducing overhead due to the dependency loop in the IIR filter. */ static void deemphasis_stereo_simple(celt_sig *in[], opus_val16 *pcm, int N, const opus_val16 coef0, celt_sig *mem) { celt_sig * OPUS_RESTRICT x0; celt_sig * OPUS_RESTRICT x1; celt_sig m0, m1; int j; x0=in[0]; x1=in[1]; m0 = mem[0]; m1 = mem[1]; for (j=0;j1) { /* Shortcut for the standard (non-custom modes) case */ for (j=0;joverlap; nbEBands = mode->nbEBands; N = mode->shortMdctSize<shortMdctSize; shift = mode->maxLM; } else { B = 1; NB = mode->shortMdctSize<maxLM-LM; } if (CC==2&&C==1) { /* Copying a mono streams to two channels */ celt_sig *freq2; denormalise_bands(mode, X, freq, oldBandE, start, effEnd, M, downsample, silence); /* Store a temporary copy in the output buffer because the IMDCT destroys its input. */ freq2 = out_syn[1]+overlap/2; OPUS_COPY(freq2, freq, N); for (b=0;bmdct, &freq2[b], out_syn[0]+NB*b, mode->window, overlap, shift, B, arch); for (b=0;bmdct, &freq[b], out_syn[1]+NB*b, mode->window, overlap, shift, B, arch); } else if (CC==1&&C==2) { /* Downmixing a stereo stream to mono */ celt_sig *freq2; freq2 = out_syn[0]+overlap/2; denormalise_bands(mode, X, freq, oldBandE, start, effEnd, M, downsample, silence); /* Use the output buffer as temp array before downmixing. */ denormalise_bands(mode, X+N, freq2, oldBandE+nbEBands, start, effEnd, M, downsample, silence); for (i=0;imdct, &freq[b], out_syn[0]+NB*b, mode->window, overlap, shift, B, arch); } else { /* Normal case (mono or stereo) */ c=0; do { denormalise_bands(mode, X+c*N, freq, oldBandE+c*nbEBands, start, effEnd, M, downsample, silence); for (b=0;bmdct, &freq[b], out_syn[c]+NB*b, mode->window, overlap, shift, B, arch); } while (++cstorage*8; tell = ec_tell(dec); logp = isTransient ? 2 : 4; tf_select_rsv = LM>0 && tell+logp+1<=budget; budget -= tf_select_rsv; tf_changed = curr = 0; for (i=start;i>1, opus_val16 ); pitch_downsample(decode_mem, lp_pitch_buf, DECODE_BUFFER_SIZE, C, arch); pitch_search(lp_pitch_buf+(PLC_PITCH_LAG_MAX>>1), lp_pitch_buf, DECODE_BUFFER_SIZE-PLC_PITCH_LAG_MAX, PLC_PITCH_LAG_MAX-PLC_PITCH_LAG_MIN, &pitch_index, arch); pitch_index = PLC_PITCH_LAG_MAX-pitch_index; RESTORE_STACK; return pitch_index; } static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM) { int c; int i; const int C = st->channels; celt_sig *decode_mem[2]; celt_sig *out_syn[2]; opus_val16 *lpc; opus_val16 *oldBandE, *oldLogE, *oldLogE2, *backgroundLogE; const OpusCustomMode *mode; int nbEBands; int overlap; int start; int loss_count; int noise_based; const opus_int16 *eBands; SAVE_STACK; mode = st->mode; nbEBands = mode->nbEBands; overlap = mode->overlap; eBands = mode->eBands; c=0; do { decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+overlap); out_syn[c] = decode_mem[c]+DECODE_BUFFER_SIZE-N; } while (++c_decode_mem+(DECODE_BUFFER_SIZE+overlap)*C); oldBandE = lpc+C*LPC_ORDER; oldLogE = oldBandE + 2*nbEBands; oldLogE2 = oldLogE + 2*nbEBands; backgroundLogE = oldLogE2 + 2*nbEBands; loss_count = st->loss_count; start = st->start; noise_based = loss_count >= 5 || start != 0 || st->skip_plc; if (noise_based) { /* Noise-based PLC/CNG */ #ifdef NORM_ALIASING_HACK celt_norm *X; #else VARDECL(celt_norm, X); #endif opus_uint32 seed; int end; int effEnd; opus_val16 decay; end = st->end; effEnd = IMAX(start, IMIN(end, mode->effEBands)); #ifdef NORM_ALIASING_HACK /* This is an ugly hack that breaks aliasing rules and would be easily broken, but it saves almost 4kB of stack. */ X = (celt_norm*)(out_syn[C-1]+overlap/2); #else ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */ #endif /* Energy decay */ decay = loss_count==0 ? QCONST16(1.5f, DB_SHIFT) : QCONST16(.5f, DB_SHIFT); c=0; do { for (i=start;irng; for (c=0;c>20); } renormalise_vector(X+boffs, blen, Q15ONE, st->arch); } } st->rng = seed; c=0; do { OPUS_MOVE(decode_mem[c], decode_mem[c]+N, DECODE_BUFFER_SIZE-N+(overlap>>1)); } while (++cdownsample, 0, st->arch); } else { int exc_length; /* Pitch-based PLC */ const opus_val16 *window; opus_val16 *exc; opus_val16 fade = Q15ONE; int pitch_index; VARDECL(opus_val32, etmp); VARDECL(opus_val16, _exc); VARDECL(opus_val16, fir_tmp); if (loss_count == 0) { st->last_pitch_index = pitch_index = celt_plc_pitch_search(decode_mem, C, st->arch); } else { pitch_index = st->last_pitch_index; fade = QCONST16(.8f,15); } /* We want the excitation for 2 pitch periods in order to look for a decaying signal, but we can't get more than MAX_PERIOD. */ exc_length = IMIN(2*pitch_index, MAX_PERIOD); ALLOC(etmp, overlap, opus_val32); ALLOC(_exc, MAX_PERIOD+LPC_ORDER, opus_val16); ALLOC(fir_tmp, exc_length, opus_val16); exc = _exc+LPC_ORDER; window = mode->window; c=0; do { opus_val16 decay; opus_val16 attenuation; opus_val32 S1=0; celt_sig *buf; int extrapolation_offset; int extrapolation_len; int j; buf = decode_mem[c]; for (i=0;iarch); /* Add a noise floor of -40 dB. */ #ifdef FIXED_POINT ac[0] += SHR32(ac[0],13); #else ac[0] *= 1.0001f; #endif /* Use lag windowing to stabilize the Levinson-Durbin recursion. */ for (i=1;i<=LPC_ORDER;i++) { /*ac[i] *= exp(-.5*(2*M_PI*.002*i)*(2*M_PI*.002*i));*/ #ifdef FIXED_POINT ac[i] -= MULT16_32_Q15(2*i*i, ac[i]); #else ac[i] -= ac[i]*(0.008f*0.008f)*i*i; #endif } _celt_lpc(lpc+c*LPC_ORDER, ac, LPC_ORDER); #ifdef FIXED_POINT /* For fixed-point, apply bandwidth expansion until we can guarantee that no overflow can happen in the IIR filter. This means: 32768*sum(abs(filter)) < 2^31 */ while (1) { opus_val16 tmp=Q15ONE; opus_val32 sum=QCONST16(1., SIG_SHIFT); for (i=0;iarch); OPUS_COPY(exc+MAX_PERIOD-exc_length, fir_tmp, exc_length); } /* Check if the waveform is decaying, and if so how fast. We do this to avoid adding energy when concealing in a segment with decaying energy. */ { opus_val32 E1=1, E2=1; int decay_length; #ifdef FIXED_POINT int shift = IMAX(0,2*celt_zlog2(celt_maxabs16(&exc[MAX_PERIOD-exc_length], exc_length))-20); #endif decay_length = exc_length>>1; for (i=0;i= pitch_index) { j -= pitch_index; attenuation = MULT16_16_Q15(attenuation, decay); } buf[DECODE_BUFFER_SIZE-N+i] = SHL32(EXTEND32(MULT16_16_Q15(attenuation, exc[extrapolation_offset+j])), SIG_SHIFT); /* Compute the energy of the previously decoded signal whose excitation we're copying. */ tmp = ROUND16( buf[DECODE_BUFFER_SIZE-MAX_PERIOD-N+extrapolation_offset+j], SIG_SHIFT); S1 += SHR32(MULT16_16(tmp, tmp), 10); } { opus_val16 lpc_mem[LPC_ORDER]; /* Copy the last decoded samples (prior to the overlap region) to synthesis filter memory so we can have a continuous signal. */ for (i=0;iarch); #ifdef FIXED_POINT for (i=0; i < extrapolation_len; i++) buf[DECODE_BUFFER_SIZE-N+i] = SATURATE(buf[DECODE_BUFFER_SIZE-N+i], SIG_SAT); #endif } /* Check if the synthesis energy is higher than expected, which can happen with the signal changes during our window. If so, attenuate. */ { opus_val32 S2=0; for (i=0;i SHR32(S2,2))) #else /* The float test is written this way to catch NaNs in the output of the IIR filter at the same time. */ if (!(S1 > 0.2f*S2)) #endif { for (i=0;ipostfilter_period, st->postfilter_period, overlap, -st->postfilter_gain, -st->postfilter_gain, st->postfilter_tapset, st->postfilter_tapset, NULL, 0, st->arch); /* Simulate TDAC on the concealed audio so that it blends with the MDCT of the next frame. */ for (i=0;iloss_count = loss_count+1; RESTORE_STACK; } int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_val16 * OPUS_RESTRICT pcm, int frame_size, ec_dec *dec, int accum) { int c, i, N; int spread_decision; opus_int32 bits; ec_dec _dec; #ifdef NORM_ALIASING_HACK celt_norm *X; #else VARDECL(celt_norm, X); #endif VARDECL(int, fine_quant); VARDECL(int, pulses); VARDECL(int, cap); VARDECL(int, offsets); VARDECL(int, fine_priority); VARDECL(int, tf_res); VARDECL(unsigned char, collapse_masks); celt_sig *decode_mem[2]; celt_sig *out_syn[2]; opus_val16 *lpc; opus_val16 *oldBandE, *oldLogE, *oldLogE2, *backgroundLogE; int shortBlocks; int isTransient; int intra_ener; const int CC = st->channels; int LM, M; int start; int end; int effEnd; int codedBands; int alloc_trim; int postfilter_pitch; opus_val16 postfilter_gain; int intensity=0; int dual_stereo=0; opus_int32 total_bits; opus_int32 balance; opus_int32 tell; int dynalloc_logp; int postfilter_tapset; int anti_collapse_rsv; int anti_collapse_on=0; int silence; int C = st->stream_channels; const OpusCustomMode *mode; int nbEBands; int overlap; const opus_int16 *eBands; ALLOC_STACK; VALIDATE_CELT_DECODER(st); mode = st->mode; nbEBands = mode->nbEBands; overlap = mode->overlap; eBands = mode->eBands; start = st->start; end = st->end; frame_size *= st->downsample; lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+overlap)*CC); oldBandE = lpc+CC*LPC_ORDER; oldLogE = oldBandE + 2*nbEBands; oldLogE2 = oldLogE + 2*nbEBands; backgroundLogE = oldLogE2 + 2*nbEBands; #ifdef CUSTOM_MODES if (st->signalling && data!=NULL) { int data0=data[0]; /* Convert "standard mode" to Opus header */ if (mode->Fs==48000 && mode->shortMdctSize==120) { data0 = fromOpus(data0); if (data0<0) return OPUS_INVALID_PACKET; } st->end = end = IMAX(1, mode->effEBands-2*(data0>>5)); LM = (data0>>3)&0x3; C = 1 + ((data0>>2)&0x1); data++; len--; if (LM>mode->maxLM) return OPUS_INVALID_PACKET; if (frame_size < mode->shortMdctSize<shortMdctSize<maxLM;LM++) if (mode->shortMdctSize<mode->maxLM) return OPUS_BAD_ARG; } M=1<1275 || pcm==NULL) return OPUS_BAD_ARG; N = M*mode->shortMdctSize; c=0; do { decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+overlap); out_syn[c] = decode_mem[c]+DECODE_BUFFER_SIZE-N; } while (++c mode->effEBands) effEnd = mode->effEBands; if (data == NULL || len<=1) { celt_decode_lost(st, N, LM); deemphasis(out_syn, pcm, N, CC, st->downsample, mode->preemph, st->preemph_memD, accum); RESTORE_STACK; return frame_size/st->downsample; } /* Check if there are at least two packets received consecutively before * turning on the pitch-based PLC */ st->skip_plc = st->loss_count != 0; if (dec == NULL) { ec_dec_init(&_dec,(unsigned char*)data,len); dec = &_dec; } if (C==1) { for (i=0;i= total_bits) silence = 1; else if (tell==1) silence = ec_dec_bit_logp(dec, 15); else silence = 0; if (silence) { /* Pretend we've read all the remaining bits */ tell = len*8; dec->nbits_total+=tell-ec_tell(dec); } postfilter_gain = 0; postfilter_pitch = 0; postfilter_tapset = 0; if (start==0 && tell+16 <= total_bits) { if(ec_dec_bit_logp(dec, 1)) { int qg, octave; octave = ec_dec_uint(dec, 6); postfilter_pitch = (16< 0 && tell+3 <= total_bits) { isTransient = ec_dec_bit_logp(dec, 3); tell = ec_tell(dec); } else isTransient = 0; if (isTransient) shortBlocks = M; else shortBlocks = 0; /* Decode the global flags (first symbols in the stream) */ intra_ener = tell+3<=total_bits ? ec_dec_bit_logp(dec, 3) : 0; /* Get band energies */ unquant_coarse_energy(mode, start, end, oldBandE, intra_ener, dec, C, LM); ALLOC(tf_res, nbEBands, int); tf_decode(start, end, isTransient, tf_res, LM, dec); tell = ec_tell(dec); spread_decision = SPREAD_NORMAL; if (tell+4 <= total_bits) spread_decision = ec_dec_icdf(dec, spread_icdf, 5); ALLOC(cap, nbEBands, int); init_caps(mode,cap,LM,C); ALLOC(offsets, nbEBands, int); dynalloc_logp = 6; total_bits<<=BITRES; tell = ec_tell_frac(dec); for (i=start;i0) dynalloc_logp = IMAX(2, dynalloc_logp-1); } ALLOC(fine_quant, nbEBands, int); alloc_trim = tell+(6<=2&&bits>=((LM+2)<rng, 0, st->arch, st->disable_inv); if (anti_collapse_rsv > 0) { anti_collapse_on = ec_dec_bits(dec, 1); } unquant_energy_finalise(mode, start, end, oldBandE, fine_quant, fine_priority, len*8-ec_tell(dec), dec, C); if (anti_collapse_on) anti_collapse(mode, X, collapse_masks, LM, C, N, start, end, oldBandE, oldLogE, oldLogE2, pulses, st->rng, st->arch); if (silence) { for (i=0;idownsample, silence, st->arch); c=0; do { st->postfilter_period=IMAX(st->postfilter_period, COMBFILTER_MINPERIOD); st->postfilter_period_old=IMAX(st->postfilter_period_old, COMBFILTER_MINPERIOD); comb_filter(out_syn[c], out_syn[c], st->postfilter_period_old, st->postfilter_period, mode->shortMdctSize, st->postfilter_gain_old, st->postfilter_gain, st->postfilter_tapset_old, st->postfilter_tapset, mode->window, overlap, st->arch); if (LM!=0) comb_filter(out_syn[c]+mode->shortMdctSize, out_syn[c]+mode->shortMdctSize, st->postfilter_period, postfilter_pitch, N-mode->shortMdctSize, st->postfilter_gain, postfilter_gain, st->postfilter_tapset, postfilter_tapset, mode->window, overlap, st->arch); } while (++cpostfilter_period_old = st->postfilter_period; st->postfilter_gain_old = st->postfilter_gain; st->postfilter_tapset_old = st->postfilter_tapset; st->postfilter_period = postfilter_pitch; st->postfilter_gain = postfilter_gain; st->postfilter_tapset = postfilter_tapset; if (LM!=0) { st->postfilter_period_old = st->postfilter_period; st->postfilter_gain_old = st->postfilter_gain; st->postfilter_tapset_old = st->postfilter_tapset; } if (C==1) OPUS_COPY(&oldBandE[nbEBands], oldBandE, nbEBands); /* In case start or end were to change */ if (!isTransient) { opus_val16 max_background_increase; OPUS_COPY(oldLogE2, oldLogE, 2*nbEBands); OPUS_COPY(oldLogE, oldBandE, 2*nbEBands); /* In normal circumstances, we only allow the noise floor to increase by up to 2.4 dB/second, but when we're in DTX, we allow up to 6 dB increase for each update.*/ if (st->loss_count < 10) max_background_increase = M*QCONST16(0.001f,DB_SHIFT); else max_background_increase = QCONST16(1.f,DB_SHIFT); for (i=0;i<2*nbEBands;i++) backgroundLogE[i] = MIN16(backgroundLogE[i] + max_background_increase, oldBandE[i]); } else { for (i=0;i<2*nbEBands;i++) oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]); } c=0; do { for (i=0;irng = dec->rng; deemphasis(out_syn, pcm, N, CC, st->downsample, mode->preemph, st->preemph_memD, accum); st->loss_count = 0; RESTORE_STACK; if (ec_tell(dec) > 8*len) return OPUS_INTERNAL_ERROR; if(ec_get_error(dec)) st->error = 1; return frame_size/st->downsample; } #ifdef CUSTOM_MODES #ifdef FIXED_POINT int opus_custom_decode(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_int16 * OPUS_RESTRICT pcm, int frame_size) { return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL, 0); } #ifndef DISABLE_FLOAT_API int opus_custom_decode_float(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, float * OPUS_RESTRICT pcm, int frame_size) { int j, ret, C, N; VARDECL(opus_int16, out); ALLOC_STACK; if (pcm==NULL) return OPUS_BAD_ARG; C = st->channels; N = frame_size; ALLOC(out, C*N, opus_int16); ret=celt_decode_with_ec(st, data, len, out, frame_size, NULL, 0); if (ret>0) for (j=0;jchannels; N = frame_size; ALLOC(out, C*N, celt_sig); ret=celt_decode_with_ec(st, data, len, out, frame_size, NULL, 0); if (ret>0) for (j=0;j=st->mode->nbEBands) goto bad_arg; st->start = value; } break; case CELT_SET_END_BAND_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); if (value<1 || value>st->mode->nbEBands) goto bad_arg; st->end = value; } break; case CELT_SET_CHANNELS_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); if (value<1 || value>2) goto bad_arg; st->stream_channels = value; } break; case CELT_GET_AND_CLEAR_ERROR_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (value==NULL) goto bad_arg; *value=st->error; st->error = 0; } break; case OPUS_GET_LOOKAHEAD_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (value==NULL) goto bad_arg; *value = st->overlap/st->downsample; } break; case OPUS_RESET_STATE: { int i; opus_val16 *lpc, *oldBandE, *oldLogE, *oldLogE2; lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*st->channels); oldBandE = lpc+st->channels*LPC_ORDER; oldLogE = oldBandE + 2*st->mode->nbEBands; oldLogE2 = oldLogE + 2*st->mode->nbEBands; OPUS_CLEAR((char*)&st->DECODER_RESET_START, opus_custom_decoder_get_size(st->mode, st->channels)- ((char*)&st->DECODER_RESET_START - (char*)st)); for (i=0;i<2*st->mode->nbEBands;i++) oldLogE[i]=oldLogE2[i]=-QCONST16(28.f,DB_SHIFT); st->skip_plc = 1; } break; case OPUS_GET_PITCH_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (value==NULL) goto bad_arg; *value = st->postfilter_period; } break; case CELT_GET_MODE_REQUEST: { const CELTMode ** value = va_arg(ap, const CELTMode**); if (value==0) goto bad_arg; *value=st->mode; } break; case CELT_SET_SIGNALLING_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); st->signalling = value; } break; case OPUS_GET_FINAL_RANGE_REQUEST: { opus_uint32 * value = va_arg(ap, opus_uint32 *); if (value==0) goto bad_arg; *value=st->rng; } break; case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); if(value<0 || value>1) { goto bad_arg; } st->disable_inv = value; } break; case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } *value = st->disable_inv; } break; default: goto bad_request; } va_end(ap); return OPUS_OK; bad_arg: va_end(ap); return OPUS_BAD_ARG; bad_request: va_end(ap); return OPUS_UNIMPLEMENTED; } jamulus-3.9.1+dfsg/libs/opus/celt/quant_bands.h0000644000175000017500000000563614340334543020504 0ustar vimervimer/* Copyright (c) 2007-2008 CSIRO Copyright (c) 2007-2009 Xiph.Org Foundation Written by Jean-Marc Valin */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef QUANT_BANDS #define QUANT_BANDS #include "arch.h" #include "modes.h" #include "entenc.h" #include "entdec.h" #include "mathops.h" #ifdef FIXED_POINT extern const signed char eMeans[25]; #else extern const opus_val16 eMeans[25]; #endif void amp2Log2(const CELTMode *m, int effEnd, int end, celt_ener *bandE, opus_val16 *bandLogE, int C); void log2Amp(const CELTMode *m, int start, int end, celt_ener *eBands, const opus_val16 *oldEBands, int C); void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd, const opus_val16 *eBands, opus_val16 *oldEBands, opus_uint32 budget, opus_val16 *error, ec_enc *enc, int C, int LM, int nbAvailableBytes, int force_intra, opus_val32 *delayedIntra, int two_pass, int loss_rate, int lfe); void quant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, opus_val16 *error, int *fine_quant, ec_enc *enc, int C); void quant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *oldEBands, opus_val16 *error, int *fine_quant, int *fine_priority, int bits_left, ec_enc *enc, int C); void unquant_coarse_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int intra, ec_dec *dec, int C, int LM); void unquant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int *fine_quant, ec_dec *dec, int C); void unquant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int *fine_quant, int *fine_priority, int bits_left, ec_dec *dec, int C); #endif /* QUANT_BANDS */ jamulus-3.9.1+dfsg/libs/opus/celt/celt_lpc.c0000644000175000017500000001752314340334543017763 0ustar vimervimer/* Copyright (c) 2009-2010 Xiph.Org Foundation Written by Jean-Marc Valin */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "celt_lpc.h" #include "stack_alloc.h" #include "mathops.h" #include "pitch.h" void _celt_lpc( opus_val16 *_lpc, /* out: [0...p-1] LPC coefficients */ const opus_val32 *ac, /* in: [0...p] autocorrelation values */ int p ) { int i, j; opus_val32 r; opus_val32 error = ac[0]; #ifdef FIXED_POINT opus_val32 lpc[LPC_ORDER]; #else float *lpc = _lpc; #endif OPUS_CLEAR(lpc, p); if (ac[0] != 0) { for (i = 0; i < p; i++) { /* Sum up this iteration's reflection coefficient */ opus_val32 rr = 0; for (j = 0; j < i; j++) rr += MULT32_32_Q31(lpc[j],ac[i - j]); rr += SHR32(ac[i + 1],3); r = -frac_div32(SHL32(rr,3), error); /* Update LPC coefficients and total error */ lpc[i] = SHR32(r,3); for (j = 0; j < (i+1)>>1; j++) { opus_val32 tmp1, tmp2; tmp1 = lpc[j]; tmp2 = lpc[i-1-j]; lpc[j] = tmp1 + MULT32_32_Q31(r,tmp2); lpc[i-1-j] = tmp2 + MULT32_32_Q31(r,tmp1); } error = error - MULT32_32_Q31(MULT32_32_Q31(r,r),error); /* Bail out once we get 30 dB gain */ #ifdef FIXED_POINT if (error=1;j--) { mem[j]=mem[j-1]; } mem[0] = SROUND16(sum, SIG_SHIFT); _y[i] = sum; } #else int i,j; VARDECL(opus_val16, rden); VARDECL(opus_val16, y); SAVE_STACK; celt_assert((ord&3)==0); ALLOC(rden, ord, opus_val16); ALLOC(y, N+ord, opus_val16); for(i=0;i0); celt_assert(overlap>=0); if (overlap == 0) { xptr = x; } else { for (i=0;i0) { for(i=0;i= 536870912) { int shift2=1; if (ac[0] >= 1073741824) shift2++; for (i=0;i<=lag;i++) ac[i] = SHR32(ac[i], shift2); shift += shift2; } #endif RESTORE_STACK; return shift; } jamulus-3.9.1+dfsg/libs/opus/celt/modes.c0000644000175000017500000003317714340334543017310 0ustar vimervimer/* Copyright (c) 2007-2008 CSIRO Copyright (c) 2007-2009 Xiph.Org Foundation Copyright (c) 2008 Gregory Maxwell Written by Jean-Marc Valin and Gregory Maxwell */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "celt.h" #include "modes.h" #include "rate.h" #include "os_support.h" #include "stack_alloc.h" #include "quant_bands.h" #include "cpu_support.h" static const opus_int16 eband5ms[] = { /*0 200 400 600 800 1k 1.2 1.4 1.6 2k 2.4 2.8 3.2 4k 4.8 5.6 6.8 8k 9.6 12k 15.6 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 34, 40, 48, 60, 78, 100 }; /* Alternate tuning (partially derived from Vorbis) */ #define BITALLOC_SIZE 11 /* Bit allocation table in units of 1/32 bit/sample (0.1875 dB SNR) */ static const unsigned char band_allocation[] = { /*0 200 400 600 800 1k 1.2 1.4 1.6 2k 2.4 2.8 3.2 4k 4.8 5.6 6.8 8k 9.6 12k 15.6 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 80, 75, 69, 63, 56, 49, 40, 34, 29, 20, 18, 10, 0, 0, 0, 0, 0, 0, 0, 0, 110,100, 90, 84, 78, 71, 65, 58, 51, 45, 39, 32, 26, 20, 12, 0, 0, 0, 0, 0, 0, 118,110,103, 93, 86, 80, 75, 70, 65, 59, 53, 47, 40, 31, 23, 15, 4, 0, 0, 0, 0, 126,119,112,104, 95, 89, 83, 78, 72, 66, 60, 54, 47, 39, 32, 25, 17, 12, 1, 0, 0, 134,127,120,114,103, 97, 91, 85, 78, 72, 66, 60, 54, 47, 41, 35, 29, 23, 16, 10, 1, 144,137,130,124,113,107,101, 95, 88, 82, 76, 70, 64, 57, 51, 45, 39, 33, 26, 15, 1, 152,145,138,132,123,117,111,105, 98, 92, 86, 80, 74, 67, 61, 55, 49, 43, 36, 20, 1, 162,155,148,142,133,127,121,115,108,102, 96, 90, 84, 77, 71, 65, 59, 53, 46, 30, 1, 172,165,158,152,143,137,131,125,118,112,106,100, 94, 87, 81, 75, 69, 63, 56, 45, 20, 200,200,200,200,200,200,200,200,198,193,188,183,178,173,168,163,158,153,148,129,104, }; #ifndef CUSTOM_MODES_ONLY #ifdef FIXED_POINT #include "static_modes_fixed.h" #else #include "static_modes_float.h" #endif #endif /* CUSTOM_MODES_ONLY */ #ifndef M_PI #define M_PI 3.141592653 #endif #ifdef CUSTOM_MODES /* Defining 25 critical bands for the full 0-20 kHz audio bandwidth Taken from http://ccrma.stanford.edu/~jos/bbt/Bark_Frequency_Scale.html */ #define BARK_BANDS 25 static const opus_int16 bark_freq[BARK_BANDS+1] = { 0, 100, 200, 300, 400, 510, 630, 770, 920, 1080, 1270, 1480, 1720, 2000, 2320, 2700, 3150, 3700, 4400, 5300, 6400, 7700, 9500, 12000, 15500, 20000}; static opus_int16 *compute_ebands(opus_int32 Fs, int frame_size, int res, int *nbEBands) { opus_int16 *eBands; int i, j, lin, low, high, nBark, offset=0; /* All modes that have 2.5 ms short blocks use the same definition */ if (Fs == 400*(opus_int32)frame_size) { *nbEBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1; eBands = opus_alloc(sizeof(opus_int16)*(*nbEBands+1)); for (i=0;i<*nbEBands+1;i++) eBands[i] = eband5ms[i]; return eBands; } /* Find the number of critical bands supported by our sampling rate */ for (nBark=1;nBark= Fs) break; /* Find where the linear part ends (i.e. where the spacing is more than min_width */ for (lin=0;lin= res) break; low = (bark_freq[lin]+res/2)/res; high = nBark-lin; *nbEBands = low+high; eBands = opus_alloc(sizeof(opus_int16)*(*nbEBands+2)); if (eBands==NULL) return NULL; /* Linear spacing (min_width) */ for (i=0;i0) offset = eBands[low-1]*res - bark_freq[lin-1]; /* Spacing follows critical bands */ for (i=0;i frame_size) eBands[*nbEBands] = frame_size; for (i=1;i<*nbEBands-1;i++) { if (eBands[i+1]-eBands[i] < eBands[i]-eBands[i-1]) { eBands[i] -= (2*eBands[i]-eBands[i-1]-eBands[i+1])/2; } } /* Remove any empty bands. */ for (i=j=0;i<*nbEBands;i++) if(eBands[i+1]>eBands[j]) eBands[++j]=eBands[i+1]; *nbEBands=j; for (i=1;i<*nbEBands;i++) { /* Every band must be smaller than the last band. */ celt_assert(eBands[i]-eBands[i-1]<=eBands[*nbEBands]-eBands[*nbEBands-1]); /* Each band must be no larger than twice the size of the previous one. */ celt_assert(eBands[i+1]-eBands[i]<=2*(eBands[i]-eBands[i-1])); } return eBands; } static void compute_allocation_table(CELTMode *mode) { int i, j; unsigned char *allocVectors; int maxBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1; mode->nbAllocVectors = BITALLOC_SIZE; allocVectors = opus_alloc(sizeof(unsigned char)*(BITALLOC_SIZE*mode->nbEBands)); if (allocVectors==NULL) return; /* Check for standard mode */ if (mode->Fs == 400*(opus_int32)mode->shortMdctSize) { for (i=0;inbEBands;i++) allocVectors[i] = band_allocation[i]; mode->allocVectors = allocVectors; return; } /* If not the standard mode, interpolate */ /* Compute per-codec-band allocation from per-critical-band matrix */ for (i=0;inbEBands;j++) { int k; for (k=0;k mode->eBands[j]*(opus_int32)mode->Fs/mode->shortMdctSize) break; } if (k>maxBands-1) allocVectors[i*mode->nbEBands+j] = band_allocation[i*maxBands + maxBands-1]; else { opus_int32 a0, a1; a1 = mode->eBands[j]*(opus_int32)mode->Fs/mode->shortMdctSize - 400*(opus_int32)eband5ms[k-1]; a0 = 400*(opus_int32)eband5ms[k] - mode->eBands[j]*(opus_int32)mode->Fs/mode->shortMdctSize; allocVectors[i*mode->nbEBands+j] = (a0*band_allocation[i*maxBands+k-1] + a1*band_allocation[i*maxBands+k])/(a0+a1); } } } /*printf ("\n"); for (i=0;inbEBands;j++) printf ("%d ", allocVectors[i*mode->nbEBands+j]); printf ("\n"); } exit(0);*/ mode->allocVectors = allocVectors; } #endif /* CUSTOM_MODES */ CELTMode *opus_custom_mode_create(opus_int32 Fs, int frame_size, int *error) { int i; #ifdef CUSTOM_MODES CELTMode *mode=NULL; int res; opus_val16 *window; opus_int16 *logN; int LM; int arch = opus_select_arch(); ALLOC_STACK; #if !defined(VAR_ARRAYS) && !defined(USE_ALLOCA) if (global_stack==NULL) goto failure; #endif #endif #ifndef CUSTOM_MODES_ONLY for (i=0;iFs && (frame_size<shortMdctSize*static_mode_list[i]->nbShortMdcts) { if (error) *error = OPUS_OK; return (CELTMode*)static_mode_list[i]; } } } #endif /* CUSTOM_MODES_ONLY */ #ifndef CUSTOM_MODES if (error) *error = OPUS_BAD_ARG; return NULL; #else /* The good thing here is that permutation of the arguments will automatically be invalid */ if (Fs < 8000 || Fs > 96000) { if (error) *error = OPUS_BAD_ARG; return NULL; } if (frame_size < 40 || frame_size > 1024 || frame_size%2!=0) { if (error) *error = OPUS_BAD_ARG; return NULL; } /* Frames of less than 1ms are not supported. */ if ((opus_int32)frame_size*1000 < Fs) { if (error) *error = OPUS_BAD_ARG; return NULL; } if ((opus_int32)frame_size*75 >= Fs && (frame_size%16)==0) { LM = 3; } else if ((opus_int32)frame_size*150 >= Fs && (frame_size%8)==0) { LM = 2; } else if ((opus_int32)frame_size*300 >= Fs && (frame_size%4)==0) { LM = 1; } else { LM = 0; } /* Shorts longer than 3.3ms are not supported. */ if ((opus_int32)(frame_size>>LM)*300 > Fs) { if (error) *error = OPUS_BAD_ARG; return NULL; } mode = opus_alloc(sizeof(CELTMode)); if (mode==NULL) goto failure; mode->Fs = Fs; /* Pre/de-emphasis depends on sampling rate. The "standard" pre-emphasis is defined as A(z) = 1 - 0.85*z^-1 at 48 kHz. Other rates should approximate that. */ if(Fs < 12000) /* 8 kHz */ { mode->preemph[0] = QCONST16(0.3500061035f, 15); mode->preemph[1] = -QCONST16(0.1799926758f, 15); mode->preemph[2] = QCONST16(0.2719968125f, SIG_SHIFT); /* exact 1/preemph[3] */ mode->preemph[3] = QCONST16(3.6765136719f, 13); } else if(Fs < 24000) /* 16 kHz */ { mode->preemph[0] = QCONST16(0.6000061035f, 15); mode->preemph[1] = -QCONST16(0.1799926758f, 15); mode->preemph[2] = QCONST16(0.4424998650f, SIG_SHIFT); /* exact 1/preemph[3] */ mode->preemph[3] = QCONST16(2.2598876953f, 13); } else if(Fs < 40000) /* 32 kHz */ { mode->preemph[0] = QCONST16(0.7799987793f, 15); mode->preemph[1] = -QCONST16(0.1000061035f, 15); mode->preemph[2] = QCONST16(0.7499771125f, SIG_SHIFT); /* exact 1/preemph[3] */ mode->preemph[3] = QCONST16(1.3333740234f, 13); } else /* 48 kHz */ { mode->preemph[0] = QCONST16(0.8500061035f, 15); mode->preemph[1] = QCONST16(0.0f, 15); mode->preemph[2] = QCONST16(1.f, SIG_SHIFT); mode->preemph[3] = QCONST16(1.f, 13); } mode->maxLM = LM; mode->nbShortMdcts = 1<shortMdctSize = frame_size/mode->nbShortMdcts; res = (mode->Fs+mode->shortMdctSize)/(2*mode->shortMdctSize); mode->eBands = compute_ebands(Fs, mode->shortMdctSize, res, &mode->nbEBands); if (mode->eBands==NULL) goto failure; #if !defined(SMALL_FOOTPRINT) /* Make sure we don't allocate a band larger than our PVQ table. 208 should be enough, but let's be paranoid. */ if ((mode->eBands[mode->nbEBands] - mode->eBands[mode->nbEBands-1])< 208) { goto failure; } #endif mode->effEBands = mode->nbEBands; while (mode->eBands[mode->effEBands] > mode->shortMdctSize) mode->effEBands--; /* Overlap must be divisible by 4 */ mode->overlap = ((mode->shortMdctSize>>2)<<2); compute_allocation_table(mode); if (mode->allocVectors==NULL) goto failure; window = (opus_val16*)opus_alloc(mode->overlap*sizeof(opus_val16)); if (window==NULL) goto failure; #ifndef FIXED_POINT for (i=0;ioverlap;i++) window[i] = Q15ONE*sin(.5*M_PI* sin(.5*M_PI*(i+.5)/mode->overlap) * sin(.5*M_PI*(i+.5)/mode->overlap)); #else for (i=0;ioverlap;i++) window[i] = MIN32(32767,floor(.5+32768.*sin(.5*M_PI* sin(.5*M_PI*(i+.5)/mode->overlap) * sin(.5*M_PI*(i+.5)/mode->overlap)))); #endif mode->window = window; logN = (opus_int16*)opus_alloc(mode->nbEBands*sizeof(opus_int16)); if (logN==NULL) goto failure; for (i=0;inbEBands;i++) logN[i] = log2_frac(mode->eBands[i+1]-mode->eBands[i], BITRES); mode->logN = logN; compute_pulse_cache(mode, mode->maxLM); if (clt_mdct_init(&mode->mdct, 2*mode->shortMdctSize*mode->nbShortMdcts, mode->maxLM, arch) == 0) goto failure; if (error) *error = OPUS_OK; return mode; failure: if (error) *error = OPUS_ALLOC_FAIL; if (mode!=NULL) opus_custom_mode_destroy(mode); return NULL; #endif /* !CUSTOM_MODES */ } #ifdef CUSTOM_MODES void opus_custom_mode_destroy(CELTMode *mode) { int arch = opus_select_arch(); if (mode == NULL) return; #ifndef CUSTOM_MODES_ONLY { int i; for (i=0;ieBands); opus_free((unsigned char*)mode->allocVectors); opus_free((opus_val16*)mode->window); opus_free((opus_int16*)mode->logN); opus_free((opus_int16*)mode->cache.index); opus_free((unsigned char*)mode->cache.bits); opus_free((unsigned char*)mode->cache.caps); clt_mdct_clear(&mode->mdct, arch); opus_free((CELTMode *)mode); } #endif jamulus-3.9.1+dfsg/libs/opus/celt/entdec.h0000644000175000017500000001134114340334543017435 0ustar vimervimer/* Copyright (c) 2001-2011 Timothy B. Terriberry Copyright (c) 2008-2009 Xiph.Org Foundation */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(_entdec_H) # define _entdec_H (1) # include # include "entcode.h" /*Initializes the decoder. _buf: The input buffer to use. Return: 0 on success, or a negative value on error.*/ void ec_dec_init(ec_dec *_this,unsigned char *_buf,opus_uint32 _storage); /*Calculates the cumulative frequency for the next symbol. This can then be fed into the probability model to determine what that symbol is, and the additional frequency information required to advance to the next symbol. This function cannot be called more than once without a corresponding call to ec_dec_update(), or decoding will not proceed correctly. _ft: The total frequency of the symbols in the alphabet the next symbol was encoded with. Return: A cumulative frequency representing the encoded symbol. If the cumulative frequency of all the symbols before the one that was encoded was fl, and the cumulative frequency of all the symbols up to and including the one encoded is fh, then the returned value will fall in the range [fl,fh).*/ unsigned ec_decode(ec_dec *_this,unsigned _ft); /*Equivalent to ec_decode() with _ft==1<<_bits.*/ unsigned ec_decode_bin(ec_dec *_this,unsigned _bits); /*Advance the decoder past the next symbol using the frequency information the symbol was encoded with. Exactly one call to ec_decode() must have been made so that all necessary intermediate calculations are performed. _fl: The cumulative frequency of all symbols that come before the symbol decoded. _fh: The cumulative frequency of all symbols up to and including the symbol decoded. Together with _fl, this defines the range [_fl,_fh) in which the value returned above must fall. _ft: The total frequency of the symbols in the alphabet the symbol decoded was encoded in. This must be the same as passed to the preceding call to ec_decode().*/ void ec_dec_update(ec_dec *_this,unsigned _fl,unsigned _fh,unsigned _ft); /* Decode a bit that has a 1/(1<<_logp) probability of being a one */ int ec_dec_bit_logp(ec_dec *_this,unsigned _logp); /*Decodes a symbol given an "inverse" CDF table. No call to ec_dec_update() is necessary after this call. _icdf: The "inverse" CDF, such that symbol s falls in the range [s>0?ft-_icdf[s-1]:0,ft-_icdf[s]), where ft=1<<_ftb. The values must be monotonically non-increasing, and the last value must be 0. _ftb: The number of bits of precision in the cumulative distribution. Return: The decoded symbol s.*/ int ec_dec_icdf(ec_dec *_this,const unsigned char *_icdf,unsigned _ftb); /*Extracts a raw unsigned integer with a non-power-of-2 range from the stream. The bits must have been encoded with ec_enc_uint(). No call to ec_dec_update() is necessary after this call. _ft: The number of integers that can be decoded (one more than the max). This must be at least 2, and no more than 2**32-1. Return: The decoded bits.*/ opus_uint32 ec_dec_uint(ec_dec *_this,opus_uint32 _ft); /*Extracts a sequence of raw bits from the stream. The bits must have been encoded with ec_enc_bits(). No call to ec_dec_update() is necessary after this call. _ftb: The number of bits to extract. This must be between 0 and 25, inclusive. Return: The decoded bits.*/ opus_uint32 ec_dec_bits(ec_dec *_this,unsigned _ftb); #endif jamulus-3.9.1+dfsg/libs/opus/celt/static_modes_fixed.h0000644000175000017500000010006314340334543022030 0ustar vimervimer/* The contents of this file was automatically generated by dump_modes.c with arguments: 48000 960 It contains static definitions for some pre-defined modes. */ #include "modes.h" #include "rate.h" #ifdef HAVE_ARM_NE10 #define OVERRIDE_FFT 1 #include "static_modes_fixed_arm_ne10.h" #endif #ifndef DEF_WINDOW120 #define DEF_WINDOW120 static const opus_val16 window120[120] = { 2, 20, 55, 108, 178, 266, 372, 494, 635, 792, 966, 1157, 1365, 1590, 1831, 2089, 2362, 2651, 2956, 3276, 3611, 3961, 4325, 4703, 5094, 5499, 5916, 6346, 6788, 7241, 7705, 8179, 8663, 9156, 9657, 10167, 10684, 11207, 11736, 12271, 12810, 13353, 13899, 14447, 14997, 15547, 16098, 16648, 17197, 17744, 18287, 18827, 19363, 19893, 20418, 20936, 21447, 21950, 22445, 22931, 23407, 23874, 24330, 24774, 25208, 25629, 26039, 26435, 26819, 27190, 27548, 27893, 28224, 28541, 28845, 29135, 29411, 29674, 29924, 30160, 30384, 30594, 30792, 30977, 31151, 31313, 31463, 31602, 31731, 31849, 31958, 32057, 32148, 32229, 32303, 32370, 32429, 32481, 32528, 32568, 32604, 32634, 32661, 32683, 32701, 32717, 32729, 32740, 32748, 32754, 32758, 32762, 32764, 32766, 32767, 32767, 32767, 32767, 32767, 32767, }; #endif #ifndef DEF_LOGN400 #define DEF_LOGN400 static const opus_int16 logN400[21] = { 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 16, 16, 16, 21, 21, 24, 29, 34, 36, }; #endif #ifndef DEF_PULSE_CACHE50 #define DEF_PULSE_CACHE50 static const opus_int16 cache_index50[105] = { -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 41, 41, 41, 82, 82, 123, 164, 200, 222, 0, 0, 0, 0, 0, 0, 0, 0, 41, 41, 41, 41, 123, 123, 123, 164, 164, 240, 266, 283, 295, 41, 41, 41, 41, 41, 41, 41, 41, 123, 123, 123, 123, 240, 240, 240, 266, 266, 305, 318, 328, 336, 123, 123, 123, 123, 123, 123, 123, 123, 240, 240, 240, 240, 305, 305, 305, 318, 318, 343, 351, 358, 364, 240, 240, 240, 240, 240, 240, 240, 240, 305, 305, 305, 305, 343, 343, 343, 351, 351, 370, 376, 382, 387, }; static const unsigned char cache_bits50[392] = { 40, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 40, 15, 23, 28, 31, 34, 36, 38, 39, 41, 42, 43, 44, 45, 46, 47, 47, 49, 50, 51, 52, 53, 54, 55, 55, 57, 58, 59, 60, 61, 62, 63, 63, 65, 66, 67, 68, 69, 70, 71, 71, 40, 20, 33, 41, 48, 53, 57, 61, 64, 66, 69, 71, 73, 75, 76, 78, 80, 82, 85, 87, 89, 91, 92, 94, 96, 98, 101, 103, 105, 107, 108, 110, 112, 114, 117, 119, 121, 123, 124, 126, 128, 40, 23, 39, 51, 60, 67, 73, 79, 83, 87, 91, 94, 97, 100, 102, 105, 107, 111, 115, 118, 121, 124, 126, 129, 131, 135, 139, 142, 145, 148, 150, 153, 155, 159, 163, 166, 169, 172, 174, 177, 179, 35, 28, 49, 65, 78, 89, 99, 107, 114, 120, 126, 132, 136, 141, 145, 149, 153, 159, 165, 171, 176, 180, 185, 189, 192, 199, 205, 211, 216, 220, 225, 229, 232, 239, 245, 251, 21, 33, 58, 79, 97, 112, 125, 137, 148, 157, 166, 174, 182, 189, 195, 201, 207, 217, 227, 235, 243, 251, 17, 35, 63, 86, 106, 123, 139, 152, 165, 177, 187, 197, 206, 214, 222, 230, 237, 250, 25, 31, 55, 75, 91, 105, 117, 128, 138, 146, 154, 161, 168, 174, 180, 185, 190, 200, 208, 215, 222, 229, 235, 240, 245, 255, 16, 36, 65, 89, 110, 128, 144, 159, 173, 185, 196, 207, 217, 226, 234, 242, 250, 11, 41, 74, 103, 128, 151, 172, 191, 209, 225, 241, 255, 9, 43, 79, 110, 138, 163, 186, 207, 227, 246, 12, 39, 71, 99, 123, 144, 164, 182, 198, 214, 228, 241, 253, 9, 44, 81, 113, 142, 168, 192, 214, 235, 255, 7, 49, 90, 127, 160, 191, 220, 247, 6, 51, 95, 134, 170, 203, 234, 7, 47, 87, 123, 155, 184, 212, 237, 6, 52, 97, 137, 174, 208, 240, 5, 57, 106, 151, 192, 231, 5, 59, 111, 158, 202, 243, 5, 55, 103, 147, 187, 224, 5, 60, 113, 161, 206, 248, 4, 65, 122, 175, 224, 4, 67, 127, 182, 234, }; static const unsigned char cache_caps50[168] = { 224, 224, 224, 224, 224, 224, 224, 224, 160, 160, 160, 160, 185, 185, 185, 178, 178, 168, 134, 61, 37, 224, 224, 224, 224, 224, 224, 224, 224, 240, 240, 240, 240, 207, 207, 207, 198, 198, 183, 144, 66, 40, 160, 160, 160, 160, 160, 160, 160, 160, 185, 185, 185, 185, 193, 193, 193, 183, 183, 172, 138, 64, 38, 240, 240, 240, 240, 240, 240, 240, 240, 207, 207, 207, 207, 204, 204, 204, 193, 193, 180, 143, 66, 40, 185, 185, 185, 185, 185, 185, 185, 185, 193, 193, 193, 193, 193, 193, 193, 183, 183, 172, 138, 65, 39, 207, 207, 207, 207, 207, 207, 207, 207, 204, 204, 204, 204, 201, 201, 201, 188, 188, 176, 141, 66, 40, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 194, 194, 194, 184, 184, 173, 139, 65, 39, 204, 204, 204, 204, 204, 204, 204, 204, 201, 201, 201, 201, 198, 198, 198, 187, 187, 175, 140, 66, 40, }; #endif #ifndef FFT_TWIDDLES48000_960 #define FFT_TWIDDLES48000_960 static const kiss_twiddle_cpx fft_twiddles48000_960[480] = { {32767, 0}, {32766, -429}, {32757, -858}, {32743, -1287}, {32724, -1715}, {32698, -2143}, {32667, -2570}, {32631, -2998}, {32588, -3425}, {32541, -3851}, {32488, -4277}, {32429, -4701}, {32364, -5125}, {32295, -5548}, {32219, -5971}, {32138, -6393}, {32051, -6813}, {31960, -7231}, {31863, -7650}, {31760, -8067}, {31652, -8481}, {31539, -8895}, {31419, -9306}, {31294, -9716}, {31165, -10126}, {31030, -10532}, {30889, -10937}, {30743, -11340}, {30592, -11741}, {30436, -12141}, {30274, -12540}, {30107, -12935}, {29936, -13328}, {29758, -13718}, {29577, -14107}, {29390, -14493}, {29197, -14875}, {29000, -15257}, {28797, -15635}, {28590, -16010}, {28379, -16384}, {28162, -16753}, {27940, -17119}, {27714, -17484}, {27482, -17845}, {27246, -18205}, {27006, -18560}, {26760, -18911}, {26510, -19260}, {26257, -19606}, {25997, -19947}, {25734, -20286}, {25466, -20621}, {25194, -20952}, {24918, -21281}, {24637, -21605}, {24353, -21926}, {24063, -22242}, {23770, -22555}, {23473, -22865}, {23171, -23171}, {22866, -23472}, {22557, -23769}, {22244, -24063}, {21927, -24352}, {21606, -24636}, {21282, -24917}, {20954, -25194}, {20622, -25465}, {20288, -25733}, {19949, -25997}, {19607, -26255}, {19261, -26509}, {18914, -26760}, {18561, -27004}, {18205, -27246}, {17846, -27481}, {17485, -27713}, {17122, -27940}, {16755, -28162}, {16385, -28378}, {16012, -28590}, {15636, -28797}, {15258, -28999}, {14878, -29197}, {14494, -29389}, {14108, -29576}, {13720, -29757}, {13329, -29934}, {12937, -30107}, {12540, -30274}, {12142, -30435}, {11744, -30592}, {11342, -30743}, {10939, -30889}, {10534, -31030}, {10127, -31164}, {9718, -31294}, {9307, -31418}, {8895, -31537}, {8482, -31652}, {8067, -31759}, {7650, -31862}, {7233, -31960}, {6815, -32051}, {6393, -32138}, {5973, -32219}, {5549, -32294}, {5127, -32364}, {4703, -32429}, {4278, -32487}, {3852, -32541}, {3426, -32588}, {2999, -32630}, {2572, -32667}, {2144, -32698}, {1716, -32724}, {1287, -32742}, {860, -32757}, {430, -32766}, {0, -32767}, {-429, -32766}, {-858, -32757}, {-1287, -32743}, {-1715, -32724}, {-2143, -32698}, {-2570, -32667}, {-2998, -32631}, {-3425, -32588}, {-3851, -32541}, {-4277, -32488}, {-4701, -32429}, {-5125, -32364}, {-5548, -32295}, {-5971, -32219}, {-6393, -32138}, {-6813, -32051}, {-7231, -31960}, {-7650, -31863}, {-8067, -31760}, {-8481, -31652}, {-8895, -31539}, {-9306, -31419}, {-9716, -31294}, {-10126, -31165}, {-10532, -31030}, {-10937, -30889}, {-11340, -30743}, {-11741, -30592}, {-12141, -30436}, {-12540, -30274}, {-12935, -30107}, {-13328, -29936}, {-13718, -29758}, {-14107, -29577}, {-14493, -29390}, {-14875, -29197}, {-15257, -29000}, {-15635, -28797}, {-16010, -28590}, {-16384, -28379}, {-16753, -28162}, {-17119, -27940}, {-17484, -27714}, {-17845, -27482}, {-18205, -27246}, {-18560, -27006}, {-18911, -26760}, {-19260, -26510}, {-19606, -26257}, {-19947, -25997}, {-20286, -25734}, {-20621, -25466}, {-20952, -25194}, {-21281, -24918}, {-21605, -24637}, {-21926, -24353}, {-22242, -24063}, {-22555, -23770}, {-22865, -23473}, {-23171, -23171}, {-23472, -22866}, {-23769, -22557}, {-24063, -22244}, {-24352, -21927}, {-24636, -21606}, {-24917, -21282}, {-25194, -20954}, {-25465, -20622}, {-25733, -20288}, {-25997, -19949}, {-26255, -19607}, {-26509, -19261}, {-26760, -18914}, {-27004, -18561}, {-27246, -18205}, {-27481, -17846}, {-27713, -17485}, {-27940, -17122}, {-28162, -16755}, {-28378, -16385}, {-28590, -16012}, {-28797, -15636}, {-28999, -15258}, {-29197, -14878}, {-29389, -14494}, {-29576, -14108}, {-29757, -13720}, {-29934, -13329}, {-30107, -12937}, {-30274, -12540}, {-30435, -12142}, {-30592, -11744}, {-30743, -11342}, {-30889, -10939}, {-31030, -10534}, {-31164, -10127}, {-31294, -9718}, {-31418, -9307}, {-31537, -8895}, {-31652, -8482}, {-31759, -8067}, {-31862, -7650}, {-31960, -7233}, {-32051, -6815}, {-32138, -6393}, {-32219, -5973}, {-32294, -5549}, {-32364, -5127}, {-32429, -4703}, {-32487, -4278}, {-32541, -3852}, {-32588, -3426}, {-32630, -2999}, {-32667, -2572}, {-32698, -2144}, {-32724, -1716}, {-32742, -1287}, {-32757, -860}, {-32766, -430}, {-32767, 0}, {-32766, 429}, {-32757, 858}, {-32743, 1287}, {-32724, 1715}, {-32698, 2143}, {-32667, 2570}, {-32631, 2998}, {-32588, 3425}, {-32541, 3851}, {-32488, 4277}, {-32429, 4701}, {-32364, 5125}, {-32295, 5548}, {-32219, 5971}, {-32138, 6393}, {-32051, 6813}, {-31960, 7231}, {-31863, 7650}, {-31760, 8067}, {-31652, 8481}, {-31539, 8895}, {-31419, 9306}, {-31294, 9716}, {-31165, 10126}, {-31030, 10532}, {-30889, 10937}, {-30743, 11340}, {-30592, 11741}, {-30436, 12141}, {-30274, 12540}, {-30107, 12935}, {-29936, 13328}, {-29758, 13718}, {-29577, 14107}, {-29390, 14493}, {-29197, 14875}, {-29000, 15257}, {-28797, 15635}, {-28590, 16010}, {-28379, 16384}, {-28162, 16753}, {-27940, 17119}, {-27714, 17484}, {-27482, 17845}, {-27246, 18205}, {-27006, 18560}, {-26760, 18911}, {-26510, 19260}, {-26257, 19606}, {-25997, 19947}, {-25734, 20286}, {-25466, 20621}, {-25194, 20952}, {-24918, 21281}, {-24637, 21605}, {-24353, 21926}, {-24063, 22242}, {-23770, 22555}, {-23473, 22865}, {-23171, 23171}, {-22866, 23472}, {-22557, 23769}, {-22244, 24063}, {-21927, 24352}, {-21606, 24636}, {-21282, 24917}, {-20954, 25194}, {-20622, 25465}, {-20288, 25733}, {-19949, 25997}, {-19607, 26255}, {-19261, 26509}, {-18914, 26760}, {-18561, 27004}, {-18205, 27246}, {-17846, 27481}, {-17485, 27713}, {-17122, 27940}, {-16755, 28162}, {-16385, 28378}, {-16012, 28590}, {-15636, 28797}, {-15258, 28999}, {-14878, 29197}, {-14494, 29389}, {-14108, 29576}, {-13720, 29757}, {-13329, 29934}, {-12937, 30107}, {-12540, 30274}, {-12142, 30435}, {-11744, 30592}, {-11342, 30743}, {-10939, 30889}, {-10534, 31030}, {-10127, 31164}, {-9718, 31294}, {-9307, 31418}, {-8895, 31537}, {-8482, 31652}, {-8067, 31759}, {-7650, 31862}, {-7233, 31960}, {-6815, 32051}, {-6393, 32138}, {-5973, 32219}, {-5549, 32294}, {-5127, 32364}, {-4703, 32429}, {-4278, 32487}, {-3852, 32541}, {-3426, 32588}, {-2999, 32630}, {-2572, 32667}, {-2144, 32698}, {-1716, 32724}, {-1287, 32742}, {-860, 32757}, {-430, 32766}, {0, 32767}, {429, 32766}, {858, 32757}, {1287, 32743}, {1715, 32724}, {2143, 32698}, {2570, 32667}, {2998, 32631}, {3425, 32588}, {3851, 32541}, {4277, 32488}, {4701, 32429}, {5125, 32364}, {5548, 32295}, {5971, 32219}, {6393, 32138}, {6813, 32051}, {7231, 31960}, {7650, 31863}, {8067, 31760}, {8481, 31652}, {8895, 31539}, {9306, 31419}, {9716, 31294}, {10126, 31165}, {10532, 31030}, {10937, 30889}, {11340, 30743}, {11741, 30592}, {12141, 30436}, {12540, 30274}, {12935, 30107}, {13328, 29936}, {13718, 29758}, {14107, 29577}, {14493, 29390}, {14875, 29197}, {15257, 29000}, {15635, 28797}, {16010, 28590}, {16384, 28379}, {16753, 28162}, {17119, 27940}, {17484, 27714}, {17845, 27482}, {18205, 27246}, {18560, 27006}, {18911, 26760}, {19260, 26510}, {19606, 26257}, {19947, 25997}, {20286, 25734}, {20621, 25466}, {20952, 25194}, {21281, 24918}, {21605, 24637}, {21926, 24353}, {22242, 24063}, {22555, 23770}, {22865, 23473}, {23171, 23171}, {23472, 22866}, {23769, 22557}, {24063, 22244}, {24352, 21927}, {24636, 21606}, {24917, 21282}, {25194, 20954}, {25465, 20622}, {25733, 20288}, {25997, 19949}, {26255, 19607}, {26509, 19261}, {26760, 18914}, {27004, 18561}, {27246, 18205}, {27481, 17846}, {27713, 17485}, {27940, 17122}, {28162, 16755}, {28378, 16385}, {28590, 16012}, {28797, 15636}, {28999, 15258}, {29197, 14878}, {29389, 14494}, {29576, 14108}, {29757, 13720}, {29934, 13329}, {30107, 12937}, {30274, 12540}, {30435, 12142}, {30592, 11744}, {30743, 11342}, {30889, 10939}, {31030, 10534}, {31164, 10127}, {31294, 9718}, {31418, 9307}, {31537, 8895}, {31652, 8482}, {31759, 8067}, {31862, 7650}, {31960, 7233}, {32051, 6815}, {32138, 6393}, {32219, 5973}, {32294, 5549}, {32364, 5127}, {32429, 4703}, {32487, 4278}, {32541, 3852}, {32588, 3426}, {32630, 2999}, {32667, 2572}, {32698, 2144}, {32724, 1716}, {32742, 1287}, {32757, 860}, {32766, 430}, }; #ifndef FFT_BITREV480 #define FFT_BITREV480 static const opus_int16 fft_bitrev480[480] = { 0, 96, 192, 288, 384, 32, 128, 224, 320, 416, 64, 160, 256, 352, 448, 8, 104, 200, 296, 392, 40, 136, 232, 328, 424, 72, 168, 264, 360, 456, 16, 112, 208, 304, 400, 48, 144, 240, 336, 432, 80, 176, 272, 368, 464, 24, 120, 216, 312, 408, 56, 152, 248, 344, 440, 88, 184, 280, 376, 472, 4, 100, 196, 292, 388, 36, 132, 228, 324, 420, 68, 164, 260, 356, 452, 12, 108, 204, 300, 396, 44, 140, 236, 332, 428, 76, 172, 268, 364, 460, 20, 116, 212, 308, 404, 52, 148, 244, 340, 436, 84, 180, 276, 372, 468, 28, 124, 220, 316, 412, 60, 156, 252, 348, 444, 92, 188, 284, 380, 476, 1, 97, 193, 289, 385, 33, 129, 225, 321, 417, 65, 161, 257, 353, 449, 9, 105, 201, 297, 393, 41, 137, 233, 329, 425, 73, 169, 265, 361, 457, 17, 113, 209, 305, 401, 49, 145, 241, 337, 433, 81, 177, 273, 369, 465, 25, 121, 217, 313, 409, 57, 153, 249, 345, 441, 89, 185, 281, 377, 473, 5, 101, 197, 293, 389, 37, 133, 229, 325, 421, 69, 165, 261, 357, 453, 13, 109, 205, 301, 397, 45, 141, 237, 333, 429, 77, 173, 269, 365, 461, 21, 117, 213, 309, 405, 53, 149, 245, 341, 437, 85, 181, 277, 373, 469, 29, 125, 221, 317, 413, 61, 157, 253, 349, 445, 93, 189, 285, 381, 477, 2, 98, 194, 290, 386, 34, 130, 226, 322, 418, 66, 162, 258, 354, 450, 10, 106, 202, 298, 394, 42, 138, 234, 330, 426, 74, 170, 266, 362, 458, 18, 114, 210, 306, 402, 50, 146, 242, 338, 434, 82, 178, 274, 370, 466, 26, 122, 218, 314, 410, 58, 154, 250, 346, 442, 90, 186, 282, 378, 474, 6, 102, 198, 294, 390, 38, 134, 230, 326, 422, 70, 166, 262, 358, 454, 14, 110, 206, 302, 398, 46, 142, 238, 334, 430, 78, 174, 270, 366, 462, 22, 118, 214, 310, 406, 54, 150, 246, 342, 438, 86, 182, 278, 374, 470, 30, 126, 222, 318, 414, 62, 158, 254, 350, 446, 94, 190, 286, 382, 478, 3, 99, 195, 291, 387, 35, 131, 227, 323, 419, 67, 163, 259, 355, 451, 11, 107, 203, 299, 395, 43, 139, 235, 331, 427, 75, 171, 267, 363, 459, 19, 115, 211, 307, 403, 51, 147, 243, 339, 435, 83, 179, 275, 371, 467, 27, 123, 219, 315, 411, 59, 155, 251, 347, 443, 91, 187, 283, 379, 475, 7, 103, 199, 295, 391, 39, 135, 231, 327, 423, 71, 167, 263, 359, 455, 15, 111, 207, 303, 399, 47, 143, 239, 335, 431, 79, 175, 271, 367, 463, 23, 119, 215, 311, 407, 55, 151, 247, 343, 439, 87, 183, 279, 375, 471, 31, 127, 223, 319, 415, 63, 159, 255, 351, 447, 95, 191, 287, 383, 479, }; #endif #ifndef FFT_BITREV240 #define FFT_BITREV240 static const opus_int16 fft_bitrev240[240] = { 0, 48, 96, 144, 192, 16, 64, 112, 160, 208, 32, 80, 128, 176, 224, 4, 52, 100, 148, 196, 20, 68, 116, 164, 212, 36, 84, 132, 180, 228, 8, 56, 104, 152, 200, 24, 72, 120, 168, 216, 40, 88, 136, 184, 232, 12, 60, 108, 156, 204, 28, 76, 124, 172, 220, 44, 92, 140, 188, 236, 1, 49, 97, 145, 193, 17, 65, 113, 161, 209, 33, 81, 129, 177, 225, 5, 53, 101, 149, 197, 21, 69, 117, 165, 213, 37, 85, 133, 181, 229, 9, 57, 105, 153, 201, 25, 73, 121, 169, 217, 41, 89, 137, 185, 233, 13, 61, 109, 157, 205, 29, 77, 125, 173, 221, 45, 93, 141, 189, 237, 2, 50, 98, 146, 194, 18, 66, 114, 162, 210, 34, 82, 130, 178, 226, 6, 54, 102, 150, 198, 22, 70, 118, 166, 214, 38, 86, 134, 182, 230, 10, 58, 106, 154, 202, 26, 74, 122, 170, 218, 42, 90, 138, 186, 234, 14, 62, 110, 158, 206, 30, 78, 126, 174, 222, 46, 94, 142, 190, 238, 3, 51, 99, 147, 195, 19, 67, 115, 163, 211, 35, 83, 131, 179, 227, 7, 55, 103, 151, 199, 23, 71, 119, 167, 215, 39, 87, 135, 183, 231, 11, 59, 107, 155, 203, 27, 75, 123, 171, 219, 43, 91, 139, 187, 235, 15, 63, 111, 159, 207, 31, 79, 127, 175, 223, 47, 95, 143, 191, 239, }; #endif #ifndef FFT_BITREV120 #define FFT_BITREV120 static const opus_int16 fft_bitrev120[120] = { 0, 24, 48, 72, 96, 8, 32, 56, 80, 104, 16, 40, 64, 88, 112, 4, 28, 52, 76, 100, 12, 36, 60, 84, 108, 20, 44, 68, 92, 116, 1, 25, 49, 73, 97, 9, 33, 57, 81, 105, 17, 41, 65, 89, 113, 5, 29, 53, 77, 101, 13, 37, 61, 85, 109, 21, 45, 69, 93, 117, 2, 26, 50, 74, 98, 10, 34, 58, 82, 106, 18, 42, 66, 90, 114, 6, 30, 54, 78, 102, 14, 38, 62, 86, 110, 22, 46, 70, 94, 118, 3, 27, 51, 75, 99, 11, 35, 59, 83, 107, 19, 43, 67, 91, 115, 7, 31, 55, 79, 103, 15, 39, 63, 87, 111, 23, 47, 71, 95, 119, }; #endif #ifndef FFT_BITREV60 #define FFT_BITREV60 static const opus_int16 fft_bitrev60[60] = { 0, 12, 24, 36, 48, 4, 16, 28, 40, 52, 8, 20, 32, 44, 56, 1, 13, 25, 37, 49, 5, 17, 29, 41, 53, 9, 21, 33, 45, 57, 2, 14, 26, 38, 50, 6, 18, 30, 42, 54, 10, 22, 34, 46, 58, 3, 15, 27, 39, 51, 7, 19, 31, 43, 55, 11, 23, 35, 47, 59, }; #endif #ifndef FFT_STATE48000_960_0 #define FFT_STATE48000_960_0 static const kiss_fft_state fft_state48000_960_0 = { 480, /* nfft */ 17476, /* scale */ 8, /* scale_shift */ -1, /* shift */ {5, 96, 3, 32, 4, 8, 2, 4, 4, 1, 0, 0, 0, 0, 0, 0, }, /* factors */ fft_bitrev480, /* bitrev */ fft_twiddles48000_960, /* bitrev */ #ifdef OVERRIDE_FFT (arch_fft_state *)&cfg_arch_480, #else NULL, #endif }; #endif #ifndef FFT_STATE48000_960_1 #define FFT_STATE48000_960_1 static const kiss_fft_state fft_state48000_960_1 = { 240, /* nfft */ 17476, /* scale */ 7, /* scale_shift */ 1, /* shift */ {5, 48, 3, 16, 4, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ fft_bitrev240, /* bitrev */ fft_twiddles48000_960, /* bitrev */ #ifdef OVERRIDE_FFT (arch_fft_state *)&cfg_arch_240, #else NULL, #endif }; #endif #ifndef FFT_STATE48000_960_2 #define FFT_STATE48000_960_2 static const kiss_fft_state fft_state48000_960_2 = { 120, /* nfft */ 17476, /* scale */ 6, /* scale_shift */ 2, /* shift */ {5, 24, 3, 8, 2, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ fft_bitrev120, /* bitrev */ fft_twiddles48000_960, /* bitrev */ #ifdef OVERRIDE_FFT (arch_fft_state *)&cfg_arch_120, #else NULL, #endif }; #endif #ifndef FFT_STATE48000_960_3 #define FFT_STATE48000_960_3 static const kiss_fft_state fft_state48000_960_3 = { 60, /* nfft */ 17476, /* scale */ 5, /* scale_shift */ 3, /* shift */ {5, 12, 3, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ fft_bitrev60, /* bitrev */ fft_twiddles48000_960, /* bitrev */ #ifdef OVERRIDE_FFT (arch_fft_state *)&cfg_arch_60, #else NULL, #endif }; #endif #endif #ifndef MDCT_TWIDDLES960 #define MDCT_TWIDDLES960 static const opus_val16 mdct_twiddles960[1800] = { 32767, 32767, 32767, 32766, 32765, 32763, 32761, 32759, 32756, 32753, 32750, 32746, 32742, 32738, 32733, 32728, 32722, 32717, 32710, 32704, 32697, 32690, 32682, 32674, 32666, 32657, 32648, 32639, 32629, 32619, 32609, 32598, 32587, 32576, 32564, 32552, 32539, 32526, 32513, 32500, 32486, 32472, 32457, 32442, 32427, 32411, 32395, 32379, 32362, 32345, 32328, 32310, 32292, 32274, 32255, 32236, 32217, 32197, 32177, 32157, 32136, 32115, 32093, 32071, 32049, 32027, 32004, 31981, 31957, 31933, 31909, 31884, 31859, 31834, 31809, 31783, 31756, 31730, 31703, 31676, 31648, 31620, 31592, 31563, 31534, 31505, 31475, 31445, 31415, 31384, 31353, 31322, 31290, 31258, 31226, 31193, 31160, 31127, 31093, 31059, 31025, 30990, 30955, 30920, 30884, 30848, 30812, 30775, 30738, 30701, 30663, 30625, 30587, 30548, 30509, 30470, 30430, 30390, 30350, 30309, 30269, 30227, 30186, 30144, 30102, 30059, 30016, 29973, 29930, 29886, 29842, 29797, 29752, 29707, 29662, 29616, 29570, 29524, 29477, 29430, 29383, 29335, 29287, 29239, 29190, 29142, 29092, 29043, 28993, 28943, 28892, 28842, 28791, 28739, 28688, 28636, 28583, 28531, 28478, 28425, 28371, 28317, 28263, 28209, 28154, 28099, 28044, 27988, 27932, 27876, 27820, 27763, 27706, 27648, 27591, 27533, 27474, 27416, 27357, 27298, 27238, 27178, 27118, 27058, 26997, 26936, 26875, 26814, 26752, 26690, 26628, 26565, 26502, 26439, 26375, 26312, 26247, 26183, 26119, 26054, 25988, 25923, 25857, 25791, 25725, 25658, 25592, 25524, 25457, 25389, 25322, 25253, 25185, 25116, 25047, 24978, 24908, 24838, 24768, 24698, 24627, 24557, 24485, 24414, 24342, 24270, 24198, 24126, 24053, 23980, 23907, 23834, 23760, 23686, 23612, 23537, 23462, 23387, 23312, 23237, 23161, 23085, 23009, 22932, 22856, 22779, 22701, 22624, 22546, 22468, 22390, 22312, 22233, 22154, 22075, 21996, 21916, 21836, 21756, 21676, 21595, 21515, 21434, 21352, 21271, 21189, 21107, 21025, 20943, 20860, 20777, 20694, 20611, 20528, 20444, 20360, 20276, 20192, 20107, 20022, 19937, 19852, 19767, 19681, 19595, 19509, 19423, 19336, 19250, 19163, 19076, 18988, 18901, 18813, 18725, 18637, 18549, 18460, 18372, 18283, 18194, 18104, 18015, 17925, 17835, 17745, 17655, 17565, 17474, 17383, 17292, 17201, 17110, 17018, 16927, 16835, 16743, 16650, 16558, 16465, 16372, 16279, 16186, 16093, 15999, 15906, 15812, 15718, 15624, 15529, 15435, 15340, 15245, 15150, 15055, 14960, 14864, 14769, 14673, 14577, 14481, 14385, 14288, 14192, 14095, 13998, 13901, 13804, 13706, 13609, 13511, 13414, 13316, 13218, 13119, 13021, 12923, 12824, 12725, 12626, 12527, 12428, 12329, 12230, 12130, 12030, 11930, 11831, 11730, 11630, 11530, 11430, 11329, 11228, 11128, 11027, 10926, 10824, 10723, 10622, 10520, 10419, 10317, 10215, 10113, 10011, 9909, 9807, 9704, 9602, 9499, 9397, 9294, 9191, 9088, 8985, 8882, 8778, 8675, 8572, 8468, 8364, 8261, 8157, 8053, 7949, 7845, 7741, 7637, 7532, 7428, 7323, 7219, 7114, 7009, 6905, 6800, 6695, 6590, 6485, 6380, 6274, 6169, 6064, 5958, 5853, 5747, 5642, 5536, 5430, 5325, 5219, 5113, 5007, 4901, 4795, 4689, 4583, 4476, 4370, 4264, 4157, 4051, 3945, 3838, 3732, 3625, 3518, 3412, 3305, 3198, 3092, 2985, 2878, 2771, 2664, 2558, 2451, 2344, 2237, 2130, 2023, 1916, 1809, 1702, 1594, 1487, 1380, 1273, 1166, 1059, 952, 844, 737, 630, 523, 416, 308, 201, 94, -13, -121, -228, -335, -442, -550, -657, -764, -871, -978, -1086, -1193, -1300, -1407, -1514, -1621, -1728, -1835, -1942, -2049, -2157, -2263, -2370, -2477, -2584, -2691, -2798, -2905, -3012, -3118, -3225, -3332, -3439, -3545, -3652, -3758, -3865, -3971, -4078, -4184, -4290, -4397, -4503, -4609, -4715, -4821, -4927, -5033, -5139, -5245, -5351, -5457, -5562, -5668, -5774, -5879, -5985, -6090, -6195, -6301, -6406, -6511, -6616, -6721, -6826, -6931, -7036, -7140, -7245, -7349, -7454, -7558, -7663, -7767, -7871, -7975, -8079, -8183, -8287, -8390, -8494, -8597, -8701, -8804, -8907, -9011, -9114, -9217, -9319, -9422, -9525, -9627, -9730, -9832, -9934, -10037, -10139, -10241, -10342, -10444, -10546, -10647, -10748, -10850, -10951, -11052, -11153, -11253, -11354, -11455, -11555, -11655, -11756, -11856, -11955, -12055, -12155, -12254, -12354, -12453, -12552, -12651, -12750, -12849, -12947, -13046, -13144, -13242, -13340, -13438, -13536, -13633, -13731, -13828, -13925, -14022, -14119, -14216, -14312, -14409, -14505, -14601, -14697, -14793, -14888, -14984, -15079, -15174, -15269, -15364, -15459, -15553, -15647, -15741, -15835, -15929, -16023, -16116, -16210, -16303, -16396, -16488, -16581, -16673, -16766, -16858, -16949, -17041, -17133, -17224, -17315, -17406, -17497, -17587, -17678, -17768, -17858, -17948, -18037, -18127, -18216, -18305, -18394, -18483, -18571, -18659, -18747, -18835, -18923, -19010, -19098, -19185, -19271, -19358, -19444, -19531, -19617, -19702, -19788, -19873, -19959, -20043, -20128, -20213, -20297, -20381, -20465, -20549, -20632, -20715, -20798, -20881, -20963, -21046, -21128, -21210, -21291, -21373, -21454, -21535, -21616, -21696, -21776, -21856, -21936, -22016, -22095, -22174, -22253, -22331, -22410, -22488, -22566, -22643, -22721, -22798, -22875, -22951, -23028, -23104, -23180, -23256, -23331, -23406, -23481, -23556, -23630, -23704, -23778, -23852, -23925, -23998, -24071, -24144, -24216, -24288, -24360, -24432, -24503, -24574, -24645, -24716, -24786, -24856, -24926, -24995, -25064, -25133, -25202, -25270, -25339, -25406, -25474, -25541, -25608, -25675, -25742, -25808, -25874, -25939, -26005, -26070, -26135, -26199, -26264, -26327, -26391, -26455, -26518, -26581, -26643, -26705, -26767, -26829, -26891, -26952, -27013, -27073, -27133, -27193, -27253, -27312, -27372, -27430, -27489, -27547, -27605, -27663, -27720, -27777, -27834, -27890, -27946, -28002, -28058, -28113, -28168, -28223, -28277, -28331, -28385, -28438, -28491, -28544, -28596, -28649, -28701, -28752, -28803, -28854, -28905, -28955, -29006, -29055, -29105, -29154, -29203, -29251, -29299, -29347, -29395, -29442, -29489, -29535, -29582, -29628, -29673, -29719, -29764, -29808, -29853, -29897, -29941, -29984, -30027, -30070, -30112, -30154, -30196, -30238, -30279, -30320, -30360, -30400, -30440, -30480, -30519, -30558, -30596, -30635, -30672, -30710, -30747, -30784, -30821, -30857, -30893, -30929, -30964, -30999, -31033, -31068, -31102, -31135, -31168, -31201, -31234, -31266, -31298, -31330, -31361, -31392, -31422, -31453, -31483, -31512, -31541, -31570, -31599, -31627, -31655, -31682, -31710, -31737, -31763, -31789, -31815, -31841, -31866, -31891, -31915, -31939, -31963, -31986, -32010, -32032, -32055, -32077, -32099, -32120, -32141, -32162, -32182, -32202, -32222, -32241, -32260, -32279, -32297, -32315, -32333, -32350, -32367, -32383, -32399, -32415, -32431, -32446, -32461, -32475, -32489, -32503, -32517, -32530, -32542, -32555, -32567, -32579, -32590, -32601, -32612, -32622, -32632, -32641, -32651, -32659, -32668, -32676, -32684, -32692, -32699, -32706, -32712, -32718, -32724, -32729, -32734, -32739, -32743, -32747, -32751, -32754, -32757, -32760, -32762, -32764, -32765, -32767, -32767, -32767, 32767, 32767, 32765, 32761, 32756, 32750, 32742, 32732, 32722, 32710, 32696, 32681, 32665, 32647, 32628, 32608, 32586, 32562, 32538, 32512, 32484, 32455, 32425, 32393, 32360, 32326, 32290, 32253, 32214, 32174, 32133, 32090, 32046, 32001, 31954, 31906, 31856, 31805, 31753, 31700, 31645, 31588, 31530, 31471, 31411, 31349, 31286, 31222, 31156, 31089, 31020, 30951, 30880, 30807, 30733, 30658, 30582, 30504, 30425, 30345, 30263, 30181, 30096, 30011, 29924, 29836, 29747, 29656, 29564, 29471, 29377, 29281, 29184, 29086, 28987, 28886, 28784, 28681, 28577, 28471, 28365, 28257, 28147, 28037, 27925, 27812, 27698, 27583, 27467, 27349, 27231, 27111, 26990, 26868, 26744, 26620, 26494, 26367, 26239, 26110, 25980, 25849, 25717, 25583, 25449, 25313, 25176, 25038, 24900, 24760, 24619, 24477, 24333, 24189, 24044, 23898, 23751, 23602, 23453, 23303, 23152, 22999, 22846, 22692, 22537, 22380, 22223, 22065, 21906, 21746, 21585, 21423, 21261, 21097, 20933, 20767, 20601, 20434, 20265, 20096, 19927, 19756, 19584, 19412, 19239, 19065, 18890, 18714, 18538, 18361, 18183, 18004, 17824, 17644, 17463, 17281, 17098, 16915, 16731, 16546, 16361, 16175, 15988, 15800, 15612, 15423, 15234, 15043, 14852, 14661, 14469, 14276, 14083, 13889, 13694, 13499, 13303, 13107, 12910, 12713, 12515, 12317, 12118, 11918, 11718, 11517, 11316, 11115, 10913, 10710, 10508, 10304, 10100, 9896, 9691, 9486, 9281, 9075, 8869, 8662, 8455, 8248, 8040, 7832, 7623, 7415, 7206, 6996, 6787, 6577, 6366, 6156, 5945, 5734, 5523, 5311, 5100, 4888, 4675, 4463, 4251, 4038, 3825, 3612, 3399, 3185, 2972, 2758, 2544, 2330, 2116, 1902, 1688, 1474, 1260, 1045, 831, 617, 402, 188, -27, -241, -456, -670, -885, -1099, -1313, -1528, -1742, -1956, -2170, -2384, -2598, -2811, -3025, -3239, -3452, -3665, -3878, -4091, -4304, -4516, -4728, -4941, -5153, -5364, -5576, -5787, -5998, -6209, -6419, -6629, -6839, -7049, -7258, -7467, -7676, -7884, -8092, -8300, -8507, -8714, -8920, -9127, -9332, -9538, -9743, -9947, -10151, -10355, -10558, -10761, -10963, -11165, -11367, -11568, -11768, -11968, -12167, -12366, -12565, -12762, -12960, -13156, -13352, -13548, -13743, -13937, -14131, -14324, -14517, -14709, -14900, -15091, -15281, -15470, -15659, -15847, -16035, -16221, -16407, -16593, -16777, -16961, -17144, -17326, -17508, -17689, -17869, -18049, -18227, -18405, -18582, -18758, -18934, -19108, -19282, -19455, -19627, -19799, -19969, -20139, -20308, -20475, -20642, -20809, -20974, -21138, -21301, -21464, -21626, -21786, -21946, -22105, -22263, -22420, -22575, -22730, -22884, -23037, -23189, -23340, -23490, -23640, -23788, -23935, -24080, -24225, -24369, -24512, -24654, -24795, -24934, -25073, -25211, -25347, -25482, -25617, -25750, -25882, -26013, -26143, -26272, -26399, -26526, -26651, -26775, -26898, -27020, -27141, -27260, -27379, -27496, -27612, -27727, -27841, -27953, -28065, -28175, -28284, -28391, -28498, -28603, -28707, -28810, -28911, -29012, -29111, -29209, -29305, -29401, -29495, -29587, -29679, -29769, -29858, -29946, -30032, -30118, -30201, -30284, -30365, -30445, -30524, -30601, -30677, -30752, -30825, -30897, -30968, -31038, -31106, -31172, -31238, -31302, -31365, -31426, -31486, -31545, -31602, -31658, -31713, -31766, -31818, -31869, -31918, -31966, -32012, -32058, -32101, -32144, -32185, -32224, -32262, -32299, -32335, -32369, -32401, -32433, -32463, -32491, -32518, -32544, -32568, -32591, -32613, -32633, -32652, -32669, -32685, -32700, -32713, -32724, -32735, -32744, -32751, -32757, -32762, -32766, -32767, 32767, 32764, 32755, 32741, 32720, 32694, 32663, 32626, 32583, 32535, 32481, 32421, 32356, 32286, 32209, 32128, 32041, 31948, 31850, 31747, 31638, 31523, 31403, 31278, 31148, 31012, 30871, 30724, 30572, 30415, 30253, 30086, 29913, 29736, 29553, 29365, 29172, 28974, 28771, 28564, 28351, 28134, 27911, 27684, 27452, 27216, 26975, 26729, 26478, 26223, 25964, 25700, 25432, 25159, 24882, 24601, 24315, 24026, 23732, 23434, 23133, 22827, 22517, 22204, 21886, 21565, 21240, 20912, 20580, 20244, 19905, 19563, 19217, 18868, 18516, 18160, 17802, 17440, 17075, 16708, 16338, 15964, 15588, 15210, 14829, 14445, 14059, 13670, 13279, 12886, 12490, 12093, 11693, 11291, 10888, 10482, 10075, 9666, 9255, 8843, 8429, 8014, 7597, 7180, 6760, 6340, 5919, 5496, 5073, 4649, 4224, 3798, 3372, 2945, 2517, 2090, 1661, 1233, 804, 375, -54, -483, -911, -1340, -1768, -2197, -2624, -3052, -3479, -3905, -4330, -4755, -5179, -5602, -6024, -6445, -6865, -7284, -7702, -8118, -8533, -8946, -9358, -9768, -10177, -10584, -10989, -11392, -11793, -12192, -12589, -12984, -13377, -13767, -14155, -14541, -14924, -15305, -15683, -16058, -16430, -16800, -17167, -17531, -17892, -18249, -18604, -18956, -19304, -19649, -19990, -20329, -20663, -20994, -21322, -21646, -21966, -22282, -22595, -22904, -23208, -23509, -23806, -24099, -24387, -24672, -24952, -25228, -25499, -25766, -26029, -26288, -26541, -26791, -27035, -27275, -27511, -27741, -27967, -28188, -28405, -28616, -28823, -29024, -29221, -29412, -29599, -29780, -29957, -30128, -30294, -30455, -30611, -30761, -30906, -31046, -31181, -31310, -31434, -31552, -31665, -31773, -31875, -31972, -32063, -32149, -32229, -32304, -32373, -32437, -32495, -32547, -32594, -32635, -32671, -32701, -32726, -32745, -32758, -32766, 32767, 32754, 32717, 32658, 32577, 32473, 32348, 32200, 32029, 31837, 31624, 31388, 31131, 30853, 30553, 30232, 29891, 29530, 29148, 28746, 28324, 27883, 27423, 26944, 26447, 25931, 25398, 24847, 24279, 23695, 23095, 22478, 21846, 21199, 20538, 19863, 19174, 18472, 17757, 17030, 16291, 15541, 14781, 14010, 13230, 12441, 11643, 10837, 10024, 9204, 8377, 7545, 6708, 5866, 5020, 4171, 3319, 2464, 1608, 751, -107, -965, -1822, -2678, -3532, -4383, -5232, -6077, -6918, -7754, -8585, -9409, -10228, -11039, -11843, -12639, -13426, -14204, -14972, -15730, -16477, -17213, -17937, -18648, -19347, -20033, -20705, -21363, -22006, -22634, -23246, -23843, -24423, -24986, -25533, -26062, -26573, -27066, -27540, -27995, -28431, -28848, -29245, -29622, -29979, -30315, -30630, -30924, -31197, -31449, -31679, -31887, -32074, -32239, -32381, -32501, -32600, -32675, -32729, -32759, }; #endif static const CELTMode mode48000_960_120 = { 48000, /* Fs */ 120, /* overlap */ 21, /* nbEBands */ 21, /* effEBands */ {27853, 0, 4096, 8192, }, /* preemph */ eband5ms, /* eBands */ 3, /* maxLM */ 8, /* nbShortMdcts */ 120, /* shortMdctSize */ 11, /* nbAllocVectors */ band_allocation, /* allocVectors */ logN400, /* logN */ window120, /* window */ {1920, 3, {&fft_state48000_960_0, &fft_state48000_960_1, &fft_state48000_960_2, &fft_state48000_960_3, }, mdct_twiddles960}, /* mdct */ {392, cache_index50, cache_bits50, cache_caps50}, /* cache */ }; /* List of all the available modes */ #define TOTAL_MODES 1 static const CELTMode * const static_mode_list[TOTAL_MODES] = { &mode48000_960_120, }; jamulus-3.9.1+dfsg/libs/opus/celt/vq.c0000644000175000017500000003103614340334543016617 0ustar vimervimer/* Copyright (c) 2007-2008 CSIRO Copyright (c) 2007-2009 Xiph.Org Foundation Written by Jean-Marc Valin */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "mathops.h" #include "cwrs.h" #include "vq.h" #include "arch.h" #include "os_support.h" #include "bands.h" #include "rate.h" #include "pitch.h" #if defined(MIPSr1_ASM) #include "mips/vq_mipsr1.h" #endif #ifndef OVERRIDE_vq_exp_rotation1 static void exp_rotation1(celt_norm *X, int len, int stride, opus_val16 c, opus_val16 s) { int i; opus_val16 ms; celt_norm *Xptr; Xptr = X; ms = NEG16(s); for (i=0;i=0;i--) { celt_norm x1, x2; x1 = Xptr[0]; x2 = Xptr[stride]; Xptr[stride] = EXTRACT16(PSHR32(MAC16_16(MULT16_16(c, x2), s, x1), 15)); *Xptr-- = EXTRACT16(PSHR32(MAC16_16(MULT16_16(c, x1), ms, x2), 15)); } } #endif /* OVERRIDE_vq_exp_rotation1 */ void exp_rotation(celt_norm *X, int len, int dir, int stride, int K, int spread) { static const int SPREAD_FACTOR[3]={15,10,5}; int i; opus_val16 c, s; opus_val16 gain, theta; int stride2=0; int factor; if (2*K>=len || spread==SPREAD_NONE) return; factor = SPREAD_FACTOR[spread-1]; gain = celt_div((opus_val32)MULT16_16(Q15_ONE,len),(opus_val32)(len+factor*K)); theta = HALF16(MULT16_16_Q15(gain,gain)); c = celt_cos_norm(EXTEND32(theta)); s = celt_cos_norm(EXTEND32(SUB16(Q15ONE,theta))); /* sin(theta) */ if (len>=8*stride) { stride2 = 1; /* This is just a simple (equivalent) way of computing sqrt(len/stride) with rounding. It's basically incrementing long as (stride2+0.5)^2 < len/stride. */ while ((stride2*stride2+stride2)*stride + (stride>>2) < len) stride2++; } /*NOTE: As a minor optimization, we could be passing around log2(B), not B, for both this and for extract_collapse_mask().*/ len = celt_udiv(len, stride); for (i=0;i>1; #endif t = VSHR32(Ryy, 2*(k-7)); g = MULT16_16_P15(celt_rsqrt_norm(t),gain); i=0; do X[i] = EXTRACT16(PSHR32(MULT16_16(g, iy[i]), k+1)); while (++i < N); } static unsigned extract_collapse_mask(int *iy, int N, int B) { unsigned collapse_mask; int N0; int i; if (B<=1) return 1; /*NOTE: As a minor optimization, we could be passing around log2(B), not B, for both this and for exp_rotation().*/ N0 = celt_udiv(N, B); collapse_mask = 0; i=0; do { int j; unsigned tmp=0; j=0; do { tmp |= iy[i*N0+j]; } while (++j (N>>1)) { opus_val16 rcp; j=0; do { sum += X[j]; } while (++j EPSILON && sum < 64)) #endif { X[0] = QCONST16(1.f,14); j=1; do X[j]=0; while (++j=0); /* This should never happen, but just in case it does (e.g. on silence) we fill the first bin with pulses. */ #ifdef FIXED_POINT_DEBUG celt_sig_assert(pulsesLeft<=N+3); #endif if (pulsesLeft > N+3) { opus_val16 tmp = (opus_val16)pulsesLeft; yy = MAC16_16(yy, tmp, tmp); yy = MAC16_16(yy, tmp, y[0]); iy[0] += pulsesLeft; pulsesLeft=0; } for (i=0;i= best_num/best_den, but that way we can do it without any division */ /* OPT: It's not clear whether a cmov is faster than a branch here since the condition is more often false than true and using a cmov introduces data dependencies across iterations. The optimal choice may be architecture-dependent. */ if (opus_unlikely(MULT16_16(best_den, Rxy) > MULT16_16(Ryy, best_num))) { best_den = Ryy; best_num = Rxy; best_id = j; } } while (++j0, "alg_quant() needs at least one pulse"); celt_assert2(N>1, "alg_quant() needs at least two dimensions"); /* Covers vectorization by up to 4. */ ALLOC(iy, N+3, int); exp_rotation(X, N, 1, B, K, spread); yy = op_pvq_search(X, iy, K, N, arch); encode_pulses(iy, N, K, enc); if (resynth) { normalise_residual(iy, X, N, yy, gain); exp_rotation(X, N, -1, B, K, spread); } collapse_mask = extract_collapse_mask(iy, N, B); RESTORE_STACK; return collapse_mask; } /** Decode pulse vector and combine the result with the pitch vector to produce the final normalised signal in the current band. */ unsigned alg_unquant(celt_norm *X, int N, int K, int spread, int B, ec_dec *dec, opus_val16 gain) { opus_val32 Ryy; unsigned collapse_mask; VARDECL(int, iy); SAVE_STACK; celt_assert2(K>0, "alg_unquant() needs at least one pulse"); celt_assert2(N>1, "alg_unquant() needs at least two dimensions"); ALLOC(iy, N, int); Ryy = decode_pulses(iy, N, K, dec); normalise_residual(iy, X, N, Ryy, gain); exp_rotation(X, N, -1, B, K, spread); collapse_mask = extract_collapse_mask(iy, N, B); RESTORE_STACK; return collapse_mask; } #ifndef OVERRIDE_renormalise_vector void renormalise_vector(celt_norm *X, int N, opus_val16 gain, int arch) { int i; #ifdef FIXED_POINT int k; #endif opus_val32 E; opus_val16 g; opus_val32 t; celt_norm *xptr; E = EPSILON + celt_inner_prod(X, X, N, arch); #ifdef FIXED_POINT k = celt_ilog2(E)>>1; #endif t = VSHR32(E, 2*(k-7)); g = MULT16_16_P15(celt_rsqrt_norm(t),gain); xptr = X; for (i=0;i #include #define CELT_C #include "laplace.h" #include "stack_alloc.h" #include "entenc.c" #include "entdec.c" #include "entcode.c" #include "laplace.c" #define DATA_SIZE 40000 int ec_laplace_get_start_freq(int decay) { opus_uint32 ft = 32768 - LAPLACE_MINP*(2*LAPLACE_NMIN+1); int fs = (ft*(16384-decay))/(16384+decay); return fs+LAPLACE_MINP; } int main(void) { int i; int ret = 0; ec_enc enc; ec_dec dec; unsigned char *ptr; int val[10000], decay[10000]; ALLOC_STACK; ptr = (unsigned char *)malloc(DATA_SIZE); ec_enc_init(&enc,ptr,DATA_SIZE); val[0] = 3; decay[0] = 6000; val[1] = 0; decay[1] = 5800; val[2] = -1; decay[2] = 5600; for (i=3;i<10000;i++) { val[i] = rand()%15-7; decay[i] = rand()%11000+5000; } for (i=0;i<10000;i++) ec_laplace_encode(&enc, &val[i], ec_laplace_get_start_freq(decay[i]), decay[i]); ec_enc_done(&enc); ec_dec_init(&dec,ec_get_buffer(&enc),ec_range_bytes(&enc)); for (i=0;i<10000;i++) { int d = ec_laplace_decode(&dec, ec_laplace_get_start_freq(decay[i]), decay[i]); if (d != val[i]) { fprintf (stderr, "Got %d instead of %d\n", d, val[i]); ret = 1; } } free(ptr); return ret; } jamulus-3.9.1+dfsg/libs/opus/celt/tests/test_unit_mdct.c0000644000175000017500000001367714340334543022373 0ustar vimervimer/* Copyright (c) 2008-2011 Xiph.Org Foundation Written by Jean-Marc Valin */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "mdct.h" #include "stack_alloc.h" #include "kiss_fft.h" #include "mdct.h" #include "modes.h" #ifndef M_PI #define M_PI 3.141592653 #endif int ret = 0; void check(kiss_fft_scalar * in,kiss_fft_scalar * out,int nfft,int isinverse) { int bin,k; double errpow=0,sigpow=0; double snr; for (bin=0;binmdct; #endif in = (kiss_fft_scalar*)malloc(buflen); in_copy = (kiss_fft_scalar*)malloc(buflen); out = (kiss_fft_scalar*)malloc(buflen); window = (opus_val16*)malloc(sizeof(opus_val16)*nfft/2); for (k=0;k1) { int k; for (k=1;k #include "stack_alloc.h" #include "kiss_fft.h" #include "mathops.h" #include "modes.h" #ifndef M_PI #define M_PI 3.141592653 #endif int ret = 0; void check(kiss_fft_cpx * in,kiss_fft_cpx * out,int nfft,int isinverse) { int bin,k; double errpow=0,sigpow=0, snr; for (bin=0;binmdct.kfft[id]; #endif in = (kiss_fft_cpx*)malloc(buflen); out = (kiss_fft_cpx*)malloc(buflen); for (k=0;k1) { int k; for (k=1;k #include #include #include #define CELT_C #include "entcode.h" #include "entenc.h" #include "entdec.h" #include #include "entenc.c" #include "entdec.c" #include "entcode.c" #ifndef M_LOG2E # define M_LOG2E 1.4426950408889634074 #endif #define DATA_SIZE 10000000 #define DATA_SIZE2 10000 int main(int _argc,char **_argv){ ec_enc enc; ec_dec dec; long nbits; long nbits2; double entropy; int ft; int ftb; int sz; int i; int ret; unsigned int sym; unsigned int seed; unsigned char *ptr; const char *env_seed; ret=0; entropy=0; if (_argc > 2) { fprintf(stderr, "Usage: %s []\n", _argv[0]); return 1; } env_seed = getenv("SEED"); if (_argc > 1) seed = atoi(_argv[1]); else if (env_seed) seed = atoi(env_seed); else seed = time(NULL); /*Testing encoding of raw bit values.*/ ptr = (unsigned char *)malloc(DATA_SIZE); ec_enc_init(&enc,ptr, DATA_SIZE); for(ft=2;ft<1024;ft++){ for(i=0;i>(rand()%11U))+1U)+10; sz=rand()/((RAND_MAX>>(rand()%9U))+1U); data=(unsigned *)malloc(sz*sizeof(*data)); tell=(unsigned *)malloc((sz+1)*sizeof(*tell)); ec_enc_init(&enc,ptr,DATA_SIZE2); zeros = rand()%13==0; tell[0]=ec_tell_frac(&enc); for(j=0;j>(rand()%9U))+1U); logp1=(unsigned *)malloc(sz*sizeof(*logp1)); data=(unsigned *)malloc(sz*sizeof(*data)); tell=(unsigned *)malloc((sz+1)*sizeof(*tell)); enc_method=(unsigned *)malloc(sz*sizeof(*enc_method)); ec_enc_init(&enc,ptr,DATA_SIZE2); tell[0]=ec_tell_frac(&enc); for(j=0;j>1)+1); logp1[j]=(rand()%15)+1; enc_method[j]=rand()/((RAND_MAX>>2)+1); switch(enc_method[j]){ case 0:{ ec_encode(&enc,data[j]?(1<>2)+1); switch(dec_method){ case 0:{ fs=ec_decode(&dec,1<=(1<=(1< #include #include "mathops.h" #include "bands.h" #ifdef FIXED_POINT #define WORD "%d" #else #define WORD "%f" #endif int ret = 0; void testdiv(void) { opus_int32 i; for (i=1;i<=327670;i++) { double prod; opus_val32 val; val = celt_rcp(i); #ifdef FIXED_POINT prod = (1./32768./65526.)*val*i; #else prod = val*i; #endif if (fabs(prod-1) > .00025) { fprintf (stderr, "div failed: 1/%d="WORD" (product = %f)\n", i, val, prod); ret = 1; } } } void testsqrt(void) { opus_int32 i; for (i=1;i<=1000000000;i++) { double ratio; opus_val16 val; val = celt_sqrt(i); ratio = val/sqrt(i); if (fabs(ratio - 1) > .0005 && fabs(val-sqrt(i)) > 2) { fprintf (stderr, "sqrt failed: sqrt(%d)="WORD" (ratio = %f)\n", i, val, ratio); ret = 1; } i+= i>>10; } } void testbitexactcos(void) { int i; opus_int32 min_d,max_d,last,chk; chk=max_d=0; last=min_d=32767; for(i=64;i<=16320;i++) { opus_int32 d; opus_int32 q=bitexact_cos(i); chk ^= q*i; d = last - q; if (d>max_d)max_d=d; if (dmax_d)max_d=d; if (d0.0009) { fprintf (stderr, "celt_log2 failed: fabs((1.442695040888963387*log(x))-celt_log2(x))>0.001 (x = %f, error = %f)\n", x,error); ret = 1; } } } void testexp2(void) { float x; for (x=-11.0;x<24.0;x+=0.0007) { float error = fabs(x-(1.442695040888963387*log(celt_exp2(x)))); if (error>0.0002) { fprintf (stderr, "celt_exp2 failed: fabs(x-(1.442695040888963387*log(celt_exp2(x))))>0.0005 (x = %f, error = %f)\n", x,error); ret = 1; } } } void testexp2log2(void) { float x; for (x=-11.0;x<24.0;x+=0.0007) { float error = fabs(x-(celt_log2(celt_exp2(x)))); if (error>0.001) { fprintf (stderr, "celt_log2/celt_exp2 failed: fabs(x-(celt_log2(celt_exp2(x))))>0.001 (x = %f, error = %f)\n", x,error); ret = 1; } } } #else void testlog2(void) { opus_val32 x; for (x=8;x<1073741824;x+=(x>>3)) { float error = fabs((1.442695040888963387*log(x/16384.0))-celt_log2(x)/1024.0); if (error>0.003) { fprintf (stderr, "celt_log2 failed: x = %ld, error = %f\n", (long)x,error); ret = 1; } } } void testexp2(void) { opus_val16 x; for (x=-32768;x<15360;x++) { float error1 = fabs(x/1024.0-(1.442695040888963387*log(celt_exp2(x)/65536.0))); float error2 = fabs(exp(0.6931471805599453094*x/1024.0)-celt_exp2(x)/65536.0); if (error1>0.0002&&error2>0.00004) { fprintf (stderr, "celt_exp2 failed: x = "WORD", error1 = %f, error2 = %f\n", x,error1,error2); ret = 1; } } } void testexp2log2(void) { opus_val32 x; for (x=8;x<65536;x+=(x>>3)) { float error = fabs(x-0.25*celt_exp2(celt_log2(x)))/16384; if (error>0.004) { fprintf (stderr, "celt_log2/celt_exp2 failed: fabs(x-(celt_exp2(celt_log2(x))))>0.001 (x = %ld, error = %f)\n", (long)x,error); ret = 1; } } } void testilog2(void) { opus_val32 x; for (x=1;x<=268435455;x+=127) { opus_val32 lg; opus_val32 y; lg = celt_ilog2(x); if (lg<0 || lg>=31) { printf("celt_ilog2 failed: 0<=celt_ilog2(x)<31 (x = %d, celt_ilog2(x) = %d)\n",x,lg); ret = 1; } y = 1<>1)>=y) { printf("celt_ilog2 failed: 2**celt_ilog2(x)<=x<2**(celt_ilog2(x)+1) (x = %d, 2**celt_ilog2(x) = %d)\n",x,y); ret = 1; } } } #endif int main(void) { testbitexactcos(); testbitexactlog2tan(); testdiv(); testsqrt(); testlog2(); testexp2(); testexp2log2(); #ifdef FIXED_POINT testilog2(); #endif return ret; } jamulus-3.9.1+dfsg/libs/opus/celt/tests/test_unit_cwrs32.c0000644000175000017500000001057014340334543022554 0ustar vimervimer/* Copyright (c) 2008-2011 Xiph.Org Foundation, Mozilla Corporation, Gregory Maxwell Written by Jean-Marc Valin, Gregory Maxwell, and Timothy B. Terriberry */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #ifndef CUSTOM_MODES #define CUSTOM_MODES #else #define TEST_CUSTOM_MODES #endif #define CELT_C #include "stack_alloc.h" #include "entenc.c" #include "entdec.c" #include "entcode.c" #include "cwrs.c" #include "mathops.c" #include "rate.h" #define NMAX (240) #define KMAX (128) #ifdef TEST_CUSTOM_MODES #define NDIMS (44) static const int pn[NDIMS]={ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 22, 24, 26, 28, 30, 32, 36, 40, 44, 48, 52, 56, 60, 64, 72, 80, 88, 96, 104, 112, 120, 128, 144, 160, 176, 192, 208 }; static const int pkmax[NDIMS]={ 128, 128, 128, 128, 88, 52, 36, 26, 22, 18, 16, 15, 13, 12, 12, 11, 10, 9, 9, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4 }; #else /* TEST_CUSTOM_MODES */ #define NDIMS (22) static const int pn[NDIMS]={ 2, 3, 4, 6, 8, 9, 11, 12, 16, 18, 22, 24, 32, 36, 44, 48, 64, 72, 88, 96, 144, 176 }; static const int pkmax[NDIMS]={ 128, 128, 128, 88, 36, 26, 18, 16, 12, 11, 9, 9, 7, 7, 6, 6, 5, 5, 5, 5, 4, 4 }; #endif int main(void){ int t; int n; ALLOC_STACK; for(t=0;tpkmax[t])break; printf("Testing CWRS with N=%i, K=%i...\n",n,k); #if defined(SMALL_FOOTPRINT) nc=ncwrs_urow(n,k,uu); #else nc=CELT_PVQ_V(n,k); #endif inc=nc/20000; if(inc<1)inc=1; for(i=0;i");*/ #if defined(SMALL_FOOTPRINT) ii=icwrs(n,k,&v,y,u); #else ii=icwrs(n,y); v=CELT_PVQ_V(n,k); #endif if(ii!=i){ fprintf(stderr,"Combination-index mismatch (%lu!=%lu).\n", (long)ii,(long)i); return 1; } if(v!=nc){ fprintf(stderr,"Combination count mismatch (%lu!=%lu).\n", (long)v,(long)nc); return 2; } /*printf(" %6u\n",i);*/ } /*printf("\n");*/ } } return 0; } jamulus-3.9.1+dfsg/libs/opus/celt/tests/test_unit_rotation.c0000644000175000017500000000504014340334543023264 0ustar vimervimer/* Copyright (c) 2008-2011 Xiph.Org Foundation Written by Jean-Marc Valin */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifndef CUSTOM_MODES #define CUSTOM_MODES #endif #include #include #include "vq.h" #include "bands.h" #include "stack_alloc.h" #include #define MAX_SIZE 100 int ret=0; void test_rotation(int N, int K) { int i; double err = 0, ener = 0, snr, snr0; opus_val16 x0[MAX_SIZE]; opus_val16 x1[MAX_SIZE]; for (i=0;i 20) { fprintf(stderr, "FAIL!\n"); ret = 1; } } int main(void) { ALLOC_STACK; test_rotation(15, 3); test_rotation(23, 5); test_rotation(50, 3); test_rotation(80, 1); return ret; } jamulus-3.9.1+dfsg/libs/opus/celt/tests/test_unit_types.c0000644000175000017500000000333014340334543022571 0ustar vimervimer/* Copyright (c) 2008-2011 Xiph.Org Foundation Written by Jean-Marc Valin */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "opus_types.h" #include int main(void) { opus_int16 i = 1; i <<= 14; if (i>>14 != 1) { fprintf(stderr, "opus_int16 isn't 16 bits\n"); return 1; } if (sizeof(opus_int16)*2 != sizeof(opus_int32)) { fprintf(stderr, "16*2 != 32\n"); return 1; } return 0; } jamulus-3.9.1+dfsg/libs/opus/celt/celt_encoder.c0000644000175000017500000024672114340334543020630 0ustar vimervimer/* Copyright (c) 2007-2008 CSIRO Copyright (c) 2007-2010 Xiph.Org Foundation Copyright (c) 2008 Gregory Maxwell Written by Jean-Marc Valin and Gregory Maxwell */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define CELT_ENCODER_C #include "cpu_support.h" #include "os_support.h" #include "mdct.h" #include #include "celt.h" #include "pitch.h" #include "bands.h" #include "modes.h" #include "entcode.h" #include "quant_bands.h" #include "rate.h" #include "stack_alloc.h" #include "mathops.h" #include "float_cast.h" #include #include "celt_lpc.h" #include "vq.h" /** Encoder state @brief Encoder state */ struct OpusCustomEncoder { const OpusCustomMode *mode; /**< Mode used by the encoder */ int channels; int stream_channels; int force_intra; int clip; int disable_pf; int complexity; int upsample; int start, end; opus_int32 bitrate; int vbr; int signalling; int constrained_vbr; /* If zero, VBR can do whatever it likes with the rate */ int loss_rate; int lsb_depth; int lfe; int disable_inv; int arch; /* Everything beyond this point gets cleared on a reset */ #define ENCODER_RESET_START rng opus_uint32 rng; int spread_decision; opus_val32 delayedIntra; int tonal_average; int lastCodedBands; int hf_average; int tapset_decision; int prefilter_period; opus_val16 prefilter_gain; int prefilter_tapset; #ifdef RESYNTH int prefilter_period_old; opus_val16 prefilter_gain_old; int prefilter_tapset_old; #endif int consec_transient; AnalysisInfo analysis; SILKInfo silk_info; opus_val32 preemph_memE[2]; opus_val32 preemph_memD[2]; /* VBR-related parameters */ opus_int32 vbr_reservoir; opus_int32 vbr_drift; opus_int32 vbr_offset; opus_int32 vbr_count; opus_val32 overlap_max; opus_val16 stereo_saving; int intensity; opus_val16 *energy_mask; opus_val16 spec_avg; #ifdef RESYNTH /* +MAX_PERIOD/2 to make space for overlap */ celt_sig syn_mem[2][2*MAX_PERIOD+MAX_PERIOD/2]; #endif celt_sig in_mem[1]; /* Size = channels*mode->overlap */ /* celt_sig prefilter_mem[], Size = channels*COMBFILTER_MAXPERIOD */ /* opus_val16 oldBandE[], Size = channels*mode->nbEBands */ /* opus_val16 oldLogE[], Size = channels*mode->nbEBands */ /* opus_val16 oldLogE2[], Size = channels*mode->nbEBands */ /* opus_val16 energyError[], Size = channels*mode->nbEBands */ }; int celt_encoder_get_size(int channels) { CELTMode *mode = opus_custom_mode_create(48000, 960, NULL); return opus_custom_encoder_get_size(mode, channels); } OPUS_CUSTOM_NOSTATIC int opus_custom_encoder_get_size(const CELTMode *mode, int channels) { int size = sizeof(struct CELTEncoder) + (channels*mode->overlap-1)*sizeof(celt_sig) /* celt_sig in_mem[channels*mode->overlap]; */ + channels*COMBFILTER_MAXPERIOD*sizeof(celt_sig) /* celt_sig prefilter_mem[channels*COMBFILTER_MAXPERIOD]; */ + 4*channels*mode->nbEBands*sizeof(opus_val16); /* opus_val16 oldBandE[channels*mode->nbEBands]; */ /* opus_val16 oldLogE[channels*mode->nbEBands]; */ /* opus_val16 oldLogE2[channels*mode->nbEBands]; */ /* opus_val16 energyError[channels*mode->nbEBands]; */ return size; } #ifdef CUSTOM_MODES CELTEncoder *opus_custom_encoder_create(const CELTMode *mode, int channels, int *error) { int ret; CELTEncoder *st = (CELTEncoder *)opus_alloc(opus_custom_encoder_get_size(mode, channels)); /* init will handle the NULL case */ ret = opus_custom_encoder_init(st, mode, channels); if (ret != OPUS_OK) { opus_custom_encoder_destroy(st); st = NULL; } if (error) *error = ret; return st; } #endif /* CUSTOM_MODES */ static int opus_custom_encoder_init_arch(CELTEncoder *st, const CELTMode *mode, int channels, int arch) { if (channels < 0 || channels > 2) return OPUS_BAD_ARG; if (st==NULL || mode==NULL) return OPUS_ALLOC_FAIL; OPUS_CLEAR((char*)st, opus_custom_encoder_get_size(mode, channels)); st->mode = mode; st->stream_channels = st->channels = channels; st->upsample = 1; st->start = 0; st->end = st->mode->effEBands; st->signalling = 1; st->arch = arch; st->constrained_vbr = 1; st->clip = 1; st->bitrate = OPUS_BITRATE_MAX; st->vbr = 0; st->force_intra = 0; st->complexity = 5; st->lsb_depth=24; opus_custom_encoder_ctl(st, OPUS_RESET_STATE); return OPUS_OK; } #ifdef CUSTOM_MODES int opus_custom_encoder_init(CELTEncoder *st, const CELTMode *mode, int channels) { return opus_custom_encoder_init_arch(st, mode, channels, opus_select_arch()); } #endif int celt_encoder_init(CELTEncoder *st, opus_int32 sampling_rate, int channels, int arch) { int ret; ret = opus_custom_encoder_init_arch(st, opus_custom_mode_create(48000, 960, NULL), channels, arch); if (ret != OPUS_OK) return ret; st->upsample = resampling_factor(sampling_rate); return OPUS_OK; } #ifdef CUSTOM_MODES void opus_custom_encoder_destroy(CELTEncoder *st) { opus_free(st); } #endif /* CUSTOM_MODES */ static int transient_analysis(const opus_val32 * OPUS_RESTRICT in, int len, int C, opus_val16 *tf_estimate, int *tf_chan, int allow_weak_transients, int *weak_transient) { int i; VARDECL(opus_val16, tmp); opus_val32 mem0,mem1; int is_transient = 0; opus_int32 mask_metric = 0; int c; opus_val16 tf_max; int len2; /* Forward masking: 6.7 dB/ms. */ #ifdef FIXED_POINT int forward_shift = 4; #else opus_val16 forward_decay = QCONST16(.0625f,15); #endif /* Table of 6*64/x, trained on real data to minimize the average error */ static const unsigned char inv_table[128] = { 255,255,156,110, 86, 70, 59, 51, 45, 40, 37, 33, 31, 28, 26, 25, 23, 22, 21, 20, 19, 18, 17, 16, 16, 15, 15, 14, 13, 13, 12, 12, 12, 12, 11, 11, 11, 10, 10, 10, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, }; SAVE_STACK; ALLOC(tmp, len, opus_val16); *weak_transient = 0; /* For lower bitrates, let's be more conservative and have a forward masking decay of 3.3 dB/ms. This avoids having to code transients at very low bitrate (mostly for hybrid), which can result in unstable energy and/or partial collapse. */ if (allow_weak_transients) { #ifdef FIXED_POINT forward_shift = 5; #else forward_decay = QCONST16(.03125f,15); #endif } len2=len/2; for (c=0;c=0;i--) { /* Backward masking: 13.9 dB/ms. */ #ifdef FIXED_POINT /* FIXME: Use PSHR16() instead */ tmp[i] = mem0 + PSHR32(tmp[i]-mem0,3); #else tmp[i] = mem0 + MULT16_16_P15(QCONST16(0.125f,15),tmp[i]-mem0); #endif mem0 = tmp[i]; maxE = MAX16(maxE, mem0); } /*for (i=0;i>1))); #else mean = celt_sqrt(mean * maxE*.5*len2); #endif /* Inverse of the mean energy in Q15+6 */ norm = SHL32(EXTEND32(len2),6+14)/ADD32(EPSILON,SHR32(mean,1)); /* Compute harmonic mean discarding the unreliable boundaries The data is smooth, so we only take 1/4th of the samples */ unmask=0; /* We should never see NaNs here. If we find any, then something really bad happened and we better abort before it does any damage later on. If these asserts are disabled (no hardening), then the table lookup a few lines below (id = ...) is likely to crash due to an out-of-bounds read. DO NOT FIX that crash on NaN since it could result in a worse issue later on. */ celt_assert(!celt_isnan(tmp[0])); celt_assert(!celt_isnan(norm)); for (i=12;imask_metric) { *tf_chan = c; mask_metric = unmask; } } is_transient = mask_metric>200; /* For low bitrates, define "weak transients" that need to be handled differently to avoid partial collapse. */ if (allow_weak_transients && is_transient && mask_metric<600) { is_transient = 0; *weak_transient = 1; } /* Arbitrary metric for VBR boost */ tf_max = MAX16(0,celt_sqrt(27*mask_metric)-42); /* *tf_estimate = 1 + MIN16(1, sqrt(MAX16(0, tf_max-30))/20); */ *tf_estimate = celt_sqrt(MAX32(0, SHL32(MULT16_16(QCONST16(0.0069,14),MIN16(163,tf_max)),14)-QCONST32(0.139,28))); /*printf("%d %f\n", tf_max, mask_metric);*/ RESTORE_STACK; #ifdef FUZZING is_transient = rand()&0x1; #endif /*printf("%d %f %d\n", is_transient, (float)*tf_estimate, tf_max);*/ return is_transient; } /* Looks for sudden increases of energy to decide whether we need to patch the transient decision */ static int patch_transient_decision(opus_val16 *newE, opus_val16 *oldE, int nbEBands, int start, int end, int C) { int i, c; opus_val32 mean_diff=0; opus_val16 spread_old[26]; /* Apply an aggressive (-6 dB/Bark) spreading function to the old frame to avoid false detection caused by irrelevant bands */ if (C==1) { spread_old[start] = oldE[start]; for (i=start+1;i=start;i--) spread_old[i] = MAX16(spread_old[i], spread_old[i+1]-QCONST16(1.0f, DB_SHIFT)); /* Compute mean increase */ c=0; do { for (i=IMAX(2,start);i QCONST16(1.f, DB_SHIFT); } /** Apply window and compute the MDCT for all sub-frames and all channels in a frame */ static void compute_mdcts(const CELTMode *mode, int shortBlocks, celt_sig * OPUS_RESTRICT in, celt_sig * OPUS_RESTRICT out, int C, int CC, int LM, int upsample, int arch) { const int overlap = mode->overlap; int N; int B; int shift; int i, b, c; if (shortBlocks) { B = shortBlocks; N = mode->shortMdctSize; shift = mode->maxLM; } else { B = 1; N = mode->shortMdctSize<maxLM-LM; } c=0; do { for (b=0;bmdct, in+c*(B*N+overlap)+b*N, &out[b+c*N*B], mode->window, overlap, shift, B, arch); } } while (++ceBands[len]-m->eBands[len-1])<eBands[len]-m->eBands[len-1])<eBands[i+1]-m->eBands[i])<eBands[i+1]-m->eBands[i])==1; OPUS_COPY(tmp, &X[tf_chan*N0 + (m->eBands[i]<eBands[i]<>LM, 1<>k, 1<=0;i--) { if (tf_res[i+1] == 1) tf_res[i] = path1[i+1]; else tf_res[i] = path0[i+1]; } /*printf("%d %f\n", *tf_sum, tf_estimate);*/ RESTORE_STACK; #ifdef FUZZING tf_select = rand()&0x1; tf_res[0] = rand()&0x1; for (i=1;istorage*8; tell = ec_tell(enc); logp = isTransient ? 2 : 4; /* Reserve space to code the tf_select decision. */ tf_select_rsv = LM>0 && tell+logp+1 <= budget; budget -= tf_select_rsv; curr = tf_changed = 0; for (i=start;i> 10; trim = QCONST16(4.f, 8) + QCONST16(1.f/16.f, 8)*frac; } if (C==2) { opus_val16 sum = 0; /* Q10 */ opus_val16 minXC; /* Q10 */ /* Compute inter-channel correlation for low frequencies */ for (i=0;i<8;i++) { opus_val32 partial; partial = celt_inner_prod(&X[m->eBands[i]<eBands[i]<eBands[i+1]-m->eBands[i])<eBands[i]<eBands[i]<eBands[i+1]-m->eBands[i])<nbEBands]*(opus_int32)(2+2*i-end); } } while (++cvalid) { trim -= MAX16(-QCONST16(2.f, 8), MIN16(QCONST16(2.f, 8), (opus_val16)(QCONST16(2.f, 8)*(analysis->tonality_slope+.05f)))); } #else (void)analysis; #endif #ifdef FIXED_POINT trim_index = PSHR32(trim, 8); #else trim_index = (int)floor(.5f+trim); #endif trim_index = IMAX(0, IMIN(10, trim_index)); /*printf("%d\n", trim_index);*/ #ifdef FUZZING trim_index = rand()%11; #endif return trim_index; } static int stereo_analysis(const CELTMode *m, const celt_norm *X, int LM, int N0) { int i; int thetas; opus_val32 sumLR = EPSILON, sumMS = EPSILON; /* Use the L1 norm to model the entropy of the L/R signal vs the M/S signal */ for (i=0;i<13;i++) { int j; for (j=m->eBands[i]<eBands[i+1]<eBands[13]<<(LM+1))+thetas, sumMS) > MULT16_32_Q15(m->eBands[13]<<(LM+1), sumLR); } #define MSWAP(a,b) do {opus_val16 tmp = a;a=b;b=tmp;} while(0) static opus_val16 median_of_5(const opus_val16 *x) { opus_val16 t0, t1, t2, t3, t4; t2 = x[2]; if (x[0] > x[1]) { t0 = x[1]; t1 = x[0]; } else { t0 = x[0]; t1 = x[1]; } if (x[3] > x[4]) { t3 = x[4]; t4 = x[3]; } else { t3 = x[3]; t4 = x[4]; } if (t0 > t3) { MSWAP(t0, t3); MSWAP(t1, t4); } if (t2 > t1) { if (t1 < t3) return MIN16(t2, t3); else return MIN16(t4, t1); } else { if (t2 < t3) return MIN16(t1, t3); else return MIN16(t2, t4); } } static opus_val16 median_of_3(const opus_val16 *x) { opus_val16 t0, t1, t2; if (x[0] > x[1]) { t0 = x[1]; t1 = x[0]; } else { t0 = x[0]; t1 = x[1]; } t2 = x[2]; if (t1 < t2) return t1; else if (t0 < t2) return t2; else return t0; } static opus_val16 dynalloc_analysis(const opus_val16 *bandLogE, const opus_val16 *bandLogE2, int nbEBands, int start, int end, int C, int *offsets, int lsb_depth, const opus_int16 *logN, int isTransient, int vbr, int constrained_vbr, const opus_int16 *eBands, int LM, int effectiveBytes, opus_int32 *tot_boost_, int lfe, opus_val16 *surround_dynalloc, AnalysisInfo *analysis, int *importance, int *spread_weight) { int i, c; opus_int32 tot_boost=0; opus_val16 maxDepth; VARDECL(opus_val16, follower); VARDECL(opus_val16, noise_floor); SAVE_STACK; ALLOC(follower, C*nbEBands, opus_val16); ALLOC(noise_floor, C*nbEBands, opus_val16); OPUS_CLEAR(offsets, nbEBands); /* Dynamic allocation code */ maxDepth=-QCONST16(31.9f, DB_SHIFT); for (i=0;i=0;i--) mask[i] = MAX16(mask[i], mask[i+1] - QCONST16(3.f, DB_SHIFT)); for (i=0;i> shift; } /*for (i=0;i 50 && LM>=1 && !lfe) { int last=0; c=0;do { opus_val16 offset; opus_val16 tmp; opus_val16 *f; f = &follower[c*nbEBands]; f[0] = bandLogE2[c*nbEBands]; for (i=1;i bandLogE2[c*nbEBands+i-1]+QCONST16(.5f,DB_SHIFT)) last=i; f[i] = MIN16(f[i-1]+QCONST16(1.5f,DB_SHIFT), bandLogE2[c*nbEBands+i]); } for (i=last-1;i>=0;i--) f[i] = MIN16(f[i], MIN16(f[i+1]+QCONST16(2.f,DB_SHIFT), bandLogE2[c*nbEBands+i])); /* Combine with a median filter to avoid dynalloc triggering unnecessarily. The "offset" value controls how conservative we are -- a higher offset reduces the impact of the median filter and makes dynalloc use more bits. */ offset = QCONST16(1.f, DB_SHIFT); for (i=2;i=12) follower[i] = HALF16(follower[i]); } #ifdef DISABLE_FLOAT_API (void)analysis; #else if (analysis->valid) { for (i=start;ileak_boost[i]; } #endif for (i=start;i 48) { boost = (int)SHR32(EXTEND32(follower[i])*8,DB_SHIFT); boost_bits = (boost*width<>BITRES>>3 > 2*effectiveBytes/3) { opus_int32 cap = ((2*effectiveBytes/3)<mode; overlap = mode->overlap; ALLOC(_pre, CC*(N+COMBFILTER_MAXPERIOD), celt_sig); pre[0] = _pre; pre[1] = _pre + (N+COMBFILTER_MAXPERIOD); c=0; do { OPUS_COPY(pre[c], prefilter_mem+c*COMBFILTER_MAXPERIOD, COMBFILTER_MAXPERIOD); OPUS_COPY(pre[c]+COMBFILTER_MAXPERIOD, in+c*(N+overlap)+overlap, N); } while (++c>1, opus_val16); pitch_downsample(pre, pitch_buf, COMBFILTER_MAXPERIOD+N, CC, st->arch); /* Don't search for the fir last 1.5 octave of the range because there's too many false-positives due to short-term correlation */ pitch_search(pitch_buf+(COMBFILTER_MAXPERIOD>>1), pitch_buf, N, COMBFILTER_MAXPERIOD-3*COMBFILTER_MINPERIOD, &pitch_index, st->arch); pitch_index = COMBFILTER_MAXPERIOD-pitch_index; gain1 = remove_doubling(pitch_buf, COMBFILTER_MAXPERIOD, COMBFILTER_MINPERIOD, N, &pitch_index, st->prefilter_period, st->prefilter_gain, st->arch); if (pitch_index > COMBFILTER_MAXPERIOD-2) pitch_index = COMBFILTER_MAXPERIOD-2; gain1 = MULT16_16_Q15(QCONST16(.7f,15),gain1); /*printf("%d %d %f %f\n", pitch_change, pitch_index, gain1, st->analysis.tonality);*/ if (st->loss_rate>2) gain1 = HALF32(gain1); if (st->loss_rate>4) gain1 = HALF32(gain1); if (st->loss_rate>8) gain1 = 0; } else { gain1 = 0; pitch_index = COMBFILTER_MINPERIOD; } #ifndef DISABLE_FLOAT_API if (analysis->valid) gain1 = (opus_val16)(gain1 * analysis->max_pitch_ratio); #else (void)analysis; #endif /* Gain threshold for enabling the prefilter/postfilter */ pf_threshold = QCONST16(.2f,15); /* Adjusting the threshold based on rate and continuity */ if (abs(pitch_index-st->prefilter_period)*10>pitch_index) pf_threshold += QCONST16(.2f,15); if (nbAvailableBytes<25) pf_threshold += QCONST16(.1f,15); if (nbAvailableBytes<35) pf_threshold += QCONST16(.1f,15); if (st->prefilter_gain > QCONST16(.4f,15)) pf_threshold -= QCONST16(.1f,15); if (st->prefilter_gain > QCONST16(.55f,15)) pf_threshold -= QCONST16(.1f,15); /* Hard threshold at 0.2 */ pf_threshold = MAX16(pf_threshold, QCONST16(.2f,15)); if (gain1prefilter_gain)prefilter_gain; #ifdef FIXED_POINT qg = ((gain1+1536)>>10)/3-1; #else qg = (int)floor(.5f+gain1*32/3)-1; #endif qg = IMAX(0, IMIN(7, qg)); gain1 = QCONST16(0.09375f,15)*(qg+1); pf_on = 1; } /*printf("%d %f\n", pitch_index, gain1);*/ c=0; do { int offset = mode->shortMdctSize-overlap; st->prefilter_period=IMAX(st->prefilter_period, COMBFILTER_MINPERIOD); OPUS_COPY(in+c*(N+overlap), st->in_mem+c*(overlap), overlap); if (offset) comb_filter(in+c*(N+overlap)+overlap, pre[c]+COMBFILTER_MAXPERIOD, st->prefilter_period, st->prefilter_period, offset, -st->prefilter_gain, -st->prefilter_gain, st->prefilter_tapset, st->prefilter_tapset, NULL, 0, st->arch); comb_filter(in+c*(N+overlap)+overlap+offset, pre[c]+COMBFILTER_MAXPERIOD+offset, st->prefilter_period, pitch_index, N-offset, -st->prefilter_gain, -gain1, st->prefilter_tapset, prefilter_tapset, mode->window, overlap, st->arch); OPUS_COPY(st->in_mem+c*(overlap), in+c*(N+overlap)+N, overlap); if (N>COMBFILTER_MAXPERIOD) { OPUS_COPY(prefilter_mem+c*COMBFILTER_MAXPERIOD, pre[c]+N, COMBFILTER_MAXPERIOD); } else { OPUS_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD, prefilter_mem+c*COMBFILTER_MAXPERIOD+N, COMBFILTER_MAXPERIOD-N); OPUS_COPY(prefilter_mem+c*COMBFILTER_MAXPERIOD+COMBFILTER_MAXPERIOD-N, pre[c]+COMBFILTER_MAXPERIOD, N); } } while (++cnbEBands; eBands = mode->eBands; coded_bands = lastCodedBands ? lastCodedBands : nbEBands; coded_bins = eBands[coded_bands]<analysis.activity, st->analysis.tonality, tf_estimate, st->stereo_saving, tot_boost, coded_bands);*/ #ifndef DISABLE_FLOAT_API if (analysis->valid && analysis->activity<.4) target -= (opus_int32)((coded_bins<activity)); #endif /* Stereo savings */ if (C==2) { int coded_stereo_bands; int coded_stereo_dof; opus_val16 max_frac; coded_stereo_bands = IMIN(intensity, coded_bands); coded_stereo_dof = (eBands[coded_stereo_bands]<valid && !lfe) { opus_int32 tonal_target; float tonal; /* Tonality boost (compensating for the average). */ tonal = MAX16(0.f,analysis->tonality-.15f)-0.12f; tonal_target = target + (opus_int32)((coded_bins<tonality, tonal);*/ target = tonal_target; } #else (void)analysis; (void)pitch_change; #endif if (has_surround_mask&&!lfe) { opus_int32 surround_target = target + (opus_int32)SHR32(MULT16_16(surround_masking,coded_bins<end, st->intensity, surround_target, target, st->bitrate);*/ target = IMAX(target/4, surround_target); } { opus_int32 floor_depth; int bins; bins = eBands[nbEBands-2]<>2); target = IMIN(target, floor_depth); /*printf("%f %d\n", maxDepth, floor_depth);*/ } /* Make VBR less aggressive for constrained VBR because we can't keep a higher bitrate for long. Needs tuning. */ if ((!has_surround_mask||lfe) && constrained_vbr) { target = base_target + (opus_int32)MULT16_32_Q15(QCONST16(0.67f, 15), target-base_target); } if (!has_surround_mask && tf_estimate < QCONST16(.2f, 14)) { opus_val16 amount; opus_val16 tvbr_factor; amount = MULT16_16_Q15(QCONST16(.0000031f, 30), IMAX(0, IMIN(32000, 96000-bitrate))); tvbr_factor = SHR32(MULT16_16(temporal_vbr, amount), DB_SHIFT); target += (opus_int32)MULT16_32_Q15(tvbr_factor, target); } /* Don't allow more than doubling the rate */ target = IMIN(2*base_target, target); return target; } int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc) { int i, c, N; opus_int32 bits; ec_enc _enc; VARDECL(celt_sig, in); VARDECL(celt_sig, freq); VARDECL(celt_norm, X); VARDECL(celt_ener, bandE); VARDECL(opus_val16, bandLogE); VARDECL(opus_val16, bandLogE2); VARDECL(int, fine_quant); VARDECL(opus_val16, error); VARDECL(int, pulses); VARDECL(int, cap); VARDECL(int, offsets); VARDECL(int, importance); VARDECL(int, spread_weight); VARDECL(int, fine_priority); VARDECL(int, tf_res); VARDECL(unsigned char, collapse_masks); celt_sig *prefilter_mem; opus_val16 *oldBandE, *oldLogE, *oldLogE2, *energyError; int shortBlocks=0; int isTransient=0; const int CC = st->channels; const int C = st->stream_channels; int LM, M; int tf_select; int nbFilledBytes, nbAvailableBytes; int start; int end; int effEnd; int codedBands; int alloc_trim; int pitch_index=COMBFILTER_MINPERIOD; opus_val16 gain1 = 0; int dual_stereo=0; int effectiveBytes; int dynalloc_logp; opus_int32 vbr_rate; opus_int32 total_bits; opus_int32 total_boost; opus_int32 balance; opus_int32 tell; opus_int32 tell0_frac; int prefilter_tapset=0; int pf_on; int anti_collapse_rsv; int anti_collapse_on=0; int silence=0; int tf_chan = 0; opus_val16 tf_estimate; int pitch_change=0; opus_int32 tot_boost; opus_val32 sample_max; opus_val16 maxDepth; const OpusCustomMode *mode; int nbEBands; int overlap; const opus_int16 *eBands; int secondMdct; int signalBandwidth; int transient_got_disabled=0; opus_val16 surround_masking=0; opus_val16 temporal_vbr=0; opus_val16 surround_trim = 0; opus_int32 equiv_rate; int hybrid; int weak_transient = 0; int enable_tf_analysis; VARDECL(opus_val16, surround_dynalloc); ALLOC_STACK; mode = st->mode; nbEBands = mode->nbEBands; overlap = mode->overlap; eBands = mode->eBands; start = st->start; end = st->end; hybrid = start != 0; tf_estimate = 0; if (nbCompressedBytes<2 || pcm==NULL) { RESTORE_STACK; return OPUS_BAD_ARG; } frame_size *= st->upsample; for (LM=0;LM<=mode->maxLM;LM++) if (mode->shortMdctSize<mode->maxLM) { RESTORE_STACK; return OPUS_BAD_ARG; } M=1<shortMdctSize; prefilter_mem = st->in_mem+CC*(overlap); oldBandE = (opus_val16*)(st->in_mem+CC*(overlap+COMBFILTER_MAXPERIOD)); oldLogE = oldBandE + CC*nbEBands; oldLogE2 = oldLogE + CC*nbEBands; energyError = oldLogE2 + CC*nbEBands; if (enc==NULL) { tell0_frac=tell=1; nbFilledBytes=0; } else { tell0_frac=ec_tell_frac(enc); tell=ec_tell(enc); nbFilledBytes=(tell+4)>>3; } #ifdef CUSTOM_MODES if (st->signalling && enc==NULL) { int tmp = (mode->effEBands-end)>>1; end = st->end = IMAX(1, mode->effEBands-tmp); compressed[0] = tmp<<5; compressed[0] |= LM<<3; compressed[0] |= (C==2)<<2; /* Convert "standard mode" to Opus header */ if (mode->Fs==48000 && mode->shortMdctSize==120) { int c0 = toOpus(compressed[0]); if (c0<0) { RESTORE_STACK; return OPUS_BAD_ARG; } compressed[0] = c0; } compressed++; nbCompressedBytes--; } #else celt_assert(st->signalling==0); #endif /* Can't produce more than 1275 output bytes */ nbCompressedBytes = IMIN(nbCompressedBytes,1275); nbAvailableBytes = nbCompressedBytes - nbFilledBytes; if (st->vbr && st->bitrate!=OPUS_BITRATE_MAX) { opus_int32 den=mode->Fs>>BITRES; vbr_rate=(st->bitrate*frame_size+(den>>1))/den; #ifdef CUSTOM_MODES if (st->signalling) vbr_rate -= 8<>(3+BITRES); } else { opus_int32 tmp; vbr_rate = 0; tmp = st->bitrate*frame_size; if (tell>1) tmp += tell; if (st->bitrate!=OPUS_BITRATE_MAX) nbCompressedBytes = IMAX(2, IMIN(nbCompressedBytes, (tmp+4*mode->Fs)/(8*mode->Fs)-!!st->signalling)); effectiveBytes = nbCompressedBytes - nbFilledBytes; } equiv_rate = ((opus_int32)nbCompressedBytes*8*50 << (3-LM)) - (40*C+20)*((400>>LM) - 50); if (st->bitrate != OPUS_BITRATE_MAX) equiv_rate = IMIN(equiv_rate, st->bitrate - (40*C+20)*((400>>LM) - 50)); if (enc==NULL) { ec_enc_init(&_enc, compressed, nbCompressedBytes); enc = &_enc; } if (vbr_rate>0) { /* Computes the max bit-rate allowed in VBR mode to avoid violating the target rate and buffering. We must do this up front so that bust-prevention logic triggers correctly if we don't have enough bits. */ if (st->constrained_vbr) { opus_int32 vbr_bound; opus_int32 max_allowed; /* We could use any multiple of vbr_rate as bound (depending on the delay). This is clamped to ensure we use at least two bytes if the encoder was entirely empty, but to allow 0 in hybrid mode. */ vbr_bound = vbr_rate; max_allowed = IMIN(IMAX(tell==1?2:0, (vbr_rate+vbr_bound-st->vbr_reservoir)>>(BITRES+3)), nbAvailableBytes); if(max_allowed < nbAvailableBytes) { nbCompressedBytes = nbFilledBytes+max_allowed; nbAvailableBytes = max_allowed; ec_enc_shrink(enc, nbCompressedBytes); } } } total_bits = nbCompressedBytes*8; effEnd = end; if (effEnd > mode->effEBands) effEnd = mode->effEBands; ALLOC(in, CC*(N+overlap), celt_sig); sample_max=MAX32(st->overlap_max, celt_maxabs16(pcm, C*(N-overlap)/st->upsample)); st->overlap_max=celt_maxabs16(pcm+C*(N-overlap)/st->upsample, C*overlap/st->upsample); sample_max=MAX32(sample_max, st->overlap_max); #ifdef FIXED_POINT silence = (sample_max==0); #else silence = (sample_max <= (opus_val16)1/(1<lsb_depth)); #endif #ifdef FUZZING if ((rand()&0x3F)==0) silence = 1; #endif if (tell==1) ec_enc_bit_logp(enc, silence, 15); else silence=0; if (silence) { /*In VBR mode there is no need to send more than the minimum. */ if (vbr_rate>0) { effectiveBytes=nbCompressedBytes=IMIN(nbCompressedBytes, nbFilledBytes+2); total_bits=nbCompressedBytes*8; nbAvailableBytes=2; ec_enc_shrink(enc, nbCompressedBytes); } /* Pretend we've filled all the remaining bits with zeros (that's what the initialiser did anyway) */ tell = nbCompressedBytes*8; enc->nbits_total+=tell-ec_tell(enc); } c=0; do { int need_clip=0; #ifndef FIXED_POINT need_clip = st->clip && sample_max>65536.f; #endif celt_preemphasis(pcm+c, in+c*(N+overlap)+overlap, N, CC, st->upsample, mode->preemph, st->preemph_memE+c, need_clip); } while (++clfe&&nbAvailableBytes>3) || nbAvailableBytes>12*C) && !hybrid && !silence && !st->disable_pf && st->complexity >= 5; prefilter_tapset = st->tapset_decision; pf_on = run_prefilter(st, in, prefilter_mem, CC, N, prefilter_tapset, &pitch_index, &gain1, &qg, enabled, nbAvailableBytes, &st->analysis); if ((gain1 > QCONST16(.4f,15) || st->prefilter_gain > QCONST16(.4f,15)) && (!st->analysis.valid || st->analysis.tonality > .3) && (pitch_index > 1.26*st->prefilter_period || pitch_index < .79*st->prefilter_period)) pitch_change = 1; if (pf_on==0) { if(!hybrid && tell+16<=total_bits) ec_enc_bit_logp(enc, 0, 1); } else { /*This block is not gated by a total bits check only because of the nbAvailableBytes check above.*/ int octave; ec_enc_bit_logp(enc, 1, 1); pitch_index += 1; octave = EC_ILOG(pitch_index)-5; ec_enc_uint(enc, octave, 6); ec_enc_bits(enc, pitch_index-(16<complexity >= 1 && !st->lfe) { /* Reduces the likelihood of energy instability on fricatives at low bitrate in hybrid mode. It seems like we still want to have real transients on vowels though (small SILK quantization offset value). */ int allow_weak_transients = hybrid && effectiveBytes<15 && st->silk_info.signalType != 2; isTransient = transient_analysis(in, N+overlap, CC, &tf_estimate, &tf_chan, allow_weak_transients, &weak_transient); } if (LM>0 && ec_tell(enc)+3<=total_bits) { if (isTransient) shortBlocks = M; } else { isTransient = 0; transient_got_disabled=1; } ALLOC(freq, CC*N, celt_sig); /**< Interleaved signal MDCTs */ ALLOC(bandE,nbEBands*CC, celt_ener); ALLOC(bandLogE,nbEBands*CC, opus_val16); secondMdct = shortBlocks && st->complexity>=8; ALLOC(bandLogE2, C*nbEBands, opus_val16); if (secondMdct) { compute_mdcts(mode, 0, in, freq, C, CC, LM, st->upsample, st->arch); compute_band_energies(mode, freq, bandE, effEnd, C, LM, st->arch); amp2Log2(mode, effEnd, end, bandE, bandLogE2, C); for (i=0;iupsample, st->arch); /* This should catch any NaN in the CELT input. Since we're not supposed to see any (they're filtered at the Opus layer), just abort. */ celt_assert(!celt_isnan(freq[0]) && (C==1 || !celt_isnan(freq[N]))); if (CC==2&&C==1) tf_chan = 0; compute_band_energies(mode, freq, bandE, effEnd, C, LM, st->arch); if (st->lfe) { for (i=2;ienergy_mask&&!st->lfe) { int mask_end; int midband; int count_dynalloc; opus_val32 mask_avg=0; opus_val32 diff=0; int count=0; mask_end = IMAX(2,st->lastCodedBands); for (c=0;cenergy_mask[nbEBands*c+i], QCONST16(.25f, DB_SHIFT)), -QCONST16(2.0f, DB_SHIFT)); if (mask > 0) mask = HALF16(mask); mask_avg += MULT16_16(mask, eBands[i+1]-eBands[i]); count += eBands[i+1]-eBands[i]; diff += MULT16_16(mask, 1+2*i-mask_end); } } celt_assert(count>0); mask_avg = DIV32_16(mask_avg,count); mask_avg += QCONST16(.2f, DB_SHIFT); diff = diff*6/(C*(mask_end-1)*(mask_end+1)*mask_end); /* Again, being conservative */ diff = HALF32(diff); diff = MAX32(MIN32(diff, QCONST32(.031f, DB_SHIFT)), -QCONST32(.031f, DB_SHIFT)); /* Find the band that's in the middle of the coded spectrum */ for (midband=0;eBands[midband+1] < eBands[mask_end]/2;midband++); count_dynalloc=0; for(i=0;ienergy_mask[i], st->energy_mask[nbEBands+i]); else unmask = st->energy_mask[i]; unmask = MIN16(unmask, QCONST16(.0f, DB_SHIFT)); unmask -= lin; if (unmask > QCONST16(.25f, DB_SHIFT)) { surround_dynalloc[i] = unmask - QCONST16(.25f, DB_SHIFT); count_dynalloc++; } } if (count_dynalloc>=3) { /* If we need dynalloc in many bands, it's probably because our initial masking rate was too low. */ mask_avg += QCONST16(.25f, DB_SHIFT); if (mask_avg>0) { /* Something went really wrong in the original calculations, disabling masking. */ mask_avg = 0; diff = 0; OPUS_CLEAR(surround_dynalloc, mask_end); } else { for(i=0;ilfe) { opus_val16 follow=-QCONST16(10.0f,DB_SHIFT); opus_val32 frame_avg=0; opus_val16 offset = shortBlocks?HALF16(SHL16(LM, DB_SHIFT)):0; for(i=start;ispec_avg); temporal_vbr = MIN16(QCONST16(3.f, DB_SHIFT), MAX16(-QCONST16(1.5f, DB_SHIFT), temporal_vbr)); st->spec_avg += MULT16_16_Q15(QCONST16(.02f, 15), temporal_vbr); } /*for (i=0;i<21;i++) printf("%f ", bandLogE[i]); printf("\n");*/ if (!secondMdct) { OPUS_COPY(bandLogE2, bandLogE, C*nbEBands); } /* Last chance to catch any transient we might have missed in the time-domain analysis */ if (LM>0 && ec_tell(enc)+3<=total_bits && !isTransient && st->complexity>=5 && !st->lfe && !hybrid) { if (patch_transient_decision(bandLogE, oldBandE, nbEBands, start, end, C)) { isTransient = 1; shortBlocks = M; compute_mdcts(mode, shortBlocks, in, freq, C, CC, LM, st->upsample, st->arch); compute_band_energies(mode, freq, bandE, effEnd, C, LM, st->arch); amp2Log2(mode, effEnd, end, bandE, bandLogE, C); /* Compensate for the scaling of short vs long mdcts */ for (i=0;i0 && ec_tell(enc)+3<=total_bits) ec_enc_bit_logp(enc, isTransient, 3); ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */ /* Band normalisation */ normalise_bands(mode, freq, X, bandE, effEnd, C, M); enable_tf_analysis = effectiveBytes>=15*C && !hybrid && st->complexity>=2 && !st->lfe; ALLOC(offsets, nbEBands, int); ALLOC(importance, nbEBands, int); ALLOC(spread_weight, nbEBands, int); maxDepth = dynalloc_analysis(bandLogE, bandLogE2, nbEBands, start, end, C, offsets, st->lsb_depth, mode->logN, isTransient, st->vbr, st->constrained_vbr, eBands, LM, effectiveBytes, &tot_boost, st->lfe, surround_dynalloc, &st->analysis, importance, spread_weight); ALLOC(tf_res, nbEBands, int); /* Disable variable tf resolution for hybrid and at very low bitrate */ if (enable_tf_analysis) { int lambda; lambda = IMAX(80, 20480/effectiveBytes + 2); tf_select = tf_analysis(mode, effEnd, isTransient, tf_res, lambda, X, N, LM, tf_estimate, tf_chan, importance); for (i=effEnd;isilk_info.signalType != 2) { /* For low bitrate hybrid, we force temporal resolution to 5 ms rather than 2.5 ms. */ for (i=0;iforce_intra, &st->delayedIntra, st->complexity >= 4, st->loss_rate, st->lfe); tf_encode(start, end, isTransient, tf_res, LM, tf_select, enc); if (ec_tell(enc)+4<=total_bits) { if (st->lfe) { st->tapset_decision = 0; st->spread_decision = SPREAD_NORMAL; } else if (hybrid) { if (st->complexity == 0) st->spread_decision = SPREAD_NONE; else if (isTransient) st->spread_decision = SPREAD_NORMAL; else st->spread_decision = SPREAD_AGGRESSIVE; } else if (shortBlocks || st->complexity < 3 || nbAvailableBytes < 10*C) { if (st->complexity == 0) st->spread_decision = SPREAD_NONE; else st->spread_decision = SPREAD_NORMAL; } else { /* Disable new spreading+tapset estimator until we can show it works better than the old one. So far it seems like spreading_decision() works best. */ #if 0 if (st->analysis.valid) { static const opus_val16 spread_thresholds[3] = {-QCONST16(.6f, 15), -QCONST16(.2f, 15), -QCONST16(.07f, 15)}; static const opus_val16 spread_histeresis[3] = {QCONST16(.15f, 15), QCONST16(.07f, 15), QCONST16(.02f, 15)}; static const opus_val16 tapset_thresholds[2] = {QCONST16(.0f, 15), QCONST16(.15f, 15)}; static const opus_val16 tapset_histeresis[2] = {QCONST16(.1f, 15), QCONST16(.05f, 15)}; st->spread_decision = hysteresis_decision(-st->analysis.tonality, spread_thresholds, spread_histeresis, 3, st->spread_decision); st->tapset_decision = hysteresis_decision(st->analysis.tonality_slope, tapset_thresholds, tapset_histeresis, 2, st->tapset_decision); } else #endif { st->spread_decision = spreading_decision(mode, X, &st->tonal_average, st->spread_decision, &st->hf_average, &st->tapset_decision, pf_on&&!shortBlocks, effEnd, C, M, spread_weight); } /*printf("%d %d\n", st->tapset_decision, st->spread_decision);*/ /*printf("%f %d %f %d\n\n", st->analysis.tonality, st->spread_decision, st->analysis.tonality_slope, st->tapset_decision);*/ } ec_enc_icdf(enc, st->spread_decision, spread_icdf, 5); } /* For LFE, everything interesting is in the first band */ if (st->lfe) offsets[0] = IMIN(8, effectiveBytes/3); ALLOC(cap, nbEBands, int); init_caps(mode,cap,LM,C); dynalloc_logp = 6; total_bits<<=BITRES; total_boost = 0; tell = ec_tell_frac(enc); for (i=start;iintensity = hysteresis_decision((opus_val16)(equiv_rate/1000), intensity_thresholds, intensity_histeresis, 21, st->intensity); st->intensity = IMIN(end,IMAX(start, st->intensity)); } alloc_trim = 5; if (tell+(6< 0 || st->lfe) { st->stereo_saving = 0; alloc_trim = 5; } else { alloc_trim = alloc_trim_analysis(mode, X, bandLogE, end, LM, C, N, &st->analysis, &st->stereo_saving, tf_estimate, st->intensity, surround_trim, equiv_rate, st->arch); } ec_enc_icdf(enc, alloc_trim, trim_icdf, 7); tell = ec_tell_frac(enc); } /* Variable bitrate */ if (vbr_rate>0) { opus_val16 alpha; opus_int32 delta; /* The target rate in 8th bits per frame */ opus_int32 target, base_target; opus_int32 min_allowed; int lm_diff = mode->maxLM - LM; /* Don't attempt to use more than 510 kb/s, even for frames smaller than 20 ms. The CELT allocator will just not be able to use more than that anyway. */ nbCompressedBytes = IMIN(nbCompressedBytes,1275>>(3-LM)); if (!hybrid) { base_target = vbr_rate - ((40*C+20)<constrained_vbr) base_target += (st->vbr_offset>>lm_diff); if (!hybrid) { target = compute_vbr(mode, &st->analysis, base_target, LM, equiv_rate, st->lastCodedBands, C, st->intensity, st->constrained_vbr, st->stereo_saving, tot_boost, tf_estimate, pitch_change, maxDepth, st->lfe, st->energy_mask!=NULL, surround_masking, temporal_vbr); } else { target = base_target; /* Tonal frames (offset<100) need more bits than noisy (offset>100) ones. */ if (st->silk_info.offset < 100) target += 12 << BITRES >> (3-LM); if (st->silk_info.offset > 100) target -= 18 << BITRES >> (3-LM); /* Boosting bitrate on transients and vowels with significant temporal spikes. */ target += (opus_int32)MULT16_16_Q14(tf_estimate-QCONST16(.25f,14), (50< QCONST16(.7f,14)) target = IMAX(target, 50<>(BITRES+3)) + 2; /* Take into account the 37 bits we need to have left in the packet to signal a redundant frame in hybrid mode. Creating a shorter packet would create an entropy coder desync. */ if (hybrid) min_allowed = IMAX(min_allowed, (tell0_frac+(37<>(BITRES+3)); nbAvailableBytes = (target+(1<<(BITRES+2)))>>(BITRES+3); nbAvailableBytes = IMAX(min_allowed,nbAvailableBytes); nbAvailableBytes = IMIN(nbCompressedBytes,nbAvailableBytes); /* By how much did we "miss" the target on that frame */ delta = target - vbr_rate; target=nbAvailableBytes<<(BITRES+3); /*If the frame is silent we don't adjust our drift, otherwise the encoder will shoot to very high rates after hitting a span of silence, but we do allow the bitres to refill. This means that we'll undershoot our target in CVBR/VBR modes on files with lots of silence. */ if(silence) { nbAvailableBytes = 2; target = 2*8<vbr_count < 970) { st->vbr_count++; alpha = celt_rcp(SHL32(EXTEND32(st->vbr_count+20),16)); } else alpha = QCONST16(.001f,15); /* How many bits have we used in excess of what we're allowed */ if (st->constrained_vbr) st->vbr_reservoir += target - vbr_rate; /*printf ("%d\n", st->vbr_reservoir);*/ /* Compute the offset we need to apply in order to reach the target */ if (st->constrained_vbr) { st->vbr_drift += (opus_int32)MULT16_32_Q15(alpha,(delta*(1<vbr_offset-st->vbr_drift); st->vbr_offset = -st->vbr_drift; } /*printf ("%d\n", st->vbr_drift);*/ if (st->constrained_vbr && st->vbr_reservoir < 0) { /* We're under the min value -- increase rate */ int adjust = (-st->vbr_reservoir)/(8<vbr_reservoir = 0; /*printf ("+%d\n", adjust);*/ } nbCompressedBytes = IMIN(nbCompressedBytes,nbAvailableBytes); /*printf("%d\n", nbCompressedBytes*50*8);*/ /* This moves the raw bits to take into account the new compressed size */ ec_enc_shrink(enc, nbCompressedBytes); } /* Bit allocation */ ALLOC(fine_quant, nbEBands, int); ALLOC(pulses, nbEBands, int); ALLOC(fine_priority, nbEBands, int); /* bits = packet size - where we are - safety*/ bits = (((opus_int32)nbCompressedBytes*8)<=2&&bits>=((LM+2)<analysis.valid) { int min_bandwidth; if (equiv_rate < (opus_int32)32000*C) min_bandwidth = 13; else if (equiv_rate < (opus_int32)48000*C) min_bandwidth = 16; else if (equiv_rate < (opus_int32)60000*C) min_bandwidth = 18; else if (equiv_rate < (opus_int32)80000*C) min_bandwidth = 19; else min_bandwidth = 20; signalBandwidth = IMAX(st->analysis.bandwidth, min_bandwidth); } #endif if (st->lfe) signalBandwidth = 1; codedBands = clt_compute_allocation(mode, start, end, offsets, cap, alloc_trim, &st->intensity, &dual_stereo, bits, &balance, pulses, fine_quant, fine_priority, C, LM, enc, 1, st->lastCodedBands, signalBandwidth); if (st->lastCodedBands) st->lastCodedBands = IMIN(st->lastCodedBands+1,IMAX(st->lastCodedBands-1,codedBands)); else st->lastCodedBands = codedBands; quant_fine_energy(mode, start, end, oldBandE, error, fine_quant, enc, C); /* Residual quantisation */ ALLOC(collapse_masks, C*nbEBands, unsigned char); quant_all_bands(1, mode, start, end, X, C==2 ? X+N : NULL, collapse_masks, bandE, pulses, shortBlocks, st->spread_decision, dual_stereo, st->intensity, tf_res, nbCompressedBytes*(8<rng, st->complexity, st->arch, st->disable_inv); if (anti_collapse_rsv > 0) { anti_collapse_on = st->consec_transient<2; #ifdef FUZZING anti_collapse_on = rand()&0x1; #endif ec_enc_bits(enc, anti_collapse_on, 1); } quant_energy_finalise(mode, start, end, oldBandE, error, fine_quant, fine_priority, nbCompressedBytes*8-ec_tell(enc), enc, C); OPUS_CLEAR(energyError, nbEBands*CC); c=0; do { for (i=start;irng); } c=0; do { OPUS_MOVE(st->syn_mem[c], st->syn_mem[c]+N, 2*MAX_PERIOD-N+overlap/2); } while (++csyn_mem[c]+2*MAX_PERIOD-N; } while (++cupsample, silence, st->arch); c=0; do { st->prefilter_period=IMAX(st->prefilter_period, COMBFILTER_MINPERIOD); st->prefilter_period_old=IMAX(st->prefilter_period_old, COMBFILTER_MINPERIOD); comb_filter(out_mem[c], out_mem[c], st->prefilter_period_old, st->prefilter_period, mode->shortMdctSize, st->prefilter_gain_old, st->prefilter_gain, st->prefilter_tapset_old, st->prefilter_tapset, mode->window, overlap); if (LM!=0) comb_filter(out_mem[c]+mode->shortMdctSize, out_mem[c]+mode->shortMdctSize, st->prefilter_period, pitch_index, N-mode->shortMdctSize, st->prefilter_gain, gain1, st->prefilter_tapset, prefilter_tapset, mode->window, overlap); } while (++cupsample, mode->preemph, st->preemph_memD); st->prefilter_period_old = st->prefilter_period; st->prefilter_gain_old = st->prefilter_gain; st->prefilter_tapset_old = st->prefilter_tapset; } #endif st->prefilter_period = pitch_index; st->prefilter_gain = gain1; st->prefilter_tapset = prefilter_tapset; #ifdef RESYNTH if (LM!=0) { st->prefilter_period_old = st->prefilter_period; st->prefilter_gain_old = st->prefilter_gain; st->prefilter_tapset_old = st->prefilter_tapset; } #endif if (CC==2&&C==1) { OPUS_COPY(&oldBandE[nbEBands], oldBandE, nbEBands); } if (!isTransient) { OPUS_COPY(oldLogE2, oldLogE, CC*nbEBands); OPUS_COPY(oldLogE, oldBandE, CC*nbEBands); } else { for (i=0;iconsec_transient++; else st->consec_transient=0; st->rng = enc->rng; /* If there's any room left (can only happen for very high rates), it's already filled with zeros */ ec_enc_done(enc); #ifdef CUSTOM_MODES if (st->signalling) nbCompressedBytes++; #endif RESTORE_STACK; if (ec_get_error(enc)) return OPUS_INTERNAL_ERROR; else return nbCompressedBytes; } #ifdef CUSTOM_MODES #ifdef FIXED_POINT int opus_custom_encode(CELTEncoder * OPUS_RESTRICT st, const opus_int16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes) { return celt_encode_with_ec(st, pcm, frame_size, compressed, nbCompressedBytes, NULL); } #ifndef DISABLE_FLOAT_API int opus_custom_encode_float(CELTEncoder * OPUS_RESTRICT st, const float * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes) { int j, ret, C, N; VARDECL(opus_int16, in); ALLOC_STACK; if (pcm==NULL) return OPUS_BAD_ARG; C = st->channels; N = frame_size; ALLOC(in, C*N, opus_int16); for (j=0;jchannels; N=frame_size; ALLOC(in, C*N, celt_sig); for (j=0;j10) goto bad_arg; st->complexity = value; } break; case CELT_SET_START_BAND_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); if (value<0 || value>=st->mode->nbEBands) goto bad_arg; st->start = value; } break; case CELT_SET_END_BAND_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); if (value<1 || value>st->mode->nbEBands) goto bad_arg; st->end = value; } break; case CELT_SET_PREDICTION_REQUEST: { int value = va_arg(ap, opus_int32); if (value<0 || value>2) goto bad_arg; st->disable_pf = value<=1; st->force_intra = value==0; } break; case OPUS_SET_PACKET_LOSS_PERC_REQUEST: { int value = va_arg(ap, opus_int32); if (value<0 || value>100) goto bad_arg; st->loss_rate = value; } break; case OPUS_SET_VBR_CONSTRAINT_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); st->constrained_vbr = value; } break; case OPUS_SET_VBR_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); st->vbr = value; } break; case OPUS_SET_BITRATE_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); if (value<=500 && value!=OPUS_BITRATE_MAX) goto bad_arg; value = IMIN(value, 260000*st->channels); st->bitrate = value; } break; case CELT_SET_CHANNELS_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); if (value<1 || value>2) goto bad_arg; st->stream_channels = value; } break; case OPUS_SET_LSB_DEPTH_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); if (value<8 || value>24) goto bad_arg; st->lsb_depth=value; } break; case OPUS_GET_LSB_DEPTH_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); *value=st->lsb_depth; } break; case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); if(value<0 || value>1) { goto bad_arg; } st->disable_inv = value; } break; case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } *value = st->disable_inv; } break; case OPUS_RESET_STATE: { int i; opus_val16 *oldBandE, *oldLogE, *oldLogE2; oldBandE = (opus_val16*)(st->in_mem+st->channels*(st->mode->overlap+COMBFILTER_MAXPERIOD)); oldLogE = oldBandE + st->channels*st->mode->nbEBands; oldLogE2 = oldLogE + st->channels*st->mode->nbEBands; OPUS_CLEAR((char*)&st->ENCODER_RESET_START, opus_custom_encoder_get_size(st->mode, st->channels)- ((char*)&st->ENCODER_RESET_START - (char*)st)); for (i=0;ichannels*st->mode->nbEBands;i++) oldLogE[i]=oldLogE2[i]=-QCONST16(28.f,DB_SHIFT); st->vbr_offset = 0; st->delayedIntra = 1; st->spread_decision = SPREAD_NORMAL; st->tonal_average = 256; st->hf_average = 0; st->tapset_decision = 0; } break; #ifdef CUSTOM_MODES case CELT_SET_INPUT_CLIPPING_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); st->clip = value; } break; #endif case CELT_SET_SIGNALLING_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); st->signalling = value; } break; case CELT_SET_ANALYSIS_REQUEST: { AnalysisInfo *info = va_arg(ap, AnalysisInfo *); if (info) OPUS_COPY(&st->analysis, info, 1); } break; case CELT_SET_SILK_INFO_REQUEST: { SILKInfo *info = va_arg(ap, SILKInfo *); if (info) OPUS_COPY(&st->silk_info, info, 1); } break; case CELT_GET_MODE_REQUEST: { const CELTMode ** value = va_arg(ap, const CELTMode**); if (value==0) goto bad_arg; *value=st->mode; } break; case OPUS_GET_FINAL_RANGE_REQUEST: { opus_uint32 * value = va_arg(ap, opus_uint32 *); if (value==0) goto bad_arg; *value=st->rng; } break; case OPUS_SET_LFE_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); st->lfe = value; } break; case OPUS_SET_ENERGY_MASK_REQUEST: { opus_val16 *value = va_arg(ap, opus_val16*); st->energy_mask = value; } break; default: goto bad_request; } va_end(ap); return OPUS_OK; bad_arg: va_end(ap); return OPUS_BAD_ARG; bad_request: va_end(ap); return OPUS_UNIMPLEMENTED; } jamulus-3.9.1+dfsg/libs/opus/celt/stack_alloc.h0000644000175000017500000001354514340334543020462 0ustar vimervimer/* Copyright (C) 2002-2003 Jean-Marc Valin Copyright (C) 2007-2009 Xiph.Org Foundation */ /** @file stack_alloc.h @brief Temporary memory allocation on stack */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef STACK_ALLOC_H #define STACK_ALLOC_H #include "opus_types.h" #include "opus_defines.h" #if (!defined (VAR_ARRAYS) && !defined (USE_ALLOCA) && !defined (NONTHREADSAFE_PSEUDOSTACK)) #error "Opus requires one of VAR_ARRAYS, USE_ALLOCA, or NONTHREADSAFE_PSEUDOSTACK be defined to select the temporary allocation mode." #endif #ifdef USE_ALLOCA # ifdef WIN32 # include # else # ifdef HAVE_ALLOCA_H # include # else # include # endif # endif #endif /** * @def ALIGN(stack, size) * * Aligns the stack to a 'size' boundary * * @param stack Stack * @param size New size boundary */ /** * @def PUSH(stack, size, type) * * Allocates 'size' elements of type 'type' on the stack * * @param stack Stack * @param size Number of elements * @param type Type of element */ /** * @def VARDECL(var) * * Declare variable on stack * * @param var Variable to declare */ /** * @def ALLOC(var, size, type) * * Allocate 'size' elements of 'type' on stack * * @param var Name of variable to allocate * @param size Number of elements * @param type Type of element */ #if defined(VAR_ARRAYS) #define VARDECL(type, var) #define ALLOC(var, size, type) type var[size] #define SAVE_STACK #define RESTORE_STACK #define ALLOC_STACK /* C99 does not allow VLAs of size zero */ #define ALLOC_NONE 1 #elif defined(USE_ALLOCA) #define VARDECL(type, var) type *var # ifdef WIN32 # define ALLOC(var, size, type) var = ((type*)_alloca(sizeof(type)*(size))) # else # define ALLOC(var, size, type) var = ((type*)alloca(sizeof(type)*(size))) # endif #define SAVE_STACK #define RESTORE_STACK #define ALLOC_STACK #define ALLOC_NONE 0 #else #ifdef CELT_C char *scratch_ptr=0; char *global_stack=0; #else extern char *global_stack; extern char *scratch_ptr; #endif /* CELT_C */ #ifdef ENABLE_VALGRIND #include #ifdef CELT_C char *global_stack_top=0; #else extern char *global_stack_top; #endif /* CELT_C */ #define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1)) #define PUSH(stack, size, type) (VALGRIND_MAKE_MEM_NOACCESS(stack, global_stack_top-stack),ALIGN((stack),sizeof(type)/sizeof(char)),VALGRIND_MAKE_MEM_UNDEFINED(stack, ((size)*sizeof(type)/sizeof(char))),(stack)+=(2*(size)*sizeof(type)/sizeof(char)),(type*)((stack)-(2*(size)*sizeof(type)/sizeof(char)))) #define RESTORE_STACK ((global_stack = _saved_stack),VALGRIND_MAKE_MEM_NOACCESS(global_stack, global_stack_top-global_stack)) #define ALLOC_STACK char *_saved_stack; ((global_stack = (global_stack==0) ? ((global_stack_top=opus_alloc_scratch(GLOBAL_STACK_SIZE*2)+(GLOBAL_STACK_SIZE*2))-(GLOBAL_STACK_SIZE*2)) : global_stack),VALGRIND_MAKE_MEM_NOACCESS(global_stack, global_stack_top-global_stack)); _saved_stack = global_stack; #else #define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1)) #define PUSH(stack, size, type) (ALIGN((stack),sizeof(type)/sizeof(char)),(stack)+=(size)*(sizeof(type)/sizeof(char)),(type*)((stack)-(size)*(sizeof(type)/sizeof(char)))) #if 0 /* Set this to 1 to instrument pseudostack usage */ #define RESTORE_STACK (printf("%ld %s:%d\n", global_stack-scratch_ptr, __FILE__, __LINE__),global_stack = _saved_stack) #else #define RESTORE_STACK (global_stack = _saved_stack) #endif #define ALLOC_STACK char *_saved_stack; (global_stack = (global_stack==0) ? (scratch_ptr=opus_alloc_scratch(GLOBAL_STACK_SIZE)) : global_stack); _saved_stack = global_stack; #endif /* ENABLE_VALGRIND */ #include "os_support.h" #define VARDECL(type, var) type *var #define ALLOC(var, size, type) var = PUSH(global_stack, size, type) #define SAVE_STACK char *_saved_stack = global_stack; #define ALLOC_NONE 0 #endif /* VAR_ARRAYS */ #ifdef ENABLE_VALGRIND #include #define OPUS_CHECK_ARRAY(ptr, len) VALGRIND_CHECK_MEM_IS_DEFINED(ptr, len*sizeof(*ptr)) #define OPUS_CHECK_VALUE(value) VALGRIND_CHECK_VALUE_IS_DEFINED(value) #define OPUS_CHECK_ARRAY_COND(ptr, len) VALGRIND_CHECK_MEM_IS_DEFINED(ptr, len*sizeof(*ptr)) #define OPUS_CHECK_VALUE_COND(value) VALGRIND_CHECK_VALUE_IS_DEFINED(value) #define OPUS_PRINT_INT(value) do {fprintf(stderr, #value " = %d at %s:%d\n", value, __FILE__, __LINE__);}while(0) #define OPUS_FPRINTF fprintf #else static OPUS_INLINE int _opus_false(void) {return 0;} #define OPUS_CHECK_ARRAY(ptr, len) _opus_false() #define OPUS_CHECK_VALUE(value) _opus_false() #define OPUS_PRINT_INT(value) do{}while(0) #define OPUS_FPRINTF (void) #endif #endif /* STACK_ALLOC_H */ jamulus-3.9.1+dfsg/libs/opus/celt/cwrs.h0000644000175000017500000000353514340334543017157 0ustar vimervimer/* Copyright (c) 2007-2008 CSIRO Copyright (c) 2007-2009 Xiph.Org Foundation Copyright (c) 2007-2009 Timothy B. Terriberry Written by Timothy B. Terriberry and Jean-Marc Valin */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef CWRS_H #define CWRS_H #include "arch.h" #include "stack_alloc.h" #include "entenc.h" #include "entdec.h" #ifdef CUSTOM_MODES int log2_frac(opus_uint32 val, int frac); #endif void get_required_bits(opus_int16 *bits, int N, int K, int frac); void encode_pulses(const int *_y, int N, int K, ec_enc *enc); opus_val32 decode_pulses(int *_y, int N, int K, ec_dec *dec); #endif /* CWRS_H */ jamulus-3.9.1+dfsg/libs/opus/celt/pitch.h0000644000175000017500000001340314340334543017303 0ustar vimervimer/* Copyright (c) 2007-2008 CSIRO Copyright (c) 2007-2009 Xiph.Org Foundation Written by Jean-Marc Valin */ /** @file pitch.h @brief Pitch analysis */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef PITCH_H #define PITCH_H #include "modes.h" #include "cpu_support.h" #if (defined(OPUS_X86_MAY_HAVE_SSE) && !defined(FIXED_POINT)) \ || ((defined(OPUS_X86_MAY_HAVE_SSE4_1) || defined(OPUS_X86_MAY_HAVE_SSE2)) && defined(FIXED_POINT)) #include "x86/pitch_sse.h" #endif #if defined(MIPSr1_ASM) #include "mips/pitch_mipsr1.h" #endif #if (defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)) # include "arm/pitch_arm.h" #endif void pitch_downsample(celt_sig * OPUS_RESTRICT x[], opus_val16 * OPUS_RESTRICT x_lp, int len, int C, int arch); void pitch_search(const opus_val16 * OPUS_RESTRICT x_lp, opus_val16 * OPUS_RESTRICT y, int len, int max_pitch, int *pitch, int arch); opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod, int N, int *T0, int prev_period, opus_val16 prev_gain, int arch); /* OPT: This is the kernel you really want to optimize. It gets used a lot by the prefilter and by the PLC. */ static OPUS_INLINE void xcorr_kernel_c(const opus_val16 * x, const opus_val16 * y, opus_val32 sum[4], int len) { int j; opus_val16 y_0, y_1, y_2, y_3; celt_assert(len>=3); y_3=0; /* gcc doesn't realize that y_3 can't be used uninitialized */ y_0=*y++; y_1=*y++; y_2=*y++; for (j=0;j #include "celt.h" #include "pitch.h" #include "bands.h" #include "modes.h" #include "entcode.h" #include "quant_bands.h" #include "rate.h" #include "stack_alloc.h" #include "mathops.h" #include "float_cast.h" #include #include "celt_lpc.h" #include "vq.h" #ifndef PACKAGE_VERSION #define PACKAGE_VERSION "unknown" #endif #if defined(MIPSr1_ASM) #include "mips/celt_mipsr1.h" #endif int resampling_factor(opus_int32 rate) { int ret; switch (rate) { case 48000: ret = 1; break; case 24000: ret = 2; break; case 16000: ret = 3; break; case 12000: ret = 4; break; case 8000: ret = 6; break; default: #ifndef CUSTOM_MODES celt_assert(0); #endif ret = 0; break; } return ret; } #if !defined(OVERRIDE_COMB_FILTER_CONST) || defined(NON_STATIC_COMB_FILTER_CONST_C) /* This version should be faster on ARM */ #ifdef OPUS_ARM_ASM #ifndef NON_STATIC_COMB_FILTER_CONST_C static #endif void comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N, opus_val16 g10, opus_val16 g11, opus_val16 g12) { opus_val32 x0, x1, x2, x3, x4; int i; x4 = SHL32(x[-T-2], 1); x3 = SHL32(x[-T-1], 1); x2 = SHL32(x[-T], 1); x1 = SHL32(x[-T+1], 1); for (i=0;inbEBands;i++) { int N; N=(m->eBands[i+1]-m->eBands[i])<cache.caps[m->nbEBands*(2*LM+C-1)+i]+64)*C*N>>2; } } const char *opus_strerror(int error) { static const char * const error_strings[8] = { "success", "invalid argument", "buffer too small", "internal error", "corrupted stream", "request not implemented", "invalid state", "memory allocation failed" }; if (error > 0 || error < -7) return "unknown error"; else return error_strings[-error]; } const char *opus_get_version_string(void) { return "libopus " PACKAGE_VERSION /* Applications may rely on the presence of this substring in the version string to determine if they have a fixed-point or floating-point build at runtime. */ #ifdef FIXED_POINT "-fixed" #endif #ifdef FUZZING "-fuzzing" #endif ; } jamulus-3.9.1+dfsg/libs/opus/celt/kiss_fft.h0000644000175000017500000001422714340334543020011 0ustar vimervimer/*Copyright (c) 2003-2004, Mark Borgerding Lots of modifications by Jean-Marc Valin Copyright (c) 2005-2007, Xiph.Org Foundation Copyright (c) 2008, Xiph.Org Foundation, CSIRO All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/ #ifndef KISS_FFT_H #define KISS_FFT_H #include #include #include "arch.h" #include "cpu_support.h" #ifdef __cplusplus extern "C" { #endif #ifdef USE_SIMD # include # define kiss_fft_scalar __m128 #define KISS_FFT_MALLOC(nbytes) memalign(16,nbytes) #else #define KISS_FFT_MALLOC opus_alloc #endif #ifdef FIXED_POINT #include "arch.h" # define kiss_fft_scalar opus_int32 # define kiss_twiddle_scalar opus_int16 #else # ifndef kiss_fft_scalar /* default is float */ # define kiss_fft_scalar float # define kiss_twiddle_scalar float # define KF_SUFFIX _celt_single # endif #endif typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; typedef struct { kiss_twiddle_scalar r; kiss_twiddle_scalar i; }kiss_twiddle_cpx; #define MAXFACTORS 8 /* e.g. an fft of length 128 has 4 factors as far as kissfft is concerned 4*4*4*2 */ typedef struct arch_fft_state{ int is_supported; void *priv; } arch_fft_state; typedef struct kiss_fft_state{ int nfft; opus_val16 scale; #ifdef FIXED_POINT int scale_shift; #endif int shift; opus_int16 factors[2*MAXFACTORS]; const opus_int16 *bitrev; const kiss_twiddle_cpx *twiddles; arch_fft_state *arch_fft; } kiss_fft_state; #if defined(HAVE_ARM_NE10) #include "arm/fft_arm.h" #endif /*typedef struct kiss_fft_state* kiss_fft_cfg;*/ /** * opus_fft_alloc * * Initialize a FFT (or IFFT) algorithm's cfg/state buffer. * * typical usage: kiss_fft_cfg mycfg=opus_fft_alloc(1024,0,NULL,NULL); * * The return value from fft_alloc is a cfg buffer used internally * by the fft routine or NULL. * * If lenmem is NULL, then opus_fft_alloc will allocate a cfg buffer using malloc. * The returned value should be free()d when done to avoid memory leaks. * * The state can be placed in a user supplied buffer 'mem': * If lenmem is not NULL and mem is not NULL and *lenmem is large enough, * then the function places the cfg in mem and the size used in *lenmem * and returns mem. * * If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough), * then the function returns NULL and places the minimum cfg * buffer size in *lenmem. * */ kiss_fft_state *opus_fft_alloc_twiddles(int nfft,void * mem,size_t * lenmem, const kiss_fft_state *base, int arch); kiss_fft_state *opus_fft_alloc(int nfft,void * mem,size_t * lenmem, int arch); /** * opus_fft(cfg,in_out_buf) * * Perform an FFT on a complex input buffer. * for a forward FFT, * fin should be f[0] , f[1] , ... ,f[nfft-1] * fout will be F[0] , F[1] , ... ,F[nfft-1] * Note that each element is complex and can be accessed like f[k].r and f[k].i * */ void opus_fft_c(const kiss_fft_state *cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout); void opus_ifft_c(const kiss_fft_state *cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout); void opus_fft_impl(const kiss_fft_state *st,kiss_fft_cpx *fout); void opus_ifft_impl(const kiss_fft_state *st,kiss_fft_cpx *fout); void opus_fft_free(const kiss_fft_state *cfg, int arch); void opus_fft_free_arch_c(kiss_fft_state *st); int opus_fft_alloc_arch_c(kiss_fft_state *st); #if !defined(OVERRIDE_OPUS_FFT) /* Is run-time CPU detection enabled on this platform? */ #if defined(OPUS_HAVE_RTCD) && (defined(HAVE_ARM_NE10)) extern int (*const OPUS_FFT_ALLOC_ARCH_IMPL[OPUS_ARCHMASK+1])( kiss_fft_state *st); #define opus_fft_alloc_arch(_st, arch) \ ((*OPUS_FFT_ALLOC_ARCH_IMPL[(arch)&OPUS_ARCHMASK])(_st)) extern void (*const OPUS_FFT_FREE_ARCH_IMPL[OPUS_ARCHMASK+1])( kiss_fft_state *st); #define opus_fft_free_arch(_st, arch) \ ((*OPUS_FFT_FREE_ARCH_IMPL[(arch)&OPUS_ARCHMASK])(_st)) extern void (*const OPUS_FFT[OPUS_ARCHMASK+1])(const kiss_fft_state *cfg, const kiss_fft_cpx *fin, kiss_fft_cpx *fout); #define opus_fft(_cfg, _fin, _fout, arch) \ ((*OPUS_FFT[(arch)&OPUS_ARCHMASK])(_cfg, _fin, _fout)) extern void (*const OPUS_IFFT[OPUS_ARCHMASK+1])(const kiss_fft_state *cfg, const kiss_fft_cpx *fin, kiss_fft_cpx *fout); #define opus_ifft(_cfg, _fin, _fout, arch) \ ((*OPUS_IFFT[(arch)&OPUS_ARCHMASK])(_cfg, _fin, _fout)) #else /* else for if defined(OPUS_HAVE_RTCD) && (defined(HAVE_ARM_NE10)) */ #define opus_fft_alloc_arch(_st, arch) \ ((void)(arch), opus_fft_alloc_arch_c(_st)) #define opus_fft_free_arch(_st, arch) \ ((void)(arch), opus_fft_free_arch_c(_st)) #define opus_fft(_cfg, _fin, _fout, arch) \ ((void)(arch), opus_fft_c(_cfg, _fin, _fout)) #define opus_ifft(_cfg, _fin, _fout, arch) \ ((void)(arch), opus_ifft_c(_cfg, _fin, _fout)) #endif /* end if defined(OPUS_HAVE_RTCD) && (defined(HAVE_ARM_NE10)) */ #endif /* end if !defined(OVERRIDE_OPUS_FFT) */ #ifdef __cplusplus } #endif #endif jamulus-3.9.1+dfsg/libs/opus/celt/mathops.h0000644000175000017500000001736014340334543017655 0ustar vimervimer/* Copyright (c) 2002-2008 Jean-Marc Valin Copyright (c) 2007-2008 CSIRO Copyright (c) 2007-2009 Xiph.Org Foundation Written by Jean-Marc Valin */ /** @file mathops.h @brief Various math functions */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef MATHOPS_H #define MATHOPS_H #include "arch.h" #include "entcode.h" #include "os_support.h" #define PI 3.141592653f /* Multiplies two 16-bit fractional values. Bit-exactness of this macro is important */ #define FRAC_MUL16(a,b) ((16384+((opus_int32)(opus_int16)(a)*(opus_int16)(b)))>>15) unsigned isqrt32(opus_uint32 _val); /* CELT doesn't need it for fixed-point, by analysis.c does. */ #if !defined(FIXED_POINT) || defined(ANALYSIS_C) #define cA 0.43157974f #define cB 0.67848403f #define cC 0.08595542f #define cE ((float)PI/2) static OPUS_INLINE float fast_atan2f(float y, float x) { float x2, y2; x2 = x*x; y2 = y*y; /* For very small values, we don't care about the answer, so we can just return 0. */ if (x2 + y2 < 1e-18f) { return 0; } if(x2>23)-127; in.i -= integer<<23; frac = in.f - 1.5f; frac = -0.41445418f + frac*(0.95909232f + frac*(-0.33951290f + frac*0.16541097f)); return 1+integer+frac; } /** Base-2 exponential approximation (2^x). */ static OPUS_INLINE float celt_exp2(float x) { int integer; float frac; union { float f; opus_uint32 i; } res; integer = floor(x); if (integer < -50) return 0; frac = x-integer; /* K0 = 1, K1 = log(2), K2 = 3-4*log(2), K3 = 3*log(2) - 2 */ res.f = 0.99992522f + frac * (0.69583354f + frac * (0.22606716f + 0.078024523f*frac)); res.i = (res.i + (integer<<23)) & 0x7fffffff; return res.f; } #else #define celt_log2(x) ((float)(1.442695040888963387*log(x))) #define celt_exp2(x) ((float)exp(0.6931471805599453094*(x))) #endif #endif #ifdef FIXED_POINT #include "os_support.h" #ifndef OVERRIDE_CELT_ILOG2 /** Integer log in base2. Undefined for zero and negative numbers */ static OPUS_INLINE opus_int16 celt_ilog2(opus_int32 x) { celt_sig_assert(x>0); return EC_ILOG(x)-1; } #endif /** Integer log in base2. Defined for zero, but not for negative numbers */ static OPUS_INLINE opus_int16 celt_zlog2(opus_val32 x) { return x <= 0 ? 0 : celt_ilog2(x); } opus_val16 celt_rsqrt_norm(opus_val32 x); opus_val32 celt_sqrt(opus_val32 x); opus_val16 celt_cos_norm(opus_val32 x); /** Base-2 logarithm approximation (log2(x)). (Q14 input, Q10 output) */ static OPUS_INLINE opus_val16 celt_log2(opus_val32 x) { int i; opus_val16 n, frac; /* -0.41509302963303146, 0.9609890551383969, -0.31836011537636605, 0.15530808010959576, -0.08556153059057618 */ static const opus_val16 C[5] = {-6801+(1<<(13-DB_SHIFT)), 15746, -5217, 2545, -1401}; if (x==0) return -32767; i = celt_ilog2(x); n = VSHR32(x,i-15)-32768-16384; frac = ADD16(C[0], MULT16_16_Q15(n, ADD16(C[1], MULT16_16_Q15(n, ADD16(C[2], MULT16_16_Q15(n, ADD16(C[3], MULT16_16_Q15(n, C[4])))))))); return SHL16(i-13,DB_SHIFT)+SHR16(frac,14-DB_SHIFT); } /* K0 = 1 K1 = log(2) K2 = 3-4*log(2) K3 = 3*log(2) - 2 */ #define D0 16383 #define D1 22804 #define D2 14819 #define D3 10204 static OPUS_INLINE opus_val32 celt_exp2_frac(opus_val16 x) { opus_val16 frac; frac = SHL16(x, 4); return ADD16(D0, MULT16_16_Q15(frac, ADD16(D1, MULT16_16_Q15(frac, ADD16(D2 , MULT16_16_Q15(D3,frac)))))); } /** Base-2 exponential approximation (2^x). (Q10 input, Q16 output) */ static OPUS_INLINE opus_val32 celt_exp2(opus_val16 x) { int integer; opus_val16 frac; integer = SHR16(x,10); if (integer>14) return 0x7f000000; else if (integer < -15) return 0; frac = celt_exp2_frac(x-SHL16(integer,10)); return VSHR32(EXTEND32(frac), -integer-2); } opus_val32 celt_rcp(opus_val32 x); #define celt_div(a,b) MULT32_32_Q31((opus_val32)(a),celt_rcp(b)) opus_val32 frac_div32(opus_val32 a, opus_val32 b); #define M1 32767 #define M2 -21 #define M3 -11943 #define M4 4936 /* Atan approximation using a 4th order polynomial. Input is in Q15 format and normalized by pi/4. Output is in Q15 format */ static OPUS_INLINE opus_val16 celt_atan01(opus_val16 x) { return MULT16_16_P15(x, ADD32(M1, MULT16_16_P15(x, ADD32(M2, MULT16_16_P15(x, ADD32(M3, MULT16_16_P15(M4, x))))))); } #undef M1 #undef M2 #undef M3 #undef M4 /* atan2() approximation valid for positive input values */ static OPUS_INLINE opus_val16 celt_atan2p(opus_val16 y, opus_val16 x) { if (y < x) { opus_val32 arg; arg = celt_div(SHL32(EXTEND32(y),15),x); if (arg >= 32767) arg = 32767; return SHR16(celt_atan01(EXTRACT16(arg)),1); } else { opus_val32 arg; arg = celt_div(SHL32(EXTEND32(x),15),y); if (arg >= 32767) arg = 32767; return 25736-SHR16(celt_atan01(EXTRACT16(arg)),1); } } #endif /* FIXED_POINT */ #endif /* MATHOPS_H */ jamulus-3.9.1+dfsg/libs/opus/celt/cwrs.c0000644000175000017500000006714514340334543017161 0ustar vimervimer/* Copyright (c) 2007-2008 CSIRO Copyright (c) 2007-2009 Xiph.Org Foundation Copyright (c) 2007-2009 Timothy B. Terriberry Written by Timothy B. Terriberry and Jean-Marc Valin */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "os_support.h" #include "cwrs.h" #include "mathops.h" #include "arch.h" #ifdef CUSTOM_MODES /*Guaranteed to return a conservatively large estimate of the binary logarithm with frac bits of fractional precision. Tested for all possible 32-bit inputs with frac=4, where the maximum overestimation is 0.06254243 bits.*/ int log2_frac(opus_uint32 val, int frac) { int l; l=EC_ILOG(val); if(val&(val-1)){ /*This is (val>>l-16), but guaranteed to round up, even if adding a bias before the shift would cause overflow (e.g., for 0xFFFFxxxx). Doesn't work for val=0, but that case fails the test above.*/ if(l>16)val=((val-1)>>(l-16))+1; else val<<=16-l; l=(l-1)<>16); l+=b<>b; val=(val*val+0x7FFF)>>15; } while(frac-->0); /*If val is not exactly 0x8000, then we have to round up the remainder.*/ return l+(val>0x8000); } /*Exact powers of two require no rounding.*/ else return (l-1)<0 ? sum(k=1...K,2**k*choose(N,k)*choose(K-1,k-1)) : 1, where choose() is the binomial function. A table of values for N<10 and K<10 looks like: V[10][10] = { {1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {1, 2, 2, 2, 2, 2, 2, 2, 2, 2}, {1, 4, 8, 12, 16, 20, 24, 28, 32, 36}, {1, 6, 18, 38, 66, 102, 146, 198, 258, 326}, {1, 8, 32, 88, 192, 360, 608, 952, 1408, 1992}, {1, 10, 50, 170, 450, 1002, 1970, 3530, 5890, 9290}, {1, 12, 72, 292, 912, 2364, 5336, 10836, 20256, 35436}, {1, 14, 98, 462, 1666, 4942, 12642, 28814, 59906, 115598}, {1, 16, 128, 688, 2816, 9424, 27008, 68464, 157184, 332688}, {1, 18, 162, 978, 4482, 16722, 53154, 148626, 374274, 864146} }; U(N,K) = the number of such combinations wherein N-1 objects are taken at most K-1 at a time. This is given by U(N,K) = sum(k=0...K-1,V(N-1,k)) = K>0 ? (V(N-1,K-1) + V(N,K-1))/2 : 0. The latter expression also makes clear that U(N,K) is half the number of such combinations wherein the first object is taken at least once. Although it may not be clear from either of these definitions, U(N,K) is the natural function to work with when enumerating the pulse vector codebooks, not V(N,K). U(N,K) is not well-defined for N=0, but with the extension U(0,K) = K>0 ? 0 : 1, the function becomes symmetric: U(N,K) = U(K,N), with a similar table: U[10][10] = { {1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {0, 1, 3, 5, 7, 9, 11, 13, 15, 17}, {0, 1, 5, 13, 25, 41, 61, 85, 113, 145}, {0, 1, 7, 25, 63, 129, 231, 377, 575, 833}, {0, 1, 9, 41, 129, 321, 681, 1289, 2241, 3649}, {0, 1, 11, 61, 231, 681, 1683, 3653, 7183, 13073}, {0, 1, 13, 85, 377, 1289, 3653, 8989, 19825, 40081}, {0, 1, 15, 113, 575, 2241, 7183, 19825, 48639, 108545}, {0, 1, 17, 145, 833, 3649, 13073, 40081, 108545, 265729} }; With this extension, V(N,K) may be written in terms of U(N,K): V(N,K) = U(N,K) + U(N,K+1) for all N>=0, K>=0. Thus U(N,K+1) represents the number of combinations where the first element is positive or zero, and U(N,K) represents the number of combinations where it is negative. With a large enough table of U(N,K) values, we could write O(N) encoding and O(min(N*log(K),N+K)) decoding routines, but such a table would be prohibitively large for small embedded devices (K may be as large as 32767 for small N, and N may be as large as 200). Both functions obey the same recurrence relation: V(N,K) = V(N-1,K) + V(N,K-1) + V(N-1,K-1), U(N,K) = U(N-1,K) + U(N,K-1) + U(N-1,K-1), for all N>0, K>0, with different initial conditions at N=0 or K=0. This allows us to construct a row of one of the tables above given the previous row or the next row. Thus we can derive O(NK) encoding and decoding routines with O(K) memory using only addition and subtraction. When encoding, we build up from the U(2,K) row and work our way forwards. When decoding, we need to start at the U(N,K) row and work our way backwards, which requires a means of computing U(N,K). U(N,K) may be computed from two previous values with the same N: U(N,K) = ((2*N-1)*U(N,K-1) - U(N,K-2))/(K-1) + U(N,K-2) for all N>1, and since U(N,K) is symmetric, a similar relation holds for two previous values with the same K: U(N,K>1) = ((2*K-1)*U(N-1,K) - U(N-2,K))/(N-1) + U(N-2,K) for all K>1. This allows us to construct an arbitrary row of the U(N,K) table by starting with the first two values, which are constants. This saves roughly 2/3 the work in our O(NK) decoding routine, but costs O(K) multiplications. Similar relations can be derived for V(N,K), but are not used here. For N>0 and K>0, U(N,K) and V(N,K) take on the form of an (N-1)-degree polynomial for fixed N. The first few are U(1,K) = 1, U(2,K) = 2*K-1, U(3,K) = (2*K-2)*K+1, U(4,K) = (((4*K-6)*K+8)*K-3)/3, U(5,K) = ((((2*K-4)*K+10)*K-8)*K+3)/3, and V(1,K) = 2, V(2,K) = 4*K, V(3,K) = 4*K*K+2, V(4,K) = 8*(K*K+2)*K/3, V(5,K) = ((4*K*K+20)*K*K+6)/3, for all K>0. This allows us to derive O(N) encoding and O(N*log(K)) decoding routines for small N (and indeed decoding is also O(N) for N<3). @ARTICLE{Fis86, author="Thomas R. Fischer", title="A Pyramid Vector Quantizer", journal="IEEE Transactions on Information Theory", volume="IT-32", number=4, pages="568--583", month=Jul, year=1986 }*/ #if !defined(SMALL_FOOTPRINT) /*U(N,K) = U(K,N) := N>0?K>0?U(N-1,K)+U(N,K-1)+U(N-1,K-1):0:K>0?1:0*/ # define CELT_PVQ_U(_n,_k) (CELT_PVQ_U_ROW[IMIN(_n,_k)][IMAX(_n,_k)]) /*V(N,K) := U(N,K)+U(N,K+1) = the number of PVQ codewords for a band of size N with K pulses allocated to it.*/ # define CELT_PVQ_V(_n,_k) (CELT_PVQ_U(_n,_k)+CELT_PVQ_U(_n,(_k)+1)) /*For each V(N,K) supported, we will access element U(min(N,K+1),max(N,K+1)). Thus, the number of entries in row I is the larger of the maximum number of pulses we will ever allocate for a given N=I (K=128, or however many fit in 32 bits, whichever is smaller), plus one, and the maximum N for which K=I-1 pulses fit in 32 bits. The largest band size in an Opus Custom mode is 208. Otherwise, we can limit things to the set of N which can be achieved by splitting a band from a standard Opus mode: 176, 144, 96, 88, 72, 64, 48, 44, 36, 32, 24, 22, 18, 16, 8, 4, 2).*/ #if defined(CUSTOM_MODES) static const opus_uint32 CELT_PVQ_U_DATA[1488]={ #else static const opus_uint32 CELT_PVQ_U_DATA[1272]={ #endif /*N=0, K=0...176:*/ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, #if defined(CUSTOM_MODES) /*...208:*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, #endif /*N=1, K=1...176:*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, #if defined(CUSTOM_MODES) /*...208:*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, #endif /*N=2, K=2...176:*/ 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99, 101, 103, 105, 107, 109, 111, 113, 115, 117, 119, 121, 123, 125, 127, 129, 131, 133, 135, 137, 139, 141, 143, 145, 147, 149, 151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171, 173, 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231, 233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255, 257, 259, 261, 263, 265, 267, 269, 271, 273, 275, 277, 279, 281, 283, 285, 287, 289, 291, 293, 295, 297, 299, 301, 303, 305, 307, 309, 311, 313, 315, 317, 319, 321, 323, 325, 327, 329, 331, 333, 335, 337, 339, 341, 343, 345, 347, 349, 351, #if defined(CUSTOM_MODES) /*...208:*/ 353, 355, 357, 359, 361, 363, 365, 367, 369, 371, 373, 375, 377, 379, 381, 383, 385, 387, 389, 391, 393, 395, 397, 399, 401, 403, 405, 407, 409, 411, 413, 415, #endif /*N=3, K=3...176:*/ 13, 25, 41, 61, 85, 113, 145, 181, 221, 265, 313, 365, 421, 481, 545, 613, 685, 761, 841, 925, 1013, 1105, 1201, 1301, 1405, 1513, 1625, 1741, 1861, 1985, 2113, 2245, 2381, 2521, 2665, 2813, 2965, 3121, 3281, 3445, 3613, 3785, 3961, 4141, 4325, 4513, 4705, 4901, 5101, 5305, 5513, 5725, 5941, 6161, 6385, 6613, 6845, 7081, 7321, 7565, 7813, 8065, 8321, 8581, 8845, 9113, 9385, 9661, 9941, 10225, 10513, 10805, 11101, 11401, 11705, 12013, 12325, 12641, 12961, 13285, 13613, 13945, 14281, 14621, 14965, 15313, 15665, 16021, 16381, 16745, 17113, 17485, 17861, 18241, 18625, 19013, 19405, 19801, 20201, 20605, 21013, 21425, 21841, 22261, 22685, 23113, 23545, 23981, 24421, 24865, 25313, 25765, 26221, 26681, 27145, 27613, 28085, 28561, 29041, 29525, 30013, 30505, 31001, 31501, 32005, 32513, 33025, 33541, 34061, 34585, 35113, 35645, 36181, 36721, 37265, 37813, 38365, 38921, 39481, 40045, 40613, 41185, 41761, 42341, 42925, 43513, 44105, 44701, 45301, 45905, 46513, 47125, 47741, 48361, 48985, 49613, 50245, 50881, 51521, 52165, 52813, 53465, 54121, 54781, 55445, 56113, 56785, 57461, 58141, 58825, 59513, 60205, 60901, 61601, #if defined(CUSTOM_MODES) /*...208:*/ 62305, 63013, 63725, 64441, 65161, 65885, 66613, 67345, 68081, 68821, 69565, 70313, 71065, 71821, 72581, 73345, 74113, 74885, 75661, 76441, 77225, 78013, 78805, 79601, 80401, 81205, 82013, 82825, 83641, 84461, 85285, 86113, #endif /*N=4, K=4...176:*/ 63, 129, 231, 377, 575, 833, 1159, 1561, 2047, 2625, 3303, 4089, 4991, 6017, 7175, 8473, 9919, 11521, 13287, 15225, 17343, 19649, 22151, 24857, 27775, 30913, 34279, 37881, 41727, 45825, 50183, 54809, 59711, 64897, 70375, 76153, 82239, 88641, 95367, 102425, 109823, 117569, 125671, 134137, 142975, 152193, 161799, 171801, 182207, 193025, 204263, 215929, 228031, 240577, 253575, 267033, 280959, 295361, 310247, 325625, 341503, 357889, 374791, 392217, 410175, 428673, 447719, 467321, 487487, 508225, 529543, 551449, 573951, 597057, 620775, 645113, 670079, 695681, 721927, 748825, 776383, 804609, 833511, 863097, 893375, 924353, 956039, 988441, 1021567, 1055425, 1090023, 1125369, 1161471, 1198337, 1235975, 1274393, 1313599, 1353601, 1394407, 1436025, 1478463, 1521729, 1565831, 1610777, 1656575, 1703233, 1750759, 1799161, 1848447, 1898625, 1949703, 2001689, 2054591, 2108417, 2163175, 2218873, 2275519, 2333121, 2391687, 2451225, 2511743, 2573249, 2635751, 2699257, 2763775, 2829313, 2895879, 2963481, 3032127, 3101825, 3172583, 3244409, 3317311, 3391297, 3466375, 3542553, 3619839, 3698241, 3777767, 3858425, 3940223, 4023169, 4107271, 4192537, 4278975, 4366593, 4455399, 4545401, 4636607, 4729025, 4822663, 4917529, 5013631, 5110977, 5209575, 5309433, 5410559, 5512961, 5616647, 5721625, 5827903, 5935489, 6044391, 6154617, 6266175, 6379073, 6493319, 6608921, 6725887, 6844225, 6963943, 7085049, 7207551, #if defined(CUSTOM_MODES) /*...208:*/ 7331457, 7456775, 7583513, 7711679, 7841281, 7972327, 8104825, 8238783, 8374209, 8511111, 8649497, 8789375, 8930753, 9073639, 9218041, 9363967, 9511425, 9660423, 9810969, 9963071, 10116737, 10271975, 10428793, 10587199, 10747201, 10908807, 11072025, 11236863, 11403329, 11571431, 11741177, 11912575, #endif /*N=5, K=5...176:*/ 321, 681, 1289, 2241, 3649, 5641, 8361, 11969, 16641, 22569, 29961, 39041, 50049, 63241, 78889, 97281, 118721, 143529, 172041, 204609, 241601, 283401, 330409, 383041, 441729, 506921, 579081, 658689, 746241, 842249, 947241, 1061761, 1186369, 1321641, 1468169, 1626561, 1797441, 1981449, 2179241, 2391489, 2618881, 2862121, 3121929, 3399041, 3694209, 4008201, 4341801, 4695809, 5071041, 5468329, 5888521, 6332481, 6801089, 7295241, 7815849, 8363841, 8940161, 9545769, 10181641, 10848769, 11548161, 12280841, 13047849, 13850241, 14689089, 15565481, 16480521, 17435329, 18431041, 19468809, 20549801, 21675201, 22846209, 24064041, 25329929, 26645121, 28010881, 29428489, 30899241, 32424449, 34005441, 35643561, 37340169, 39096641, 40914369, 42794761, 44739241, 46749249, 48826241, 50971689, 53187081, 55473921, 57833729, 60268041, 62778409, 65366401, 68033601, 70781609, 73612041, 76526529, 79526721, 82614281, 85790889, 89058241, 92418049, 95872041, 99421961, 103069569, 106816641, 110664969, 114616361, 118672641, 122835649, 127107241, 131489289, 135983681, 140592321, 145317129, 150160041, 155123009, 160208001, 165417001, 170752009, 176215041, 181808129, 187533321, 193392681, 199388289, 205522241, 211796649, 218213641, 224775361, 231483969, 238341641, 245350569, 252512961, 259831041, 267307049, 274943241, 282741889, 290705281, 298835721, 307135529, 315607041, 324252609, 333074601, 342075401, 351257409, 360623041, 370174729, 379914921, 389846081, 399970689, 410291241, 420810249, 431530241, 442453761, 453583369, 464921641, 476471169, 488234561, 500214441, 512413449, 524834241, 537479489, 550351881, 563454121, 576788929, 590359041, 604167209, 618216201, 632508801, #if defined(CUSTOM_MODES) /*...208:*/ 647047809, 661836041, 676876329, 692171521, 707724481, 723538089, 739615241, 755958849, 772571841, 789457161, 806617769, 824056641, 841776769, 859781161, 878072841, 896654849, 915530241, 934702089, 954173481, 973947521, 994027329, 1014416041, 1035116809, 1056132801, 1077467201, 1099123209, 1121104041, 1143412929, 1166053121, 1189027881, 1212340489, 1235994241, #endif /*N=6, K=6...96:*/ 1683, 3653, 7183, 13073, 22363, 36365, 56695, 85305, 124515, 177045, 246047, 335137, 448427, 590557, 766727, 982729, 1244979, 1560549, 1937199, 2383409, 2908411, 3522221, 4235671, 5060441, 6009091, 7095093, 8332863, 9737793, 11326283, 13115773, 15124775, 17372905, 19880915, 22670725, 25765455, 29189457, 32968347, 37129037, 41699767, 46710137, 52191139, 58175189, 64696159, 71789409, 79491819, 87841821, 96879431, 106646281, 117185651, 128542501, 140763503, 153897073, 167993403, 183104493, 199284183, 216588185, 235074115, 254801525, 275831935, 298228865, 322057867, 347386557, 374284647, 402823977, 433078547, 465124549, 499040399, 534906769, 572806619, 612825229, 655050231, 699571641, 746481891, 795875861, 847850911, 902506913, 959946283, 1020274013, 1083597703, 1150027593, 1219676595, 1292660325, 1369097135, 1449108145, 1532817275, 1620351277, 1711839767, 1807415257, 1907213187, 2011371957, 2120032959, #if defined(CUSTOM_MODES) /*...109:*/ 2233340609U, 2351442379U, 2474488829U, 2602633639U, 2736033641U, 2874848851U, 3019242501U, 3169381071U, 3325434321U, 3487575323U, 3655980493U, 3830829623U, 4012305913U, #endif /*N=7, K=7...54*/ 8989, 19825, 40081, 75517, 134245, 227305, 369305, 579125, 880685, 1303777, 1884961, 2668525, 3707509, 5064793, 6814249, 9041957, 11847485, 15345233, 19665841, 24957661, 31388293, 39146185, 48442297, 59511829, 72616013, 88043969, 106114625, 127178701, 151620757, 179861305, 212358985, 249612805, 292164445, 340600625, 395555537, 457713341, 527810725, 606639529, 695049433, 793950709, 904317037, 1027188385, 1163673953, 1314955181, 1482288821, 1667010073, 1870535785, 2094367717, #if defined(CUSTOM_MODES) /*...60:*/ 2340095869U, 2609401873U, 2904062449U, 3225952925U, 3577050821U, 3959439497U, #endif /*N=8, K=8...37*/ 48639, 108545, 224143, 433905, 795455, 1392065, 2340495, 3800305, 5984767, 9173505, 13726991, 20103025, 28875327, 40754369, 56610575, 77500017, 104692735, 139703809, 184327311, 240673265, 311207743, 398796225, 506750351, 638878193, 799538175, 993696769, 1226990095, 1505789553, 1837271615, 2229491905U, #if defined(CUSTOM_MODES) /*...40:*/ 2691463695U, 3233240945U, 3866006015U, #endif /*N=9, K=9...28:*/ 265729, 598417, 1256465, 2485825, 4673345, 8405905, 14546705, 24331777, 39490049, 62390545, 96220561, 145198913, 214828609, 312193553, 446304145, 628496897, 872893441, 1196924561, 1621925137, 2173806145U, #if defined(CUSTOM_MODES) /*...29:*/ 2883810113U, #endif /*N=10, K=10...24:*/ 1462563, 3317445, 7059735, 14218905, 27298155, 50250765, 89129247, 152951073, 254831667, 413442773, 654862247, 1014889769, 1541911931, 2300409629U, 3375210671U, /*N=11, K=11...19:*/ 8097453, 18474633, 39753273, 81270333, 158819253, 298199265, 540279585, 948062325, 1616336765, #if defined(CUSTOM_MODES) /*...20:*/ 2684641785U, #endif /*N=12, K=12...18:*/ 45046719, 103274625, 224298231, 464387817, 921406335, 1759885185, 3248227095U, /*N=13, K=13...16:*/ 251595969, 579168825, 1267854873, 2653649025U, /*N=14, K=14:*/ 1409933619 }; #if defined(CUSTOM_MODES) static const opus_uint32 *const CELT_PVQ_U_ROW[15]={ CELT_PVQ_U_DATA+ 0,CELT_PVQ_U_DATA+ 208,CELT_PVQ_U_DATA+ 415, CELT_PVQ_U_DATA+ 621,CELT_PVQ_U_DATA+ 826,CELT_PVQ_U_DATA+1030, CELT_PVQ_U_DATA+1233,CELT_PVQ_U_DATA+1336,CELT_PVQ_U_DATA+1389, CELT_PVQ_U_DATA+1421,CELT_PVQ_U_DATA+1441,CELT_PVQ_U_DATA+1455, CELT_PVQ_U_DATA+1464,CELT_PVQ_U_DATA+1470,CELT_PVQ_U_DATA+1473 }; #else static const opus_uint32 *const CELT_PVQ_U_ROW[15]={ CELT_PVQ_U_DATA+ 0,CELT_PVQ_U_DATA+ 176,CELT_PVQ_U_DATA+ 351, CELT_PVQ_U_DATA+ 525,CELT_PVQ_U_DATA+ 698,CELT_PVQ_U_DATA+ 870, CELT_PVQ_U_DATA+1041,CELT_PVQ_U_DATA+1131,CELT_PVQ_U_DATA+1178, CELT_PVQ_U_DATA+1207,CELT_PVQ_U_DATA+1226,CELT_PVQ_U_DATA+1240, CELT_PVQ_U_DATA+1248,CELT_PVQ_U_DATA+1254,CELT_PVQ_U_DATA+1257 }; #endif #if defined(CUSTOM_MODES) void get_required_bits(opus_int16 *_bits,int _n,int _maxk,int _frac){ int k; /*_maxk==0 => there's nothing to do.*/ celt_assert(_maxk>0); _bits[0]=0; for(k=1;k<=_maxk;k++)_bits[k]=log2_frac(CELT_PVQ_V(_n,k),_frac); } #endif static opus_uint32 icwrs(int _n,const int *_y){ opus_uint32 i; int j; int k; celt_assert(_n>=2); j=_n-1; i=_y[j]<0; k=abs(_y[j]); do{ j--; i+=CELT_PVQ_U(_n-j,k); k+=abs(_y[j]); if(_y[j]<0)i+=CELT_PVQ_U(_n-j,k+1); } while(j>0); return i; } void encode_pulses(const int *_y,int _n,int _k,ec_enc *_enc){ celt_assert(_k>0); ec_enc_uint(_enc,icwrs(_n,_y),CELT_PVQ_V(_n,_k)); } static opus_val32 cwrsi(int _n,int _k,opus_uint32 _i,int *_y){ opus_uint32 p; int s; int k0; opus_int16 val; opus_val32 yy=0; celt_assert(_k>0); celt_assert(_n>1); while(_n>2){ opus_uint32 q; /*Lots of pulses case:*/ if(_k>=_n){ const opus_uint32 *row; row=CELT_PVQ_U_ROW[_n]; /*Are the pulses in this dimension negative?*/ p=row[_k+1]; s=-(_i>=p); _i-=p&s; /*Count how many pulses were placed in this dimension.*/ k0=_k; q=row[_n]; if(q>_i){ celt_sig_assert(p>q); _k=_n; do p=CELT_PVQ_U_ROW[--_k][_n]; while(p>_i); } else for(p=row[_k];p>_i;p=row[_k])_k--; _i-=p; val=(k0-_k+s)^s; *_y++=val; yy=MAC16_16(yy,val,val); } /*Lots of dimensions case:*/ else{ /*Are there any pulses in this dimension at all?*/ p=CELT_PVQ_U_ROW[_k][_n]; q=CELT_PVQ_U_ROW[_k+1][_n]; if(p<=_i&&_i=q); _i-=q&s; /*Count how many pulses were placed in this dimension.*/ k0=_k; do p=CELT_PVQ_U_ROW[--_k][_n]; while(p>_i); _i-=p; val=(k0-_k+s)^s; *_y++=val; yy=MAC16_16(yy,val,val); } } _n--; } /*_n==2*/ p=2*_k+1; s=-(_i>=p); _i-=p&s; k0=_k; _k=(_i+1)>>1; if(_k)_i-=2*_k-1; val=(k0-_k+s)^s; *_y++=val; yy=MAC16_16(yy,val,val); /*_n==1*/ s=-(int)_i; val=(_k+s)^s; *_y=val; yy=MAC16_16(yy,val,val); return yy; } opus_val32 decode_pulses(int *_y,int _n,int _k,ec_dec *_dec){ return cwrsi(_n,_k,ec_dec_uint(_dec,CELT_PVQ_V(_n,_k)),_y); } #else /* SMALL_FOOTPRINT */ /*Computes the next row/column of any recurrence that obeys the relation u[i][j]=u[i-1][j]+u[i][j-1]+u[i-1][j-1]. _ui0 is the base case for the new row/column.*/ static OPUS_INLINE void unext(opus_uint32 *_ui,unsigned _len,opus_uint32 _ui0){ opus_uint32 ui1; unsigned j; /*This do-while will overrun the array if we don't have storage for at least 2 values.*/ j=1; do { ui1=UADD32(UADD32(_ui[j],_ui[j-1]),_ui0); _ui[j-1]=_ui0; _ui0=ui1; } while (++j<_len); _ui[j-1]=_ui0; } /*Computes the previous row/column of any recurrence that obeys the relation u[i-1][j]=u[i][j]-u[i][j-1]-u[i-1][j-1]. _ui0 is the base case for the new row/column.*/ static OPUS_INLINE void uprev(opus_uint32 *_ui,unsigned _n,opus_uint32 _ui0){ opus_uint32 ui1; unsigned j; /*This do-while will overrun the array if we don't have storage for at least 2 values.*/ j=1; do { ui1=USUB32(USUB32(_ui[j],_ui[j-1]),_ui0); _ui[j-1]=_ui0; _ui0=ui1; } while (++j<_n); _ui[j-1]=_ui0; } /*Compute V(_n,_k), as well as U(_n,0..._k+1). _u: On exit, _u[i] contains U(_n,i) for i in [0..._k+1].*/ static opus_uint32 ncwrs_urow(unsigned _n,unsigned _k,opus_uint32 *_u){ opus_uint32 um2; unsigned len; unsigned k; len=_k+2; /*We require storage at least 3 values (e.g., _k>0).*/ celt_assert(len>=3); _u[0]=0; _u[1]=um2=1; /*If _n==0, _u[0] should be 1 and the rest should be 0.*/ /*If _n==1, _u[i] should be 1 for i>1.*/ celt_assert(_n>=2); /*If _k==0, the following do-while loop will overflow the buffer.*/ celt_assert(_k>0); k=2; do _u[k]=(k<<1)-1; while(++k0); j=0; do{ opus_uint32 p; int s; int yj; p=_u[_k+1]; s=-(_i>=p); _i-=p&s; yj=_k; p=_u[_k]; while(p>_i)p=_u[--_k]; _i-=p; yj-=_k; val=(yj+s)^s; _y[j]=val; yy=MAC16_16(yy,val,val); uprev(_u,_k+2,0); } while(++j<_n); return yy; } /*Returns the index of the given combination of K elements chosen from a set of size 1 with associated sign bits. _y: The vector of pulses, whose sum of absolute values is K. _k: Returns K.*/ static OPUS_INLINE opus_uint32 icwrs1(const int *_y,int *_k){ *_k=abs(_y[0]); return _y[0]<0; } /*Returns the index of the given combination of K elements chosen from a set of size _n with associated sign bits. _y: The vector of pulses, whose sum of absolute values must be _k. _nc: Returns V(_n,_k).*/ static OPUS_INLINE opus_uint32 icwrs(int _n,int _k,opus_uint32 *_nc,const int *_y, opus_uint32 *_u){ opus_uint32 i; int j; int k; /*We can't unroll the first two iterations of the loop unless _n>=2.*/ celt_assert(_n>=2); _u[0]=0; for(k=1;k<=_k+1;k++)_u[k]=(k<<1)-1; i=icwrs1(_y+_n-1,&k); j=_n-2; i+=_u[k]; k+=abs(_y[j]); if(_y[j]<0)i+=_u[k+1]; while(j-->0){ unext(_u,_k+2,0); i+=_u[k]; k+=abs(_y[j]); if(_y[j]<0)i+=_u[k+1]; } *_nc=_u[k]+_u[k+1]; return i; } #ifdef CUSTOM_MODES void get_required_bits(opus_int16 *_bits,int _n,int _maxk,int _frac){ int k; /*_maxk==0 => there's nothing to do.*/ celt_assert(_maxk>0); _bits[0]=0; if (_n==1) { for (k=1;k<=_maxk;k++) _bits[k] = 1<<_frac; } else { VARDECL(opus_uint32,u); SAVE_STACK; ALLOC(u,_maxk+2U,opus_uint32); ncwrs_urow(_n,_maxk,u); for(k=1;k<=_maxk;k++) _bits[k]=log2_frac(u[k]+u[k+1],_frac); RESTORE_STACK; } } #endif /* CUSTOM_MODES */ void encode_pulses(const int *_y,int _n,int _k,ec_enc *_enc){ opus_uint32 i; VARDECL(opus_uint32,u); opus_uint32 nc; SAVE_STACK; celt_assert(_k>0); ALLOC(u,_k+2U,opus_uint32); i=icwrs(_n,_k,&nc,_y,u); ec_enc_uint(_enc,i,nc); RESTORE_STACK; } opus_val32 decode_pulses(int *_y,int _n,int _k,ec_dec *_dec){ VARDECL(opus_uint32,u); int ret; SAVE_STACK; celt_assert(_k>0); ALLOC(u,_k+2U,opus_uint32); ret = cwrsi(_n,_k,ec_dec_uint(_dec,ncwrs_urow(_n,_k,u)),_y,u); RESTORE_STACK; return ret; } #endif /* SMALL_FOOTPRINT */ jamulus-3.9.1+dfsg/libs/opus/celt/laplace.c0000644000175000017500000000766614340334543017606 0ustar vimervimer/* Copyright (c) 2007 CSIRO Copyright (c) 2007-2009 Xiph.Org Foundation Written by Jean-Marc Valin */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "laplace.h" #include "mathops.h" /* The minimum probability of an energy delta (out of 32768). */ #define LAPLACE_LOG_MINP (0) #define LAPLACE_MINP (1<>15; } void ec_laplace_encode(ec_enc *enc, int *value, unsigned fs, int decay) { unsigned fl; int val = *value; fl = 0; if (val) { int s; int i; s = -(val<0); val = (val+s)^s; fl = fs; fs = ec_laplace_get_freq1(fs, decay); /* Search the decaying part of the PDF.*/ for (i=1; fs > 0 && i < val; i++) { fs *= 2; fl += fs+2*LAPLACE_MINP; fs = (fs*(opus_int32)decay)>>15; } /* Everything beyond that has probability LAPLACE_MINP. */ if (!fs) { int di; int ndi_max; ndi_max = (32768-fl+LAPLACE_MINP-1)>>LAPLACE_LOG_MINP; ndi_max = (ndi_max-s)>>1; di = IMIN(val - i, ndi_max - 1); fl += (2*di+1+s)*LAPLACE_MINP; fs = IMIN(LAPLACE_MINP, 32768-fl); *value = (i+di+s)^s; } else { fs += LAPLACE_MINP; fl += fs&~s; } celt_assert(fl+fs<=32768); celt_assert(fs>0); } ec_encode_bin(enc, fl, fl+fs, 15); } int ec_laplace_decode(ec_dec *dec, unsigned fs, int decay) { int val=0; unsigned fl; unsigned fm; fm = ec_decode_bin(dec, 15); fl = 0; if (fm >= fs) { val++; fl = fs; fs = ec_laplace_get_freq1(fs, decay)+LAPLACE_MINP; /* Search the decaying part of the PDF.*/ while(fs > LAPLACE_MINP && fm >= fl+2*fs) { fs *= 2; fl += fs; fs = ((fs-2*LAPLACE_MINP)*(opus_int32)decay)>>15; fs += LAPLACE_MINP; val++; } /* Everything beyond that has probability LAPLACE_MINP. */ if (fs <= LAPLACE_MINP) { int di; di = (fm-fl)>>(LAPLACE_LOG_MINP+1); val += di; fl += 2*di*LAPLACE_MINP; } if (fm < fl+fs) val = -val; else fl += fs; } celt_assert(fl<32768); celt_assert(fs>0); celt_assert(fl<=fm); celt_assert(fm>1; b=1U<>=1; bshift--; } while(bshift>=0); return g; } #ifdef FIXED_POINT opus_val32 frac_div32(opus_val32 a, opus_val32 b) { opus_val16 rcp; opus_val32 result, rem; int shift = celt_ilog2(b)-29; a = VSHR32(a,shift); b = VSHR32(b,shift); /* 16-bit reciprocal */ rcp = ROUND16(celt_rcp(ROUND16(b,16)),3); result = MULT16_32_Q15(rcp, a); rem = PSHR32(a,2)-MULT32_32_Q31(result, b); result = ADD32(result, SHL32(MULT16_32_Q15(rcp, rem),2)); if (result >= 536870912) /* 2^29 */ return 2147483647; /* 2^31 - 1 */ else if (result <= -536870912) /* -2^29 */ return -2147483647; /* -2^31 */ else return SHL32(result, 2); } /** Reciprocal sqrt approximation in the range [0.25,1) (Q16 in, Q14 out) */ opus_val16 celt_rsqrt_norm(opus_val32 x) { opus_val16 n; opus_val16 r; opus_val16 r2; opus_val16 y; /* Range of n is [-16384,32767] ([-0.5,1) in Q15). */ n = x-32768; /* Get a rough initial guess for the root. The optimal minimax quadratic approximation (using relative error) is r = 1.437799046117536+n*(-0.823394375837328+n*0.4096419668459485). Coefficients here, and the final result r, are Q14.*/ r = ADD16(23557, MULT16_16_Q15(n, ADD16(-13490, MULT16_16_Q15(n, 6713)))); /* We want y = x*r*r-1 in Q15, but x is 32-bit Q16 and r is Q14. We can compute the result from n and r using Q15 multiplies with some adjustment, carefully done to avoid overflow. Range of y is [-1564,1594]. */ r2 = MULT16_16_Q15(r, r); y = SHL16(SUB16(ADD16(MULT16_16_Q15(r2, n), r2), 16384), 1); /* Apply a 2nd-order Householder iteration: r += r*y*(y*0.375-0.5). This yields the Q14 reciprocal square root of the Q16 x, with a maximum relative error of 1.04956E-4, a (relative) RMSE of 2.80979E-5, and a peak absolute error of 2.26591/16384. */ return ADD16(r, MULT16_16_Q15(r, MULT16_16_Q15(y, SUB16(MULT16_16_Q15(y, 12288), 16384)))); } /** Sqrt approximation (QX input, QX/2 output) */ opus_val32 celt_sqrt(opus_val32 x) { int k; opus_val16 n; opus_val32 rt; static const opus_val16 C[5] = {23175, 11561, -3011, 1699, -664}; if (x==0) return 0; else if (x>=1073741824) return 32767; k = (celt_ilog2(x)>>1)-7; x = VSHR32(x, 2*k); n = x-32768; rt = ADD16(C[0], MULT16_16_Q15(n, ADD16(C[1], MULT16_16_Q15(n, ADD16(C[2], MULT16_16_Q15(n, ADD16(C[3], MULT16_16_Q15(n, (C[4]))))))))); rt = VSHR32(rt,7-k); return rt; } #define L1 32767 #define L2 -7651 #define L3 8277 #define L4 -626 static OPUS_INLINE opus_val16 _celt_cos_pi_2(opus_val16 x) { opus_val16 x2; x2 = MULT16_16_P15(x,x); return ADD16(1,MIN16(32766,ADD32(SUB16(L1,x2), MULT16_16_P15(x2, ADD32(L2, MULT16_16_P15(x2, ADD32(L3, MULT16_16_P15(L4, x2 )))))))); } #undef L1 #undef L2 #undef L3 #undef L4 opus_val16 celt_cos_norm(opus_val32 x) { x = x&0x0001ffff; if (x>SHL32(EXTEND32(1), 16)) x = SUB32(SHL32(EXTEND32(1), 17),x); if (x&0x00007fff) { if (x0); i = celt_ilog2(x); /* n is Q15 with range [0,1). */ n = VSHR32(x,i-15)-32768; /* Start with a linear approximation: r = 1.8823529411764706-0.9411764705882353*n. The coefficients and the result are Q14 in the range [15420,30840].*/ r = ADD16(30840, MULT16_16_Q15(-15420, n)); /* Perform two Newton iterations: r -= r*((r*n)-1.Q15) = r*((r*n)+(r-1.Q15)). */ r = SUB16(r, MULT16_16_Q15(r, ADD16(MULT16_16_Q15(r, n), ADD16(r, -32768)))); /* We subtract an extra 1 in the second iteration to avoid overflow; it also neatly compensates for truncation error in the rest of the process. */ r = SUB16(r, ADD16(1, MULT16_16_Q15(r, ADD16(MULT16_16_Q15(r, n), ADD16(r, -32768))))); /* r is now the Q15 solution to 2/(n+1), with a maximum relative error of 7.05346E-5, a (relative) RMSE of 2.14418E-5, and a peak absolute error of 1.24665/32768. */ return VSHR32(EXTEND32(r),i-16); } #endif jamulus-3.9.1+dfsg/libs/opus/celt/entenc.c0000644000175000017500000002253114340334543017445 0ustar vimervimer/* Copyright (c) 2001-2011 Timothy B. Terriberry Copyright (c) 2008-2009 Xiph.Org Foundation */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if defined(HAVE_CONFIG_H) # include "config.h" #endif #include "os_support.h" #include "arch.h" #include "entenc.h" #include "mfrngcod.h" /*A range encoder. See entdec.c and the references for implementation details \cite{Mar79,MNW98}. @INPROCEEDINGS{Mar79, author="Martin, G.N.N.", title="Range encoding: an algorithm for removing redundancy from a digitised message", booktitle="Video \& Data Recording Conference", year=1979, address="Southampton", month=Jul } @ARTICLE{MNW98, author="Alistair Moffat and Radford Neal and Ian H. Witten", title="Arithmetic Coding Revisited", journal="{ACM} Transactions on Information Systems", year=1998, volume=16, number=3, pages="256--294", month=Jul, URL="http://www.stanford.edu/class/ee398/handouts/papers/Moffat98ArithmCoding.pdf" }*/ static int ec_write_byte(ec_enc *_this,unsigned _value){ if(_this->offs+_this->end_offs>=_this->storage)return -1; _this->buf[_this->offs++]=(unsigned char)_value; return 0; } static int ec_write_byte_at_end(ec_enc *_this,unsigned _value){ if(_this->offs+_this->end_offs>=_this->storage)return -1; _this->buf[_this->storage-++(_this->end_offs)]=(unsigned char)_value; return 0; } /*Outputs a symbol, with a carry bit. If there is a potential to propagate a carry over several symbols, they are buffered until it can be determined whether or not an actual carry will occur. If the counter for the buffered symbols overflows, then the stream becomes undecodable. This gives a theoretical limit of a few billion symbols in a single packet on 32-bit systems. The alternative is to truncate the range in order to force a carry, but requires similar carry tracking in the decoder, needlessly slowing it down.*/ static void ec_enc_carry_out(ec_enc *_this,int _c){ if(_c!=EC_SYM_MAX){ /*No further carry propagation possible, flush buffer.*/ int carry; carry=_c>>EC_SYM_BITS; /*Don't output a byte on the first write. This compare should be taken care of by branch-prediction thereafter.*/ if(_this->rem>=0)_this->error|=ec_write_byte(_this,_this->rem+carry); if(_this->ext>0){ unsigned sym; sym=(EC_SYM_MAX+carry)&EC_SYM_MAX; do _this->error|=ec_write_byte(_this,sym); while(--(_this->ext)>0); } _this->rem=_c&EC_SYM_MAX; } else _this->ext++; } static OPUS_INLINE void ec_enc_normalize(ec_enc *_this){ /*If the range is too small, output some bits and rescale it.*/ while(_this->rng<=EC_CODE_BOT){ ec_enc_carry_out(_this,(int)(_this->val>>EC_CODE_SHIFT)); /*Move the next-to-high-order symbol into the high-order position.*/ _this->val=(_this->val<rng<<=EC_SYM_BITS; _this->nbits_total+=EC_SYM_BITS; } } void ec_enc_init(ec_enc *_this,unsigned char *_buf,opus_uint32 _size){ _this->buf=_buf; _this->end_offs=0; _this->end_window=0; _this->nend_bits=0; /*This is the offset from which ec_tell() will subtract partial bits.*/ _this->nbits_total=EC_CODE_BITS+1; _this->offs=0; _this->rng=EC_CODE_TOP; _this->rem=-1; _this->val=0; _this->ext=0; _this->storage=_size; _this->error=0; } void ec_encode(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _ft){ opus_uint32 r; r=celt_udiv(_this->rng,_ft); if(_fl>0){ _this->val+=_this->rng-IMUL32(r,(_ft-_fl)); _this->rng=IMUL32(r,(_fh-_fl)); } else _this->rng-=IMUL32(r,(_ft-_fh)); ec_enc_normalize(_this); } void ec_encode_bin(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _bits){ opus_uint32 r; r=_this->rng>>_bits; if(_fl>0){ _this->val+=_this->rng-IMUL32(r,((1U<<_bits)-_fl)); _this->rng=IMUL32(r,(_fh-_fl)); } else _this->rng-=IMUL32(r,((1U<<_bits)-_fh)); ec_enc_normalize(_this); } /*The probability of having a "one" is 1/(1<<_logp).*/ void ec_enc_bit_logp(ec_enc *_this,int _val,unsigned _logp){ opus_uint32 r; opus_uint32 s; opus_uint32 l; r=_this->rng; l=_this->val; s=r>>_logp; r-=s; if(_val)_this->val=l+r; _this->rng=_val?s:r; ec_enc_normalize(_this); } void ec_enc_icdf(ec_enc *_this,int _s,const unsigned char *_icdf,unsigned _ftb){ opus_uint32 r; r=_this->rng>>_ftb; if(_s>0){ _this->val+=_this->rng-IMUL32(r,_icdf[_s-1]); _this->rng=IMUL32(r,_icdf[_s-1]-_icdf[_s]); } else _this->rng-=IMUL32(r,_icdf[_s]); ec_enc_normalize(_this); } void ec_enc_uint(ec_enc *_this,opus_uint32 _fl,opus_uint32 _ft){ unsigned ft; unsigned fl; int ftb; /*In order to optimize EC_ILOG(), it is undefined for the value 0.*/ celt_assert(_ft>1); _ft--; ftb=EC_ILOG(_ft); if(ftb>EC_UINT_BITS){ ftb-=EC_UINT_BITS; ft=(_ft>>ftb)+1; fl=(unsigned)(_fl>>ftb); ec_encode(_this,fl,fl+1,ft); ec_enc_bits(_this,_fl&(((opus_uint32)1<end_window; used=_this->nend_bits; celt_assert(_bits>0); if(used+_bits>EC_WINDOW_SIZE){ do{ _this->error|=ec_write_byte_at_end(_this,(unsigned)window&EC_SYM_MAX); window>>=EC_SYM_BITS; used-=EC_SYM_BITS; } while(used>=EC_SYM_BITS); } window|=(ec_window)_fl<end_window=window; _this->nend_bits=used; _this->nbits_total+=_bits; } void ec_enc_patch_initial_bits(ec_enc *_this,unsigned _val,unsigned _nbits){ int shift; unsigned mask; celt_assert(_nbits<=EC_SYM_BITS); shift=EC_SYM_BITS-_nbits; mask=((1<<_nbits)-1)<offs>0){ /*The first byte has been finalized.*/ _this->buf[0]=(unsigned char)((_this->buf[0]&~mask)|_val<rem>=0){ /*The first byte is still awaiting carry propagation.*/ _this->rem=(_this->rem&~mask)|_val<rng<=(EC_CODE_TOP>>_nbits)){ /*The renormalization loop has never been run.*/ _this->val=(_this->val&~((opus_uint32)mask<error=-1; } void ec_enc_shrink(ec_enc *_this,opus_uint32 _size){ celt_assert(_this->offs+_this->end_offs<=_size); OPUS_MOVE(_this->buf+_size-_this->end_offs, _this->buf+_this->storage-_this->end_offs,_this->end_offs); _this->storage=_size; } void ec_enc_done(ec_enc *_this){ ec_window window; int used; opus_uint32 msk; opus_uint32 end; int l; /*We output the minimum number of bits that ensures that the symbols encoded thus far will be decoded correctly regardless of the bits that follow.*/ l=EC_CODE_BITS-EC_ILOG(_this->rng); msk=(EC_CODE_TOP-1)>>l; end=(_this->val+msk)&~msk; if((end|msk)>=_this->val+_this->rng){ l++; msk>>=1; end=(_this->val+msk)&~msk; } while(l>0){ ec_enc_carry_out(_this,(int)(end>>EC_CODE_SHIFT)); end=(end<rem>=0||_this->ext>0)ec_enc_carry_out(_this,0); /*If we have buffered extra bits, flush them as well.*/ window=_this->end_window; used=_this->nend_bits; while(used>=EC_SYM_BITS){ _this->error|=ec_write_byte_at_end(_this,(unsigned)window&EC_SYM_MAX); window>>=EC_SYM_BITS; used-=EC_SYM_BITS; } /*Clear any excess space and add any remaining extra bits to the last byte.*/ if(!_this->error){ OPUS_CLEAR(_this->buf+_this->offs, _this->storage-_this->offs-_this->end_offs); if(used>0){ /*If there's no range coder data at all, give up.*/ if(_this->end_offs>=_this->storage)_this->error=-1; else{ l=-l; /*If we've busted, don't add too many extra bits to the last byte; it would corrupt the range coder data, and that's more important.*/ if(_this->offs+_this->end_offs>=_this->storage&&lerror=-1; } _this->buf[_this->storage-_this->end_offs-1]|=(unsigned char)window; } } } } jamulus-3.9.1+dfsg/libs/opus/celt/float_cast.h0000644000175000017500000001170314340334543020314 0ustar vimervimer/* Copyright (C) 2001 Erik de Castro Lopo */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* Version 1.1 */ #ifndef FLOAT_CAST_H #define FLOAT_CAST_H #include "arch.h" /*============================================================================ ** On Intel Pentium processors (especially PIII and probably P4), converting ** from float to int is very slow. To meet the C specs, the code produced by ** most C compilers targeting Pentium needs to change the FPU rounding mode ** before the float to int conversion is performed. ** ** Changing the FPU rounding mode causes the FPU pipeline to be flushed. It ** is this flushing of the pipeline which is so slow. ** ** Fortunately the ISO C99 specifications define the functions lrint, lrintf, ** llrint and llrintf which fix this problem as a side effect. ** ** On Unix-like systems, the configure process should have detected the ** presence of these functions. If they weren't found we have to replace them ** here with a standard C cast. */ /* ** The C99 prototypes for lrint and lrintf are as follows: ** ** long int lrintf (float x) ; ** long int lrint (double x) ; */ /* The presence of the required functions are detected during the configure ** process and the values HAVE_LRINT and HAVE_LRINTF are set accordingly in ** the config.h file. */ /* With GCC, when SSE is available, the fastest conversion is cvtss2si. */ #if defined(__GNUC__) && defined(__SSE__) #include static OPUS_INLINE opus_int32 float2int(float x) {return _mm_cvt_ss2si(_mm_set_ss(x));} #elif defined(HAVE_LRINTF) /* These defines enable functionality introduced with the 1999 ISO C ** standard. They must be defined before the inclusion of math.h to ** engage them. If optimisation is enabled, these functions will be ** inlined. With optimisation switched off, you have to link in the ** maths library using -lm. */ #define _ISOC9X_SOURCE 1 #define _ISOC99_SOURCE 1 #define __USE_ISOC9X 1 #define __USE_ISOC99 1 #include #define float2int(x) lrintf(x) #elif (defined(HAVE_LRINT)) #define _ISOC9X_SOURCE 1 #define _ISOC99_SOURCE 1 #define __USE_ISOC9X 1 #define __USE_ISOC99 1 #include #define float2int(x) lrint(x) #elif (defined(_MSC_VER) && _MSC_VER >= 1400) && (defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 1)) #include static __inline long int float2int(float value) { return _mm_cvtss_si32(_mm_load_ss(&value)); } #elif (defined(_MSC_VER) && _MSC_VER >= 1400) && defined (_M_IX86) #include /* Win32 doesn't seem to have these functions. ** Therefore implement OPUS_INLINE versions of these functions here. */ static __inline long int float2int (float flt) { int intgr; _asm { fld flt fistp intgr } ; return intgr ; } #else #if (defined(__GNUC__) && defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) /* supported by gcc in C99 mode, but not by all other compilers */ #warning "Don't have the functions lrint() and lrintf ()." #warning "Replacing these functions with a standard C cast." #endif /* __STDC_VERSION__ >= 199901L */ #include #define float2int(flt) ((int)(floor(.5+flt))) #endif #ifndef DISABLE_FLOAT_API static OPUS_INLINE opus_int16 FLOAT2INT16(float x) { x = x*CELT_SIG_SCALE; x = MAX32(x, -32768); x = MIN32(x, 32767); return (opus_int16)float2int(x); } #endif /* DISABLE_FLOAT_API */ #endif /* FLOAT_CAST_H */ jamulus-3.9.1+dfsg/libs/opus/celt/pitch.c0000644000175000017500000003367714340334543017315 0ustar vimervimer/* Copyright (c) 2007-2008 CSIRO Copyright (c) 2007-2009 Xiph.Org Foundation Written by Jean-Marc Valin */ /** @file pitch.c @brief Pitch analysis */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "pitch.h" #include "os_support.h" #include "modes.h" #include "stack_alloc.h" #include "mathops.h" #include "celt_lpc.h" static void find_best_pitch(opus_val32 *xcorr, opus_val16 *y, int len, int max_pitch, int *best_pitch #ifdef FIXED_POINT , int yshift, opus_val32 maxcorr #endif ) { int i, j; opus_val32 Syy=1; opus_val16 best_num[2]; opus_val32 best_den[2]; #ifdef FIXED_POINT int xshift; xshift = celt_ilog2(maxcorr)-14; #endif best_num[0] = -1; best_num[1] = -1; best_den[0] = 0; best_den[1] = 0; best_pitch[0] = 0; best_pitch[1] = 1; for (j=0;j0) { opus_val16 num; opus_val32 xcorr16; xcorr16 = EXTRACT16(VSHR32(xcorr[i], xshift)); #ifndef FIXED_POINT /* Considering the range of xcorr16, this should avoid both underflows and overflows (inf) when squaring xcorr16 */ xcorr16 *= 1e-12f; #endif num = MULT16_16_Q15(xcorr16,xcorr16); if (MULT16_32_Q15(num,best_den[1]) > MULT16_32_Q15(best_num[1],Syy)) { if (MULT16_32_Q15(num,best_den[0]) > MULT16_32_Q15(best_num[0],Syy)) { best_num[1] = best_num[0]; best_den[1] = best_den[0]; best_pitch[1] = best_pitch[0]; best_num[0] = num; best_den[0] = Syy; best_pitch[0] = i; } else { best_num[1] = num; best_den[1] = Syy; best_pitch[1] = i; } } } Syy += SHR32(MULT16_16(y[i+len],y[i+len]),yshift) - SHR32(MULT16_16(y[i],y[i]),yshift); Syy = MAX32(1, Syy); } } static void celt_fir5(opus_val16 *x, const opus_val16 *num, int N) { int i; opus_val16 num0, num1, num2, num3, num4; opus_val32 mem0, mem1, mem2, mem3, mem4; num0=num[0]; num1=num[1]; num2=num[2]; num3=num[3]; num4=num[4]; mem0=0; mem1=0; mem2=0; mem3=0; mem4=0; for (i=0;i>1;i++) x_lp[i] = SHR32(HALF32(HALF32(x[0][(2*i-1)]+x[0][(2*i+1)])+x[0][2*i]), shift); x_lp[0] = SHR32(HALF32(HALF32(x[0][1])+x[0][0]), shift); if (C==2) { for (i=1;i>1;i++) x_lp[i] += SHR32(HALF32(HALF32(x[1][(2*i-1)]+x[1][(2*i+1)])+x[1][2*i]), shift); x_lp[0] += SHR32(HALF32(HALF32(x[1][1])+x[1][0]), shift); } _celt_autocorr(x_lp, ac, NULL, 0, 4, len>>1, arch); /* Noise floor -40 dB */ #ifdef FIXED_POINT ac[0] += SHR32(ac[0],13); #else ac[0] *= 1.0001f; #endif /* Lag windowing */ for (i=1;i<=4;i++) { /*ac[i] *= exp(-.5*(2*M_PI*.002*i)*(2*M_PI*.002*i));*/ #ifdef FIXED_POINT ac[i] -= MULT16_32_Q15(2*i*i, ac[i]); #else ac[i] -= ac[i]*(.008f*i)*(.008f*i); #endif } _celt_lpc(lpc, ac, 4); for (i=0;i<4;i++) { tmp = MULT16_16_Q15(QCONST16(.9f,15), tmp); lpc[i] = MULT16_16_Q15(lpc[i], tmp); } /* Add a zero */ lpc2[0] = lpc[0] + QCONST16(.8f,SIG_SHIFT); lpc2[1] = lpc[1] + MULT16_16_Q15(c1,lpc[0]); lpc2[2] = lpc[2] + MULT16_16_Q15(c1,lpc[1]); lpc2[3] = lpc[3] + MULT16_16_Q15(c1,lpc[2]); lpc2[4] = MULT16_16_Q15(c1,lpc[3]); celt_fir5(x_lp, lpc2, len>>1); } /* Pure C implementation. */ #ifdef FIXED_POINT opus_val32 #else void #endif celt_pitch_xcorr_c(const opus_val16 *_x, const opus_val16 *_y, opus_val32 *xcorr, int len, int max_pitch, int arch) { #if 0 /* This is a simple version of the pitch correlation that should work well on DSPs like Blackfin and TI C5x/C6x */ int i, j; #ifdef FIXED_POINT opus_val32 maxcorr=1; #endif #if !defined(OVERRIDE_PITCH_XCORR) (void)arch; #endif for (i=0;i0); celt_sig_assert((((unsigned char *)_x-(unsigned char *)NULL)&3)==0); for (i=0;i0); celt_assert(max_pitch>0); lag = len+max_pitch; ALLOC(x_lp4, len>>2, opus_val16); ALLOC(y_lp4, lag>>2, opus_val16); ALLOC(xcorr, max_pitch>>1, opus_val32); /* Downsample by 2 again */ for (j=0;j>2;j++) x_lp4[j] = x_lp[2*j]; for (j=0;j>2;j++) y_lp4[j] = y[2*j]; #ifdef FIXED_POINT xmax = celt_maxabs16(x_lp4, len>>2); ymax = celt_maxabs16(y_lp4, lag>>2); shift = celt_ilog2(MAX32(1, MAX32(xmax, ymax)))-11; if (shift>0) { for (j=0;j>2;j++) x_lp4[j] = SHR16(x_lp4[j], shift); for (j=0;j>2;j++) y_lp4[j] = SHR16(y_lp4[j], shift); /* Use double the shift for a MAC */ shift *= 2; } else { shift = 0; } #endif /* Coarse search with 4x decimation */ #ifdef FIXED_POINT maxcorr = #endif celt_pitch_xcorr(x_lp4, y_lp4, xcorr, len>>2, max_pitch>>2, arch); find_best_pitch(xcorr, y_lp4, len>>2, max_pitch>>2, best_pitch #ifdef FIXED_POINT , 0, maxcorr #endif ); /* Finer search with 2x decimation */ #ifdef FIXED_POINT maxcorr=1; #endif for (i=0;i>1;i++) { opus_val32 sum; xcorr[i] = 0; if (abs(i-2*best_pitch[0])>2 && abs(i-2*best_pitch[1])>2) continue; #ifdef FIXED_POINT sum = 0; for (j=0;j>1;j++) sum += SHR32(MULT16_16(x_lp[j],y[i+j]), shift); #else sum = celt_inner_prod(x_lp, y+i, len>>1, arch); #endif xcorr[i] = MAX32(-1, sum); #ifdef FIXED_POINT maxcorr = MAX32(maxcorr, sum); #endif } find_best_pitch(xcorr, y, len>>1, max_pitch>>1, best_pitch #ifdef FIXED_POINT , shift+1, maxcorr #endif ); /* Refine by pseudo-interpolation */ if (best_pitch[0]>0 && best_pitch[0]<(max_pitch>>1)-1) { opus_val32 a, b, c; a = xcorr[best_pitch[0]-1]; b = xcorr[best_pitch[0]]; c = xcorr[best_pitch[0]+1]; if ((c-a) > MULT16_32_Q15(QCONST16(.7f,15),b-a)) offset = 1; else if ((a-c) > MULT16_32_Q15(QCONST16(.7f,15),b-c)) offset = -1; else offset = 0; } else { offset = 0; } *pitch = 2*best_pitch[0]-offset; RESTORE_STACK; } #ifdef FIXED_POINT static opus_val16 compute_pitch_gain(opus_val32 xy, opus_val32 xx, opus_val32 yy) { opus_val32 x2y2; int sx, sy, shift; opus_val32 g; opus_val16 den; if (xy == 0 || xx == 0 || yy == 0) return 0; sx = celt_ilog2(xx)-14; sy = celt_ilog2(yy)-14; shift = sx + sy; x2y2 = SHR32(MULT16_16(VSHR32(xx, sx), VSHR32(yy, sy)), 14); if (shift & 1) { if (x2y2 < 32768) { x2y2 <<= 1; shift--; } else { x2y2 >>= 1; shift++; } } den = celt_rsqrt_norm(x2y2); g = MULT16_32_Q15(den, xy); g = VSHR32(g, (shift>>1)-1); return EXTRACT16(MIN32(g, Q15ONE)); } #else static opus_val16 compute_pitch_gain(opus_val32 xy, opus_val32 xx, opus_val32 yy) { return xy/celt_sqrt(1+xx*yy); } #endif static const int second_check[16] = {0, 0, 3, 2, 3, 2, 5, 2, 3, 2, 3, 2, 5, 2, 3, 2}; opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod, int N, int *T0_, int prev_period, opus_val16 prev_gain, int arch) { int k, i, T, T0; opus_val16 g, g0; opus_val16 pg; opus_val32 xy,xx,yy,xy2; opus_val32 xcorr[3]; opus_val32 best_xy, best_yy; int offset; int minperiod0; VARDECL(opus_val32, yy_lookup); SAVE_STACK; minperiod0 = minperiod; maxperiod /= 2; minperiod /= 2; *T0_ /= 2; prev_period /= 2; N /= 2; x += maxperiod; if (*T0_>=maxperiod) *T0_=maxperiod-1; T = T0 = *T0_; ALLOC(yy_lookup, maxperiod+1, opus_val32); dual_inner_prod(x, x, x-T0, N, &xx, &xy, arch); yy_lookup[0] = xx; yy=xx; for (i=1;i<=maxperiod;i++) { yy = yy+MULT16_16(x[-i],x[-i])-MULT16_16(x[N-i],x[N-i]); yy_lookup[i] = MAX32(0, yy); } yy = yy_lookup[T0]; best_xy = xy; best_yy = yy; g = g0 = compute_pitch_gain(xy, xx, yy); /* Look for any pitch at T/k */ for (k=2;k<=15;k++) { int T1, T1b; opus_val16 g1; opus_val16 cont=0; opus_val16 thresh; T1 = celt_udiv(2*T0+k, 2*k); if (T1 < minperiod) break; /* Look for another strong correlation at T1b */ if (k==2) { if (T1+T0>maxperiod) T1b = T0; else T1b = T0+T1; } else { T1b = celt_udiv(2*second_check[k]*T0+k, 2*k); } dual_inner_prod(x, &x[-T1], &x[-T1b], N, &xy, &xy2, arch); xy = HALF32(xy + xy2); yy = HALF32(yy_lookup[T1] + yy_lookup[T1b]); g1 = compute_pitch_gain(xy, xx, yy); if (abs(T1-prev_period)<=1) cont = prev_gain; else if (abs(T1-prev_period)<=2 && 5*k*k < T0) cont = HALF16(prev_gain); else cont = 0; thresh = MAX16(QCONST16(.3f,15), MULT16_16_Q15(QCONST16(.7f,15),g0)-cont); /* Bias against very high pitch (very short period) to avoid false-positives due to short-term correlation */ if (T1<3*minperiod) thresh = MAX16(QCONST16(.4f,15), MULT16_16_Q15(QCONST16(.85f,15),g0)-cont); else if (T1<2*minperiod) thresh = MAX16(QCONST16(.5f,15), MULT16_16_Q15(QCONST16(.9f,15),g0)-cont); if (g1 > thresh) { best_xy = xy; best_yy = yy; T = T1; g = g1; } } best_xy = MAX32(0, best_xy); if (best_yy <= best_xy) pg = Q15ONE; else pg = SHR32(frac_div32(best_xy,best_yy+1),16); for (k=0;k<3;k++) xcorr[k] = celt_inner_prod(x, x-(T+k-1), N, arch); if ((xcorr[2]-xcorr[0]) > MULT16_32_Q15(QCONST16(.7f,15),xcorr[1]-xcorr[0])) offset = 1; else if ((xcorr[0]-xcorr[2]) > MULT16_32_Q15(QCONST16(.7f,15),xcorr[1]-xcorr[2])) offset = -1; else offset = 0; if (pg > g) pg = g; *T0_ = 2*T+offset; if (*T0_ #include #include "arch.h" #if !defined(_ecintrin_H) # define _ecintrin_H (1) /*Some specific platforms may have optimized intrinsic or OPUS_INLINE assembly versions of these functions which can substantially improve performance. We define macros for them to allow easy incorporation of these non-ANSI features.*/ /*Modern gcc (4.x) can compile the naive versions of min and max with cmov if given an appropriate architecture, but the branchless bit-twiddling versions are just as fast, and do not require any special target architecture. Earlier gcc versions (3.x) compiled both code to the same assembly instructions, because of the way they represented ((_b)>(_a)) internally.*/ # define EC_MINI(_a,_b) ((_a)+(((_b)-(_a))&-((_b)<(_a)))) /*Count leading zeros. This macro should only be used for implementing ec_ilog(), if it is defined. All other code should use EC_ILOG() instead.*/ #if defined(_MSC_VER) && (_MSC_VER >= 1400) # include /*In _DEBUG mode this is not an intrinsic by default.*/ # pragma intrinsic(_BitScanReverse) static __inline int ec_bsr(unsigned long _x){ unsigned long ret; _BitScanReverse(&ret,_x); return (int)ret; } # define EC_CLZ0 (1) # define EC_CLZ(_x) (-ec_bsr(_x)) #elif defined(ENABLE_TI_DSPLIB) # include "dsplib.h" # define EC_CLZ0 (31) # define EC_CLZ(_x) (_lnorm(_x)) #elif __GNUC_PREREQ(3,4) # if INT_MAX>=2147483647 # define EC_CLZ0 ((int)sizeof(unsigned)*CHAR_BIT) # define EC_CLZ(_x) (__builtin_clz(_x)) # elif LONG_MAX>=2147483647L # define EC_CLZ0 ((int)sizeof(unsigned long)*CHAR_BIT) # define EC_CLZ(_x) (__builtin_clzl(_x)) # endif #endif #if defined(EC_CLZ) /*Note that __builtin_clz is not defined when _x==0, according to the gcc documentation (and that of the BSR instruction that implements it on x86). The majority of the time we can never pass it zero. When we need to, it can be special cased.*/ # define EC_ILOG(_x) (EC_CLZ0-EC_CLZ(_x)) #else int ec_ilog(opus_uint32 _v); # define EC_ILOG(_x) (ec_ilog(_x)) #endif #endif jamulus-3.9.1+dfsg/libs/opus/celt/bands.h0000644000175000017500000001250314340334543017263 0ustar vimervimer/* Copyright (c) 2007-2008 CSIRO Copyright (c) 2007-2009 Xiph.Org Foundation Copyright (c) 2008-2009 Gregory Maxwell Written by Jean-Marc Valin and Gregory Maxwell */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef BANDS_H #define BANDS_H #include "arch.h" #include "modes.h" #include "entenc.h" #include "entdec.h" #include "rate.h" opus_int16 bitexact_cos(opus_int16 x); int bitexact_log2tan(int isin,int icos); /** Compute the amplitude (sqrt energy) in each of the bands * @param m Mode data * @param X Spectrum * @param bandE Square root of the energy for each band (returned) */ void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int LM, int arch); /*void compute_noise_energies(const CELTMode *m, const celt_sig *X, const opus_val16 *tonality, celt_ener *bandE);*/ /** Normalise each band of X such that the energy in each band is equal to 1 * @param m Mode data * @param X Spectrum (returned normalised) * @param bandE Square root of the energy for each band */ void normalise_bands(const CELTMode *m, const celt_sig * OPUS_RESTRICT freq, celt_norm * OPUS_RESTRICT X, const celt_ener *bandE, int end, int C, int M); /** Denormalise each band of X to restore full amplitude * @param m Mode data * @param X Spectrum (returned de-normalised) * @param bandE Square root of the energy for each band */ void denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X, celt_sig * OPUS_RESTRICT freq, const opus_val16 *bandE, int start, int end, int M, int downsample, int silence); #define SPREAD_NONE (0) #define SPREAD_LIGHT (1) #define SPREAD_NORMAL (2) #define SPREAD_AGGRESSIVE (3) int spreading_decision(const CELTMode *m, const celt_norm *X, int *average, int last_decision, int *hf_average, int *tapset_decision, int update_hf, int end, int C, int M, const int *spread_weight); #ifdef MEASURE_NORM_MSE void measure_norm_mse(const CELTMode *m, float *X, float *X0, float *bandE, float *bandE0, int M, int N, int C); #endif void haar1(celt_norm *X, int N0, int stride); /** Quantisation/encoding of the residual spectrum * @param encode flag that indicates whether we're encoding (1) or decoding (0) * @param m Mode data * @param start First band to process * @param end Last band to process + 1 * @param X Residual (normalised) * @param Y Residual (normalised) for second channel (or NULL for mono) * @param collapse_masks Anti-collapse tracking mask * @param bandE Square root of the energy for each band * @param pulses Bit allocation (per band) for PVQ * @param shortBlocks Zero for long blocks, non-zero for short blocks * @param spread Amount of spreading to use * @param dual_stereo Zero for MS stereo, non-zero for dual stereo * @param intensity First band to use intensity stereo * @param tf_res Time-frequency resolution change * @param total_bits Total number of bits that can be used for the frame (including the ones already spent) * @param balance Number of unallocated bits * @param en Entropy coder state * @param LM log2() of the number of 2.5 subframes in the frame * @param codedBands Last band to receive bits + 1 * @param seed Random generator seed * @param arch Run-time architecture (see opus_select_arch()) */ void quant_all_bands(int encode, const CELTMode *m, int start, int end, celt_norm * X, celt_norm * Y, unsigned char *collapse_masks, const celt_ener *bandE, int *pulses, int shortBlocks, int spread, int dual_stereo, int intensity, int *tf_res, opus_int32 total_bits, opus_int32 balance, ec_ctx *ec, int M, int codedBands, opus_uint32 *seed, int complexity, int arch, int disable_inv); void anti_collapse(const CELTMode *m, celt_norm *X_, unsigned char *collapse_masks, int LM, int C, int size, int start, int end, const opus_val16 *logE, const opus_val16 *prev1logE, const opus_val16 *prev2logE, const int *pulses, opus_uint32 seed, int arch); opus_uint32 celt_lcg_rand(opus_uint32 seed); int hysteresis_decision(opus_val16 val, const opus_val16 *thresholds, const opus_val16 *hysteresis, int N, int prev); #endif /* BANDS_H */ jamulus-3.9.1+dfsg/libs/opus/celt/mips/0000755000175000017500000000000014340334543016772 5ustar vimervimerjamulus-3.9.1+dfsg/libs/opus/celt/mips/mdct_mipsr1.h0000644000175000017500000002203614340334543021370 0ustar vimervimer/* Copyright (c) 2007-2008 CSIRO Copyright (c) 2007-2008 Xiph.Org Foundation Written by Jean-Marc Valin */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* This is a simple MDCT implementation that uses a N/4 complex FFT to do most of the work. It should be relatively straightforward to plug in pretty much and FFT here. This replaces the Vorbis FFT (and uses the exact same API), which was a bit too messy and that was ending up duplicating code (might as well use the same FFT everywhere). The algorithm is similar to (and inspired from) Fabrice Bellard's MDCT implementation in FFMPEG, but has differences in signs, ordering and scaling in many places. */ #ifndef __MDCT_MIPSR1_H__ #define __MDCT_MIPSR1_H__ #ifndef SKIP_CONFIG_H #ifdef HAVE_CONFIG_H #include "config.h" #endif #endif #include "mdct.h" #include "kiss_fft.h" #include "_kiss_fft_guts.h" #include #include "os_support.h" #include "mathops.h" #include "stack_alloc.h" /* Forward MDCT trashes the input array */ #define OVERRIDE_clt_mdct_forward void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out, const opus_val16 *window, int overlap, int shift, int stride, int arch) { int i; int N, N2, N4; VARDECL(kiss_fft_scalar, f); VARDECL(kiss_fft_cpx, f2); const kiss_fft_state *st = l->kfft[shift]; const kiss_twiddle_scalar *trig; opus_val16 scale; #ifdef FIXED_POINT /* Allows us to scale with MULT16_32_Q16(), which is faster than MULT16_32_Q15() on ARM. */ int scale_shift = st->scale_shift-1; #endif (void)arch; SAVE_STACK; scale = st->scale; N = l->n; trig = l->trig; for (i=0;i>= 1; trig += N; } N2 = N>>1; N4 = N>>2; ALLOC(f, N2, kiss_fft_scalar); ALLOC(f2, N4, kiss_fft_cpx); /* Consider the input to be composed of four blocks: [a, b, c, d] */ /* Window, shuffle, fold */ { /* Temp pointers to make it really clear to the compiler what we're doing */ const kiss_fft_scalar * OPUS_RESTRICT xp1 = in+(overlap>>1); const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+N2-1+(overlap>>1); kiss_fft_scalar * OPUS_RESTRICT yp = f; const opus_val16 * OPUS_RESTRICT wp1 = window+(overlap>>1); const opus_val16 * OPUS_RESTRICT wp2 = window+(overlap>>1)-1; for(i=0;i<((overlap+3)>>2);i++) { /* Real part arranged as -d-cR, Imag part arranged as -b+aR*/ *yp++ = S_MUL_ADD(*wp2, xp1[N2],*wp1,*xp2); *yp++ = S_MUL_SUB(*wp1, *xp1,*wp2, xp2[-N2]); xp1+=2; xp2-=2; wp1+=2; wp2-=2; } wp1 = window; wp2 = window+overlap-1; for(;i>2);i++) { /* Real part arranged as a-bR, Imag part arranged as -c-dR */ *yp++ = *xp2; *yp++ = *xp1; xp1+=2; xp2-=2; } for(;ibitrev[i]] = yc; } } /* N/4 complex FFT, does not downscale anymore */ opus_fft_impl(st, f2); /* Post-rotate */ { /* Temp pointers to make it really clear to the compiler what we're doing */ const kiss_fft_cpx * OPUS_RESTRICT fp = f2; kiss_fft_scalar * OPUS_RESTRICT yp1 = out; kiss_fft_scalar * OPUS_RESTRICT yp2 = out+stride*(N2-1); const kiss_twiddle_scalar *t = &trig[0]; /* Temp pointers to make it really clear to the compiler what we're doing */ for(i=0;ii,t[N4+i] , fp->r,t[i]); yi = S_MUL_ADD(fp->r,t[N4+i] ,fp->i,t[i]); *yp1 = yr; *yp2 = yi; fp++; yp1 += 2*stride; yp2 -= 2*stride; } } RESTORE_STACK; } #define OVERRIDE_clt_mdct_backward void clt_mdct_backward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out, const opus_val16 * OPUS_RESTRICT window, int overlap, int shift, int stride, int arch) { int i; int N, N2, N4; const kiss_twiddle_scalar *trig; (void)arch; N = l->n; trig = l->trig; for (i=0;i>= 1; trig += N; } N2 = N>>1; N4 = N>>2; /* Pre-rotate */ { /* Temp pointers to make it really clear to the compiler what we're doing */ const kiss_fft_scalar * OPUS_RESTRICT xp1 = in; const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+stride*(N2-1); kiss_fft_scalar * OPUS_RESTRICT yp = out+(overlap>>1); const kiss_twiddle_scalar * OPUS_RESTRICT t = &trig[0]; const opus_int16 * OPUS_RESTRICT bitrev = l->kfft[shift]->bitrev; for(i=0;ikfft[shift], (kiss_fft_cpx*)(out+(overlap>>1))); /* Post-rotate and de-shuffle from both ends of the buffer at once to make it in-place. */ { kiss_fft_scalar * OPUS_RESTRICT yp0 = out+(overlap>>1); kiss_fft_scalar * OPUS_RESTRICT yp1 = out+(overlap>>1)+N2-2; const kiss_twiddle_scalar *t = &trig[0]; /* Loop to (N4+1)>>1 to handle odd N4. When N4 is odd, the middle pair will be computed twice. */ for(i=0;i<(N4+1)>>1;i++) { kiss_fft_scalar re, im, yr, yi; kiss_twiddle_scalar t0, t1; /* We swap real and imag because we're using an FFT instead of an IFFT. */ re = yp0[1]; im = yp0[0]; t0 = t[i]; t1 = t[N4+i]; /* We'd scale up by 2 here, but instead it's done when mixing the windows */ yr = S_MUL_ADD(re,t0 , im,t1); yi = S_MUL_SUB(re,t1 , im,t0); /* We swap real and imag because we're using an FFT instead of an IFFT. */ re = yp1[1]; im = yp1[0]; yp0[0] = yr; yp1[1] = yi; t0 = t[(N4-i-1)]; t1 = t[(N2-i-1)]; /* We'd scale up by 2 here, but instead it's done when mixing the windows */ yr = S_MUL_ADD(re,t0,im,t1); yi = S_MUL_SUB(re,t1,im,t0); yp1[0] = yr; yp0[1] = yi; yp0 += 2; yp1 -= 2; } } /* Mirror on both sides for TDAC */ { kiss_fft_scalar * OPUS_RESTRICT xp1 = out+overlap-1; kiss_fft_scalar * OPUS_RESTRICT yp1 = out; const opus_val16 * OPUS_RESTRICT wp1 = window; const opus_val16 * OPUS_RESTRICT wp2 = window+overlap-1; for(i = 0; i < overlap/2; i++) { kiss_fft_scalar x1, x2; x1 = *xp1; x2 = *yp1; *yp1++ = MULT16_32_Q15(*wp2, x2) - MULT16_32_Q15(*wp1, x1); *xp1-- = MULT16_32_Q15(*wp1, x2) + MULT16_32_Q15(*wp2, x1); wp1++; wp2--; } } } #endif /* __MDCT_MIPSR1_H__ */ jamulus-3.9.1+dfsg/libs/opus/celt/mips/fixed_generic_mipsr1.h0000644000175000017500000001010214340334543023223 0ustar vimervimer/* Copyright (C) 2007-2009 Xiph.Org Foundation Copyright (C) 2003-2008 Jean-Marc Valin Copyright (C) 2007-2008 CSIRO */ /** @file fixed_generic.h @brief Generic fixed-point operations */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef CELT_FIXED_GENERIC_MIPSR1_H #define CELT_FIXED_GENERIC_MIPSR1_H #undef MULT16_32_Q15_ADD static inline int MULT16_32_Q15_ADD(int a, int b, int c, int d) { int m; asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a), "r" ((int)b)); asm volatile("madd $ac1, %0, %1" : : "r" ((int)c), "r" ((int)d)); asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m): "i" (15)); return m; } #undef MULT16_32_Q15_SUB static inline int MULT16_32_Q15_SUB(int a, int b, int c, int d) { int m; asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a), "r" ((int)b)); asm volatile("msub $ac1, %0, %1" : : "r" ((int)c), "r" ((int)d)); asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m): "i" (15)); return m; } #undef MULT16_16_Q15_ADD static inline int MULT16_16_Q15_ADD(int a, int b, int c, int d) { int m; asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a), "r" ((int)b)); asm volatile("madd $ac1, %0, %1" : : "r" ((int)c), "r" ((int)d)); asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m): "i" (15)); return m; } #undef MULT16_16_Q15_SUB static inline int MULT16_16_Q15_SUB(int a, int b, int c, int d) { int m; asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a), "r" ((int)b)); asm volatile("msub $ac1, %0, %1" : : "r" ((int)c), "r" ((int)d)); asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m): "i" (15)); return m; } #undef MULT16_32_Q16 static inline int MULT16_32_Q16(int a, int b) { int c; asm volatile("MULT $ac1,%0, %1" : : "r" (a), "r" (b)); asm volatile("EXTR.W %0,$ac1, %1" : "=r" (c): "i" (16)); return c; } #undef MULT16_32_P16 static inline int MULT16_32_P16(int a, int b) { int c; asm volatile("MULT $ac1, %0, %1" : : "r" (a), "r" (b)); asm volatile("EXTR_R.W %0,$ac1, %1" : "=r" (c): "i" (16)); return c; } #undef MULT16_32_Q15 static inline int MULT16_32_Q15(int a, int b) { int c; asm volatile("MULT $ac1, %0, %1" : : "r" (a), "r" (b)); asm volatile("EXTR.W %0,$ac1, %1" : "=r" (c): "i" (15)); return c; } #undef MULT32_32_Q31 static inline int MULT32_32_Q31(int a, int b) { int r; asm volatile("MULT $ac1, %0, %1" : : "r" (a), "r" (b)); asm volatile("EXTR.W %0,$ac1, %1" : "=r" (r): "i" (31)); return r; } #undef PSHR32 static inline int PSHR32(int a, int shift) { int r; asm volatile ("SHRAV_R.W %0, %1, %2" :"=r" (r): "r" (a), "r" (shift)); return r; } #undef MULT16_16_P15 static inline int MULT16_16_P15(int a, int b) { int r; asm volatile ("mul %0, %1, %2" :"=r" (r): "r" (a), "r" (b)); asm volatile ("SHRA_R.W %0, %1, %2" : "+r" (r): "0" (r), "i"(15)); return r; } #endif /* CELT_FIXED_GENERIC_MIPSR1_H */ jamulus-3.9.1+dfsg/libs/opus/celt/mips/pitch_mipsr1.h0000644000175000017500000001176014340334543021552 0ustar vimervimer/* Copyright (c) 2007-2008 CSIRO Copyright (c) 2007-2009 Xiph.Org Foundation Written by Jean-Marc Valin */ /** @file pitch.h @brief Pitch analysis */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef PITCH_MIPSR1_H #define PITCH_MIPSR1_H #define OVERRIDE_DUAL_INNER_PROD static inline void dual_inner_prod(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02, int N, opus_val32 *xy1, opus_val32 *xy2, int arch) { int j; opus_val32 xy01=0; opus_val32 xy02=0; (void)arch; asm volatile("MULT $ac1, $0, $0"); asm volatile("MULT $ac2, $0, $0"); /* Compute the norm of X+Y and X-Y as |X|^2 + |Y|^2 +/- sum(xy) */ for (j=0;j=0;i--) { celt_norm x1, x2; x1 = Xptr[0]; x2 = Xptr[stride]; Xptr[stride] = EXTRACT16(PSHR32(MAC16_16(MULT16_16(c, x2), s, x1), 15)); *Xptr-- = EXTRACT16(PSHR32(MAC16_16(MULT16_16(c, x1), ms, x2), 15)); } } #define OVERRIDE_renormalise_vector void renormalise_vector(celt_norm *X, int N, opus_val16 gain, int arch) { int i; #ifdef FIXED_POINT int k; #endif opus_val32 E = EPSILON; opus_val16 g; opus_val32 t; celt_norm *xptr = X; int X0, X1; (void)arch; asm volatile("mult $ac1, $0, $0"); asm volatile("MTLO %0, $ac1" : :"r" (E)); /*if(N %4) printf("error");*/ for (i=0;i>1; #endif t = VSHR32(E, 2*(k-7)); g = MULT16_16_P15(celt_rsqrt_norm(t),gain); xptr = X; for (i=0;itwiddles[fstride*m]; yb = st->twiddles[fstride*2*m]; #endif tw=st->twiddles; for (i=0;ir += scratch[7].r + scratch[8].r; Fout0->i += scratch[7].i + scratch[8].i; scratch[5].r = scratch[0].r + S_MUL_ADD(scratch[7].r,ya.r,scratch[8].r,yb.r); scratch[5].i = scratch[0].i + S_MUL_ADD(scratch[7].i,ya.r,scratch[8].i,yb.r); scratch[6].r = S_MUL_ADD(scratch[10].i,ya.i,scratch[9].i,yb.i); scratch[6].i = -S_MUL_ADD(scratch[10].r,ya.i,scratch[9].r,yb.i); C_SUB(*Fout1,scratch[5],scratch[6]); C_ADD(*Fout4,scratch[5],scratch[6]); scratch[11].r = scratch[0].r + S_MUL_ADD(scratch[7].r,yb.r,scratch[8].r,ya.r); scratch[11].i = scratch[0].i + S_MUL_ADD(scratch[7].i,yb.r,scratch[8].i,ya.r); scratch[12].r = S_MUL_SUB(scratch[9].i,ya.i,scratch[10].i,yb.i); scratch[12].i = S_MUL_SUB(scratch[10].r,yb.i,scratch[9].r,ya.i); C_ADD(*Fout2,scratch[11],scratch[12]); C_SUB(*Fout3,scratch[11],scratch[12]); ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4; } } } #endif /* KISS_FFT_MIPSR1_H */ jamulus-3.9.1+dfsg/libs/opus/celt/mips/celt_mipsr1.h0000644000175000017500000001173314340334543021372 0ustar vimervimer/* Copyright (c) 2007-2008 CSIRO Copyright (c) 2007-2010 Xiph.Org Foundation Copyright (c) 2008 Gregory Maxwell Written by Jean-Marc Valin and Gregory Maxwell */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __CELT_MIPSR1_H__ #define __CELT_MIPSR1_H__ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define CELT_C #include "os_support.h" #include "mdct.h" #include #include "celt.h" #include "pitch.h" #include "bands.h" #include "modes.h" #include "entcode.h" #include "quant_bands.h" #include "rate.h" #include "stack_alloc.h" #include "mathops.h" #include "float_cast.h" #include #include "celt_lpc.h" #include "vq.h" #define OVERRIDE_COMB_FILTER_CONST #define OVERRIDE_comb_filter void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N, opus_val16 g0, opus_val16 g1, int tapset0, int tapset1, const opus_val16 *window, int overlap, int arch) { int i; opus_val32 x0, x1, x2, x3, x4; (void)arch; /* printf ("%d %d %f %f\n", T0, T1, g0, g1); */ opus_val16 g00, g01, g02, g10, g11, g12; static const opus_val16 gains[3][3] = { {QCONST16(0.3066406250f, 15), QCONST16(0.2170410156f, 15), QCONST16(0.1296386719f, 15)}, {QCONST16(0.4638671875f, 15), QCONST16(0.2680664062f, 15), QCONST16(0.f, 15)}, {QCONST16(0.7998046875f, 15), QCONST16(0.1000976562f, 15), QCONST16(0.f, 15)}}; if (g0==0 && g1==0) { /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */ if (x!=y) OPUS_MOVE(y, x, N); return; } g00 = MULT16_16_P15(g0, gains[tapset0][0]); g01 = MULT16_16_P15(g0, gains[tapset0][1]); g02 = MULT16_16_P15(g0, gains[tapset0][2]); g10 = MULT16_16_P15(g1, gains[tapset1][0]); g11 = MULT16_16_P15(g1, gains[tapset1][1]); g12 = MULT16_16_P15(g1, gains[tapset1][2]); x1 = x[-T1+1]; x2 = x[-T1 ]; x3 = x[-T1-1]; x4 = x[-T1-2]; /* If the filter didn't change, we don't need the overlap */ if (g0==g1 && T0==T1 && tapset0==tapset1) overlap=0; for (i=0;i>EC_SYM_BITS) /*The number of bits available for the last, partial symbol in the code field.*/ # define EC_CODE_EXTRA ((EC_CODE_BITS-2)%EC_SYM_BITS+1) #endif jamulus-3.9.1+dfsg/libs/opus/celt/modes.h0000644000175000017500000000460514340334543017307 0ustar vimervimer/* Copyright (c) 2007-2008 CSIRO Copyright (c) 2007-2009 Xiph.Org Foundation Copyright (c) 2008 Gregory Maxwell Written by Jean-Marc Valin and Gregory Maxwell */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef MODES_H #define MODES_H #include "opus_types.h" #include "celt.h" #include "arch.h" #include "mdct.h" #include "entenc.h" #include "entdec.h" #define MAX_PERIOD 1024 typedef struct { int size; const opus_int16 *index; const unsigned char *bits; const unsigned char *caps; } PulseCache; /** Mode definition (opaque) @brief Mode definition */ struct OpusCustomMode { opus_int32 Fs; int overlap; int nbEBands; int effEBands; opus_val16 preemph[4]; const opus_int16 *eBands; /**< Definition for each "pseudo-critical band" */ int maxLM; int nbShortMdcts; int shortMdctSize; int nbAllocVectors; /**< Number of lines in the matrix below */ const unsigned char *allocVectors; /**< Number of bits in each band for several rates */ const opus_int16 *logN; const opus_val16 *window; mdct_lookup mdct; PulseCache cache; }; #endif jamulus-3.9.1+dfsg/libs/opus/celt/mdct.h0000644000175000017500000001125014340334543017121 0ustar vimervimer/* Copyright (c) 2007-2008 CSIRO Copyright (c) 2007-2008 Xiph.Org Foundation Written by Jean-Marc Valin */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* This is a simple MDCT implementation that uses a N/4 complex FFT to do most of the work. It should be relatively straightforward to plug in pretty much and FFT here. This replaces the Vorbis FFT (and uses the exact same API), which was a bit too messy and that was ending up duplicating code (might as well use the same FFT everywhere). The algorithm is similar to (and inspired from) Fabrice Bellard's MDCT implementation in FFMPEG, but has differences in signs, ordering and scaling in many places. */ #ifndef MDCT_H #define MDCT_H #include "opus_defines.h" #include "kiss_fft.h" #include "arch.h" typedef struct { int n; int maxshift; const kiss_fft_state *kfft[4]; const kiss_twiddle_scalar * OPUS_RESTRICT trig; } mdct_lookup; #if defined(HAVE_ARM_NE10) #include "arm/mdct_arm.h" #endif int clt_mdct_init(mdct_lookup *l,int N, int maxshift, int arch); void clt_mdct_clear(mdct_lookup *l, int arch); /** Compute a forward MDCT and scale by 4/N, trashes the input array */ void clt_mdct_forward_c(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out, const opus_val16 *window, int overlap, int shift, int stride, int arch); /** Compute a backward MDCT (no scaling) and performs weighted overlap-add (scales implicitly by 1/2) */ void clt_mdct_backward_c(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out, const opus_val16 * OPUS_RESTRICT window, int overlap, int shift, int stride, int arch); #if !defined(OVERRIDE_OPUS_MDCT) /* Is run-time CPU detection enabled on this platform? */ #if defined(OPUS_HAVE_RTCD) && defined(HAVE_ARM_NE10) extern void (*const CLT_MDCT_FORWARD_IMPL[OPUS_ARCHMASK+1])( const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out, const opus_val16 *window, int overlap, int shift, int stride, int arch); #define clt_mdct_forward(_l, _in, _out, _window, _overlap, _shift, _stride, _arch) \ ((*CLT_MDCT_FORWARD_IMPL[(arch)&OPUS_ARCHMASK])(_l, _in, _out, \ _window, _overlap, _shift, \ _stride, _arch)) extern void (*const CLT_MDCT_BACKWARD_IMPL[OPUS_ARCHMASK+1])( const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out, const opus_val16 *window, int overlap, int shift, int stride, int arch); #define clt_mdct_backward(_l, _in, _out, _window, _overlap, _shift, _stride, _arch) \ (*CLT_MDCT_BACKWARD_IMPL[(arch)&OPUS_ARCHMASK])(_l, _in, _out, \ _window, _overlap, _shift, \ _stride, _arch) #else /* if defined(OPUS_HAVE_RTCD) && defined(HAVE_ARM_NE10) */ #define clt_mdct_forward(_l, _in, _out, _window, _overlap, _shift, _stride, _arch) \ clt_mdct_forward_c(_l, _in, _out, _window, _overlap, _shift, _stride, _arch) #define clt_mdct_backward(_l, _in, _out, _window, _overlap, _shift, _stride, _arch) \ clt_mdct_backward_c(_l, _in, _out, _window, _overlap, _shift, _stride, _arch) #endif /* end if defined(OPUS_HAVE_RTCD) && defined(HAVE_ARM_NE10) && !defined(FIXED_POINT) */ #endif /* end if !defined(OVERRIDE_OPUS_MDCT) */ #endif jamulus-3.9.1+dfsg/libs/opus/celt/static_modes_float_arm_ne10.h0000644000175000017500000006770514340334543023537 0ustar vimervimer/* The contents of this file was automatically generated by * dump_mode_arm_ne10.c with arguments: 48000 960 * It contains static definitions for some pre-defined modes. */ #include #ifndef NE10_FFT_PARAMS48000_960 #define NE10_FFT_PARAMS48000_960 static const ne10_int32_t ne10_factors_480[64] = { 4, 40, 4, 30, 2, 15, 5, 3, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const ne10_int32_t ne10_factors_240[64] = { 3, 20, 4, 15, 5, 3, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const ne10_int32_t ne10_factors_120[64] = { 3, 10, 2, 15, 5, 3, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const ne10_int32_t ne10_factors_60[64] = { 2, 5, 5, 3, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const ne10_fft_cpx_float32_t ne10_twiddles_480[480] = { {1.0000000f,0.0000000f}, {1.0000000f,-0.0000000f}, {1.0000000f,-0.0000000f}, {1.0000000f,-0.0000000f}, {0.91354543f,-0.40673664f}, {0.66913056f,-0.74314487f}, {1.0000000f,-0.0000000f}, {0.66913056f,-0.74314487f}, {-0.10452851f,-0.99452192f}, {1.0000000f,-0.0000000f}, {0.30901697f,-0.95105654f}, {-0.80901700f,-0.58778518f}, {1.0000000f,-0.0000000f}, {-0.10452851f,-0.99452192f}, {-0.97814757f,0.20791179f}, {1.0000000f,-0.0000000f}, {0.97814763f,-0.20791170f}, {0.91354543f,-0.40673664f}, {0.80901700f,-0.58778524f}, {0.66913056f,-0.74314487f}, {0.49999997f,-0.86602545f}, {0.30901697f,-0.95105654f}, {0.10452842f,-0.99452192f}, {-0.10452851f,-0.99452192f}, {-0.30901703f,-0.95105648f}, {-0.50000006f,-0.86602533f}, {-0.66913068f,-0.74314475f}, {-0.80901700f,-0.58778518f}, {-0.91354549f,-0.40673658f}, {-0.97814763f,-0.20791161f}, {1.0000000f,-0.0000000f}, {0.99862951f,-0.052335959f}, {0.99452192f,-0.10452846f}, {0.98768836f,-0.15643448f}, {0.97814763f,-0.20791170f}, {0.96592581f,-0.25881904f}, {0.95105648f,-0.30901700f}, {0.93358040f,-0.35836795f}, {0.91354543f,-0.40673664f}, {0.89100653f,-0.45399052f}, {0.86602545f,-0.50000000f}, {0.83867055f,-0.54463905f}, {0.80901700f,-0.58778524f}, {0.77714598f,-0.62932038f}, {0.74314475f,-0.66913062f}, {0.70710677f,-0.70710683f}, {0.66913056f,-0.74314487f}, {0.62932038f,-0.77714598f}, {0.58778524f,-0.80901700f}, {0.54463899f,-0.83867055f}, {0.49999997f,-0.86602545f}, {0.45399052f,-0.89100653f}, {0.40673661f,-0.91354549f}, {0.35836786f,-0.93358046f}, {0.30901697f,-0.95105654f}, {0.25881907f,-0.96592581f}, {0.20791166f,-0.97814763f}, {0.15643437f,-0.98768836f}, {0.10452842f,-0.99452192f}, {0.052335974f,-0.99862951f}, {1.0000000f,-0.0000000f}, {0.99452192f,-0.10452846f}, {0.97814763f,-0.20791170f}, {0.95105648f,-0.30901700f}, {0.91354543f,-0.40673664f}, {0.86602545f,-0.50000000f}, {0.80901700f,-0.58778524f}, {0.74314475f,-0.66913062f}, {0.66913056f,-0.74314487f}, {0.58778524f,-0.80901700f}, {0.49999997f,-0.86602545f}, {0.40673661f,-0.91354549f}, {0.30901697f,-0.95105654f}, {0.20791166f,-0.97814763f}, {0.10452842f,-0.99452192f}, {-4.3711388e-08f,-1.0000000f}, {-0.10452851f,-0.99452192f}, {-0.20791174f,-0.97814757f}, {-0.30901703f,-0.95105648f}, {-0.40673670f,-0.91354543f}, {-0.50000006f,-0.86602533f}, {-0.58778518f,-0.80901700f}, {-0.66913068f,-0.74314475f}, {-0.74314493f,-0.66913044f}, {-0.80901700f,-0.58778518f}, {-0.86602539f,-0.50000006f}, {-0.91354549f,-0.40673658f}, {-0.95105654f,-0.30901679f}, {-0.97814763f,-0.20791161f}, {-0.99452192f,-0.10452849f}, {1.0000000f,-0.0000000f}, {0.98768836f,-0.15643448f}, {0.95105648f,-0.30901700f}, {0.89100653f,-0.45399052f}, {0.80901700f,-0.58778524f}, {0.70710677f,-0.70710683f}, {0.58778524f,-0.80901700f}, {0.45399052f,-0.89100653f}, {0.30901697f,-0.95105654f}, {0.15643437f,-0.98768836f}, {-4.3711388e-08f,-1.0000000f}, {-0.15643445f,-0.98768836f}, {-0.30901703f,-0.95105648f}, {-0.45399061f,-0.89100647f}, {-0.58778518f,-0.80901700f}, {-0.70710677f,-0.70710677f}, {-0.80901700f,-0.58778518f}, {-0.89100659f,-0.45399037f}, {-0.95105654f,-0.30901679f}, {-0.98768836f,-0.15643445f}, {-1.0000000f,8.7422777e-08f}, {-0.98768830f,0.15643461f}, {-0.95105654f,0.30901697f}, {-0.89100653f,0.45399055f}, {-0.80901694f,0.58778536f}, {-0.70710665f,0.70710689f}, {-0.58778507f,0.80901712f}, {-0.45399022f,0.89100665f}, {-0.30901709f,0.95105648f}, {-0.15643452f,0.98768830f}, {1.0000000f,-0.0000000f}, {0.99991435f,-0.013089596f}, {0.99965733f,-0.026176950f}, {0.99922901f,-0.039259817f}, {0.99862951f,-0.052335959f}, {0.99785894f,-0.065403134f}, {0.99691731f,-0.078459099f}, {0.99580491f,-0.091501623f}, {0.99452192f,-0.10452846f}, {0.99306846f,-0.11753740f}, {0.99144489f,-0.13052620f}, {0.98965138f,-0.14349262f}, {0.98768836f,-0.15643448f}, {0.98555607f,-0.16934951f}, {0.98325491f,-0.18223552f}, {0.98078525f,-0.19509032f}, {0.97814763f,-0.20791170f}, {0.97534233f,-0.22069745f}, {0.97236991f,-0.23344538f}, {0.96923089f,-0.24615330f}, {0.96592581f,-0.25881904f}, {0.96245521f,-0.27144045f}, {0.95881975f,-0.28401536f}, {0.95501995f,-0.29654160f}, {0.95105648f,-0.30901700f}, {0.94693011f,-0.32143945f}, {0.94264150f,-0.33380687f}, {0.93819129f,-0.34611708f}, {0.93358040f,-0.35836795f}, {0.92880952f,-0.37055743f}, {0.92387956f,-0.38268346f}, {0.91879117f,-0.39474389f}, {0.91354543f,-0.40673664f}, {0.90814316f,-0.41865975f}, {0.90258527f,-0.43051112f}, {0.89687270f,-0.44228873f}, {0.89100653f,-0.45399052f}, {0.88498765f,-0.46561453f}, {0.87881708f,-0.47715878f}, {0.87249601f,-0.48862126f}, {0.86602545f,-0.50000000f}, {0.85940641f,-0.51129311f}, {0.85264015f,-0.52249855f}, {0.84572786f,-0.53361452f}, {0.83867055f,-0.54463905f}, {0.83146960f,-0.55557024f}, {0.82412618f,-0.56640625f}, {0.81664151f,-0.57714522f}, {0.80901700f,-0.58778524f}, {0.80125380f,-0.59832460f}, {0.79335332f,-0.60876143f}, {0.78531694f,-0.61909395f}, {0.77714598f,-0.62932038f}, {0.76884180f,-0.63943899f}, {0.76040596f,-0.64944810f}, {0.75183982f,-0.65934587f}, {0.74314475f,-0.66913062f}, {0.73432249f,-0.67880076f}, {0.72537434f,-0.68835455f}, {0.71630192f,-0.69779050f}, {0.70710677f,-0.70710683f}, {0.69779044f,-0.71630198f}, {0.68835455f,-0.72537440f}, {0.67880070f,-0.73432255f}, {0.66913056f,-0.74314487f}, {0.65934581f,-0.75183982f}, {0.64944804f,-0.76040596f}, {0.63943899f,-0.76884186f}, {0.62932038f,-0.77714598f}, {0.61909395f,-0.78531694f}, {0.60876137f,-0.79335338f}, {0.59832460f,-0.80125386f}, {0.58778524f,-0.80901700f}, {0.57714516f,-0.81664151f}, {0.56640625f,-0.82412618f}, {0.55557019f,-0.83146960f}, {0.54463899f,-0.83867055f}, {0.53361452f,-0.84572786f}, {0.52249849f,-0.85264015f}, {0.51129311f,-0.85940641f}, {0.49999997f,-0.86602545f}, {0.48862118f,-0.87249601f}, {0.47715876f,-0.87881708f}, {0.46561447f,-0.88498765f}, {0.45399052f,-0.89100653f}, {0.44228867f,-0.89687276f}, {0.43051103f,-0.90258533f}, {0.41865975f,-0.90814316f}, {0.40673661f,-0.91354549f}, {0.39474380f,-0.91879129f}, {0.38268343f,-0.92387956f}, {0.37055740f,-0.92880958f}, {0.35836786f,-0.93358046f}, {0.34611705f,-0.93819135f}, {0.33380681f,-0.94264150f}, {0.32143947f,-0.94693011f}, {0.30901697f,-0.95105654f}, {0.29654151f,-0.95501995f}, {0.28401533f,-0.95881975f}, {0.27144039f,-0.96245527f}, {0.25881907f,-0.96592581f}, {0.24615327f,-0.96923089f}, {0.23344530f,-0.97236991f}, {0.22069745f,-0.97534233f}, {0.20791166f,-0.97814763f}, {0.19509023f,-0.98078531f}, {0.18223552f,-0.98325491f}, {0.16934945f,-0.98555607f}, {0.15643437f,-0.98768836f}, {0.14349259f,-0.98965138f}, {0.13052613f,-0.99144489f}, {0.11753740f,-0.99306846f}, {0.10452842f,-0.99452192f}, {0.091501534f,-0.99580491f}, {0.078459084f,-0.99691731f}, {0.065403074f,-0.99785894f}, {0.052335974f,-0.99862951f}, {0.039259788f,-0.99922901f}, {0.026176875f,-0.99965733f}, {0.013089597f,-0.99991435f}, {1.0000000f,-0.0000000f}, {0.99965733f,-0.026176950f}, {0.99862951f,-0.052335959f}, {0.99691731f,-0.078459099f}, {0.99452192f,-0.10452846f}, {0.99144489f,-0.13052620f}, {0.98768836f,-0.15643448f}, {0.98325491f,-0.18223552f}, {0.97814763f,-0.20791170f}, {0.97236991f,-0.23344538f}, {0.96592581f,-0.25881904f}, {0.95881975f,-0.28401536f}, {0.95105648f,-0.30901700f}, {0.94264150f,-0.33380687f}, {0.93358040f,-0.35836795f}, {0.92387956f,-0.38268346f}, {0.91354543f,-0.40673664f}, {0.90258527f,-0.43051112f}, {0.89100653f,-0.45399052f}, {0.87881708f,-0.47715878f}, {0.86602545f,-0.50000000f}, {0.85264015f,-0.52249855f}, {0.83867055f,-0.54463905f}, {0.82412618f,-0.56640625f}, {0.80901700f,-0.58778524f}, {0.79335332f,-0.60876143f}, {0.77714598f,-0.62932038f}, {0.76040596f,-0.64944810f}, {0.74314475f,-0.66913062f}, {0.72537434f,-0.68835455f}, {0.70710677f,-0.70710683f}, {0.68835455f,-0.72537440f}, {0.66913056f,-0.74314487f}, {0.64944804f,-0.76040596f}, {0.62932038f,-0.77714598f}, {0.60876137f,-0.79335338f}, {0.58778524f,-0.80901700f}, {0.56640625f,-0.82412618f}, {0.54463899f,-0.83867055f}, {0.52249849f,-0.85264015f}, {0.49999997f,-0.86602545f}, {0.47715876f,-0.87881708f}, {0.45399052f,-0.89100653f}, {0.43051103f,-0.90258533f}, {0.40673661f,-0.91354549f}, {0.38268343f,-0.92387956f}, {0.35836786f,-0.93358046f}, {0.33380681f,-0.94264150f}, {0.30901697f,-0.95105654f}, {0.28401533f,-0.95881975f}, {0.25881907f,-0.96592581f}, {0.23344530f,-0.97236991f}, {0.20791166f,-0.97814763f}, {0.18223552f,-0.98325491f}, {0.15643437f,-0.98768836f}, {0.13052613f,-0.99144489f}, {0.10452842f,-0.99452192f}, {0.078459084f,-0.99691731f}, {0.052335974f,-0.99862951f}, {0.026176875f,-0.99965733f}, {-4.3711388e-08f,-1.0000000f}, {-0.026176963f,-0.99965733f}, {-0.052336060f,-0.99862951f}, {-0.078459173f,-0.99691731f}, {-0.10452851f,-0.99452192f}, {-0.13052621f,-0.99144489f}, {-0.15643445f,-0.98768836f}, {-0.18223560f,-0.98325491f}, {-0.20791174f,-0.97814757f}, {-0.23344538f,-0.97236991f}, {-0.25881916f,-0.96592581f}, {-0.28401542f,-0.95881969f}, {-0.30901703f,-0.95105648f}, {-0.33380687f,-0.94264150f}, {-0.35836795f,-0.93358040f}, {-0.38268352f,-0.92387950f}, {-0.40673670f,-0.91354543f}, {-0.43051112f,-0.90258527f}, {-0.45399061f,-0.89100647f}, {-0.47715873f,-0.87881708f}, {-0.50000006f,-0.86602533f}, {-0.52249867f,-0.85264009f}, {-0.54463905f,-0.83867055f}, {-0.56640631f,-0.82412612f}, {-0.58778518f,-0.80901700f}, {-0.60876143f,-0.79335332f}, {-0.62932050f,-0.77714586f}, {-0.64944804f,-0.76040596f}, {-0.66913068f,-0.74314475f}, {-0.68835467f,-0.72537428f}, {-0.70710677f,-0.70710677f}, {-0.72537446f,-0.68835449f}, {-0.74314493f,-0.66913044f}, {-0.76040596f,-0.64944804f}, {-0.77714604f,-0.62932026f}, {-0.79335332f,-0.60876143f}, {-0.80901700f,-0.58778518f}, {-0.82412624f,-0.56640613f}, {-0.83867055f,-0.54463899f}, {-0.85264021f,-0.52249849f}, {-0.86602539f,-0.50000006f}, {-0.87881714f,-0.47715873f}, {-0.89100659f,-0.45399037f}, {-0.90258527f,-0.43051112f}, {-0.91354549f,-0.40673658f}, {-0.92387956f,-0.38268328f}, {-0.93358040f,-0.35836792f}, {-0.94264150f,-0.33380675f}, {-0.95105654f,-0.30901679f}, {-0.95881975f,-0.28401530f}, {-0.96592587f,-0.25881892f}, {-0.97236991f,-0.23344538f}, {-0.97814763f,-0.20791161f}, {-0.98325491f,-0.18223536f}, {-0.98768836f,-0.15643445f}, {-0.99144489f,-0.13052608f}, {-0.99452192f,-0.10452849f}, {-0.99691737f,-0.078459039f}, {-0.99862957f,-0.052335810f}, {-0.99965733f,-0.026176952f}, {1.0000000f,-0.0000000f}, {0.99922901f,-0.039259817f}, {0.99691731f,-0.078459099f}, {0.99306846f,-0.11753740f}, {0.98768836f,-0.15643448f}, {0.98078525f,-0.19509032f}, {0.97236991f,-0.23344538f}, {0.96245521f,-0.27144045f}, {0.95105648f,-0.30901700f}, {0.93819129f,-0.34611708f}, {0.92387956f,-0.38268346f}, {0.90814316f,-0.41865975f}, {0.89100653f,-0.45399052f}, {0.87249601f,-0.48862126f}, {0.85264015f,-0.52249855f}, {0.83146960f,-0.55557024f}, {0.80901700f,-0.58778524f}, {0.78531694f,-0.61909395f}, {0.76040596f,-0.64944810f}, {0.73432249f,-0.67880076f}, {0.70710677f,-0.70710683f}, {0.67880070f,-0.73432255f}, {0.64944804f,-0.76040596f}, {0.61909395f,-0.78531694f}, {0.58778524f,-0.80901700f}, {0.55557019f,-0.83146960f}, {0.52249849f,-0.85264015f}, {0.48862118f,-0.87249601f}, {0.45399052f,-0.89100653f}, {0.41865975f,-0.90814316f}, {0.38268343f,-0.92387956f}, {0.34611705f,-0.93819135f}, {0.30901697f,-0.95105654f}, {0.27144039f,-0.96245527f}, {0.23344530f,-0.97236991f}, {0.19509023f,-0.98078531f}, {0.15643437f,-0.98768836f}, {0.11753740f,-0.99306846f}, {0.078459084f,-0.99691731f}, {0.039259788f,-0.99922901f}, {-4.3711388e-08f,-1.0000000f}, {-0.039259877f,-0.99922901f}, {-0.078459173f,-0.99691731f}, {-0.11753749f,-0.99306846f}, {-0.15643445f,-0.98768836f}, {-0.19509032f,-0.98078525f}, {-0.23344538f,-0.97236991f}, {-0.27144048f,-0.96245521f}, {-0.30901703f,-0.95105648f}, {-0.34611711f,-0.93819129f}, {-0.38268352f,-0.92387950f}, {-0.41865984f,-0.90814310f}, {-0.45399061f,-0.89100647f}, {-0.48862135f,-0.87249595f}, {-0.52249867f,-0.85264009f}, {-0.55557036f,-0.83146954f}, {-0.58778518f,-0.80901700f}, {-0.61909389f,-0.78531694f}, {-0.64944804f,-0.76040596f}, {-0.67880076f,-0.73432249f}, {-0.70710677f,-0.70710677f}, {-0.73432249f,-0.67880070f}, {-0.76040596f,-0.64944804f}, {-0.78531694f,-0.61909389f}, {-0.80901700f,-0.58778518f}, {-0.83146966f,-0.55557019f}, {-0.85264021f,-0.52249849f}, {-0.87249607f,-0.48862115f}, {-0.89100659f,-0.45399037f}, {-0.90814322f,-0.41865960f}, {-0.92387956f,-0.38268328f}, {-0.93819135f,-0.34611690f}, {-0.95105654f,-0.30901679f}, {-0.96245521f,-0.27144048f}, {-0.97236991f,-0.23344538f}, {-0.98078531f,-0.19509031f}, {-0.98768836f,-0.15643445f}, {-0.99306846f,-0.11753736f}, {-0.99691737f,-0.078459039f}, {-0.99922901f,-0.039259743f}, {-1.0000000f,8.7422777e-08f}, {-0.99922901f,0.039259918f}, {-0.99691731f,0.078459218f}, {-0.99306846f,0.11753753f}, {-0.98768830f,0.15643461f}, {-0.98078525f,0.19509049f}, {-0.97236985f,0.23344554f}, {-0.96245515f,0.27144065f}, {-0.95105654f,0.30901697f}, {-0.93819135f,0.34611705f}, {-0.92387956f,0.38268346f}, {-0.90814316f,0.41865975f}, {-0.89100653f,0.45399055f}, {-0.87249601f,0.48862129f}, {-0.85264015f,0.52249861f}, {-0.83146960f,0.55557030f}, {-0.80901694f,0.58778536f}, {-0.78531688f,0.61909401f}, {-0.76040590f,0.64944816f}, {-0.73432243f,0.67880082f}, {-0.70710665f,0.70710689f}, {-0.67880058f,0.73432261f}, {-0.64944792f,0.76040608f}, {-0.61909378f,0.78531706f}, {-0.58778507f,0.80901712f}, {-0.55557001f,0.83146977f}, {-0.52249837f,0.85264033f}, {-0.48862100f,0.87249613f}, {-0.45399022f,0.89100665f}, {-0.41865945f,0.90814328f}, {-0.38268313f,0.92387968f}, {-0.34611672f,0.93819147f}, {-0.30901709f,0.95105648f}, {-0.27144054f,0.96245521f}, {-0.23344545f,0.97236991f}, {-0.19509038f,0.98078525f}, {-0.15643452f,0.98768830f}, {-0.11753743f,0.99306846f}, {-0.078459114f,0.99691731f}, {-0.039259821f,0.99922901f}, }; static const ne10_fft_cpx_float32_t ne10_twiddles_240[240] = { {1.0000000f,0.0000000f}, {1.0000000f,-0.0000000f}, {1.0000000f,-0.0000000f}, {1.0000000f,-0.0000000f}, {0.91354543f,-0.40673664f}, {0.66913056f,-0.74314487f}, {1.0000000f,-0.0000000f}, {0.66913056f,-0.74314487f}, {-0.10452851f,-0.99452192f}, {1.0000000f,-0.0000000f}, {0.30901697f,-0.95105654f}, {-0.80901700f,-0.58778518f}, {1.0000000f,-0.0000000f}, {-0.10452851f,-0.99452192f}, {-0.97814757f,0.20791179f}, {1.0000000f,-0.0000000f}, {0.99452192f,-0.10452846f}, {0.97814763f,-0.20791170f}, {0.95105648f,-0.30901700f}, {0.91354543f,-0.40673664f}, {0.86602545f,-0.50000000f}, {0.80901700f,-0.58778524f}, {0.74314475f,-0.66913062f}, {0.66913056f,-0.74314487f}, {0.58778524f,-0.80901700f}, {0.49999997f,-0.86602545f}, {0.40673661f,-0.91354549f}, {0.30901697f,-0.95105654f}, {0.20791166f,-0.97814763f}, {0.10452842f,-0.99452192f}, {1.0000000f,-0.0000000f}, {0.97814763f,-0.20791170f}, {0.91354543f,-0.40673664f}, {0.80901700f,-0.58778524f}, {0.66913056f,-0.74314487f}, {0.49999997f,-0.86602545f}, {0.30901697f,-0.95105654f}, {0.10452842f,-0.99452192f}, {-0.10452851f,-0.99452192f}, {-0.30901703f,-0.95105648f}, {-0.50000006f,-0.86602533f}, {-0.66913068f,-0.74314475f}, {-0.80901700f,-0.58778518f}, {-0.91354549f,-0.40673658f}, {-0.97814763f,-0.20791161f}, {1.0000000f,-0.0000000f}, {0.95105648f,-0.30901700f}, {0.80901700f,-0.58778524f}, {0.58778524f,-0.80901700f}, {0.30901697f,-0.95105654f}, {-4.3711388e-08f,-1.0000000f}, {-0.30901703f,-0.95105648f}, {-0.58778518f,-0.80901700f}, {-0.80901700f,-0.58778518f}, {-0.95105654f,-0.30901679f}, {-1.0000000f,8.7422777e-08f}, {-0.95105654f,0.30901697f}, {-0.80901694f,0.58778536f}, {-0.58778507f,0.80901712f}, {-0.30901709f,0.95105648f}, {1.0000000f,-0.0000000f}, {0.99965733f,-0.026176950f}, {0.99862951f,-0.052335959f}, {0.99691731f,-0.078459099f}, {0.99452192f,-0.10452846f}, {0.99144489f,-0.13052620f}, {0.98768836f,-0.15643448f}, {0.98325491f,-0.18223552f}, {0.97814763f,-0.20791170f}, {0.97236991f,-0.23344538f}, {0.96592581f,-0.25881904f}, {0.95881975f,-0.28401536f}, {0.95105648f,-0.30901700f}, {0.94264150f,-0.33380687f}, {0.93358040f,-0.35836795f}, {0.92387956f,-0.38268346f}, {0.91354543f,-0.40673664f}, {0.90258527f,-0.43051112f}, {0.89100653f,-0.45399052f}, {0.87881708f,-0.47715878f}, {0.86602545f,-0.50000000f}, {0.85264015f,-0.52249855f}, {0.83867055f,-0.54463905f}, {0.82412618f,-0.56640625f}, {0.80901700f,-0.58778524f}, {0.79335332f,-0.60876143f}, {0.77714598f,-0.62932038f}, {0.76040596f,-0.64944810f}, {0.74314475f,-0.66913062f}, {0.72537434f,-0.68835455f}, {0.70710677f,-0.70710683f}, {0.68835455f,-0.72537440f}, {0.66913056f,-0.74314487f}, {0.64944804f,-0.76040596f}, {0.62932038f,-0.77714598f}, {0.60876137f,-0.79335338f}, {0.58778524f,-0.80901700f}, {0.56640625f,-0.82412618f}, {0.54463899f,-0.83867055f}, {0.52249849f,-0.85264015f}, {0.49999997f,-0.86602545f}, {0.47715876f,-0.87881708f}, {0.45399052f,-0.89100653f}, {0.43051103f,-0.90258533f}, {0.40673661f,-0.91354549f}, {0.38268343f,-0.92387956f}, {0.35836786f,-0.93358046f}, {0.33380681f,-0.94264150f}, {0.30901697f,-0.95105654f}, {0.28401533f,-0.95881975f}, {0.25881907f,-0.96592581f}, {0.23344530f,-0.97236991f}, {0.20791166f,-0.97814763f}, {0.18223552f,-0.98325491f}, {0.15643437f,-0.98768836f}, {0.13052613f,-0.99144489f}, {0.10452842f,-0.99452192f}, {0.078459084f,-0.99691731f}, {0.052335974f,-0.99862951f}, {0.026176875f,-0.99965733f}, {1.0000000f,-0.0000000f}, {0.99862951f,-0.052335959f}, {0.99452192f,-0.10452846f}, {0.98768836f,-0.15643448f}, {0.97814763f,-0.20791170f}, {0.96592581f,-0.25881904f}, {0.95105648f,-0.30901700f}, {0.93358040f,-0.35836795f}, {0.91354543f,-0.40673664f}, {0.89100653f,-0.45399052f}, {0.86602545f,-0.50000000f}, {0.83867055f,-0.54463905f}, {0.80901700f,-0.58778524f}, {0.77714598f,-0.62932038f}, {0.74314475f,-0.66913062f}, {0.70710677f,-0.70710683f}, {0.66913056f,-0.74314487f}, {0.62932038f,-0.77714598f}, {0.58778524f,-0.80901700f}, {0.54463899f,-0.83867055f}, {0.49999997f,-0.86602545f}, {0.45399052f,-0.89100653f}, {0.40673661f,-0.91354549f}, {0.35836786f,-0.93358046f}, {0.30901697f,-0.95105654f}, {0.25881907f,-0.96592581f}, {0.20791166f,-0.97814763f}, {0.15643437f,-0.98768836f}, {0.10452842f,-0.99452192f}, {0.052335974f,-0.99862951f}, {-4.3711388e-08f,-1.0000000f}, {-0.052336060f,-0.99862951f}, {-0.10452851f,-0.99452192f}, {-0.15643445f,-0.98768836f}, {-0.20791174f,-0.97814757f}, {-0.25881916f,-0.96592581f}, {-0.30901703f,-0.95105648f}, {-0.35836795f,-0.93358040f}, {-0.40673670f,-0.91354543f}, {-0.45399061f,-0.89100647f}, {-0.50000006f,-0.86602533f}, {-0.54463905f,-0.83867055f}, {-0.58778518f,-0.80901700f}, {-0.62932050f,-0.77714586f}, {-0.66913068f,-0.74314475f}, {-0.70710677f,-0.70710677f}, {-0.74314493f,-0.66913044f}, {-0.77714604f,-0.62932026f}, {-0.80901700f,-0.58778518f}, {-0.83867055f,-0.54463899f}, {-0.86602539f,-0.50000006f}, {-0.89100659f,-0.45399037f}, {-0.91354549f,-0.40673658f}, {-0.93358040f,-0.35836792f}, {-0.95105654f,-0.30901679f}, {-0.96592587f,-0.25881892f}, {-0.97814763f,-0.20791161f}, {-0.98768836f,-0.15643445f}, {-0.99452192f,-0.10452849f}, {-0.99862957f,-0.052335810f}, {1.0000000f,-0.0000000f}, {0.99691731f,-0.078459099f}, {0.98768836f,-0.15643448f}, {0.97236991f,-0.23344538f}, {0.95105648f,-0.30901700f}, {0.92387956f,-0.38268346f}, {0.89100653f,-0.45399052f}, {0.85264015f,-0.52249855f}, {0.80901700f,-0.58778524f}, {0.76040596f,-0.64944810f}, {0.70710677f,-0.70710683f}, {0.64944804f,-0.76040596f}, {0.58778524f,-0.80901700f}, {0.52249849f,-0.85264015f}, {0.45399052f,-0.89100653f}, {0.38268343f,-0.92387956f}, {0.30901697f,-0.95105654f}, {0.23344530f,-0.97236991f}, {0.15643437f,-0.98768836f}, {0.078459084f,-0.99691731f}, {-4.3711388e-08f,-1.0000000f}, {-0.078459173f,-0.99691731f}, {-0.15643445f,-0.98768836f}, {-0.23344538f,-0.97236991f}, {-0.30901703f,-0.95105648f}, {-0.38268352f,-0.92387950f}, {-0.45399061f,-0.89100647f}, {-0.52249867f,-0.85264009f}, {-0.58778518f,-0.80901700f}, {-0.64944804f,-0.76040596f}, {-0.70710677f,-0.70710677f}, {-0.76040596f,-0.64944804f}, {-0.80901700f,-0.58778518f}, {-0.85264021f,-0.52249849f}, {-0.89100659f,-0.45399037f}, {-0.92387956f,-0.38268328f}, {-0.95105654f,-0.30901679f}, {-0.97236991f,-0.23344538f}, {-0.98768836f,-0.15643445f}, {-0.99691737f,-0.078459039f}, {-1.0000000f,8.7422777e-08f}, {-0.99691731f,0.078459218f}, {-0.98768830f,0.15643461f}, {-0.97236985f,0.23344554f}, {-0.95105654f,0.30901697f}, {-0.92387956f,0.38268346f}, {-0.89100653f,0.45399055f}, {-0.85264015f,0.52249861f}, {-0.80901694f,0.58778536f}, {-0.76040590f,0.64944816f}, {-0.70710665f,0.70710689f}, {-0.64944792f,0.76040608f}, {-0.58778507f,0.80901712f}, {-0.52249837f,0.85264033f}, {-0.45399022f,0.89100665f}, {-0.38268313f,0.92387968f}, {-0.30901709f,0.95105648f}, {-0.23344545f,0.97236991f}, {-0.15643452f,0.98768830f}, {-0.078459114f,0.99691731f}, }; static const ne10_fft_cpx_float32_t ne10_twiddles_120[120] = { {1.0000000f,0.0000000f}, {1.0000000f,-0.0000000f}, {1.0000000f,-0.0000000f}, {1.0000000f,-0.0000000f}, {0.91354543f,-0.40673664f}, {0.66913056f,-0.74314487f}, {1.0000000f,-0.0000000f}, {0.66913056f,-0.74314487f}, {-0.10452851f,-0.99452192f}, {1.0000000f,-0.0000000f}, {0.30901697f,-0.95105654f}, {-0.80901700f,-0.58778518f}, {1.0000000f,-0.0000000f}, {-0.10452851f,-0.99452192f}, {-0.97814757f,0.20791179f}, {1.0000000f,-0.0000000f}, {0.97814763f,-0.20791170f}, {0.91354543f,-0.40673664f}, {0.80901700f,-0.58778524f}, {0.66913056f,-0.74314487f}, {0.49999997f,-0.86602545f}, {0.30901697f,-0.95105654f}, {0.10452842f,-0.99452192f}, {-0.10452851f,-0.99452192f}, {-0.30901703f,-0.95105648f}, {-0.50000006f,-0.86602533f}, {-0.66913068f,-0.74314475f}, {-0.80901700f,-0.58778518f}, {-0.91354549f,-0.40673658f}, {-0.97814763f,-0.20791161f}, {1.0000000f,-0.0000000f}, {0.99862951f,-0.052335959f}, {0.99452192f,-0.10452846f}, {0.98768836f,-0.15643448f}, {0.97814763f,-0.20791170f}, {0.96592581f,-0.25881904f}, {0.95105648f,-0.30901700f}, {0.93358040f,-0.35836795f}, {0.91354543f,-0.40673664f}, {0.89100653f,-0.45399052f}, {0.86602545f,-0.50000000f}, {0.83867055f,-0.54463905f}, {0.80901700f,-0.58778524f}, {0.77714598f,-0.62932038f}, {0.74314475f,-0.66913062f}, {0.70710677f,-0.70710683f}, {0.66913056f,-0.74314487f}, {0.62932038f,-0.77714598f}, {0.58778524f,-0.80901700f}, {0.54463899f,-0.83867055f}, {0.49999997f,-0.86602545f}, {0.45399052f,-0.89100653f}, {0.40673661f,-0.91354549f}, {0.35836786f,-0.93358046f}, {0.30901697f,-0.95105654f}, {0.25881907f,-0.96592581f}, {0.20791166f,-0.97814763f}, {0.15643437f,-0.98768836f}, {0.10452842f,-0.99452192f}, {0.052335974f,-0.99862951f}, {1.0000000f,-0.0000000f}, {0.99452192f,-0.10452846f}, {0.97814763f,-0.20791170f}, {0.95105648f,-0.30901700f}, {0.91354543f,-0.40673664f}, {0.86602545f,-0.50000000f}, {0.80901700f,-0.58778524f}, {0.74314475f,-0.66913062f}, {0.66913056f,-0.74314487f}, {0.58778524f,-0.80901700f}, {0.49999997f,-0.86602545f}, {0.40673661f,-0.91354549f}, {0.30901697f,-0.95105654f}, {0.20791166f,-0.97814763f}, {0.10452842f,-0.99452192f}, {-4.3711388e-08f,-1.0000000f}, {-0.10452851f,-0.99452192f}, {-0.20791174f,-0.97814757f}, {-0.30901703f,-0.95105648f}, {-0.40673670f,-0.91354543f}, {-0.50000006f,-0.86602533f}, {-0.58778518f,-0.80901700f}, {-0.66913068f,-0.74314475f}, {-0.74314493f,-0.66913044f}, {-0.80901700f,-0.58778518f}, {-0.86602539f,-0.50000006f}, {-0.91354549f,-0.40673658f}, {-0.95105654f,-0.30901679f}, {-0.97814763f,-0.20791161f}, {-0.99452192f,-0.10452849f}, {1.0000000f,-0.0000000f}, {0.98768836f,-0.15643448f}, {0.95105648f,-0.30901700f}, {0.89100653f,-0.45399052f}, {0.80901700f,-0.58778524f}, {0.70710677f,-0.70710683f}, {0.58778524f,-0.80901700f}, {0.45399052f,-0.89100653f}, {0.30901697f,-0.95105654f}, {0.15643437f,-0.98768836f}, {-4.3711388e-08f,-1.0000000f}, {-0.15643445f,-0.98768836f}, {-0.30901703f,-0.95105648f}, {-0.45399061f,-0.89100647f}, {-0.58778518f,-0.80901700f}, {-0.70710677f,-0.70710677f}, {-0.80901700f,-0.58778518f}, {-0.89100659f,-0.45399037f}, {-0.95105654f,-0.30901679f}, {-0.98768836f,-0.15643445f}, {-1.0000000f,8.7422777e-08f}, {-0.98768830f,0.15643461f}, {-0.95105654f,0.30901697f}, {-0.89100653f,0.45399055f}, {-0.80901694f,0.58778536f}, {-0.70710665f,0.70710689f}, {-0.58778507f,0.80901712f}, {-0.45399022f,0.89100665f}, {-0.30901709f,0.95105648f}, {-0.15643452f,0.98768830f}, }; static const ne10_fft_cpx_float32_t ne10_twiddles_60[60] = { {1.0000000f,0.0000000f}, {1.0000000f,-0.0000000f}, {1.0000000f,-0.0000000f}, {1.0000000f,-0.0000000f}, {0.91354543f,-0.40673664f}, {0.66913056f,-0.74314487f}, {1.0000000f,-0.0000000f}, {0.66913056f,-0.74314487f}, {-0.10452851f,-0.99452192f}, {1.0000000f,-0.0000000f}, {0.30901697f,-0.95105654f}, {-0.80901700f,-0.58778518f}, {1.0000000f,-0.0000000f}, {-0.10452851f,-0.99452192f}, {-0.97814757f,0.20791179f}, {1.0000000f,-0.0000000f}, {0.99452192f,-0.10452846f}, {0.97814763f,-0.20791170f}, {0.95105648f,-0.30901700f}, {0.91354543f,-0.40673664f}, {0.86602545f,-0.50000000f}, {0.80901700f,-0.58778524f}, {0.74314475f,-0.66913062f}, {0.66913056f,-0.74314487f}, {0.58778524f,-0.80901700f}, {0.49999997f,-0.86602545f}, {0.40673661f,-0.91354549f}, {0.30901697f,-0.95105654f}, {0.20791166f,-0.97814763f}, {0.10452842f,-0.99452192f}, {1.0000000f,-0.0000000f}, {0.97814763f,-0.20791170f}, {0.91354543f,-0.40673664f}, {0.80901700f,-0.58778524f}, {0.66913056f,-0.74314487f}, {0.49999997f,-0.86602545f}, {0.30901697f,-0.95105654f}, {0.10452842f,-0.99452192f}, {-0.10452851f,-0.99452192f}, {-0.30901703f,-0.95105648f}, {-0.50000006f,-0.86602533f}, {-0.66913068f,-0.74314475f}, {-0.80901700f,-0.58778518f}, {-0.91354549f,-0.40673658f}, {-0.97814763f,-0.20791161f}, {1.0000000f,-0.0000000f}, {0.95105648f,-0.30901700f}, {0.80901700f,-0.58778524f}, {0.58778524f,-0.80901700f}, {0.30901697f,-0.95105654f}, {-4.3711388e-08f,-1.0000000f}, {-0.30901703f,-0.95105648f}, {-0.58778518f,-0.80901700f}, {-0.80901700f,-0.58778518f}, {-0.95105654f,-0.30901679f}, {-1.0000000f,8.7422777e-08f}, {-0.95105654f,0.30901697f}, {-0.80901694f,0.58778536f}, {-0.58778507f,0.80901712f}, {-0.30901709f,0.95105648f}, }; static const ne10_fft_state_float32_t ne10_fft_state_float32_t_480 = { 120, (ne10_int32_t *)ne10_factors_480, (ne10_fft_cpx_float32_t *)ne10_twiddles_480, NULL, (ne10_fft_cpx_float32_t *)&ne10_twiddles_480[120], /* is_forward_scaled = true */ (ne10_int32_t) 1, /* is_backward_scaled = false */ (ne10_int32_t) 0, }; static const arch_fft_state cfg_arch_480 = { 1, (void *)&ne10_fft_state_float32_t_480, }; static const ne10_fft_state_float32_t ne10_fft_state_float32_t_240 = { 60, (ne10_int32_t *)ne10_factors_240, (ne10_fft_cpx_float32_t *)ne10_twiddles_240, NULL, (ne10_fft_cpx_float32_t *)&ne10_twiddles_240[60], /* is_forward_scaled = true */ (ne10_int32_t) 1, /* is_backward_scaled = false */ (ne10_int32_t) 0, }; static const arch_fft_state cfg_arch_240 = { 1, (void *)&ne10_fft_state_float32_t_240, }; static const ne10_fft_state_float32_t ne10_fft_state_float32_t_120 = { 30, (ne10_int32_t *)ne10_factors_120, (ne10_fft_cpx_float32_t *)ne10_twiddles_120, NULL, (ne10_fft_cpx_float32_t *)&ne10_twiddles_120[30], /* is_forward_scaled = true */ (ne10_int32_t) 1, /* is_backward_scaled = false */ (ne10_int32_t) 0, }; static const arch_fft_state cfg_arch_120 = { 1, (void *)&ne10_fft_state_float32_t_120, }; static const ne10_fft_state_float32_t ne10_fft_state_float32_t_60 = { 15, (ne10_int32_t *)ne10_factors_60, (ne10_fft_cpx_float32_t *)ne10_twiddles_60, NULL, (ne10_fft_cpx_float32_t *)&ne10_twiddles_60[15], /* is_forward_scaled = true */ (ne10_int32_t) 1, /* is_backward_scaled = false */ (ne10_int32_t) 0, }; static const arch_fft_state cfg_arch_60 = { 1, (void *)&ne10_fft_state_float32_t_60, }; #endif /* end NE10_FFT_PARAMS48000_960 */ jamulus-3.9.1+dfsg/libs/opus/celt/entdec.c0000644000175000017500000001752014340334543017435 0ustar vimervimer/* Copyright (c) 2001-2011 Timothy B. Terriberry Copyright (c) 2008-2009 Xiph.Org Foundation */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "os_support.h" #include "arch.h" #include "entdec.h" #include "mfrngcod.h" /*A range decoder. This is an entropy decoder based upon \cite{Mar79}, which is itself a rediscovery of the FIFO arithmetic code introduced by \cite{Pas76}. It is very similar to arithmetic encoding, except that encoding is done with digits in any base, instead of with bits, and so it is faster when using larger bases (i.e.: a byte). The author claims an average waste of $\frac{1}{2}\log_b(2b)$ bits, where $b$ is the base, longer than the theoretical optimum, but to my knowledge there is no published justification for this claim. This only seems true when using near-infinite precision arithmetic so that the process is carried out with no rounding errors. An excellent description of implementation details is available at http://www.arturocampos.com/ac_range.html A recent work \cite{MNW98} which proposes several changes to arithmetic encoding for efficiency actually re-discovers many of the principles behind range encoding, and presents a good theoretical analysis of them. End of stream is handled by writing out the smallest number of bits that ensures that the stream will be correctly decoded regardless of the value of any subsequent bits. ec_tell() can be used to determine how many bits were needed to decode all the symbols thus far; other data can be packed in the remaining bits of the input buffer. @PHDTHESIS{Pas76, author="Richard Clark Pasco", title="Source coding algorithms for fast data compression", school="Dept. of Electrical Engineering, Stanford University", address="Stanford, CA", month=May, year=1976 } @INPROCEEDINGS{Mar79, author="Martin, G.N.N.", title="Range encoding: an algorithm for removing redundancy from a digitised message", booktitle="Video & Data Recording Conference", year=1979, address="Southampton", month=Jul } @ARTICLE{MNW98, author="Alistair Moffat and Radford Neal and Ian H. Witten", title="Arithmetic Coding Revisited", journal="{ACM} Transactions on Information Systems", year=1998, volume=16, number=3, pages="256--294", month=Jul, URL="http://www.stanford.edu/class/ee398a/handouts/papers/Moffat98ArithmCoding.pdf" }*/ static int ec_read_byte(ec_dec *_this){ return _this->offs<_this->storage?_this->buf[_this->offs++]:0; } static int ec_read_byte_from_end(ec_dec *_this){ return _this->end_offs<_this->storage? _this->buf[_this->storage-++(_this->end_offs)]:0; } /*Normalizes the contents of val and rng so that rng lies entirely in the high-order symbol.*/ static void ec_dec_normalize(ec_dec *_this){ /*If the range is too small, rescale it and input some bits.*/ while(_this->rng<=EC_CODE_BOT){ int sym; _this->nbits_total+=EC_SYM_BITS; _this->rng<<=EC_SYM_BITS; /*Use up the remaining bits from our last symbol.*/ sym=_this->rem; /*Read the next value from the input.*/ _this->rem=ec_read_byte(_this); /*Take the rest of the bits we need from this new symbol.*/ sym=(sym<rem)>>(EC_SYM_BITS-EC_CODE_EXTRA); /*And subtract them from val, capped to be less than EC_CODE_TOP.*/ _this->val=((_this->val<buf=_buf; _this->storage=_storage; _this->end_offs=0; _this->end_window=0; _this->nend_bits=0; /*This is the offset from which ec_tell() will subtract partial bits. The final value after the ec_dec_normalize() call will be the same as in the encoder, but we have to compensate for the bits that are added there.*/ _this->nbits_total=EC_CODE_BITS+1 -((EC_CODE_BITS-EC_CODE_EXTRA)/EC_SYM_BITS)*EC_SYM_BITS; _this->offs=0; _this->rng=1U<rem=ec_read_byte(_this); _this->val=_this->rng-1-(_this->rem>>(EC_SYM_BITS-EC_CODE_EXTRA)); _this->error=0; /*Normalize the interval.*/ ec_dec_normalize(_this); } unsigned ec_decode(ec_dec *_this,unsigned _ft){ unsigned s; _this->ext=celt_udiv(_this->rng,_ft); s=(unsigned)(_this->val/_this->ext); return _ft-EC_MINI(s+1,_ft); } unsigned ec_decode_bin(ec_dec *_this,unsigned _bits){ unsigned s; _this->ext=_this->rng>>_bits; s=(unsigned)(_this->val/_this->ext); return (1U<<_bits)-EC_MINI(s+1U,1U<<_bits); } void ec_dec_update(ec_dec *_this,unsigned _fl,unsigned _fh,unsigned _ft){ opus_uint32 s; s=IMUL32(_this->ext,_ft-_fh); _this->val-=s; _this->rng=_fl>0?IMUL32(_this->ext,_fh-_fl):_this->rng-s; ec_dec_normalize(_this); } /*The probability of having a "one" is 1/(1<<_logp).*/ int ec_dec_bit_logp(ec_dec *_this,unsigned _logp){ opus_uint32 r; opus_uint32 d; opus_uint32 s; int ret; r=_this->rng; d=_this->val; s=r>>_logp; ret=dval=d-s; _this->rng=ret?s:r-s; ec_dec_normalize(_this); return ret; } int ec_dec_icdf(ec_dec *_this,const unsigned char *_icdf,unsigned _ftb){ opus_uint32 r; opus_uint32 d; opus_uint32 s; opus_uint32 t; int ret; s=_this->rng; d=_this->val; r=s>>_ftb; ret=-1; do{ t=s; s=IMUL32(r,_icdf[++ret]); } while(dval=d-s; _this->rng=t-s; ec_dec_normalize(_this); return ret; } opus_uint32 ec_dec_uint(ec_dec *_this,opus_uint32 _ft){ unsigned ft; unsigned s; int ftb; /*In order to optimize EC_ILOG(), it is undefined for the value 0.*/ celt_assert(_ft>1); _ft--; ftb=EC_ILOG(_ft); if(ftb>EC_UINT_BITS){ opus_uint32 t; ftb-=EC_UINT_BITS; ft=(unsigned)(_ft>>ftb)+1; s=ec_decode(_this,ft); ec_dec_update(_this,s,s+1,ft); t=(opus_uint32)s<error=1; return _ft; } else{ _ft++; s=ec_decode(_this,(unsigned)_ft); ec_dec_update(_this,s,s+1,(unsigned)_ft); return s; } } opus_uint32 ec_dec_bits(ec_dec *_this,unsigned _bits){ ec_window window; int available; opus_uint32 ret; window=_this->end_window; available=_this->nend_bits; if((unsigned)available<_bits){ do{ window|=(ec_window)ec_read_byte_from_end(_this)<>=_bits; available-=_bits; _this->end_window=window; _this->nend_bits=available; _this->nbits_total+=_bits; return ret; } jamulus-3.9.1+dfsg/libs/opus/celt/x86/0000755000175000017500000000000014340334543016447 5ustar vimervimerjamulus-3.9.1+dfsg/libs/opus/celt/x86/pitch_sse4_1.c0000644000175000017500000001450014340334543021100 0ustar vimervimer/* Copyright (c) 2014, Cisco Systems, INC Written by XiangMingZhu WeiZhou MinPeng YanWang Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "macros.h" #include "celt_lpc.h" #include "stack_alloc.h" #include "mathops.h" #include "pitch.h" #if defined(OPUS_X86_MAY_HAVE_SSE4_1) && defined(FIXED_POINT) #include #include "x86cpu.h" opus_val32 celt_inner_prod_sse4_1(const opus_val16 *x, const opus_val16 *y, int N) { opus_int i, dataSize16; opus_int32 sum; __m128i inVec1_76543210, inVec1_FEDCBA98, acc1; __m128i inVec2_76543210, inVec2_FEDCBA98, acc2; __m128i inVec1_3210, inVec2_3210; sum = 0; dataSize16 = N & ~15; acc1 = _mm_setzero_si128(); acc2 = _mm_setzero_si128(); for (i=0;i= 8) { inVec1_76543210 = _mm_loadu_si128((__m128i *)(&x[i + 0])); inVec2_76543210 = _mm_loadu_si128((__m128i *)(&y[i + 0])); inVec1_76543210 = _mm_madd_epi16(inVec1_76543210, inVec2_76543210); acc1 = _mm_add_epi32(acc1, inVec1_76543210); i += 8; } if (N - i >= 4) { inVec1_3210 = OP_CVTEPI16_EPI32_M64(&x[i + 0]); inVec2_3210 = OP_CVTEPI16_EPI32_M64(&y[i + 0]); inVec1_3210 = _mm_mullo_epi32(inVec1_3210, inVec2_3210); acc1 = _mm_add_epi32(acc1, inVec1_3210); i += 4; } acc1 = _mm_add_epi32(acc1, _mm_unpackhi_epi64(acc1, acc1)); acc1 = _mm_add_epi32(acc1, _mm_shufflelo_epi16(acc1, 0x0E)); sum += _mm_cvtsi128_si32(acc1); for (;i= 3); sum0 = _mm_setzero_si128(); sum1 = _mm_setzero_si128(); sum2 = _mm_setzero_si128(); sum3 = _mm_setzero_si128(); for (j=0;j<(len-7);j+=8) { vecX = _mm_loadu_si128((__m128i *)(&x[j + 0])); vecY0 = _mm_loadu_si128((__m128i *)(&y[j + 0])); vecY1 = _mm_loadu_si128((__m128i *)(&y[j + 1])); vecY2 = _mm_loadu_si128((__m128i *)(&y[j + 2])); vecY3 = _mm_loadu_si128((__m128i *)(&y[j + 3])); sum0 = _mm_add_epi32(sum0, _mm_madd_epi16(vecX, vecY0)); sum1 = _mm_add_epi32(sum1, _mm_madd_epi16(vecX, vecY1)); sum2 = _mm_add_epi32(sum2, _mm_madd_epi16(vecX, vecY2)); sum3 = _mm_add_epi32(sum3, _mm_madd_epi16(vecX, vecY3)); } sum0 = _mm_add_epi32(sum0, _mm_unpackhi_epi64( sum0, sum0)); sum0 = _mm_add_epi32(sum0, _mm_shufflelo_epi16( sum0, 0x0E)); sum1 = _mm_add_epi32(sum1, _mm_unpackhi_epi64( sum1, sum1)); sum1 = _mm_add_epi32(sum1, _mm_shufflelo_epi16( sum1, 0x0E)); sum2 = _mm_add_epi32(sum2, _mm_unpackhi_epi64( sum2, sum2)); sum2 = _mm_add_epi32(sum2, _mm_shufflelo_epi16( sum2, 0x0E)); sum3 = _mm_add_epi32(sum3, _mm_unpackhi_epi64( sum3, sum3)); sum3 = _mm_add_epi32(sum3, _mm_shufflelo_epi16( sum3, 0x0E)); vecSum = _mm_unpacklo_epi64(_mm_unpacklo_epi32(sum0, sum1), _mm_unpacklo_epi32(sum2, sum3)); for (;j<(len-3);j+=4) { vecX = OP_CVTEPI16_EPI32_M64(&x[j + 0]); vecX0 = _mm_shuffle_epi32(vecX, 0x00); vecX1 = _mm_shuffle_epi32(vecX, 0x55); vecX2 = _mm_shuffle_epi32(vecX, 0xaa); vecX3 = _mm_shuffle_epi32(vecX, 0xff); vecY0 = OP_CVTEPI16_EPI32_M64(&y[j + 0]); vecY1 = OP_CVTEPI16_EPI32_M64(&y[j + 1]); vecY2 = OP_CVTEPI16_EPI32_M64(&y[j + 2]); vecY3 = OP_CVTEPI16_EPI32_M64(&y[j + 3]); sum0 = _mm_mullo_epi32(vecX0, vecY0); sum1 = _mm_mullo_epi32(vecX1, vecY1); sum2 = _mm_mullo_epi32(vecX2, vecY2); sum3 = _mm_mullo_epi32(vecX3, vecY3); sum0 = _mm_add_epi32(sum0, sum1); sum2 = _mm_add_epi32(sum2, sum3); vecSum = _mm_add_epi32(vecSum, sum0); vecSum = _mm_add_epi32(vecSum, sum2); } for (;j #include #include "celt_lpc.h" #include "stack_alloc.h" #include "mathops.h" #include "vq.h" #include "x86cpu.h" #ifndef FIXED_POINT opus_val16 op_pvq_search_sse2(celt_norm *_X, int *iy, int K, int N, int arch) { int i, j; int pulsesLeft; float xy, yy; VARDECL(celt_norm, y); VARDECL(celt_norm, X); VARDECL(float, signy); __m128 signmask; __m128 sums; __m128i fours; SAVE_STACK; (void)arch; /* All bits set to zero, except for the sign bit. */ signmask = _mm_set_ps1(-0.f); fours = _mm_set_epi32(4, 4, 4, 4); ALLOC(y, N+3, celt_norm); ALLOC(X, N+3, celt_norm); ALLOC(signy, N+3, float); OPUS_COPY(X, _X, N); X[N] = X[N+1] = X[N+2] = 0; sums = _mm_setzero_ps(); for (j=0;j (N>>1)) { __m128i pulses_sum; __m128 yy4, xy4; __m128 rcp4; opus_val32 sum = _mm_cvtss_f32(sums); /* If X is too small, just replace it with a pulse at 0 */ /* Prevents infinities and NaNs from causing too many pulses to be allocated. 64 is an approximation of infinity here. */ if (!(sum > EPSILON && sum < 64)) { X[0] = QCONST16(1.f,14); j=1; do X[j]=0; while (++j=0); /* This should never happen, but just in case it does (e.g. on silence) we fill the first bin with pulses. */ if (pulsesLeft > N+3) { opus_val16 tmp = (opus_val16)pulsesLeft; yy = MAC16_16(yy, tmp, tmp); yy = MAC16_16(yy, tmp, y[0]); iy[0] += pulsesLeft; pulsesLeft=0; } for (i=0;i static _inline void cpuid(unsigned int CPUInfo[4], unsigned int InfoType) { __cpuid((int*)CPUInfo, InfoType); } #else #if defined(CPU_INFO_BY_C) #include #endif static void cpuid(unsigned int CPUInfo[4], unsigned int InfoType) { #if defined(CPU_INFO_BY_ASM) #if defined(__i386__) && defined(__PIC__) /* %ebx is PIC register in 32-bit, so mustn't clobber it. */ __asm__ __volatile__ ( "xchg %%ebx, %1\n" "cpuid\n" "xchg %%ebx, %1\n": "=a" (CPUInfo[0]), "=r" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3]) : "0" (InfoType) ); #else __asm__ __volatile__ ( "cpuid": "=a" (CPUInfo[0]), "=b" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3]) : "0" (InfoType) ); #endif #elif defined(CPU_INFO_BY_C) __get_cpuid(InfoType, &(CPUInfo[0]), &(CPUInfo[1]), &(CPUInfo[2]), &(CPUInfo[3])); #endif } #endif typedef struct CPU_Feature{ /* SIMD: 128-bit */ int HW_SSE; int HW_SSE2; int HW_SSE41; /* SIMD: 256-bit */ int HW_AVX; } CPU_Feature; static void opus_cpu_feature_check(CPU_Feature *cpu_feature) { unsigned int info[4] = {0}; unsigned int nIds = 0; cpuid(info, 0); nIds = info[0]; if (nIds >= 1){ cpuid(info, 1); cpu_feature->HW_SSE = (info[3] & (1 << 25)) != 0; cpu_feature->HW_SSE2 = (info[3] & (1 << 26)) != 0; cpu_feature->HW_SSE41 = (info[2] & (1 << 19)) != 0; cpu_feature->HW_AVX = (info[2] & (1 << 28)) != 0; } else { cpu_feature->HW_SSE = 0; cpu_feature->HW_SSE2 = 0; cpu_feature->HW_SSE41 = 0; cpu_feature->HW_AVX = 0; } } int opus_select_arch(void) { CPU_Feature cpu_feature; int arch; opus_cpu_feature_check(&cpu_feature); arch = 0; if (!cpu_feature.HW_SSE) { return arch; } arch++; if (!cpu_feature.HW_SSE2) { return arch; } arch++; if (!cpu_feature.HW_SSE41) { return arch; } arch++; if (!cpu_feature.HW_AVX) { return arch; } arch++; return arch; } #endif jamulus-3.9.1+dfsg/libs/opus/celt/x86/pitch_sse.c0000644000175000017500000001341514340334543020600 0ustar vimervimer/* Copyright (c) 2014, Cisco Systems, INC Written by XiangMingZhu WeiZhou MinPeng YanWang Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "macros.h" #include "celt_lpc.h" #include "stack_alloc.h" #include "mathops.h" #include "pitch.h" #if defined(OPUS_X86_MAY_HAVE_SSE) && !defined(FIXED_POINT) #include #include "arch.h" void xcorr_kernel_sse(const opus_val16 *x, const opus_val16 *y, opus_val32 sum[4], int len) { int j; __m128 xsum1, xsum2; xsum1 = _mm_loadu_ps(sum); xsum2 = _mm_setzero_ps(); for (j = 0; j < len-3; j += 4) { __m128 x0 = _mm_loadu_ps(x+j); __m128 yj = _mm_loadu_ps(y+j); __m128 y3 = _mm_loadu_ps(y+j+3); xsum1 = _mm_add_ps(xsum1,_mm_mul_ps(_mm_shuffle_ps(x0,x0,0x00),yj)); xsum2 = _mm_add_ps(xsum2,_mm_mul_ps(_mm_shuffle_ps(x0,x0,0x55), _mm_shuffle_ps(yj,y3,0x49))); xsum1 = _mm_add_ps(xsum1,_mm_mul_ps(_mm_shuffle_ps(x0,x0,0xaa), _mm_shuffle_ps(yj,y3,0x9e))); xsum2 = _mm_add_ps(xsum2,_mm_mul_ps(_mm_shuffle_ps(x0,x0,0xff),y3)); } if (j < len) { xsum1 = _mm_add_ps(xsum1,_mm_mul_ps(_mm_load1_ps(x+j),_mm_loadu_ps(y+j))); if (++j < len) { xsum2 = _mm_add_ps(xsum2,_mm_mul_ps(_mm_load1_ps(x+j),_mm_loadu_ps(y+j))); if (++j < len) { xsum1 = _mm_add_ps(xsum1,_mm_mul_ps(_mm_load1_ps(x+j),_mm_loadu_ps(y+j))); } } } _mm_storeu_ps(sum,_mm_add_ps(xsum1,xsum2)); } void dual_inner_prod_sse(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02, int N, opus_val32 *xy1, opus_val32 *xy2) { int i; __m128 xsum1, xsum2; xsum1 = _mm_setzero_ps(); xsum2 = _mm_setzero_ps(); for (i=0;i #include #include "macros.h" #include "celt_lpc.h" #include "stack_alloc.h" #include "mathops.h" #include "pitch.h" #if defined(OPUS_X86_MAY_HAVE_SSE2) && defined(FIXED_POINT) opus_val32 celt_inner_prod_sse2(const opus_val16 *x, const opus_val16 *y, int N) { opus_int i, dataSize16; opus_int32 sum; __m128i inVec1_76543210, inVec1_FEDCBA98, acc1; __m128i inVec2_76543210, inVec2_FEDCBA98, acc2; sum = 0; dataSize16 = N & ~15; acc1 = _mm_setzero_si128(); acc2 = _mm_setzero_si128(); for (i=0;i= 8) { inVec1_76543210 = _mm_loadu_si128((__m128i *)(&x[i + 0])); inVec2_76543210 = _mm_loadu_si128((__m128i *)(&y[i + 0])); inVec1_76543210 = _mm_madd_epi16(inVec1_76543210, inVec2_76543210); acc1 = _mm_add_epi32(acc1, inVec1_76543210); i += 8; } acc1 = _mm_add_epi32(acc1, _mm_unpackhi_epi64( acc1, acc1)); acc1 = _mm_add_epi32(acc1, _mm_shufflelo_epi16( acc1, 0x0E)); sum += _mm_cvtsi128_si32(acc1); for (;i #include #include #include "celt_lpc.h" #include "stack_alloc.h" #include "mathops.h" #include "pitch.h" #include "x86cpu.h" #if defined(FIXED_POINT) void celt_fir_sse4_1(const opus_val16 *x, const opus_val16 *num, opus_val16 *y, int N, int ord, int arch) { int i,j; VARDECL(opus_val16, rnum); __m128i vecNoA; opus_int32 noA ; SAVE_STACK; ALLOC(rnum, ord, opus_val16); for(i=0;i> 1; vecNoA = _mm_set_epi32(noA, noA, noA, noA); for (i=0;i #include #include #include #define MAX_PACKET 1275 int main(int argc, char *argv[]) { int err; char *inFile, *outFile; FILE *fin, *fout; OpusCustomMode *mode=NULL; OpusCustomEncoder *enc; OpusCustomDecoder *dec; int len; opus_int32 frame_size, channels, rate; int bytes_per_packet; unsigned char data[MAX_PACKET]; int complexity; #if !(defined (FIXED_POINT) && !defined(CUSTOM_MODES)) && defined(RESYNTH) int i; double rmsd = 0; #endif int count = 0; opus_int32 skip; opus_int16 *in, *out; if (argc != 9 && argc != 8 && argc != 7) { fprintf (stderr, "Usage: test_opus_custom " " [ [packet loss rate]] " " \n"); return 1; } rate = (opus_int32)atol(argv[1]); channels = atoi(argv[2]); frame_size = atoi(argv[3]); mode = opus_custom_mode_create(rate, frame_size, NULL); if (mode == NULL) { fprintf(stderr, "failed to create a mode\n"); return 1; } bytes_per_packet = atoi(argv[4]); if (bytes_per_packet < 0 || bytes_per_packet > MAX_PACKET) { fprintf (stderr, "bytes per packet must be between 0 and %d\n", MAX_PACKET); return 1; } inFile = argv[argc-2]; fin = fopen(inFile, "rb"); if (!fin) { fprintf (stderr, "Could not open input file %s\n", argv[argc-2]); return 1; } outFile = argv[argc-1]; fout = fopen(outFile, "wb+"); if (!fout) { fprintf (stderr, "Could not open output file %s\n", argv[argc-1]); fclose(fin); return 1; } enc = opus_custom_encoder_create(mode, channels, &err); if (err != 0) { fprintf(stderr, "Failed to create the encoder: %s\n", opus_strerror(err)); fclose(fin); fclose(fout); return 1; } dec = opus_custom_decoder_create(mode, channels, &err); if (err != 0) { fprintf(stderr, "Failed to create the decoder: %s\n", opus_strerror(err)); fclose(fin); fclose(fout); return 1; } opus_custom_decoder_ctl(dec, OPUS_GET_LOOKAHEAD(&skip)); if (argc>7) { complexity=atoi(argv[5]); opus_custom_encoder_ctl(enc,OPUS_SET_COMPLEXITY(complexity)); } in = (opus_int16*)malloc(frame_size*channels*sizeof(opus_int16)); out = (opus_int16*)malloc(frame_size*channels*sizeof(opus_int16)); while (!feof(fin)) { int ret; err = fread(in, sizeof(short), frame_size*channels, fin); if (feof(fin)) break; len = opus_custom_encode(enc, in, frame_size, data, bytes_per_packet); if (len <= 0) fprintf (stderr, "opus_custom_encode() failed: %s\n", opus_strerror(len)); /* This is for simulating bit errors */ #if 0 int errors = 0; int eid = 0; /* This simulates random bit error */ for (i=0;i 0) { rmsd = sqrt(rmsd/(1.0*frame_size*channels*count)); fprintf (stderr, "Error: encoder doesn't match decoder\n"); fprintf (stderr, "RMS mismatch is %f\n", rmsd); return 1; } else { fprintf (stderr, "Encoder matches decoder!!\n"); } #endif return 0; } jamulus-3.9.1+dfsg/libs/opus/celt/quant_bands.c0000644000175000017500000004443614340334543020500 0ustar vimervimer/* Copyright (c) 2007-2008 CSIRO Copyright (c) 2007-2009 Xiph.Org Foundation Written by Jean-Marc Valin */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "quant_bands.h" #include "laplace.h" #include #include "os_support.h" #include "arch.h" #include "mathops.h" #include "stack_alloc.h" #include "rate.h" #ifdef FIXED_POINT /* Mean energy in each band quantized in Q4 */ const signed char eMeans[25] = { 103,100, 92, 85, 81, 77, 72, 70, 78, 75, 73, 71, 78, 74, 69, 72, 70, 74, 76, 71, 60, 60, 60, 60, 60 }; #else /* Mean energy in each band quantized in Q4 and converted back to float */ const opus_val16 eMeans[25] = { 6.437500f, 6.250000f, 5.750000f, 5.312500f, 5.062500f, 4.812500f, 4.500000f, 4.375000f, 4.875000f, 4.687500f, 4.562500f, 4.437500f, 4.875000f, 4.625000f, 4.312500f, 4.500000f, 4.375000f, 4.625000f, 4.750000f, 4.437500f, 3.750000f, 3.750000f, 3.750000f, 3.750000f, 3.750000f }; #endif /* prediction coefficients: 0.9, 0.8, 0.65, 0.5 */ #ifdef FIXED_POINT static const opus_val16 pred_coef[4] = {29440, 26112, 21248, 16384}; static const opus_val16 beta_coef[4] = {30147, 22282, 12124, 6554}; static const opus_val16 beta_intra = 4915; #else static const opus_val16 pred_coef[4] = {29440/32768., 26112/32768., 21248/32768., 16384/32768.}; static const opus_val16 beta_coef[4] = {30147/32768., 22282/32768., 12124/32768., 6554/32768.}; static const opus_val16 beta_intra = 4915/32768.; #endif /*Parameters of the Laplace-like probability models used for the coarse energy. There is one pair of parameters for each frame size, prediction type (inter/intra), and band number. The first number of each pair is the probability of 0, and the second is the decay rate, both in Q8 precision.*/ static const unsigned char e_prob_model[4][2][42] = { /*120 sample frames.*/ { /*Inter*/ { 72, 127, 65, 129, 66, 128, 65, 128, 64, 128, 62, 128, 64, 128, 64, 128, 92, 78, 92, 79, 92, 78, 90, 79, 116, 41, 115, 40, 114, 40, 132, 26, 132, 26, 145, 17, 161, 12, 176, 10, 177, 11 }, /*Intra*/ { 24, 179, 48, 138, 54, 135, 54, 132, 53, 134, 56, 133, 55, 132, 55, 132, 61, 114, 70, 96, 74, 88, 75, 88, 87, 74, 89, 66, 91, 67, 100, 59, 108, 50, 120, 40, 122, 37, 97, 43, 78, 50 } }, /*240 sample frames.*/ { /*Inter*/ { 83, 78, 84, 81, 88, 75, 86, 74, 87, 71, 90, 73, 93, 74, 93, 74, 109, 40, 114, 36, 117, 34, 117, 34, 143, 17, 145, 18, 146, 19, 162, 12, 165, 10, 178, 7, 189, 6, 190, 8, 177, 9 }, /*Intra*/ { 23, 178, 54, 115, 63, 102, 66, 98, 69, 99, 74, 89, 71, 91, 73, 91, 78, 89, 86, 80, 92, 66, 93, 64, 102, 59, 103, 60, 104, 60, 117, 52, 123, 44, 138, 35, 133, 31, 97, 38, 77, 45 } }, /*480 sample frames.*/ { /*Inter*/ { 61, 90, 93, 60, 105, 42, 107, 41, 110, 45, 116, 38, 113, 38, 112, 38, 124, 26, 132, 27, 136, 19, 140, 20, 155, 14, 159, 16, 158, 18, 170, 13, 177, 10, 187, 8, 192, 6, 175, 9, 159, 10 }, /*Intra*/ { 21, 178, 59, 110, 71, 86, 75, 85, 84, 83, 91, 66, 88, 73, 87, 72, 92, 75, 98, 72, 105, 58, 107, 54, 115, 52, 114, 55, 112, 56, 129, 51, 132, 40, 150, 33, 140, 29, 98, 35, 77, 42 } }, /*960 sample frames.*/ { /*Inter*/ { 42, 121, 96, 66, 108, 43, 111, 40, 117, 44, 123, 32, 120, 36, 119, 33, 127, 33, 134, 34, 139, 21, 147, 23, 152, 20, 158, 25, 154, 26, 166, 21, 173, 16, 184, 13, 184, 10, 150, 13, 139, 15 }, /*Intra*/ { 22, 178, 63, 114, 74, 82, 84, 83, 92, 82, 103, 62, 96, 72, 96, 67, 101, 73, 107, 72, 113, 55, 118, 52, 125, 52, 118, 52, 117, 55, 135, 49, 137, 39, 157, 32, 145, 29, 97, 33, 77, 40 } } }; static const unsigned char small_energy_icdf[3]={2,1,0}; static opus_val32 loss_distortion(const opus_val16 *eBands, opus_val16 *oldEBands, int start, int end, int len, int C) { int c, i; opus_val32 dist = 0; c=0; do { for (i=start;inbEBands]; oldE = MAX16(-QCONST16(9.f,DB_SHIFT), oldEBands[i+c*m->nbEBands]); #ifdef FIXED_POINT f = SHL32(EXTEND32(x),7) - PSHR32(MULT16_16(coef,oldE), 8) - prev[c]; /* Rounding to nearest integer here is really important! */ qi = (f+QCONST32(.5f,DB_SHIFT+7))>>(DB_SHIFT+7); decay_bound = EXTRACT16(MAX32(-QCONST16(28.f,DB_SHIFT), SUB32((opus_val32)oldEBands[i+c*m->nbEBands],max_decay))); #else f = x-coef*oldE-prev[c]; /* Rounding to nearest integer here is really important! */ qi = (int)floor(.5f+f); decay_bound = MAX16(-QCONST16(28.f,DB_SHIFT), oldEBands[i+c*m->nbEBands]) - max_decay; #endif /* Prevent the energy from going down too quickly (e.g. for bands that have just one bin) */ if (qi < 0 && x < decay_bound) { qi += (int)SHR16(SUB16(decay_bound,x), DB_SHIFT); if (qi > 0) qi = 0; } qi0 = qi; /* If we don't have enough bits to encode all the energy, just assume something safe. */ tell = ec_tell(enc); bits_left = budget-tell-3*C*(end-i); if (i!=start && bits_left < 30) { if (bits_left < 24) qi = IMIN(1, qi); if (bits_left < 16) qi = IMAX(-1, qi); } if (lfe && i>=2) qi = IMIN(qi, 0); if (budget-tell >= 15) { int pi; pi = 2*IMIN(i,20); ec_laplace_encode(enc, &qi, prob_model[pi]<<7, prob_model[pi+1]<<6); } else if(budget-tell >= 2) { qi = IMAX(-1, IMIN(qi, 1)); ec_enc_icdf(enc, 2*qi^-(qi<0), small_energy_icdf, 2); } else if(budget-tell >= 1) { qi = IMIN(0, qi); ec_enc_bit_logp(enc, -qi, 1); } else qi = -1; error[i+c*m->nbEBands] = PSHR32(f,7) - SHL16(qi,DB_SHIFT); badness += abs(qi0-qi); q = (opus_val32)SHL32(EXTEND32(qi),DB_SHIFT); tmp = PSHR32(MULT16_16(coef,oldE),8) + prev[c] + SHL32(q,7); #ifdef FIXED_POINT tmp = MAX32(-QCONST32(28.f, DB_SHIFT+7), tmp); #endif oldEBands[i+c*m->nbEBands] = PSHR32(tmp, 7); prev[c] = prev[c] + SHL32(q,7) - MULT16_16(beta,PSHR32(q,8)); } while (++c < C); } return lfe ? 0 : badness; } void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd, const opus_val16 *eBands, opus_val16 *oldEBands, opus_uint32 budget, opus_val16 *error, ec_enc *enc, int C, int LM, int nbAvailableBytes, int force_intra, opus_val32 *delayedIntra, int two_pass, int loss_rate, int lfe) { int intra; opus_val16 max_decay; VARDECL(opus_val16, oldEBands_intra); VARDECL(opus_val16, error_intra); ec_enc enc_start_state; opus_uint32 tell; int badness1=0; opus_int32 intra_bias; opus_val32 new_distortion; SAVE_STACK; intra = force_intra || (!two_pass && *delayedIntra>2*C*(end-start) && nbAvailableBytes > (end-start)*C); intra_bias = (opus_int32)((budget**delayedIntra*loss_rate)/(C*512)); new_distortion = loss_distortion(eBands, oldEBands, start, effEnd, m->nbEBands, C); tell = ec_tell(enc); if (tell+3 > budget) two_pass = intra = 0; max_decay = QCONST16(16.f,DB_SHIFT); if (end-start>10) { #ifdef FIXED_POINT max_decay = MIN32(max_decay, SHL32(EXTEND32(nbAvailableBytes),DB_SHIFT-3)); #else max_decay = MIN32(max_decay, .125f*nbAvailableBytes); #endif } if (lfe) max_decay = QCONST16(3.f,DB_SHIFT); enc_start_state = *enc; ALLOC(oldEBands_intra, C*m->nbEBands, opus_val16); ALLOC(error_intra, C*m->nbEBands, opus_val16); OPUS_COPY(oldEBands_intra, oldEBands, C*m->nbEBands); if (two_pass || intra) { badness1 = quant_coarse_energy_impl(m, start, end, eBands, oldEBands_intra, budget, tell, e_prob_model[LM][1], error_intra, enc, C, LM, 1, max_decay, lfe); } if (!intra) { unsigned char *intra_buf; ec_enc enc_intra_state; opus_int32 tell_intra; opus_uint32 nstart_bytes; opus_uint32 nintra_bytes; opus_uint32 save_bytes; int badness2; VARDECL(unsigned char, intra_bits); tell_intra = ec_tell_frac(enc); enc_intra_state = *enc; nstart_bytes = ec_range_bytes(&enc_start_state); nintra_bytes = ec_range_bytes(&enc_intra_state); intra_buf = ec_get_buffer(&enc_intra_state) + nstart_bytes; save_bytes = nintra_bytes-nstart_bytes; if (save_bytes == 0) save_bytes = ALLOC_NONE; ALLOC(intra_bits, save_bytes, unsigned char); /* Copy bits from intra bit-stream */ OPUS_COPY(intra_bits, intra_buf, nintra_bytes - nstart_bytes); *enc = enc_start_state; badness2 = quant_coarse_energy_impl(m, start, end, eBands, oldEBands, budget, tell, e_prob_model[LM][intra], error, enc, C, LM, 0, max_decay, lfe); if (two_pass && (badness1 < badness2 || (badness1 == badness2 && ((opus_int32)ec_tell_frac(enc))+intra_bias > tell_intra))) { *enc = enc_intra_state; /* Copy intra bits to bit-stream */ OPUS_COPY(intra_buf, intra_bits, nintra_bytes - nstart_bytes); OPUS_COPY(oldEBands, oldEBands_intra, C*m->nbEBands); OPUS_COPY(error, error_intra, C*m->nbEBands); intra = 1; } } else { OPUS_COPY(oldEBands, oldEBands_intra, C*m->nbEBands); OPUS_COPY(error, error_intra, C*m->nbEBands); } if (intra) *delayedIntra = new_distortion; else *delayedIntra = ADD32(MULT16_32_Q15(MULT16_16_Q15(pred_coef[LM], pred_coef[LM]),*delayedIntra), new_distortion); RESTORE_STACK; } void quant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, opus_val16 *error, int *fine_quant, ec_enc *enc, int C) { int i, c; /* Encode finer resolution */ for (i=start;inbEBands]+QCONST16(.5f,DB_SHIFT))>>(DB_SHIFT-fine_quant[i]); #else q2 = (int)floor((error[i+c*m->nbEBands]+.5f)*frac); #endif if (q2 > frac-1) q2 = frac-1; if (q2<0) q2 = 0; ec_enc_bits(enc, q2, fine_quant[i]); #ifdef FIXED_POINT offset = SUB16(SHR32(SHL32(EXTEND32(q2),DB_SHIFT)+QCONST16(.5f,DB_SHIFT),fine_quant[i]),QCONST16(.5f,DB_SHIFT)); #else offset = (q2+.5f)*(1<<(14-fine_quant[i]))*(1.f/16384) - .5f; #endif oldEBands[i+c*m->nbEBands] += offset; error[i+c*m->nbEBands] -= offset; /*printf ("%f ", error[i] - offset);*/ } while (++c < C); } } void quant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *oldEBands, opus_val16 *error, int *fine_quant, int *fine_priority, int bits_left, ec_enc *enc, int C) { int i, prio, c; /* Use up the remaining bits */ for (prio=0;prio<2;prio++) { for (i=start;i=C ;i++) { if (fine_quant[i] >= MAX_FINE_BITS || fine_priority[i]!=prio) continue; c=0; do { int q2; opus_val16 offset; q2 = error[i+c*m->nbEBands]<0 ? 0 : 1; ec_enc_bits(enc, q2, 1); #ifdef FIXED_POINT offset = SHR16(SHL16(q2,DB_SHIFT)-QCONST16(.5f,DB_SHIFT),fine_quant[i]+1); #else offset = (q2-.5f)*(1<<(14-fine_quant[i]-1))*(1.f/16384); #endif oldEBands[i+c*m->nbEBands] += offset; error[i+c*m->nbEBands] -= offset; bits_left--; } while (++c < C); } } } void unquant_coarse_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int intra, ec_dec *dec, int C, int LM) { const unsigned char *prob_model = e_prob_model[LM][intra]; int i, c; opus_val32 prev[2] = {0, 0}; opus_val16 coef; opus_val16 beta; opus_int32 budget; opus_int32 tell; if (intra) { coef = 0; beta = beta_intra; } else { beta = beta_coef[LM]; coef = pred_coef[LM]; } budget = dec->storage*8; /* Decode at a fixed coarse resolution */ for (i=start;i=15) { int pi; pi = 2*IMIN(i,20); qi = ec_laplace_decode(dec, prob_model[pi]<<7, prob_model[pi+1]<<6); } else if(budget-tell>=2) { qi = ec_dec_icdf(dec, small_energy_icdf, 2); qi = (qi>>1)^-(qi&1); } else if(budget-tell>=1) { qi = -ec_dec_bit_logp(dec, 1); } else qi = -1; q = (opus_val32)SHL32(EXTEND32(qi),DB_SHIFT); oldEBands[i+c*m->nbEBands] = MAX16(-QCONST16(9.f,DB_SHIFT), oldEBands[i+c*m->nbEBands]); tmp = PSHR32(MULT16_16(coef,oldEBands[i+c*m->nbEBands]),8) + prev[c] + SHL32(q,7); #ifdef FIXED_POINT tmp = MAX32(-QCONST32(28.f, DB_SHIFT+7), tmp); #endif oldEBands[i+c*m->nbEBands] = PSHR32(tmp, 7); prev[c] = prev[c] + SHL32(q,7) - MULT16_16(beta,PSHR32(q,8)); } while (++c < C); } } void unquant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int *fine_quant, ec_dec *dec, int C) { int i, c; /* Decode finer resolution */ for (i=start;inbEBands] += offset; } while (++c < C); } } void unquant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int *fine_quant, int *fine_priority, int bits_left, ec_dec *dec, int C) { int i, prio, c; /* Use up the remaining bits */ for (prio=0;prio<2;prio++) { for (i=start;i=C ;i++) { if (fine_quant[i] >= MAX_FINE_BITS || fine_priority[i]!=prio) continue; c=0; do { int q2; opus_val16 offset; q2 = ec_dec_bits(dec, 1); #ifdef FIXED_POINT offset = SHR16(SHL16(q2,DB_SHIFT)-QCONST16(.5f,DB_SHIFT),fine_quant[i]+1); #else offset = (q2-.5f)*(1<<(14-fine_quant[i]-1))*(1.f/16384); #endif oldEBands[i+c*m->nbEBands] += offset; bits_left--; } while (++c < C); } } } void amp2Log2(const CELTMode *m, int effEnd, int end, celt_ener *bandE, opus_val16 *bandLogE, int C) { int c, i; c=0; do { for (i=0;inbEBands] = celt_log2(bandE[i+c*m->nbEBands]) - SHL16((opus_val16)eMeans[i],6); #ifdef FIXED_POINT /* Compensate for bandE[] being Q12 but celt_log2() taking a Q14 input. */ bandLogE[i+c*m->nbEBands] += QCONST16(2.f, DB_SHIFT); #endif } for (i=effEnd;inbEBands+i] = -QCONST16(14.f,DB_SHIFT); } while (++c < C); } jamulus-3.9.1+dfsg/libs/opus/celt/arm/0000755000175000017500000000000014340334543016601 5ustar vimervimerjamulus-3.9.1+dfsg/libs/opus/celt/arm/fixed_armv4.h0000644000175000017500000000561014340334543021164 0ustar vimervimer/* Copyright (C) 2013 Xiph.Org Foundation and contributors */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef FIXED_ARMv4_H #define FIXED_ARMv4_H /** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */ #undef MULT16_32_Q16 static OPUS_INLINE opus_val32 MULT16_32_Q16_armv4(opus_val16 a, opus_val32 b) { unsigned rd_lo; int rd_hi; __asm__( "#MULT16_32_Q16\n\t" "smull %0, %1, %2, %3\n\t" : "=&r"(rd_lo), "=&r"(rd_hi) : "%r"(b),"r"(SHL32(a,16)) ); return rd_hi; } #define MULT16_32_Q16(a, b) (MULT16_32_Q16_armv4(a, b)) /** 16x32 multiplication, followed by a 15-bit shift right. Results fits in 32 bits */ #undef MULT16_32_Q15 static OPUS_INLINE opus_val32 MULT16_32_Q15_armv4(opus_val16 a, opus_val32 b) { unsigned rd_lo; int rd_hi; __asm__( "#MULT16_32_Q15\n\t" "smull %0, %1, %2, %3\n\t" : "=&r"(rd_lo), "=&r"(rd_hi) : "%r"(b), "r"(SHL32(a,16)) ); /*We intentionally don't OR in the high bit of rd_lo for speed.*/ return SHL32(rd_hi,1); } #define MULT16_32_Q15(a, b) (MULT16_32_Q15_armv4(a, b)) /** 16x32 multiply, followed by a 15-bit shift right and 32-bit add. b must fit in 31 bits. Result fits in 32 bits. */ #undef MAC16_32_Q15 #define MAC16_32_Q15(c, a, b) ADD32(c, MULT16_32_Q15(a, b)) /** 16x32 multiply, followed by a 16-bit shift right and 32-bit add. Result fits in 32 bits. */ #undef MAC16_32_Q16 #define MAC16_32_Q16(c, a, b) ADD32(c, MULT16_32_Q16(a, b)) /** 32x32 multiplication, followed by a 31-bit shift right. Results fits in 32 bits */ #undef MULT32_32_Q31 #define MULT32_32_Q31(a,b) (opus_val32)((((opus_int64)(a)) * ((opus_int64)(b)))>>31) #endif jamulus-3.9.1+dfsg/libs/opus/celt/arm/celt_neon_intr.c0000644000175000017500000001520214340334543021747 0ustar vimervimer/* Copyright (c) 2014-2015 Xiph.Org Foundation Written by Viswanath Puttagunta */ /** @file celt_neon_intr.c @brief ARM Neon Intrinsic optimizations for celt */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "../pitch.h" #if defined(FIXED_POINT) void xcorr_kernel_neon_fixed(const opus_val16 * x, const opus_val16 * y, opus_val32 sum[4], int len) { int j; int32x4_t a = vld1q_s32(sum); /* Load y[0...3] */ /* This requires len>0 to always be valid (which we assert in the C code). */ int16x4_t y0 = vld1_s16(y); y += 4; for (j = 0; j + 8 <= len; j += 8) { /* Load x[0...7] */ int16x8_t xx = vld1q_s16(x); int16x4_t x0 = vget_low_s16(xx); int16x4_t x4 = vget_high_s16(xx); /* Load y[4...11] */ int16x8_t yy = vld1q_s16(y); int16x4_t y4 = vget_low_s16(yy); int16x4_t y8 = vget_high_s16(yy); int32x4_t a0 = vmlal_lane_s16(a, y0, x0, 0); int32x4_t a1 = vmlal_lane_s16(a0, y4, x4, 0); int16x4_t y1 = vext_s16(y0, y4, 1); int16x4_t y5 = vext_s16(y4, y8, 1); int32x4_t a2 = vmlal_lane_s16(a1, y1, x0, 1); int32x4_t a3 = vmlal_lane_s16(a2, y5, x4, 1); int16x4_t y2 = vext_s16(y0, y4, 2); int16x4_t y6 = vext_s16(y4, y8, 2); int32x4_t a4 = vmlal_lane_s16(a3, y2, x0, 2); int32x4_t a5 = vmlal_lane_s16(a4, y6, x4, 2); int16x4_t y3 = vext_s16(y0, y4, 3); int16x4_t y7 = vext_s16(y4, y8, 3); int32x4_t a6 = vmlal_lane_s16(a5, y3, x0, 3); int32x4_t a7 = vmlal_lane_s16(a6, y7, x4, 3); y0 = y8; a = a7; x += 8; y += 8; } for (; j < len; j++) { int16x4_t x0 = vld1_dup_s16(x); /* load next x */ int32x4_t a0 = vmlal_s16(a, y0, x0); int16x4_t y4 = vld1_dup_s16(y); /* load next y */ y0 = vext_s16(y0, y4, 1); a = a0; x++; y++; } vst1q_s32(sum, a); } #else /* * Function: xcorr_kernel_neon_float * --------------------------------- * Computes 4 correlation values and stores them in sum[4] */ static void xcorr_kernel_neon_float(const float32_t *x, const float32_t *y, float32_t sum[4], int len) { float32x4_t YY[3]; float32x4_t YEXT[3]; float32x4_t XX[2]; float32x2_t XX_2; float32x4_t SUMM; const float32_t *xi = x; const float32_t *yi = y; celt_assert(len>0); YY[0] = vld1q_f32(yi); SUMM = vdupq_n_f32(0); /* Consume 8 elements in x vector and 12 elements in y * vector. However, the 12'th element never really gets * touched in this loop. So, if len == 8, then we only * must access y[0] to y[10]. y[11] must not be accessed * hence make sure len > 8 and not len >= 8 */ while (len > 8) { yi += 4; YY[1] = vld1q_f32(yi); yi += 4; YY[2] = vld1q_f32(yi); XX[0] = vld1q_f32(xi); xi += 4; XX[1] = vld1q_f32(xi); xi += 4; SUMM = vmlaq_lane_f32(SUMM, YY[0], vget_low_f32(XX[0]), 0); YEXT[0] = vextq_f32(YY[0], YY[1], 1); SUMM = vmlaq_lane_f32(SUMM, YEXT[0], vget_low_f32(XX[0]), 1); YEXT[1] = vextq_f32(YY[0], YY[1], 2); SUMM = vmlaq_lane_f32(SUMM, YEXT[1], vget_high_f32(XX[0]), 0); YEXT[2] = vextq_f32(YY[0], YY[1], 3); SUMM = vmlaq_lane_f32(SUMM, YEXT[2], vget_high_f32(XX[0]), 1); SUMM = vmlaq_lane_f32(SUMM, YY[1], vget_low_f32(XX[1]), 0); YEXT[0] = vextq_f32(YY[1], YY[2], 1); SUMM = vmlaq_lane_f32(SUMM, YEXT[0], vget_low_f32(XX[1]), 1); YEXT[1] = vextq_f32(YY[1], YY[2], 2); SUMM = vmlaq_lane_f32(SUMM, YEXT[1], vget_high_f32(XX[1]), 0); YEXT[2] = vextq_f32(YY[1], YY[2], 3); SUMM = vmlaq_lane_f32(SUMM, YEXT[2], vget_high_f32(XX[1]), 1); YY[0] = YY[2]; len -= 8; } /* Consume 4 elements in x vector and 8 elements in y * vector. However, the 8'th element in y never really gets * touched in this loop. So, if len == 4, then we only * must access y[0] to y[6]. y[7] must not be accessed * hence make sure len>4 and not len>=4 */ if (len > 4) { yi += 4; YY[1] = vld1q_f32(yi); XX[0] = vld1q_f32(xi); xi += 4; SUMM = vmlaq_lane_f32(SUMM, YY[0], vget_low_f32(XX[0]), 0); YEXT[0] = vextq_f32(YY[0], YY[1], 1); SUMM = vmlaq_lane_f32(SUMM, YEXT[0], vget_low_f32(XX[0]), 1); YEXT[1] = vextq_f32(YY[0], YY[1], 2); SUMM = vmlaq_lane_f32(SUMM, YEXT[1], vget_high_f32(XX[0]), 0); YEXT[2] = vextq_f32(YY[0], YY[1], 3); SUMM = vmlaq_lane_f32(SUMM, YEXT[2], vget_high_f32(XX[0]), 1); YY[0] = YY[1]; len -= 4; } while (--len > 0) { XX_2 = vld1_dup_f32(xi++); SUMM = vmlaq_lane_f32(SUMM, YY[0], XX_2, 0); YY[0]= vld1q_f32(++yi); } XX_2 = vld1_dup_f32(xi); SUMM = vmlaq_lane_f32(SUMM, YY[0], XX_2, 0); vst1q_f32(sum, SUMM); } void celt_pitch_xcorr_float_neon(const opus_val16 *_x, const opus_val16 *_y, opus_val32 *xcorr, int len, int max_pitch, int arch) { int i; (void)arch; celt_assert(max_pitch > 0); celt_sig_assert((((unsigned char *)_x-(unsigned char *)NULL)&3)==0); for (i = 0; i < (max_pitch-3); i += 4) { xcorr_kernel_neon_float((const float32_t *)_x, (const float32_t *)_y+i, (float32_t *)xcorr+i, len); } /* In case max_pitch isn't a multiple of 4, do non-unrolled version. */ for (; i < max_pitch; i++) { xcorr[i] = celt_inner_prod_neon(_x, _y+i, len); } } #endif jamulus-3.9.1+dfsg/libs/opus/celt/arm/fixed_arm64.h0000644000175000017500000000271414340334543021066 0ustar vimervimer/* Copyright (C) 2015 Vidyo */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef FIXED_ARM64_H #define FIXED_ARM64_H #include #undef SIG2WORD16 #define SIG2WORD16(x) (vqmovns_s32(PSHR32((x), SIG_SHIFT))) #endif jamulus-3.9.1+dfsg/libs/opus/celt/arm/armopts.s.in0000644000175000017500000000326314340334543021063 0ustar vimervimer/* Copyright (C) 2013 Mozilla Corporation */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ ; Set the following to 1 if we have EDSP instructions ; (LDRD/STRD, etc., ARMv5E and later). OPUS_ARM_MAY_HAVE_EDSP * @OPUS_ARM_MAY_HAVE_EDSP@ ; Set the following to 1 if we have ARMv6 media instructions. OPUS_ARM_MAY_HAVE_MEDIA * @OPUS_ARM_MAY_HAVE_MEDIA@ ; Set the following to 1 if we have NEON (some ARMv7) OPUS_ARM_MAY_HAVE_NEON * @OPUS_ARM_MAY_HAVE_NEON@ END jamulus-3.9.1+dfsg/libs/opus/celt/arm/celt_mdct_ne10.c0000644000175000017500000001766614340334543021546 0ustar vimervimer/* Copyright (c) 2015 Xiph.Org Foundation Written by Viswanath Puttagunta */ /** @file celt_mdct_ne10.c @brief ARM Neon optimizations for mdct using NE10 library */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef SKIP_CONFIG_H #ifdef HAVE_CONFIG_H #include "config.h" #endif #endif #include "kiss_fft.h" #include "_kiss_fft_guts.h" #include "mdct.h" #include "stack_alloc.h" void clt_mdct_forward_neon(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out, const opus_val16 *window, int overlap, int shift, int stride, int arch) { int i; int N, N2, N4; VARDECL(kiss_fft_scalar, f); VARDECL(kiss_fft_cpx, f2); const kiss_fft_state *st = l->kfft[shift]; const kiss_twiddle_scalar *trig; SAVE_STACK; N = l->n; trig = l->trig; for (i=0;i>= 1; trig += N; } N2 = N>>1; N4 = N>>2; ALLOC(f, N2, kiss_fft_scalar); ALLOC(f2, N4, kiss_fft_cpx); /* Consider the input to be composed of four blocks: [a, b, c, d] */ /* Window, shuffle, fold */ { /* Temp pointers to make it really clear to the compiler what we're doing */ const kiss_fft_scalar * OPUS_RESTRICT xp1 = in+(overlap>>1); const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+N2-1+(overlap>>1); kiss_fft_scalar * OPUS_RESTRICT yp = f; const opus_val16 * OPUS_RESTRICT wp1 = window+(overlap>>1); const opus_val16 * OPUS_RESTRICT wp2 = window+(overlap>>1)-1; for(i=0;i<((overlap+3)>>2);i++) { /* Real part arranged as -d-cR, Imag part arranged as -b+aR*/ *yp++ = MULT16_32_Q15(*wp2, xp1[N2]) + MULT16_32_Q15(*wp1,*xp2); *yp++ = MULT16_32_Q15(*wp1, *xp1) - MULT16_32_Q15(*wp2, xp2[-N2]); xp1+=2; xp2-=2; wp1+=2; wp2-=2; } wp1 = window; wp2 = window+overlap-1; for(;i>2);i++) { /* Real part arranged as a-bR, Imag part arranged as -c-dR */ *yp++ = *xp2; *yp++ = *xp1; xp1+=2; xp2-=2; } for(;ii,t[N4+i]) - S_MUL(fp->r,t[i]); yi = S_MUL(fp->r,t[N4+i]) + S_MUL(fp->i,t[i]); *yp1 = yr; *yp2 = yi; fp++; yp1 += 2*stride; yp2 -= 2*stride; } } RESTORE_STACK; } void clt_mdct_backward_neon(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out, const opus_val16 * OPUS_RESTRICT window, int overlap, int shift, int stride, int arch) { int i; int N, N2, N4; VARDECL(kiss_fft_scalar, f); const kiss_twiddle_scalar *trig; const kiss_fft_state *st = l->kfft[shift]; N = l->n; trig = l->trig; for (i=0;i>= 1; trig += N; } N2 = N>>1; N4 = N>>2; ALLOC(f, N2, kiss_fft_scalar); /* Pre-rotate */ { /* Temp pointers to make it really clear to the compiler what we're doing */ const kiss_fft_scalar * OPUS_RESTRICT xp1 = in; const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+stride*(N2-1); kiss_fft_scalar * OPUS_RESTRICT yp = f; const kiss_twiddle_scalar * OPUS_RESTRICT t = &trig[0]; for(i=0;i>1)), arch); /* Post-rotate and de-shuffle from both ends of the buffer at once to make it in-place. */ { kiss_fft_scalar * yp0 = out+(overlap>>1); kiss_fft_scalar * yp1 = out+(overlap>>1)+N2-2; const kiss_twiddle_scalar *t = &trig[0]; /* Loop to (N4+1)>>1 to handle odd N4. When N4 is odd, the middle pair will be computed twice. */ for(i=0;i<(N4+1)>>1;i++) { kiss_fft_scalar re, im, yr, yi; kiss_twiddle_scalar t0, t1; re = yp0[0]; im = yp0[1]; t0 = t[i]; t1 = t[N4+i]; /* We'd scale up by 2 here, but instead it's done when mixing the windows */ yr = S_MUL(re,t0) + S_MUL(im,t1); yi = S_MUL(re,t1) - S_MUL(im,t0); re = yp1[0]; im = yp1[1]; yp0[0] = yr; yp1[1] = yi; t0 = t[(N4-i-1)]; t1 = t[(N2-i-1)]; /* We'd scale up by 2 here, but instead it's done when mixing the windows */ yr = S_MUL(re,t0) + S_MUL(im,t1); yi = S_MUL(re,t1) - S_MUL(im,t0); yp1[0] = yr; yp0[1] = yi; yp0 += 2; yp1 -= 2; } } /* Mirror on both sides for TDAC */ { kiss_fft_scalar * OPUS_RESTRICT xp1 = out+overlap-1; kiss_fft_scalar * OPUS_RESTRICT yp1 = out; const opus_val16 * OPUS_RESTRICT wp1 = window; const opus_val16 * OPUS_RESTRICT wp2 = window+overlap-1; for(i = 0; i < overlap/2; i++) { kiss_fft_scalar x1, x2; x1 = *xp1; x2 = *yp1; *yp1++ = MULT16_32_Q15(*wp2, x2) - MULT16_32_Q15(*wp1, x1); *xp1-- = MULT16_32_Q15(*wp1, x2) + MULT16_32_Q15(*wp2, x1); wp1++; wp2--; } } RESTORE_STACK; } jamulus-3.9.1+dfsg/libs/opus/celt/arm/kiss_fft_armv4.h0000644000175000017500000001056114340334543021676 0ustar vimervimer/*Copyright (c) 2013, Xiph.Org Foundation and contributors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/ #ifndef KISS_FFT_ARMv4_H #define KISS_FFT_ARMv4_H #if !defined(KISS_FFT_GUTS_H) #error "This file should only be included from _kiss_fft_guts.h" #endif #ifdef FIXED_POINT #undef C_MUL #define C_MUL(m,a,b) \ do{ \ int br__; \ int bi__; \ int tt__; \ __asm__ __volatile__( \ "#C_MUL\n\t" \ "ldrsh %[br], [%[bp], #0]\n\t" \ "ldm %[ap], {r0,r1}\n\t" \ "ldrsh %[bi], [%[bp], #2]\n\t" \ "smull %[tt], %[mi], r1, %[br]\n\t" \ "smlal %[tt], %[mi], r0, %[bi]\n\t" \ "rsb %[bi], %[bi], #0\n\t" \ "smull %[br], %[mr], r0, %[br]\n\t" \ "mov %[tt], %[tt], lsr #15\n\t" \ "smlal %[br], %[mr], r1, %[bi]\n\t" \ "orr %[mi], %[tt], %[mi], lsl #17\n\t" \ "mov %[br], %[br], lsr #15\n\t" \ "orr %[mr], %[br], %[mr], lsl #17\n\t" \ : [mr]"=r"((m).r), [mi]"=r"((m).i), \ [br]"=&r"(br__), [bi]"=r"(bi__), [tt]"=r"(tt__) \ : [ap]"r"(&(a)), [bp]"r"(&(b)) \ : "r0", "r1" \ ); \ } \ while(0) #undef C_MUL4 #define C_MUL4(m,a,b) \ do{ \ int br__; \ int bi__; \ int tt__; \ __asm__ __volatile__( \ "#C_MUL4\n\t" \ "ldrsh %[br], [%[bp], #0]\n\t" \ "ldm %[ap], {r0,r1}\n\t" \ "ldrsh %[bi], [%[bp], #2]\n\t" \ "smull %[tt], %[mi], r1, %[br]\n\t" \ "smlal %[tt], %[mi], r0, %[bi]\n\t" \ "rsb %[bi], %[bi], #0\n\t" \ "smull %[br], %[mr], r0, %[br]\n\t" \ "mov %[tt], %[tt], lsr #17\n\t" \ "smlal %[br], %[mr], r1, %[bi]\n\t" \ "orr %[mi], %[tt], %[mi], lsl #15\n\t" \ "mov %[br], %[br], lsr #17\n\t" \ "orr %[mr], %[br], %[mr], lsl #15\n\t" \ : [mr]"=r"((m).r), [mi]"=r"((m).i), \ [br]"=&r"(br__), [bi]"=r"(bi__), [tt]"=r"(tt__) \ : [ap]"r"(&(a)), [bp]"r"(&(b)) \ : "r0", "r1" \ ); \ } \ while(0) #undef C_MULC #define C_MULC(m,a,b) \ do{ \ int br__; \ int bi__; \ int tt__; \ __asm__ __volatile__( \ "#C_MULC\n\t" \ "ldrsh %[br], [%[bp], #0]\n\t" \ "ldm %[ap], {r0,r1}\n\t" \ "ldrsh %[bi], [%[bp], #2]\n\t" \ "smull %[tt], %[mr], r0, %[br]\n\t" \ "smlal %[tt], %[mr], r1, %[bi]\n\t" \ "rsb %[bi], %[bi], #0\n\t" \ "smull %[br], %[mi], r1, %[br]\n\t" \ "mov %[tt], %[tt], lsr #15\n\t" \ "smlal %[br], %[mi], r0, %[bi]\n\t" \ "orr %[mr], %[tt], %[mr], lsl #17\n\t" \ "mov %[br], %[br], lsr #15\n\t" \ "orr %[mi], %[br], %[mi], lsl #17\n\t" \ : [mr]"=r"((m).r), [mi]"=r"((m).i), \ [br]"=&r"(br__), [bi]"=r"(bi__), [tt]"=r"(tt__) \ : [ap]"r"(&(a)), [bp]"r"(&(b)) \ : "r0", "r1" \ ); \ } \ while(0) #endif /* FIXED_POINT */ #endif /* KISS_FFT_ARMv4_H */ jamulus-3.9.1+dfsg/libs/opus/celt/arm/mdct_arm.h0000644000175000017500000000507514340334543020547 0ustar vimervimer/* Copyright (c) 2015 Xiph.Org Foundation Written by Viswanath Puttagunta */ /** @file arm_mdct.h @brief ARM Neon Intrinsic optimizations for mdct using NE10 library */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(MDCT_ARM_H) #define MDCT_ARM_H #include "mdct.h" #if defined(HAVE_ARM_NE10) /** Compute a forward MDCT and scale by 4/N, trashes the input array */ void clt_mdct_forward_neon(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out, const opus_val16 *window, int overlap, int shift, int stride, int arch); void clt_mdct_backward_neon(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out, const opus_val16 *window, int overlap, int shift, int stride, int arch); #if !defined(OPUS_HAVE_RTCD) #define OVERRIDE_OPUS_MDCT (1) #define clt_mdct_forward(_l, _in, _out, _window, _int, _shift, _stride, _arch) \ clt_mdct_forward_neon(_l, _in, _out, _window, _int, _shift, _stride, _arch) #define clt_mdct_backward(_l, _in, _out, _window, _int, _shift, _stride, _arch) \ clt_mdct_backward_neon(_l, _in, _out, _window, _int, _shift, _stride, _arch) #endif /* OPUS_HAVE_RTCD */ #endif /* HAVE_ARM_NE10 */ #endif jamulus-3.9.1+dfsg/libs/opus/celt/arm/fft_arm.h0000644000175000017500000000457414340334543020402 0ustar vimervimer/* Copyright (c) 2015 Xiph.Org Foundation Written by Viswanath Puttagunta */ /** @file fft_arm.h @brief ARM Neon Intrinsic optimizations for fft using NE10 library */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(FFT_ARM_H) #define FFT_ARM_H #include "kiss_fft.h" #if defined(HAVE_ARM_NE10) int opus_fft_alloc_arm_neon(kiss_fft_state *st); void opus_fft_free_arm_neon(kiss_fft_state *st); void opus_fft_neon(const kiss_fft_state *st, const kiss_fft_cpx *fin, kiss_fft_cpx *fout); void opus_ifft_neon(const kiss_fft_state *st, const kiss_fft_cpx *fin, kiss_fft_cpx *fout); #if !defined(OPUS_HAVE_RTCD) #define OVERRIDE_OPUS_FFT (1) #define opus_fft_alloc_arch(_st, arch) \ ((void)(arch), opus_fft_alloc_arm_neon(_st)) #define opus_fft_free_arch(_st, arch) \ ((void)(arch), opus_fft_free_arm_neon(_st)) #define opus_fft(_st, _fin, _fout, arch) \ ((void)(arch), opus_fft_neon(_st, _fin, _fout)) #define opus_ifft(_st, _fin, _fout, arch) \ ((void)(arch), opus_ifft_neon(_st, _fin, _fout)) #endif /* OPUS_HAVE_RTCD */ #endif /* HAVE_ARM_NE10 */ #endif jamulus-3.9.1+dfsg/libs/opus/celt/arm/celt_fft_ne10.c0000644000175000017500000001310714340334543021360 0ustar vimervimer/* Copyright (c) 2015 Xiph.Org Foundation Written by Viswanath Puttagunta */ /** @file celt_fft_ne10.c @brief ARM Neon optimizations for fft using NE10 library */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef SKIP_CONFIG_H #ifdef HAVE_CONFIG_H #include "config.h" #endif #endif #include #include "os_support.h" #include "kiss_fft.h" #include "stack_alloc.h" #if !defined(FIXED_POINT) # define NE10_FFT_ALLOC_C2C_TYPE_NEON ne10_fft_alloc_c2c_float32_neon # define NE10_FFT_CFG_TYPE_T ne10_fft_cfg_float32_t # define NE10_FFT_STATE_TYPE_T ne10_fft_state_float32_t # define NE10_FFT_DESTROY_C2C_TYPE ne10_fft_destroy_c2c_float32 # define NE10_FFT_CPX_TYPE_T ne10_fft_cpx_float32_t # define NE10_FFT_C2C_1D_TYPE_NEON ne10_fft_c2c_1d_float32_neon #else # define NE10_FFT_ALLOC_C2C_TYPE_NEON(nfft) ne10_fft_alloc_c2c_int32_neon(nfft) # define NE10_FFT_CFG_TYPE_T ne10_fft_cfg_int32_t # define NE10_FFT_STATE_TYPE_T ne10_fft_state_int32_t # define NE10_FFT_DESTROY_C2C_TYPE ne10_fft_destroy_c2c_int32 # define NE10_FFT_DESTROY_C2C_TYPE ne10_fft_destroy_c2c_int32 # define NE10_FFT_CPX_TYPE_T ne10_fft_cpx_int32_t # define NE10_FFT_C2C_1D_TYPE_NEON ne10_fft_c2c_1d_int32_neon #endif #if defined(CUSTOM_MODES) /* nfft lengths in NE10 that support scaled fft */ # define NE10_FFTSCALED_SUPPORT_MAX 4 static const int ne10_fft_scaled_support[NE10_FFTSCALED_SUPPORT_MAX] = { 480, 240, 120, 60 }; int opus_fft_alloc_arm_neon(kiss_fft_state *st) { int i; size_t memneeded = sizeof(struct arch_fft_state); st->arch_fft = (arch_fft_state *)opus_alloc(memneeded); if (!st->arch_fft) return -1; for (i = 0; i < NE10_FFTSCALED_SUPPORT_MAX; i++) { if(st->nfft == ne10_fft_scaled_support[i]) break; } if (i == NE10_FFTSCALED_SUPPORT_MAX) { /* This nfft length (scaled fft) is not supported in NE10 */ st->arch_fft->is_supported = 0; st->arch_fft->priv = NULL; } else { st->arch_fft->is_supported = 1; st->arch_fft->priv = (void *)NE10_FFT_ALLOC_C2C_TYPE_NEON(st->nfft); if (st->arch_fft->priv == NULL) { return -1; } } return 0; } void opus_fft_free_arm_neon(kiss_fft_state *st) { NE10_FFT_CFG_TYPE_T cfg; if (!st->arch_fft) return; cfg = (NE10_FFT_CFG_TYPE_T)st->arch_fft->priv; if (cfg) NE10_FFT_DESTROY_C2C_TYPE(cfg); opus_free(st->arch_fft); } #endif void opus_fft_neon(const kiss_fft_state *st, const kiss_fft_cpx *fin, kiss_fft_cpx *fout) { NE10_FFT_STATE_TYPE_T state; NE10_FFT_CFG_TYPE_T cfg = &state; VARDECL(NE10_FFT_CPX_TYPE_T, buffer); SAVE_STACK; ALLOC(buffer, st->nfft, NE10_FFT_CPX_TYPE_T); if (!st->arch_fft->is_supported) { /* This nfft length (scaled fft) not supported in NE10 */ opus_fft_c(st, fin, fout); } else { memcpy((void *)cfg, st->arch_fft->priv, sizeof(NE10_FFT_STATE_TYPE_T)); state.buffer = (NE10_FFT_CPX_TYPE_T *)&buffer[0]; #if !defined(FIXED_POINT) state.is_forward_scaled = 1; NE10_FFT_C2C_1D_TYPE_NEON((NE10_FFT_CPX_TYPE_T *)fout, (NE10_FFT_CPX_TYPE_T *)fin, cfg, 0); #else NE10_FFT_C2C_1D_TYPE_NEON((NE10_FFT_CPX_TYPE_T *)fout, (NE10_FFT_CPX_TYPE_T *)fin, cfg, 0, 1); #endif } RESTORE_STACK; } void opus_ifft_neon(const kiss_fft_state *st, const kiss_fft_cpx *fin, kiss_fft_cpx *fout) { NE10_FFT_STATE_TYPE_T state; NE10_FFT_CFG_TYPE_T cfg = &state; VARDECL(NE10_FFT_CPX_TYPE_T, buffer); SAVE_STACK; ALLOC(buffer, st->nfft, NE10_FFT_CPX_TYPE_T); if (!st->arch_fft->is_supported) { /* This nfft length (scaled fft) not supported in NE10 */ opus_ifft_c(st, fin, fout); } else { memcpy((void *)cfg, st->arch_fft->priv, sizeof(NE10_FFT_STATE_TYPE_T)); state.buffer = (NE10_FFT_CPX_TYPE_T *)&buffer[0]; #if !defined(FIXED_POINT) state.is_backward_scaled = 0; NE10_FFT_C2C_1D_TYPE_NEON((NE10_FFT_CPX_TYPE_T *)fout, (NE10_FFT_CPX_TYPE_T *)fin, cfg, 1); #else NE10_FFT_C2C_1D_TYPE_NEON((NE10_FFT_CPX_TYPE_T *)fout, (NE10_FFT_CPX_TYPE_T *)fin, cfg, 1, 0); #endif } RESTORE_STACK; } jamulus-3.9.1+dfsg/libs/opus/celt/arm/pitch_arm.h0000644000175000017500000001474714340334543020735 0ustar vimervimer/* Copyright (c) 2010 Xiph.Org Foundation * Copyright (c) 2013 Parrot */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(PITCH_ARM_H) # define PITCH_ARM_H # include "armcpu.h" # if defined(OPUS_ARM_MAY_HAVE_NEON_INTR) opus_val32 celt_inner_prod_neon(const opus_val16 *x, const opus_val16 *y, int N); void dual_inner_prod_neon(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02, int N, opus_val32 *xy1, opus_val32 *xy2); # if !defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_PRESUME_NEON) # define OVERRIDE_CELT_INNER_PROD (1) # define OVERRIDE_DUAL_INNER_PROD (1) # define celt_inner_prod(x, y, N, arch) ((void)(arch), PRESUME_NEON(celt_inner_prod)(x, y, N)) # define dual_inner_prod(x, y01, y02, N, xy1, xy2, arch) ((void)(arch), PRESUME_NEON(dual_inner_prod)(x, y01, y02, N, xy1, xy2)) # endif # endif # if !defined(OVERRIDE_CELT_INNER_PROD) # if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR)) extern opus_val32 (*const CELT_INNER_PROD_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *x, const opus_val16 *y, int N); # define OVERRIDE_CELT_INNER_PROD (1) # define celt_inner_prod(x, y, N, arch) ((*CELT_INNER_PROD_IMPL[(arch)&OPUS_ARCHMASK])(x, y, N)) # elif defined(OPUS_ARM_PRESUME_NEON_INTR) # define OVERRIDE_CELT_INNER_PROD (1) # define celt_inner_prod(x, y, N, arch) ((void)(arch), celt_inner_prod_neon(x, y, N)) # endif # endif # if !defined(OVERRIDE_DUAL_INNER_PROD) # if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR)) extern void (*const DUAL_INNER_PROD_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02, int N, opus_val32 *xy1, opus_val32 *xy2); # define OVERRIDE_DUAL_INNER_PROD (1) # define dual_inner_prod(x, y01, y02, N, xy1, xy2, arch) ((*DUAL_INNER_PROD_IMPL[(arch)&OPUS_ARCHMASK])(x, y01, y02, N, xy1, xy2)) # elif defined(OPUS_ARM_PRESUME_NEON_INTR) # define OVERRIDE_DUAL_INNER_PROD (1) # define dual_inner_prod(x, y01, y02, N, xy1, xy2, arch) ((void)(arch), dual_inner_prod_neon(x, y01, y02, N, xy1, xy2)) # endif # endif # if defined(FIXED_POINT) # if defined(OPUS_ARM_MAY_HAVE_NEON) opus_val32 celt_pitch_xcorr_neon(const opus_val16 *_x, const opus_val16 *_y, opus_val32 *xcorr, int len, int max_pitch, int arch); # endif # if defined(OPUS_ARM_MAY_HAVE_MEDIA) # define celt_pitch_xcorr_media MAY_HAVE_EDSP(celt_pitch_xcorr) # endif # if defined(OPUS_ARM_MAY_HAVE_EDSP) opus_val32 celt_pitch_xcorr_edsp(const opus_val16 *_x, const opus_val16 *_y, opus_val32 *xcorr, int len, int max_pitch, int arch); # endif # if defined(OPUS_HAVE_RTCD) && \ ((defined(OPUS_ARM_MAY_HAVE_NEON) && !defined(OPUS_ARM_PRESUME_NEON)) || \ (defined(OPUS_ARM_MAY_HAVE_MEDIA) && !defined(OPUS_ARM_PRESUME_MEDIA)) || \ (defined(OPUS_ARM_MAY_HAVE_EDSP) && !defined(OPUS_ARM_PRESUME_EDSP))) extern opus_val32 (*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *, const opus_val16 *, opus_val32 *, int, int, int); # define OVERRIDE_PITCH_XCORR (1) # define celt_pitch_xcorr(_x, _y, xcorr, len, max_pitch, arch) \ ((*CELT_PITCH_XCORR_IMPL[(arch)&OPUS_ARCHMASK])(_x, _y, \ xcorr, len, max_pitch, arch)) # elif defined(OPUS_ARM_PRESUME_EDSP) || \ defined(OPUS_ARM_PRESUME_MEDIA) || \ defined(OPUS_ARM_PRESUME_NEON) # define OVERRIDE_PITCH_XCORR (1) # define celt_pitch_xcorr (PRESUME_NEON(celt_pitch_xcorr)) # endif # if defined(OPUS_ARM_MAY_HAVE_NEON_INTR) void xcorr_kernel_neon_fixed( const opus_val16 *x, const opus_val16 *y, opus_val32 sum[4], int len); # endif # if defined(OPUS_HAVE_RTCD) && \ (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR)) extern void (*const XCORR_KERNEL_IMPL[OPUS_ARCHMASK + 1])( const opus_val16 *x, const opus_val16 *y, opus_val32 sum[4], int len); # define OVERRIDE_XCORR_KERNEL (1) # define xcorr_kernel(x, y, sum, len, arch) \ ((*XCORR_KERNEL_IMPL[(arch) & OPUS_ARCHMASK])(x, y, sum, len)) # elif defined(OPUS_ARM_PRESUME_NEON_INTR) # define OVERRIDE_XCORR_KERNEL (1) # define xcorr_kernel(x, y, sum, len, arch) \ ((void)arch, xcorr_kernel_neon_fixed(x, y, sum, len)) # endif #else /* Start !FIXED_POINT */ /* Float case */ #if defined(OPUS_ARM_MAY_HAVE_NEON_INTR) void celt_pitch_xcorr_float_neon(const opus_val16 *_x, const opus_val16 *_y, opus_val32 *xcorr, int len, int max_pitch, int arch); #endif # if defined(OPUS_HAVE_RTCD) && \ (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR)) extern void (*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *, const opus_val16 *, opus_val32 *, int, int, int); # define OVERRIDE_PITCH_XCORR (1) # define celt_pitch_xcorr(_x, _y, xcorr, len, max_pitch, arch) \ ((*CELT_PITCH_XCORR_IMPL[(arch)&OPUS_ARCHMASK])(_x, _y, \ xcorr, len, max_pitch, arch)) # elif defined(OPUS_ARM_PRESUME_NEON_INTR) # define OVERRIDE_PITCH_XCORR (1) # define celt_pitch_xcorr celt_pitch_xcorr_float_neon # endif #endif /* end !FIXED_POINT */ #endif jamulus-3.9.1+dfsg/libs/opus/celt/arm/kiss_fft_armv5e.h0000644000175000017500000001000514340334543022035 0ustar vimervimer/*Copyright (c) 2013, Xiph.Org Foundation and contributors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/ #ifndef KISS_FFT_ARMv5E_H #define KISS_FFT_ARMv5E_H #if !defined(KISS_FFT_GUTS_H) #error "This file should only be included from _kiss_fft_guts.h" #endif #ifdef FIXED_POINT #if defined(__thumb__)||defined(__thumb2__) #define LDRD_CONS "Q" #else #define LDRD_CONS "Uq" #endif #undef C_MUL #define C_MUL(m,a,b) \ do{ \ int mr1__; \ int mr2__; \ int mi__; \ long long aval__; \ int bval__; \ __asm__( \ "#C_MUL\n\t" \ "ldrd %[aval], %H[aval], %[ap]\n\t" \ "ldr %[bval], %[bp]\n\t" \ "smulwb %[mi], %H[aval], %[bval]\n\t" \ "smulwb %[mr1], %[aval], %[bval]\n\t" \ "smulwt %[mr2], %H[aval], %[bval]\n\t" \ "smlawt %[mi], %[aval], %[bval], %[mi]\n\t" \ : [mr1]"=r"(mr1__), [mr2]"=r"(mr2__), [mi]"=r"(mi__), \ [aval]"=&r"(aval__), [bval]"=r"(bval__) \ : [ap]LDRD_CONS(a), [bp]"m"(b) \ ); \ (m).r = SHL32(SUB32(mr1__, mr2__), 1); \ (m).i = SHL32(mi__, 1); \ } \ while(0) #undef C_MUL4 #define C_MUL4(m,a,b) \ do{ \ int mr1__; \ int mr2__; \ int mi__; \ long long aval__; \ int bval__; \ __asm__( \ "#C_MUL4\n\t" \ "ldrd %[aval], %H[aval], %[ap]\n\t" \ "ldr %[bval], %[bp]\n\t" \ "smulwb %[mi], %H[aval], %[bval]\n\t" \ "smulwb %[mr1], %[aval], %[bval]\n\t" \ "smulwt %[mr2], %H[aval], %[bval]\n\t" \ "smlawt %[mi], %[aval], %[bval], %[mi]\n\t" \ : [mr1]"=r"(mr1__), [mr2]"=r"(mr2__), [mi]"=r"(mi__), \ [aval]"=&r"(aval__), [bval]"=r"(bval__) \ : [ap]LDRD_CONS(a), [bp]"m"(b) \ ); \ (m).r = SHR32(SUB32(mr1__, mr2__), 1); \ (m).i = SHR32(mi__, 1); \ } \ while(0) #undef C_MULC #define C_MULC(m,a,b) \ do{ \ int mr__; \ int mi1__; \ int mi2__; \ long long aval__; \ int bval__; \ __asm__( \ "#C_MULC\n\t" \ "ldrd %[aval], %H[aval], %[ap]\n\t" \ "ldr %[bval], %[bp]\n\t" \ "smulwb %[mr], %[aval], %[bval]\n\t" \ "smulwb %[mi1], %H[aval], %[bval]\n\t" \ "smulwt %[mi2], %[aval], %[bval]\n\t" \ "smlawt %[mr], %H[aval], %[bval], %[mr]\n\t" \ : [mr]"=r"(mr__), [mi1]"=r"(mi1__), [mi2]"=r"(mi2__), \ [aval]"=&r"(aval__), [bval]"=r"(bval__) \ : [ap]LDRD_CONS(a), [bp]"m"(b) \ ); \ (m).r = SHL32(mr__, 1); \ (m).i = SHL32(SUB32(mi1__, mi2__), 1); \ } \ while(0) #endif /* FIXED_POINT */ #endif /* KISS_FFT_GUTS_H */ jamulus-3.9.1+dfsg/libs/opus/celt/arm/arm2gnu.pl0000755000175000017500000002501214340334543020514 0ustar vimervimer#!/usr/bin/perl # Copyright (C) 2002-2013 Xiph.org Foundation # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # - Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # - Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER # OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. my $bigend; # little/big endian my $nxstack; my $apple = 0; my $symprefix = ""; $nxstack = 0; eval 'exec /usr/local/bin/perl -S $0 ${1+"$@"}' if $running_under_some_shell; while ($ARGV[0] =~ /^-/) { $_ = shift; last if /^--$/; if (/^-n$/) { $nflag++; next; } if (/^--apple$/) { $apple = 1; $symprefix = "_"; next; } die "I don't recognize this switch: $_\\n"; } $printit++ unless $nflag; $\ = "\n"; # automatically add newline on print $n=0; $thumb = 0; # ARM mode by default, not Thumb. @proc_stack = (); printf (" .syntax unified\n"); LINE: while (<>) { # For ADRLs we need to add a new line after the substituted one. $addPadding = 0; # First, we do not dare to touch *anything* inside double quotes, do we? # Second, if you want a dollar character in the string, # insert two of them -- that's how ARM C and assembler treat strings. s/^([A-Za-z_]\w*)[ \t]+DCB[ \t]*\"/$1: .ascii \"/ && do { s/\$\$/\$/g; next }; s/\bDCB\b[ \t]*\"/.ascii \"/ && do { s/\$\$/\$/g; next }; s/^(\S+)\s+RN\s+(\S+)/$1 .req r$2/ && do { s/\$\$/\$/g; next }; # If there's nothing on a line but a comment, don't try to apply any further # substitutions (this is a cheap hack to avoid mucking up the license header) s/^([ \t]*);/$1@/ && do { s/\$\$/\$/g; next }; # If substituted -- leave immediately ! s/@/,:/; s/;/@/; while ( /@.*'/ ) { s/(@.*)'/$1/g; } s/\{FALSE\}/0/g; s/\{TRUE\}/1/g; s/\{(\w\w\w\w+)\}/$1/g; s/\bINCLUDE[ \t]*([^ \t\n]+)/.include \"$1\"/; s/\bGET[ \t]*([^ \t\n]+)/.include \"${ my $x=$1; $x =~ s|\.s|-gnu.S|; \$x }\"/; s/\bIMPORT\b/.extern/; s/\bEXPORT\b\s*/.global $symprefix/; s/^(\s+)\[/$1IF/; s/^(\s+)\|/$1ELSE/; s/^(\s+)\]/$1ENDIF/; s/IF *:DEF:/ .ifdef/; s/IF *:LNOT: *:DEF:/ .ifndef/; s/ELSE/ .else/; s/ENDIF/ .endif/; if( /\bIF\b/ ) { s/\bIF\b/ .if/; s/=/==/; } if ( $n == 2) { s/\$/\\/g; } if ($n == 1) { s/\$//g; s/label//g; $n = 2; } if ( /MACRO/ ) { s/MACRO *\n/.macro/; $n=1; } if ( /\bMEND\b/ ) { s/\bMEND\b/.endm/; $n=0; } # ".rdata" doesn't work in 'as' version 2.13.2, as it is ".rodata" there. # if ( /\bAREA\b/ ) { my $align; $align = "2"; if ( /ALIGN=(\d+)/ ) { $align = $1; } if ( /CODE/ ) { $nxstack = 1; } s/^(.+)CODE(.+)READONLY(.*)/ .text/; s/^(.+)DATA(.+)READONLY(.*)/ .section .rdata/; s/^(.+)\|\|\.data\|\|(.+)/ .data/; s/^(.+)\|\|\.bss\|\|(.+)/ .bss/; s/$/; .p2align $align/; # Enable NEON instructions but don't produce a binary that requires # ARMv7. RVCT does not have equivalent directives, so we just do this # for all CODE areas. if ( /.text/ ) { # Separating .arch, .fpu, etc., by semicolons does not work (gas # thinks the semicolon is part of the arch name, even when there's # whitespace separating them). Sadly this means our line numbers # won't match the original source file (we could use the .line # directive, which is documented to be obsolete, but then gdb will # show the wrong line in the translated source file). s/$/; .arch armv7-a\n .fpu neon\n .object_arch armv4t/ unless ($apple); } } s/\|\|\.constdata\$(\d+)\|\|/.L_CONST$1/; # ||.constdata$3|| s/\|\|\.bss\$(\d+)\|\|/.L_BSS$1/; # ||.bss$2|| s/\|\|\.data\$(\d+)\|\|/.L_DATA$1/; # ||.data$2|| s/\|\|([a-zA-Z0-9_]+)\@([a-zA-Z0-9_]+)\|\|/@ $&/; s/^(\s+)\%(\s)/ .space $1/; s/\|(.+)\.(\d+)\|/\.$1_$2/; # |L80.123| -> .L80_123 s/\bCODE32\b/.code 32/ && do {$thumb = 0}; s/\bCODE16\b/.code 16/ && do {$thumb = 1}; if (/\bPROC\b/) { my $prefix; my $proc; /^([A-Za-z_\.]\w+)\b/; $proc = $1; $prefix = ""; if ($proc) { $prefix = $prefix.sprintf("\t.type\t%s, %%function", $proc) unless ($apple); # Make sure we $prefix isn't empty here (for the $apple case). # We handle mangling the label here, make sure it doesn't match # the label handling below (if $prefix would be empty). $prefix = $prefix."; "; push(@proc_stack, $proc); s/^[A-Za-z_\.]\w+/$symprefix$&:/; } $prefix = $prefix."\t.thumb_func; " if ($thumb); s/\bPROC\b/@ $&/; $_ = $prefix.$_; } s/^(\s*)(S|Q|SH|U|UQ|UH)ASX\b/$1$2ADDSUBX/; s/^(\s*)(S|Q|SH|U|UQ|UH)SAX\b/$1$2SUBADDX/; if (/\bENDP\b/) { my $proc; s/\bENDP\b/@ $&/; $proc = pop(@proc_stack); $_ = "\t.size $proc, .-$proc".$_ if ($proc && !$apple); } s/\bSUBT\b/@ $&/; s/\bDATA\b/@ $&/; # DATA directive is deprecated -- Asm guide, p.7-25 s/\bKEEP\b/@ $&/; s/\bEXPORTAS\b/@ $&/; s/\|\|(.)+\bEQU\b/@ $&/; s/\|\|([\w\$]+)\|\|/$1/; s/\bENTRY\b/@ $&/; s/\bASSERT\b/@ $&/; s/\bGBLL\b/@ $&/; s/\bGBLA\b/@ $&/; s/^\W+OPT\b/@ $&/; s/:OR:/|/g; s/:SHL:/<>/g; s/:AND:/&/g; s/:LAND:/&&/g; s/CPSR/cpsr/; s/SPSR/spsr/; s/ALIGN$/.balign 4/; s/ALIGN\s+([0-9x]+)$/.balign $1/; s/psr_cxsf/psr_all/; s/LTORG/.ltorg/; s/^([A-Za-z_]\w*)[ \t]+EQU/ .set $1,/; s/^([A-Za-z_]\w*)[ \t]+SETL/ .set $1,/; s/^([A-Za-z_]\w*)[ \t]+SETA/ .set $1,/; s/^([A-Za-z_]\w*)[ \t]+\*/ .set $1,/; # {PC} + 0xdeadfeed --> . + 0xdeadfeed s/\{PC\} \+/ \. +/; # Single hex constant on the line ! # # >>> NOTE <<< # Double-precision floats in gcc are always mixed-endian, which means # bytes in two words are little-endian, but words are big-endian. # So, 0x0000deadfeed0000 would be stored as 0x0000dead at low address # and 0xfeed0000 at high address. # s/\bDCFD\b[ \t]+0x([a-fA-F0-9]{8})([a-fA-F0-9]{8})/.long 0x$1, 0x$2/; # Only decimal constants on the line, no hex ! s/\bDCFD\b[ \t]+([0-9\.\-]+)/.double $1/; # Single hex constant on the line ! # s/\bDCFS\b[ \t]+0x([a-f0-9]{8})([a-f0-9]{8})/.long 0x$1, 0x$2/; # Only decimal constants on the line, no hex ! # s/\bDCFS\b[ \t]+([0-9\.\-]+)/.double $1/; s/\bDCFS[ \t]+0x/.word 0x/; s/\bDCFS\b/.float/; s/^([A-Za-z_]\w*)[ \t]+DCD/$1 .word/; s/\bDCD\b/.word/; s/^([A-Za-z_]\w*)[ \t]+DCW/$1 .short/; s/\bDCW\b/.short/; s/^([A-Za-z_]\w*)[ \t]+DCB/$1 .byte/; s/\bDCB\b/.byte/; s/^([A-Za-z_]\w*)[ \t]+\%/.comm $1,/; s/^[A-Za-z_\.]\w+/$&:/; s/^(\d+)/$1:/; s/\%(\d+)/$1b_or_f/; s/\%[Bb](\d+)/$1b/; s/\%[Ff](\d+)/$1f/; s/\%[Ff][Tt](\d+)/$1f/; s/&([\dA-Fa-f]+)/0x$1/; if ( /\b2_[01]+\b/ ) { s/\b2_([01]+)\b/conv$1&&&&/g; while ( /[01][01][01][01]&&&&/ ) { s/0000&&&&/&&&&0/g; s/0001&&&&/&&&&1/g; s/0010&&&&/&&&&2/g; s/0011&&&&/&&&&3/g; s/0100&&&&/&&&&4/g; s/0101&&&&/&&&&5/g; s/0110&&&&/&&&&6/g; s/0111&&&&/&&&&7/g; s/1000&&&&/&&&&8/g; s/1001&&&&/&&&&9/g; s/1010&&&&/&&&&A/g; s/1011&&&&/&&&&B/g; s/1100&&&&/&&&&C/g; s/1101&&&&/&&&&D/g; s/1110&&&&/&&&&E/g; s/1111&&&&/&&&&F/g; } s/000&&&&/&&&&0/g; s/001&&&&/&&&&1/g; s/010&&&&/&&&&2/g; s/011&&&&/&&&&3/g; s/100&&&&/&&&&4/g; s/101&&&&/&&&&5/g; s/110&&&&/&&&&6/g; s/111&&&&/&&&&7/g; s/00&&&&/&&&&0/g; s/01&&&&/&&&&1/g; s/10&&&&/&&&&2/g; s/11&&&&/&&&&3/g; s/0&&&&/&&&&0/g; s/1&&&&/&&&&1/g; s/conv&&&&/0x/g; } if ( /commandline/) { if( /-bigend/) { $bigend=1; } } if ( /\bDCDU\b/ ) { my $cmd=$_; my $value; my $prefix; my $w1; my $w2; my $w3; my $w4; s/\s+DCDU\b/@ $&/; $cmd =~ /\bDCDU\b\s+0x(\d+)/; $value = $1; $value =~ /(\w\w)(\w\w)(\w\w)(\w\w)/; $w1 = $1; $w2 = $2; $w3 = $3; $w4 = $4; if( $bigend ne "") { # big endian $prefix = "\t.byte\t0x".$w1.";". "\t.byte\t0x".$w2.";". "\t.byte\t0x".$w3.";". "\t.byte\t0x".$w4."; "; } else { # little endian $prefix = "\t.byte\t0x".$w4.";". "\t.byte\t0x".$w3.";". "\t.byte\t0x".$w2.";". "\t.byte\t0x".$w1."; "; } $_=$prefix.$_; } if ( /\badrl\b/i ) { s/\badrl\s+(\w+)\s*,\s*(\w+)/ldr $1,=$2/i; $addPadding = 1; } s/\bEND\b/@ END/; } continue { printf ("%s", $_) if $printit; if ($addPadding != 0) { printf (" mov r0,r0\n"); $addPadding = 0; } } #If we had a code section, mark that this object doesn't need an executable # stack. if ($nxstack && !$apple) { printf (" .section\t.note.GNU-stack,\"\",\%\%progbits\n"); } jamulus-3.9.1+dfsg/libs/opus/celt/arm/arm_celt_map.c0000644000175000017500000001477214340334543021403 0ustar vimervimer/* Copyright (c) 2010 Xiph.Org Foundation * Copyright (c) 2013 Parrot */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "pitch.h" #include "kiss_fft.h" #include "mdct.h" #if defined(OPUS_HAVE_RTCD) # if defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR) opus_val32 (*const CELT_INNER_PROD_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *x, const opus_val16 *y, int N) = { celt_inner_prod_c, /* ARMv4 */ celt_inner_prod_c, /* EDSP */ celt_inner_prod_c, /* Media */ celt_inner_prod_neon /* NEON */ }; void (*const DUAL_INNER_PROD_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02, int N, opus_val32 *xy1, opus_val32 *xy2) = { dual_inner_prod_c, /* ARMv4 */ dual_inner_prod_c, /* EDSP */ dual_inner_prod_c, /* Media */ dual_inner_prod_neon /* NEON */ }; # endif # if defined(FIXED_POINT) # if ((defined(OPUS_ARM_MAY_HAVE_NEON) && !defined(OPUS_ARM_PRESUME_NEON)) || \ (defined(OPUS_ARM_MAY_HAVE_MEDIA) && !defined(OPUS_ARM_PRESUME_MEDIA)) || \ (defined(OPUS_ARM_MAY_HAVE_EDSP) && !defined(OPUS_ARM_PRESUME_EDSP))) opus_val32 (*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *, const opus_val16 *, opus_val32 *, int, int, int) = { celt_pitch_xcorr_c, /* ARMv4 */ MAY_HAVE_EDSP(celt_pitch_xcorr), /* EDSP */ MAY_HAVE_MEDIA(celt_pitch_xcorr), /* Media */ MAY_HAVE_NEON(celt_pitch_xcorr) /* NEON */ }; # endif # else /* !FIXED_POINT */ # if defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR) void (*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *, const opus_val16 *, opus_val32 *, int, int, int) = { celt_pitch_xcorr_c, /* ARMv4 */ celt_pitch_xcorr_c, /* EDSP */ celt_pitch_xcorr_c, /* Media */ celt_pitch_xcorr_float_neon /* Neon */ }; # endif # endif /* FIXED_POINT */ #if defined(FIXED_POINT) && defined(OPUS_HAVE_RTCD) && \ defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR) void (*const XCORR_KERNEL_IMPL[OPUS_ARCHMASK + 1])( const opus_val16 *x, const opus_val16 *y, opus_val32 sum[4], int len ) = { xcorr_kernel_c, /* ARMv4 */ xcorr_kernel_c, /* EDSP */ xcorr_kernel_c, /* Media */ xcorr_kernel_neon_fixed, /* Neon */ }; #endif # if defined(OPUS_ARM_MAY_HAVE_NEON_INTR) # if defined(HAVE_ARM_NE10) # if defined(CUSTOM_MODES) int (*const OPUS_FFT_ALLOC_ARCH_IMPL[OPUS_ARCHMASK+1])(kiss_fft_state *st) = { opus_fft_alloc_arch_c, /* ARMv4 */ opus_fft_alloc_arch_c, /* EDSP */ opus_fft_alloc_arch_c, /* Media */ opus_fft_alloc_arm_neon /* Neon with NE10 library support */ }; void (*const OPUS_FFT_FREE_ARCH_IMPL[OPUS_ARCHMASK+1])(kiss_fft_state *st) = { opus_fft_free_arch_c, /* ARMv4 */ opus_fft_free_arch_c, /* EDSP */ opus_fft_free_arch_c, /* Media */ opus_fft_free_arm_neon /* Neon with NE10 */ }; # endif /* CUSTOM_MODES */ void (*const OPUS_FFT[OPUS_ARCHMASK+1])(const kiss_fft_state *cfg, const kiss_fft_cpx *fin, kiss_fft_cpx *fout) = { opus_fft_c, /* ARMv4 */ opus_fft_c, /* EDSP */ opus_fft_c, /* Media */ opus_fft_neon /* Neon with NE10 */ }; void (*const OPUS_IFFT[OPUS_ARCHMASK+1])(const kiss_fft_state *cfg, const kiss_fft_cpx *fin, kiss_fft_cpx *fout) = { opus_ifft_c, /* ARMv4 */ opus_ifft_c, /* EDSP */ opus_ifft_c, /* Media */ opus_ifft_neon /* Neon with NE10 */ }; void (*const CLT_MDCT_FORWARD_IMPL[OPUS_ARCHMASK+1])(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out, const opus_val16 *window, int overlap, int shift, int stride, int arch) = { clt_mdct_forward_c, /* ARMv4 */ clt_mdct_forward_c, /* EDSP */ clt_mdct_forward_c, /* Media */ clt_mdct_forward_neon /* Neon with NE10 */ }; void (*const CLT_MDCT_BACKWARD_IMPL[OPUS_ARCHMASK+1])(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out, const opus_val16 *window, int overlap, int shift, int stride, int arch) = { clt_mdct_backward_c, /* ARMv4 */ clt_mdct_backward_c, /* EDSP */ clt_mdct_backward_c, /* Media */ clt_mdct_backward_neon /* Neon with NE10 */ }; # endif /* HAVE_ARM_NE10 */ # endif /* OPUS_ARM_MAY_HAVE_NEON_INTR */ #endif /* OPUS_HAVE_RTCD */ jamulus-3.9.1+dfsg/libs/opus/celt/arm/armcpu.c0000644000175000017500000001307714340334543020244 0ustar vimervimer/* Copyright (c) 2010 Xiph.Org Foundation * Copyright (c) 2013 Parrot */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* Original code from libtheora modified to suit to Opus */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef OPUS_HAVE_RTCD #include "armcpu.h" #include "cpu_support.h" #include "os_support.h" #include "opus_types.h" #include "arch.h" #define OPUS_CPU_ARM_V4_FLAG (1< static OPUS_INLINE opus_uint32 opus_cpu_capabilities(void){ opus_uint32 flags; flags=0; /* MSVC has no OPUS_INLINE __asm support for ARM, but it does let you __emit * instructions via their assembled hex code. * All of these instructions should be essentially nops. */ # if defined(OPUS_ARM_MAY_HAVE_EDSP) || defined(OPUS_ARM_MAY_HAVE_MEDIA) \ || defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR) __try{ /*PLD [r13]*/ __emit(0xF5DDF000); flags|=OPUS_CPU_ARM_EDSP_FLAG; } __except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){ /*Ignore exception.*/ } # if defined(OPUS_ARM_MAY_HAVE_MEDIA) \ || defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR) __try{ /*SHADD8 r3,r3,r3*/ __emit(0xE6333F93); flags|=OPUS_CPU_ARM_MEDIA_FLAG; } __except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){ /*Ignore exception.*/ } # if defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR) __try{ /*VORR q0,q0,q0*/ __emit(0xF2200150); flags|=OPUS_CPU_ARM_NEON_FLAG; } __except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){ /*Ignore exception.*/ } # endif # endif # endif return flags; } #elif defined(__linux__) /* Linux based */ opus_uint32 opus_cpu_capabilities(void) { opus_uint32 flags = 0; FILE *cpuinfo; /* Reading /proc/self/auxv would be easier, but that doesn't work reliably on * Android */ cpuinfo = fopen("/proc/cpuinfo", "r"); if(cpuinfo != NULL) { /* 512 should be enough for anybody (it's even enough for all the flags that * x86 has accumulated... so far). */ char buf[512]; while(fgets(buf, 512, cpuinfo) != NULL) { # if defined(OPUS_ARM_MAY_HAVE_EDSP) || defined(OPUS_ARM_MAY_HAVE_MEDIA) \ || defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR) /* Search for edsp and neon flag */ if(memcmp(buf, "Features", 8) == 0) { char *p; p = strstr(buf, " edsp"); if(p != NULL && (p[5] == ' ' || p[5] == '\n')) flags |= OPUS_CPU_ARM_EDSP_FLAG; # if defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR) p = strstr(buf, " neon"); if(p != NULL && (p[5] == ' ' || p[5] == '\n')) flags |= OPUS_CPU_ARM_NEON_FLAG; # endif } # endif # if defined(OPUS_ARM_MAY_HAVE_MEDIA) \ || defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR) /* Search for media capabilities (>= ARMv6) */ if(memcmp(buf, "CPU architecture:", 17) == 0) { int version; version = atoi(buf+17); if(version >= 6) flags |= OPUS_CPU_ARM_MEDIA_FLAG; } # endif } fclose(cpuinfo); } return flags; } #else /* The feature registers which can tell us what the processor supports are * accessible in privileged modes only, so we can't have a general user-space * detection method like on x86.*/ # error "Configured to use ARM asm but no CPU detection method available for " \ "your platform. Reconfigure with --disable-rtcd (or send patches)." #endif int opus_select_arch(void) { opus_uint32 flags = opus_cpu_capabilities(); int arch = 0; if(!(flags & OPUS_CPU_ARM_EDSP_FLAG)) { /* Asserts ensure arch values are sequential */ celt_assert(arch == OPUS_ARCH_ARM_V4); return arch; } arch++; if(!(flags & OPUS_CPU_ARM_MEDIA_FLAG)) { celt_assert(arch == OPUS_ARCH_ARM_EDSP); return arch; } arch++; if(!(flags & OPUS_CPU_ARM_NEON_FLAG)) { celt_assert(arch == OPUS_ARCH_ARM_MEDIA); return arch; } arch++; celt_assert(arch == OPUS_ARCH_ARM_NEON); return arch; } #endif jamulus-3.9.1+dfsg/libs/opus/celt/arm/celt_pitch_xcorr_arm.s0000644000175000017500000004722514340334543023171 0ustar vimervimer; Copyright (c) 2007-2008 CSIRO ; Copyright (c) 2007-2009 Xiph.Org Foundation ; Copyright (c) 2013 Parrot ; Written by Aurélien Zanelli ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions ; are met: ; ; - Redistributions of source code must retain the above copyright ; notice, this list of conditions and the following disclaimer. ; ; - Redistributions in binary form must reproduce the above copyright ; notice, this list of conditions and the following disclaimer in the ; documentation and/or other materials provided with the distribution. ; ; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ; ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER ; OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, ; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, ; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. AREA |.text|, CODE, READONLY GET celt/arm/armopts.s IF OPUS_ARM_MAY_HAVE_EDSP EXPORT celt_pitch_xcorr_edsp ENDIF IF OPUS_ARM_MAY_HAVE_NEON EXPORT celt_pitch_xcorr_neon ENDIF IF OPUS_ARM_MAY_HAVE_NEON ; Compute sum[k]=sum(x[j]*y[j+k],j=0...len-1), k=0...3 xcorr_kernel_neon PROC xcorr_kernel_neon_start ; input: ; r3 = int len ; r4 = opus_val16 *x ; r5 = opus_val16 *y ; q0 = opus_val32 sum[4] ; output: ; q0 = opus_val32 sum[4] ; preserved: r0-r3, r6-r11, d2, q4-q7, q9-q15 ; internal usage: ; r12 = int j ; d3 = y_3|y_2|y_1|y_0 ; q2 = y_B|y_A|y_9|y_8|y_7|y_6|y_5|y_4 ; q3 = x_7|x_6|x_5|x_4|x_3|x_2|x_1|x_0 ; q8 = scratch ; ; Load y[0...3] ; This requires len>0 to always be valid (which we assert in the C code). VLD1.16 {d5}, [r5]! SUBS r12, r3, #8 BLE xcorr_kernel_neon_process4 ; Process 8 samples at a time. ; This loop loads one y value more than we actually need. Therefore we have to ; stop as soon as there are 8 or fewer samples left (instead of 7), to avoid ; reading past the end of the array. xcorr_kernel_neon_process8 ; This loop has 19 total instructions (10 cycles to issue, minimum), with ; - 2 cycles of ARM insrtuctions, ; - 10 cycles of load/store/byte permute instructions, and ; - 9 cycles of data processing instructions. ; On a Cortex A8, we dual-issue the maximum amount (9 cycles) between the ; latter two categories, meaning the whole loop should run in 10 cycles per ; iteration, barring cache misses. ; ; Load x[0...7] VLD1.16 {d6, d7}, [r4]! ; Unlike VMOV, VAND is a data processing instruction (and doesn't get ; assembled to VMOV, like VORR would), so it dual-issues with the prior VLD1. VAND d3, d5, d5 SUBS r12, r12, #8 ; Load y[4...11] VLD1.16 {d4, d5}, [r5]! VMLAL.S16 q0, d3, d6[0] VEXT.16 d16, d3, d4, #1 VMLAL.S16 q0, d4, d7[0] VEXT.16 d17, d4, d5, #1 VMLAL.S16 q0, d16, d6[1] VEXT.16 d16, d3, d4, #2 VMLAL.S16 q0, d17, d7[1] VEXT.16 d17, d4, d5, #2 VMLAL.S16 q0, d16, d6[2] VEXT.16 d16, d3, d4, #3 VMLAL.S16 q0, d17, d7[2] VEXT.16 d17, d4, d5, #3 VMLAL.S16 q0, d16, d6[3] VMLAL.S16 q0, d17, d7[3] BGT xcorr_kernel_neon_process8 ; Process 4 samples here if we have > 4 left (still reading one extra y value). xcorr_kernel_neon_process4 ADDS r12, r12, #4 BLE xcorr_kernel_neon_process2 ; Load x[0...3] VLD1.16 d6, [r4]! ; Use VAND since it's a data processing instruction again. VAND d4, d5, d5 SUB r12, r12, #4 ; Load y[4...7] VLD1.16 d5, [r5]! VMLAL.S16 q0, d4, d6[0] VEXT.16 d16, d4, d5, #1 VMLAL.S16 q0, d16, d6[1] VEXT.16 d16, d4, d5, #2 VMLAL.S16 q0, d16, d6[2] VEXT.16 d16, d4, d5, #3 VMLAL.S16 q0, d16, d6[3] ; Process 2 samples here if we have > 2 left (still reading one extra y value). xcorr_kernel_neon_process2 ADDS r12, r12, #2 BLE xcorr_kernel_neon_process1 ; Load x[0...1] VLD2.16 {d6[],d7[]}, [r4]! ; Use VAND since it's a data processing instruction again. VAND d4, d5, d5 SUB r12, r12, #2 ; Load y[4...5] VLD1.32 {d5[]}, [r5]! VMLAL.S16 q0, d4, d6 VEXT.16 d16, d4, d5, #1 ; Replace bottom copy of {y5,y4} in d5 with {y3,y2} from d4, using VSRI ; instead of VEXT, since it's a data-processing instruction. VSRI.64 d5, d4, #32 VMLAL.S16 q0, d16, d7 ; Process 1 sample using the extra y value we loaded above. xcorr_kernel_neon_process1 ; Load next *x VLD1.16 {d6[]}, [r4]! ADDS r12, r12, #1 ; y[0...3] are left in d5 from prior iteration(s) (if any) VMLAL.S16 q0, d5, d6 MOVLE pc, lr ; Now process 1 last sample, not reading ahead. ; Load last *y VLD1.16 {d4[]}, [r5]! VSRI.64 d4, d5, #16 ; Load last *x VLD1.16 {d6[]}, [r4]! VMLAL.S16 q0, d4, d6 MOV pc, lr ENDP ; opus_val32 celt_pitch_xcorr_neon(opus_val16 *_x, opus_val16 *_y, ; opus_val32 *xcorr, int len, int max_pitch, int arch) celt_pitch_xcorr_neon PROC ; input: ; r0 = opus_val16 *_x ; r1 = opus_val16 *_y ; r2 = opus_val32 *xcorr ; r3 = int len ; output: ; r0 = int maxcorr ; internal usage: ; r4 = opus_val16 *x (for xcorr_kernel_neon()) ; r5 = opus_val16 *y (for xcorr_kernel_neon()) ; r6 = int max_pitch ; r12 = int j ; q15 = int maxcorr[4] (q15 is not used by xcorr_kernel_neon()) ; ignored: ; int arch STMFD sp!, {r4-r6, lr} LDR r6, [sp, #16] VMOV.S32 q15, #1 ; if (max_pitch < 4) goto celt_pitch_xcorr_neon_process4_done SUBS r6, r6, #4 BLT celt_pitch_xcorr_neon_process4_done celt_pitch_xcorr_neon_process4 ; xcorr_kernel_neon parameters: ; r3 = len, r4 = _x, r5 = _y, q0 = {0, 0, 0, 0} MOV r4, r0 MOV r5, r1 VEOR q0, q0, q0 ; xcorr_kernel_neon only modifies r4, r5, r12, and q0...q3. ; So we don't save/restore any other registers. BL xcorr_kernel_neon_start SUBS r6, r6, #4 VST1.32 {q0}, [r2]! ; _y += 4 ADD r1, r1, #8 VMAX.S32 q15, q15, q0 ; if (max_pitch < 4) goto celt_pitch_xcorr_neon_process4_done BGE celt_pitch_xcorr_neon_process4 ; We have less than 4 sums left to compute. celt_pitch_xcorr_neon_process4_done ADDS r6, r6, #4 ; Reduce maxcorr to a single value VMAX.S32 d30, d30, d31 VPMAX.S32 d30, d30, d30 ; if (max_pitch <= 0) goto celt_pitch_xcorr_neon_done BLE celt_pitch_xcorr_neon_done ; Now compute each remaining sum one at a time. celt_pitch_xcorr_neon_process_remaining MOV r4, r0 MOV r5, r1 VMOV.I32 q0, #0 SUBS r12, r3, #8 BLT celt_pitch_xcorr_neon_process_remaining4 ; Sum terms 8 at a time. celt_pitch_xcorr_neon_process_remaining_loop8 ; Load x[0...7] VLD1.16 {q1}, [r4]! ; Load y[0...7] VLD1.16 {q2}, [r5]! SUBS r12, r12, #8 VMLAL.S16 q0, d4, d2 VMLAL.S16 q0, d5, d3 BGE celt_pitch_xcorr_neon_process_remaining_loop8 ; Sum terms 4 at a time. celt_pitch_xcorr_neon_process_remaining4 ADDS r12, r12, #4 BLT celt_pitch_xcorr_neon_process_remaining4_done ; Load x[0...3] VLD1.16 {d2}, [r4]! ; Load y[0...3] VLD1.16 {d3}, [r5]! SUB r12, r12, #4 VMLAL.S16 q0, d3, d2 celt_pitch_xcorr_neon_process_remaining4_done ; Reduce the sum to a single value. VADD.S32 d0, d0, d1 VPADDL.S32 d0, d0 ADDS r12, r12, #4 BLE celt_pitch_xcorr_neon_process_remaining_loop_done ; Sum terms 1 at a time. celt_pitch_xcorr_neon_process_remaining_loop1 VLD1.16 {d2[]}, [r4]! VLD1.16 {d3[]}, [r5]! SUBS r12, r12, #1 VMLAL.S16 q0, d2, d3 BGT celt_pitch_xcorr_neon_process_remaining_loop1 celt_pitch_xcorr_neon_process_remaining_loop_done VST1.32 {d0[0]}, [r2]! VMAX.S32 d30, d30, d0 SUBS r6, r6, #1 ; _y++ ADD r1, r1, #2 ; if (--max_pitch > 0) goto celt_pitch_xcorr_neon_process_remaining BGT celt_pitch_xcorr_neon_process_remaining celt_pitch_xcorr_neon_done VMOV.32 r0, d30[0] LDMFD sp!, {r4-r6, pc} ENDP ENDIF IF OPUS_ARM_MAY_HAVE_EDSP ; This will get used on ARMv7 devices without NEON, so it has been optimized ; to take advantage of dual-issuing where possible. xcorr_kernel_edsp PROC xcorr_kernel_edsp_start ; input: ; r3 = int len ; r4 = opus_val16 *_x (must be 32-bit aligned) ; r5 = opus_val16 *_y (must be 32-bit aligned) ; r6...r9 = opus_val32 sum[4] ; output: ; r6...r9 = opus_val32 sum[4] ; preserved: r0-r5 ; internal usage ; r2 = int j ; r12,r14 = opus_val16 x[4] ; r10,r11 = opus_val16 y[4] STMFD sp!, {r2,r4,r5,lr} LDR r10, [r5], #4 ; Load y[0...1] SUBS r2, r3, #4 ; j = len-4 LDR r11, [r5], #4 ; Load y[2...3] BLE xcorr_kernel_edsp_process4_done LDR r12, [r4], #4 ; Load x[0...1] ; Stall xcorr_kernel_edsp_process4 ; The multiplies must issue from pipeline 0, and can't dual-issue with each ; other. Every other instruction here dual-issues with a multiply, and is ; thus "free". There should be no stalls in the body of the loop. SMLABB r6, r12, r10, r6 ; sum[0] = MAC16_16(sum[0],x_0,y_0) LDR r14, [r4], #4 ; Load x[2...3] SMLABT r7, r12, r10, r7 ; sum[1] = MAC16_16(sum[1],x_0,y_1) SUBS r2, r2, #4 ; j-=4 SMLABB r8, r12, r11, r8 ; sum[2] = MAC16_16(sum[2],x_0,y_2) SMLABT r9, r12, r11, r9 ; sum[3] = MAC16_16(sum[3],x_0,y_3) SMLATT r6, r12, r10, r6 ; sum[0] = MAC16_16(sum[0],x_1,y_1) LDR r10, [r5], #4 ; Load y[4...5] SMLATB r7, r12, r11, r7 ; sum[1] = MAC16_16(sum[1],x_1,y_2) SMLATT r8, r12, r11, r8 ; sum[2] = MAC16_16(sum[2],x_1,y_3) SMLATB r9, r12, r10, r9 ; sum[3] = MAC16_16(sum[3],x_1,y_4) LDRGT r12, [r4], #4 ; Load x[0...1] SMLABB r6, r14, r11, r6 ; sum[0] = MAC16_16(sum[0],x_2,y_2) SMLABT r7, r14, r11, r7 ; sum[1] = MAC16_16(sum[1],x_2,y_3) SMLABB r8, r14, r10, r8 ; sum[2] = MAC16_16(sum[2],x_2,y_4) SMLABT r9, r14, r10, r9 ; sum[3] = MAC16_16(sum[3],x_2,y_5) SMLATT r6, r14, r11, r6 ; sum[0] = MAC16_16(sum[0],x_3,y_3) LDR r11, [r5], #4 ; Load y[6...7] SMLATB r7, r14, r10, r7 ; sum[1] = MAC16_16(sum[1],x_3,y_4) SMLATT r8, r14, r10, r8 ; sum[2] = MAC16_16(sum[2],x_3,y_5) SMLATB r9, r14, r11, r9 ; sum[3] = MAC16_16(sum[3],x_3,y_6) BGT xcorr_kernel_edsp_process4 xcorr_kernel_edsp_process4_done ADDS r2, r2, #4 BLE xcorr_kernel_edsp_done LDRH r12, [r4], #2 ; r12 = *x++ SUBS r2, r2, #1 ; j-- ; Stall SMLABB r6, r12, r10, r6 ; sum[0] = MAC16_16(sum[0],x,y_0) LDRHGT r14, [r4], #2 ; r14 = *x++ SMLABT r7, r12, r10, r7 ; sum[1] = MAC16_16(sum[1],x,y_1) SMLABB r8, r12, r11, r8 ; sum[2] = MAC16_16(sum[2],x,y_2) SMLABT r9, r12, r11, r9 ; sum[3] = MAC16_16(sum[3],x,y_3) BLE xcorr_kernel_edsp_done SMLABT r6, r14, r10, r6 ; sum[0] = MAC16_16(sum[0],x,y_1) SUBS r2, r2, #1 ; j-- SMLABB r7, r14, r11, r7 ; sum[1] = MAC16_16(sum[1],x,y_2) LDRH r10, [r5], #2 ; r10 = y_4 = *y++ SMLABT r8, r14, r11, r8 ; sum[2] = MAC16_16(sum[2],x,y_3) LDRHGT r12, [r4], #2 ; r12 = *x++ SMLABB r9, r14, r10, r9 ; sum[3] = MAC16_16(sum[3],x,y_4) BLE xcorr_kernel_edsp_done SMLABB r6, r12, r11, r6 ; sum[0] = MAC16_16(sum[0],tmp,y_2) CMP r2, #1 ; j-- SMLABT r7, r12, r11, r7 ; sum[1] = MAC16_16(sum[1],tmp,y_3) LDRH r2, [r5], #2 ; r2 = y_5 = *y++ SMLABB r8, r12, r10, r8 ; sum[2] = MAC16_16(sum[2],tmp,y_4) LDRHGT r14, [r4] ; r14 = *x SMLABB r9, r12, r2, r9 ; sum[3] = MAC16_16(sum[3],tmp,y_5) BLE xcorr_kernel_edsp_done SMLABT r6, r14, r11, r6 ; sum[0] = MAC16_16(sum[0],tmp,y_3) LDRH r11, [r5] ; r11 = y_6 = *y SMLABB r7, r14, r10, r7 ; sum[1] = MAC16_16(sum[1],tmp,y_4) SMLABB r8, r14, r2, r8 ; sum[2] = MAC16_16(sum[2],tmp,y_5) SMLABB r9, r14, r11, r9 ; sum[3] = MAC16_16(sum[3],tmp,y_6) xcorr_kernel_edsp_done LDMFD sp!, {r2,r4,r5,pc} ENDP celt_pitch_xcorr_edsp PROC ; input: ; r0 = opus_val16 *_x (must be 32-bit aligned) ; r1 = opus_val16 *_y (only needs to be 16-bit aligned) ; r2 = opus_val32 *xcorr ; r3 = int len ; output: ; r0 = maxcorr ; internal usage ; r4 = opus_val16 *x ; r5 = opus_val16 *y ; r6 = opus_val32 sum0 ; r7 = opus_val32 sum1 ; r8 = opus_val32 sum2 ; r9 = opus_val32 sum3 ; r1 = int max_pitch ; r12 = int j ; ignored: ; int arch STMFD sp!, {r4-r11, lr} MOV r5, r1 LDR r1, [sp, #36] MOV r4, r0 TST r5, #3 ; maxcorr = 1 MOV r0, #1 BEQ celt_pitch_xcorr_edsp_process1u_done ; Compute one sum at the start to make y 32-bit aligned. SUBS r12, r3, #4 ; r14 = sum = 0 MOV r14, #0 LDRH r8, [r5], #2 BLE celt_pitch_xcorr_edsp_process1u_loop4_done LDR r6, [r4], #4 MOV r8, r8, LSL #16 celt_pitch_xcorr_edsp_process1u_loop4 LDR r9, [r5], #4 SMLABT r14, r6, r8, r14 ; sum = MAC16_16(sum, x_0, y_0) LDR r7, [r4], #4 SMLATB r14, r6, r9, r14 ; sum = MAC16_16(sum, x_1, y_1) LDR r8, [r5], #4 SMLABT r14, r7, r9, r14 ; sum = MAC16_16(sum, x_2, y_2) SUBS r12, r12, #4 ; j-=4 SMLATB r14, r7, r8, r14 ; sum = MAC16_16(sum, x_3, y_3) LDRGT r6, [r4], #4 BGT celt_pitch_xcorr_edsp_process1u_loop4 MOV r8, r8, LSR #16 celt_pitch_xcorr_edsp_process1u_loop4_done ADDS r12, r12, #4 celt_pitch_xcorr_edsp_process1u_loop1 LDRHGE r6, [r4], #2 ; Stall SMLABBGE r14, r6, r8, r14 ; sum = MAC16_16(sum, *x, *y) SUBSGE r12, r12, #1 LDRHGT r8, [r5], #2 BGT celt_pitch_xcorr_edsp_process1u_loop1 ; Restore _x SUB r4, r4, r3, LSL #1 ; Restore and advance _y SUB r5, r5, r3, LSL #1 ; maxcorr = max(maxcorr, sum) CMP r0, r14 ADD r5, r5, #2 MOVLT r0, r14 SUBS r1, r1, #1 ; xcorr[i] = sum STR r14, [r2], #4 BLE celt_pitch_xcorr_edsp_done celt_pitch_xcorr_edsp_process1u_done ; if (max_pitch < 4) goto celt_pitch_xcorr_edsp_process2 SUBS r1, r1, #4 BLT celt_pitch_xcorr_edsp_process2 celt_pitch_xcorr_edsp_process4 ; xcorr_kernel_edsp parameters: ; r3 = len, r4 = _x, r5 = _y, r6...r9 = sum[4] = {0, 0, 0, 0} MOV r6, #0 MOV r7, #0 MOV r8, #0 MOV r9, #0 BL xcorr_kernel_edsp_start ; xcorr_kernel_edsp(_x, _y+i, xcorr+i, len) ; maxcorr = max(maxcorr, sum0, sum1, sum2, sum3) CMP r0, r6 ; _y+=4 ADD r5, r5, #8 MOVLT r0, r6 CMP r0, r7 MOVLT r0, r7 CMP r0, r8 MOVLT r0, r8 CMP r0, r9 MOVLT r0, r9 STMIA r2!, {r6-r9} SUBS r1, r1, #4 BGE celt_pitch_xcorr_edsp_process4 celt_pitch_xcorr_edsp_process2 ADDS r1, r1, #2 BLT celt_pitch_xcorr_edsp_process1a SUBS r12, r3, #4 ; {r10, r11} = {sum0, sum1} = {0, 0} MOV r10, #0 MOV r11, #0 LDR r8, [r5], #4 BLE celt_pitch_xcorr_edsp_process2_loop_done LDR r6, [r4], #4 LDR r9, [r5], #4 celt_pitch_xcorr_edsp_process2_loop4 SMLABB r10, r6, r8, r10 ; sum0 = MAC16_16(sum0, x_0, y_0) LDR r7, [r4], #4 SMLABT r11, r6, r8, r11 ; sum1 = MAC16_16(sum1, x_0, y_1) SUBS r12, r12, #4 ; j-=4 SMLATT r10, r6, r8, r10 ; sum0 = MAC16_16(sum0, x_1, y_1) LDR r8, [r5], #4 SMLATB r11, r6, r9, r11 ; sum1 = MAC16_16(sum1, x_1, y_2) LDRGT r6, [r4], #4 SMLABB r10, r7, r9, r10 ; sum0 = MAC16_16(sum0, x_2, y_2) SMLABT r11, r7, r9, r11 ; sum1 = MAC16_16(sum1, x_2, y_3) SMLATT r10, r7, r9, r10 ; sum0 = MAC16_16(sum0, x_3, y_3) LDRGT r9, [r5], #4 SMLATB r11, r7, r8, r11 ; sum1 = MAC16_16(sum1, x_3, y_4) BGT celt_pitch_xcorr_edsp_process2_loop4 celt_pitch_xcorr_edsp_process2_loop_done ADDS r12, r12, #2 BLE celt_pitch_xcorr_edsp_process2_1 LDR r6, [r4], #4 ; Stall SMLABB r10, r6, r8, r10 ; sum0 = MAC16_16(sum0, x_0, y_0) LDR r9, [r5], #4 SMLABT r11, r6, r8, r11 ; sum1 = MAC16_16(sum1, x_0, y_1) SUB r12, r12, #2 SMLATT r10, r6, r8, r10 ; sum0 = MAC16_16(sum0, x_1, y_1) MOV r8, r9 SMLATB r11, r6, r9, r11 ; sum1 = MAC16_16(sum1, x_1, y_2) celt_pitch_xcorr_edsp_process2_1 LDRH r6, [r4], #2 ADDS r12, r12, #1 ; Stall SMLABB r10, r6, r8, r10 ; sum0 = MAC16_16(sum0, x_0, y_0) LDRHGT r7, [r4], #2 SMLABT r11, r6, r8, r11 ; sum1 = MAC16_16(sum1, x_0, y_1) BLE celt_pitch_xcorr_edsp_process2_done LDRH r9, [r5], #2 SMLABT r10, r7, r8, r10 ; sum0 = MAC16_16(sum0, x_0, y_1) SMLABB r11, r7, r9, r11 ; sum1 = MAC16_16(sum1, x_0, y_2) celt_pitch_xcorr_edsp_process2_done ; Restore _x SUB r4, r4, r3, LSL #1 ; Restore and advance _y SUB r5, r5, r3, LSL #1 ; maxcorr = max(maxcorr, sum0) CMP r0, r10 ADD r5, r5, #2 MOVLT r0, r10 SUB r1, r1, #2 ; maxcorr = max(maxcorr, sum1) CMP r0, r11 ; xcorr[i] = sum STR r10, [r2], #4 MOVLT r0, r11 STR r11, [r2], #4 celt_pitch_xcorr_edsp_process1a ADDS r1, r1, #1 BLT celt_pitch_xcorr_edsp_done SUBS r12, r3, #4 ; r14 = sum = 0 MOV r14, #0 BLT celt_pitch_xcorr_edsp_process1a_loop_done LDR r6, [r4], #4 LDR r8, [r5], #4 LDR r7, [r4], #4 LDR r9, [r5], #4 celt_pitch_xcorr_edsp_process1a_loop4 SMLABB r14, r6, r8, r14 ; sum = MAC16_16(sum, x_0, y_0) SUBS r12, r12, #4 ; j-=4 SMLATT r14, r6, r8, r14 ; sum = MAC16_16(sum, x_1, y_1) LDRGE r6, [r4], #4 SMLABB r14, r7, r9, r14 ; sum = MAC16_16(sum, x_2, y_2) LDRGE r8, [r5], #4 SMLATT r14, r7, r9, r14 ; sum = MAC16_16(sum, x_3, y_3) LDRGE r7, [r4], #4 LDRGE r9, [r5], #4 BGE celt_pitch_xcorr_edsp_process1a_loop4 celt_pitch_xcorr_edsp_process1a_loop_done ADDS r12, r12, #2 LDRGE r6, [r4], #4 LDRGE r8, [r5], #4 ; Stall SMLABBGE r14, r6, r8, r14 ; sum = MAC16_16(sum, x_0, y_0) SUBGE r12, r12, #2 SMLATTGE r14, r6, r8, r14 ; sum = MAC16_16(sum, x_1, y_1) ADDS r12, r12, #1 LDRHGE r6, [r4], #2 LDRHGE r8, [r5], #2 ; Stall SMLABBGE r14, r6, r8, r14 ; sum = MAC16_16(sum, *x, *y) ; maxcorr = max(maxcorr, sum) CMP r0, r14 ; xcorr[i] = sum STR r14, [r2], #4 MOVLT r0, r14 celt_pitch_xcorr_edsp_done LDMFD sp!, {r4-r11, pc} ENDP ENDIF END jamulus-3.9.1+dfsg/libs/opus/celt/arm/celt_pitch_xcorr_arm-gnu.S0000644000175000017500000005026114340334543023712 0ustar vimervimer .syntax unified @ Copyright (c) 2007-2008 CSIRO @ Copyright (c) 2007-2009 Xiph.Org Foundation @ Copyright (c) 2013 Parrot @ Written by Aurélien Zanelli @ @ Redistribution and use in source and binary forms, with or without @ modification, are permitted provided that the following conditions @ are met: @ @ - Redistributions of source code must retain the above copyright @ notice, this list of conditions and the following disclaimer. @ @ - Redistributions in binary form must reproduce the above copyright @ notice, this list of conditions and the following disclaimer in the @ documentation and/or other materials provided with the distribution. @ @ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS @ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT @ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER @ OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, @ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, @ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR @ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF @ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING @ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS @ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .text; .p2align 2; .arch armv7-a .fpu neon .object_arch armv4t .include "celt/arm/armopts-gnu.S" .if OPUS_ARM_MAY_HAVE_EDSP .global celt_pitch_xcorr_edsp .endif .if OPUS_ARM_MAY_HAVE_NEON .global celt_pitch_xcorr_neon .endif .if OPUS_ARM_MAY_HAVE_NEON @ Compute sum[k]=sum(x[j]*y[j+k],j=0...len-1), k=0...3 .type xcorr_kernel_neon, %function; xcorr_kernel_neon: @ PROC xcorr_kernel_neon_start: @ input: @ r3 = int len @ r4 = opus_val16 *x @ r5 = opus_val16 *y @ q0 = opus_val32 sum[4] @ output: @ q0 = opus_val32 sum[4] @ preserved: r0-r3, r6-r11, d2, q4-q7, q9-q15 @ internal usage: @ r12 = int j @ d3 = y_3|y_2|y_1|y_0 @ q2 = y_B|y_A|y_9|y_8|y_7|y_6|y_5|y_4 @ q3 = x_7|x_6|x_5|x_4|x_3|x_2|x_1|x_0 @ q8 = scratch @ @ Load y[0...3] @ This requires len>0 to always be valid (which we assert in the C code). VLD1.16 {d5}, [r5]! SUBS r12, r3, #8 BLE xcorr_kernel_neon_process4 @ Process 8 samples at a time. @ This loop loads one y value more than we actually need. Therefore we have to @ stop as soon as there are 8 or fewer samples left (instead of 7), to avoid @ reading past the end of the array. xcorr_kernel_neon_process8: @ This loop has 19 total instructions (10 cycles to issue, minimum), with @ - 2 cycles of ARM insrtuctions, @ - 10 cycles of load/store/byte permute instructions, and @ - 9 cycles of data processing instructions. @ On a Cortex A8, we dual-issue the maximum amount (9 cycles) between the @ latter two categories, meaning the whole loop should run in 10 cycles per @ iteration, barring cache misses. @ @ Load x[0...7] VLD1.16 {d6, d7}, [r4]! @ Unlike VMOV, VAND is a data processing instruction (and doesn't get @ assembled to VMOV, like VORR would), so it dual-issues with the prior VLD1. VAND d3, d5, d5 SUBS r12, r12, #8 @ Load y[4...11] VLD1.16 {d4, d5}, [r5]! VMLAL.S16 q0, d3, d6[0] VEXT.16 d16, d3, d4, #1 VMLAL.S16 q0, d4, d7[0] VEXT.16 d17, d4, d5, #1 VMLAL.S16 q0, d16, d6[1] VEXT.16 d16, d3, d4, #2 VMLAL.S16 q0, d17, d7[1] VEXT.16 d17, d4, d5, #2 VMLAL.S16 q0, d16, d6[2] VEXT.16 d16, d3, d4, #3 VMLAL.S16 q0, d17, d7[2] VEXT.16 d17, d4, d5, #3 VMLAL.S16 q0, d16, d6[3] VMLAL.S16 q0, d17, d7[3] BGT xcorr_kernel_neon_process8 @ Process 4 samples here if we have > 4 left (still reading one extra y value). xcorr_kernel_neon_process4: ADDS r12, r12, #4 BLE xcorr_kernel_neon_process2 @ Load x[0...3] VLD1.16 d6, [r4]! @ Use VAND since it's a data processing instruction again. VAND d4, d5, d5 SUB r12, r12, #4 @ Load y[4...7] VLD1.16 d5, [r5]! VMLAL.S16 q0, d4, d6[0] VEXT.16 d16, d4, d5, #1 VMLAL.S16 q0, d16, d6[1] VEXT.16 d16, d4, d5, #2 VMLAL.S16 q0, d16, d6[2] VEXT.16 d16, d4, d5, #3 VMLAL.S16 q0, d16, d6[3] @ Process 2 samples here if we have > 2 left (still reading one extra y value). xcorr_kernel_neon_process2: ADDS r12, r12, #2 BLE xcorr_kernel_neon_process1 @ Load x[0...1] VLD2.16 {d6[],d7[]}, [r4]! @ Use VAND since it's a data processing instruction again. VAND d4, d5, d5 SUB r12, r12, #2 @ Load y[4...5] VLD1.32 {d5[]}, [r5]! VMLAL.S16 q0, d4, d6 VEXT.16 d16, d4, d5, #1 @ Replace bottom copy of {y5,y4} in d5 with {y3,y2} from d4, using VSRI @ instead of VEXT, since it's a data-processing instruction. VSRI.64 d5, d4, #32 VMLAL.S16 q0, d16, d7 @ Process 1 sample using the extra y value we loaded above. xcorr_kernel_neon_process1: @ Load next *x VLD1.16 {d6[]}, [r4]! ADDS r12, r12, #1 @ y[0...3] are left in d5 from prior iteration(s) (if any) VMLAL.S16 q0, d5, d6 MOVLE pc, lr @ Now process 1 last sample, not reading ahead. @ Load last *y VLD1.16 {d4[]}, [r5]! VSRI.64 d4, d5, #16 @ Load last *x VLD1.16 {d6[]}, [r4]! VMLAL.S16 q0, d4, d6 MOV pc, lr .size xcorr_kernel_neon, .-xcorr_kernel_neon @ ENDP @ opus_val32 celt_pitch_xcorr_neon(opus_val16 *_x, opus_val16 *_y, @ opus_val32 *xcorr, int len, int max_pitch, int arch) .type celt_pitch_xcorr_neon, %function; celt_pitch_xcorr_neon: @ PROC @ input: @ r0 = opus_val16 *_x @ r1 = opus_val16 *_y @ r2 = opus_val32 *xcorr @ r3 = int len @ output: @ r0 = int maxcorr @ internal usage: @ r4 = opus_val16 *x (for xcorr_kernel_neon()) @ r5 = opus_val16 *y (for xcorr_kernel_neon()) @ r6 = int max_pitch @ r12 = int j @ q15 = int maxcorr[4] (q15 is not used by xcorr_kernel_neon()) @ ignored: @ int arch STMFD sp!, {r4-r6, lr} LDR r6, [sp, #16] VMOV.S32 q15, #1 @ if (max_pitch < 4) goto celt_pitch_xcorr_neon_process4_done SUBS r6, r6, #4 BLT celt_pitch_xcorr_neon_process4_done celt_pitch_xcorr_neon_process4: @ xcorr_kernel_neon parameters: @ r3 = len, r4 = _x, r5 = _y, q0 = {0, 0, 0, 0} MOV r4, r0 MOV r5, r1 VEOR q0, q0, q0 @ xcorr_kernel_neon only modifies r4, r5, r12, and q0...q3. @ So we don't save/restore any other registers. BL xcorr_kernel_neon_start SUBS r6, r6, #4 VST1.32 {q0}, [r2]! @ _y += 4 ADD r1, r1, #8 VMAX.S32 q15, q15, q0 @ if (max_pitch < 4) goto celt_pitch_xcorr_neon_process4_done BGE celt_pitch_xcorr_neon_process4 @ We have less than 4 sums left to compute. celt_pitch_xcorr_neon_process4_done: ADDS r6, r6, #4 @ Reduce maxcorr to a single value VMAX.S32 d30, d30, d31 VPMAX.S32 d30, d30, d30 @ if (max_pitch <= 0) goto celt_pitch_xcorr_neon_done BLE celt_pitch_xcorr_neon_done @ Now compute each remaining sum one at a time. celt_pitch_xcorr_neon_process_remaining: MOV r4, r0 MOV r5, r1 VMOV.I32 q0, #0 SUBS r12, r3, #8 BLT celt_pitch_xcorr_neon_process_remaining4 @ Sum terms 8 at a time. celt_pitch_xcorr_neon_process_remaining_loop8: @ Load x[0...7] VLD1.16 {q1}, [r4]! @ Load y[0...7] VLD1.16 {q2}, [r5]! SUBS r12, r12, #8 VMLAL.S16 q0, d4, d2 VMLAL.S16 q0, d5, d3 BGE celt_pitch_xcorr_neon_process_remaining_loop8 @ Sum terms 4 at a time. celt_pitch_xcorr_neon_process_remaining4: ADDS r12, r12, #4 BLT celt_pitch_xcorr_neon_process_remaining4_done @ Load x[0...3] VLD1.16 {d2}, [r4]! @ Load y[0...3] VLD1.16 {d3}, [r5]! SUB r12, r12, #4 VMLAL.S16 q0, d3, d2 celt_pitch_xcorr_neon_process_remaining4_done: @ Reduce the sum to a single value. VADD.S32 d0, d0, d1 VPADDL.S32 d0, d0 ADDS r12, r12, #4 BLE celt_pitch_xcorr_neon_process_remaining_loop_done @ Sum terms 1 at a time. celt_pitch_xcorr_neon_process_remaining_loop1: VLD1.16 {d2[]}, [r4]! VLD1.16 {d3[]}, [r5]! SUBS r12, r12, #1 VMLAL.S16 q0, d2, d3 BGT celt_pitch_xcorr_neon_process_remaining_loop1 celt_pitch_xcorr_neon_process_remaining_loop_done: VST1.32 {d0[0]}, [r2]! VMAX.S32 d30, d30, d0 SUBS r6, r6, #1 @ _y++ ADD r1, r1, #2 @ if (--max_pitch > 0) goto celt_pitch_xcorr_neon_process_remaining BGT celt_pitch_xcorr_neon_process_remaining celt_pitch_xcorr_neon_done: VMOV.32 r0, d30[0] LDMFD sp!, {r4-r6, pc} .size celt_pitch_xcorr_neon, .-celt_pitch_xcorr_neon @ ENDP .endif .if OPUS_ARM_MAY_HAVE_EDSP @ This will get used on ARMv7 devices without NEON, so it has been optimized @ to take advantage of dual-issuing where possible. .type xcorr_kernel_edsp, %function; xcorr_kernel_edsp: @ PROC xcorr_kernel_edsp_start: @ input: @ r3 = int len @ r4 = opus_val16 *_x (must be 32-bit aligned) @ r5 = opus_val16 *_y (must be 32-bit aligned) @ r6...r9 = opus_val32 sum[4] @ output: @ r6...r9 = opus_val32 sum[4] @ preserved: r0-r5 @ internal usage @ r2 = int j @ r12,r14 = opus_val16 x[4] @ r10,r11 = opus_val16 y[4] STMFD sp!, {r2,r4,r5,lr} LDR r10, [r5], #4 @ Load y[0...1] SUBS r2, r3, #4 @ j = len-4 LDR r11, [r5], #4 @ Load y[2...3] BLE xcorr_kernel_edsp_process4_done LDR r12, [r4], #4 @ Load x[0...1] @ Stall xcorr_kernel_edsp_process4: @ The multiplies must issue from pipeline 0, and can't dual-issue with each @ other. Every other instruction here dual-issues with a multiply, and is @ thus "free". There should be no stalls in the body of the loop. SMLABB r6, r12, r10, r6 @ sum[0] = MAC16_16(sum[0],x_0,y_0) LDR r14, [r4], #4 @ Load x[2...3] SMLABT r7, r12, r10, r7 @ sum[1] = MAC16_16(sum[1],x_0,y_1) SUBS r2, r2, #4 @ j-=4 SMLABB r8, r12, r11, r8 @ sum[2] = MAC16_16(sum[2],x_0,y_2) SMLABT r9, r12, r11, r9 @ sum[3] = MAC16_16(sum[3],x_0,y_3) SMLATT r6, r12, r10, r6 @ sum[0] = MAC16_16(sum[0],x_1,y_1) LDR r10, [r5], #4 @ Load y[4...5] SMLATB r7, r12, r11, r7 @ sum[1] = MAC16_16(sum[1],x_1,y_2) SMLATT r8, r12, r11, r8 @ sum[2] = MAC16_16(sum[2],x_1,y_3) SMLATB r9, r12, r10, r9 @ sum[3] = MAC16_16(sum[3],x_1,y_4) LDRGT r12, [r4], #4 @ Load x[0...1] SMLABB r6, r14, r11, r6 @ sum[0] = MAC16_16(sum[0],x_2,y_2) SMLABT r7, r14, r11, r7 @ sum[1] = MAC16_16(sum[1],x_2,y_3) SMLABB r8, r14, r10, r8 @ sum[2] = MAC16_16(sum[2],x_2,y_4) SMLABT r9, r14, r10, r9 @ sum[3] = MAC16_16(sum[3],x_2,y_5) SMLATT r6, r14, r11, r6 @ sum[0] = MAC16_16(sum[0],x_3,y_3) LDR r11, [r5], #4 @ Load y[6...7] SMLATB r7, r14, r10, r7 @ sum[1] = MAC16_16(sum[1],x_3,y_4) SMLATT r8, r14, r10, r8 @ sum[2] = MAC16_16(sum[2],x_3,y_5) SMLATB r9, r14, r11, r9 @ sum[3] = MAC16_16(sum[3],x_3,y_6) BGT xcorr_kernel_edsp_process4 xcorr_kernel_edsp_process4_done: ADDS r2, r2, #4 BLE xcorr_kernel_edsp_done LDRH r12, [r4], #2 @ r12 = *x++ SUBS r2, r2, #1 @ j-- @ Stall SMLABB r6, r12, r10, r6 @ sum[0] = MAC16_16(sum[0],x,y_0) LDRHGT r14, [r4], #2 @ r14 = *x++ SMLABT r7, r12, r10, r7 @ sum[1] = MAC16_16(sum[1],x,y_1) SMLABB r8, r12, r11, r8 @ sum[2] = MAC16_16(sum[2],x,y_2) SMLABT r9, r12, r11, r9 @ sum[3] = MAC16_16(sum[3],x,y_3) BLE xcorr_kernel_edsp_done SMLABT r6, r14, r10, r6 @ sum[0] = MAC16_16(sum[0],x,y_1) SUBS r2, r2, #1 @ j-- SMLABB r7, r14, r11, r7 @ sum[1] = MAC16_16(sum[1],x,y_2) LDRH r10, [r5], #2 @ r10 = y_4 = *y++ SMLABT r8, r14, r11, r8 @ sum[2] = MAC16_16(sum[2],x,y_3) LDRHGT r12, [r4], #2 @ r12 = *x++ SMLABB r9, r14, r10, r9 @ sum[3] = MAC16_16(sum[3],x,y_4) BLE xcorr_kernel_edsp_done SMLABB r6, r12, r11, r6 @ sum[0] = MAC16_16(sum[0],tmp,y_2) CMP r2, #1 @ j-- SMLABT r7, r12, r11, r7 @ sum[1] = MAC16_16(sum[1],tmp,y_3) LDRH r2, [r5], #2 @ r2 = y_5 = *y++ SMLABB r8, r12, r10, r8 @ sum[2] = MAC16_16(sum[2],tmp,y_4) LDRHGT r14, [r4] @ r14 = *x SMLABB r9, r12, r2, r9 @ sum[3] = MAC16_16(sum[3],tmp,y_5) BLE xcorr_kernel_edsp_done SMLABT r6, r14, r11, r6 @ sum[0] = MAC16_16(sum[0],tmp,y_3) LDRH r11, [r5] @ r11 = y_6 = *y SMLABB r7, r14, r10, r7 @ sum[1] = MAC16_16(sum[1],tmp,y_4) SMLABB r8, r14, r2, r8 @ sum[2] = MAC16_16(sum[2],tmp,y_5) SMLABB r9, r14, r11, r9 @ sum[3] = MAC16_16(sum[3],tmp,y_6) xcorr_kernel_edsp_done: LDMFD sp!, {r2,r4,r5,pc} .size xcorr_kernel_edsp, .-xcorr_kernel_edsp @ ENDP .type celt_pitch_xcorr_edsp, %function; celt_pitch_xcorr_edsp: @ PROC @ input: @ r0 = opus_val16 *_x (must be 32-bit aligned) @ r1 = opus_val16 *_y (only needs to be 16-bit aligned) @ r2 = opus_val32 *xcorr @ r3 = int len @ output: @ r0 = maxcorr @ internal usage @ r4 = opus_val16 *x @ r5 = opus_val16 *y @ r6 = opus_val32 sum0 @ r7 = opus_val32 sum1 @ r8 = opus_val32 sum2 @ r9 = opus_val32 sum3 @ r1 = int max_pitch @ r12 = int j @ ignored: @ int arch STMFD sp!, {r4-r11, lr} MOV r5, r1 LDR r1, [sp, #36] MOV r4, r0 TST r5, #3 @ maxcorr = 1 MOV r0, #1 BEQ celt_pitch_xcorr_edsp_process1u_done @ Compute one sum at the start to make y 32-bit aligned. SUBS r12, r3, #4 @ r14 = sum = 0 MOV r14, #0 LDRH r8, [r5], #2 BLE celt_pitch_xcorr_edsp_process1u_loop4_done LDR r6, [r4], #4 MOV r8, r8, LSL #16 celt_pitch_xcorr_edsp_process1u_loop4: LDR r9, [r5], #4 SMLABT r14, r6, r8, r14 @ sum = MAC16_16(sum, x_0, y_0) LDR r7, [r4], #4 SMLATB r14, r6, r9, r14 @ sum = MAC16_16(sum, x_1, y_1) LDR r8, [r5], #4 SMLABT r14, r7, r9, r14 @ sum = MAC16_16(sum, x_2, y_2) SUBS r12, r12, #4 @ j-=4 SMLATB r14, r7, r8, r14 @ sum = MAC16_16(sum, x_3, y_3) LDRGT r6, [r4], #4 BGT celt_pitch_xcorr_edsp_process1u_loop4 MOV r8, r8, LSR #16 celt_pitch_xcorr_edsp_process1u_loop4_done: ADDS r12, r12, #4 celt_pitch_xcorr_edsp_process1u_loop1: LDRHGE r6, [r4], #2 @ Stall SMLABBGE r14, r6, r8, r14 @ sum = MAC16_16(sum, *x, *y) SUBSGE r12, r12, #1 LDRHGT r8, [r5], #2 BGT celt_pitch_xcorr_edsp_process1u_loop1 @ Restore _x SUB r4, r4, r3, LSL #1 @ Restore and advance _y SUB r5, r5, r3, LSL #1 @ maxcorr = max(maxcorr, sum) CMP r0, r14 ADD r5, r5, #2 MOVLT r0, r14 SUBS r1, r1, #1 @ xcorr[i] = sum STR r14, [r2], #4 BLE celt_pitch_xcorr_edsp_done celt_pitch_xcorr_edsp_process1u_done: @ if (max_pitch < 4) goto celt_pitch_xcorr_edsp_process2 SUBS r1, r1, #4 BLT celt_pitch_xcorr_edsp_process2 celt_pitch_xcorr_edsp_process4: @ xcorr_kernel_edsp parameters: @ r3 = len, r4 = _x, r5 = _y, r6...r9 = sum[4] = {0, 0, 0, 0} MOV r6, #0 MOV r7, #0 MOV r8, #0 MOV r9, #0 BL xcorr_kernel_edsp_start @ xcorr_kernel_edsp(_x, _y+i, xcorr+i, len) @ maxcorr = max(maxcorr, sum0, sum1, sum2, sum3) CMP r0, r6 @ _y+=4 ADD r5, r5, #8 MOVLT r0, r6 CMP r0, r7 MOVLT r0, r7 CMP r0, r8 MOVLT r0, r8 CMP r0, r9 MOVLT r0, r9 STMIA r2!, {r6-r9} SUBS r1, r1, #4 BGE celt_pitch_xcorr_edsp_process4 celt_pitch_xcorr_edsp_process2: ADDS r1, r1, #2 BLT celt_pitch_xcorr_edsp_process1a SUBS r12, r3, #4 @ {r10, r11} = {sum0, sum1} = {0, 0} MOV r10, #0 MOV r11, #0 LDR r8, [r5], #4 BLE celt_pitch_xcorr_edsp_process2_loop_done LDR r6, [r4], #4 LDR r9, [r5], #4 celt_pitch_xcorr_edsp_process2_loop4: SMLABB r10, r6, r8, r10 @ sum0 = MAC16_16(sum0, x_0, y_0) LDR r7, [r4], #4 SMLABT r11, r6, r8, r11 @ sum1 = MAC16_16(sum1, x_0, y_1) SUBS r12, r12, #4 @ j-=4 SMLATT r10, r6, r8, r10 @ sum0 = MAC16_16(sum0, x_1, y_1) LDR r8, [r5], #4 SMLATB r11, r6, r9, r11 @ sum1 = MAC16_16(sum1, x_1, y_2) LDRGT r6, [r4], #4 SMLABB r10, r7, r9, r10 @ sum0 = MAC16_16(sum0, x_2, y_2) SMLABT r11, r7, r9, r11 @ sum1 = MAC16_16(sum1, x_2, y_3) SMLATT r10, r7, r9, r10 @ sum0 = MAC16_16(sum0, x_3, y_3) LDRGT r9, [r5], #4 SMLATB r11, r7, r8, r11 @ sum1 = MAC16_16(sum1, x_3, y_4) BGT celt_pitch_xcorr_edsp_process2_loop4 celt_pitch_xcorr_edsp_process2_loop_done: ADDS r12, r12, #2 BLE celt_pitch_xcorr_edsp_process2_1 LDR r6, [r4], #4 @ Stall SMLABB r10, r6, r8, r10 @ sum0 = MAC16_16(sum0, x_0, y_0) LDR r9, [r5], #4 SMLABT r11, r6, r8, r11 @ sum1 = MAC16_16(sum1, x_0, y_1) SUB r12, r12, #2 SMLATT r10, r6, r8, r10 @ sum0 = MAC16_16(sum0, x_1, y_1) MOV r8, r9 SMLATB r11, r6, r9, r11 @ sum1 = MAC16_16(sum1, x_1, y_2) celt_pitch_xcorr_edsp_process2_1: LDRH r6, [r4], #2 ADDS r12, r12, #1 @ Stall SMLABB r10, r6, r8, r10 @ sum0 = MAC16_16(sum0, x_0, y_0) LDRHGT r7, [r4], #2 SMLABT r11, r6, r8, r11 @ sum1 = MAC16_16(sum1, x_0, y_1) BLE celt_pitch_xcorr_edsp_process2_done LDRH r9, [r5], #2 SMLABT r10, r7, r8, r10 @ sum0 = MAC16_16(sum0, x_0, y_1) SMLABB r11, r7, r9, r11 @ sum1 = MAC16_16(sum1, x_0, y_2) celt_pitch_xcorr_edsp_process2_done: @ Restore _x SUB r4, r4, r3, LSL #1 @ Restore and advance _y SUB r5, r5, r3, LSL #1 @ maxcorr = max(maxcorr, sum0) CMP r0, r10 ADD r5, r5, #2 MOVLT r0, r10 SUB r1, r1, #2 @ maxcorr = max(maxcorr, sum1) CMP r0, r11 @ xcorr[i] = sum STR r10, [r2], #4 MOVLT r0, r11 STR r11, [r2], #4 celt_pitch_xcorr_edsp_process1a: ADDS r1, r1, #1 BLT celt_pitch_xcorr_edsp_done SUBS r12, r3, #4 @ r14 = sum = 0 MOV r14, #0 BLT celt_pitch_xcorr_edsp_process1a_loop_done LDR r6, [r4], #4 LDR r8, [r5], #4 LDR r7, [r4], #4 LDR r9, [r5], #4 celt_pitch_xcorr_edsp_process1a_loop4: SMLABB r14, r6, r8, r14 @ sum = MAC16_16(sum, x_0, y_0) SUBS r12, r12, #4 @ j-=4 SMLATT r14, r6, r8, r14 @ sum = MAC16_16(sum, x_1, y_1) LDRGE r6, [r4], #4 SMLABB r14, r7, r9, r14 @ sum = MAC16_16(sum, x_2, y_2) LDRGE r8, [r5], #4 SMLATT r14, r7, r9, r14 @ sum = MAC16_16(sum, x_3, y_3) LDRGE r7, [r4], #4 LDRGE r9, [r5], #4 BGE celt_pitch_xcorr_edsp_process1a_loop4 celt_pitch_xcorr_edsp_process1a_loop_done: ADDS r12, r12, #2 LDRGE r6, [r4], #4 LDRGE r8, [r5], #4 @ Stall SMLABBGE r14, r6, r8, r14 @ sum = MAC16_16(sum, x_0, y_0) SUBGE r12, r12, #2 SMLATTGE r14, r6, r8, r14 @ sum = MAC16_16(sum, x_1, y_1) ADDS r12, r12, #1 LDRHGE r6, [r4], #2 LDRHGE r8, [r5], #2 @ Stall SMLABBGE r14, r6, r8, r14 @ sum = MAC16_16(sum, *x, *y) @ maxcorr = max(maxcorr, sum) CMP r0, r14 @ xcorr[i] = sum STR r14, [r2], #4 MOVLT r0, r14 celt_pitch_xcorr_edsp_done: LDMFD sp!, {r4-r11, pc} .size celt_pitch_xcorr_edsp, .-celt_pitch_xcorr_edsp @ ENDP .endif @ END: .section .note.GNU-stack,"",%progbits jamulus-3.9.1+dfsg/libs/opus/celt/arm/fixed_armv5e.h0000644000175000017500000001027414340334543021334 0ustar vimervimer/* Copyright (C) 2007-2009 Xiph.Org Foundation Copyright (C) 2003-2008 Jean-Marc Valin Copyright (C) 2007-2008 CSIRO Copyright (C) 2013 Parrot */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef FIXED_ARMv5E_H #define FIXED_ARMv5E_H #include "fixed_armv4.h" /** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */ #undef MULT16_32_Q16 static OPUS_INLINE opus_val32 MULT16_32_Q16_armv5e(opus_val16 a, opus_val32 b) { int res; __asm__( "#MULT16_32_Q16\n\t" "smulwb %0, %1, %2\n\t" : "=r"(res) : "r"(b),"r"(a) ); return res; } #define MULT16_32_Q16(a, b) (MULT16_32_Q16_armv5e(a, b)) /** 16x32 multiplication, followed by a 15-bit shift right. Results fits in 32 bits */ #undef MULT16_32_Q15 static OPUS_INLINE opus_val32 MULT16_32_Q15_armv5e(opus_val16 a, opus_val32 b) { int res; __asm__( "#MULT16_32_Q15\n\t" "smulwb %0, %1, %2\n\t" : "=r"(res) : "r"(b), "r"(a) ); return SHL32(res,1); } #define MULT16_32_Q15(a, b) (MULT16_32_Q15_armv5e(a, b)) /** 16x32 multiply, followed by a 15-bit shift right and 32-bit add. b must fit in 31 bits. Result fits in 32 bits. */ #undef MAC16_32_Q15 static OPUS_INLINE opus_val32 MAC16_32_Q15_armv5e(opus_val32 c, opus_val16 a, opus_val32 b) { int res; __asm__( "#MAC16_32_Q15\n\t" "smlawb %0, %1, %2, %3;\n" : "=r"(res) : "r"(SHL32(b,1)), "r"(a), "r"(c) ); return res; } #define MAC16_32_Q15(c, a, b) (MAC16_32_Q15_armv5e(c, a, b)) /** 16x32 multiply, followed by a 16-bit shift right and 32-bit add. Result fits in 32 bits. */ #undef MAC16_32_Q16 static OPUS_INLINE opus_val32 MAC16_32_Q16_armv5e(opus_val32 c, opus_val16 a, opus_val32 b) { int res; __asm__( "#MAC16_32_Q16\n\t" "smlawb %0, %1, %2, %3;\n" : "=r"(res) : "r"(b), "r"(a), "r"(c) ); return res; } #define MAC16_32_Q16(c, a, b) (MAC16_32_Q16_armv5e(c, a, b)) /** 16x16 multiply-add where the result fits in 32 bits */ #undef MAC16_16 static OPUS_INLINE opus_val32 MAC16_16_armv5e(opus_val32 c, opus_val16 a, opus_val16 b) { int res; __asm__( "#MAC16_16\n\t" "smlabb %0, %1, %2, %3;\n" : "=r"(res) : "r"(a), "r"(b), "r"(c) ); return res; } #define MAC16_16(c, a, b) (MAC16_16_armv5e(c, a, b)) /** 16x16 multiplication where the result fits in 32 bits */ #undef MULT16_16 static OPUS_INLINE opus_val32 MULT16_16_armv5e(opus_val16 a, opus_val16 b) { int res; __asm__( "#MULT16_16\n\t" "smulbb %0, %1, %2;\n" : "=r"(res) : "r"(a), "r"(b) ); return res; } #define MULT16_16(a, b) (MULT16_16_armv5e(a, b)) #ifdef OPUS_ARM_INLINE_MEDIA #undef SIG2WORD16 static OPUS_INLINE opus_val16 SIG2WORD16_armv6(opus_val32 x) { celt_sig res; __asm__( "#SIG2WORD16\n\t" "ssat %0, #16, %1, ASR #12\n\t" : "=r"(res) : "r"(x+2048) ); return EXTRACT16(res); } #define SIG2WORD16(x) (SIG2WORD16_armv6(x)) #endif /* OPUS_ARM_INLINE_MEDIA */ #endif jamulus-3.9.1+dfsg/libs/opus/celt/arm/pitch_neon_intr.c0000644000175000017500000002425314340334543022135 0ustar vimervimer/*********************************************************************** Copyright (c) 2017 Google Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "pitch.h" #ifdef FIXED_POINT opus_val32 celt_inner_prod_neon(const opus_val16 *x, const opus_val16 *y, int N) { int i; opus_val32 xy; int16x8_t x_s16x8, y_s16x8; int32x4_t xy_s32x4 = vdupq_n_s32(0); int64x2_t xy_s64x2; int64x1_t xy_s64x1; for (i = 0; i < N - 7; i += 8) { x_s16x8 = vld1q_s16(&x[i]); y_s16x8 = vld1q_s16(&y[i]); xy_s32x4 = vmlal_s16(xy_s32x4, vget_low_s16 (x_s16x8), vget_low_s16 (y_s16x8)); xy_s32x4 = vmlal_s16(xy_s32x4, vget_high_s16(x_s16x8), vget_high_s16(y_s16x8)); } if (N - i >= 4) { const int16x4_t x_s16x4 = vld1_s16(&x[i]); const int16x4_t y_s16x4 = vld1_s16(&y[i]); xy_s32x4 = vmlal_s16(xy_s32x4, x_s16x4, y_s16x4); i += 4; } xy_s64x2 = vpaddlq_s32(xy_s32x4); xy_s64x1 = vadd_s64(vget_low_s64(xy_s64x2), vget_high_s64(xy_s64x2)); xy = vget_lane_s32(vreinterpret_s32_s64(xy_s64x1), 0); for (; i < N; i++) { xy = MAC16_16(xy, x[i], y[i]); } #ifdef OPUS_CHECK_ASM celt_assert(celt_inner_prod_c(x, y, N) == xy); #endif return xy; } void dual_inner_prod_neon(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02, int N, opus_val32 *xy1, opus_val32 *xy2) { int i; opus_val32 xy01, xy02; int16x8_t x_s16x8, y01_s16x8, y02_s16x8; int32x4_t xy01_s32x4 = vdupq_n_s32(0); int32x4_t xy02_s32x4 = vdupq_n_s32(0); int64x2_t xy01_s64x2, xy02_s64x2; int64x1_t xy01_s64x1, xy02_s64x1; for (i = 0; i < N - 7; i += 8) { x_s16x8 = vld1q_s16(&x[i]); y01_s16x8 = vld1q_s16(&y01[i]); y02_s16x8 = vld1q_s16(&y02[i]); xy01_s32x4 = vmlal_s16(xy01_s32x4, vget_low_s16 (x_s16x8), vget_low_s16 (y01_s16x8)); xy02_s32x4 = vmlal_s16(xy02_s32x4, vget_low_s16 (x_s16x8), vget_low_s16 (y02_s16x8)); xy01_s32x4 = vmlal_s16(xy01_s32x4, vget_high_s16(x_s16x8), vget_high_s16(y01_s16x8)); xy02_s32x4 = vmlal_s16(xy02_s32x4, vget_high_s16(x_s16x8), vget_high_s16(y02_s16x8)); } if (N - i >= 4) { const int16x4_t x_s16x4 = vld1_s16(&x[i]); const int16x4_t y01_s16x4 = vld1_s16(&y01[i]); const int16x4_t y02_s16x4 = vld1_s16(&y02[i]); xy01_s32x4 = vmlal_s16(xy01_s32x4, x_s16x4, y01_s16x4); xy02_s32x4 = vmlal_s16(xy02_s32x4, x_s16x4, y02_s16x4); i += 4; } xy01_s64x2 = vpaddlq_s32(xy01_s32x4); xy02_s64x2 = vpaddlq_s32(xy02_s32x4); xy01_s64x1 = vadd_s64(vget_low_s64(xy01_s64x2), vget_high_s64(xy01_s64x2)); xy02_s64x1 = vadd_s64(vget_low_s64(xy02_s64x2), vget_high_s64(xy02_s64x2)); xy01 = vget_lane_s32(vreinterpret_s32_s64(xy01_s64x1), 0); xy02 = vget_lane_s32(vreinterpret_s32_s64(xy02_s64x1), 0); for (; i < N; i++) { xy01 = MAC16_16(xy01, x[i], y01[i]); xy02 = MAC16_16(xy02, x[i], y02[i]); } *xy1 = xy01; *xy2 = xy02; #ifdef OPUS_CHECK_ASM { opus_val32 xy1_c, xy2_c; dual_inner_prod_c(x, y01, y02, N, &xy1_c, &xy2_c); celt_assert(xy1_c == *xy1); celt_assert(xy2_c == *xy2); } #endif } #else /* !FIXED_POINT */ /* ========================================================================== */ #ifdef OPUS_CHECK_ASM /* This part of code simulates floating-point NEON operations. */ /* celt_inner_prod_neon_float_c_simulation() simulates the floating-point */ /* operations of celt_inner_prod_neon(), and both functions should have bit */ /* exact output. */ static opus_val32 celt_inner_prod_neon_float_c_simulation(const opus_val16 *x, const opus_val16 *y, int N) { int i; opus_val32 xy, xy0 = 0, xy1 = 0, xy2 = 0, xy3 = 0; for (i = 0; i < N - 3; i += 4) { xy0 = MAC16_16(xy0, x[i + 0], y[i + 0]); xy1 = MAC16_16(xy1, x[i + 1], y[i + 1]); xy2 = MAC16_16(xy2, x[i + 2], y[i + 2]); xy3 = MAC16_16(xy3, x[i + 3], y[i + 3]); } xy0 += xy2; xy1 += xy3; xy = xy0 + xy1; for (; i < N; i++) { xy = MAC16_16(xy, x[i], y[i]); } return xy; } /* dual_inner_prod_neon_float_c_simulation() simulates the floating-point */ /* operations of dual_inner_prod_neon(), and both functions should have bit */ /* exact output. */ static void dual_inner_prod_neon_float_c_simulation(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02, int N, opus_val32 *xy1, opus_val32 *xy2) { int i; opus_val32 xy01, xy02, xy01_0 = 0, xy01_1 = 0, xy01_2 = 0, xy01_3 = 0, xy02_0 = 0, xy02_1 = 0, xy02_2 = 0, xy02_3 = 0; for (i = 0; i < N - 3; i += 4) { xy01_0 = MAC16_16(xy01_0, x[i + 0], y01[i + 0]); xy01_1 = MAC16_16(xy01_1, x[i + 1], y01[i + 1]); xy01_2 = MAC16_16(xy01_2, x[i + 2], y01[i + 2]); xy01_3 = MAC16_16(xy01_3, x[i + 3], y01[i + 3]); xy02_0 = MAC16_16(xy02_0, x[i + 0], y02[i + 0]); xy02_1 = MAC16_16(xy02_1, x[i + 1], y02[i + 1]); xy02_2 = MAC16_16(xy02_2, x[i + 2], y02[i + 2]); xy02_3 = MAC16_16(xy02_3, x[i + 3], y02[i + 3]); } xy01_0 += xy01_2; xy02_0 += xy02_2; xy01_1 += xy01_3; xy02_1 += xy02_3; xy01 = xy01_0 + xy01_1; xy02 = xy02_0 + xy02_1; for (; i < N; i++) { xy01 = MAC16_16(xy01, x[i], y01[i]); xy02 = MAC16_16(xy02, x[i], y02[i]); } *xy1 = xy01; *xy2 = xy02; } #endif /* OPUS_CHECK_ASM */ /* ========================================================================== */ opus_val32 celt_inner_prod_neon(const opus_val16 *x, const opus_val16 *y, int N) { int i; opus_val32 xy; float32x4_t xy_f32x4 = vdupq_n_f32(0); float32x2_t xy_f32x2; for (i = 0; i < N - 7; i += 8) { float32x4_t x_f32x4, y_f32x4; x_f32x4 = vld1q_f32(&x[i]); y_f32x4 = vld1q_f32(&y[i]); xy_f32x4 = vmlaq_f32(xy_f32x4, x_f32x4, y_f32x4); x_f32x4 = vld1q_f32(&x[i + 4]); y_f32x4 = vld1q_f32(&y[i + 4]); xy_f32x4 = vmlaq_f32(xy_f32x4, x_f32x4, y_f32x4); } if (N - i >= 4) { const float32x4_t x_f32x4 = vld1q_f32(&x[i]); const float32x4_t y_f32x4 = vld1q_f32(&y[i]); xy_f32x4 = vmlaq_f32(xy_f32x4, x_f32x4, y_f32x4); i += 4; } xy_f32x2 = vadd_f32(vget_low_f32(xy_f32x4), vget_high_f32(xy_f32x4)); xy_f32x2 = vpadd_f32(xy_f32x2, xy_f32x2); xy = vget_lane_f32(xy_f32x2, 0); for (; i < N; i++) { xy = MAC16_16(xy, x[i], y[i]); } #ifdef OPUS_CHECK_ASM celt_assert(ABS32(celt_inner_prod_neon_float_c_simulation(x, y, N) - xy) <= VERY_SMALL); #endif return xy; } void dual_inner_prod_neon(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02, int N, opus_val32 *xy1, opus_val32 *xy2) { int i; opus_val32 xy01, xy02; float32x4_t xy01_f32x4 = vdupq_n_f32(0); float32x4_t xy02_f32x4 = vdupq_n_f32(0); float32x2_t xy01_f32x2, xy02_f32x2; for (i = 0; i < N - 7; i += 8) { float32x4_t x_f32x4, y01_f32x4, y02_f32x4; x_f32x4 = vld1q_f32(&x[i]); y01_f32x4 = vld1q_f32(&y01[i]); y02_f32x4 = vld1q_f32(&y02[i]); xy01_f32x4 = vmlaq_f32(xy01_f32x4, x_f32x4, y01_f32x4); xy02_f32x4 = vmlaq_f32(xy02_f32x4, x_f32x4, y02_f32x4); x_f32x4 = vld1q_f32(&x[i + 4]); y01_f32x4 = vld1q_f32(&y01[i + 4]); y02_f32x4 = vld1q_f32(&y02[i + 4]); xy01_f32x4 = vmlaq_f32(xy01_f32x4, x_f32x4, y01_f32x4); xy02_f32x4 = vmlaq_f32(xy02_f32x4, x_f32x4, y02_f32x4); } if (N - i >= 4) { const float32x4_t x_f32x4 = vld1q_f32(&x[i]); const float32x4_t y01_f32x4 = vld1q_f32(&y01[i]); const float32x4_t y02_f32x4 = vld1q_f32(&y02[i]); xy01_f32x4 = vmlaq_f32(xy01_f32x4, x_f32x4, y01_f32x4); xy02_f32x4 = vmlaq_f32(xy02_f32x4, x_f32x4, y02_f32x4); i += 4; } xy01_f32x2 = vadd_f32(vget_low_f32(xy01_f32x4), vget_high_f32(xy01_f32x4)); xy02_f32x2 = vadd_f32(vget_low_f32(xy02_f32x4), vget_high_f32(xy02_f32x4)); xy01_f32x2 = vpadd_f32(xy01_f32x2, xy01_f32x2); xy02_f32x2 = vpadd_f32(xy02_f32x2, xy02_f32x2); xy01 = vget_lane_f32(xy01_f32x2, 0); xy02 = vget_lane_f32(xy02_f32x2, 0); for (; i < N; i++) { xy01 = MAC16_16(xy01, x[i], y01[i]); xy02 = MAC16_16(xy02, x[i], y02[i]); } *xy1 = xy01; *xy2 = xy02; #ifdef OPUS_CHECK_ASM { opus_val32 xy1_c, xy2_c; dual_inner_prod_neon_float_c_simulation(x, y01, y02, N, &xy1_c, &xy2_c); celt_assert(ABS32(xy1_c - *xy1) <= VERY_SMALL); celt_assert(ABS32(xy2_c - *xy2) <= VERY_SMALL); } #endif } #endif /* FIXED_POINT */ jamulus-3.9.1+dfsg/libs/opus/celt/arm/armcpu.h0000644000175000017500000000466114340334543020250 0ustar vimervimer/* Copyright (c) 2010 Xiph.Org Foundation * Copyright (c) 2013 Parrot */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(ARMCPU_H) # define ARMCPU_H # if defined(OPUS_ARM_MAY_HAVE_EDSP) # define MAY_HAVE_EDSP(name) name ## _edsp # else # define MAY_HAVE_EDSP(name) name ## _c # endif # if defined(OPUS_ARM_MAY_HAVE_MEDIA) # define MAY_HAVE_MEDIA(name) name ## _media # else # define MAY_HAVE_MEDIA(name) MAY_HAVE_EDSP(name) # endif # if defined(OPUS_ARM_MAY_HAVE_NEON) # define MAY_HAVE_NEON(name) name ## _neon # else # define MAY_HAVE_NEON(name) MAY_HAVE_MEDIA(name) # endif # if defined(OPUS_ARM_PRESUME_EDSP) # define PRESUME_EDSP(name) name ## _edsp # else # define PRESUME_EDSP(name) name ## _c # endif # if defined(OPUS_ARM_PRESUME_MEDIA) # define PRESUME_MEDIA(name) name ## _media # else # define PRESUME_MEDIA(name) PRESUME_EDSP(name) # endif # if defined(OPUS_ARM_PRESUME_NEON) # define PRESUME_NEON(name) name ## _neon # else # define PRESUME_NEON(name) PRESUME_MEDIA(name) # endif # if defined(OPUS_HAVE_RTCD) int opus_select_arch(void); #define OPUS_ARCH_ARM_V4 (0) #define OPUS_ARCH_ARM_EDSP (1) #define OPUS_ARCH_ARM_MEDIA (2) #define OPUS_ARCH_ARM_NEON (3) # endif #endif jamulus-3.9.1+dfsg/libs/opus/celt/bands.c0000644000175000017500000014421214340334543017261 0ustar vimervimer/* Copyright (c) 2007-2008 CSIRO Copyright (c) 2007-2009 Xiph.Org Foundation Copyright (c) 2008-2009 Gregory Maxwell Written by Jean-Marc Valin and Gregory Maxwell */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "bands.h" #include "modes.h" #include "vq.h" #include "cwrs.h" #include "stack_alloc.h" #include "os_support.h" #include "mathops.h" #include "rate.h" #include "quant_bands.h" #include "pitch.h" int hysteresis_decision(opus_val16 val, const opus_val16 *thresholds, const opus_val16 *hysteresis, int N, int prev) { int i; for (i=0;iprev && val < thresholds[prev]+hysteresis[prev]) i=prev; if (i thresholds[prev-1]-hysteresis[prev-1]) i=prev; return i; } opus_uint32 celt_lcg_rand(opus_uint32 seed) { return 1664525 * seed + 1013904223; } /* This is a cos() approximation designed to be bit-exact on any platform. Bit exactness with this approximation is important because it has an impact on the bit allocation */ opus_int16 bitexact_cos(opus_int16 x) { opus_int32 tmp; opus_int16 x2; tmp = (4096+((opus_int32)(x)*(x)))>>13; celt_sig_assert(tmp<=32767); x2 = tmp; x2 = (32767-x2) + FRAC_MUL16(x2, (-7651 + FRAC_MUL16(x2, (8277 + FRAC_MUL16(-626, x2))))); celt_sig_assert(x2<=32766); return 1+x2; } int bitexact_log2tan(int isin,int icos) { int lc; int ls; lc=EC_ILOG(icos); ls=EC_ILOG(isin); icos<<=15-lc; isin<<=15-ls; return (ls-lc)*(1<<11) +FRAC_MUL16(isin, FRAC_MUL16(isin, -2597) + 7932) -FRAC_MUL16(icos, FRAC_MUL16(icos, -2597) + 7932); } #ifdef FIXED_POINT /* Compute the amplitude (sqrt energy) in each of the bands */ void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int LM, int arch) { int i, c, N; const opus_int16 *eBands = m->eBands; (void)arch; N = m->shortMdctSize< 0) { int shift = celt_ilog2(maxval) - 14 + (((m->logN[i]>>BITRES)+LM+1)>>1); j=eBands[i]<0) { do { sum = MAC16_16(sum, EXTRACT16(SHR32(X[j+c*N],shift)), EXTRACT16(SHR32(X[j+c*N],shift))); } while (++jnbEBands] = EPSILON+VSHR32(EXTEND32(celt_sqrt(sum)),-shift); } else { bandE[i+c*m->nbEBands] = EPSILON; } /*printf ("%f ", bandE[i+c*m->nbEBands]);*/ } } while (++ceBands; N = M*m->shortMdctSize; c=0; do { i=0; do { opus_val16 g; int j,shift; opus_val16 E; shift = celt_zlog2(bandE[i+c*m->nbEBands])-13; E = VSHR32(bandE[i+c*m->nbEBands], shift); g = EXTRACT16(celt_rcp(SHL32(E,3))); j=M*eBands[i]; do { X[j+c*N] = MULT16_16_Q15(VSHR32(freq[j+c*N],shift-1),g); } while (++jeBands; N = m->shortMdctSize<nbEBands] = celt_sqrt(sum); /*printf ("%f ", bandE[i+c*m->nbEBands]);*/ } } while (++ceBands; N = M*m->shortMdctSize; c=0; do { for (i=0;inbEBands]); for (j=M*eBands[i];jeBands; N = M*m->shortMdctSize; bound = M*eBands[end]; if (downsample!=1) bound = IMIN(bound, N/downsample); if (silence) { bound = 0; start = end = 0; } f = freq; x = X+M*eBands[start]; for (i=0;i>DB_SHIFT); if (shift>31) { shift=0; g=0; } else { /* Handle the fractional part. */ g = celt_exp2_frac(lg&((1< 16384 we'd be likely to overflow, so we're capping the gain here, which is equivalent to a cap of 18 on lg. This shouldn't trigger unless the bitstream is already corrupted. */ if (shift <= -2) { g = 16384; shift = -2; } do { *f++ = SHL32(MULT16_16(*x++, g), -shift); } while (++jeBands[i+1]-m->eBands[i]; /* depth in 1/8 bits */ celt_sig_assert(pulses[i]>=0); depth = celt_udiv(1+pulses[i], (m->eBands[i+1]-m->eBands[i]))>>LM; #ifdef FIXED_POINT thresh32 = SHR32(celt_exp2(-SHL16(depth, 10-BITRES)),1); thresh = MULT16_32_Q15(QCONST16(0.5f, 15), MIN32(32767,thresh32)); { opus_val32 t; t = N0<>1; t = SHL32(t, (7-shift)<<1); sqrt_1 = celt_rsqrt_norm(t); } #else thresh = .5f*celt_exp2(-.125f*depth); sqrt_1 = celt_rsqrt(N0<nbEBands+i]; prev2 = prev2logE[c*m->nbEBands+i]; if (C==1) { prev1 = MAX16(prev1,prev1logE[m->nbEBands+i]); prev2 = MAX16(prev2,prev2logE[m->nbEBands+i]); } Ediff = EXTEND32(logE[c*m->nbEBands+i])-EXTEND32(MIN16(prev1,prev2)); Ediff = MAX32(0, Ediff); #ifdef FIXED_POINT if (Ediff < 16384) { opus_val32 r32 = SHR32(celt_exp2(-EXTRACT16(Ediff)),1); r = 2*MIN16(16383,r32); } else { r = 0; } if (LM==3) r = MULT16_16_Q14(23170, MIN32(23169, r)); r = SHR16(MIN16(thresh, r),1); r = SHR32(MULT16_16_Q15(sqrt_1, r),shift); #else /* r needs to be multiplied by 2 or 2*sqrt(2) depending on LM because short blocks don't have the same energy as long */ r = 2.f*celt_exp2(-Ediff); if (LM==3) r *= 1.41421356f; r = MIN16(thresh, r); r = r*sqrt_1; #endif X = X_+c*size+(m->eBands[i]<nbEBands]))-13; #endif left = VSHR32(bandE[i],shift); right = VSHR32(bandE[i+m->nbEBands],shift); norm = EPSILON + celt_sqrt(EPSILON+MULT16_16(left,left)+MULT16_16(right,right)); a1 = DIV32_16(SHL32(EXTEND32(left),14),norm); a2 = DIV32_16(SHL32(EXTEND32(right),14),norm); for (j=0;j>1; kr = celt_ilog2(Er)>>1; #endif t = VSHR32(El, (kl-7)<<1); lgain = celt_rsqrt_norm(t); t = VSHR32(Er, (kr-7)<<1); rgain = celt_rsqrt_norm(t); #ifdef FIXED_POINT if (kl < 7) kl = 7; if (kr < 7) kr = 7; #endif for (j=0;jeBands; int decision; int hf_sum=0; celt_assert(end>0); N0 = M*m->shortMdctSize; if (M*(eBands[end]-eBands[end-1]) <= 8) return SPREAD_NONE; c=0; do { for (i=0;im->nbEBands-4) hf_sum += celt_udiv(32*(tcount[1]+tcount[0]), N); tmp = (2*tcount[2] >= N) + (2*tcount[1] >= N) + (2*tcount[0] >= N); sum += tmp*spread_weight[i]; nbBands+=spread_weight[i]; } } while (++cnbEBands+end)); *hf_average = (*hf_average+hf_sum)>>1; hf_sum = *hf_average; if (*tapset_decision==2) hf_sum += 4; else if (*tapset_decision==0) hf_sum -= 4; if (hf_sum > 22) *tapset_decision=2; else if (hf_sum > 18) *tapset_decision=1; else *tapset_decision=0; } /*printf("%d %d %d\n", hf_sum, *hf_average, *tapset_decision);*/ celt_assert(nbBands>0); /* end has to be non-zero */ celt_assert(sum>=0); sum = celt_udiv((opus_int32)sum<<8, nbBands); /* Recursive averaging */ sum = (sum+*average)>>1; *average = sum; /* Hysteresis */ sum = (3*sum + (((3-last_decision)<<7) + 64) + 2)>>2; if (sum < 80) { decision = SPREAD_AGGRESSIVE; } else if (sum < 256) { decision = SPREAD_NORMAL; } else if (sum < 384) { decision = SPREAD_LIGHT; } else { decision = SPREAD_NONE; } #ifdef FUZZING decision = rand()&0x3; *tapset_decision=rand()%3; #endif return decision; } /* Indexing table for converting from natural Hadamard to ordery Hadamard This is essentially a bit-reversed Gray, on top of which we've added an inversion of the order because we want the DC at the end rather than the beginning. The lines are for N=2, 4, 8, 16 */ static const int ordery_table[] = { 1, 0, 3, 0, 2, 1, 7, 0, 4, 3, 6, 1, 5, 2, 15, 0, 8, 7, 12, 3, 11, 4, 14, 1, 9, 6, 13, 2, 10, 5, }; static void deinterleave_hadamard(celt_norm *X, int N0, int stride, int hadamard) { int i,j; VARDECL(celt_norm, tmp); int N; SAVE_STACK; N = N0*stride; ALLOC(tmp, N, celt_norm); celt_assert(stride>0); if (hadamard) { const int *ordery = ordery_table+stride-2; for (i=0;i>= 1; for (i=0;i>1)) { qn = 1; } else { qn = exp2_table8[qb&0x7]>>(14-(qb>>BITRES)); qn = (qn+1)>>1<<1; } celt_assert(qn <= 256); return qn; } struct band_ctx { int encode; int resynth; const CELTMode *m; int i; int intensity; int spread; int tf_change; ec_ctx *ec; opus_int32 remaining_bits; const celt_ener *bandE; opus_uint32 seed; int arch; int theta_round; int disable_inv; int avoid_split_noise; }; struct split_ctx { int inv; int imid; int iside; int delta; int itheta; int qalloc; }; static void compute_theta(struct band_ctx *ctx, struct split_ctx *sctx, celt_norm *X, celt_norm *Y, int N, int *b, int B, int B0, int LM, int stereo, int *fill) { int qn; int itheta=0; int delta; int imid, iside; int qalloc; int pulse_cap; int offset; opus_int32 tell; int inv=0; int encode; const CELTMode *m; int i; int intensity; ec_ctx *ec; const celt_ener *bandE; encode = ctx->encode; m = ctx->m; i = ctx->i; intensity = ctx->intensity; ec = ctx->ec; bandE = ctx->bandE; /* Decide on the resolution to give to the split parameter theta */ pulse_cap = m->logN[i]+LM*(1<>1) - (stereo&&N==2 ? QTHETA_OFFSET_TWOPHASE : QTHETA_OFFSET); qn = compute_qn(N, *b, offset, pulse_cap, stereo); if (stereo && i>=intensity) qn = 1; if (encode) { /* theta is the atan() of the ratio between the (normalized) side and mid. With just that parameter, we can re-scale both mid and side because we know that 1) they have unit norm and 2) they are orthogonal. */ itheta = stereo_itheta(X, Y, stereo, N, ctx->arch); } tell = ec_tell_frac(ec); if (qn!=1) { if (encode) { if (!stereo || ctx->theta_round == 0) { itheta = (itheta*(opus_int32)qn+8192)>>14; if (!stereo && ctx->avoid_split_noise && itheta > 0 && itheta < qn) { /* Check if the selected value of theta will cause the bit allocation to inject noise on one side. If so, make sure the energy of that side is zero. */ int unquantized = celt_udiv((opus_int32)itheta*16384, qn); imid = bitexact_cos((opus_int16)unquantized); iside = bitexact_cos((opus_int16)(16384-unquantized)); delta = FRAC_MUL16((N-1)<<7,bitexact_log2tan(iside,imid)); if (delta > *b) itheta = qn; else if (delta < -*b) itheta = 0; } } else { int down; /* Bias quantization towards itheta=0 and itheta=16384. */ int bias = itheta > 8192 ? 32767/qn : -32767/qn; down = IMIN(qn-1, IMAX(0, (itheta*(opus_int32)qn + bias)>>14)); if (ctx->theta_round < 0) itheta = down; else itheta = down+1; } } /* Entropy coding of the angle. We use a uniform pdf for the time split, a step for stereo, and a triangular one for the rest. */ if (stereo && N>2) { int p0 = 3; int x = itheta; int x0 = qn/2; int ft = p0*(x0+1) + x0; /* Use a probability of p0 up to itheta=8192 and then use 1 after */ if (encode) { ec_encode(ec,x<=x0?p0*x:(x-1-x0)+(x0+1)*p0,x<=x0?p0*(x+1):(x-x0)+(x0+1)*p0,ft); } else { int fs; fs=ec_decode(ec,ft); if (fs<(x0+1)*p0) x=fs/p0; else x=x0+1+(fs-(x0+1)*p0); ec_dec_update(ec,x<=x0?p0*x:(x-1-x0)+(x0+1)*p0,x<=x0?p0*(x+1):(x-x0)+(x0+1)*p0,ft); itheta = x; } } else if (B0>1 || stereo) { /* Uniform pdf */ if (encode) ec_enc_uint(ec, itheta, qn+1); else itheta = ec_dec_uint(ec, qn+1); } else { int fs=1, ft; ft = ((qn>>1)+1)*((qn>>1)+1); if (encode) { int fl; fs = itheta <= (qn>>1) ? itheta + 1 : qn + 1 - itheta; fl = itheta <= (qn>>1) ? itheta*(itheta + 1)>>1 : ft - ((qn + 1 - itheta)*(qn + 2 - itheta)>>1); ec_encode(ec, fl, fl+fs, ft); } else { /* Triangular pdf */ int fl=0; int fm; fm = ec_decode(ec, ft); if (fm < ((qn>>1)*((qn>>1) + 1)>>1)) { itheta = (isqrt32(8*(opus_uint32)fm + 1) - 1)>>1; fs = itheta + 1; fl = itheta*(itheta + 1)>>1; } else { itheta = (2*(qn + 1) - isqrt32(8*(opus_uint32)(ft - fm - 1) + 1))>>1; fs = qn + 1 - itheta; fl = ft - ((qn + 1 - itheta)*(qn + 2 - itheta)>>1); } ec_dec_update(ec, fl, fl+fs, ft); } } celt_assert(itheta>=0); itheta = celt_udiv((opus_int32)itheta*16384, qn); if (encode && stereo) { if (itheta==0) intensity_stereo(m, X, Y, bandE, i, N); else stereo_split(X, Y, N); } /* NOTE: Renormalising X and Y *may* help fixed-point a bit at very high rate. Let's do that at higher complexity */ } else if (stereo) { if (encode) { inv = itheta > 8192 && !ctx->disable_inv; if (inv) { int j; for (j=0;j2<remaining_bits > 2<disable_inv) inv = 0; itheta = 0; } qalloc = ec_tell_frac(ec) - tell; *b -= qalloc; if (itheta == 0) { imid = 32767; iside = 0; *fill &= (1<inv = inv; sctx->imid = imid; sctx->iside = iside; sctx->delta = delta; sctx->itheta = itheta; sctx->qalloc = qalloc; } static unsigned quant_band_n1(struct band_ctx *ctx, celt_norm *X, celt_norm *Y, int b, celt_norm *lowband_out) { int c; int stereo; celt_norm *x = X; int encode; ec_ctx *ec; encode = ctx->encode; ec = ctx->ec; stereo = Y != NULL; c=0; do { int sign=0; if (ctx->remaining_bits>=1<remaining_bits -= 1<resynth) x[0] = sign ? -NORM_SCALING : NORM_SCALING; x = Y; } while (++c<1+stereo); if (lowband_out) lowband_out[0] = SHR16(X[0],4); return 1; } /* This function is responsible for encoding and decoding a mono partition. It can split the band in two and transmit the energy difference with the two half-bands. It can be called recursively so bands can end up being split in 8 parts. */ static unsigned quant_partition(struct band_ctx *ctx, celt_norm *X, int N, int b, int B, celt_norm *lowband, int LM, opus_val16 gain, int fill) { const unsigned char *cache; int q; int curr_bits; int imid=0, iside=0; int B0=B; opus_val16 mid=0, side=0; unsigned cm=0; celt_norm *Y=NULL; int encode; const CELTMode *m; int i; int spread; ec_ctx *ec; encode = ctx->encode; m = ctx->m; i = ctx->i; spread = ctx->spread; ec = ctx->ec; /* If we need 1.5 more bit than we can produce, split the band in two. */ cache = m->cache.bits + m->cache.index[(LM+1)*m->nbEBands+i]; if (LM != -1 && b > cache[cache[0]]+12 && N>2) { int mbits, sbits, delta; int itheta; int qalloc; struct split_ctx sctx; celt_norm *next_lowband2=NULL; opus_int32 rebalance; N >>= 1; Y = X+N; LM -= 1; if (B==1) fill = (fill&1)|(fill<<1); B = (B+1)>>1; compute_theta(ctx, &sctx, X, Y, N, &b, B, B0, LM, 0, &fill); imid = sctx.imid; iside = sctx.iside; delta = sctx.delta; itheta = sctx.itheta; qalloc = sctx.qalloc; #ifdef FIXED_POINT mid = imid; side = iside; #else mid = (1.f/32768)*imid; side = (1.f/32768)*iside; #endif /* Give more bits to low-energy MDCTs than they would otherwise deserve */ if (B0>1 && (itheta&0x3fff)) { if (itheta > 8192) /* Rough approximation for pre-echo masking */ delta -= delta>>(4-LM); else /* Corresponds to a forward-masking slope of 1.5 dB per 10 ms */ delta = IMIN(0, delta + (N<>(5-LM))); } mbits = IMAX(0, IMIN(b, (b-delta)/2)); sbits = b-mbits; ctx->remaining_bits -= qalloc; if (lowband) next_lowband2 = lowband+N; /* >32-bit split case */ rebalance = ctx->remaining_bits; if (mbits >= sbits) { cm = quant_partition(ctx, X, N, mbits, B, lowband, LM, MULT16_16_P15(gain,mid), fill); rebalance = mbits - (rebalance-ctx->remaining_bits); if (rebalance > 3<>B)<<(B0>>1); } else { cm = quant_partition(ctx, Y, N, sbits, B, next_lowband2, LM, MULT16_16_P15(gain,side), fill>>B)<<(B0>>1); rebalance = sbits - (rebalance-ctx->remaining_bits); if (rebalance > 3<remaining_bits -= curr_bits; /* Ensures we can never bust the budget */ while (ctx->remaining_bits < 0 && q > 0) { ctx->remaining_bits += curr_bits; q--; curr_bits = pulses2bits(m, i, LM, q); ctx->remaining_bits -= curr_bits; } if (q!=0) { int K = get_pulses(q); /* Finally do the actual quantization */ if (encode) { cm = alg_quant(X, N, K, spread, B, ec, gain, ctx->resynth, ctx->arch); } else { cm = alg_unquant(X, N, K, spread, B, ec, gain); } } else { /* If there's no pulse, fill the band anyway */ int j; if (ctx->resynth) { unsigned cm_mask; /* B can be as large as 16, so this shift might overflow an int on a 16-bit platform; use a long to get defined behavior.*/ cm_mask = (unsigned)(1UL<seed = celt_lcg_rand(ctx->seed); X[j] = (celt_norm)((opus_int32)ctx->seed>>20); } cm = cm_mask; } else { /* Folded spectrum */ for (j=0;jseed = celt_lcg_rand(ctx->seed); /* About 48 dB below the "normal" folding level */ tmp = QCONST16(1.0f/256, 10); tmp = (ctx->seed)&0x8000 ? tmp : -tmp; X[j] = lowband[j]+tmp; } cm = fill; } renormalise_vector(X, N, gain, ctx->arch); } } } } return cm; } /* This function is responsible for encoding and decoding a band for the mono case. */ static unsigned quant_band(struct band_ctx *ctx, celt_norm *X, int N, int b, int B, celt_norm *lowband, int LM, celt_norm *lowband_out, opus_val16 gain, celt_norm *lowband_scratch, int fill) { int N0=N; int N_B=N; int N_B0; int B0=B; int time_divide=0; int recombine=0; int longBlocks; unsigned cm=0; int k; int encode; int tf_change; encode = ctx->encode; tf_change = ctx->tf_change; longBlocks = B0==1; N_B = celt_udiv(N_B, B); /* Special case for one sample */ if (N==1) { return quant_band_n1(ctx, X, NULL, b, lowband_out); } if (tf_change>0) recombine = tf_change; /* Band recombining to increase frequency resolution */ if (lowband_scratch && lowband && (recombine || ((N_B&1) == 0 && tf_change<0) || B0>1)) { OPUS_COPY(lowband_scratch, lowband, N); lowband = lowband_scratch; } for (k=0;k>k, 1<>k, 1<>4]<<2; } B>>=recombine; N_B<<=recombine; /* Increasing the time resolution */ while ((N_B&1) == 0 && tf_change<0) { if (encode) haar1(X, N_B, B); if (lowband) haar1(lowband, N_B, B); fill |= fill<>= 1; time_divide++; tf_change++; } B0=B; N_B0 = N_B; /* Reorganize the samples in time order instead of frequency order */ if (B0>1) { if (encode) deinterleave_hadamard(X, N_B>>recombine, B0<>recombine, B0<resynth) { /* Undo the sample reorganization going from time order to frequency order */ if (B0>1) interleave_hadamard(X, N_B>>recombine, B0<>= 1; N_B <<= 1; cm |= cm>>B; haar1(X, N_B, B); } for (k=0;k>k, 1<encode; ec = ctx->ec; /* Special case for one sample */ if (N==1) { return quant_band_n1(ctx, X, Y, b, lowband_out); } orig_fill = fill; compute_theta(ctx, &sctx, X, Y, N, &b, B, B, LM, 1, &fill); inv = sctx.inv; imid = sctx.imid; iside = sctx.iside; delta = sctx.delta; itheta = sctx.itheta; qalloc = sctx.qalloc; #ifdef FIXED_POINT mid = imid; side = iside; #else mid = (1.f/32768)*imid; side = (1.f/32768)*iside; #endif /* This is a special case for N=2 that only works for stereo and takes advantage of the fact that mid and side are orthogonal to encode the side with just one bit. */ if (N==2) { int c; int sign=0; celt_norm *x2, *y2; mbits = b; sbits = 0; /* Only need one bit for the side. */ if (itheta != 0 && itheta != 16384) sbits = 1< 8192; ctx->remaining_bits -= qalloc+sbits; x2 = c ? Y : X; y2 = c ? X : Y; if (sbits) { if (encode) { /* Here we only need to encode a sign for the side. */ sign = x2[0]*y2[1] - x2[1]*y2[0] < 0; ec_enc_bits(ec, sign, 1); } else { sign = ec_dec_bits(ec, 1); } } sign = 1-2*sign; /* We use orig_fill here because we want to fold the side, but if itheta==16384, we'll have cleared the low bits of fill. */ cm = quant_band(ctx, x2, N, mbits, B, lowband, LM, lowband_out, Q15ONE, lowband_scratch, orig_fill); /* We don't split N=2 bands, so cm is either 1 or 0 (for a fold-collapse), and there's no need to worry about mixing with the other channel. */ y2[0] = -sign*x2[1]; y2[1] = sign*x2[0]; if (ctx->resynth) { celt_norm tmp; X[0] = MULT16_16_Q15(mid, X[0]); X[1] = MULT16_16_Q15(mid, X[1]); Y[0] = MULT16_16_Q15(side, Y[0]); Y[1] = MULT16_16_Q15(side, Y[1]); tmp = X[0]; X[0] = SUB16(tmp,Y[0]); Y[0] = ADD16(tmp,Y[0]); tmp = X[1]; X[1] = SUB16(tmp,Y[1]); Y[1] = ADD16(tmp,Y[1]); } } else { /* "Normal" split code */ opus_int32 rebalance; mbits = IMAX(0, IMIN(b, (b-delta)/2)); sbits = b-mbits; ctx->remaining_bits -= qalloc; rebalance = ctx->remaining_bits; if (mbits >= sbits) { /* In stereo mode, we do not apply a scaling to the mid because we need the normalized mid for folding later. */ cm = quant_band(ctx, X, N, mbits, B, lowband, LM, lowband_out, Q15ONE, lowband_scratch, fill); rebalance = mbits - (rebalance-ctx->remaining_bits); if (rebalance > 3<>B); } else { /* For a stereo split, the high bits of fill are always zero, so no folding will be done to the side. */ cm = quant_band(ctx, Y, N, sbits, B, NULL, LM, NULL, side, NULL, fill>>B); rebalance = sbits - (rebalance-ctx->remaining_bits); if (rebalance > 3<resynth) { if (N!=2) stereo_merge(X, Y, mid, N, ctx->arch); if (inv) { int j; for (j=0;jeBands; n1 = M*(eBands[start+1]-eBands[start]); n2 = M*(eBands[start+2]-eBands[start+1]); /* Duplicate enough of the first band folding data to be able to fold the second band. Copies no data for CELT-only mode. */ OPUS_COPY(&norm[n1], &norm[2*n1 - n2], n2-n1); if (dual_stereo) OPUS_COPY(&norm2[n1], &norm2[2*n1 - n2], n2-n1); } void quant_all_bands(int encode, const CELTMode *m, int start, int end, celt_norm *X_, celt_norm *Y_, unsigned char *collapse_masks, const celt_ener *bandE, int *pulses, int shortBlocks, int spread, int dual_stereo, int intensity, int *tf_res, opus_int32 total_bits, opus_int32 balance, ec_ctx *ec, int LM, int codedBands, opus_uint32 *seed, int complexity, int arch, int disable_inv) { int i; opus_int32 remaining_bits; const opus_int16 * OPUS_RESTRICT eBands = m->eBands; celt_norm * OPUS_RESTRICT norm, * OPUS_RESTRICT norm2; VARDECL(celt_norm, _norm); VARDECL(celt_norm, _lowband_scratch); VARDECL(celt_norm, X_save); VARDECL(celt_norm, Y_save); VARDECL(celt_norm, X_save2); VARDECL(celt_norm, Y_save2); VARDECL(celt_norm, norm_save2); int resynth_alloc; celt_norm *lowband_scratch; int B; int M; int lowband_offset; int update_lowband = 1; int C = Y_ != NULL ? 2 : 1; int norm_offset; int theta_rdo = encode && Y_!=NULL && !dual_stereo && complexity>=8; #ifdef RESYNTH int resynth = 1; #else int resynth = !encode || theta_rdo; #endif struct band_ctx ctx; SAVE_STACK; M = 1<nbEBands-1]-norm_offset), celt_norm); norm = _norm; norm2 = norm + M*eBands[m->nbEBands-1]-norm_offset; /* For decoding, we can use the last band as scratch space because we don't need that scratch space for the last band and we don't care about the data there until we're decoding the last band. */ if (encode && resynth) resynth_alloc = M*(eBands[m->nbEBands]-eBands[m->nbEBands-1]); else resynth_alloc = ALLOC_NONE; ALLOC(_lowband_scratch, resynth_alloc, celt_norm); if (encode && resynth) lowband_scratch = _lowband_scratch; else lowband_scratch = X_+M*eBands[m->nbEBands-1]; ALLOC(X_save, resynth_alloc, celt_norm); ALLOC(Y_save, resynth_alloc, celt_norm); ALLOC(X_save2, resynth_alloc, celt_norm); ALLOC(Y_save2, resynth_alloc, celt_norm); ALLOC(norm_save2, resynth_alloc, celt_norm); lowband_offset = 0; ctx.bandE = bandE; ctx.ec = ec; ctx.encode = encode; ctx.intensity = intensity; ctx.m = m; ctx.seed = *seed; ctx.spread = spread; ctx.arch = arch; ctx.disable_inv = disable_inv; ctx.resynth = resynth; ctx.theta_round = 0; /* Avoid injecting noise in the first band on transients. */ ctx.avoid_split_noise = B > 1; for (i=start;i 0); tell = ec_tell_frac(ec); /* Compute how many bits we want to allocate to this band */ if (i != start) balance -= tell; remaining_bits = total_bits-tell-1; ctx.remaining_bits = remaining_bits; if (i <= codedBands-1) { curr_balance = celt_sudiv(balance, IMIN(3, codedBands-i)); b = IMAX(0, IMIN(16383, IMIN(remaining_bits+1,pulses[i]+curr_balance))); } else { b = 0; } #ifndef DISABLE_UPDATE_DRAFT if (resynth && (M*eBands[i]-N >= M*eBands[start] || i==start+1) && (update_lowband || lowband_offset==0)) lowband_offset = i; if (i == start+1) special_hybrid_folding(m, norm, norm2, start, M, dual_stereo); #else if (resynth && M*eBands[i]-N >= M*eBands[start] && (update_lowband || lowband_offset==0)) lowband_offset = i; #endif tf_change = tf_res[i]; ctx.tf_change = tf_change; if (i>=m->effEBands) { X=norm; if (Y_!=NULL) Y = norm; lowband_scratch = NULL; } if (last && !theta_rdo) lowband_scratch = NULL; /* Get a conservative estimate of the collapse_mask's for the bands we're going to be folding from. */ if (lowband_offset != 0 && (spread!=SPREAD_AGGRESSIVE || B>1 || tf_change<0)) { int fold_start; int fold_end; int fold_i; /* This ensures we never repeat spectral content within one band */ effective_lowband = IMAX(0, M*eBands[lowband_offset]-norm_offset-N); fold_start = lowband_offset; while(M*eBands[--fold_start] > effective_lowband+norm_offset); fold_end = lowband_offset-1; #ifndef DISABLE_UPDATE_DRAFT while(++fold_end < i && M*eBands[fold_end] < effective_lowband+norm_offset+N); #else while(M*eBands[++fold_end] < effective_lowband+norm_offset+N); #endif x_cm = y_cm = 0; fold_i = fold_start; do { x_cm |= collapse_masks[fold_i*C+0]; y_cm |= collapse_masks[fold_i*C+C-1]; } while (++fold_inbEBands], w); /* Make a copy. */ cm = x_cm|y_cm; ec_save = *ec; ctx_save = ctx; OPUS_COPY(X_save, X, N); OPUS_COPY(Y_save, Y, N); /* Encode and round down. */ ctx.theta_round = -1; x_cm = quant_band_stereo(&ctx, X, Y, N, b, B, effective_lowband != -1 ? norm+effective_lowband : NULL, LM, last?NULL:norm+M*eBands[i]-norm_offset, lowband_scratch, cm); dist0 = MULT16_32_Q15(w[0], celt_inner_prod(X_save, X, N, arch)) + MULT16_32_Q15(w[1], celt_inner_prod(Y_save, Y, N, arch)); /* Save first result. */ cm2 = x_cm; ec_save2 = *ec; ctx_save2 = ctx; OPUS_COPY(X_save2, X, N); OPUS_COPY(Y_save2, Y, N); if (!last) OPUS_COPY(norm_save2, norm+M*eBands[i]-norm_offset, N); nstart_bytes = ec_save.offs; nend_bytes = ec_save.storage; bytes_buf = ec_save.buf+nstart_bytes; save_bytes = nend_bytes-nstart_bytes; OPUS_COPY(bytes_save, bytes_buf, save_bytes); /* Restore */ *ec = ec_save; ctx = ctx_save; OPUS_COPY(X, X_save, N); OPUS_COPY(Y, Y_save, N); #ifndef DISABLE_UPDATE_DRAFT if (i == start+1) special_hybrid_folding(m, norm, norm2, start, M, dual_stereo); #endif /* Encode and round up. */ ctx.theta_round = 1; x_cm = quant_band_stereo(&ctx, X, Y, N, b, B, effective_lowband != -1 ? norm+effective_lowband : NULL, LM, last?NULL:norm+M*eBands[i]-norm_offset, lowband_scratch, cm); dist1 = MULT16_32_Q15(w[0], celt_inner_prod(X_save, X, N, arch)) + MULT16_32_Q15(w[1], celt_inner_prod(Y_save, Y, N, arch)); if (dist0 >= dist1) { x_cm = cm2; *ec = ec_save2; ctx = ctx_save2; OPUS_COPY(X, X_save2, N); OPUS_COPY(Y, Y_save2, N); if (!last) OPUS_COPY(norm+M*eBands[i]-norm_offset, norm_save2, N); OPUS_COPY(bytes_buf, bytes_save, save_bytes); } } else { ctx.theta_round = 0; x_cm = quant_band_stereo(&ctx, X, Y, N, b, B, effective_lowband != -1 ? norm+effective_lowband : NULL, LM, last?NULL:norm+M*eBands[i]-norm_offset, lowband_scratch, x_cm|y_cm); } } else { x_cm = quant_band(&ctx, X, N, b, B, effective_lowband != -1 ? norm+effective_lowband : NULL, LM, last?NULL:norm+M*eBands[i]-norm_offset, Q15ONE, lowband_scratch, x_cm|y_cm); } y_cm = x_cm; } collapse_masks[i*C+0] = (unsigned char)x_cm; collapse_masks[i*C+C-1] = (unsigned char)y_cm; balance += pulses[i] + tell; /* Update the folding position only as long as we have 1 bit/sample depth. */ update_lowband = b>(N< #ifndef NE10_FFT_PARAMS48000_960 #define NE10_FFT_PARAMS48000_960 static const ne10_int32_t ne10_factors_480[64] = { 4, 40, 4, 30, 2, 15, 5, 3, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const ne10_int32_t ne10_factors_240[64] = { 3, 20, 4, 15, 5, 3, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const ne10_int32_t ne10_factors_120[64] = { 3, 10, 2, 15, 5, 3, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const ne10_int32_t ne10_factors_60[64] = { 2, 5, 5, 3, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const ne10_fft_cpx_int32_t ne10_twiddles_480[480] = { {0,0}, {2147483647,0}, {2147483647,0}, {2147483647,0}, {1961823921,-873460313}, {1436946998,-1595891394}, {2147483647,0}, {1436946998,-1595891394}, {-224473265,-2135719496}, {2147483647,0}, {663608871,-2042378339}, {-1737350854,-1262259096}, {2147483647,0}, {-224473265,-2135719496}, {-2100555935,446487152}, {2147483647,0}, {2100555974,-446486968}, {1961823921,-873460313}, {1737350743,-1262259248}, {1436946998,-1595891394}, {1073741769,-1859775424}, {663608871,-2042378339}, {224473078,-2135719516}, {-224473265,-2135719496}, {-663609049,-2042378281}, {-1073741932,-1859775330}, {-1436947137,-1595891268}, {-1737350854,-1262259096}, {-1961823997,-873460141}, {-2100556013,-446486785}, {2147483647,0}, {2144540595,-112390613}, {2135719506,-224473172}, {2121044558,-335940465}, {2100555974,-446486968}, {2074309912,-555809682}, {2042378310,-663608960}, {2004848691,-769589332}, {1961823921,-873460313}, {1913421927,-974937199}, {1859775377,-1073741851}, {1801031311,-1169603450}, {1737350743,-1262259248}, {1668908218,-1351455280}, {1595891331,-1436947067}, {1518500216,-1518500282}, {1436946998,-1595891394}, {1351455207,-1668908277}, {1262259172,-1737350799}, {1169603371,-1801031362}, {1073741769,-1859775424}, {974937230,-1913421912}, {873460227,-1961823959}, {769589125,-2004848771}, {663608871,-2042378339}, {555809715,-2074309903}, {446486876,-2100555994}, {335940246,-2121044593}, {224473078,-2135719516}, {112390647,-2144540593}, {2147483647,0}, {2135719506,-224473172}, {2100555974,-446486968}, {2042378310,-663608960}, {1961823921,-873460313}, {1859775377,-1073741851}, {1737350743,-1262259248}, {1595891331,-1436947067}, {1436946998,-1595891394}, {1262259172,-1737350799}, {1073741769,-1859775424}, {873460227,-1961823959}, {663608871,-2042378339}, {446486876,-2100555994}, {224473078,-2135719516}, {-94,-2147483647}, {-224473265,-2135719496}, {-446487060,-2100555955}, {-663609049,-2042378281}, {-873460398,-1961823883}, {-1073741932,-1859775330}, {-1262259116,-1737350839}, {-1436947137,-1595891268}, {-1595891628,-1436946738}, {-1737350854,-1262259096}, {-1859775343,-1073741910}, {-1961823997,-873460141}, {-2042378447,-663608538}, {-2100556013,-446486785}, {-2135719499,-224473240}, {2147483647,0}, {2121044558,-335940465}, {2042378310,-663608960}, {1913421927,-974937199}, {1737350743,-1262259248}, {1518500216,-1518500282}, {1262259172,-1737350799}, {974937230,-1913421912}, {663608871,-2042378339}, {335940246,-2121044593}, {-94,-2147483647}, {-335940431,-2121044564}, {-663609049,-2042378281}, {-974937397,-1913421827}, {-1262259116,-1737350839}, {-1518500258,-1518500240}, {-1737350854,-1262259096}, {-1913422071,-974936918}, {-2042378447,-663608538}, {-2121044568,-335940406}, {-2147483647,188}, {-2121044509,335940777}, {-2042378331,663608895}, {-1913421900,974937252}, {-1737350633,1262259400}, {-1518499993,1518500506}, {-1262258813,1737351059}, {-974936606,1913422229}, {-663609179,2042378239}, {-335940566,2121044542}, {2147483647,0}, {2147299667,-28109693}, {2146747758,-56214570}, {2145828015,-84309815}, {2144540595,-112390613}, {2142885719,-140452154}, {2140863671,-168489630}, {2138474797,-196498235}, {2135719506,-224473172}, {2132598271,-252409646}, {2129111626,-280302871}, {2125260168,-308148068}, {2121044558,-335940465}, {2116465518,-363675300}, {2111523833,-391347822}, {2106220349,-418953288}, {2100555974,-446486968}, {2094531681,-473944146}, {2088148500,-501320115}, {2081407525,-528610186}, {2074309912,-555809682}, {2066856885,-582913912}, {2059049696,-609918325}, {2050889698,-636818231}, {2042378310,-663608960}, {2033516972,-690285983}, {2024307180,-716844791}, {2014750533,-743280770}, {2004848691,-769589332}, {1994603329,-795766029}, {1984016179,-821806435}, {1973089077,-847706028}, {1961823921,-873460313}, {1950222618,-899064934}, {1938287127,-924515564}, {1926019520,-949807783}, {1913421927,-974937199}, {1900496481,-999899565}, {1887245364,-1024690661}, {1873670877,-1049306180}, {1859775377,-1073741851}, {1845561215,-1097993541}, {1831030826,-1122057097}, {1816186632,-1145928502}, {1801031311,-1169603450}, {1785567394,-1193077993}, {1769797456,-1216348214}, {1753724345,-1239409914}, {1737350743,-1262259248}, {1720679456,-1284892300}, {1703713340,-1307305194}, {1686455222,-1329494189}, {1668908218,-1351455280}, {1651075255,-1373184807}, {1632959307,-1394679144}, {1614563642,-1415934412}, {1595891331,-1436947067}, {1576945572,-1457713510}, {1557729613,-1478230181}, {1538246655,-1498493658}, {1518500216,-1518500282}, {1498493590,-1538246721}, {1478230113,-1557729677}, {1457713441,-1576945636}, {1436946998,-1595891394}, {1415934341,-1614563704}, {1394679073,-1632959368}, {1373184735,-1651075315}, {1351455207,-1668908277}, {1329494115,-1686455280}, {1307305120,-1703713397}, {1284892225,-1720679512}, {1262259172,-1737350799}, {1239409837,-1753724400}, {1216348136,-1769797510}, {1193077915,-1785567446}, {1169603371,-1801031362}, {1145928423,-1816186682}, {1122057017,-1831030875}, {1097993571,-1845561197}, {1073741769,-1859775424}, {1049305987,-1873670985}, {1024690635,-1887245378}, {999899482,-1900496524}, {974937230,-1913421912}, {949807699,-1926019561}, {924515422,-1938287195}, {899064965,-1950222603}, {873460227,-1961823959}, {847705824,-1973089164}, {821806407,-1984016190}, {795765941,-1994603364}, {769589125,-2004848771}, {743280682,-2014750566}, {716844642,-2024307233}, {690286016,-2033516961}, {663608871,-2042378339}, {636818019,-2050889764}, {609918296,-2059049705}, {582913822,-2066856911}, {555809715,-2074309903}, {528610126,-2081407540}, {501319962,-2088148536}, {473944148,-2094531680}, {446486876,-2100555994}, {418953102,-2106220386}, {391347792,-2111523838}, {363675176,-2116465540}, {335940246,-2121044593}, {308148006,-2125260177}, {280302715,-2129111646}, {252409648,-2132598271}, {224473078,-2135719516}, {196498046,-2138474814}, {168489600,-2140863674}, {140452029,-2142885728}, {112390647,-2144540593}, {84309753,-2145828017}, {56214412,-2146747762}, {28109695,-2147299667}, {2147483647,0}, {2146747758,-56214570}, {2144540595,-112390613}, {2140863671,-168489630}, {2135719506,-224473172}, {2129111626,-280302871}, {2121044558,-335940465}, {2111523833,-391347822}, {2100555974,-446486968}, {2088148500,-501320115}, {2074309912,-555809682}, {2059049696,-609918325}, {2042378310,-663608960}, {2024307180,-716844791}, {2004848691,-769589332}, {1984016179,-821806435}, {1961823921,-873460313}, {1938287127,-924515564}, {1913421927,-974937199}, {1887245364,-1024690661}, {1859775377,-1073741851}, {1831030826,-1122057097}, {1801031311,-1169603450}, {1769797456,-1216348214}, {1737350743,-1262259248}, {1703713340,-1307305194}, {1668908218,-1351455280}, {1632959307,-1394679144}, {1595891331,-1436947067}, {1557729613,-1478230181}, {1518500216,-1518500282}, {1478230113,-1557729677}, {1436946998,-1595891394}, {1394679073,-1632959368}, {1351455207,-1668908277}, {1307305120,-1703713397}, {1262259172,-1737350799}, {1216348136,-1769797510}, {1169603371,-1801031362}, {1122057017,-1831030875}, {1073741769,-1859775424}, {1024690635,-1887245378}, {974937230,-1913421912}, {924515422,-1938287195}, {873460227,-1961823959}, {821806407,-1984016190}, {769589125,-2004848771}, {716844642,-2024307233}, {663608871,-2042378339}, {609918296,-2059049705}, {555809715,-2074309903}, {501319962,-2088148536}, {446486876,-2100555994}, {391347792,-2111523838}, {335940246,-2121044593}, {280302715,-2129111646}, {224473078,-2135719516}, {168489600,-2140863674}, {112390647,-2144540593}, {56214412,-2146747762}, {-94,-2147483647}, {-56214600,-2146747757}, {-112390835,-2144540584}, {-168489787,-2140863659}, {-224473265,-2135719496}, {-280302901,-2129111622}, {-335940431,-2121044564}, {-391347977,-2111523804}, {-446487060,-2100555955}, {-501320144,-2088148493}, {-555809896,-2074309855}, {-609918476,-2059049651}, {-663609049,-2042378281}, {-716844819,-2024307170}, {-769589300,-2004848703}, {-821806581,-1984016118}, {-873460398,-1961823883}, {-924515591,-1938287114}, {-974937397,-1913421827}, {-1024690575,-1887245411}, {-1073741932,-1859775330}, {-1122057395,-1831030643}, {-1169603421,-1801031330}, {-1216348291,-1769797403}, {-1262259116,-1737350839}, {-1307305268,-1703713283}, {-1351455453,-1668908078}, {-1394679021,-1632959413}, {-1436947137,-1595891268}, {-1478230435,-1557729372}, {-1518500258,-1518500240}, {-1557729742,-1478230045}, {-1595891628,-1436946738}, {-1632959429,-1394679001}, {-1668908417,-1351455035}, {-1703713298,-1307305248}, {-1737350854,-1262259096}, {-1769797708,-1216347848}, {-1801031344,-1169603400}, {-1831030924,-1122056937}, {-1859775343,-1073741910}, {-1887245423,-1024690552}, {-1913422071,-974936918}, {-1938287125,-924515568}, {-1961823997,-873460141}, {-1984016324,-821806084}, {-2004848713,-769589276}, {-2024307264,-716844553}, {-2042378447,-663608538}, {-2059049731,-609918206}, {-2074309994,-555809377}, {-2088148499,-501320119}, {-2100556013,-446486785}, {-2111523902,-391347448}, {-2121044568,-335940406}, {-2129111659,-280302621}, {-2135719499,-224473240}, {-2140863681,-168489506}, {-2144540612,-112390298}, {-2146747758,-56214574}, {2147483647,0}, {2145828015,-84309815}, {2140863671,-168489630}, {2132598271,-252409646}, {2121044558,-335940465}, {2106220349,-418953288}, {2088148500,-501320115}, {2066856885,-582913912}, {2042378310,-663608960}, {2014750533,-743280770}, {1984016179,-821806435}, {1950222618,-899064934}, {1913421927,-974937199}, {1873670877,-1049306180}, {1831030826,-1122057097}, {1785567394,-1193077993}, {1737350743,-1262259248}, {1686455222,-1329494189}, {1632959307,-1394679144}, {1576945572,-1457713510}, {1518500216,-1518500282}, {1457713441,-1576945636}, {1394679073,-1632959368}, {1329494115,-1686455280}, {1262259172,-1737350799}, {1193077915,-1785567446}, {1122057017,-1831030875}, {1049305987,-1873670985}, {974937230,-1913421912}, {899064965,-1950222603}, {821806407,-1984016190}, {743280682,-2014750566}, {663608871,-2042378339}, {582913822,-2066856911}, {501319962,-2088148536}, {418953102,-2106220386}, {335940246,-2121044593}, {252409648,-2132598271}, {168489600,-2140863674}, {84309753,-2145828017}, {-94,-2147483647}, {-84309940,-2145828010}, {-168489787,-2140863659}, {-252409834,-2132598249}, {-335940431,-2121044564}, {-418953286,-2106220349}, {-501320144,-2088148493}, {-582914003,-2066856860}, {-663609049,-2042378281}, {-743280858,-2014750501}, {-821806581,-1984016118}, {-899065136,-1950222525}, {-974937397,-1913421827}, {-1049306374,-1873670768}, {-1122057395,-1831030643}, {-1193078284,-1785567199}, {-1262259116,-1737350839}, {-1329494061,-1686455323}, {-1394679021,-1632959413}, {-1457713485,-1576945595}, {-1518500258,-1518500240}, {-1576945613,-1457713466}, {-1632959429,-1394679001}, {-1686455338,-1329494041}, {-1737350854,-1262259096}, {-1785567498,-1193077837}, {-1831030924,-1122056937}, {-1873671031,-1049305905}, {-1913422071,-974936918}, {-1950222750,-899064648}, {-1984016324,-821806084}, {-2014750687,-743280354}, {-2042378447,-663608538}, {-2066856867,-582913978}, {-2088148499,-501320119}, {-2106220354,-418953261}, {-2121044568,-335940406}, {-2132598282,-252409555}, {-2140863681,-168489506}, {-2145828021,-84309659}, {-2147483647,188}, {-2145828006,84310034}, {-2140863651,168489881}, {-2132598237,252409928}, {-2121044509,335940777}, {-2106220281,418953629}, {-2088148411,501320484}, {-2066856765,582914339}, {-2042378331,663608895}, {-2014750557,743280706}, {-1984016181,821806431}, {-1950222593,899064989}, {-1913421900,974937252}, {-1873670848,1049306232}, {-1831030728,1122057257}, {-1785567289,1193078149}, {-1737350633,1262259400}, {-1686455106,1329494336}, {-1632959185,1394679287}, {-1576945358,1457713742}, {-1518499993,1518500506}, {-1457713209,1576945850}, {-1394678735,1632959656}, {-1329493766,1686455555}, {-1262258813,1737351059}, {-1193077546,1785567692}, {-1122056638,1831031107}, {-1049305599,1873671202}, {-974936606,1913422229}, {-899064330,1950222896}, {-821805761,1984016458}, {-743280025,2014750808}, {-663609179,2042378239}, {-582914134,2066856823}, {-501320277,2088148461}, {-418953420,2106220322}, {-335940566,2121044542}, {-252409716,2132598263}, {-168489668,2140863668}, {-84309821,2145828015}, }; static const ne10_fft_cpx_int32_t ne10_twiddles_240[240] = { {0,0}, {2147483647,0}, {2147483647,0}, {2147483647,0}, {1961823921,-873460313}, {1436946998,-1595891394}, {2147483647,0}, {1436946998,-1595891394}, {-224473265,-2135719496}, {2147483647,0}, {663608871,-2042378339}, {-1737350854,-1262259096}, {2147483647,0}, {-224473265,-2135719496}, {-2100555935,446487152}, {2147483647,0}, {2135719506,-224473172}, {2100555974,-446486968}, {2042378310,-663608960}, {1961823921,-873460313}, {1859775377,-1073741851}, {1737350743,-1262259248}, {1595891331,-1436947067}, {1436946998,-1595891394}, {1262259172,-1737350799}, {1073741769,-1859775424}, {873460227,-1961823959}, {663608871,-2042378339}, {446486876,-2100555994}, {224473078,-2135719516}, {2147483647,0}, {2100555974,-446486968}, {1961823921,-873460313}, {1737350743,-1262259248}, {1436946998,-1595891394}, {1073741769,-1859775424}, {663608871,-2042378339}, {224473078,-2135719516}, {-224473265,-2135719496}, {-663609049,-2042378281}, {-1073741932,-1859775330}, {-1436947137,-1595891268}, {-1737350854,-1262259096}, {-1961823997,-873460141}, {-2100556013,-446486785}, {2147483647,0}, {2042378310,-663608960}, {1737350743,-1262259248}, {1262259172,-1737350799}, {663608871,-2042378339}, {-94,-2147483647}, {-663609049,-2042378281}, {-1262259116,-1737350839}, {-1737350854,-1262259096}, {-2042378447,-663608538}, {-2147483647,188}, {-2042378331,663608895}, {-1737350633,1262259400}, {-1262258813,1737351059}, {-663609179,2042378239}, {2147483647,0}, {2146747758,-56214570}, {2144540595,-112390613}, {2140863671,-168489630}, {2135719506,-224473172}, {2129111626,-280302871}, {2121044558,-335940465}, {2111523833,-391347822}, {2100555974,-446486968}, {2088148500,-501320115}, {2074309912,-555809682}, {2059049696,-609918325}, {2042378310,-663608960}, {2024307180,-716844791}, {2004848691,-769589332}, {1984016179,-821806435}, {1961823921,-873460313}, {1938287127,-924515564}, {1913421927,-974937199}, {1887245364,-1024690661}, {1859775377,-1073741851}, {1831030826,-1122057097}, {1801031311,-1169603450}, {1769797456,-1216348214}, {1737350743,-1262259248}, {1703713340,-1307305194}, {1668908218,-1351455280}, {1632959307,-1394679144}, {1595891331,-1436947067}, {1557729613,-1478230181}, {1518500216,-1518500282}, {1478230113,-1557729677}, {1436946998,-1595891394}, {1394679073,-1632959368}, {1351455207,-1668908277}, {1307305120,-1703713397}, {1262259172,-1737350799}, {1216348136,-1769797510}, {1169603371,-1801031362}, {1122057017,-1831030875}, {1073741769,-1859775424}, {1024690635,-1887245378}, {974937230,-1913421912}, {924515422,-1938287195}, {873460227,-1961823959}, {821806407,-1984016190}, {769589125,-2004848771}, {716844642,-2024307233}, {663608871,-2042378339}, {609918296,-2059049705}, {555809715,-2074309903}, {501319962,-2088148536}, {446486876,-2100555994}, {391347792,-2111523838}, {335940246,-2121044593}, {280302715,-2129111646}, {224473078,-2135719516}, {168489600,-2140863674}, {112390647,-2144540593}, {56214412,-2146747762}, {2147483647,0}, {2144540595,-112390613}, {2135719506,-224473172}, {2121044558,-335940465}, {2100555974,-446486968}, {2074309912,-555809682}, {2042378310,-663608960}, {2004848691,-769589332}, {1961823921,-873460313}, {1913421927,-974937199}, {1859775377,-1073741851}, {1801031311,-1169603450}, {1737350743,-1262259248}, {1668908218,-1351455280}, {1595891331,-1436947067}, {1518500216,-1518500282}, {1436946998,-1595891394}, {1351455207,-1668908277}, {1262259172,-1737350799}, {1169603371,-1801031362}, {1073741769,-1859775424}, {974937230,-1913421912}, {873460227,-1961823959}, {769589125,-2004848771}, {663608871,-2042378339}, {555809715,-2074309903}, {446486876,-2100555994}, {335940246,-2121044593}, {224473078,-2135719516}, {112390647,-2144540593}, {-94,-2147483647}, {-112390835,-2144540584}, {-224473265,-2135719496}, {-335940431,-2121044564}, {-446487060,-2100555955}, {-555809896,-2074309855}, {-663609049,-2042378281}, {-769589300,-2004848703}, {-873460398,-1961823883}, {-974937397,-1913421827}, {-1073741932,-1859775330}, {-1169603421,-1801031330}, {-1262259116,-1737350839}, {-1351455453,-1668908078}, {-1436947137,-1595891268}, {-1518500258,-1518500240}, {-1595891628,-1436946738}, {-1668908417,-1351455035}, {-1737350854,-1262259096}, {-1801031344,-1169603400}, {-1859775343,-1073741910}, {-1913422071,-974936918}, {-1961823997,-873460141}, {-2004848713,-769589276}, {-2042378447,-663608538}, {-2074309994,-555809377}, {-2100556013,-446486785}, {-2121044568,-335940406}, {-2135719499,-224473240}, {-2144540612,-112390298}, {2147483647,0}, {2140863671,-168489630}, {2121044558,-335940465}, {2088148500,-501320115}, {2042378310,-663608960}, {1984016179,-821806435}, {1913421927,-974937199}, {1831030826,-1122057097}, {1737350743,-1262259248}, {1632959307,-1394679144}, {1518500216,-1518500282}, {1394679073,-1632959368}, {1262259172,-1737350799}, {1122057017,-1831030875}, {974937230,-1913421912}, {821806407,-1984016190}, {663608871,-2042378339}, {501319962,-2088148536}, {335940246,-2121044593}, {168489600,-2140863674}, {-94,-2147483647}, {-168489787,-2140863659}, {-335940431,-2121044564}, {-501320144,-2088148493}, {-663609049,-2042378281}, {-821806581,-1984016118}, {-974937397,-1913421827}, {-1122057395,-1831030643}, {-1262259116,-1737350839}, {-1394679021,-1632959413}, {-1518500258,-1518500240}, {-1632959429,-1394679001}, {-1737350854,-1262259096}, {-1831030924,-1122056937}, {-1913422071,-974936918}, {-1984016324,-821806084}, {-2042378447,-663608538}, {-2088148499,-501320119}, {-2121044568,-335940406}, {-2140863681,-168489506}, {-2147483647,188}, {-2140863651,168489881}, {-2121044509,335940777}, {-2088148411,501320484}, {-2042378331,663608895}, {-1984016181,821806431}, {-1913421900,974937252}, {-1831030728,1122057257}, {-1737350633,1262259400}, {-1632959185,1394679287}, {-1518499993,1518500506}, {-1394678735,1632959656}, {-1262258813,1737351059}, {-1122056638,1831031107}, {-974936606,1913422229}, {-821805761,1984016458}, {-663609179,2042378239}, {-501320277,2088148461}, {-335940566,2121044542}, {-168489668,2140863668}, }; static const ne10_fft_cpx_int32_t ne10_twiddles_120[120] = { {0,0}, {2147483647,0}, {2147483647,0}, {2147483647,0}, {1961823921,-873460313}, {1436946998,-1595891394}, {2147483647,0}, {1436946998,-1595891394}, {-224473265,-2135719496}, {2147483647,0}, {663608871,-2042378339}, {-1737350854,-1262259096}, {2147483647,0}, {-224473265,-2135719496}, {-2100555935,446487152}, {2147483647,0}, {2100555974,-446486968}, {1961823921,-873460313}, {1737350743,-1262259248}, {1436946998,-1595891394}, {1073741769,-1859775424}, {663608871,-2042378339}, {224473078,-2135719516}, {-224473265,-2135719496}, {-663609049,-2042378281}, {-1073741932,-1859775330}, {-1436947137,-1595891268}, {-1737350854,-1262259096}, {-1961823997,-873460141}, {-2100556013,-446486785}, {2147483647,0}, {2144540595,-112390613}, {2135719506,-224473172}, {2121044558,-335940465}, {2100555974,-446486968}, {2074309912,-555809682}, {2042378310,-663608960}, {2004848691,-769589332}, {1961823921,-873460313}, {1913421927,-974937199}, {1859775377,-1073741851}, {1801031311,-1169603450}, {1737350743,-1262259248}, {1668908218,-1351455280}, {1595891331,-1436947067}, {1518500216,-1518500282}, {1436946998,-1595891394}, {1351455207,-1668908277}, {1262259172,-1737350799}, {1169603371,-1801031362}, {1073741769,-1859775424}, {974937230,-1913421912}, {873460227,-1961823959}, {769589125,-2004848771}, {663608871,-2042378339}, {555809715,-2074309903}, {446486876,-2100555994}, {335940246,-2121044593}, {224473078,-2135719516}, {112390647,-2144540593}, {2147483647,0}, {2135719506,-224473172}, {2100555974,-446486968}, {2042378310,-663608960}, {1961823921,-873460313}, {1859775377,-1073741851}, {1737350743,-1262259248}, {1595891331,-1436947067}, {1436946998,-1595891394}, {1262259172,-1737350799}, {1073741769,-1859775424}, {873460227,-1961823959}, {663608871,-2042378339}, {446486876,-2100555994}, {224473078,-2135719516}, {-94,-2147483647}, {-224473265,-2135719496}, {-446487060,-2100555955}, {-663609049,-2042378281}, {-873460398,-1961823883}, {-1073741932,-1859775330}, {-1262259116,-1737350839}, {-1436947137,-1595891268}, {-1595891628,-1436946738}, {-1737350854,-1262259096}, {-1859775343,-1073741910}, {-1961823997,-873460141}, {-2042378447,-663608538}, {-2100556013,-446486785}, {-2135719499,-224473240}, {2147483647,0}, {2121044558,-335940465}, {2042378310,-663608960}, {1913421927,-974937199}, {1737350743,-1262259248}, {1518500216,-1518500282}, {1262259172,-1737350799}, {974937230,-1913421912}, {663608871,-2042378339}, {335940246,-2121044593}, {-94,-2147483647}, {-335940431,-2121044564}, {-663609049,-2042378281}, {-974937397,-1913421827}, {-1262259116,-1737350839}, {-1518500258,-1518500240}, {-1737350854,-1262259096}, {-1913422071,-974936918}, {-2042378447,-663608538}, {-2121044568,-335940406}, {-2147483647,188}, {-2121044509,335940777}, {-2042378331,663608895}, {-1913421900,974937252}, {-1737350633,1262259400}, {-1518499993,1518500506}, {-1262258813,1737351059}, {-974936606,1913422229}, {-663609179,2042378239}, {-335940566,2121044542}, }; static const ne10_fft_cpx_int32_t ne10_twiddles_60[60] = { {0,0}, {2147483647,0}, {2147483647,0}, {2147483647,0}, {1961823921,-873460313}, {1436946998,-1595891394}, {2147483647,0}, {1436946998,-1595891394}, {-224473265,-2135719496}, {2147483647,0}, {663608871,-2042378339}, {-1737350854,-1262259096}, {2147483647,0}, {-224473265,-2135719496}, {-2100555935,446487152}, {2147483647,0}, {2135719506,-224473172}, {2100555974,-446486968}, {2042378310,-663608960}, {1961823921,-873460313}, {1859775377,-1073741851}, {1737350743,-1262259248}, {1595891331,-1436947067}, {1436946998,-1595891394}, {1262259172,-1737350799}, {1073741769,-1859775424}, {873460227,-1961823959}, {663608871,-2042378339}, {446486876,-2100555994}, {224473078,-2135719516}, {2147483647,0}, {2100555974,-446486968}, {1961823921,-873460313}, {1737350743,-1262259248}, {1436946998,-1595891394}, {1073741769,-1859775424}, {663608871,-2042378339}, {224473078,-2135719516}, {-224473265,-2135719496}, {-663609049,-2042378281}, {-1073741932,-1859775330}, {-1436947137,-1595891268}, {-1737350854,-1262259096}, {-1961823997,-873460141}, {-2100556013,-446486785}, {2147483647,0}, {2042378310,-663608960}, {1737350743,-1262259248}, {1262259172,-1737350799}, {663608871,-2042378339}, {-94,-2147483647}, {-663609049,-2042378281}, {-1262259116,-1737350839}, {-1737350854,-1262259096}, {-2042378447,-663608538}, {-2147483647,188}, {-2042378331,663608895}, {-1737350633,1262259400}, {-1262258813,1737351059}, {-663609179,2042378239}, }; static const ne10_fft_state_int32_t ne10_fft_state_int32_t_480 = { 120, (ne10_int32_t *)ne10_factors_480, (ne10_fft_cpx_int32_t *)ne10_twiddles_480, NULL, (ne10_fft_cpx_int32_t *)&ne10_twiddles_480[120], }; static const arch_fft_state cfg_arch_480 = { 1, (void *)&ne10_fft_state_int32_t_480, }; static const ne10_fft_state_int32_t ne10_fft_state_int32_t_240 = { 60, (ne10_int32_t *)ne10_factors_240, (ne10_fft_cpx_int32_t *)ne10_twiddles_240, NULL, (ne10_fft_cpx_int32_t *)&ne10_twiddles_240[60], }; static const arch_fft_state cfg_arch_240 = { 1, (void *)&ne10_fft_state_int32_t_240, }; static const ne10_fft_state_int32_t ne10_fft_state_int32_t_120 = { 30, (ne10_int32_t *)ne10_factors_120, (ne10_fft_cpx_int32_t *)ne10_twiddles_120, NULL, (ne10_fft_cpx_int32_t *)&ne10_twiddles_120[30], }; static const arch_fft_state cfg_arch_120 = { 1, (void *)&ne10_fft_state_int32_t_120, }; static const ne10_fft_state_int32_t ne10_fft_state_int32_t_60 = { 15, (ne10_int32_t *)ne10_factors_60, (ne10_fft_cpx_int32_t *)ne10_twiddles_60, NULL, (ne10_fft_cpx_int32_t *)&ne10_twiddles_60[15], }; static const arch_fft_state cfg_arch_60 = { 1, (void *)&ne10_fft_state_int32_t_60, }; #endif /* end NE10_FFT_PARAMS48000_960 */ jamulus-3.9.1+dfsg/libs/opus/celt/fixed_debug.h0000644000175000017500000005132614340334543020447 0ustar vimervimer/* Copyright (C) 2003-2008 Jean-Marc Valin Copyright (C) 2007-2012 Xiph.Org Foundation */ /** @file fixed_debug.h @brief Fixed-point operations with debugging */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef FIXED_DEBUG_H #define FIXED_DEBUG_H #include #include "opus_defines.h" #ifdef CELT_C OPUS_EXPORT opus_int64 celt_mips=0; #else extern opus_int64 celt_mips; #endif #define MULT16_16SU(a,b) ((opus_val32)(opus_val16)(a)*(opus_val32)(opus_uint16)(b)) #define MULT32_32_Q31(a,b) ADD32(ADD32(SHL32(MULT16_16(SHR32((a),16),SHR((b),16)),1), SHR32(MULT16_16SU(SHR32((a),16),((b)&0x0000ffff)),15)), SHR32(MULT16_16SU(SHR32((b),16),((a)&0x0000ffff)),15)) /** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */ #define MULT16_32_Q16(a,b) ADD32(MULT16_16((a),SHR32((b),16)), SHR32(MULT16_16SU((a),((b)&0x0000ffff)),16)) #define MULT16_32_P16(a,b) MULT16_32_PX(a,b,16) #define QCONST16(x,bits) ((opus_val16)(.5+(x)*(((opus_val32)1)<<(bits)))) #define QCONST32(x,bits) ((opus_val32)(.5+(x)*(((opus_val32)1)<<(bits)))) #define VERIFY_SHORT(x) ((x)<=32767&&(x)>=-32768) #define VERIFY_INT(x) ((x)<=2147483647LL&&(x)>=-2147483648LL) #define VERIFY_UINT(x) ((x)<=(2147483647LLU<<1)) #define SHR(a,b) SHR32(a,b) #define PSHR(a,b) PSHR32(a,b) /** Add two 32-bit values, ignore any overflows */ #define ADD32_ovflw(a,b) (celt_mips+=2,(opus_val32)((opus_uint32)(a)+(opus_uint32)(b))) /** Subtract two 32-bit values, ignore any overflows */ #define SUB32_ovflw(a,b) (celt_mips+=2,(opus_val32)((opus_uint32)(a)-(opus_uint32)(b))) /* Avoid MSVC warning C4146: unary minus operator applied to unsigned type */ /** Negate 32-bit value, ignore any overflows */ #define NEG32_ovflw(a) (celt_mips+=2,(opus_val32)(0-(opus_uint32)(a))) static OPUS_INLINE short NEG16(int x) { int res; if (!VERIFY_SHORT(x)) { fprintf (stderr, "NEG16: input is not short: %d\n", (int)x); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } res = -x; if (!VERIFY_SHORT(res)) { fprintf (stderr, "NEG16: output is not short: %d\n", (int)res); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } celt_mips++; return res; } static OPUS_INLINE int NEG32(opus_int64 x) { opus_int64 res; if (!VERIFY_INT(x)) { fprintf (stderr, "NEG16: input is not int: %d\n", (int)x); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } res = -x; if (!VERIFY_INT(res)) { fprintf (stderr, "NEG16: output is not int: %d\n", (int)res); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } celt_mips+=2; return res; } #define EXTRACT16(x) EXTRACT16_(x, __FILE__, __LINE__) static OPUS_INLINE short EXTRACT16_(int x, char *file, int line) { int res; if (!VERIFY_SHORT(x)) { fprintf (stderr, "EXTRACT16: input is not short: %d in %s: line %d\n", x, file, line); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } res = x; celt_mips++; return res; } #define EXTEND32(x) EXTEND32_(x, __FILE__, __LINE__) static OPUS_INLINE int EXTEND32_(int x, char *file, int line) { int res; if (!VERIFY_SHORT(x)) { fprintf (stderr, "EXTEND32: input is not short: %d in %s: line %d\n", x, file, line); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } res = x; celt_mips++; return res; } #define SHR16(a, shift) SHR16_(a, shift, __FILE__, __LINE__) static OPUS_INLINE short SHR16_(int a, int shift, char *file, int line) { int res; if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift)) { fprintf (stderr, "SHR16: inputs are not short: %d >> %d in %s: line %d\n", a, shift, file, line); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } res = a>>shift; if (!VERIFY_SHORT(res)) { fprintf (stderr, "SHR16: output is not short: %d in %s: line %d\n", res, file, line); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } celt_mips++; return res; } #define SHL16(a, shift) SHL16_(a, shift, __FILE__, __LINE__) static OPUS_INLINE short SHL16_(int a, int shift, char *file, int line) { int res; if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift)) { fprintf (stderr, "SHL16: inputs are not short: %d %d in %s: line %d\n", a, shift, file, line); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } res = a<>shift; if (!VERIFY_INT(res)) { fprintf (stderr, "SHR32: output is not int: %d\n", (int)res); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } celt_mips+=2; return res; } #define SHL32(a, shift) SHL32_(a, shift, __FILE__, __LINE__) static OPUS_INLINE int SHL32_(opus_int64 a, int shift, char *file, int line) { opus_int64 res; if (!VERIFY_INT(a) || !VERIFY_SHORT(shift)) { fprintf (stderr, "SHL32: inputs are not int: %lld %d in %s: line %d\n", a, shift, file, line); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } res = a<>1))),shift)) #define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift))) #define ROUND16(x,a) (celt_mips--,EXTRACT16(PSHR32((x),(a)))) #define SROUND16(x,a) (celt_mips--,EXTRACT16(SATURATE(PSHR32(x,a), 32767))); #define HALF16(x) (SHR16(x,1)) #define HALF32(x) (SHR32(x,1)) #define ADD16(a, b) ADD16_(a, b, __FILE__, __LINE__) static OPUS_INLINE short ADD16_(int a, int b, char *file, int line) { int res; if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) { fprintf (stderr, "ADD16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } res = a+b; if (!VERIFY_SHORT(res)) { fprintf (stderr, "ADD16: output is not short: %d+%d=%d in %s: line %d\n", a,b,res, file, line); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } celt_mips++; return res; } #define SUB16(a, b) SUB16_(a, b, __FILE__, __LINE__) static OPUS_INLINE short SUB16_(int a, int b, char *file, int line) { int res; if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) { fprintf (stderr, "SUB16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } res = a-b; if (!VERIFY_SHORT(res)) { fprintf (stderr, "SUB16: output is not short: %d in %s: line %d\n", res, file, line); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } celt_mips++; return res; } #define ADD32(a, b) ADD32_(a, b, __FILE__, __LINE__) static OPUS_INLINE int ADD32_(opus_int64 a, opus_int64 b, char *file, int line) { opus_int64 res; if (!VERIFY_INT(a) || !VERIFY_INT(b)) { fprintf (stderr, "ADD32: inputs are not int: %d %d in %s: line %d\n", (int)a, (int)b, file, line); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } res = a+b; if (!VERIFY_INT(res)) { fprintf (stderr, "ADD32: output is not int: %d in %s: line %d\n", (int)res, file, line); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } celt_mips+=2; return res; } #define SUB32(a, b) SUB32_(a, b, __FILE__, __LINE__) static OPUS_INLINE int SUB32_(opus_int64 a, opus_int64 b, char *file, int line) { opus_int64 res; if (!VERIFY_INT(a) || !VERIFY_INT(b)) { fprintf (stderr, "SUB32: inputs are not int: %d %d in %s: line %d\n", (int)a, (int)b, file, line); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } res = a-b; if (!VERIFY_INT(res)) { fprintf (stderr, "SUB32: output is not int: %d in %s: line %d\n", (int)res, file, line); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } celt_mips+=2; return res; } #undef UADD32 #define UADD32(a, b) UADD32_(a, b, __FILE__, __LINE__) static OPUS_INLINE unsigned int UADD32_(opus_uint64 a, opus_uint64 b, char *file, int line) { opus_uint64 res; if (!VERIFY_UINT(a) || !VERIFY_UINT(b)) { fprintf (stderr, "UADD32: inputs are not uint32: %llu %llu in %s: line %d\n", a, b, file, line); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } res = a+b; if (!VERIFY_UINT(res)) { fprintf (stderr, "UADD32: output is not uint32: %llu in %s: line %d\n", res, file, line); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } celt_mips+=2; return res; } #undef USUB32 #define USUB32(a, b) USUB32_(a, b, __FILE__, __LINE__) static OPUS_INLINE unsigned int USUB32_(opus_uint64 a, opus_uint64 b, char *file, int line) { opus_uint64 res; if (!VERIFY_UINT(a) || !VERIFY_UINT(b)) { fprintf (stderr, "USUB32: inputs are not uint32: %llu %llu in %s: line %d\n", a, b, file, line); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } if (a=((opus_val32)(1)<<(15+Q))) { fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } res = (((opus_int64)a)*(opus_int64)b) >> Q; if (!VERIFY_INT(res)) { fprintf (stderr, "MULT16_32_Q%d: output is not int: %d*%d=%d in %s: line %d\n", Q, (int)a, (int)b,(int)res, file, line); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } if (Q==15) celt_mips+=3; else celt_mips+=4; return res; } #define MULT16_32_PX(a, b, Q) MULT16_32_PX_(a, b, Q, __FILE__, __LINE__) static OPUS_INLINE int MULT16_32_PX_(int a, opus_int64 b, int Q, char *file, int line) { opus_int64 res; if (!VERIFY_SHORT(a) || !VERIFY_INT(b)) { fprintf (stderr, "MULT16_32_P%d: inputs are not short+int: %d %d in %s: line %d\n\n", Q, (int)a, (int)b, file, line); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } if (ABS32(b)>=((opus_int64)(1)<<(15+Q))) { fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n\n", Q, (int)a, (int)b,file, line); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } res = ((((opus_int64)a)*(opus_int64)b) + (((opus_val32)(1)<>1))>> Q; if (!VERIFY_INT(res)) { fprintf (stderr, "MULT16_32_P%d: output is not int: %d*%d=%d in %s: line %d\n\n", Q, (int)a, (int)b,(int)res, file, line); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } if (Q==15) celt_mips+=4; else celt_mips+=5; return res; } #define MULT16_32_Q15(a,b) MULT16_32_QX(a,b,15) #define MAC16_32_Q15(c,a,b) (celt_mips-=2,ADD32((c),MULT16_32_Q15((a),(b)))) #define MAC16_32_Q16(c,a,b) (celt_mips-=2,ADD32((c),MULT16_32_Q16((a),(b)))) static OPUS_INLINE int SATURATE(int a, int b) { if (a>b) a=b; if (a<-b) a = -b; celt_mips+=3; return a; } static OPUS_INLINE opus_int16 SATURATE16(opus_int32 a) { celt_mips+=3; if (a>32767) return 32767; else if (a<-32768) return -32768; else return a; } static OPUS_INLINE int MULT16_16_Q11_32(int a, int b) { opus_int64 res; if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) { fprintf (stderr, "MULT16_16_Q11: inputs are not short: %d %d\n", a, b); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } res = ((opus_int64)a)*b; res >>= 11; if (!VERIFY_INT(res)) { fprintf (stderr, "MULT16_16_Q11: output is not short: %d*%d=%d\n", (int)a, (int)b, (int)res); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } celt_mips+=3; return res; } static OPUS_INLINE short MULT16_16_Q13(int a, int b) { opus_int64 res; if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) { fprintf (stderr, "MULT16_16_Q13: inputs are not short: %d %d\n", a, b); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } res = ((opus_int64)a)*b; res >>= 13; if (!VERIFY_SHORT(res)) { fprintf (stderr, "MULT16_16_Q13: output is not short: %d*%d=%d\n", a, b, (int)res); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } celt_mips+=3; return res; } static OPUS_INLINE short MULT16_16_Q14(int a, int b) { opus_int64 res; if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) { fprintf (stderr, "MULT16_16_Q14: inputs are not short: %d %d\n", a, b); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } res = ((opus_int64)a)*b; res >>= 14; if (!VERIFY_SHORT(res)) { fprintf (stderr, "MULT16_16_Q14: output is not short: %d\n", (int)res); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } celt_mips+=3; return res; } #define MULT16_16_Q15(a, b) MULT16_16_Q15_(a, b, __FILE__, __LINE__) static OPUS_INLINE short MULT16_16_Q15_(int a, int b, char *file, int line) { opus_int64 res; if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) { fprintf (stderr, "MULT16_16_Q15: inputs are not short: %d %d in %s: line %d\n", a, b, file, line); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } res = ((opus_int64)a)*b; res >>= 15; if (!VERIFY_SHORT(res)) { fprintf (stderr, "MULT16_16_Q15: output is not short: %d in %s: line %d\n", (int)res, file, line); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } celt_mips+=1; return res; } static OPUS_INLINE short MULT16_16_P13(int a, int b) { opus_int64 res; if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) { fprintf (stderr, "MULT16_16_P13: inputs are not short: %d %d\n", a, b); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } res = ((opus_int64)a)*b; res += 4096; if (!VERIFY_INT(res)) { fprintf (stderr, "MULT16_16_P13: overflow: %d*%d=%d\n", a, b, (int)res); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } res >>= 13; if (!VERIFY_SHORT(res)) { fprintf (stderr, "MULT16_16_P13: output is not short: %d*%d=%d\n", a, b, (int)res); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } celt_mips+=4; return res; } static OPUS_INLINE short MULT16_16_P14(int a, int b) { opus_int64 res; if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) { fprintf (stderr, "MULT16_16_P14: inputs are not short: %d %d\n", a, b); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } res = ((opus_int64)a)*b; res += 8192; if (!VERIFY_INT(res)) { fprintf (stderr, "MULT16_16_P14: overflow: %d*%d=%d\n", a, b, (int)res); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } res >>= 14; if (!VERIFY_SHORT(res)) { fprintf (stderr, "MULT16_16_P14: output is not short: %d*%d=%d\n", a, b, (int)res); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } celt_mips+=4; return res; } static OPUS_INLINE short MULT16_16_P15(int a, int b) { opus_int64 res; if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) { fprintf (stderr, "MULT16_16_P15: inputs are not short: %d %d\n", a, b); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } res = ((opus_int64)a)*b; res += 16384; if (!VERIFY_INT(res)) { fprintf (stderr, "MULT16_16_P15: overflow: %d*%d=%d\n", a, b, (int)res); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } res >>= 15; if (!VERIFY_SHORT(res)) { fprintf (stderr, "MULT16_16_P15: output is not short: %d*%d=%d\n", a, b, (int)res); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } celt_mips+=2; return res; } #define DIV32_16(a, b) DIV32_16_(a, b, __FILE__, __LINE__) static OPUS_INLINE int DIV32_16_(opus_int64 a, opus_int64 b, char *file, int line) { opus_int64 res; if (b==0) { fprintf(stderr, "DIV32_16: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif return 0; } if (!VERIFY_INT(a) || !VERIFY_SHORT(b)) { fprintf (stderr, "DIV32_16: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } res = a/b; if (!VERIFY_SHORT(res)) { fprintf (stderr, "DIV32_16: output is not short: %d / %d = %d in %s: line %d\n", (int)a,(int)b,(int)res, file, line); if (res>32767) res = 32767; if (res<-32768) res = -32768; #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } celt_mips+=35; return res; } #define DIV32(a, b) DIV32_(a, b, __FILE__, __LINE__) static OPUS_INLINE int DIV32_(opus_int64 a, opus_int64 b, char *file, int line) { opus_int64 res; if (b==0) { fprintf(stderr, "DIV32: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif return 0; } if (!VERIFY_INT(a) || !VERIFY_INT(b)) { fprintf (stderr, "DIV32: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } res = a/b; if (!VERIFY_INT(res)) { fprintf (stderr, "DIV32: output is not int: %d in %s: line %d\n", (int)res, file, line); #ifdef FIXED_DEBUG_ASSERT celt_assert(0); #endif } celt_mips+=70; return res; } static OPUS_INLINE opus_val16 SIG2WORD16_generic(celt_sig x) { x = PSHR32(x, SIG_SHIFT); x = MAX32(x, -32768); x = MIN32(x, 32767); return EXTRACT16(x); } #define SIG2WORD16(x) (SIG2WORD16_generic(x)) #undef PRINT_MIPS #define PRINT_MIPS(file) do {fprintf (file, "total complexity = %llu MIPS\n", celt_mips);} while (0); #endif jamulus-3.9.1+dfsg/libs/opus/celt/rate.c0000644000175000017500000005167014340334543017132 0ustar vimervimer/* Copyright (c) 2007-2008 CSIRO Copyright (c) 2007-2009 Xiph.Org Foundation Written by Jean-Marc Valin */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "modes.h" #include "cwrs.h" #include "arch.h" #include "os_support.h" #include "entcode.h" #include "rate.h" static const unsigned char LOG2_FRAC_TABLE[24]={ 0, 8,13, 16,19,21,23, 24,26,27,28,29,30,31,32, 32,33,34,34,35,36,36,37,37 }; #ifdef CUSTOM_MODES /*Determines if V(N,K) fits in a 32-bit unsigned integer. N and K are themselves limited to 15 bits.*/ static int fits_in32(int _n, int _k) { static const opus_int16 maxN[15] = { 32767, 32767, 32767, 1476, 283, 109, 60, 40, 29, 24, 20, 18, 16, 14, 13}; static const opus_int16 maxK[15] = { 32767, 32767, 32767, 32767, 1172, 238, 95, 53, 36, 27, 22, 18, 16, 15, 13}; if (_n>=14) { if (_k>=14) return 0; else return _n <= maxN[_k]; } else { return _k <= maxK[_n]; } } void compute_pulse_cache(CELTMode *m, int LM) { int C; int i; int j; int curr=0; int nbEntries=0; int entryN[100], entryK[100], entryI[100]; const opus_int16 *eBands = m->eBands; PulseCache *cache = &m->cache; opus_int16 *cindex; unsigned char *bits; unsigned char *cap; cindex = (opus_int16 *)opus_alloc(sizeof(cache->index[0])*m->nbEBands*(LM+2)); cache->index = cindex; /* Scan for all unique band sizes */ for (i=0;i<=LM+1;i++) { for (j=0;jnbEBands;j++) { int k; int N = (eBands[j+1]-eBands[j])<>1; cindex[i*m->nbEBands+j] = -1; /* Find other bands that have the same size */ for (k=0;k<=i;k++) { int n; for (n=0;nnbEBands && (k!=i || n>1) { cindex[i*m->nbEBands+j] = cindex[k*m->nbEBands+n]; break; } } } if (cache->index[i*m->nbEBands+j] == -1 && N!=0) { int K; entryN[nbEntries] = N; K = 0; while (fits_in32(N,get_pulses(K+1)) && KnbEBands+j] = curr; entryI[nbEntries] = curr; curr += K+1; nbEntries++; } } } bits = (unsigned char *)opus_alloc(sizeof(unsigned char)*curr); cache->bits = bits; cache->size = curr; /* Compute the cache for all unique sizes */ for (i=0;icaps = cap = (unsigned char *)opus_alloc(sizeof(cache->caps[0])*(LM+1)*2*m->nbEBands); for (i=0;i<=LM;i++) { for (C=1;C<=2;C++) { for (j=0;jnbEBands;j++) { int N0; int max_bits; N0 = m->eBands[j+1]-m->eBands[j]; /* N=1 bands only have a sign bit and fine bits. */ if (N0<1 are even, including custom modes.*/ if (N0 > 2) { N0>>=1; LM0--; } /* N0=1 bands can't be split down to N<2. */ else if (N0 <= 1) { LM0=IMIN(i,1); N0<<=LM0; } /* Compute the cost for the lowest-level PVQ of a fully split band. */ pcache = bits + cindex[(LM0+1)*m->nbEBands+j]; max_bits = pcache[pcache[0]]+1; /* Add in the cost of coding regular splits. */ N = N0; for(k=0;klogN[j]+((LM0+k)<>1)-QTHETA_OFFSET; /* The number of qtheta bits we'll allocate if the remainder is to be max_bits. The average measured cost for theta is 0.89701 times qb, approximated here as 459/512. */ num=459*(opus_int32)((2*N-1)*offset+max_bits); den=((opus_int32)(2*N-1)<<9)-459; qb = IMIN((num+(den>>1))/den, 57); celt_assert(qb >= 0); max_bits += qb; N <<= 1; } /* Add in the cost of a stereo split, if necessary. */ if (C==2) { max_bits <<= 1; offset = ((m->logN[j]+(i<>1)-(N==2?QTHETA_OFFSET_TWOPHASE:QTHETA_OFFSET); ndof = 2*N-1-(N==2); /* The average measured cost for theta with the step PDF is 0.95164 times qb, approximated here as 487/512. */ num = (N==2?512:487)*(opus_int32)(max_bits+ndof*offset); den = ((opus_int32)ndof<<9)-(N==2?512:487); qb = IMIN((num+(den>>1))/den, (N==2?64:61)); celt_assert(qb >= 0); max_bits += qb; } /* Add the fine bits we'll use. */ /* Compensate for the extra DoF in stereo */ ndof = C*N + ((C==2 && N>2) ? 1 : 0); /* Offset the number of fine bits by log2(N)/2 + FINE_OFFSET compared to their "fair share" of total/N */ offset = ((m->logN[j] + (i<>1)-FINE_OFFSET; /* N=2 is the only point that doesn't match the curve */ if (N==2) offset += 1<>2; /* The number of fine bits we'll allocate if the remainder is to be max_bits. */ num = max_bits+ndof*offset; den = (ndof-1)<>1))/den, MAX_FINE_BITS); celt_assert(qb >= 0); max_bits += C*qb<eBands[j+1]-m->eBands[j])<= 0); celt_assert(max_bits < 256); *cap++ = (unsigned char)max_bits; } } } } #endif /* CUSTOM_MODES */ #define ALLOC_STEPS 6 static OPUS_INLINE int interp_bits2pulses(const CELTMode *m, int start, int end, int skip_start, const int *bits1, const int *bits2, const int *thresh, const int *cap, opus_int32 total, opus_int32 *_balance, int skip_rsv, int *intensity, int intensity_rsv, int *dual_stereo, int dual_stereo_rsv, int *bits, int *ebits, int *fine_priority, int C, int LM, ec_ctx *ec, int encode, int prev, int signalBandwidth) { opus_int32 psum; int lo, hi; int i, j; int logM; int stereo; int codedBands=-1; int alloc_floor; opus_int32 left, percoeff; int done; opus_int32 balance; SAVE_STACK; alloc_floor = C<1; logM = LM<>1; psum = 0; done = 0; for (j=end;j-->start;) { int tmp = bits1[j] + (mid*(opus_int32)bits2[j]>>ALLOC_STEPS); if (tmp >= thresh[j] || done) { done = 1; /* Don't allocate more than we can actually use */ psum += IMIN(tmp, cap[j]); } else { if (tmp >= alloc_floor) psum += alloc_floor; } } if (psum > total) hi = mid; else lo = mid; } psum = 0; /*printf ("interp bisection gave %d\n", lo);*/ done = 0; for (j=end;j-->start;) { int tmp = bits1[j] + ((opus_int32)lo*bits2[j]>>ALLOC_STEPS); if (tmp < thresh[j] && !done) { if (tmp >= alloc_floor) tmp = alloc_floor; else tmp = 0; } else done = 1; /* Don't allocate more than we can actually use */ tmp = IMIN(tmp, cap[j]); bits[j] = tmp; psum += tmp; } /* Decide which bands to skip, working backwards from the end. */ for (codedBands=end;;codedBands--) { int band_width; int band_bits; int rem; j = codedBands-1; /* Never skip the first band, nor a band that has been boosted by dynalloc. In the first case, we'd be coding a bit to signal we're going to waste all the other bits. In the second case, we'd be coding a bit to redistribute all the bits we just signaled should be cocentrated in this band. */ if (j<=skip_start) { /* Give the bit we reserved to end skipping back. */ total += skip_rsv; break; } /*Figure out how many left-over bits we would be adding to this band. This can include bits we've stolen back from higher, skipped bands.*/ left = total-psum; percoeff = celt_udiv(left, m->eBands[codedBands]-m->eBands[start]); left -= (m->eBands[codedBands]-m->eBands[start])*percoeff; rem = IMAX(left-(m->eBands[j]-m->eBands[start]),0); band_width = m->eBands[codedBands]-m->eBands[j]; band_bits = (int)(bits[j] + percoeff*band_width + rem); /*Only code a skip decision if we're above the threshold for this band. Otherwise it is force-skipped. This ensures that we have enough bits to code the skip flag.*/ if (band_bits >= IMAX(thresh[j], alloc_floor+(1< 17) depth_threshold = j (depth_threshold*band_width<>4 && j<=signalBandwidth)) #endif { ec_enc_bit_logp(ec, 1, 1); break; } ec_enc_bit_logp(ec, 0, 1); } else if (ec_dec_bit_logp(ec, 1)) { break; } /*We used a bit to skip this band.*/ psum += 1< 0) intensity_rsv = LOG2_FRAC_TABLE[j-start]; psum += intensity_rsv; if (band_bits >= alloc_floor) { /*If we have enough for a fine energy bit per channel, use it.*/ psum += alloc_floor; bits[j] = alloc_floor; } else { /*Otherwise this band gets nothing at all.*/ bits[j] = 0; } } celt_assert(codedBands > start); /* Code the intensity and dual stereo parameters. */ if (intensity_rsv > 0) { if (encode) { *intensity = IMIN(*intensity, codedBands); ec_enc_uint(ec, *intensity-start, codedBands+1-start); } else *intensity = start+ec_dec_uint(ec, codedBands+1-start); } else *intensity = 0; if (*intensity <= start) { total += dual_stereo_rsv; dual_stereo_rsv = 0; } if (dual_stereo_rsv > 0) { if (encode) ec_enc_bit_logp(ec, *dual_stereo, 1); else *dual_stereo = ec_dec_bit_logp(ec, 1); } else *dual_stereo = 0; /* Allocate the remaining bits */ left = total-psum; percoeff = celt_udiv(left, m->eBands[codedBands]-m->eBands[start]); left -= (m->eBands[codedBands]-m->eBands[start])*percoeff; for (j=start;jeBands[j+1]-m->eBands[j])); for (j=start;jeBands[j+1]-m->eBands[j]); bits[j] += tmp; left -= tmp; } /*for (j=0;j= 0); N0 = m->eBands[j+1]-m->eBands[j]; N=N0<1) { excess = MAX32(bit-cap[j],0); bits[j] = bit-excess; /* Compensate for the extra DoF in stereo */ den=(C*N+ ((C==2 && N>2 && !*dual_stereo && j<*intensity) ? 1 : 0)); NClogN = den*(m->logN[j] + logM); /* Offset for the number of fine bits by log2(N)/2 + FINE_OFFSET compared to their "fair share" of total/N */ offset = (NClogN>>1)-den*FINE_OFFSET; /* N=2 is the only point that doesn't match the curve */ if (N==2) offset += den<>2; /* Changing the offset for allocating the second and third fine energy bit */ if (bits[j] + offset < den*2<>2; else if (bits[j] + offset < den*3<>3; /* Divide with rounding */ ebits[j] = IMAX(0, (bits[j] + offset + (den<<(BITRES-1)))); ebits[j] = celt_udiv(ebits[j], den)>>BITRES; /* Make sure not to bust */ if (C*ebits[j] > (bits[j]>>BITRES)) ebits[j] = bits[j] >> stereo >> BITRES; /* More than that is useless because that's about as far as PVQ can go */ ebits[j] = IMIN(ebits[j], MAX_FINE_BITS); /* If we rounded down or capped this band, make it a candidate for the final fine energy pass */ fine_priority[j] = ebits[j]*(den<= bits[j]+offset; /* Remove the allocated fine bits; the rest are assigned to PVQ */ bits[j] -= C*ebits[j]< 0) { int extra_fine; int extra_bits; extra_fine = IMIN(excess>>(stereo+BITRES),MAX_FINE_BITS-ebits[j]); ebits[j] += extra_fine; extra_bits = extra_fine*C<= excess-balance; excess -= extra_bits; } balance = excess; celt_assert(bits[j] >= 0); celt_assert(ebits[j] >= 0); } /* Save any remaining bits over the cap for the rebalancing in quant_all_bands(). */ *_balance = balance; /* The skipped bands use all their bits for fine energy. */ for (;j> stereo >> BITRES; celt_assert(C*ebits[j]<nbEBands; skip_start = start; /* Reserve a bit to signal the end of manually skipped bands. */ skip_rsv = total >= 1<total) intensity_rsv = 0; else { total -= intensity_rsv; dual_stereo_rsv = total>=1<eBands[j+1]-m->eBands[j])<>4); /* Tilt of the allocation curve */ trim_offset[j] = C*(m->eBands[j+1]-m->eBands[j])*(alloc_trim-5-LM)*(end-j-1) *(1<<(LM+BITRES))>>6; /* Giving less resolution to single-coefficient bands because they get more benefit from having one coarse value per coefficient*/ if ((m->eBands[j+1]-m->eBands[j])<nbAllocVectors - 1; do { int done = 0; int psum = 0; int mid = (lo+hi) >> 1; for (j=end;j-->start;) { int bitsj; int N = m->eBands[j+1]-m->eBands[j]; bitsj = C*N*m->allocVectors[mid*len+j]<>2; if (bitsj > 0) bitsj = IMAX(0, bitsj + trim_offset[j]); bitsj += offsets[j]; if (bitsj >= thresh[j] || done) { done = 1; /* Don't allocate more than we can actually use */ psum += IMIN(bitsj, cap[j]); } else { if (bitsj >= C< total) hi = mid - 1; else lo = mid + 1; /*printf ("lo = %d, hi = %d\n", lo, hi);*/ } while (lo <= hi); hi = lo--; /*printf ("interp between %d and %d\n", lo, hi);*/ for (j=start;jeBands[j+1]-m->eBands[j]; bits1j = C*N*m->allocVectors[lo*len+j]<>2; bits2j = hi>=m->nbAllocVectors ? cap[j] : C*N*m->allocVectors[hi*len+j]<>2; if (bits1j > 0) bits1j = IMAX(0, bits1j + trim_offset[j]); if (bits2j > 0) bits2j = IMAX(0, bits2j + trim_offset[j]); if (lo > 0) bits1j += offsets[j]; bits2j += offsets[j]; if (offsets[j]>0) skip_start = j; bits2j = IMAX(0,bits2j-bits1j); bits1[j] = bits1j; bits2[j] = bits2j; } codedBands = interp_bits2pulses(m, start, end, skip_start, bits1, bits2, thresh, cap, total, balance, skip_rsv, intensity, intensity_rsv, dual_stereo, dual_stereo_rsv, pulses, ebits, fine_priority, C, LM, ec, encode, prev, signalBandwidth); RESTORE_STACK; return codedBands; } jamulus-3.9.1+dfsg/libs/opus/celt/fixed_generic.h0000644000175000017500000001741514340334543020776 0ustar vimervimer/* Copyright (C) 2007-2009 Xiph.Org Foundation Copyright (C) 2003-2008 Jean-Marc Valin Copyright (C) 2007-2008 CSIRO */ /** @file fixed_generic.h @brief Generic fixed-point operations */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef FIXED_GENERIC_H #define FIXED_GENERIC_H /** Multiply a 16-bit signed value by a 16-bit unsigned value. The result is a 32-bit signed value */ #define MULT16_16SU(a,b) ((opus_val32)(opus_val16)(a)*(opus_val32)(opus_uint16)(b)) /** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */ #if OPUS_FAST_INT64 #define MULT16_32_Q16(a,b) ((opus_val32)SHR((opus_int64)((opus_val16)(a))*(b),16)) #else #define MULT16_32_Q16(a,b) ADD32(MULT16_16((a),SHR((b),16)), SHR(MULT16_16SU((a),((b)&0x0000ffff)),16)) #endif /** 16x32 multiplication, followed by a 16-bit shift right (round-to-nearest). Results fits in 32 bits */ #if OPUS_FAST_INT64 #define MULT16_32_P16(a,b) ((opus_val32)PSHR((opus_int64)((opus_val16)(a))*(b),16)) #else #define MULT16_32_P16(a,b) ADD32(MULT16_16((a),SHR((b),16)), PSHR(MULT16_16SU((a),((b)&0x0000ffff)),16)) #endif /** 16x32 multiplication, followed by a 15-bit shift right. Results fits in 32 bits */ #if OPUS_FAST_INT64 #define MULT16_32_Q15(a,b) ((opus_val32)SHR((opus_int64)((opus_val16)(a))*(b),15)) #else #define MULT16_32_Q15(a,b) ADD32(SHL(MULT16_16((a),SHR((b),16)),1), SHR(MULT16_16SU((a),((b)&0x0000ffff)),15)) #endif /** 32x32 multiplication, followed by a 31-bit shift right. Results fits in 32 bits */ #if OPUS_FAST_INT64 #define MULT32_32_Q31(a,b) ((opus_val32)SHR((opus_int64)(a)*(opus_int64)(b),31)) #else #define MULT32_32_Q31(a,b) ADD32(ADD32(SHL(MULT16_16(SHR((a),16),SHR((b),16)),1), SHR(MULT16_16SU(SHR((a),16),((b)&0x0000ffff)),15)), SHR(MULT16_16SU(SHR((b),16),((a)&0x0000ffff)),15)) #endif /** Compile-time conversion of float constant to 16-bit value */ #define QCONST16(x,bits) ((opus_val16)(.5+(x)*(((opus_val32)1)<<(bits)))) /** Compile-time conversion of float constant to 32-bit value */ #define QCONST32(x,bits) ((opus_val32)(.5+(x)*(((opus_val32)1)<<(bits)))) /** Negate a 16-bit value */ #define NEG16(x) (-(x)) /** Negate a 32-bit value */ #define NEG32(x) (-(x)) /** Change a 32-bit value into a 16-bit value. The value is assumed to fit in 16-bit, otherwise the result is undefined */ #define EXTRACT16(x) ((opus_val16)(x)) /** Change a 16-bit value into a 32-bit value */ #define EXTEND32(x) ((opus_val32)(x)) /** Arithmetic shift-right of a 16-bit value */ #define SHR16(a,shift) ((a) >> (shift)) /** Arithmetic shift-left of a 16-bit value */ #define SHL16(a,shift) ((opus_int16)((opus_uint16)(a)<<(shift))) /** Arithmetic shift-right of a 32-bit value */ #define SHR32(a,shift) ((a) >> (shift)) /** Arithmetic shift-left of a 32-bit value */ #define SHL32(a,shift) ((opus_int32)((opus_uint32)(a)<<(shift))) /** 32-bit arithmetic shift right with rounding-to-nearest instead of rounding down */ #define PSHR32(a,shift) (SHR32((a)+((EXTEND32(1)<<((shift))>>1)),shift)) /** 32-bit arithmetic shift right where the argument can be negative */ #define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift))) /** "RAW" macros, should not be used outside of this header file */ #define SHR(a,shift) ((a) >> (shift)) #define SHL(a,shift) SHL32(a,shift) #define PSHR(a,shift) (SHR((a)+((EXTEND32(1)<<((shift))>>1)),shift)) #define SATURATE(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x))) #define SATURATE16(x) (EXTRACT16((x)>32767 ? 32767 : (x)<-32768 ? -32768 : (x))) /** Shift by a and round-to-neareast 32-bit value. Result is a 16-bit value */ #define ROUND16(x,a) (EXTRACT16(PSHR32((x),(a)))) /** Shift by a and round-to-neareast 32-bit value. Result is a saturated 16-bit value */ #define SROUND16(x,a) EXTRACT16(SATURATE(PSHR32(x,a), 32767)); /** Divide by two */ #define HALF16(x) (SHR16(x,1)) #define HALF32(x) (SHR32(x,1)) /** Add two 16-bit values */ #define ADD16(a,b) ((opus_val16)((opus_val16)(a)+(opus_val16)(b))) /** Subtract two 16-bit values */ #define SUB16(a,b) ((opus_val16)(a)-(opus_val16)(b)) /** Add two 32-bit values */ #define ADD32(a,b) ((opus_val32)(a)+(opus_val32)(b)) /** Subtract two 32-bit values */ #define SUB32(a,b) ((opus_val32)(a)-(opus_val32)(b)) /** Add two 32-bit values, ignore any overflows */ #define ADD32_ovflw(a,b) ((opus_val32)((opus_uint32)(a)+(opus_uint32)(b))) /** Subtract two 32-bit values, ignore any overflows */ #define SUB32_ovflw(a,b) ((opus_val32)((opus_uint32)(a)-(opus_uint32)(b))) /* Avoid MSVC warning C4146: unary minus operator applied to unsigned type */ /** Negate 32-bit value, ignore any overflows */ #define NEG32_ovflw(a) ((opus_val32)(0-(opus_uint32)(a))) /** 16x16 multiplication where the result fits in 16 bits */ #define MULT16_16_16(a,b) ((((opus_val16)(a))*((opus_val16)(b)))) /* (opus_val32)(opus_val16) gives TI compiler a hint that it's 16x16->32 multiply */ /** 16x16 multiplication where the result fits in 32 bits */ #define MULT16_16(a,b) (((opus_val32)(opus_val16)(a))*((opus_val32)(opus_val16)(b))) /** 16x16 multiply-add where the result fits in 32 bits */ #define MAC16_16(c,a,b) (ADD32((c),MULT16_16((a),(b)))) /** 16x32 multiply, followed by a 15-bit shift right and 32-bit add. b must fit in 31 bits. Result fits in 32 bits. */ #define MAC16_32_Q15(c,a,b) ADD32((c),ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15))) /** 16x32 multiplication, followed by a 16-bit shift right and 32-bit add. Results fits in 32 bits */ #define MAC16_32_Q16(c,a,b) ADD32((c),ADD32(MULT16_16((a),SHR((b),16)), SHR(MULT16_16SU((a),((b)&0x0000ffff)),16))) #define MULT16_16_Q11_32(a,b) (SHR(MULT16_16((a),(b)),11)) #define MULT16_16_Q11(a,b) (SHR(MULT16_16((a),(b)),11)) #define MULT16_16_Q13(a,b) (SHR(MULT16_16((a),(b)),13)) #define MULT16_16_Q14(a,b) (SHR(MULT16_16((a),(b)),14)) #define MULT16_16_Q15(a,b) (SHR(MULT16_16((a),(b)),15)) #define MULT16_16_P13(a,b) (SHR(ADD32(4096,MULT16_16((a),(b))),13)) #define MULT16_16_P14(a,b) (SHR(ADD32(8192,MULT16_16((a),(b))),14)) #define MULT16_16_P15(a,b) (SHR(ADD32(16384,MULT16_16((a),(b))),15)) /** Divide a 32-bit value by a 16-bit value. Result fits in 16 bits */ #define DIV32_16(a,b) ((opus_val16)(((opus_val32)(a))/((opus_val16)(b)))) /** Divide a 32-bit value by a 32-bit value. Result fits in 32 bits */ #define DIV32(a,b) (((opus_val32)(a))/((opus_val32)(b))) #if defined(MIPSr1_ASM) #include "mips/fixed_generic_mipsr1.h" #endif static OPUS_INLINE opus_val16 SIG2WORD16_generic(celt_sig x) { x = PSHR32(x, SIG_SHIFT); x = MAX32(x, -32768); x = MIN32(x, 32767); return EXTRACT16(x); } #define SIG2WORD16(x) (SIG2WORD16_generic(x)) #endif jamulus-3.9.1+dfsg/libs/opus/celt/entcode.c0000644000175000017500000001310414340334543017606 0ustar vimervimer/* Copyright (c) 2001-2011 Timothy B. Terriberry */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "entcode.h" #include "arch.h" #if !defined(EC_CLZ) /*This is a fallback for systems where we don't know how to access a BSR or CLZ instruction (see ecintrin.h). If you are optimizing Opus on a new platform and it has a native CLZ or BZR (e.g. cell, MIPS, x86, etc) then making it available to Opus will be an easy performance win.*/ int ec_ilog(opus_uint32 _v){ /*On a Pentium M, this branchless version tested as the fastest on 1,000,000,000 random 32-bit integers, edging out a similar version with branches, and a 256-entry LUT version.*/ int ret; int m; ret=!!_v; m=!!(_v&0xFFFF0000)<<4; _v>>=m; ret|=m; m=!!(_v&0xFF00)<<3; _v>>=m; ret|=m; m=!!(_v&0xF0)<<2; _v>>=m; ret|=m; m=!!(_v&0xC)<<1; _v>>=m; ret|=m; ret+=!!(_v&0x2); return ret; } #endif #if 1 /* This is a faster version of ec_tell_frac() that takes advantage of the low (1/8 bit) resolution to use just a linear function followed by a lookup to determine the exact transition thresholds. */ opus_uint32 ec_tell_frac(ec_ctx *_this){ static const unsigned correction[8] = {35733, 38967, 42495, 46340, 50535, 55109, 60097, 65535}; opus_uint32 nbits; opus_uint32 r; int l; unsigned b; nbits=_this->nbits_total<rng); r=_this->rng>>(l-16); b = (r>>12)-8; b += r>correction[b]; l = (l<<3)+b; return nbits-l; } #else opus_uint32 ec_tell_frac(ec_ctx *_this){ opus_uint32 nbits; opus_uint32 r; int l; int i; /*To handle the non-integral number of bits still left in the encoder/decoder state, we compute the worst-case number of bits of val that must be encoded to ensure that the value is inside the range for any possible subsequent bits. The computation here is independent of val itself (the decoder does not even track that value), even though the real number of bits used after ec_enc_done() may be 1 smaller if rng is a power of two and the corresponding trailing bits of val are all zeros. If we did try to track that special case, then coding a value with a probability of 1/(1<nbits_total<rng); r=_this->rng>>(l-16); for(i=BITRES;i-->0;){ int b; r=r*r>>15; b=(int)(r>>16); l=l<<1|b; r>>=b; } return nbits-l; } #endif #ifdef USE_SMALL_DIV_TABLE /* Result of 2^32/(2*i+1), except for i=0. */ const opus_uint32 SMALL_DIV_TABLE[129] = { 0xFFFFFFFF, 0x55555555, 0x33333333, 0x24924924, 0x1C71C71C, 0x1745D174, 0x13B13B13, 0x11111111, 0x0F0F0F0F, 0x0D79435E, 0x0C30C30C, 0x0B21642C, 0x0A3D70A3, 0x097B425E, 0x08D3DCB0, 0x08421084, 0x07C1F07C, 0x07507507, 0x06EB3E45, 0x06906906, 0x063E7063, 0x05F417D0, 0x05B05B05, 0x0572620A, 0x05397829, 0x05050505, 0x04D4873E, 0x04A7904A, 0x047DC11F, 0x0456C797, 0x04325C53, 0x04104104, 0x03F03F03, 0x03D22635, 0x03B5CC0E, 0x039B0AD1, 0x0381C0E0, 0x0369D036, 0x03531DEC, 0x033D91D2, 0x0329161F, 0x03159721, 0x03030303, 0x02F14990, 0x02E05C0B, 0x02D02D02, 0x02C0B02C, 0x02B1DA46, 0x02A3A0FD, 0x0295FAD4, 0x0288DF0C, 0x027C4597, 0x02702702, 0x02647C69, 0x02593F69, 0x024E6A17, 0x0243F6F0, 0x0239E0D5, 0x02302302, 0x0226B902, 0x021D9EAD, 0x0214D021, 0x020C49BA, 0x02040810, 0x01FC07F0, 0x01F44659, 0x01ECC07B, 0x01E573AC, 0x01DE5D6E, 0x01D77B65, 0x01D0CB58, 0x01CA4B30, 0x01C3F8F0, 0x01BDD2B8, 0x01B7D6C3, 0x01B20364, 0x01AC5701, 0x01A6D01A, 0x01A16D3F, 0x019C2D14, 0x01970E4F, 0x01920FB4, 0x018D3018, 0x01886E5F, 0x0183C977, 0x017F405F, 0x017AD220, 0x01767DCE, 0x01724287, 0x016E1F76, 0x016A13CD, 0x01661EC6, 0x01623FA7, 0x015E75BB, 0x015AC056, 0x01571ED3, 0x01539094, 0x01501501, 0x014CAB88, 0x0149539E, 0x01460CBC, 0x0142D662, 0x013FB013, 0x013C995A, 0x013991C2, 0x013698DF, 0x0133AE45, 0x0130D190, 0x012E025C, 0x012B404A, 0x01288B01, 0x0125E227, 0x01234567, 0x0120B470, 0x011E2EF3, 0x011BB4A4, 0x01194538, 0x0116E068, 0x011485F0, 0x0112358E, 0x010FEF01, 0x010DB20A, 0x010B7E6E, 0x010953F3, 0x01073260, 0x0105197F, 0x0103091B, 0x01010101 }; #endif jamulus-3.9.1+dfsg/libs/opus/celt/_kiss_fft_guts.h0000644000175000017500000001357214340334543021214 0ustar vimervimer/*Copyright (c) 2003-2004, Mark Borgerding All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/ #ifndef KISS_FFT_GUTS_H #define KISS_FFT_GUTS_H #define MIN(a,b) ((a)<(b) ? (a):(b)) #define MAX(a,b) ((a)>(b) ? (a):(b)) /* kiss_fft.h defines kiss_fft_scalar as either short or a float type and defines typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */ #include "kiss_fft.h" /* Explanation of macros dealing with complex math: C_MUL(m,a,b) : m = a*b C_FIXDIV( c , div ) : if a fixed point impl., c /= div. noop otherwise C_SUB( res, a,b) : res = a - b C_SUBFROM( res , a) : res -= a C_ADDTO( res , a) : res += a * */ #ifdef FIXED_POINT #include "arch.h" #define SAMP_MAX 2147483647 #define TWID_MAX 32767 #define TRIG_UPSCALE 1 #define SAMP_MIN -SAMP_MAX # define S_MUL(a,b) MULT16_32_Q15(b, a) # define C_MUL(m,a,b) \ do{ (m).r = SUB32_ovflw(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)); \ (m).i = ADD32_ovflw(S_MUL((a).r,(b).i) , S_MUL((a).i,(b).r)); }while(0) # define C_MULC(m,a,b) \ do{ (m).r = ADD32_ovflw(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)); \ (m).i = SUB32_ovflw(S_MUL((a).i,(b).r) , S_MUL((a).r,(b).i)); }while(0) # define C_MULBYSCALAR( c, s ) \ do{ (c).r = S_MUL( (c).r , s ) ;\ (c).i = S_MUL( (c).i , s ) ; }while(0) # define DIVSCALAR(x,k) \ (x) = S_MUL( x, (TWID_MAX-((k)>>1))/(k)+1 ) # define C_FIXDIV(c,div) \ do { DIVSCALAR( (c).r , div); \ DIVSCALAR( (c).i , div); }while (0) #define C_ADD( res, a,b)\ do {(res).r=ADD32_ovflw((a).r,(b).r); (res).i=ADD32_ovflw((a).i,(b).i); \ }while(0) #define C_SUB( res, a,b)\ do {(res).r=SUB32_ovflw((a).r,(b).r); (res).i=SUB32_ovflw((a).i,(b).i); \ }while(0) #define C_ADDTO( res , a)\ do {(res).r = ADD32_ovflw((res).r, (a).r); (res).i = ADD32_ovflw((res).i,(a).i);\ }while(0) #define C_SUBFROM( res , a)\ do {(res).r = ADD32_ovflw((res).r,(a).r); (res).i = SUB32_ovflw((res).i,(a).i); \ }while(0) #if defined(OPUS_ARM_INLINE_ASM) #include "arm/kiss_fft_armv4.h" #endif #if defined(OPUS_ARM_INLINE_EDSP) #include "arm/kiss_fft_armv5e.h" #endif #if defined(MIPSr1_ASM) #include "mips/kiss_fft_mipsr1.h" #endif #else /* not FIXED_POINT*/ # define S_MUL(a,b) ( (a)*(b) ) #define C_MUL(m,a,b) \ do{ (m).r = (a).r*(b).r - (a).i*(b).i;\ (m).i = (a).r*(b).i + (a).i*(b).r; }while(0) #define C_MULC(m,a,b) \ do{ (m).r = (a).r*(b).r + (a).i*(b).i;\ (m).i = (a).i*(b).r - (a).r*(b).i; }while(0) #define C_MUL4(m,a,b) C_MUL(m,a,b) # define C_FIXDIV(c,div) /* NOOP */ # define C_MULBYSCALAR( c, s ) \ do{ (c).r *= (s);\ (c).i *= (s); }while(0) #endif #ifndef CHECK_OVERFLOW_OP # define CHECK_OVERFLOW_OP(a,op,b) /* noop */ #endif #ifndef C_ADD #define C_ADD( res, a,b)\ do { \ CHECK_OVERFLOW_OP((a).r,+,(b).r)\ CHECK_OVERFLOW_OP((a).i,+,(b).i)\ (res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \ }while(0) #define C_SUB( res, a,b)\ do { \ CHECK_OVERFLOW_OP((a).r,-,(b).r)\ CHECK_OVERFLOW_OP((a).i,-,(b).i)\ (res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \ }while(0) #define C_ADDTO( res , a)\ do { \ CHECK_OVERFLOW_OP((res).r,+,(a).r)\ CHECK_OVERFLOW_OP((res).i,+,(a).i)\ (res).r += (a).r; (res).i += (a).i;\ }while(0) #define C_SUBFROM( res , a)\ do {\ CHECK_OVERFLOW_OP((res).r,-,(a).r)\ CHECK_OVERFLOW_OP((res).i,-,(a).i)\ (res).r -= (a).r; (res).i -= (a).i; \ }while(0) #endif /* C_ADD defined */ #ifdef FIXED_POINT /*# define KISS_FFT_COS(phase) TRIG_UPSCALE*floor(MIN(32767,MAX(-32767,.5+32768 * cos (phase)))) # define KISS_FFT_SIN(phase) TRIG_UPSCALE*floor(MIN(32767,MAX(-32767,.5+32768 * sin (phase))))*/ # define KISS_FFT_COS(phase) floor(.5+TWID_MAX*cos (phase)) # define KISS_FFT_SIN(phase) floor(.5+TWID_MAX*sin (phase)) # define HALF_OF(x) ((x)>>1) #elif defined(USE_SIMD) # define KISS_FFT_COS(phase) _mm_set1_ps( cos(phase) ) # define KISS_FFT_SIN(phase) _mm_set1_ps( sin(phase) ) # define HALF_OF(x) ((x)*_mm_set1_ps(.5f)) #else # define KISS_FFT_COS(phase) (kiss_fft_scalar) cos(phase) # define KISS_FFT_SIN(phase) (kiss_fft_scalar) sin(phase) # define HALF_OF(x) ((x)*.5f) #endif #define kf_cexp(x,phase) \ do{ \ (x)->r = KISS_FFT_COS(phase);\ (x)->i = KISS_FFT_SIN(phase);\ }while(0) #define kf_cexp2(x,phase) \ do{ \ (x)->r = TRIG_UPSCALE*celt_cos_norm((phase));\ (x)->i = TRIG_UPSCALE*celt_cos_norm((phase)-32768);\ }while(0) #endif /* KISS_FFT_GUTS_H */ jamulus-3.9.1+dfsg/libs/opus/depcomp0000755000175000017500000005601714340334543016461 0ustar vimervimer#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2016-01-11.22; # UTC # Copyright (C) 1999-2017 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by 'PROGRAMS ARGS'. object Object file output by 'PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputting dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac # Get the directory component of the given path, and save it in the # global variables '$dir'. Note that this directory component will # be either empty or ending with a '/' character. This is deliberate. set_dir_from () { case $1 in */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; *) dir=;; esac } # Get the suffix-stripped basename of the given path, and save it the # global variable '$base'. set_base_from () { base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` } # If no dependency file was actually created by the compiler invocation, # we still have to create a dummy depfile, to avoid errors with the # Makefile "include basename.Plo" scheme. make_dummy_depfile () { echo "#dummy" > "$depfile" } # Factor out some common post-processing of the generated depfile. # Requires the auxiliary global variable '$tmpdepfile' to be set. aix_post_process_depfile () { # If the compiler actually managed to produce a dependency file, # post-process it. if test -f "$tmpdepfile"; then # Each line is of the form 'foo.o: dependency.h'. # Do two passes, one to just change these to # $object: dependency.h # and one to simply output # dependency.h: # which is needed to avoid the deleted-header problem. { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" } > "$depfile" rm -f "$tmpdepfile" else make_dummy_depfile fi } # A tabulation character. tab=' ' # A newline character. nl=' ' # Character ranges might be problematic outside the C locale. # These definitions help. upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ lower=abcdefghijklmnopqrstuvwxyz digits=0123456789 alpha=${upper}${lower} if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Avoid interferences from the environment. gccflag= dashmflag= # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvisualcpp fi if test "$depmode" = msvc7msys; then # This is just like msvc7 but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvc7 fi if test "$depmode" = xlc; then # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. gccflag=-qmakedep=gcc,-MF depmode=gcc fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. ## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. ## (see the conditional assignment to $gccflag above). ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). Also, it might not be ## supported by the other compilers which use the 'gcc' depmode. ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The second -e expression handles DOS-style file names with drive # letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the "deleted header file" problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. ## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as ## well. hp depmode also adds that space, but also prefixes the VPATH ## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ | tr "$nl" ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" ;; xlc) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done aix_post_process_depfile ;; tcc) # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 # FIXME: That version still under development at the moment of writing. # Make that this statement remains true also for stable, released # versions. # It will wrap lines (doesn't matter whether long or short) with a # trailing '\', as in: # # foo.o : \ # foo.c \ # foo.h \ # # It will put a trailing '\' even on the last line, and will use leading # spaces rather than leading tabs (at least since its commit 0394caf7 # "Emit spaces for -MD"). "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. # We have to change lines of the first kind to '$object: \'. sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" # And for each line of the second kind, we have to emit a 'dep.h:' # dummy dependency, to avoid the deleted-header problem. sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; ## The order of this option in the case statement is important, since the ## shell code in configure will try each of these formats in the order ## listed in this file. A plain '-MD' option would be understood by many ## compilers, so we must ensure this comes after the gcc and icc options. pgcc) # Portland's C compiler understands '-MD'. # Will always output deps to 'file.d' where file is the root name of the # source file under compilation, even if file resides in a subdirectory. # The object file name does not affect the name of the '.d' file. # pgcc 10.2 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using '\' : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... set_dir_from "$object" # Use the source, not the object, to determine the base name, since # that's sadly what pgcc will do too. set_base_from "$source" tmpdepfile=$base.d # For projects that build the same source file twice into different object # files, the pgcc approach of using the *source* file root name can cause # problems in parallel builds. Use a locking strategy to avoid stomping on # the same $tmpdepfile. lockdir=$base.d-lock trap " echo '$0: caught signal, cleaning up...' >&2 rmdir '$lockdir' exit 1 " 1 2 13 15 numtries=100 i=$numtries while test $i -gt 0; do # mkdir is a portable test-and-set. if mkdir "$lockdir" 2>/dev/null; then # This process acquired the lock. "$@" -MD stat=$? # Release the lock. rmdir "$lockdir" break else # If the lock is being held by a different process, wait # until the winning process is done or we timeout. while test -d "$lockdir" && test $i -gt 0; do sleep 1 i=`expr $i - 1` done fi i=`expr $i - 1` done trap - 1 2 13 15 if test $i -le 0; then echo "$0: failed to acquire lock after $numtries attempts" >&2 echo "$0: check lockdir '$lockdir'" >&2 exit 1 fi if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" # Add 'dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in 'foo.d' instead, so we check for that too. # Subdirectories are respected. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then # Libtool generates 2 separate objects for the 2 libraries. These # two compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir$base.o.d # libtool 1.5 tmpdepfile2=$dir.libs/$base.o.d # Likewise. tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d "$@" -MD fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done # Same post-processing that is required for AIX mode. aix_post_process_depfile ;; msvc7) if test "$libtool" = yes; then showIncludes=-Wc,-showIncludes else showIncludes=-showIncludes fi "$@" $showIncludes > "$tmpdepfile" stat=$? grep -v '^Note: including file: ' "$tmpdepfile" if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The first sed program below extracts the file names and escapes # backslashes for cygpath. The second sed program outputs the file # name when reading, but also accumulates all include files in the # hold buffer in order to output them again at the end. This only # works with sed implementations that can handle large buffers. sed < "$tmpdepfile" -n ' /^Note: including file: *\(.*\)/ { s//\1/ s/\\/\\\\/g p }' | $cygpath_u | sort -u | sed -n ' s/ /\\ /g s/\(.*\)/'"$tab"'\1 \\/p s/.\(.*\) \\/\1:/ H $ { s/.*/'"$tab"'/ G p }' >> "$depfile" echo >> "$depfile" # make sure the fragment doesn't end with a backslash rm -f "$tmpdepfile" ;; msvc7msys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for ':' # in the target name. This is to cope with DOS-style filenames: # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this sed invocation # correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" # makedepend may prepend the VPATH from the source file name to the object. # No need to regex-escape $object, excess matching of '.' is harmless. sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process the last invocation # correctly. Breaking it into two sed invocations is a workaround. sed '1,2d' "$tmpdepfile" \ | tr ' ' "$nl" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E \ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" echo "$tab" >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: jamulus-3.9.1+dfsg/libs/opus/COPYING0000644000175000017500000000361014340334543016126 0ustar vimervimerCopyright 2001-2011 Xiph.Org, Skype Limited, Octasic, Jean-Marc Valin, Timothy B. Terriberry, CSIRO, Gregory Maxwell, Mark Borgerding, Erik de Castro Lopo Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Opus is subject to the royalty-free patent licenses which are specified at: Xiph.Org Foundation: https://datatracker.ietf.org/ipr/1524/ Microsoft Corporation: https://datatracker.ietf.org/ipr/1914/ Broadcom Corporation: https://datatracker.ietf.org/ipr/1526/ jamulus-3.9.1+dfsg/libs/opus/include/0000755000175000017500000000000014340334543016516 5ustar vimervimerjamulus-3.9.1+dfsg/libs/opus/include/opus.h0000644000175000017500000013645714340334543017675 0ustar vimervimer/* Copyright (c) 2010-2011 Xiph.Org Foundation, Skype Limited Written by Jean-Marc Valin and Koen Vos */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @file opus.h * @brief Opus reference implementation API */ #ifndef OPUS_H #define OPUS_H #include "opus_types.h" #include "opus_defines.h" #ifdef __cplusplus extern "C" { #endif /** * @mainpage Opus * * The Opus codec is designed for interactive speech and audio transmission over the Internet. * It is designed by the IETF Codec Working Group and incorporates technology from * Skype's SILK codec and Xiph.Org's CELT codec. * * The Opus codec is designed to handle a wide range of interactive audio applications, * including Voice over IP, videoconferencing, in-game chat, and even remote live music * performances. It can scale from low bit-rate narrowband speech to very high quality * stereo music. Its main features are: * @li Sampling rates from 8 to 48 kHz * @li Bit-rates from 6 kb/s to 510 kb/s * @li Support for both constant bit-rate (CBR) and variable bit-rate (VBR) * @li Audio bandwidth from narrowband to full-band * @li Support for speech and music * @li Support for mono and stereo * @li Support for multichannel (up to 255 channels) * @li Frame sizes from 2.5 ms to 60 ms * @li Good loss robustness and packet loss concealment (PLC) * @li Floating point and fixed-point implementation * * Documentation sections: * @li @ref opus_encoder * @li @ref opus_decoder * @li @ref opus_repacketizer * @li @ref opus_multistream * @li @ref opus_libinfo * @li @ref opus_custom */ /** @defgroup opus_encoder Opus Encoder * @{ * * @brief This page describes the process and functions used to encode Opus. * * Since Opus is a stateful codec, the encoding process starts with creating an encoder * state. This can be done with: * * @code * int error; * OpusEncoder *enc; * enc = opus_encoder_create(Fs, channels, application, &error); * @endcode * * From this point, @c enc can be used for encoding an audio stream. An encoder state * @b must @b not be used for more than one stream at the same time. Similarly, the encoder * state @b must @b not be re-initialized for each frame. * * While opus_encoder_create() allocates memory for the state, it's also possible * to initialize pre-allocated memory: * * @code * int size; * int error; * OpusEncoder *enc; * size = opus_encoder_get_size(channels); * enc = malloc(size); * error = opus_encoder_init(enc, Fs, channels, application); * @endcode * * where opus_encoder_get_size() returns the required size for the encoder state. Note that * future versions of this code may change the size, so no assumptions should be made about it. * * The encoder state is always continuous in memory and only a shallow copy is sufficient * to copy it (e.g. memcpy()) * * It is possible to change some of the encoder's settings using the opus_encoder_ctl() * interface. All these settings already default to the recommended value, so they should * only be changed when necessary. The most common settings one may want to change are: * * @code * opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate)); * opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complexity)); * opus_encoder_ctl(enc, OPUS_SET_SIGNAL(signal_type)); * @endcode * * where * * @arg bitrate is in bits per second (b/s) * @arg complexity is a value from 1 to 10, where 1 is the lowest complexity and 10 is the highest * @arg signal_type is either OPUS_AUTO (default), OPUS_SIGNAL_VOICE, or OPUS_SIGNAL_MUSIC * * See @ref opus_encoderctls and @ref opus_genericctls for a complete list of parameters that can be set or queried. Most parameters can be set or changed at any time during a stream. * * To encode a frame, opus_encode() or opus_encode_float() must be called with exactly one frame (2.5, 5, 10, 20, 40 or 60 ms) of audio data: * @code * len = opus_encode(enc, audio_frame, frame_size, packet, max_packet); * @endcode * * where *

* * opus_encode() and opus_encode_float() return the number of bytes actually written to the packet. * The return value can be negative, which indicates that an error has occurred. If the return value * is 2 bytes or less, then the packet does not need to be transmitted (DTX). * * Once the encoder state if no longer needed, it can be destroyed with * * @code * opus_encoder_destroy(enc); * @endcode * * If the encoder was created with opus_encoder_init() rather than opus_encoder_create(), * then no action is required aside from potentially freeing the memory that was manually * allocated for it (calling free(enc) for the example above) * */ /** Opus encoder state. * This contains the complete state of an Opus encoder. * It is position independent and can be freely copied. * @see opus_encoder_create,opus_encoder_init */ typedef struct OpusEncoder OpusEncoder; /** Gets the size of an OpusEncoder structure. * @param[in] channels int: Number of channels. * This must be 1 or 2. * @returns The size in bytes. */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_encoder_get_size(int channels); /** */ /** Allocates and initializes an encoder state. * There are three coding modes: * * @ref OPUS_APPLICATION_VOIP gives best quality at a given bitrate for voice * signals. It enhances the input signal by high-pass filtering and * emphasizing formants and harmonics. Optionally it includes in-band * forward error correction to protect against packet loss. Use this * mode for typical VoIP applications. Because of the enhancement, * even at high bitrates the output may sound different from the input. * * @ref OPUS_APPLICATION_AUDIO gives best quality at a given bitrate for most * non-voice signals like music. Use this mode for music and mixed * (music/voice) content, broadcast, and applications requiring less * than 15 ms of coding delay. * * @ref OPUS_APPLICATION_RESTRICTED_LOWDELAY configures low-delay mode that * disables the speech-optimized mode in exchange for slightly reduced delay. * This mode can only be set on an newly initialized or freshly reset encoder * because it changes the codec delay. * * This is useful when the caller knows that the speech-optimized modes will not be needed (use with caution). * @param [in] Fs opus_int32: Sampling rate of input signal (Hz) * This must be one of 8000, 12000, 16000, * 24000, or 48000. * @param [in] channels int: Number of channels (1 or 2) in input signal * @param [in] application int: Coding mode (@ref OPUS_APPLICATION_VOIP/@ref OPUS_APPLICATION_AUDIO/@ref OPUS_APPLICATION_RESTRICTED_LOWDELAY) * @param [out] error int*: @ref opus_errorcodes * @note Regardless of the sampling rate and number channels selected, the Opus encoder * can switch to a lower audio bandwidth or number of channels if the bitrate * selected is too low. This also means that it is safe to always use 48 kHz stereo input * and let the encoder optimize the encoding. */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusEncoder *opus_encoder_create( opus_int32 Fs, int channels, int application, int *error ); /** Initializes a previously allocated encoder state * The memory pointed to by st must be at least the size returned by opus_encoder_get_size(). * This is intended for applications which use their own allocator instead of malloc. * @see opus_encoder_create(),opus_encoder_get_size() * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. * @param [in] st OpusEncoder*: Encoder state * @param [in] Fs opus_int32: Sampling rate of input signal (Hz) * This must be one of 8000, 12000, 16000, * 24000, or 48000. * @param [in] channels int: Number of channels (1 or 2) in input signal * @param [in] application int: Coding mode (OPUS_APPLICATION_VOIP/OPUS_APPLICATION_AUDIO/OPUS_APPLICATION_RESTRICTED_LOWDELAY) * @retval #OPUS_OK Success or @ref opus_errorcodes */ OPUS_EXPORT int opus_encoder_init( OpusEncoder *st, opus_int32 Fs, int channels, int application ) OPUS_ARG_NONNULL(1); /** Encodes an Opus frame. * @param [in] st OpusEncoder*: Encoder state * @param [in] pcm opus_int16*: Input signal (interleaved if 2 channels). length is frame_size*channels*sizeof(opus_int16) * @param [in] frame_size int: Number of samples per channel in the * input signal. * This must be an Opus frame size for * the encoder's sampling rate. * For example, at 48 kHz the permitted * values are 120, 240, 480, 960, 1920, * and 2880. * Passing in a duration of less than * 10 ms (480 samples at 48 kHz) will * prevent the encoder from using the LPC * or hybrid modes. * @param [out] data unsigned char*: Output payload. * This must contain storage for at * least \a max_data_bytes. * @param [in] max_data_bytes opus_int32: Size of the allocated * memory for the output * payload. This may be * used to impose an upper limit on * the instant bitrate, but should * not be used as the only bitrate * control. Use #OPUS_SET_BITRATE to * control the bitrate. * @returns The length of the encoded packet (in bytes) on success or a * negative error code (see @ref opus_errorcodes) on failure. */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode( OpusEncoder *st, const opus_int16 *pcm, int frame_size, unsigned char *data, opus_int32 max_data_bytes ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); /** Encodes an Opus frame from floating point input. * @param [in] st OpusEncoder*: Encoder state * @param [in] pcm float*: Input in float format (interleaved if 2 channels), with a normal range of +/-1.0. * Samples with a range beyond +/-1.0 are supported but will * be clipped by decoders using the integer API and should * only be used if it is known that the far end supports * extended dynamic range. * length is frame_size*channels*sizeof(float) * @param [in] frame_size int: Number of samples per channel in the * input signal. * This must be an Opus frame size for * the encoder's sampling rate. * For example, at 48 kHz the permitted * values are 120, 240, 480, 960, 1920, * and 2880. * Passing in a duration of less than * 10 ms (480 samples at 48 kHz) will * prevent the encoder from using the LPC * or hybrid modes. * @param [out] data unsigned char*: Output payload. * This must contain storage for at * least \a max_data_bytes. * @param [in] max_data_bytes opus_int32: Size of the allocated * memory for the output * payload. This may be * used to impose an upper limit on * the instant bitrate, but should * not be used as the only bitrate * control. Use #OPUS_SET_BITRATE to * control the bitrate. * @returns The length of the encoded packet (in bytes) on success or a * negative error code (see @ref opus_errorcodes) on failure. */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode_float( OpusEncoder *st, const float *pcm, int frame_size, unsigned char *data, opus_int32 max_data_bytes ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); /** Frees an OpusEncoder allocated by opus_encoder_create(). * @param[in] st OpusEncoder*: State to be freed. */ OPUS_EXPORT void opus_encoder_destroy(OpusEncoder *st); /** Perform a CTL function on an Opus encoder. * * Generally the request and subsequent arguments are generated * by a convenience macro. * @param st OpusEncoder*: Encoder state. * @param request This and all remaining parameters should be replaced by one * of the convenience macros in @ref opus_genericctls or * @ref opus_encoderctls. * @see opus_genericctls * @see opus_encoderctls */ OPUS_EXPORT int opus_encoder_ctl(OpusEncoder *st, int request, ...) OPUS_ARG_NONNULL(1); /**@}*/ /** @defgroup opus_decoder Opus Decoder * @{ * * @brief This page describes the process and functions used to decode Opus. * * The decoding process also starts with creating a decoder * state. This can be done with: * @code * int error; * OpusDecoder *dec; * dec = opus_decoder_create(Fs, channels, &error); * @endcode * where * @li Fs is the sampling rate and must be 8000, 12000, 16000, 24000, or 48000 * @li channels is the number of channels (1 or 2) * @li error will hold the error code in case of failure (or #OPUS_OK on success) * @li the return value is a newly created decoder state to be used for decoding * * While opus_decoder_create() allocates memory for the state, it's also possible * to initialize pre-allocated memory: * @code * int size; * int error; * OpusDecoder *dec; * size = opus_decoder_get_size(channels); * dec = malloc(size); * error = opus_decoder_init(dec, Fs, channels); * @endcode * where opus_decoder_get_size() returns the required size for the decoder state. Note that * future versions of this code may change the size, so no assumptions should be made about it. * * The decoder state is always continuous in memory and only a shallow copy is sufficient * to copy it (e.g. memcpy()) * * To decode a frame, opus_decode() or opus_decode_float() must be called with a packet of compressed audio data: * @code * frame_size = opus_decode(dec, packet, len, decoded, max_size, 0); * @endcode * where * * @li packet is the byte array containing the compressed data * @li len is the exact number of bytes contained in the packet * @li decoded is the decoded audio data in opus_int16 (or float for opus_decode_float()) * @li max_size is the max duration of the frame in samples (per channel) that can fit into the decoded_frame array * * opus_decode() and opus_decode_float() return the number of samples (per channel) decoded from the packet. * If that value is negative, then an error has occurred. This can occur if the packet is corrupted or if the audio * buffer is too small to hold the decoded audio. * * Opus is a stateful codec with overlapping blocks and as a result Opus * packets are not coded independently of each other. Packets must be * passed into the decoder serially and in the correct order for a correct * decode. Lost packets can be replaced with loss concealment by calling * the decoder with a null pointer and zero length for the missing packet. * * A single codec state may only be accessed from a single thread at * a time and any required locking must be performed by the caller. Separate * streams must be decoded with separate decoder states and can be decoded * in parallel unless the library was compiled with NONTHREADSAFE_PSEUDOSTACK * defined. * */ /** Opus decoder state. * This contains the complete state of an Opus decoder. * It is position independent and can be freely copied. * @see opus_decoder_create,opus_decoder_init */ typedef struct OpusDecoder OpusDecoder; /** Gets the size of an OpusDecoder structure. * @param [in] channels int: Number of channels. * This must be 1 or 2. * @returns The size in bytes. */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decoder_get_size(int channels); /** Allocates and initializes a decoder state. * @param [in] Fs opus_int32: Sample rate to decode at (Hz). * This must be one of 8000, 12000, 16000, * 24000, or 48000. * @param [in] channels int: Number of channels (1 or 2) to decode * @param [out] error int*: #OPUS_OK Success or @ref opus_errorcodes * * Internally Opus stores data at 48000 Hz, so that should be the default * value for Fs. However, the decoder can efficiently decode to buffers * at 8, 12, 16, and 24 kHz so if for some reason the caller cannot use * data at the full sample rate, or knows the compressed data doesn't * use the full frequency range, it can request decoding at a reduced * rate. Likewise, the decoder is capable of filling in either mono or * interleaved stereo pcm buffers, at the caller's request. */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusDecoder *opus_decoder_create( opus_int32 Fs, int channels, int *error ); /** Initializes a previously allocated decoder state. * The state must be at least the size returned by opus_decoder_get_size(). * This is intended for applications which use their own allocator instead of malloc. @see opus_decoder_create,opus_decoder_get_size * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. * @param [in] st OpusDecoder*: Decoder state. * @param [in] Fs opus_int32: Sampling rate to decode to (Hz). * This must be one of 8000, 12000, 16000, * 24000, or 48000. * @param [in] channels int: Number of channels (1 or 2) to decode * @retval #OPUS_OK Success or @ref opus_errorcodes */ OPUS_EXPORT int opus_decoder_init( OpusDecoder *st, opus_int32 Fs, int channels ) OPUS_ARG_NONNULL(1); /** Decode an Opus packet. * @param [in] st OpusDecoder*: Decoder state * @param [in] data char*: Input payload. Use a NULL pointer to indicate packet loss * @param [in] len opus_int32: Number of bytes in payload* * @param [out] pcm opus_int16*: Output signal (interleaved if 2 channels). length * is frame_size*channels*sizeof(opus_int16) * @param [in] frame_size Number of samples per channel of available space in \a pcm. * If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will * not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1), * then frame_size needs to be exactly the duration of audio that is missing, otherwise the * decoder will not be in the optimal state to decode the next incoming packet. For the PLC and * FEC cases, frame_size must be a multiple of 2.5 ms. * @param [in] decode_fec int: Flag (0 or 1) to request that any in-band forward error correction data be * decoded. If no such data is available, the frame is decoded as if it were lost. * @returns Number of decoded samples or @ref opus_errorcodes */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode( OpusDecoder *st, const unsigned char *data, opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); /** Decode an Opus packet with floating point output. * @param [in] st OpusDecoder*: Decoder state * @param [in] data char*: Input payload. Use a NULL pointer to indicate packet loss * @param [in] len opus_int32: Number of bytes in payload * @param [out] pcm float*: Output signal (interleaved if 2 channels). length * is frame_size*channels*sizeof(float) * @param [in] frame_size Number of samples per channel of available space in \a pcm. * If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will * not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1), * then frame_size needs to be exactly the duration of audio that is missing, otherwise the * decoder will not be in the optimal state to decode the next incoming packet. For the PLC and * FEC cases, frame_size must be a multiple of 2.5 ms. * @param [in] decode_fec int: Flag (0 or 1) to request that any in-band forward error correction data be * decoded. If no such data is available the frame is decoded as if it were lost. * @returns Number of decoded samples or @ref opus_errorcodes */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode_float( OpusDecoder *st, const unsigned char *data, opus_int32 len, float *pcm, int frame_size, int decode_fec ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); /** Perform a CTL function on an Opus decoder. * * Generally the request and subsequent arguments are generated * by a convenience macro. * @param st OpusDecoder*: Decoder state. * @param request This and all remaining parameters should be replaced by one * of the convenience macros in @ref opus_genericctls or * @ref opus_decoderctls. * @see opus_genericctls * @see opus_decoderctls */ OPUS_EXPORT int opus_decoder_ctl(OpusDecoder *st, int request, ...) OPUS_ARG_NONNULL(1); /** Frees an OpusDecoder allocated by opus_decoder_create(). * @param[in] st OpusDecoder*: State to be freed. */ OPUS_EXPORT void opus_decoder_destroy(OpusDecoder *st); /** Parse an opus packet into one or more frames. * Opus_decode will perform this operation internally so most applications do * not need to use this function. * This function does not copy the frames, the returned pointers are pointers into * the input packet. * @param [in] data char*: Opus packet to be parsed * @param [in] len opus_int32: size of data * @param [out] out_toc char*: TOC pointer * @param [out] frames char*[48] encapsulated frames * @param [out] size opus_int16[48] sizes of the encapsulated frames * @param [out] payload_offset int*: returns the position of the payload within the packet (in bytes) * @returns number of frames */ OPUS_EXPORT int opus_packet_parse( const unsigned char *data, opus_int32 len, unsigned char *out_toc, const unsigned char *frames[48], opus_int16 size[48], int *payload_offset ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(5); /** Gets the bandwidth of an Opus packet. * @param [in] data char*: Opus packet * @retval OPUS_BANDWIDTH_NARROWBAND Narrowband (4kHz bandpass) * @retval OPUS_BANDWIDTH_MEDIUMBAND Mediumband (6kHz bandpass) * @retval OPUS_BANDWIDTH_WIDEBAND Wideband (8kHz bandpass) * @retval OPUS_BANDWIDTH_SUPERWIDEBAND Superwideband (12kHz bandpass) * @retval OPUS_BANDWIDTH_FULLBAND Fullband (20kHz bandpass) * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_bandwidth(const unsigned char *data) OPUS_ARG_NONNULL(1); /** Gets the number of samples per frame from an Opus packet. * @param [in] data char*: Opus packet. * This must contain at least one byte of * data. * @param [in] Fs opus_int32: Sampling rate in Hz. * This must be a multiple of 400, or * inaccurate results will be returned. * @returns Number of samples per frame. */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_samples_per_frame(const unsigned char *data, opus_int32 Fs) OPUS_ARG_NONNULL(1); /** Gets the number of channels from an Opus packet. * @param [in] data char*: Opus packet * @returns Number of channels * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_channels(const unsigned char *data) OPUS_ARG_NONNULL(1); /** Gets the number of frames in an Opus packet. * @param [in] packet char*: Opus packet * @param [in] len opus_int32: Length of packet * @returns Number of frames * @retval OPUS_BAD_ARG Insufficient data was passed to the function * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_frames(const unsigned char packet[], opus_int32 len) OPUS_ARG_NONNULL(1); /** Gets the number of samples of an Opus packet. * @param [in] packet char*: Opus packet * @param [in] len opus_int32: Length of packet * @param [in] Fs opus_int32: Sampling rate in Hz. * This must be a multiple of 400, or * inaccurate results will be returned. * @returns Number of samples * @retval OPUS_BAD_ARG Insufficient data was passed to the function * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_samples(const unsigned char packet[], opus_int32 len, opus_int32 Fs) OPUS_ARG_NONNULL(1); /** Gets the number of samples of an Opus packet. * @param [in] dec OpusDecoder*: Decoder state * @param [in] packet char*: Opus packet * @param [in] len opus_int32: Length of packet * @returns Number of samples * @retval OPUS_BAD_ARG Insufficient data was passed to the function * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decoder_get_nb_samples(const OpusDecoder *dec, const unsigned char packet[], opus_int32 len) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2); /** Applies soft-clipping to bring a float signal within the [-1,1] range. If * the signal is already in that range, nothing is done. If there are values * outside of [-1,1], then the signal is clipped as smoothly as possible to * both fit in the range and avoid creating excessive distortion in the * process. * @param [in,out] pcm float*: Input PCM and modified PCM * @param [in] frame_size int Number of samples per channel to process * @param [in] channels int: Number of channels * @param [in,out] softclip_mem float*: State memory for the soft clipping process (one float per channel, initialized to zero) */ OPUS_EXPORT void opus_pcm_soft_clip(float *pcm, int frame_size, int channels, float *softclip_mem); /**@}*/ /** @defgroup opus_repacketizer Repacketizer * @{ * * The repacketizer can be used to merge multiple Opus packets into a single * packet or alternatively to split Opus packets that have previously been * merged. Splitting valid Opus packets is always guaranteed to succeed, * whereas merging valid packets only succeeds if all frames have the same * mode, bandwidth, and frame size, and when the total duration of the merged * packet is no more than 120 ms. The 120 ms limit comes from the * specification and limits decoder memory requirements at a point where * framing overhead becomes negligible. * * The repacketizer currently only operates on elementary Opus * streams. It will not manipualte multistream packets successfully, except in * the degenerate case where they consist of data from a single stream. * * The repacketizing process starts with creating a repacketizer state, either * by calling opus_repacketizer_create() or by allocating the memory yourself, * e.g., * @code * OpusRepacketizer *rp; * rp = (OpusRepacketizer*)malloc(opus_repacketizer_get_size()); * if (rp != NULL) * opus_repacketizer_init(rp); * @endcode * * Then the application should submit packets with opus_repacketizer_cat(), * extract new packets with opus_repacketizer_out() or * opus_repacketizer_out_range(), and then reset the state for the next set of * input packets via opus_repacketizer_init(). * * For example, to split a sequence of packets into individual frames: * @code * unsigned char *data; * int len; * while (get_next_packet(&data, &len)) * { * unsigned char out[1276]; * opus_int32 out_len; * int nb_frames; * int err; * int i; * err = opus_repacketizer_cat(rp, data, len); * if (err != OPUS_OK) * { * release_packet(data); * return err; * } * nb_frames = opus_repacketizer_get_nb_frames(rp); * for (i = 0; i < nb_frames; i++) * { * out_len = opus_repacketizer_out_range(rp, i, i+1, out, sizeof(out)); * if (out_len < 0) * { * release_packet(data); * return (int)out_len; * } * output_next_packet(out, out_len); * } * opus_repacketizer_init(rp); * release_packet(data); * } * @endcode * * Alternatively, to combine a sequence of frames into packets that each * contain up to TARGET_DURATION_MS milliseconds of data: * @code * // The maximum number of packets with duration TARGET_DURATION_MS occurs * // when the frame size is 2.5 ms, for a total of (TARGET_DURATION_MS*2/5) * // packets. * unsigned char *data[(TARGET_DURATION_MS*2/5)+1]; * opus_int32 len[(TARGET_DURATION_MS*2/5)+1]; * int nb_packets; * unsigned char out[1277*(TARGET_DURATION_MS*2/2)]; * opus_int32 out_len; * int prev_toc; * nb_packets = 0; * while (get_next_packet(data+nb_packets, len+nb_packets)) * { * int nb_frames; * int err; * nb_frames = opus_packet_get_nb_frames(data[nb_packets], len[nb_packets]); * if (nb_frames < 1) * { * release_packets(data, nb_packets+1); * return nb_frames; * } * nb_frames += opus_repacketizer_get_nb_frames(rp); * // If adding the next packet would exceed our target, or it has an * // incompatible TOC sequence, output the packets we already have before * // submitting it. * // N.B., The nb_packets > 0 check ensures we've submitted at least one * // packet since the last call to opus_repacketizer_init(). Otherwise a * // single packet longer than TARGET_DURATION_MS would cause us to try to * // output an (invalid) empty packet. It also ensures that prev_toc has * // been set to a valid value. Additionally, len[nb_packets] > 0 is * // guaranteed by the call to opus_packet_get_nb_frames() above, so the * // reference to data[nb_packets][0] should be valid. * if (nb_packets > 0 && ( * ((prev_toc & 0xFC) != (data[nb_packets][0] & 0xFC)) || * opus_packet_get_samples_per_frame(data[nb_packets], 48000)*nb_frames > * TARGET_DURATION_MS*48)) * { * out_len = opus_repacketizer_out(rp, out, sizeof(out)); * if (out_len < 0) * { * release_packets(data, nb_packets+1); * return (int)out_len; * } * output_next_packet(out, out_len); * opus_repacketizer_init(rp); * release_packets(data, nb_packets); * data[0] = data[nb_packets]; * len[0] = len[nb_packets]; * nb_packets = 0; * } * err = opus_repacketizer_cat(rp, data[nb_packets], len[nb_packets]); * if (err != OPUS_OK) * { * release_packets(data, nb_packets+1); * return err; * } * prev_toc = data[nb_packets][0]; * nb_packets++; * } * // Output the final, partial packet. * if (nb_packets > 0) * { * out_len = opus_repacketizer_out(rp, out, sizeof(out)); * release_packets(data, nb_packets); * if (out_len < 0) * return (int)out_len; * output_next_packet(out, out_len); * } * @endcode * * An alternate way of merging packets is to simply call opus_repacketizer_cat() * unconditionally until it fails. At that point, the merged packet can be * obtained with opus_repacketizer_out() and the input packet for which * opus_repacketizer_cat() needs to be re-added to a newly reinitialized * repacketizer state. */ typedef struct OpusRepacketizer OpusRepacketizer; /** Gets the size of an OpusRepacketizer structure. * @returns The size in bytes. */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_repacketizer_get_size(void); /** (Re)initializes a previously allocated repacketizer state. * The state must be at least the size returned by opus_repacketizer_get_size(). * This can be used for applications which use their own allocator instead of * malloc(). * It must also be called to reset the queue of packets waiting to be * repacketized, which is necessary if the maximum packet duration of 120 ms * is reached or if you wish to submit packets with a different Opus * configuration (coding mode, audio bandwidth, frame size, or channel count). * Failure to do so will prevent a new packet from being added with * opus_repacketizer_cat(). * @see opus_repacketizer_create * @see opus_repacketizer_get_size * @see opus_repacketizer_cat * @param rp OpusRepacketizer*: The repacketizer state to * (re)initialize. * @returns A pointer to the same repacketizer state that was passed in. */ OPUS_EXPORT OpusRepacketizer *opus_repacketizer_init(OpusRepacketizer *rp) OPUS_ARG_NONNULL(1); /** Allocates memory and initializes the new repacketizer with * opus_repacketizer_init(). */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusRepacketizer *opus_repacketizer_create(void); /** Frees an OpusRepacketizer allocated by * opus_repacketizer_create(). * @param[in] rp OpusRepacketizer*: State to be freed. */ OPUS_EXPORT void opus_repacketizer_destroy(OpusRepacketizer *rp); /** Add a packet to the current repacketizer state. * This packet must match the configuration of any packets already submitted * for repacketization since the last call to opus_repacketizer_init(). * This means that it must have the same coding mode, audio bandwidth, frame * size, and channel count. * This can be checked in advance by examining the top 6 bits of the first * byte of the packet, and ensuring they match the top 6 bits of the first * byte of any previously submitted packet. * The total duration of audio in the repacketizer state also must not exceed * 120 ms, the maximum duration of a single packet, after adding this packet. * * The contents of the current repacketizer state can be extracted into new * packets using opus_repacketizer_out() or opus_repacketizer_out_range(). * * In order to add a packet with a different configuration or to add more * audio beyond 120 ms, you must clear the repacketizer state by calling * opus_repacketizer_init(). * If a packet is too large to add to the current repacketizer state, no part * of it is added, even if it contains multiple frames, some of which might * fit. * If you wish to be able to add parts of such packets, you should first use * another repacketizer to split the packet into pieces and add them * individually. * @see opus_repacketizer_out_range * @see opus_repacketizer_out * @see opus_repacketizer_init * @param rp OpusRepacketizer*: The repacketizer state to which to * add the packet. * @param[in] data const unsigned char*: The packet data. * The application must ensure * this pointer remains valid * until the next call to * opus_repacketizer_init() or * opus_repacketizer_destroy(). * @param len opus_int32: The number of bytes in the packet data. * @returns An error code indicating whether or not the operation succeeded. * @retval #OPUS_OK The packet's contents have been added to the repacketizer * state. * @retval #OPUS_INVALID_PACKET The packet did not have a valid TOC sequence, * the packet's TOC sequence was not compatible * with previously submitted packets (because * the coding mode, audio bandwidth, frame size, * or channel count did not match), or adding * this packet would increase the total amount of * audio stored in the repacketizer state to more * than 120 ms. */ OPUS_EXPORT int opus_repacketizer_cat(OpusRepacketizer *rp, const unsigned char *data, opus_int32 len) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2); /** Construct a new packet from data previously submitted to the repacketizer * state via opus_repacketizer_cat(). * @param rp OpusRepacketizer*: The repacketizer state from which to * construct the new packet. * @param begin int: The index of the first frame in the current * repacketizer state to include in the output. * @param end int: One past the index of the last frame in the * current repacketizer state to include in the * output. * @param[out] data const unsigned char*: The buffer in which to * store the output packet. * @param maxlen opus_int32: The maximum number of bytes to store in * the output buffer. In order to guarantee * success, this should be at least * 1276 for a single frame, * or for multiple frames, * 1277*(end-begin). * However, 1*(end-begin) plus * the size of all packet data submitted to * the repacketizer since the last call to * opus_repacketizer_init() or * opus_repacketizer_create() is also * sufficient, and possibly much smaller. * @returns The total size of the output packet on success, or an error code * on failure. * @retval #OPUS_BAD_ARG [begin,end) was an invalid range of * frames (begin < 0, begin >= end, or end > * opus_repacketizer_get_nb_frames()). * @retval #OPUS_BUFFER_TOO_SMALL \a maxlen was insufficient to contain the * complete output packet. */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_repacketizer_out_range(OpusRepacketizer *rp, int begin, int end, unsigned char *data, opus_int32 maxlen) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); /** Return the total number of frames contained in packet data submitted to * the repacketizer state so far via opus_repacketizer_cat() since the last * call to opus_repacketizer_init() or opus_repacketizer_create(). * This defines the valid range of packets that can be extracted with * opus_repacketizer_out_range() or opus_repacketizer_out(). * @param rp OpusRepacketizer*: The repacketizer state containing the * frames. * @returns The total number of frames contained in the packet data submitted * to the repacketizer state. */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_repacketizer_get_nb_frames(OpusRepacketizer *rp) OPUS_ARG_NONNULL(1); /** Construct a new packet from data previously submitted to the repacketizer * state via opus_repacketizer_cat(). * This is a convenience routine that returns all the data submitted so far * in a single packet. * It is equivalent to calling * @code * opus_repacketizer_out_range(rp, 0, opus_repacketizer_get_nb_frames(rp), * data, maxlen) * @endcode * @param rp OpusRepacketizer*: The repacketizer state from which to * construct the new packet. * @param[out] data const unsigned char*: The buffer in which to * store the output packet. * @param maxlen opus_int32: The maximum number of bytes to store in * the output buffer. In order to guarantee * success, this should be at least * 1277*opus_repacketizer_get_nb_frames(rp). * However, * 1*opus_repacketizer_get_nb_frames(rp) * plus the size of all packet data * submitted to the repacketizer since the * last call to opus_repacketizer_init() or * opus_repacketizer_create() is also * sufficient, and possibly much smaller. * @returns The total size of the output packet on success, or an error code * on failure. * @retval #OPUS_BUFFER_TOO_SMALL \a maxlen was insufficient to contain the * complete output packet. */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_repacketizer_out(OpusRepacketizer *rp, unsigned char *data, opus_int32 maxlen) OPUS_ARG_NONNULL(1); /** Pads a given Opus packet to a larger size (possibly changing the TOC sequence). * @param[in,out] data const unsigned char*: The buffer containing the * packet to pad. * @param len opus_int32: The size of the packet. * This must be at least 1. * @param new_len opus_int32: The desired size of the packet after padding. * This must be at least as large as len. * @returns an error code * @retval #OPUS_OK \a on success. * @retval #OPUS_BAD_ARG \a len was less than 1 or new_len was less than len. * @retval #OPUS_INVALID_PACKET \a data did not contain a valid Opus packet. */ OPUS_EXPORT int opus_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len); /** Remove all padding from a given Opus packet and rewrite the TOC sequence to * minimize space usage. * @param[in,out] data const unsigned char*: The buffer containing the * packet to strip. * @param len opus_int32: The size of the packet. * This must be at least 1. * @returns The new size of the output packet on success, or an error code * on failure. * @retval #OPUS_BAD_ARG \a len was less than 1. * @retval #OPUS_INVALID_PACKET \a data did not contain a valid Opus packet. */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_packet_unpad(unsigned char *data, opus_int32 len); /** Pads a given Opus multi-stream packet to a larger size (possibly changing the TOC sequence). * @param[in,out] data const unsigned char*: The buffer containing the * packet to pad. * @param len opus_int32: The size of the packet. * This must be at least 1. * @param new_len opus_int32: The desired size of the packet after padding. * This must be at least 1. * @param nb_streams opus_int32: The number of streams (not channels) in the packet. * This must be at least as large as len. * @returns an error code * @retval #OPUS_OK \a on success. * @retval #OPUS_BAD_ARG \a len was less than 1. * @retval #OPUS_INVALID_PACKET \a data did not contain a valid Opus packet. */ OPUS_EXPORT int opus_multistream_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len, int nb_streams); /** Remove all padding from a given Opus multi-stream packet and rewrite the TOC sequence to * minimize space usage. * @param[in,out] data const unsigned char*: The buffer containing the * packet to strip. * @param len opus_int32: The size of the packet. * This must be at least 1. * @param nb_streams opus_int32: The number of streams (not channels) in the packet. * This must be at least 1. * @returns The new size of the output packet on success, or an error code * on failure. * @retval #OPUS_BAD_ARG \a len was less than 1 or new_len was less than len. * @retval #OPUS_INVALID_PACKET \a data did not contain a valid Opus packet. */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_packet_unpad(unsigned char *data, opus_int32 len, int nb_streams); /**@}*/ #ifdef __cplusplus } #endif #endif /* OPUS_H */ jamulus-3.9.1+dfsg/libs/opus/include/opus_custom.h0000644000175000017500000003463614340334543021263 0ustar vimervimer/* Copyright (c) 2007-2008 CSIRO Copyright (c) 2007-2009 Xiph.Org Foundation Copyright (c) 2008-2012 Gregory Maxwell Written by Jean-Marc Valin and Gregory Maxwell */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @file opus_custom.h @brief Opus-Custom reference implementation API */ #ifndef OPUS_CUSTOM_H #define OPUS_CUSTOM_H #include "opus_defines.h" #ifdef __cplusplus extern "C" { #endif #ifdef CUSTOM_MODES # define OPUS_CUSTOM_EXPORT OPUS_EXPORT # define OPUS_CUSTOM_EXPORT_STATIC OPUS_EXPORT #else # define OPUS_CUSTOM_EXPORT # ifdef OPUS_BUILD # define OPUS_CUSTOM_EXPORT_STATIC static OPUS_INLINE # else # define OPUS_CUSTOM_EXPORT_STATIC # endif #endif /** @defgroup opus_custom Opus Custom * @{ * Opus Custom is an optional part of the Opus specification and * reference implementation which uses a distinct API from the regular * API and supports frame sizes that are not normally supported.\ Use * of Opus Custom is discouraged for all but very special applications * for which a frame size different from 2.5, 5, 10, or 20 ms is needed * (for either complexity or latency reasons) and where interoperability * is less important. * * In addition to the interoperability limitations the use of Opus custom * disables a substantial chunk of the codec and generally lowers the * quality available at a given bitrate. Normally when an application needs * a different frame size from the codec it should buffer to match the * sizes but this adds a small amount of delay which may be important * in some very low latency applications. Some transports (especially * constant rate RF transports) may also work best with frames of * particular durations. * * Libopus only supports custom modes if they are enabled at compile time. * * The Opus Custom API is similar to the regular API but the * @ref opus_encoder_create and @ref opus_decoder_create calls take * an additional mode parameter which is a structure produced by * a call to @ref opus_custom_mode_create. Both the encoder and decoder * must create a mode using the same sample rate (fs) and frame size * (frame size) so these parameters must either be signaled out of band * or fixed in a particular implementation. * * Similar to regular Opus the custom modes support on the fly frame size * switching, but the sizes available depend on the particular frame size in * use. For some initial frame sizes on a single on the fly size is available. */ /** Contains the state of an encoder. One encoder state is needed for each stream. It is initialized once at the beginning of the stream. Do *not* re-initialize the state for every frame. @brief Encoder state */ typedef struct OpusCustomEncoder OpusCustomEncoder; /** State of the decoder. One decoder state is needed for each stream. It is initialized once at the beginning of the stream. Do *not* re-initialize the state for every frame. @brief Decoder state */ typedef struct OpusCustomDecoder OpusCustomDecoder; /** The mode contains all the information necessary to create an encoder. Both the encoder and decoder need to be initialized with exactly the same mode, otherwise the output will be corrupted. @brief Mode configuration */ typedef struct OpusCustomMode OpusCustomMode; /** Creates a new mode struct. This will be passed to an encoder or * decoder. The mode MUST NOT BE DESTROYED until the encoders and * decoders that use it are destroyed as well. * @param [in] Fs int: Sampling rate (8000 to 96000 Hz) * @param [in] frame_size int: Number of samples (per channel) to encode in each * packet (64 - 1024, prime factorization must contain zero or more 2s, 3s, or 5s and no other primes) * @param [out] error int*: Returned error code (if NULL, no error will be returned) * @return A newly created mode */ OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomMode *opus_custom_mode_create(opus_int32 Fs, int frame_size, int *error); /** Destroys a mode struct. Only call this after all encoders and * decoders using this mode are destroyed as well. * @param [in] mode OpusCustomMode*: Mode to be freed. */ OPUS_CUSTOM_EXPORT void opus_custom_mode_destroy(OpusCustomMode *mode); #if !defined(OPUS_BUILD) || defined(CELT_ENCODER_C) /* Encoder */ /** Gets the size of an OpusCustomEncoder structure. * @param [in] mode OpusCustomMode *: Mode configuration * @param [in] channels int: Number of channels * @returns size */ OPUS_CUSTOM_EXPORT_STATIC OPUS_WARN_UNUSED_RESULT int opus_custom_encoder_get_size( const OpusCustomMode *mode, int channels ) OPUS_ARG_NONNULL(1); # ifdef CUSTOM_MODES /** Initializes a previously allocated encoder state * The memory pointed to by st must be the size returned by opus_custom_encoder_get_size. * This is intended for applications which use their own allocator instead of malloc. * @see opus_custom_encoder_create(),opus_custom_encoder_get_size() * To reset a previously initialized state use the OPUS_RESET_STATE CTL. * @param [in] st OpusCustomEncoder*: Encoder state * @param [in] mode OpusCustomMode *: Contains all the information about the characteristics of * the stream (must be the same characteristics as used for the * decoder) * @param [in] channels int: Number of channels * @return OPUS_OK Success or @ref opus_errorcodes */ OPUS_CUSTOM_EXPORT int opus_custom_encoder_init( OpusCustomEncoder *st, const OpusCustomMode *mode, int channels ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2); # endif #endif /** Creates a new encoder state. Each stream needs its own encoder * state (can't be shared across simultaneous streams). * @param [in] mode OpusCustomMode*: Contains all the information about the characteristics of * the stream (must be the same characteristics as used for the * decoder) * @param [in] channels int: Number of channels * @param [out] error int*: Returns an error code * @return Newly created encoder state. */ OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomEncoder *opus_custom_encoder_create( const OpusCustomMode *mode, int channels, int *error ) OPUS_ARG_NONNULL(1); /** Destroys a an encoder state. * @param[in] st OpusCustomEncoder*: State to be freed. */ OPUS_CUSTOM_EXPORT void opus_custom_encoder_destroy(OpusCustomEncoder *st); /** Encodes a frame of audio. * @param [in] st OpusCustomEncoder*: Encoder state * @param [in] pcm float*: PCM audio in float format, with a normal range of +/-1.0. * Samples with a range beyond +/-1.0 are supported but will * be clipped by decoders using the integer API and should * only be used if it is known that the far end supports * extended dynamic range. There must be exactly * frame_size samples per channel. * @param [in] frame_size int: Number of samples per frame of input signal * @param [out] compressed char *: The compressed data is written here. This may not alias pcm and must be at least maxCompressedBytes long. * @param [in] maxCompressedBytes int: Maximum number of bytes to use for compressing the frame * (can change from one frame to another) * @return Number of bytes written to "compressed". * If negative, an error has occurred (see error codes). It is IMPORTANT that * the length returned be somehow transmitted to the decoder. Otherwise, no * decoding is possible. */ OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_encode_float( OpusCustomEncoder *st, const float *pcm, int frame_size, unsigned char *compressed, int maxCompressedBytes ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); /** Encodes a frame of audio. * @param [in] st OpusCustomEncoder*: Encoder state * @param [in] pcm opus_int16*: PCM audio in signed 16-bit format (native endian). * There must be exactly frame_size samples per channel. * @param [in] frame_size int: Number of samples per frame of input signal * @param [out] compressed char *: The compressed data is written here. This may not alias pcm and must be at least maxCompressedBytes long. * @param [in] maxCompressedBytes int: Maximum number of bytes to use for compressing the frame * (can change from one frame to another) * @return Number of bytes written to "compressed". * If negative, an error has occurred (see error codes). It is IMPORTANT that * the length returned be somehow transmitted to the decoder. Otherwise, no * decoding is possible. */ OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_encode( OpusCustomEncoder *st, const opus_int16 *pcm, int frame_size, unsigned char *compressed, int maxCompressedBytes ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); /** Perform a CTL function on an Opus custom encoder. * * Generally the request and subsequent arguments are generated * by a convenience macro. * @see opus_encoderctls */ OPUS_CUSTOM_EXPORT int opus_custom_encoder_ctl(OpusCustomEncoder * OPUS_RESTRICT st, int request, ...) OPUS_ARG_NONNULL(1); #if !defined(OPUS_BUILD) || defined(CELT_DECODER_C) /* Decoder */ /** Gets the size of an OpusCustomDecoder structure. * @param [in] mode OpusCustomMode *: Mode configuration * @param [in] channels int: Number of channels * @returns size */ OPUS_CUSTOM_EXPORT_STATIC OPUS_WARN_UNUSED_RESULT int opus_custom_decoder_get_size( const OpusCustomMode *mode, int channels ) OPUS_ARG_NONNULL(1); /** Initializes a previously allocated decoder state * The memory pointed to by st must be the size returned by opus_custom_decoder_get_size. * This is intended for applications which use their own allocator instead of malloc. * @see opus_custom_decoder_create(),opus_custom_decoder_get_size() * To reset a previously initialized state use the OPUS_RESET_STATE CTL. * @param [in] st OpusCustomDecoder*: Decoder state * @param [in] mode OpusCustomMode *: Contains all the information about the characteristics of * the stream (must be the same characteristics as used for the * encoder) * @param [in] channels int: Number of channels * @return OPUS_OK Success or @ref opus_errorcodes */ OPUS_CUSTOM_EXPORT_STATIC int opus_custom_decoder_init( OpusCustomDecoder *st, const OpusCustomMode *mode, int channels ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2); #endif /** Creates a new decoder state. Each stream needs its own decoder state (can't * be shared across simultaneous streams). * @param [in] mode OpusCustomMode: Contains all the information about the characteristics of the * stream (must be the same characteristics as used for the encoder) * @param [in] channels int: Number of channels * @param [out] error int*: Returns an error code * @return Newly created decoder state. */ OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomDecoder *opus_custom_decoder_create( const OpusCustomMode *mode, int channels, int *error ) OPUS_ARG_NONNULL(1); /** Destroys a an decoder state. * @param[in] st OpusCustomDecoder*: State to be freed. */ OPUS_CUSTOM_EXPORT void opus_custom_decoder_destroy(OpusCustomDecoder *st); /** Decode an opus custom frame with floating point output * @param [in] st OpusCustomDecoder*: Decoder state * @param [in] data char*: Input payload. Use a NULL pointer to indicate packet loss * @param [in] len int: Number of bytes in payload * @param [out] pcm float*: Output signal (interleaved if 2 channels). length * is frame_size*channels*sizeof(float) * @param [in] frame_size Number of samples per channel of available space in *pcm. * @returns Number of decoded samples or @ref opus_errorcodes */ OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_decode_float( OpusCustomDecoder *st, const unsigned char *data, int len, float *pcm, int frame_size ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); /** Decode an opus custom frame * @param [in] st OpusCustomDecoder*: Decoder state * @param [in] data char*: Input payload. Use a NULL pointer to indicate packet loss * @param [in] len int: Number of bytes in payload * @param [out] pcm opus_int16*: Output signal (interleaved if 2 channels). length * is frame_size*channels*sizeof(opus_int16) * @param [in] frame_size Number of samples per channel of available space in *pcm. * @returns Number of decoded samples or @ref opus_errorcodes */ OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_decode( OpusCustomDecoder *st, const unsigned char *data, int len, opus_int16 *pcm, int frame_size ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); /** Perform a CTL function on an Opus custom decoder. * * Generally the request and subsequent arguments are generated * by a convenience macro. * @see opus_genericctls */ OPUS_CUSTOM_EXPORT int opus_custom_decoder_ctl(OpusCustomDecoder * OPUS_RESTRICT st, int request, ...) OPUS_ARG_NONNULL(1); /**@}*/ #ifdef __cplusplus } #endif #endif /* OPUS_CUSTOM_H */ jamulus-3.9.1+dfsg/libs/opus/include/opus_projection.h0000644000175000017500000006712114340334543022120 0ustar vimervimer/* Copyright (c) 2017 Google Inc. Written by Andrew Allen */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @file opus_projection.h * @brief Opus projection reference API */ #ifndef OPUS_PROJECTION_H #define OPUS_PROJECTION_H #include "opus_multistream.h" #ifdef __cplusplus extern "C" { #endif /** @cond OPUS_INTERNAL_DOC */ /** These are the actual encoder and decoder CTL ID numbers. * They should not be used directly by applications.c * In general, SETs should be even and GETs should be odd.*/ /**@{*/ #define OPUS_PROJECTION_GET_DEMIXING_MATRIX_GAIN_REQUEST 6001 #define OPUS_PROJECTION_GET_DEMIXING_MATRIX_SIZE_REQUEST 6003 #define OPUS_PROJECTION_GET_DEMIXING_MATRIX_REQUEST 6005 /**@}*/ /** @endcond */ /** @defgroup opus_projection_ctls Projection specific encoder and decoder CTLs * * These are convenience macros that are specific to the * opus_projection_encoder_ctl() and opus_projection_decoder_ctl() * interface. * The CTLs from @ref opus_genericctls, @ref opus_encoderctls, * @ref opus_decoderctls, and @ref opus_multistream_ctls may be applied to a * projection encoder or decoder as well. */ /**@{*/ /** Gets the gain (in dB. S7.8-format) of the demixing matrix from the encoder. * @param[out] x opus_int32 *: Returns the gain (in dB. S7.8-format) * of the demixing matrix. * @hideinitializer */ #define OPUS_PROJECTION_GET_DEMIXING_MATRIX_GAIN(x) OPUS_PROJECTION_GET_DEMIXING_MATRIX_GAIN_REQUEST, __opus_check_int_ptr(x) /** Gets the size in bytes of the demixing matrix from the encoder. * @param[out] x opus_int32 *: Returns the size in bytes of the * demixing matrix. * @hideinitializer */ #define OPUS_PROJECTION_GET_DEMIXING_MATRIX_SIZE(x) OPUS_PROJECTION_GET_DEMIXING_MATRIX_SIZE_REQUEST, __opus_check_int_ptr(x) /** Copies the demixing matrix to the supplied pointer location. * @param[out] x unsigned char *: Returns the demixing matrix to the * supplied pointer location. * @param y opus_int32: The size in bytes of the reserved memory at the * pointer location. * @hideinitializer */ #define OPUS_PROJECTION_GET_DEMIXING_MATRIX(x,y) OPUS_PROJECTION_GET_DEMIXING_MATRIX_REQUEST, x, __opus_check_int(y) /**@}*/ /** Opus projection encoder state. * This contains the complete state of a projection Opus encoder. * It is position independent and can be freely copied. * @see opus_projection_ambisonics_encoder_create */ typedef struct OpusProjectionEncoder OpusProjectionEncoder; /** Opus projection decoder state. * This contains the complete state of a projection Opus decoder. * It is position independent and can be freely copied. * @see opus_projection_decoder_create * @see opus_projection_decoder_init */ typedef struct OpusProjectionDecoder OpusProjectionDecoder; /**\name Projection encoder functions */ /**@{*/ /** Gets the size of an OpusProjectionEncoder structure. * @param channels int: The total number of input channels to encode. * This must be no more than 255. * @param mapping_family int: The mapping family to use for selecting * the appropriate projection. * @returns The size in bytes on success, or a negative error code * (see @ref opus_errorcodes) on error. */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_projection_ambisonics_encoder_get_size( int channels, int mapping_family ); /** Allocates and initializes a projection encoder state. * Call opus_projection_encoder_destroy() to release * this object when finished. * @param Fs opus_int32: Sampling rate of the input signal (in Hz). * This must be one of 8000, 12000, 16000, * 24000, or 48000. * @param channels int: Number of channels in the input signal. * This must be at most 255. * It may be greater than the number of * coded channels (streams + * coupled_streams). * @param mapping_family int: The mapping family to use for selecting * the appropriate projection. * @param[out] streams int *: The total number of streams that will * be encoded from the input. * @param[out] coupled_streams int *: Number of coupled (2 channel) * streams that will be encoded from the input. * @param application int: The target encoder application. * This must be one of the following: *
*
#OPUS_APPLICATION_VOIP
*
Process signal for improved speech intelligibility.
*
#OPUS_APPLICATION_AUDIO
*
Favor faithfulness to the original input.
*
#OPUS_APPLICATION_RESTRICTED_LOWDELAY
*
Configure the minimum possible coding delay by disabling certain modes * of operation.
*
* @param[out] error int *: Returns #OPUS_OK on success, or an error * code (see @ref opus_errorcodes) on * failure. */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusProjectionEncoder *opus_projection_ambisonics_encoder_create( opus_int32 Fs, int channels, int mapping_family, int *streams, int *coupled_streams, int application, int *error ) OPUS_ARG_NONNULL(4) OPUS_ARG_NONNULL(5); /** Initialize a previously allocated projection encoder state. * The memory pointed to by \a st must be at least the size returned by * opus_projection_ambisonics_encoder_get_size(). * This is intended for applications which use their own allocator instead of * malloc. * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. * @see opus_projection_ambisonics_encoder_create * @see opus_projection_ambisonics_encoder_get_size * @param st OpusProjectionEncoder*: Projection encoder state to initialize. * @param Fs opus_int32: Sampling rate of the input signal (in Hz). * This must be one of 8000, 12000, 16000, * 24000, or 48000. * @param channels int: Number of channels in the input signal. * This must be at most 255. * It may be greater than the number of * coded channels (streams + * coupled_streams). * @param streams int: The total number of streams to encode from the * input. * This must be no more than the number of channels. * @param coupled_streams int: Number of coupled (2 channel) streams * to encode. * This must be no larger than the total * number of streams. * Additionally, The total number of * encoded channels (streams + * coupled_streams) must be no * more than the number of input channels. * @param application int: The target encoder application. * This must be one of the following: *
*
#OPUS_APPLICATION_VOIP
*
Process signal for improved speech intelligibility.
*
#OPUS_APPLICATION_AUDIO
*
Favor faithfulness to the original input.
*
#OPUS_APPLICATION_RESTRICTED_LOWDELAY
*
Configure the minimum possible coding delay by disabling certain modes * of operation.
*
* @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes) * on failure. */ OPUS_EXPORT int opus_projection_ambisonics_encoder_init( OpusProjectionEncoder *st, opus_int32 Fs, int channels, int mapping_family, int *streams, int *coupled_streams, int application ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(5) OPUS_ARG_NONNULL(6); /** Encodes a projection Opus frame. * @param st OpusProjectionEncoder*: Projection encoder state. * @param[in] pcm const opus_int16*: The input signal as interleaved * samples. * This must contain * frame_size*channels * samples. * @param frame_size int: Number of samples per channel in the input * signal. * This must be an Opus frame size for the * encoder's sampling rate. * For example, at 48 kHz the permitted values * are 120, 240, 480, 960, 1920, and 2880. * Passing in a duration of less than 10 ms * (480 samples at 48 kHz) will prevent the * encoder from using the LPC or hybrid modes. * @param[out] data unsigned char*: Output payload. * This must contain storage for at * least \a max_data_bytes. * @param [in] max_data_bytes opus_int32: Size of the allocated * memory for the output * payload. This may be * used to impose an upper limit on * the instant bitrate, but should * not be used as the only bitrate * control. Use #OPUS_SET_BITRATE to * control the bitrate. * @returns The length of the encoded packet (in bytes) on success or a * negative error code (see @ref opus_errorcodes) on failure. */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_projection_encode( OpusProjectionEncoder *st, const opus_int16 *pcm, int frame_size, unsigned char *data, opus_int32 max_data_bytes ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); /** Encodes a projection Opus frame from floating point input. * @param st OpusProjectionEncoder*: Projection encoder state. * @param[in] pcm const float*: The input signal as interleaved * samples with a normal range of * +/-1.0. * Samples with a range beyond +/-1.0 * are supported but will be clipped by * decoders using the integer API and * should only be used if it is known * that the far end supports extended * dynamic range. * This must contain * frame_size*channels * samples. * @param frame_size int: Number of samples per channel in the input * signal. * This must be an Opus frame size for the * encoder's sampling rate. * For example, at 48 kHz the permitted values * are 120, 240, 480, 960, 1920, and 2880. * Passing in a duration of less than 10 ms * (480 samples at 48 kHz) will prevent the * encoder from using the LPC or hybrid modes. * @param[out] data unsigned char*: Output payload. * This must contain storage for at * least \a max_data_bytes. * @param [in] max_data_bytes opus_int32: Size of the allocated * memory for the output * payload. This may be * used to impose an upper limit on * the instant bitrate, but should * not be used as the only bitrate * control. Use #OPUS_SET_BITRATE to * control the bitrate. * @returns The length of the encoded packet (in bytes) on success or a * negative error code (see @ref opus_errorcodes) on failure. */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_projection_encode_float( OpusProjectionEncoder *st, const float *pcm, int frame_size, unsigned char *data, opus_int32 max_data_bytes ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); /** Frees an OpusProjectionEncoder allocated by * opus_projection_ambisonics_encoder_create(). * @param st OpusProjectionEncoder*: Projection encoder state to be freed. */ OPUS_EXPORT void opus_projection_encoder_destroy(OpusProjectionEncoder *st); /** Perform a CTL function on a projection Opus encoder. * * Generally the request and subsequent arguments are generated by a * convenience macro. * @param st OpusProjectionEncoder*: Projection encoder state. * @param request This and all remaining parameters should be replaced by one * of the convenience macros in @ref opus_genericctls, * @ref opus_encoderctls, @ref opus_multistream_ctls, or * @ref opus_projection_ctls * @see opus_genericctls * @see opus_encoderctls * @see opus_multistream_ctls * @see opus_projection_ctls */ OPUS_EXPORT int opus_projection_encoder_ctl(OpusProjectionEncoder *st, int request, ...) OPUS_ARG_NONNULL(1); /**@}*/ /**\name Projection decoder functions */ /**@{*/ /** Gets the size of an OpusProjectionDecoder structure. * @param channels int: The total number of output channels. * This must be no more than 255. * @param streams int: The total number of streams coded in the * input. * This must be no more than 255. * @param coupled_streams int: Number streams to decode as coupled * (2 channel) streams. * This must be no larger than the total * number of streams. * Additionally, The total number of * coded channels (streams + * coupled_streams) must be no * more than 255. * @returns The size in bytes on success, or a negative error code * (see @ref opus_errorcodes) on error. */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_projection_decoder_get_size( int channels, int streams, int coupled_streams ); /** Allocates and initializes a projection decoder state. * Call opus_projection_decoder_destroy() to release * this object when finished. * @param Fs opus_int32: Sampling rate to decode at (in Hz). * This must be one of 8000, 12000, 16000, * 24000, or 48000. * @param channels int: Number of channels to output. * This must be at most 255. * It may be different from the number of coded * channels (streams + * coupled_streams). * @param streams int: The total number of streams coded in the * input. * This must be no more than 255. * @param coupled_streams int: Number of streams to decode as coupled * (2 channel) streams. * This must be no larger than the total * number of streams. * Additionally, The total number of * coded channels (streams + * coupled_streams) must be no * more than 255. * @param[in] demixing_matrix const unsigned char[demixing_matrix_size]: Demixing matrix * that mapping from coded channels to output channels, * as described in @ref opus_projection and * @ref opus_projection_ctls. * @param demixing_matrix_size opus_int32: The size in bytes of the * demixing matrix, as * described in @ref * opus_projection_ctls. * @param[out] error int *: Returns #OPUS_OK on success, or an error * code (see @ref opus_errorcodes) on * failure. */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusProjectionDecoder *opus_projection_decoder_create( opus_int32 Fs, int channels, int streams, int coupled_streams, unsigned char *demixing_matrix, opus_int32 demixing_matrix_size, int *error ) OPUS_ARG_NONNULL(5); /** Initialize a previously allocated projection decoder state object. * The memory pointed to by \a st must be at least the size returned by * opus_projection_decoder_get_size(). * This is intended for applications which use their own allocator instead of * malloc. * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. * @see opus_projection_decoder_create * @see opus_projection_deocder_get_size * @param st OpusProjectionDecoder*: Projection encoder state to initialize. * @param Fs opus_int32: Sampling rate to decode at (in Hz). * This must be one of 8000, 12000, 16000, * 24000, or 48000. * @param channels int: Number of channels to output. * This must be at most 255. * It may be different from the number of coded * channels (streams + * coupled_streams). * @param streams int: The total number of streams coded in the * input. * This must be no more than 255. * @param coupled_streams int: Number of streams to decode as coupled * (2 channel) streams. * This must be no larger than the total * number of streams. * Additionally, The total number of * coded channels (streams + * coupled_streams) must be no * more than 255. * @param[in] demixing_matrix const unsigned char[demixing_matrix_size]: Demixing matrix * that mapping from coded channels to output channels, * as described in @ref opus_projection and * @ref opus_projection_ctls. * @param demixing_matrix_size opus_int32: The size in bytes of the * demixing matrix, as * described in @ref * opus_projection_ctls. * @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes) * on failure. */ OPUS_EXPORT int opus_projection_decoder_init( OpusProjectionDecoder *st, opus_int32 Fs, int channels, int streams, int coupled_streams, unsigned char *demixing_matrix, opus_int32 demixing_matrix_size ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6); /** Decode a projection Opus packet. * @param st OpusProjectionDecoder*: Projection decoder state. * @param[in] data const unsigned char*: Input payload. * Use a NULL * pointer to indicate packet * loss. * @param len opus_int32: Number of bytes in payload. * @param[out] pcm opus_int16*: Output signal, with interleaved * samples. * This must contain room for * frame_size*channels * samples. * @param frame_size int: The number of samples per channel of * available space in \a pcm. * If this is less than the maximum packet duration * (120 ms; 5760 for 48kHz), this function will not be capable * of decoding some packets. In the case of PLC (data==NULL) * or FEC (decode_fec=1), then frame_size needs to be exactly * the duration of audio that is missing, otherwise the * decoder will not be in the optimal state to decode the * next incoming packet. For the PLC and FEC cases, frame_size * must be a multiple of 2.5 ms. * @param decode_fec int: Flag (0 or 1) to request that any in-band * forward error correction data be decoded. * If no such data is available, the frame is * decoded as if it were lost. * @returns Number of samples decoded on success or a negative error code * (see @ref opus_errorcodes) on failure. */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_projection_decode( OpusProjectionDecoder *st, const unsigned char *data, opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); /** Decode a projection Opus packet with floating point output. * @param st OpusProjectionDecoder*: Projection decoder state. * @param[in] data const unsigned char*: Input payload. * Use a NULL * pointer to indicate packet * loss. * @param len opus_int32: Number of bytes in payload. * @param[out] pcm opus_int16*: Output signal, with interleaved * samples. * This must contain room for * frame_size*channels * samples. * @param frame_size int: The number of samples per channel of * available space in \a pcm. * If this is less than the maximum packet duration * (120 ms; 5760 for 48kHz), this function will not be capable * of decoding some packets. In the case of PLC (data==NULL) * or FEC (decode_fec=1), then frame_size needs to be exactly * the duration of audio that is missing, otherwise the * decoder will not be in the optimal state to decode the * next incoming packet. For the PLC and FEC cases, frame_size * must be a multiple of 2.5 ms. * @param decode_fec int: Flag (0 or 1) to request that any in-band * forward error correction data be decoded. * If no such data is available, the frame is * decoded as if it were lost. * @returns Number of samples decoded on success or a negative error code * (see @ref opus_errorcodes) on failure. */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_projection_decode_float( OpusProjectionDecoder *st, const unsigned char *data, opus_int32 len, float *pcm, int frame_size, int decode_fec ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); /** Perform a CTL function on a projection Opus decoder. * * Generally the request and subsequent arguments are generated by a * convenience macro. * @param st OpusProjectionDecoder*: Projection decoder state. * @param request This and all remaining parameters should be replaced by one * of the convenience macros in @ref opus_genericctls, * @ref opus_decoderctls, @ref opus_multistream_ctls, or * @ref opus_projection_ctls. * @see opus_genericctls * @see opus_decoderctls * @see opus_multistream_ctls * @see opus_projection_ctls */ OPUS_EXPORT int opus_projection_decoder_ctl(OpusProjectionDecoder *st, int request, ...) OPUS_ARG_NONNULL(1); /** Frees an OpusProjectionDecoder allocated by * opus_projection_decoder_create(). * @param st OpusProjectionDecoder: Projection decoder state to be freed. */ OPUS_EXPORT void opus_projection_decoder_destroy(OpusProjectionDecoder *st); /**@}*/ /**@}*/ #ifdef __cplusplus } #endif #endif /* OPUS_PROJECTION_H */ jamulus-3.9.1+dfsg/libs/opus/include/opus_types.h0000644000175000017500000001204514340334543021103 0ustar vimervimer/* (C) COPYRIGHT 1994-2002 Xiph.Org Foundation */ /* Modified by Jean-Marc Valin */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* opus_types.h based on ogg_types.h from libogg */ /** @file opus_types.h @brief Opus reference implementation types */ #ifndef OPUS_TYPES_H #define OPUS_TYPES_H #define opus_int int /* used for counters etc; at least 16 bits */ #define opus_int64 long long #define opus_int8 signed char #define opus_uint unsigned int /* used for counters etc; at least 16 bits */ #define opus_uint64 unsigned long long #define opus_uint8 unsigned char /* Use the real stdint.h if it's there (taken from Paul Hsieh's pstdint.h) */ #if (defined(__STDC__) && __STDC__ && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_)) || defined (HAVE_STDINT_H)) #include # undef opus_int64 # undef opus_int8 # undef opus_uint64 # undef opus_uint8 typedef int8_t opus_int8; typedef uint8_t opus_uint8; typedef int16_t opus_int16; typedef uint16_t opus_uint16; typedef int32_t opus_int32; typedef uint32_t opus_uint32; typedef int64_t opus_int64; typedef uint64_t opus_uint64; #elif defined(_WIN32) # if defined(__CYGWIN__) # include <_G_config.h> typedef _G_int32_t opus_int32; typedef _G_uint32_t opus_uint32; typedef _G_int16 opus_int16; typedef _G_uint16 opus_uint16; # elif defined(__MINGW32__) typedef short opus_int16; typedef unsigned short opus_uint16; typedef int opus_int32; typedef unsigned int opus_uint32; # elif defined(__MWERKS__) typedef int opus_int32; typedef unsigned int opus_uint32; typedef short opus_int16; typedef unsigned short opus_uint16; # else /* MSVC/Borland */ typedef __int32 opus_int32; typedef unsigned __int32 opus_uint32; typedef __int16 opus_int16; typedef unsigned __int16 opus_uint16; # endif #elif defined(__MACOS__) # include typedef SInt16 opus_int16; typedef UInt16 opus_uint16; typedef SInt32 opus_int32; typedef UInt32 opus_uint32; #elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */ # include typedef int16_t opus_int16; typedef u_int16_t opus_uint16; typedef int32_t opus_int32; typedef u_int32_t opus_uint32; #elif defined(__BEOS__) /* Be */ # include typedef int16 opus_int16; typedef u_int16 opus_uint16; typedef int32_t opus_int32; typedef u_int32_t opus_uint32; #elif defined (__EMX__) /* OS/2 GCC */ typedef short opus_int16; typedef unsigned short opus_uint16; typedef int opus_int32; typedef unsigned int opus_uint32; #elif defined (DJGPP) /* DJGPP */ typedef short opus_int16; typedef unsigned short opus_uint16; typedef int opus_int32; typedef unsigned int opus_uint32; #elif defined(R5900) /* PS2 EE */ typedef int opus_int32; typedef unsigned opus_uint32; typedef short opus_int16; typedef unsigned short opus_uint16; #elif defined(__SYMBIAN32__) /* Symbian GCC */ typedef signed short opus_int16; typedef unsigned short opus_uint16; typedef signed int opus_int32; typedef unsigned int opus_uint32; #elif defined(CONFIG_TI_C54X) || defined (CONFIG_TI_C55X) typedef short opus_int16; typedef unsigned short opus_uint16; typedef long opus_int32; typedef unsigned long opus_uint32; #elif defined(CONFIG_TI_C6X) typedef short opus_int16; typedef unsigned short opus_uint16; typedef int opus_int32; typedef unsigned int opus_uint32; #else /* Give up, take a reasonable guess */ typedef short opus_int16; typedef unsigned short opus_uint16; typedef int opus_int32; typedef unsigned int opus_uint32; #endif #endif /* OPUS_TYPES_H */ jamulus-3.9.1+dfsg/libs/opus/include/opus_multistream.h0000644000175000017500000010140514340334543022304 0ustar vimervimer/* Copyright (c) 2011 Xiph.Org Foundation Written by Jean-Marc Valin */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @file opus_multistream.h * @brief Opus reference implementation multistream API */ #ifndef OPUS_MULTISTREAM_H #define OPUS_MULTISTREAM_H #include "opus.h" #ifdef __cplusplus extern "C" { #endif /** @cond OPUS_INTERNAL_DOC */ /** Macros to trigger compilation errors when the wrong types are provided to a * CTL. */ /**@{*/ #define __opus_check_encstate_ptr(ptr) ((ptr) + ((ptr) - (OpusEncoder**)(ptr))) #define __opus_check_decstate_ptr(ptr) ((ptr) + ((ptr) - (OpusDecoder**)(ptr))) /**@}*/ /** These are the actual encoder and decoder CTL ID numbers. * They should not be used directly by applications. * In general, SETs should be even and GETs should be odd.*/ /**@{*/ #define OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST 5120 #define OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST 5122 /**@}*/ /** @endcond */ /** @defgroup opus_multistream_ctls Multistream specific encoder and decoder CTLs * * These are convenience macros that are specific to the * opus_multistream_encoder_ctl() and opus_multistream_decoder_ctl() * interface. * The CTLs from @ref opus_genericctls, @ref opus_encoderctls, and * @ref opus_decoderctls may be applied to a multistream encoder or decoder as * well. * In addition, you may retrieve the encoder or decoder state for an specific * stream via #OPUS_MULTISTREAM_GET_ENCODER_STATE or * #OPUS_MULTISTREAM_GET_DECODER_STATE and apply CTLs to it individually. */ /**@{*/ /** Gets the encoder state for an individual stream of a multistream encoder. * @param[in] x opus_int32: The index of the stream whose encoder you * wish to retrieve. * This must be non-negative and less than * the streams parameter used * to initialize the encoder. * @param[out] y OpusEncoder**: Returns a pointer to the given * encoder state. * @retval OPUS_BAD_ARG The index of the requested stream was out of range. * @hideinitializer */ #define OPUS_MULTISTREAM_GET_ENCODER_STATE(x,y) OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST, __opus_check_int(x), __opus_check_encstate_ptr(y) /** Gets the decoder state for an individual stream of a multistream decoder. * @param[in] x opus_int32: The index of the stream whose decoder you * wish to retrieve. * This must be non-negative and less than * the streams parameter used * to initialize the decoder. * @param[out] y OpusDecoder**: Returns a pointer to the given * decoder state. * @retval OPUS_BAD_ARG The index of the requested stream was out of range. * @hideinitializer */ #define OPUS_MULTISTREAM_GET_DECODER_STATE(x,y) OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST, __opus_check_int(x), __opus_check_decstate_ptr(y) /**@}*/ /** @defgroup opus_multistream Opus Multistream API * @{ * * The multistream API allows individual Opus streams to be combined into a * single packet, enabling support for up to 255 channels. Unlike an * elementary Opus stream, the encoder and decoder must negotiate the channel * configuration before the decoder can successfully interpret the data in the * packets produced by the encoder. Some basic information, such as packet * duration, can be computed without any special negotiation. * * The format for multistream Opus packets is defined in *
RFC 7845 * and is based on the self-delimited Opus framing described in Appendix B of * RFC 6716. * Normal Opus packets are just a degenerate case of multistream Opus packets, * and can be encoded or decoded with the multistream API by setting * streams to 1 when initializing the encoder or * decoder. * * Multistream Opus streams can contain up to 255 elementary Opus streams. * These may be either "uncoupled" or "coupled", indicating that the decoder * is configured to decode them to either 1 or 2 channels, respectively. * The streams are ordered so that all coupled streams appear at the * beginning. * * A mapping table defines which decoded channel i * should be used for each input/output (I/O) channel j. This table is * typically provided as an unsigned char array. * Let i = mapping[j] be the index for I/O channel j. * If i < 2*coupled_streams, then I/O channel j is * encoded as the left channel of stream (i/2) if i * is even, or as the right channel of stream (i/2) if * i is odd. Otherwise, I/O channel j is encoded as * mono in stream (i - coupled_streams), unless it has the special * value 255, in which case it is omitted from the encoding entirely (the * decoder will reproduce it as silence). Each value i must either * be the special value 255 or be less than streams + coupled_streams. * * The output channels specified by the encoder * should use the * Vorbis * channel ordering. A decoder may wish to apply an additional permutation * to the mapping the encoder used to achieve a different output channel * order (e.g. for outputting in WAV order). * * Each multistream packet contains an Opus packet for each stream, and all of * the Opus packets in a single multistream packet must have the same * duration. Therefore the duration of a multistream packet can be extracted * from the TOC sequence of the first stream, which is located at the * beginning of the packet, just like an elementary Opus stream: * * @code * int nb_samples; * int nb_frames; * nb_frames = opus_packet_get_nb_frames(data, len); * if (nb_frames < 1) * return nb_frames; * nb_samples = opus_packet_get_samples_per_frame(data, 48000) * nb_frames; * @endcode * * The general encoding and decoding process proceeds exactly the same as in * the normal @ref opus_encoder and @ref opus_decoder APIs. * See their documentation for an overview of how to use the corresponding * multistream functions. */ /** Opus multistream encoder state. * This contains the complete state of a multistream Opus encoder. * It is position independent and can be freely copied. * @see opus_multistream_encoder_create * @see opus_multistream_encoder_init */ typedef struct OpusMSEncoder OpusMSEncoder; /** Opus multistream decoder state. * This contains the complete state of a multistream Opus decoder. * It is position independent and can be freely copied. * @see opus_multistream_decoder_create * @see opus_multistream_decoder_init */ typedef struct OpusMSDecoder OpusMSDecoder; /**\name Multistream encoder functions */ /**@{*/ /** Gets the size of an OpusMSEncoder structure. * @param streams int: The total number of streams to encode from the * input. * This must be no more than 255. * @param coupled_streams int: Number of coupled (2 channel) streams * to encode. * This must be no larger than the total * number of streams. * Additionally, The total number of * encoded channels (streams + * coupled_streams) must be no * more than 255. * @returns The size in bytes on success, or a negative error code * (see @ref opus_errorcodes) on error. */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_encoder_get_size( int streams, int coupled_streams ); OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_surround_encoder_get_size( int channels, int mapping_family ); /** Allocates and initializes a multistream encoder state. * Call opus_multistream_encoder_destroy() to release * this object when finished. * @param Fs opus_int32: Sampling rate of the input signal (in Hz). * This must be one of 8000, 12000, 16000, * 24000, or 48000. * @param channels int: Number of channels in the input signal. * This must be at most 255. * It may be greater than the number of * coded channels (streams + * coupled_streams). * @param streams int: The total number of streams to encode from the * input. * This must be no more than the number of channels. * @param coupled_streams int: Number of coupled (2 channel) streams * to encode. * This must be no larger than the total * number of streams. * Additionally, The total number of * encoded channels (streams + * coupled_streams) must be no * more than the number of input channels. * @param[in] mapping const unsigned char[channels]: Mapping from * encoded channels to input channels, as described in * @ref opus_multistream. As an extra constraint, the * multistream encoder does not allow encoding coupled * streams for which one channel is unused since this * is never a good idea. * @param application int: The target encoder application. * This must be one of the following: *
*
#OPUS_APPLICATION_VOIP
*
Process signal for improved speech intelligibility.
*
#OPUS_APPLICATION_AUDIO
*
Favor faithfulness to the original input.
*
#OPUS_APPLICATION_RESTRICTED_LOWDELAY
*
Configure the minimum possible coding delay by disabling certain modes * of operation.
*
* @param[out] error int *: Returns #OPUS_OK on success, or an error * code (see @ref opus_errorcodes) on * failure. */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSEncoder *opus_multistream_encoder_create( opus_int32 Fs, int channels, int streams, int coupled_streams, const unsigned char *mapping, int application, int *error ) OPUS_ARG_NONNULL(5); OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSEncoder *opus_multistream_surround_encoder_create( opus_int32 Fs, int channels, int mapping_family, int *streams, int *coupled_streams, unsigned char *mapping, int application, int *error ) OPUS_ARG_NONNULL(4) OPUS_ARG_NONNULL(5) OPUS_ARG_NONNULL(6); /** Initialize a previously allocated multistream encoder state. * The memory pointed to by \a st must be at least the size returned by * opus_multistream_encoder_get_size(). * This is intended for applications which use their own allocator instead of * malloc. * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. * @see opus_multistream_encoder_create * @see opus_multistream_encoder_get_size * @param st OpusMSEncoder*: Multistream encoder state to initialize. * @param Fs opus_int32: Sampling rate of the input signal (in Hz). * This must be one of 8000, 12000, 16000, * 24000, or 48000. * @param channels int: Number of channels in the input signal. * This must be at most 255. * It may be greater than the number of * coded channels (streams + * coupled_streams). * @param streams int: The total number of streams to encode from the * input. * This must be no more than the number of channels. * @param coupled_streams int: Number of coupled (2 channel) streams * to encode. * This must be no larger than the total * number of streams. * Additionally, The total number of * encoded channels (streams + * coupled_streams) must be no * more than the number of input channels. * @param[in] mapping const unsigned char[channels]: Mapping from * encoded channels to input channels, as described in * @ref opus_multistream. As an extra constraint, the * multistream encoder does not allow encoding coupled * streams for which one channel is unused since this * is never a good idea. * @param application int: The target encoder application. * This must be one of the following: *
*
#OPUS_APPLICATION_VOIP
*
Process signal for improved speech intelligibility.
*
#OPUS_APPLICATION_AUDIO
*
Favor faithfulness to the original input.
*
#OPUS_APPLICATION_RESTRICTED_LOWDELAY
*
Configure the minimum possible coding delay by disabling certain modes * of operation.
*
* @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes) * on failure. */ OPUS_EXPORT int opus_multistream_encoder_init( OpusMSEncoder *st, opus_int32 Fs, int channels, int streams, int coupled_streams, const unsigned char *mapping, int application ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6); OPUS_EXPORT int opus_multistream_surround_encoder_init( OpusMSEncoder *st, opus_int32 Fs, int channels, int mapping_family, int *streams, int *coupled_streams, unsigned char *mapping, int application ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(5) OPUS_ARG_NONNULL(6) OPUS_ARG_NONNULL(7); /** Encodes a multistream Opus frame. * @param st OpusMSEncoder*: Multistream encoder state. * @param[in] pcm const opus_int16*: The input signal as interleaved * samples. * This must contain * frame_size*channels * samples. * @param frame_size int: Number of samples per channel in the input * signal. * This must be an Opus frame size for the * encoder's sampling rate. * For example, at 48 kHz the permitted values * are 120, 240, 480, 960, 1920, and 2880. * Passing in a duration of less than 10 ms * (480 samples at 48 kHz) will prevent the * encoder from using the LPC or hybrid modes. * @param[out] data unsigned char*: Output payload. * This must contain storage for at * least \a max_data_bytes. * @param [in] max_data_bytes opus_int32: Size of the allocated * memory for the output * payload. This may be * used to impose an upper limit on * the instant bitrate, but should * not be used as the only bitrate * control. Use #OPUS_SET_BITRATE to * control the bitrate. * @returns The length of the encoded packet (in bytes) on success or a * negative error code (see @ref opus_errorcodes) on failure. */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode( OpusMSEncoder *st, const opus_int16 *pcm, int frame_size, unsigned char *data, opus_int32 max_data_bytes ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); /** Encodes a multistream Opus frame from floating point input. * @param st OpusMSEncoder*: Multistream encoder state. * @param[in] pcm const float*: The input signal as interleaved * samples with a normal range of * +/-1.0. * Samples with a range beyond +/-1.0 * are supported but will be clipped by * decoders using the integer API and * should only be used if it is known * that the far end supports extended * dynamic range. * This must contain * frame_size*channels * samples. * @param frame_size int: Number of samples per channel in the input * signal. * This must be an Opus frame size for the * encoder's sampling rate. * For example, at 48 kHz the permitted values * are 120, 240, 480, 960, 1920, and 2880. * Passing in a duration of less than 10 ms * (480 samples at 48 kHz) will prevent the * encoder from using the LPC or hybrid modes. * @param[out] data unsigned char*: Output payload. * This must contain storage for at * least \a max_data_bytes. * @param [in] max_data_bytes opus_int32: Size of the allocated * memory for the output * payload. This may be * used to impose an upper limit on * the instant bitrate, but should * not be used as the only bitrate * control. Use #OPUS_SET_BITRATE to * control the bitrate. * @returns The length of the encoded packet (in bytes) on success or a * negative error code (see @ref opus_errorcodes) on failure. */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode_float( OpusMSEncoder *st, const float *pcm, int frame_size, unsigned char *data, opus_int32 max_data_bytes ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); /** Frees an OpusMSEncoder allocated by * opus_multistream_encoder_create(). * @param st OpusMSEncoder*: Multistream encoder state to be freed. */ OPUS_EXPORT void opus_multistream_encoder_destroy(OpusMSEncoder *st); /** Perform a CTL function on a multistream Opus encoder. * * Generally the request and subsequent arguments are generated by a * convenience macro. * @param st OpusMSEncoder*: Multistream encoder state. * @param request This and all remaining parameters should be replaced by one * of the convenience macros in @ref opus_genericctls, * @ref opus_encoderctls, or @ref opus_multistream_ctls. * @see opus_genericctls * @see opus_encoderctls * @see opus_multistream_ctls */ OPUS_EXPORT int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...) OPUS_ARG_NONNULL(1); /**@}*/ /**\name Multistream decoder functions */ /**@{*/ /** Gets the size of an OpusMSDecoder structure. * @param streams int: The total number of streams coded in the * input. * This must be no more than 255. * @param coupled_streams int: Number streams to decode as coupled * (2 channel) streams. * This must be no larger than the total * number of streams. * Additionally, The total number of * coded channels (streams + * coupled_streams) must be no * more than 255. * @returns The size in bytes on success, or a negative error code * (see @ref opus_errorcodes) on error. */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_decoder_get_size( int streams, int coupled_streams ); /** Allocates and initializes a multistream decoder state. * Call opus_multistream_decoder_destroy() to release * this object when finished. * @param Fs opus_int32: Sampling rate to decode at (in Hz). * This must be one of 8000, 12000, 16000, * 24000, or 48000. * @param channels int: Number of channels to output. * This must be at most 255. * It may be different from the number of coded * channels (streams + * coupled_streams). * @param streams int: The total number of streams coded in the * input. * This must be no more than 255. * @param coupled_streams int: Number of streams to decode as coupled * (2 channel) streams. * This must be no larger than the total * number of streams. * Additionally, The total number of * coded channels (streams + * coupled_streams) must be no * more than 255. * @param[in] mapping const unsigned char[channels]: Mapping from * coded channels to output channels, as described in * @ref opus_multistream. * @param[out] error int *: Returns #OPUS_OK on success, or an error * code (see @ref opus_errorcodes) on * failure. */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSDecoder *opus_multistream_decoder_create( opus_int32 Fs, int channels, int streams, int coupled_streams, const unsigned char *mapping, int *error ) OPUS_ARG_NONNULL(5); /** Initialize a previously allocated decoder state object. * The memory pointed to by \a st must be at least the size returned by * opus_multistream_encoder_get_size(). * This is intended for applications which use their own allocator instead of * malloc. * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. * @see opus_multistream_decoder_create * @see opus_multistream_deocder_get_size * @param st OpusMSEncoder*: Multistream encoder state to initialize. * @param Fs opus_int32: Sampling rate to decode at (in Hz). * This must be one of 8000, 12000, 16000, * 24000, or 48000. * @param channels int: Number of channels to output. * This must be at most 255. * It may be different from the number of coded * channels (streams + * coupled_streams). * @param streams int: The total number of streams coded in the * input. * This must be no more than 255. * @param coupled_streams int: Number of streams to decode as coupled * (2 channel) streams. * This must be no larger than the total * number of streams. * Additionally, The total number of * coded channels (streams + * coupled_streams) must be no * more than 255. * @param[in] mapping const unsigned char[channels]: Mapping from * coded channels to output channels, as described in * @ref opus_multistream. * @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes) * on failure. */ OPUS_EXPORT int opus_multistream_decoder_init( OpusMSDecoder *st, opus_int32 Fs, int channels, int streams, int coupled_streams, const unsigned char *mapping ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6); /** Decode a multistream Opus packet. * @param st OpusMSDecoder*: Multistream decoder state. * @param[in] data const unsigned char*: Input payload. * Use a NULL * pointer to indicate packet * loss. * @param len opus_int32: Number of bytes in payload. * @param[out] pcm opus_int16*: Output signal, with interleaved * samples. * This must contain room for * frame_size*channels * samples. * @param frame_size int: The number of samples per channel of * available space in \a pcm. * If this is less than the maximum packet duration * (120 ms; 5760 for 48kHz), this function will not be capable * of decoding some packets. In the case of PLC (data==NULL) * or FEC (decode_fec=1), then frame_size needs to be exactly * the duration of audio that is missing, otherwise the * decoder will not be in the optimal state to decode the * next incoming packet. For the PLC and FEC cases, frame_size * must be a multiple of 2.5 ms. * @param decode_fec int: Flag (0 or 1) to request that any in-band * forward error correction data be decoded. * If no such data is available, the frame is * decoded as if it were lost. * @returns Number of samples decoded on success or a negative error code * (see @ref opus_errorcodes) on failure. */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode( OpusMSDecoder *st, const unsigned char *data, opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); /** Decode a multistream Opus packet with floating point output. * @param st OpusMSDecoder*: Multistream decoder state. * @param[in] data const unsigned char*: Input payload. * Use a NULL * pointer to indicate packet * loss. * @param len opus_int32: Number of bytes in payload. * @param[out] pcm opus_int16*: Output signal, with interleaved * samples. * This must contain room for * frame_size*channels * samples. * @param frame_size int: The number of samples per channel of * available space in \a pcm. * If this is less than the maximum packet duration * (120 ms; 5760 for 48kHz), this function will not be capable * of decoding some packets. In the case of PLC (data==NULL) * or FEC (decode_fec=1), then frame_size needs to be exactly * the duration of audio that is missing, otherwise the * decoder will not be in the optimal state to decode the * next incoming packet. For the PLC and FEC cases, frame_size * must be a multiple of 2.5 ms. * @param decode_fec int: Flag (0 or 1) to request that any in-band * forward error correction data be decoded. * If no such data is available, the frame is * decoded as if it were lost. * @returns Number of samples decoded on success or a negative error code * (see @ref opus_errorcodes) on failure. */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode_float( OpusMSDecoder *st, const unsigned char *data, opus_int32 len, float *pcm, int frame_size, int decode_fec ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); /** Perform a CTL function on a multistream Opus decoder. * * Generally the request and subsequent arguments are generated by a * convenience macro. * @param st OpusMSDecoder*: Multistream decoder state. * @param request This and all remaining parameters should be replaced by one * of the convenience macros in @ref opus_genericctls, * @ref opus_decoderctls, or @ref opus_multistream_ctls. * @see opus_genericctls * @see opus_decoderctls * @see opus_multistream_ctls */ OPUS_EXPORT int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...) OPUS_ARG_NONNULL(1); /** Frees an OpusMSDecoder allocated by * opus_multistream_decoder_create(). * @param st OpusMSDecoder: Multistream decoder state to be freed. */ OPUS_EXPORT void opus_multistream_decoder_destroy(OpusMSDecoder *st); /**@}*/ /**@}*/ #ifdef __cplusplus } #endif #endif /* OPUS_MULTISTREAM_H */ jamulus-3.9.1+dfsg/libs/opus/include/opus_defines.h0000644000175000017500000010412714340334543021357 0ustar vimervimer/* Copyright (c) 2010-2011 Xiph.Org Foundation, Skype Limited Written by Jean-Marc Valin and Koen Vos */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @file opus_defines.h * @brief Opus reference implementation constants */ #ifndef OPUS_DEFINES_H #define OPUS_DEFINES_H #include "opus_types.h" #ifdef __cplusplus extern "C" { #endif /** @defgroup opus_errorcodes Error codes * @{ */ /** No error @hideinitializer*/ #define OPUS_OK 0 /** One or more invalid/out of range arguments @hideinitializer*/ #define OPUS_BAD_ARG -1 /** Not enough bytes allocated in the buffer @hideinitializer*/ #define OPUS_BUFFER_TOO_SMALL -2 /** An internal error was detected @hideinitializer*/ #define OPUS_INTERNAL_ERROR -3 /** The compressed data passed is corrupted @hideinitializer*/ #define OPUS_INVALID_PACKET -4 /** Invalid/unsupported request number @hideinitializer*/ #define OPUS_UNIMPLEMENTED -5 /** An encoder or decoder structure is invalid or already freed @hideinitializer*/ #define OPUS_INVALID_STATE -6 /** Memory allocation has failed @hideinitializer*/ #define OPUS_ALLOC_FAIL -7 /**@}*/ /** @cond OPUS_INTERNAL_DOC */ /**Export control for opus functions */ #ifndef OPUS_EXPORT # if defined(WIN32) # if defined(OPUS_BUILD) && defined(DLL_EXPORT) # define OPUS_EXPORT __declspec(dllexport) # else # define OPUS_EXPORT # endif # elif defined(__GNUC__) && defined(OPUS_BUILD) # define OPUS_EXPORT __attribute__ ((visibility ("default"))) # else # define OPUS_EXPORT # endif #endif # if !defined(OPUS_GNUC_PREREQ) # if defined(__GNUC__)&&defined(__GNUC_MINOR__) # define OPUS_GNUC_PREREQ(_maj,_min) \ ((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min)) # else # define OPUS_GNUC_PREREQ(_maj,_min) 0 # endif # endif #if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) ) # if OPUS_GNUC_PREREQ(3,0) # define OPUS_RESTRICT __restrict__ # elif (defined(_MSC_VER) && _MSC_VER >= 1400) # define OPUS_RESTRICT __restrict # else # define OPUS_RESTRICT # endif #else # define OPUS_RESTRICT restrict #endif #if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) ) # if OPUS_GNUC_PREREQ(2,7) # define OPUS_INLINE __inline__ # elif (defined(_MSC_VER)) # define OPUS_INLINE __inline # else # define OPUS_INLINE # endif #else # define OPUS_INLINE inline #endif /**Warning attributes for opus functions * NONNULL is not used in OPUS_BUILD to avoid the compiler optimizing out * some paranoid null checks. */ #if defined(__GNUC__) && OPUS_GNUC_PREREQ(3, 4) # define OPUS_WARN_UNUSED_RESULT __attribute__ ((__warn_unused_result__)) #else # define OPUS_WARN_UNUSED_RESULT #endif #if !defined(OPUS_BUILD) && defined(__GNUC__) && OPUS_GNUC_PREREQ(3, 4) # define OPUS_ARG_NONNULL(_x) __attribute__ ((__nonnull__(_x))) #else # define OPUS_ARG_NONNULL(_x) #endif /** These are the actual Encoder CTL ID numbers. * They should not be used directly by applications. * In general, SETs should be even and GETs should be odd.*/ #define OPUS_SET_APPLICATION_REQUEST 4000 #define OPUS_GET_APPLICATION_REQUEST 4001 #define OPUS_SET_BITRATE_REQUEST 4002 #define OPUS_GET_BITRATE_REQUEST 4003 #define OPUS_SET_MAX_BANDWIDTH_REQUEST 4004 #define OPUS_GET_MAX_BANDWIDTH_REQUEST 4005 #define OPUS_SET_VBR_REQUEST 4006 #define OPUS_GET_VBR_REQUEST 4007 #define OPUS_SET_BANDWIDTH_REQUEST 4008 #define OPUS_GET_BANDWIDTH_REQUEST 4009 #define OPUS_SET_COMPLEXITY_REQUEST 4010 #define OPUS_GET_COMPLEXITY_REQUEST 4011 #define OPUS_SET_INBAND_FEC_REQUEST 4012 #define OPUS_GET_INBAND_FEC_REQUEST 4013 #define OPUS_SET_PACKET_LOSS_PERC_REQUEST 4014 #define OPUS_GET_PACKET_LOSS_PERC_REQUEST 4015 #define OPUS_SET_DTX_REQUEST 4016 #define OPUS_GET_DTX_REQUEST 4017 #define OPUS_SET_VBR_CONSTRAINT_REQUEST 4020 #define OPUS_GET_VBR_CONSTRAINT_REQUEST 4021 #define OPUS_SET_FORCE_CHANNELS_REQUEST 4022 #define OPUS_GET_FORCE_CHANNELS_REQUEST 4023 #define OPUS_SET_SIGNAL_REQUEST 4024 #define OPUS_GET_SIGNAL_REQUEST 4025 #define OPUS_GET_LOOKAHEAD_REQUEST 4027 /* #define OPUS_RESET_STATE 4028 */ #define OPUS_GET_SAMPLE_RATE_REQUEST 4029 #define OPUS_GET_FINAL_RANGE_REQUEST 4031 #define OPUS_GET_PITCH_REQUEST 4033 #define OPUS_SET_GAIN_REQUEST 4034 #define OPUS_GET_GAIN_REQUEST 4045 /* Should have been 4035 */ #define OPUS_SET_LSB_DEPTH_REQUEST 4036 #define OPUS_GET_LSB_DEPTH_REQUEST 4037 #define OPUS_GET_LAST_PACKET_DURATION_REQUEST 4039 #define OPUS_SET_EXPERT_FRAME_DURATION_REQUEST 4040 #define OPUS_GET_EXPERT_FRAME_DURATION_REQUEST 4041 #define OPUS_SET_PREDICTION_DISABLED_REQUEST 4042 #define OPUS_GET_PREDICTION_DISABLED_REQUEST 4043 /* Don't use 4045, it's already taken by OPUS_GET_GAIN_REQUEST */ #define OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST 4046 #define OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST 4047 #define OPUS_GET_IN_DTX_REQUEST 4049 /** Defines for the presence of extended APIs. */ #define OPUS_HAVE_OPUS_PROJECTION_H /* Macros to trigger compilation errors when the wrong types are provided to a CTL */ #define __opus_check_int(x) (((void)((x) == (opus_int32)0)), (opus_int32)(x)) #define __opus_check_int_ptr(ptr) ((ptr) + ((ptr) - (opus_int32*)(ptr))) #define __opus_check_uint_ptr(ptr) ((ptr) + ((ptr) - (opus_uint32*)(ptr))) #define __opus_check_val16_ptr(ptr) ((ptr) + ((ptr) - (opus_val16*)(ptr))) /** @endcond */ /** @defgroup opus_ctlvalues Pre-defined values for CTL interface * @see opus_genericctls, opus_encoderctls * @{ */ /* Values for the various encoder CTLs */ #define OPUS_AUTO -1000 /**opus_int32: Allowed values: 0-10, inclusive. * * @hideinitializer */ #define OPUS_SET_COMPLEXITY(x) OPUS_SET_COMPLEXITY_REQUEST, __opus_check_int(x) /** Gets the encoder's complexity configuration. * @see OPUS_SET_COMPLEXITY * @param[out] x opus_int32 *: Returns a value in the range 0-10, * inclusive. * @hideinitializer */ #define OPUS_GET_COMPLEXITY(x) OPUS_GET_COMPLEXITY_REQUEST, __opus_check_int_ptr(x) /** Configures the bitrate in the encoder. * Rates from 500 to 512000 bits per second are meaningful, as well as the * special values #OPUS_AUTO and #OPUS_BITRATE_MAX. * The value #OPUS_BITRATE_MAX can be used to cause the codec to use as much * rate as it can, which is useful for controlling the rate by adjusting the * output buffer size. * @see OPUS_GET_BITRATE * @param[in] x opus_int32: Bitrate in bits per second. The default * is determined based on the number of * channels and the input sampling rate. * @hideinitializer */ #define OPUS_SET_BITRATE(x) OPUS_SET_BITRATE_REQUEST, __opus_check_int(x) /** Gets the encoder's bitrate configuration. * @see OPUS_SET_BITRATE * @param[out] x opus_int32 *: Returns the bitrate in bits per second. * The default is determined based on the * number of channels and the input * sampling rate. * @hideinitializer */ #define OPUS_GET_BITRATE(x) OPUS_GET_BITRATE_REQUEST, __opus_check_int_ptr(x) /** Enables or disables variable bitrate (VBR) in the encoder. * The configured bitrate may not be met exactly because frames must * be an integer number of bytes in length. * @see OPUS_GET_VBR * @see OPUS_SET_VBR_CONSTRAINT * @param[in] x opus_int32: Allowed values: *
*
0
Hard CBR. For LPC/hybrid modes at very low bit-rate, this can * cause noticeable quality degradation.
*
1
VBR (default). The exact type of VBR is controlled by * #OPUS_SET_VBR_CONSTRAINT.
*
* @hideinitializer */ #define OPUS_SET_VBR(x) OPUS_SET_VBR_REQUEST, __opus_check_int(x) /** Determine if variable bitrate (VBR) is enabled in the encoder. * @see OPUS_SET_VBR * @see OPUS_GET_VBR_CONSTRAINT * @param[out] x opus_int32 *: Returns one of the following values: *
*
0
Hard CBR.
*
1
VBR (default). The exact type of VBR may be retrieved via * #OPUS_GET_VBR_CONSTRAINT.
*
* @hideinitializer */ #define OPUS_GET_VBR(x) OPUS_GET_VBR_REQUEST, __opus_check_int_ptr(x) /** Enables or disables constrained VBR in the encoder. * This setting is ignored when the encoder is in CBR mode. * @warning Only the MDCT mode of Opus currently heeds the constraint. * Speech mode ignores it completely, hybrid mode may fail to obey it * if the LPC layer uses more bitrate than the constraint would have * permitted. * @see OPUS_GET_VBR_CONSTRAINT * @see OPUS_SET_VBR * @param[in] x opus_int32: Allowed values: *
*
0
Unconstrained VBR.
*
1
Constrained VBR (default). This creates a maximum of one * frame of buffering delay assuming a transport with a * serialization speed of the nominal bitrate.
*
* @hideinitializer */ #define OPUS_SET_VBR_CONSTRAINT(x) OPUS_SET_VBR_CONSTRAINT_REQUEST, __opus_check_int(x) /** Determine if constrained VBR is enabled in the encoder. * @see OPUS_SET_VBR_CONSTRAINT * @see OPUS_GET_VBR * @param[out] x opus_int32 *: Returns one of the following values: *
*
0
Unconstrained VBR.
*
1
Constrained VBR (default).
*
* @hideinitializer */ #define OPUS_GET_VBR_CONSTRAINT(x) OPUS_GET_VBR_CONSTRAINT_REQUEST, __opus_check_int_ptr(x) /** Configures mono/stereo forcing in the encoder. * This can force the encoder to produce packets encoded as either mono or * stereo, regardless of the format of the input audio. This is useful when * the caller knows that the input signal is currently a mono source embedded * in a stereo stream. * @see OPUS_GET_FORCE_CHANNELS * @param[in] x opus_int32: Allowed values: *
*
#OPUS_AUTO
Not forced (default)
*
1
Forced mono
*
2
Forced stereo
*
* @hideinitializer */ #define OPUS_SET_FORCE_CHANNELS(x) OPUS_SET_FORCE_CHANNELS_REQUEST, __opus_check_int(x) /** Gets the encoder's forced channel configuration. * @see OPUS_SET_FORCE_CHANNELS * @param[out] x opus_int32 *: *
*
#OPUS_AUTO
Not forced (default)
*
1
Forced mono
*
2
Forced stereo
*
* @hideinitializer */ #define OPUS_GET_FORCE_CHANNELS(x) OPUS_GET_FORCE_CHANNELS_REQUEST, __opus_check_int_ptr(x) /** Configures the maximum bandpass that the encoder will select automatically. * Applications should normally use this instead of #OPUS_SET_BANDWIDTH * (leaving that set to the default, #OPUS_AUTO). This allows the * application to set an upper bound based on the type of input it is * providing, but still gives the encoder the freedom to reduce the bandpass * when the bitrate becomes too low, for better overall quality. * @see OPUS_GET_MAX_BANDWIDTH * @param[in] x opus_int32: Allowed values: *
*
OPUS_BANDWIDTH_NARROWBAND
4 kHz passband
*
OPUS_BANDWIDTH_MEDIUMBAND
6 kHz passband
*
OPUS_BANDWIDTH_WIDEBAND
8 kHz passband
*
OPUS_BANDWIDTH_SUPERWIDEBAND
12 kHz passband
*
OPUS_BANDWIDTH_FULLBAND
20 kHz passband (default)
*
* @hideinitializer */ #define OPUS_SET_MAX_BANDWIDTH(x) OPUS_SET_MAX_BANDWIDTH_REQUEST, __opus_check_int(x) /** Gets the encoder's configured maximum allowed bandpass. * @see OPUS_SET_MAX_BANDWIDTH * @param[out] x opus_int32 *: Allowed values: *
*
#OPUS_BANDWIDTH_NARROWBAND
4 kHz passband
*
#OPUS_BANDWIDTH_MEDIUMBAND
6 kHz passband
*
#OPUS_BANDWIDTH_WIDEBAND
8 kHz passband
*
#OPUS_BANDWIDTH_SUPERWIDEBAND
12 kHz passband
*
#OPUS_BANDWIDTH_FULLBAND
20 kHz passband (default)
*
* @hideinitializer */ #define OPUS_GET_MAX_BANDWIDTH(x) OPUS_GET_MAX_BANDWIDTH_REQUEST, __opus_check_int_ptr(x) /** Sets the encoder's bandpass to a specific value. * This prevents the encoder from automatically selecting the bandpass based * on the available bitrate. If an application knows the bandpass of the input * audio it is providing, it should normally use #OPUS_SET_MAX_BANDWIDTH * instead, which still gives the encoder the freedom to reduce the bandpass * when the bitrate becomes too low, for better overall quality. * @see OPUS_GET_BANDWIDTH * @param[in] x opus_int32: Allowed values: *
*
#OPUS_AUTO
(default)
*
#OPUS_BANDWIDTH_NARROWBAND
4 kHz passband
*
#OPUS_BANDWIDTH_MEDIUMBAND
6 kHz passband
*
#OPUS_BANDWIDTH_WIDEBAND
8 kHz passband
*
#OPUS_BANDWIDTH_SUPERWIDEBAND
12 kHz passband
*
#OPUS_BANDWIDTH_FULLBAND
20 kHz passband
*
* @hideinitializer */ #define OPUS_SET_BANDWIDTH(x) OPUS_SET_BANDWIDTH_REQUEST, __opus_check_int(x) /** Configures the type of signal being encoded. * This is a hint which helps the encoder's mode selection. * @see OPUS_GET_SIGNAL * @param[in] x opus_int32: Allowed values: *
*
#OPUS_AUTO
(default)
*
#OPUS_SIGNAL_VOICE
Bias thresholds towards choosing LPC or Hybrid modes.
*
#OPUS_SIGNAL_MUSIC
Bias thresholds towards choosing MDCT modes.
*
* @hideinitializer */ #define OPUS_SET_SIGNAL(x) OPUS_SET_SIGNAL_REQUEST, __opus_check_int(x) /** Gets the encoder's configured signal type. * @see OPUS_SET_SIGNAL * @param[out] x opus_int32 *: Returns one of the following values: *
*
#OPUS_AUTO
(default)
*
#OPUS_SIGNAL_VOICE
Bias thresholds towards choosing LPC or Hybrid modes.
*
#OPUS_SIGNAL_MUSIC
Bias thresholds towards choosing MDCT modes.
*
* @hideinitializer */ #define OPUS_GET_SIGNAL(x) OPUS_GET_SIGNAL_REQUEST, __opus_check_int_ptr(x) /** Configures the encoder's intended application. * The initial value is a mandatory argument to the encoder_create function. * @see OPUS_GET_APPLICATION * @param[in] x opus_int32: Returns one of the following values: *
*
#OPUS_APPLICATION_VOIP
*
Process signal for improved speech intelligibility.
*
#OPUS_APPLICATION_AUDIO
*
Favor faithfulness to the original input.
*
#OPUS_APPLICATION_RESTRICTED_LOWDELAY
*
Configure the minimum possible coding delay by disabling certain modes * of operation.
*
* @hideinitializer */ #define OPUS_SET_APPLICATION(x) OPUS_SET_APPLICATION_REQUEST, __opus_check_int(x) /** Gets the encoder's configured application. * @see OPUS_SET_APPLICATION * @param[out] x opus_int32 *: Returns one of the following values: *
*
#OPUS_APPLICATION_VOIP
*
Process signal for improved speech intelligibility.
*
#OPUS_APPLICATION_AUDIO
*
Favor faithfulness to the original input.
*
#OPUS_APPLICATION_RESTRICTED_LOWDELAY
*
Configure the minimum possible coding delay by disabling certain modes * of operation.
*
* @hideinitializer */ #define OPUS_GET_APPLICATION(x) OPUS_GET_APPLICATION_REQUEST, __opus_check_int_ptr(x) /** Gets the total samples of delay added by the entire codec. * This can be queried by the encoder and then the provided number of samples can be * skipped on from the start of the decoder's output to provide time aligned input * and output. From the perspective of a decoding application the real data begins this many * samples late. * * The decoder contribution to this delay is identical for all decoders, but the * encoder portion of the delay may vary from implementation to implementation, * version to version, or even depend on the encoder's initial configuration. * Applications needing delay compensation should call this CTL rather than * hard-coding a value. * @param[out] x opus_int32 *: Number of lookahead samples * @hideinitializer */ #define OPUS_GET_LOOKAHEAD(x) OPUS_GET_LOOKAHEAD_REQUEST, __opus_check_int_ptr(x) /** Configures the encoder's use of inband forward error correction (FEC). * @note This is only applicable to the LPC layer * @see OPUS_GET_INBAND_FEC * @param[in] x opus_int32: Allowed values: *
*
0
Disable inband FEC (default).
*
1
Enable inband FEC.
*
* @hideinitializer */ #define OPUS_SET_INBAND_FEC(x) OPUS_SET_INBAND_FEC_REQUEST, __opus_check_int(x) /** Gets encoder's configured use of inband forward error correction. * @see OPUS_SET_INBAND_FEC * @param[out] x opus_int32 *: Returns one of the following values: *
*
0
Inband FEC disabled (default).
*
1
Inband FEC enabled.
*
* @hideinitializer */ #define OPUS_GET_INBAND_FEC(x) OPUS_GET_INBAND_FEC_REQUEST, __opus_check_int_ptr(x) /** Configures the encoder's expected packet loss percentage. * Higher values trigger progressively more loss resistant behavior in the encoder * at the expense of quality at a given bitrate in the absence of packet loss, but * greater quality under loss. * @see OPUS_GET_PACKET_LOSS_PERC * @param[in] x opus_int32: Loss percentage in the range 0-100, inclusive (default: 0). * @hideinitializer */ #define OPUS_SET_PACKET_LOSS_PERC(x) OPUS_SET_PACKET_LOSS_PERC_REQUEST, __opus_check_int(x) /** Gets the encoder's configured packet loss percentage. * @see OPUS_SET_PACKET_LOSS_PERC * @param[out] x opus_int32 *: Returns the configured loss percentage * in the range 0-100, inclusive (default: 0). * @hideinitializer */ #define OPUS_GET_PACKET_LOSS_PERC(x) OPUS_GET_PACKET_LOSS_PERC_REQUEST, __opus_check_int_ptr(x) /** Configures the encoder's use of discontinuous transmission (DTX). * @note This is only applicable to the LPC layer * @see OPUS_GET_DTX * @param[in] x opus_int32: Allowed values: *
*
0
Disable DTX (default).
*
1
Enabled DTX.
*
* @hideinitializer */ #define OPUS_SET_DTX(x) OPUS_SET_DTX_REQUEST, __opus_check_int(x) /** Gets encoder's configured use of discontinuous transmission. * @see OPUS_SET_DTX * @param[out] x opus_int32 *: Returns one of the following values: *
*
0
DTX disabled (default).
*
1
DTX enabled.
*
* @hideinitializer */ #define OPUS_GET_DTX(x) OPUS_GET_DTX_REQUEST, __opus_check_int_ptr(x) /** Configures the depth of signal being encoded. * * This is a hint which helps the encoder identify silence and near-silence. * It represents the number of significant bits of linear intensity below * which the signal contains ignorable quantization or other noise. * * For example, OPUS_SET_LSB_DEPTH(14) would be an appropriate setting * for G.711 u-law input. OPUS_SET_LSB_DEPTH(16) would be appropriate * for 16-bit linear pcm input with opus_encode_float(). * * When using opus_encode() instead of opus_encode_float(), or when libopus * is compiled for fixed-point, the encoder uses the minimum of the value * set here and the value 16. * * @see OPUS_GET_LSB_DEPTH * @param[in] x opus_int32: Input precision in bits, between 8 and 24 * (default: 24). * @hideinitializer */ #define OPUS_SET_LSB_DEPTH(x) OPUS_SET_LSB_DEPTH_REQUEST, __opus_check_int(x) /** Gets the encoder's configured signal depth. * @see OPUS_SET_LSB_DEPTH * @param[out] x opus_int32 *: Input precision in bits, between 8 and * 24 (default: 24). * @hideinitializer */ #define OPUS_GET_LSB_DEPTH(x) OPUS_GET_LSB_DEPTH_REQUEST, __opus_check_int_ptr(x) /** Configures the encoder's use of variable duration frames. * When variable duration is enabled, the encoder is free to use a shorter frame * size than the one requested in the opus_encode*() call. * It is then the user's responsibility * to verify how much audio was encoded by checking the ToC byte of the encoded * packet. The part of the audio that was not encoded needs to be resent to the * encoder for the next call. Do not use this option unless you really * know what you are doing. * @see OPUS_GET_EXPERT_FRAME_DURATION * @param[in] x opus_int32: Allowed values: *
*
OPUS_FRAMESIZE_ARG
Select frame size from the argument (default).
*
OPUS_FRAMESIZE_2_5_MS
Use 2.5 ms frames.
*
OPUS_FRAMESIZE_5_MS
Use 5 ms frames.
*
OPUS_FRAMESIZE_10_MS
Use 10 ms frames.
*
OPUS_FRAMESIZE_20_MS
Use 20 ms frames.
*
OPUS_FRAMESIZE_40_MS
Use 40 ms frames.
*
OPUS_FRAMESIZE_60_MS
Use 60 ms frames.
*
OPUS_FRAMESIZE_80_MS
Use 80 ms frames.
*
OPUS_FRAMESIZE_100_MS
Use 100 ms frames.
*
OPUS_FRAMESIZE_120_MS
Use 120 ms frames.
*
* @hideinitializer */ #define OPUS_SET_EXPERT_FRAME_DURATION(x) OPUS_SET_EXPERT_FRAME_DURATION_REQUEST, __opus_check_int(x) /** Gets the encoder's configured use of variable duration frames. * @see OPUS_SET_EXPERT_FRAME_DURATION * @param[out] x opus_int32 *: Returns one of the following values: *
*
OPUS_FRAMESIZE_ARG
Select frame size from the argument (default).
*
OPUS_FRAMESIZE_2_5_MS
Use 2.5 ms frames.
*
OPUS_FRAMESIZE_5_MS
Use 5 ms frames.
*
OPUS_FRAMESIZE_10_MS
Use 10 ms frames.
*
OPUS_FRAMESIZE_20_MS
Use 20 ms frames.
*
OPUS_FRAMESIZE_40_MS
Use 40 ms frames.
*
OPUS_FRAMESIZE_60_MS
Use 60 ms frames.
*
OPUS_FRAMESIZE_80_MS
Use 80 ms frames.
*
OPUS_FRAMESIZE_100_MS
Use 100 ms frames.
*
OPUS_FRAMESIZE_120_MS
Use 120 ms frames.
*
* @hideinitializer */ #define OPUS_GET_EXPERT_FRAME_DURATION(x) OPUS_GET_EXPERT_FRAME_DURATION_REQUEST, __opus_check_int_ptr(x) /** If set to 1, disables almost all use of prediction, making frames almost * completely independent. This reduces quality. * @see OPUS_GET_PREDICTION_DISABLED * @param[in] x opus_int32: Allowed values: *
*
0
Enable prediction (default).
*
1
Disable prediction.
*
* @hideinitializer */ #define OPUS_SET_PREDICTION_DISABLED(x) OPUS_SET_PREDICTION_DISABLED_REQUEST, __opus_check_int(x) /** Gets the encoder's configured prediction status. * @see OPUS_SET_PREDICTION_DISABLED * @param[out] x opus_int32 *: Returns one of the following values: *
*
0
Prediction enabled (default).
*
1
Prediction disabled.
*
* @hideinitializer */ #define OPUS_GET_PREDICTION_DISABLED(x) OPUS_GET_PREDICTION_DISABLED_REQUEST, __opus_check_int_ptr(x) /**@}*/ /** @defgroup opus_genericctls Generic CTLs * * These macros are used with the \c opus_decoder_ctl and * \c opus_encoder_ctl calls to generate a particular * request. * * When called on an \c OpusDecoder they apply to that * particular decoder instance. When called on an * \c OpusEncoder they apply to the corresponding setting * on that encoder instance, if present. * * Some usage examples: * * @code * int ret; * opus_int32 pitch; * ret = opus_decoder_ctl(dec_ctx, OPUS_GET_PITCH(&pitch)); * if (ret == OPUS_OK) return ret; * * opus_encoder_ctl(enc_ctx, OPUS_RESET_STATE); * opus_decoder_ctl(dec_ctx, OPUS_RESET_STATE); * * opus_int32 enc_bw, dec_bw; * opus_encoder_ctl(enc_ctx, OPUS_GET_BANDWIDTH(&enc_bw)); * opus_decoder_ctl(dec_ctx, OPUS_GET_BANDWIDTH(&dec_bw)); * if (enc_bw != dec_bw) { * printf("packet bandwidth mismatch!\n"); * } * @endcode * * @see opus_encoder, opus_decoder_ctl, opus_encoder_ctl, opus_decoderctls, opus_encoderctls * @{ */ /** Resets the codec state to be equivalent to a freshly initialized state. * This should be called when switching streams in order to prevent * the back to back decoding from giving different results from * one at a time decoding. * @hideinitializer */ #define OPUS_RESET_STATE 4028 /** Gets the final state of the codec's entropy coder. * This is used for testing purposes, * The encoder and decoder state should be identical after coding a payload * (assuming no data corruption or software bugs) * * @param[out] x opus_uint32 *: Entropy coder state * * @hideinitializer */ #define OPUS_GET_FINAL_RANGE(x) OPUS_GET_FINAL_RANGE_REQUEST, __opus_check_uint_ptr(x) /** Gets the encoder's configured bandpass or the decoder's last bandpass. * @see OPUS_SET_BANDWIDTH * @param[out] x opus_int32 *: Returns one of the following values: *
*
#OPUS_AUTO
(default)
*
#OPUS_BANDWIDTH_NARROWBAND
4 kHz passband
*
#OPUS_BANDWIDTH_MEDIUMBAND
6 kHz passband
*
#OPUS_BANDWIDTH_WIDEBAND
8 kHz passband
*
#OPUS_BANDWIDTH_SUPERWIDEBAND
12 kHz passband
*
#OPUS_BANDWIDTH_FULLBAND
20 kHz passband
*
* @hideinitializer */ #define OPUS_GET_BANDWIDTH(x) OPUS_GET_BANDWIDTH_REQUEST, __opus_check_int_ptr(x) /** Gets the sampling rate the encoder or decoder was initialized with. * This simply returns the Fs value passed to opus_encoder_init() * or opus_decoder_init(). * @param[out] x opus_int32 *: Sampling rate of encoder or decoder. * @hideinitializer */ #define OPUS_GET_SAMPLE_RATE(x) OPUS_GET_SAMPLE_RATE_REQUEST, __opus_check_int_ptr(x) /** If set to 1, disables the use of phase inversion for intensity stereo, * improving the quality of mono downmixes, but slightly reducing normal * stereo quality. Disabling phase inversion in the decoder does not comply * with RFC 6716, although it does not cause any interoperability issue and * is expected to become part of the Opus standard once RFC 6716 is updated * by draft-ietf-codec-opus-update. * @see OPUS_GET_PHASE_INVERSION_DISABLED * @param[in] x opus_int32: Allowed values: *
*
0
Enable phase inversion (default).
*
1
Disable phase inversion.
*
* @hideinitializer */ #define OPUS_SET_PHASE_INVERSION_DISABLED(x) OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST, __opus_check_int(x) /** Gets the encoder's configured phase inversion status. * @see OPUS_SET_PHASE_INVERSION_DISABLED * @param[out] x opus_int32 *: Returns one of the following values: *
*
0
Stereo phase inversion enabled (default).
*
1
Stereo phase inversion disabled.
*
* @hideinitializer */ #define OPUS_GET_PHASE_INVERSION_DISABLED(x) OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST, __opus_check_int_ptr(x) /** Gets the DTX state of the encoder. * Returns whether the last encoded frame was either a comfort noise update * during DTX or not encoded because of DTX. * @param[out] x opus_int32 *: Returns one of the following values: *
*
0
The encoder is not in DTX.
*
1
The encoder is in DTX.
*
* @hideinitializer */ #define OPUS_GET_IN_DTX(x) OPUS_GET_IN_DTX_REQUEST, __opus_check_int_ptr(x) /**@}*/ /** @defgroup opus_decoderctls Decoder related CTLs * @see opus_genericctls, opus_encoderctls, opus_decoder * @{ */ /** Configures decoder gain adjustment. * Scales the decoded output by a factor specified in Q8 dB units. * This has a maximum range of -32768 to 32767 inclusive, and returns * OPUS_BAD_ARG otherwise. The default is zero indicating no adjustment. * This setting survives decoder reset. * * gain = pow(10, x/(20.0*256)) * * @param[in] x opus_int32: Amount to scale PCM signal by in Q8 dB units. * @hideinitializer */ #define OPUS_SET_GAIN(x) OPUS_SET_GAIN_REQUEST, __opus_check_int(x) /** Gets the decoder's configured gain adjustment. @see OPUS_SET_GAIN * * @param[out] x opus_int32 *: Amount to scale PCM signal by in Q8 dB units. * @hideinitializer */ #define OPUS_GET_GAIN(x) OPUS_GET_GAIN_REQUEST, __opus_check_int_ptr(x) /** Gets the duration (in samples) of the last packet successfully decoded or concealed. * @param[out] x opus_int32 *: Number of samples (at current sampling rate). * @hideinitializer */ #define OPUS_GET_LAST_PACKET_DURATION(x) OPUS_GET_LAST_PACKET_DURATION_REQUEST, __opus_check_int_ptr(x) /** Gets the pitch of the last decoded frame, if available. * This can be used for any post-processing algorithm requiring the use of pitch, * e.g. time stretching/shortening. If the last frame was not voiced, or if the * pitch was not coded in the frame, then zero is returned. * * This CTL is only implemented for decoder instances. * * @param[out] x opus_int32 *: pitch period at 48 kHz (or 0 if not available) * * @hideinitializer */ #define OPUS_GET_PITCH(x) OPUS_GET_PITCH_REQUEST, __opus_check_int_ptr(x) /**@}*/ /** @defgroup opus_libinfo Opus library information functions * @{ */ /** Converts an opus error code into a human readable string. * * @param[in] error int: Error number * @returns Error string */ OPUS_EXPORT const char *opus_strerror(int error); /** Gets the libopus version string. * * Applications may look for the substring "-fixed" in the version string to * determine whether they have a fixed-point or floating-point build at * runtime. * * @returns Version string */ OPUS_EXPORT const char *opus_get_version_string(void); /**@}*/ #ifdef __cplusplus } #endif #endif /* OPUS_DEFINES_H */ jamulus-3.9.1+dfsg/libs/opus/CMakeLists.txt0000644000175000017500000003565514340334543017651 0ustar vimervimercmake_minimum_required(VERSION 3.1) include(opus_functions.cmake) get_library_version(OPUS_LIBRARY_VERSION OPUS_LIBRARY_VERSION_MAJOR) message(STATUS "Opus library version: ${OPUS_LIBRARY_VERSION}") get_package_version(PACKAGE_VERSION) message(STATUS "Opus package version: ${PACKAGE_VERSION}") string(REGEX REPLACE "^([0-9]+.[0-9]+\\.?([0-9]+)?).*" "\\1" PROJECT_VERSION ${PACKAGE_VERSION}) message(STATUS "Opus project version: ${PROJECT_VERSION}") project(Opus LANGUAGES C VERSION ${PROJECT_VERSION}) include(opus_buildtype.cmake) option(OPUS_STACK_PROTECTOR "Use stack protection" ON) option(OPUS_USE_ALLOCA "Use alloca for stack arrays (on non-C99 compilers)" OFF) option(OPUS_CUSTOM_MODES "Enable non-Opus modes, e.g. 44.1 kHz & 2^n frames" OFF) option(OPUS_BUILD_PROGRAMS "Build programs" OFF) option(OPUS_FIXED_POINT "Compile as fixed-point (for machines without a fast enough FPU)" OFF) option(OPUS_ENABLE_FLOAT_API "Compile with the floating point API (for machines with float library" ON) option(OPUS_INSTALL_PKG_CONFIG_MODULE "Install PkgConfig module" ON) option(OPUS_INSTALL_CMAKE_CONFIG_MODULE "Install CMake package config module" ON) include(opus_config.cmake) include(opus_sources.cmake) include(GNUInstallDirs) include(CMakeDependentOption) include(FeatureSummary) if(OPUS_STACK_PROTECTOR) if(NOT MSVC) # GC on by default on MSVC check_and_set_flag(STACK_PROTECTION_STRONG -fstack-protector-strong) endif() else() if(MSVC) check_and_set_flag(BUFFER_SECURITY_CHECK /GS-) endif() endif() if(OPUS_CPU_X86 OR OPUS_CPU_X64) cmake_dependent_option(OPUS_X86_MAY_HAVE_SSE "Does runtime check for SSE1 support" ON "SSE1_SUPPORTED" OFF) cmake_dependent_option(OPUS_X86_MAY_HAVE_SSE2 "Does runtime check for SSE2 support" ON "SSE2_SUPPORTED" OFF) cmake_dependent_option(OPUS_X86_MAY_HAVE_SSE4_1 "Does runtime check for SSE4.1 support" ON "SSE4_1_SUPPORTED" OFF) cmake_dependent_option(OPUS_X86_MAY_HAVE_AVX "Does runtime check for AVX support" ON "AVX_SUPPORTED" OFF) if(OPUS_CPU_X64) # Assume 64 bit has SSE2 support cmake_dependent_option(OPUS_X86_PRESUME_SSE "Assume target CPU has SSE1 support" ON "OPUS_X86_MAY_HAVE_SSE" OFF) cmake_dependent_option(OPUS_X86_PRESUME_SSE2 "Assume target CPU has SSE2 support" ON "OPUS_X86_MAY_HAVE_SSE2" OFF) else() cmake_dependent_option(OPUS_X86_PRESUME_SSE "Assume target CPU has SSE1 support" OFF "OPUS_X86_MAY_HAVE_SSE" OFF) cmake_dependent_option(OPUS_X86_PRESUME_SSE2 "Assume target CPU has SSE2 support" OFF "OPUS_X86_MAY_HAVE_SSE2" OFF) endif() cmake_dependent_option(OPUS_X86_PRESUME_SSE4_1 "Assume target CPU has SSE4.1 support" OFF "OPUS_X86_MAY_HAVE_SSE4_1" OFF) cmake_dependent_option(OPUS_X86_PRESUME_AVX "Assume target CPU has AVX support" OFF "OPUS_X86_MAY_HAVE_AVX" OFF) endif() set_package_properties(Git PROPERTIES TYPE REQUIRED DESCRIPTION "fast, scalable, distributed revision control system" URL "https://git-scm.com/" PURPOSE "required to set up package version") add_feature_info(STACK_PROTECTOR OPUS_STACK_PROTECTOR "Use stack protection") add_feature_info(USE_ALLOCA OPUS_USE_ALLOCA "Use alloca for stack arrays (on non-C99 compilers)") add_feature_info(CUSTOM_MODES OPUS_CUSTOM_MODES "Enable non-Opus modes, e.g. 44.1 kHz & 2^n frames") add_feature_info(BUILD_PROGRAMS OPUS_BUILD_PROGRAMS "Build programs") add_feature_info( FIXED_POINT OPUS_FIXED_POINT "compile as fixed-point (for machines without a fast enough FPU)") add_feature_info( FLOAT_API OPUS_ENABLE_FLOAT_API "compile with the floating point API (for machines with float library)") add_feature_info(INSTALL_PKG_CONFIG_MODULE OPUS_INSTALL_PKG_CONFIG_MODULE "install PkgConfig module") add_feature_info(INSTALL_CMAKE_CONFIG_MODULE OPUS_INSTALL_CMAKE_CONFIG_MODULE "install CMake package config module") if(OPUS_CPU_X86 OR OPUS_CPU_X64) add_feature_info(X86_MAY_HAVE_SSE OPUS_X86_MAY_HAVE_SSE "does runtime check for SSE1 support") add_feature_info(X86_MAY_HAVE_SSE2 OPUS_X86_MAY_HAVE_SSE2 "does runtime check for SSE2 support") add_feature_info(X86_MAY_HAVE_SSE4_1 OPUS_X86_MAY_HAVE_SSE4_1 "does runtime check for SSE4_1 support") add_feature_info(X86_MAY_HAVE_AVX OPUS_X86_MAY_HAVE_AVX "does runtime check for AVX support") add_feature_info(X86_PRESUME_SSE OPUS_X86_PRESUME_SSE "assume target CPU has SSE1 support") add_feature_info(X86_PRESUME_SSE2 OPUS_X86_PRESUME_SSE2 "assume target CPU has SSE2 support") add_feature_info(X86_PRESUME_SSE4_1 OPUS_X86_PRESUME_SSE4_1 "assume target CPU has SSE4_1 support") add_feature_info(X86_PRESUME_AVX OPUS_X86_PRESUME_AVX "assume target CPU has AVX support") endif() feature_summary(WHAT ALL) add_library(opus ${opus_sources} ${opus_sources_float}) set(Opus_PUBLIC_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/include/opus.h ${CMAKE_CURRENT_SOURCE_DIR}/include/opus_custom.h ${CMAKE_CURRENT_SOURCE_DIR}/include/opus_defines.h ${CMAKE_CURRENT_SOURCE_DIR}/include/opus_multistream.h ${CMAKE_CURRENT_SOURCE_DIR}/include/opus_projection.h ${CMAKE_CURRENT_SOURCE_DIR}/include/opus_types.h) set_target_properties(opus PROPERTIES SOVERSION ${OPUS_LIBRARY_VERSION_MAJOR} VERSION ${OPUS_LIBRARY_VERSION} PUBLIC_HEADER "${Opus_PUBLIC_HEADER}") target_include_directories( opus PUBLIC $ $ PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} celt silk) target_link_libraries(opus PRIVATE ${OPUS_REQUIRED_LIBRARIES}) target_compile_definitions(opus PRIVATE OPUS_BUILD ENABLE_HARDENING) if(NOT MSVC) target_compile_definitions(opus PRIVATE FORTIFY_SOURCE=2) endif() # It is strongly recommended to uncomment one of these VAR_ARRAYS: Use C99 # variable-length arrays for stack allocation USE_ALLOCA: Use alloca() for stack # allocation If none is defined, then the fallback is a non-threadsafe global # array if(OPUS_USE_ALLOCA OR MSVC) target_compile_definitions(opus PRIVATE USE_ALLOCA) else() target_compile_definitions(opus PRIVATE VAR_ARRAYS) endif() if(OPUS_CUSTOM_MODES) target_compile_definitions(opus PRIVATE CUSTOM_MODES) endif() if(BUILD_SHARED_LIBS) if(WIN32) target_compile_definitions(opus PRIVATE DLL_EXPORT) else() include(CheckCCompilerFlag) check_c_compiler_flag(-fvisibility=hidden COMPILER_HAS_HIDDEN_VISIBILITY) if(COMPILER_HAS_HIDDEN_VISIBILITY) set_target_properties(opus PROPERTIES C_VISIBILITY_PRESET hidden) endif() endif() endif() add_sources_group(opus silk ${silk_sources}) add_sources_group(opus celt ${celt_sources}) if(OPUS_FIXED_POINT) add_sources_group(opus silk ${silk_sources_fixed}) target_include_directories(opus PRIVATE silk/fixed) target_compile_definitions(opus PRIVATE FIXED_POINT=1) else() add_sources_group(opus silk ${silk_sources_float}) target_include_directories(opus PRIVATE silk/float) endif() if(NOT OPUS_ENABLE_FLOAT_API) target_compile_definitions(opus PRIVATE DISABLE_FLOAT_API) endif() if(OPUS_X86_MAY_HAVE_SSE OR OPUS_X86_MAY_HAVE_SSE2 OR OPUS_X86_MAY_HAVE_SSE4_1 OR OPUS_X86_MAY_HAVE_AVX) target_compile_definitions(opus PRIVATE OPUS_HAVE_RTCD) endif() if(OPUS_X86_MAY_HAVE_SSE) add_sources_group(opus celt ${celt_sources_sse}) target_compile_definitions(opus PRIVATE OPUS_X86_MAY_HAVE_SSE) endif() if(OPUS_X86_PRESUME_SSE) target_compile_definitions(opus PRIVATE OPUS_X86_PRESUME_SSE) endif() if(OPUS_X86_MAY_HAVE_SSE2) add_sources_group(opus celt ${celt_sources_sse2}) target_compile_definitions(opus PRIVATE OPUS_X86_MAY_HAVE_SSE2) endif() if(OPUS_X86_PRESUME_SSE2) target_compile_definitions(opus PRIVATE OPUS_X86_PRESUME_SSE2) endif() if(OPUS_X86_MAY_HAVE_SSE) add_sources_group(opus celt ${celt_sources_sse4_1}) add_sources_group(opus silk ${silk_sources_sse4_1}) if(OPUS_FIXED_POINT) add_sources_group(opus silk ${silk_sources_fixed_sse4_1}) endif() target_compile_definitions(opus PRIVATE OPUS_X86_MAY_HAVE_SSE4_1) endif() if(OPUS_X86_PRESUME_SSE4_1) target_compile_definitions(opus PRIVATE OPUS_X86_PRESUME_SSE4_1) endif() if(CMAKE_SYSTEM_PROCESSOR MATCHES "(armv7-a)") add_sources_group(opus celt ${celt_sources_arm}) endif() if(COMPILER_SUPPORT_NEON AND OPUS_USE_NEON) if(OPUS_MAY_HAVE_NEON) if(RUNTIME_CPU_CAPABILITY_DETECTION) message(STATUS "OPUS_MAY_HAVE_NEON enabling runtime detection") target_compile_definitions(opus PRIVATE OPUS_HAVE_RTCD) else() message(ERROR "Runtime cpu capability detection needed for MAY_HAVE_NEON") endif() # Do runtime check for NEON target_compile_definitions(opus PRIVATE OPUS_ARM_MAY_HAVE_NEON OPUS_ARM_MAY_HAVE_NEON_INTR) endif() add_sources_group(opus celt ${celt_sources_arm_neon_intr}) add_sources_group(opus silk ${silk_sources_arm_neon_intr}) # silk arm neon depends on main_Fix.h target_include_directories(opus PRIVATE silk/fixed) if(OPUS_FIXED_POINT) add_sources_group(opus silk ${silk_sources_fixed_arm_neon_intr}) endif() if(OPUS_PRESUME_NEON) target_compile_definitions(opus PRIVATE OPUS_ARM_PRESUME_NEON OPUS_ARM_PRESUME_NEON_INTR) endif() endif() install(TARGETS opus EXPORT OpusTargets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/opus) if(OPUS_INSTALL_PKG_CONFIG_MODULE) set(prefix ${CMAKE_INSTALL_PREFIX}) set(exec_prefix ${CMAKE_INSTALL_PREFIX}) set(libdir ${CMAKE_INSTALL_FULL_LIBDIR}) set(includedir ${CMAKE_INSTALL_FULL_INCLUDEDIR}) set(VERSION ${OPUS_LIBRARY_VERSION}) set(VERSION ${OPUS_LIBRARY_VERSION}) if(HAVE_LIBM) set(LIBM "-lm") endif() configure_file(opus.pc.in opus.pc) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/opus.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) endif() if(OPUS_INSTALL_CMAKE_CONFIG_MODULE) set(CMAKE_INSTALL_PACKAGEDIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}) install(EXPORT OpusTargets NAMESPACE Opus:: DESTINATION ${CMAKE_INSTALL_PACKAGEDIR}) include(CMakePackageConfigHelpers) set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR}) configure_package_config_file(OpusConfig.cmake.in OpusConfig.cmake INSTALL_DESTINATION ${CMAKE_INSTALL_PACKAGEDIR} PATH_VARS INCLUDE_INSTALL_DIR INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}) write_basic_package_version_file(OpusConfigVersion.cmake VERSION ${PROJECT_VERSION} COMPATIBILITY SameMajorVersion) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/OpusConfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/OpusConfigVersion.cmake DESTINATION ${CMAKE_INSTALL_PACKAGEDIR}) endif() if(OPUS_BUILD_PROGRAMS) # demo if(OPUS_CUSTOM_MODES) add_executable(opus_custom_demo ${opus_custom_demo_sources}) target_include_directories(opus_custom_demo PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) target_link_libraries(opus_custom_demo PRIVATE opus) endif() add_executable(opus_demo ${opus_demo_sources}) target_include_directories(opus_demo PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) target_include_directories(opus_demo PRIVATE silk) # debug.h target_include_directories(opus_demo PRIVATE celt) # arch.h target_link_libraries(opus_demo PRIVATE opus) # compare add_executable(opus_compare ${opus_compare_sources}) target_include_directories(opus_compare PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) target_link_libraries(opus_compare PRIVATE opus) endif() if(BUILD_TESTING) enable_testing() # tests add_executable(test_opus_decode ${test_opus_decode_sources}) target_include_directories(test_opus_decode PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) target_link_libraries(test_opus_decode PRIVATE opus) if(OPUS_FIXED_POINT) target_compile_definitions(test_opus_decode PRIVATE DISABLE_FLOAT_API) endif() add_test(test_opus_decode test_opus_decode) add_executable(test_opus_padding ${test_opus_padding_sources}) target_include_directories(test_opus_padding PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) target_link_libraries(test_opus_padding PRIVATE opus) add_test(test_opus_padding test_opus_padding) if(NOT BUILD_SHARED_LIBS) # disable tests that depends on private API when building shared lib add_executable(test_opus_api ${test_opus_api_sources}) target_include_directories(test_opus_api PRIVATE ${CMAKE_CURRENT_BINARY_DIR} celt) target_link_libraries(test_opus_api PRIVATE opus) if(OPUS_FIXED_POINT) target_compile_definitions(test_opus_api PRIVATE DISABLE_FLOAT_API) endif() add_test(test_opus_api test_opus_api) add_executable(test_opus_encode ${test_opus_encode_sources}) target_include_directories(test_opus_encode PRIVATE ${CMAKE_CURRENT_BINARY_DIR} celt) target_link_libraries(test_opus_encode PRIVATE opus) add_test(test_opus_encode test_opus_encode) endif() endif() jamulus-3.9.1+dfsg/libs/opus/config.guess0000755000175000017500000012646214340334543017426 0ustar vimervimer#! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2017 Free Software Foundation, Inc. timestamp='2017-08-08' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess # # Please send patches to . me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2017 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case "${UNAME_SYSTEM}" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu eval $set_cc_for_build cat <<-EOF > $dummy.c #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #else LIBC=gnu #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` ;; esac # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ /sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || \ echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'` endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'` machine=${arch}${endian}-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. case "${UNAME_MACHINE_ARCH}" in earm*) os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # Determine ABI tags. case "${UNAME_MACHINE_ARCH}" in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"` ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}${abi}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:LibertyBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; *:Sortix:*:*) echo ${UNAME_MACHINE}-unknown-sortix exit ;; *:Redox:*:*) echo ${UNAME_MACHINE}-unknown-redox exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE=alpha ;; "EV4.5 (21064)") UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") UNAME_MACHINE=alpha ;; "EV5 (21164)") UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH=x86_64 fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/lslpp ] ; then IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = hppa2.0w ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH=hppa2.0w else HP_ARCH=hppa64 fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case ${UNAME_PROCESSOR} in amd64) UNAME_PROCESSOR=x86_64 ;; i386) UNAME_PROCESSOR=i586 ;; esac echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW64*:*) echo ${UNAME_MACHINE}-pc-mingw64 exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; *:MSYS*:*) echo ${UNAME_MACHINE}-pc-msys exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC=gnulibc1 ; fi echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arc:Linux:*:* | arceb:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-${LIBC} else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi else echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; cris:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; e2k:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; hexagon:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:Linux:*:*) echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; k1om:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; mips64el:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; openrisc*:Linux:*:*) echo or1k-unknown-linux-${LIBC} exit ;; or32:Linux:*:* | or1k*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; padre:Linux:*:*) echo sparc-unknown-linux-${LIBC} exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; *) echo hppa-unknown-linux-${LIBC} ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-${LIBC} exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-${LIBC} exit ;; ppc64le:Linux:*:*) echo powerpc64le-unknown-linux-${LIBC} exit ;; ppcle:Linux:*:*) echo powerpcle-unknown-linux-${LIBC} exit ;; riscv32:Linux:*:* | riscv64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux-${LIBC} exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; x86_64:Haiku:*:*) echo x86_64-unknown-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; SX-ACE:SUPER-UX:*:*) echo sxace-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown eval $set_cc_for_build if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_PPC >/dev/null then UNAME_PROCESSOR=powerpc fi fi elif test "$UNAME_PROCESSOR" = i386 ; then # Avoid executing cc on OS X 10.9, as it ships with a stub # that puts up a graphical alert prompting to install # developer tools. Any system running Mac OS X 10.7 or # later (Darwin 11 and later) is required to have a 64-bit # processor. This is not true of the ARM version of Darwin # that Apple uses in portable devices. UNAME_PROCESSOR=x86_64 fi echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-*:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; NSE-*:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-*:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; NSX-*:NONSTOP_KERNEL:*:*) echo nsx-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = 386; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'` exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; amd64:Isilon\ OneFS:*:*) echo x86_64-unknown-onefs exit ;; esac cat >&2 </dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: jamulus-3.9.1+dfsg/libs/opus/NEWS0000644000175000017500000000000014340334543015560 0ustar vimervimerjamulus-3.9.1+dfsg/libs/opus/tests/0000755000175000017500000000000014340334543016235 5ustar vimervimerjamulus-3.9.1+dfsg/libs/opus/tests/test_opus_padding.c0000644000175000017500000000525714340334543022125 0ustar vimervimer/* Copyright (c) 2012 Xiph.Org Foundation Written by Jüri Aedla and Ralph Giles */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* Check for overflow in reading the padding length. * http://lists.xiph.org/pipermail/opus/2012-November/001834.html */ #include #include #include #include "opus.h" #include "test_opus_common.h" #define PACKETSIZE 16909318 #define CHANNELS 2 #define FRAMESIZE 5760 int test_overflow(void) { OpusDecoder *decoder; int result; int error; unsigned char *in = malloc(PACKETSIZE); opus_int16 *out = malloc(FRAMESIZE*CHANNELS*sizeof(*out)); fprintf(stderr, " Checking for padding overflow... "); if (!in || !out) { fprintf(stderr, "FAIL (out of memory)\n"); return -1; } in[0] = 0xff; in[1] = 0x41; memset(in + 2, 0xff, PACKETSIZE - 3); in[PACKETSIZE-1] = 0x0b; decoder = opus_decoder_create(48000, CHANNELS, &error); result = opus_decode(decoder, in, PACKETSIZE, out, FRAMESIZE, 0); opus_decoder_destroy(decoder); free(in); free(out); if (result != OPUS_INVALID_PACKET) { fprintf(stderr, "FAIL!\n"); test_failed(); } fprintf(stderr, "OK.\n"); return 1; } int main(void) { const char *oversion; int tests = 0;; iseed = 0; oversion = opus_get_version_string(); if (!oversion) test_failed(); fprintf(stderr, "Testing %s padding.\n", oversion); tests += test_overflow(); fprintf(stderr, "All padding tests passed.\n"); return 0; } jamulus-3.9.1+dfsg/libs/opus/tests/opus_encode_regressions.c0000644000175000017500000017455414340334543023347 0ustar vimervimer/* Copyright (c) 2016 Mark Harris, Jean-Marc Valin */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include "opus_multistream.h" #include "opus.h" #include "test_opus_common.h" static int celt_ec_internal_error(void) { OpusMSEncoder *enc; int err; unsigned char data[2460]; int streams; int coupled_streams; unsigned char mapping[1]; enc = opus_multistream_surround_encoder_create(16000, 1, 1, &streams, &coupled_streams, mapping, OPUS_APPLICATION_VOIP, &err); opus_multistream_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC)); opus_multistream_encoder_ctl(enc, OPUS_SET_VBR(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(1)); opus_multistream_encoder_ctl(enc, OPUS_SET_PHASE_INVERSION_DISABLED(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_DTX(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_COMPLEXITY(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND)); opus_multistream_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_AUTO)); opus_multistream_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(8)); opus_multistream_encoder_ctl(enc, OPUS_SET_INBAND_FEC(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_BITRATE(OPUS_AUTO)); { static const short pcm[320] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1792, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 0, 25600, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 7, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32767, -1, 0, 0, 0, 100, 0, 16384, 0, 0, 0, 0, 0, 0, 4, 0, 0, -256, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-32768, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, -256, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 4352, 4, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5632, 0, 0, 0, 0,-32768, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3944, 10500, 4285, 10459, -6474, 10204, -6539, 11601, -6824, 13385, -7142, 13872,-11553, 13670, -7725, 13463, -6887, 7874, -5580, 12600, -4964, 12480, 3254, 11741, -4210, 9741, -3155, 7558, -5468, 5431, -1073, 3641, -1304, 0, -1, 343, 26, 0, 0, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1799, 1799, 1799, 1799, 1799, -2553, 7, 1792, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, -9721 }; err = opus_multistream_encode(enc, pcm, 320, data, 2460); assert(err > 0); } opus_multistream_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC)); opus_multistream_encoder_ctl(enc, OPUS_SET_VBR(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(1)); opus_multistream_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(1)); opus_multistream_encoder_ctl(enc, OPUS_SET_PHASE_INVERSION_DISABLED(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_DTX(1)); opus_multistream_encoder_ctl(enc, OPUS_SET_COMPLEXITY(10)); opus_multistream_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND)); opus_multistream_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND)); opus_multistream_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(18)); opus_multistream_encoder_ctl(enc, OPUS_SET_INBAND_FEC(1)); opus_multistream_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(90)); opus_multistream_encoder_ctl(enc, OPUS_SET_BITRATE(280130)); { static const short pcm[160] = { -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9526, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, 25600, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510 }; err = opus_multistream_encode(enc, pcm, 160, data, 2460); assert(err > 0); } opus_multistream_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC)); opus_multistream_encoder_ctl(enc, OPUS_SET_VBR(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(1)); opus_multistream_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(1)); opus_multistream_encoder_ctl(enc, OPUS_SET_PHASE_INVERSION_DISABLED(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_DTX(1)); opus_multistream_encoder_ctl(enc, OPUS_SET_COMPLEXITY(10)); opus_multistream_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND)); opus_multistream_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND)); opus_multistream_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(18)); opus_multistream_encoder_ctl(enc, OPUS_SET_INBAND_FEC(1)); opus_multistream_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(90)); opus_multistream_encoder_ctl(enc, OPUS_SET_BITRATE(280130)); { static const short pcm[160] = { -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9494, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510 }; err = opus_multistream_encode(enc, pcm, 160, data, 2460); assert(err > 0); } opus_multistream_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC)); opus_multistream_encoder_ctl(enc, OPUS_SET_VBR(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(1)); opus_multistream_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(1)); opus_multistream_encoder_ctl(enc, OPUS_SET_PHASE_INVERSION_DISABLED(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_DTX(1)); opus_multistream_encoder_ctl(enc, OPUS_SET_COMPLEXITY(10)); opus_multistream_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND)); opus_multistream_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND)); opus_multistream_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(18)); opus_multistream_encoder_ctl(enc, OPUS_SET_INBAND_FEC(1)); opus_multistream_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(90)); opus_multistream_encoder_ctl(enc, OPUS_SET_BITRATE(280130)); { static const short pcm[160] = { -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9479, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510 }; err = opus_multistream_encode(enc, pcm, 160, data, 2460); assert(err > 0); } opus_multistream_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC)); opus_multistream_encoder_ctl(enc, OPUS_SET_VBR(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(1)); opus_multistream_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(1)); opus_multistream_encoder_ctl(enc, OPUS_SET_PHASE_INVERSION_DISABLED(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_DTX(1)); opus_multistream_encoder_ctl(enc, OPUS_SET_COMPLEXITY(10)); opus_multistream_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND)); opus_multistream_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND)); opus_multistream_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(18)); opus_multistream_encoder_ctl(enc, OPUS_SET_INBAND_FEC(1)); opus_multistream_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(90)); opus_multistream_encoder_ctl(enc, OPUS_SET_BITRATE(280130)); { static const short pcm[160] = { -9510, -9510, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -256, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 4352, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 0, 0, 0, 0, 5632 }; err = opus_multistream_encode(enc, pcm, 160, data, 2460); assert(err > 0); } opus_multistream_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE)); opus_multistream_encoder_ctl(enc, OPUS_SET_VBR(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(1)); opus_multistream_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(1)); opus_multistream_encoder_ctl(enc, OPUS_SET_PHASE_INVERSION_DISABLED(1)); opus_multistream_encoder_ctl(enc, OPUS_SET_DTX(1)); opus_multistream_encoder_ctl(enc, OPUS_SET_COMPLEXITY(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND)); opus_multistream_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_AUTO)); opus_multistream_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(12)); opus_multistream_encoder_ctl(enc, OPUS_SET_INBAND_FEC(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(41)); opus_multistream_encoder_ctl(enc, OPUS_SET_BITRATE(21425)); { static const short pcm[40] = { 10459, -6474, 10204, -6539, 11601, -6824, 13385, -7142, 13872, -11553, 13670, -7725, 13463, -6887, 12482, -5580, 12600, -4964, 12480, 3254, 11741, -4210, 9741, -3155, 7558, -5468, 5431, -1073, 3641, -1304, 0, -1, 343, 26, 0, 0, 0, 0, -256, 226 }; err = opus_multistream_encode(enc, pcm, 40, data, 2460); assert(err > 0); /* returns -3 */ } opus_multistream_encoder_destroy(enc); return 0; } static int mscbr_encode_fail10(void) { OpusMSEncoder *enc; int err; unsigned char data[627300]; static const unsigned char mapping[255] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101, 102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118, 119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135, 136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152, 153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169, 170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186, 187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203, 204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220, 221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237, 238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254 }; enc = opus_multistream_encoder_create(8000, 255, 254, 1, mapping, OPUS_APPLICATION_RESTRICTED_LOWDELAY, &err); opus_multistream_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE)); opus_multistream_encoder_ctl(enc, OPUS_SET_VBR(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(2)); opus_multistream_encoder_ctl(enc, OPUS_SET_PHASE_INVERSION_DISABLED(1)); opus_multistream_encoder_ctl(enc, OPUS_SET_DTX(1)); opus_multistream_encoder_ctl(enc, OPUS_SET_COMPLEXITY(2)); opus_multistream_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND)); opus_multistream_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_AUTO)); opus_multistream_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(14)); opus_multistream_encoder_ctl(enc, OPUS_SET_INBAND_FEC(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(57)); opus_multistream_encoder_ctl(enc, OPUS_SET_BITRATE(3642675)); { static const short pcm[20*255] = { 0 }; err = opus_multistream_encode(enc, pcm, 20, data, 627300); assert(err > 0); /* returns -1 */ } opus_multistream_encoder_destroy(enc); return 0; } static int mscbr_encode_fail(void) { OpusMSEncoder *enc; int err; unsigned char data[472320]; static const unsigned char mapping[192] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101, 102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118, 119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135, 136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152, 153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169, 170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186, 187,188,189,190,191 }; enc = opus_multistream_encoder_create(8000, 192, 189, 3, mapping, OPUS_APPLICATION_RESTRICTED_LOWDELAY, &err); opus_multistream_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC)); opus_multistream_encoder_ctl(enc, OPUS_SET_VBR(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(OPUS_AUTO)); opus_multistream_encoder_ctl(enc, OPUS_SET_PHASE_INVERSION_DISABLED(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_DTX(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_COMPLEXITY(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_MEDIUMBAND)); opus_multistream_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_AUTO)); opus_multistream_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(8)); opus_multistream_encoder_ctl(enc, OPUS_SET_INBAND_FEC(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_BITRATE(15360)); { static const short pcm[20*192] = { 0 }; err = opus_multistream_encode(enc, pcm, 20, data, 472320); assert(err > 0); /* returns -1 */ } opus_multistream_encoder_destroy(enc); return 0; } static int surround_analysis_uninit(void) { OpusMSEncoder *enc; int err; unsigned char data[7380]; int streams; int coupled_streams; unsigned char mapping[3]; enc = opus_multistream_surround_encoder_create(24000, 3, 1, &streams, &coupled_streams, mapping, OPUS_APPLICATION_AUDIO, &err); opus_multistream_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE)); opus_multistream_encoder_ctl(enc, OPUS_SET_VBR(1)); opus_multistream_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(1)); opus_multistream_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(OPUS_AUTO)); opus_multistream_encoder_ctl(enc, OPUS_SET_PHASE_INVERSION_DISABLED(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_DTX(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_COMPLEXITY(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND)); opus_multistream_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND)); opus_multistream_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(8)); opus_multistream_encoder_ctl(enc, OPUS_SET_INBAND_FEC(1)); opus_multistream_encoder_ctl(enc, OPUS_SET_BITRATE(84315)); { static const short pcm[960*3] = { -6896, 4901, -6158, 4120, -5164, 3631, -4442, 3153, -4070, 3349, -4577, 4474, -5541, 5058, -6701, 3881, -7933, 1863, -8041, 697, -6738,-31464, 14330,-12523, 4096, -6130, 29178, -250,-21252, 10467, 16907, -3359, -6644, 31965, 14607,-21544, -32497, 24020, 12557,-26926,-18421, -1842, 24587, 19659, 4878, 10954, 23060, 8907,-10215,-16179, 31772,-11825,-15590,-23089, 17173,-25903,-17387, 11733, 4884, 10204,-16476,-14367, 516, 20453,-16898, 20967,-23813, -20, 22011,-17167, 9459, 32499, -25855, -523, -3883, -390, -4206, 634, -3767, 2325, -2751, 3115, -2392, 2746, -2173, 2317, -1147, 2326, 23142, 11314, -15350,-24529, 3026, 6146, 2150, 2476, 1105, -830, 1775, -3425, 3674,-14907,-14907,-14907,-14907,-14907,-14907,-14907, 4293,-14023, 3879,-15553, 3158,-16161, 2629, 18433,-12535, -6645,-20735,-32763,-13824,-20992, 25859, 13052, -8731, 2292, -3860, 24049, 10225,-19220, 10478,-22294, 22773, 28137, 13816, 30953,-25863,-24598, 16888,-14612,-28942, 20974,-27397,-18944, -18690, 20991,-16638, 5632,-14330, 28911,-25594, 17408, 29958, -517,-20984, -1800, 11281, 9977,-21221,-14854, 23840, -9477, 3362,-12805,-22493, 32507, 156, 16384, -1163, 2301, -1874, 4600, -1748, 6950, 16557, 8192, -7372, -1033, -3278, 2806, 20275, 3317, -717, 9792, -767, 9099, -613, 8362, 5027, 7774, 2597, 8549, 5278, 8743, 9343, 6940, 13038, 4826, 14086, 2964, 13215, 1355, 11596, 455, 9850, -519, 10680, -2287, 12551, -3736, 13639, -4291, 13790, -2722, 14544, -866, 15050, -304, 22833, -1196, 13520, -2063, 13051, -2317, 13066, -2737, 13773, -2664, 14105, -3447, 13854, 24589, 24672, -5280, 10388, -4933, 7543, -4149, 3654, -1552, 1726, 661, 57, 2922, -751, 3917, 8419, 3840, -5218, 3435, 5540, -1073, 4153, -6656, 1649, -769, -7276,-13072, 6380, -7948, 20717, 18425, 17392, 14335,-18190, -1842, 24587, 19659, 11790, 10954, 23060, 8907,-10215,-16179, 31772,-11825,-15590,-23101, 17173, -25903,-17387, 11733, 4884, 10192,-16627,-14367, 516, 20453, -16898, 20967,-23813, -20, 22011,-17167, 9468, 32499,-25607, -523, -3883, -390, -4206, 634, -3767, 2325, -2751, 3115, -2392, 2746, -2161, 2317, -1147, 2326, 23142, 11314,-15350, -29137, 3026,-15056, -491,-15170, -386,-16015, -641,-16505, -930,-16206, -717,-16175, -2839,-16374, -4558,-16237, -5207, -15903, -6421, 6373, -1403, 5431, -1073, 3641, -1304, -4495, -769, -7276, 2856, -7870, 3314, -8730, 3964,-10183, 4011, -11135, 3421,-11727, 2966,-12360, 2818,-13472, 3660,-13805, 5162,-13478, 6434,-12840, 7335,-12420, 6865,-12349, 5541, -11965, 5530,-10820, 5132, -9197, 3367, -7745, 1223, -6910, -433, -6211, -1711, -4958, -1025, -3755, -836, -3292, -1666, -2661,-10755, 31472,-27906, 31471, 18690, 5617, 16649, 11253, -22516,-17674,-31990, 3575,-31479, 5883, 26121, 12890, -6612, 12228,-11634, 523, 26136,-21496, 20745,-15868, -4100,-24826, 23282, 22798, 491, -1774, 15075,-27373,-13094, 6417,-29487, 14608, 10185, 16143, 22211, -8436, 4288, -8694, 2375, 3023, 486, 1455, 128, 202, 942, -923, 2068, -1233, -717, -1042, -2167, 32255, -4632, 310, -4458, -3639, -5258, 2106, -6857, 2681, -7497, 2765, -6601, 1945, -5219, 19154, -4877, 619, -5719, -1928, -6208, -121, 593, 188, 1558, -4152, 1648, 156, 1604, -3664, -6862, -2851, -5112, -3600, -3747, -5081, -4428, -5592, 20974,-27397,-18944,-18690, 20991,-17406, 5632,-14330, 28911, 15934, 15934, 15934, 15934, 15934, 15934, 15934, 15934, 15934, 15934, 15934, 15934,-25594, 17408, 29958, -7173,-16888, 9098, -613, 8362, 675, 7774, 2597, 8549, 5278, 8743, 9375, 6940, 13038, 4826, 14598, 7721,-24308, -29905,-19703,-17106,-16124, -3287,-26118,-19709,-10769, 24353, 28648, 6946, -1363, 12485, -1187, 26074,-25055, 10004,-24798, 7204, -4581, -9678, 1554, 10553, 3102, 12193, 2443, 11955, 1213, 10689, -1293, 921, -4173, 10709, -6049, 8815, -7128, 8147, -8308, 6847, -2977, 4920,-11447,-22426,-11794, 3514, -10220, 3430, -7993, 1926, -7072, 327, -7569, -608, -7605, 3695, -6271, -1579, -4877, -1419, -3103, -2197, 128, -3904, 3760, -5401, 4906, -6051, 4250, -6272, 3492, -6343, 3197, -6397, 4041, -6341, 6255, -6381, 7905, 16504, 0, -6144, 8062, -5606, 8622, -5555, -9, -1, 7423, 0, 1, 238, 5148, 1309, 4700, 2218, 4403, 2573, 3568, 28303, 1758, 3454, -1247, 3434, -4912, 2862, -7844, 1718,-10095, 369,-12631, 128, -3904, 3632, -5401, 4906, -6051, 4250, -6272, 3492, -6343, 3197, -6397, 4041, -6341, 6255, -6381, 7905, 16504, 0, -6144, 8062, -5606, 8622, -5555, 8439, -3382, 7398, -1170, 6132, 238, 5148, 1309, 4700, 2218, 4403, 2573, 3568, 2703, 1758, 3454, -1247, 3434, -4912, 2862, -7844, 1718,-10095, 369,-12631, -259,-14632, 234, -15056, -521,-15170, -386,-16015, -641,-16505, -930,-16206, -1209,-16146, -2839,-16374, -4558,-16218, -5207,-15903, -6421, -15615, -6925,-14871, -6149,-13759, -5233,-12844, 18313, -4357, -5696, 2804, 12992,-22802, -6720, -9770, -7088, -8998, 14330, -12523, 14843, -6130, 29178, -250,-27396, 10467, 16907, -3359, -6644, 31965, 14607,-21544,-32497, 24020, 12557,-26926, -173, -129, -6401, -130,-25089, -3841, -4916, -3048, 224, -237, -3969, -189, -3529, -535, -3464,-14863,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14395,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907, 0, 32512,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907, 9925, -718, 9753, -767, 9099, -613, 8362, 675, 7774, 2597, 8549, 5278, 8743, 9375, 6940, 13038, 4826, 14598, 7721,-24308,-29905,-19703, -17106,-16124, -3287,-26118,-19709, 0, 24353, 28648, 10274, -11292,-29665,-16417, 24346, 14553, 18707, 26323, -4596,-17711, 5133, 26328, 13,-31168, 24583, 18404,-28927,-24350, 19453, 28642, 1019,-10777, -3079, 30188, -7686, 27635,-32521,-16384, 12528, -6386, 10986, 23827,-25880,-32752,-23321, 14605, 32231, 780,-13849, 15119, 28647, 4888, -7705, 30750, 64, 0, 32488, 6687,-20758, 19745, -2070,-13792, -6414, 28188, -2821, -4585, 7168, 7444, 23557,-21998, 13064, 3345, -4086,-28915, -8694, 32262, 8461, 27387,-12275, 12012, 23563,-18719,-28410, 29144,-22271, -562, -9986, -5434, 12288, 5573,-16642, 32448, 29182, 32705,-30723, 24255,-19716, 18368, -4357, -5696, 2804, 12992,-22802,-22080, -7701, -5183, 486, -3133, -5660, -1083, 16871,-28726,-11029,-30259, -1209,-16146, -2839,-16374, -4558, -16218,-10523, 20697, -9500, -1316, 5431, -1073, 3641, -1304, 1649, -769, -7276, 2856, -7870, 3314, -8730, 3964,-10183, 4011,-11135, 3421,-11727, 21398, 32767, -1, 32486, -1, 6301,-13071, 6380, -7948, -1, 32767, 240, 14081, -5646, 30973, -3598,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907, 32767,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907, 8901, 9375, 6940, 13038, 4826, 14598, 7721,-24308, -29905,-19703,-17106,-16124, -3287,-26118,-19709,-10769, 24361, 28648, 10274,-11292,-29665,-16417, 24346, 14580, 18707, 26323, -4440,-17711, 5133, 26328,-14579,-31008, 24583, 18404, 28417, -24350, 19453, 28642,-32513,-10777, -3079, 30188, -7686, 27635, -32521,-16384,-20240, -6386, 10986, 23827,-25880,-32752,-23321, 14605, 32231, 780,-13849, 15119, 28647, 4888, -7705,-15074, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907, 8192,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14897,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -15931,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907, 26121, 12890, 2604, 12228,-11634, 12299, 5573,-16642, 32452, 29182, 32705,-30723, 24255,-19716, 13248,-11779, -5696, 2804, 12992,-27666,-22080, -7701, -5183, -6682,-31464, 14330,-12523, 14843, -6130, 29178, -18,-27396, 10467, 16907, -3359, -6644, 31965, 14607,-21544, -32497, 24020, 12557,-26926,-18421, 706, 24587, 19659, 4878, 10954, 23060, 8907,-10215,-22579, 31772,-11825,-15590,-23089, 17173,-25903,-17387, 3285, 4884, 10204,-16627,-14367, 516, 20453,-16898, 20967,-23815, -20, 22011,-17167, 9468, 32499, -25607, -523, -3883, -390, -4206, 634, -3767, 2325, -2751, 3115, -2392, 2746, -2173, 2317, -1147, 2326, 23142, 11314, -15130,-29137, 3026, 6146, 2150, 2476, 1105, -830, 1775, -3425, 3674, -5287, 4609, -7175, 4922, -9579, 4556,-12007, 4236,-14023, 3879,-15553, 3158,-16161, 2576, 18398,-12535, -6645,-20735,-32763,-13824,-20992, 25859, 5372, 12040, 13307, -4355,-30213, -9, -6019, 14061,-31487,-13842, 30449, 15083, 14088, 31205,-18678,-12830, 14090,-26138,-25337,-11541, -3254, 27628,-22270, 30953,-16136,-30745, 20991,-17406, 5632,-14330, 28911,-25594, 17408,-20474, 13041, -8731, 2292, -3860, 24049, 10225,-19220, 10478, -4374, -1199, 148, -330, -74, 593, 188, 1558, -4152, 15984, 15934, 15934, 15934, 15934, 15934, 15934, 15934, 15934, 15934, 15934, 15934, 1598, 156, 1604, -1163, 2278,-30018,-25821,-21763,-23776, 24066, 9502, 25866, -25055, 10004,-24798, 7204, -4581, -9678, 1554, 10553, 3102, 12193, 2443, 11955, 1213, 10689, -1293, 921, -4173, 8661, -6049, 8815,-21221,-14854, 23840, -9477, 8549, 5278, 8743, 9375, 6940, 13038, 4826, 14598, 7721,-24308,-29905,-19703, -17106,-16124, -3287,-26118,-19709,-10769, 24361, 28648, 10274, -11292,-29665,-16417, 24346, 14580, 18707, 26323, -4410,-17711, 5133, 26328,-14579,-31008, 24583, 18404, 28417,-24350, 19453, 28642,-32513,-10777, -3079, 30188, -7686, 27635,-32521,-16384, -20240, -6386, 10986, 23827,-25880,-32752,-23321, 14605, 32231, 780,-13849, 15119, 28647, 4888, -7705, 30750, 64, 0, 32488, 6687,-20758, 19745, -2070, -1, -1, 28, 256, -4608, 7168, 7444, 23557,-21998, 13064, 3345, -4086,-28915, -8594, 32262, 8461, 27387,-12275, 12012, 23563,-18719,-28410, 29144,-22271,-32562,-16384, 12528, -6386, 10986, 23827,-25880, -32752,-23321, 14605, 32231, 780,-13849, 15119, 28647, 4888, -7705, 30750, 64, 0, 32488, 6687,-20758, 19745, -2070, -13792, -6414, 28188, -2821, -4585, 7168, 7444, 23557,-21998, 13064, 3345, -4086,-28915, -8694, 32262, 8461, 27387,-12275, 12012, 23563,-18719,-28410, 29144,-22271, -562, -9986, -5434, 12288, -2107,-16643, 32452, 29182, 32705,-30723, 24255,-19716, 18368, -4357, -5696, 2804, 12992,-22802,-22080, -7701, -5183, 486, -3133, -5660, -1083, 16871,-28726,-11029,-30259, -1209, -16146, -2839,-16374, -4558,-16218,-10523, 20697, -9500, -1316, 5431, -1073, 3641, -1304, 1649, -769, -7276, 2856, -7870, 3314, -8730, 3964,-10183, 4011,-11135, 3421,-11727, 21398, 32767, -1, 32486, -1, -99,-13072, 6380, -7948, 4864, 32767, 17392, 14335, -5646, 30973, -3598,-10299,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14905,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-19771,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-16443,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-15931,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907, -1,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907, 7877, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, -994, -7276, 2856, -7870, 3314, -8730, 3964,-10183, 4011,-11135, 3421,-11727, 21398, 32767, -1, 32486, -1, -99,-13072, 6380, -7948, 4864, 32767, 17392, 14335, -5646, 30973, -3598,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14905,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907, 197, 0,-14977,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907, 12838, 6653, 294, -29699,-25821,-21763,-23776, 24066, 9502, 25866,-25055, 10004, -24798, 7204, -4581, -9678, 1554, 10553, 3102, 12193, 2443, 11955, 1213, 10689, -1293, 921, 179, 8448, -6049, 8815, -7128, 8147, -8308, 6847, -9889, 4920,-11447, 3174,-11794, 3514,-10220, 3430, 16384, 1926, -7072, 327, -7537, -608, -7605, -1169, -6397, -1579, -4877, -1419, -3103, -2197, 128, -3904, 3632, -5401, 4906, -6051, 4250, -6272, 3492, -6343, 3197, -6397, 4041, -6341, 6255, -6381, 7905, 16504, 0, -6144, 8062, -5606, 8622, -5555, 8439, -3382, 7398, -1170, 6132, 238, 5148, 1309, 4700, 2218, 4403, 2573, 3568, 2703, 1758, 3454, -1247, 3434, -4912, 2862, -7844, 1718, -10095, 369,-12631, -259,-14632, 234,-15056, -491,-16194, -386,-16015, -641,-16505, -930,-16206, -1209,-16146, -2839, -16374, -4558,-16218, -5207,-15903, -6421,-15615, -6925,-14871, -6149,-13759, -5233,-12844, 18313, -4357, -5696, 2804, 12992, -22802, -6720, -9770, -7088, -8998, 14330,-12523, 14843, -6130, 29178, -250,-27396, 10467, 16907, -3359, -6644, 31965, 14607, -21544,-32497, 24020, 12557,-26926, -173, -129, -6401, -130, -25089, -3816, -4916, -3048, -32, -1, -3969, 256, -3529, -535, -3464,-14863,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -1209,-16146, -2839,-16374, -4558,-16218,-10523, 20697, -9500, -1316, 5431, -1073, 3641, -1304, 1649, -769, -7276, 2856, -7870, 3314, -8730, 3964,-10183, 4011,-11135, 3421,-11727, 21398, 32767, -1, 32486, -1, 6301,-13071, 6380, -7948, -1, 32767, 240, 14081, -5646, 30973, -3598,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, 32767,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907, 8901, 9375, 6940, 13038, 4826, 14598, 7721,-24308,-29905,-19703,-17106,-16124, -3287,-26118,-19709,-10769, 24361, 28648, 10274,-11292,-29665, -16417, 24346, 14580, 18707, 26323, -4440,-17711, 5133, 26328, -14579,-31008, 24583, 18404, 28417,-24350, 19453, 28642,-32513, -10777, -3079, 30188, -7686, 27635,-32521,-16384,-20240, -6386, 10986, 23827,-25880,-32752,-23321, 14605, 32231, 780,-13849, 15119, 28647, 4888, -7705,-15074,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, 8192, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14897, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-15931,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907, 26121, 12890, 2604, 12228,-11634, 12299, 5573, -16642, 32452, 29182, 32705,-30723, 24255,-19716, 13248,-11779, -5696, 2804, 12992,-27666,-22080, -7701, -5183, -6682,-31464, 14330,-12523, 14843, -6130, 29178, -18,-27396, 10467, 16907, -3359, -6644, 31965, 14607,-21544,-32497, 24020, 12557,-26926, -18421, 706, 24587, 19659, 4878, 10954, 23060, 8907,-10215, -22579, 31772,-11825,-15590,-23089, 17173,-25903,-17387, 3285, 4884, 10204,-16627,-14367, 516, 20453,-16898, 20967,-23815, -20, 22011,-17167, 9468, 32499,-25607, -523, -3883, -390, -4206, 634, -3767, 2325, -2751, 3115, -2392, 2746, -2173, 2317, -1147, 2326, 23142, 11314,-15130,-29137, 3026, 6146, 2150, 2476, 1105, -830, 1775, -3425, 3674, -5287, 4609, -7175, 4922, -9579, 4556,-12007, 4236,-14023, 3879,-15553, 3158,-16161, 2576, 18398,-12535, -6645,-20735,-32763,-13824, -20992, 25859, 5372, 12040, 13307, -4355,-30213, -9, -6019 }; err = opus_multistream_encode(enc, pcm, 960, data, 7380); assert(err > 0); } opus_multistream_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC)); opus_multistream_encoder_ctl(enc, OPUS_SET_VBR(1)); opus_multistream_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(0)); opus_multistream_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(1)); opus_multistream_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(OPUS_AUTO)); opus_multistream_encoder_ctl(enc, OPUS_SET_PHASE_INVERSION_DISABLED(1)); opus_multistream_encoder_ctl(enc, OPUS_SET_DTX(1)); opus_multistream_encoder_ctl(enc, OPUS_SET_COMPLEXITY(6)); opus_multistream_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND)); opus_multistream_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_AUTO)); opus_multistream_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(9)); opus_multistream_encoder_ctl(enc, OPUS_SET_INBAND_FEC(1)); opus_multistream_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(5)); opus_multistream_encoder_ctl(enc, OPUS_SET_BITRATE(775410)); { static const short pcm[1440*3] = { 30449, 15083, 14088, 31205,-18678,-12830, 14090,-26138,-25337, -11541, -3254, 27628,-22270, 30953,-16136,-30745, 20991,-17406, 5632,-14330, 28911,-25594, 17408,-20474, 13041, -8731, 2292, -3860, 24049, 10225,-19220, 10478, -4374, -1199, 148, -330, -74, 593, 188, 1558, -4152, 15984, 15934, 15934, 15934, 15934, 15934, 15934, 15934, 15934, 15934, 15934, 15934, 1598, 156, 1604, -1163, 2278,-30018,-25821,-21763,-23776, 24066, 9502, 25866,-25055, 10004,-24798, 7204, -4581, -9678, 1554, 10553, 3102, 12193, 2443, 11955, 1213, 10689, -1293, 921, -4173, 8661, -6049, 8815,-21221,-14854, 23840, -9477, 8549, 5278, 8743, 9375, 6940, 13038, 4826, 14598, 7721,-24308, -29905,-19703,-17106,-16124, -3287,-26118,-19709,-10769, 24361, 28648, 10274,-11292,-29665,-16417, 24346, 14580, 18707, 26323, -4410,-17711, 5133, 26328,-14579,-31008, 24583, 18404, 28417, -24350, 19453, 28642,-32513,-10777, -3079, 30188, -7686, 27635, -32521,-16384,-20240, -6386, 10986, 23827,-25880,-32752,-23321, 14605, 32231, 780,-13849, 15119, 28647, 4888, -7705, 30750, 64, 0, 32488, 6687,-20758, 19745, -2070, -1, -1, 28, 256, -4608, 7168, 7444, 23557,-21998, 13064, 3345, -4086,-28915, -8594, 32262, 8461, 27387,-12275, 12012, 23563, -18719,-28410, 29144,-22271,-32562,-16384, 12528, -6386, 10986, 23827,-25880,-32752,-23321, 14605, 32231, 780,-13849, 15119, 28647, 4888, -7705, 30750, 64, 0, 32488, 6687,-20758, 19745, -2070,-13792, -6414, 28188, -2821, -4585, 7168, 7444, 23557,-21998, 13064, 3345, -4086,-28915, -8694, 32262, 8461, -14853,-14907,-14907,-14907,-14907, 32767,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14891,-14907,-14907,-14907, -14907,-14907, 8901, 9375, 6940, 13038, 4826, 14598, 7721, -24308,-29905,-19703,-17106,-16124, -3287,-26118,-19709,-10769, 24361, 28648, 10274,-11292,-29665,-16417, 24346, 14580, 18707, 26323, -4440,-17711, 5133, 26328,-14579,-31008, 24583, 18404, 28417,-24350, 19453, 28642,-32513,-10777, -3079, 30188, -7686, 27635,-32521,-16384,-20240, -6386, 10986, 23827,-25880,-32752, -23321, 14605, 32231, 780,-13849, 15119, 28647, 4888, -7705, -15074,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907, 8192,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14897,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-15931,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907, 26121, 12890, 2604, 12228,-11634, 12299, 5573,-16642, 32452, 29182, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-10811,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14917,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14938,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, -14907,-14907,-14907,-14907, -571, -9986, -58, 12542,-18491, 32507, 12838, 6653, 294, -1, 0,-19968, 18368, -4357, -5696, 2804, 12998,-22802,-22080, -7701, -5183, 486, -3133, -5660, -1083, 13799,-28726,-11029, 205,-14848, 32464, -1, -129,-13072, 6380, -7948, 20717, 18425, 17392, 14335, -5646, 30973, -3598, 7188, -3867, 3055, -4247, 5597, -4011,-26427, -11,-30418, 7922, 2614, 237, -5839,-27413,-17624,-29716, -13539, 239, 20991, 18164, -4082,-16647,-27386, 19458, 20224, 4619, 19728, -7409,-18186,-25073, 27627,-23539, -7945,-31464, 14330,-12523,-22021, -7701, -5183, 486, -3133, -5660, -1083, 13799,-28726,-11029, 205,-14848, 32464, -1, -129,-13072, 6380, -7948, 20717, 18425, 17392, 14093, -5646, 30973, -3598, 7188, -3867, 3055, 3689, -5401, 4906, -6051, 4250, -6272, 3492, -6343, 3197, -6397, 4041, -6341, 6255, -6381, 239, 20991, 18164, -4082,-16647,-27386, 19458, 20224, 4619, 19728, -7409,-18186,-25073, 27627,-23539, -7945,-31464, 14330,-12523, 14843, -6130, 30202, -250,-28420, 10467, 16907, -3359, -6644, 31965, 3343,-11727, 2966,-12616, 3064,-13472, 6732,-12349, 5541,-11965, 5530,-10820, -1912, -3637, 32285, -4607, 310, -32768, 0, -5258, 2106, -6857, 2681, -5449, -3606, -6717, -5482, -3606, -1853, 4082, -7631, -9808, -1742, -2851, -5112, 64, -868,-13546,-13365,-13365,-13365,-13365,-13365,-13365, -13365,-13365,-13365,-13365,-13365,-13365,-13365,-13365,-13365, -13365,-13365,-13365,-13365,-13365,-13365,-13365,-13365,-13365, -13365,-13365,-13365,-13365,-13365,-13365,-13365,-13365,-13365, -13365,-13365,-13365,-13365,-13365,-13365,-13365, 7883, -2316, 9086, -3944, 10500, 4285, 10459, -6474, 10204, -6539, 11601, -6824, 13385, -7142, 13872, -7457, 13670, -7725, 13463, -6887, 12482, -5580, 12600, -4964, 12480, 3254, 11741, -4210,-24819, 23282, 22798, 491, -1774, -1073, 3641, -1304, 28928, -250, -27396, 6657, -8961, 22524, 19987, 10231, 1791, 8947,-32763, -26385,-31227, -792,-30461, 8926, 4866, 27863, 27756, 27756, 27756, 27756, 27756, 27756, 27756, 27756, 5630,-11070,-16136, 20671,-11530, 27328, 8179, 5059,-31503,-24379,-19472, 17863, -29202, 22986, -23, 8909, 8422, 10450 }; err = opus_multistream_encode(enc, pcm, 1440, data, 7380); /* reads uninitialized data at src/opus_multistream_encoder.c:293 */ assert(err > 0); } opus_multistream_encoder_destroy(enc); return 0; } static int ec_enc_shrink_assert(void) { OpusEncoder *enc; int err; int data_len; unsigned char data[2000]; static const short pcm1[960] = { 5140 }; static const short pcm2[2880] = { -256,-12033, 0, -2817, 6912, 0, -5359, 5200, 3061, 0, -2903, 5652, -1281,-24656,-14433,-24678, 32,-29793, 2870, 0, 4096, 5120, 5140, -234,-20230,-24673,-24633, -24673,-24705, 0,-32768,-25444,-25444, 0,-25444,-25444, 156,-20480, -7948, -5920, -7968, -7968, 224, 0, 20480, 11, 20496, 13, 20496, 11,-20480, 2292,-20240, 244, 20480, 11, 20496, 11,-20480, 244,-20240, 7156, 20456, -246,-20243, 244, 128, 244, 20480, 11, 20496, 11, -20480, 244,-20256, 244, 20480, 256, 0, -246, 16609, -176, 0, 29872, -4096, -2888, 516, 2896, 4096, 2896, -20480, -3852, -2896, -1025,-31056,-14433, 244, 1792, -256, -12033, 0, -2817, 0, 0, -5359, 5200, 3061, 16, -2903, 5652, -1281,-24656,-14433,-24678, 32,-29793, 2870, 0, 4096, 5120, 5140, -234,-20230,-24673,-24633,-24673, -24705, 0,-32768,-25444,-25444, 0,-25444,-25444, 156, -20480, -7973, -5920, -7968, -7968, 224, 0, 20480, 11, 20496, 11, 20496, 11,-20480, 2292,-20213, 244, 20480, 11, 20496, 11,-24698, -2873, 0, 7, -1, 208, -256, 244, 0, 4352, 20715, -2796, 11,-22272, 5364, -234,-20230,-24673,-25913, 8351,-24832, 13963, 11, 0, 16, 5140, 5652, -1281,-24656,-14433,-24673, 32671, 159, 0,-25472,-25444, 156,-25600,-25444,-25444, 0, -2896, -7968, -7960, -7968, -7968, 0, 0, 2896, 4096, 2896, 4096, 2896, 0, -2896, -4088, -2896, 0, 2896, 0, -2896, -4096, -2896, 11, 2640, -4609, -2896,-32768, -3072, 0, 2896, 4096, 2896, 0, -2896, -4096, -2896, 0, 80, 1, 2816, 0, 20656, 255,-20480, 116,-18192 }; static const short pcm3[2880] = { 0 }; enc = opus_encoder_create(48000, 1, OPUS_APPLICATION_AUDIO, &err); opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(10)); opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(6)); opus_encoder_ctl(enc, OPUS_SET_BITRATE(6000)); data_len = opus_encode(enc, pcm1, 960, data, 2000); assert(data_len > 0); opus_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE)); opus_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(1)); opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_SUPERWIDEBAND)); opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(1)); opus_encoder_ctl(enc, OPUS_SET_BITRATE(15600)); data_len = opus_encode(enc, pcm2, 2880, data, 122); assert(data_len > 0); opus_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC)); opus_encoder_ctl(enc, OPUS_SET_BITRATE(27000)); data_len = opus_encode(enc, pcm3, 2880, data, 122); /* assertion failure */ assert(data_len > 0); opus_encoder_destroy(enc); return 0; } static int ec_enc_shrink_assert2(void) { OpusEncoder *enc; int err; int data_len; unsigned char data[2000]; enc = opus_encoder_create(48000, 1, OPUS_APPLICATION_AUDIO, &err); opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(6)); opus_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE)); opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND)); opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(26)); opus_encoder_ctl(enc, OPUS_SET_BITRATE(27000)); { static const short pcm[960] = { 0 }; data_len = opus_encode(enc, pcm, 960, data, 2000); assert(data_len > 0); } opus_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC)); { static const short pcm[480] = { 32767, 32767, 0, 0, 32767, 32767, 0, 0, 32767, 32767, -32768, -32768, 0, 0, -32768, -32768, 0, 0, -32768, -32768 }; data_len = opus_encode(enc, pcm, 480, data, 19); assert(data_len > 0); } opus_encoder_destroy(enc); return 0; } static int silk_gain_assert(void) { OpusEncoder *enc; int err; int data_len; unsigned char data[1000]; static const short pcm1[160] = { 0 }; static const short pcm2[960] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32767, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32767 }; enc = opus_encoder_create(8000, 1, OPUS_APPLICATION_AUDIO, &err); opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(3)); opus_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND)); opus_encoder_ctl(enc, OPUS_SET_BITRATE(6000)); data_len = opus_encode(enc, pcm1, 160, data, 1000); assert(data_len > 0); opus_encoder_ctl(enc, OPUS_SET_VBR(0)); opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(0)); opus_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_MEDIUMBAND)); opus_encoder_ctl(enc, OPUS_SET_BITRATE(2867)); data_len = opus_encode(enc, pcm2, 960, data, 1000); assert(data_len > 0); opus_encoder_destroy(enc); return 0; } void regression_test(void) { fprintf(stderr, "Running simple tests for bugs that have been fixed previously\n"); celt_ec_internal_error(); mscbr_encode_fail10(); mscbr_encode_fail(); surround_analysis_uninit(); ec_enc_shrink_assert(); ec_enc_shrink_assert2(); silk_gain_assert(); } jamulus-3.9.1+dfsg/libs/opus/tests/test_opus_encode.c0000644000175000017500000007141514340334543021753 0ustar vimervimer/* Copyright (c) 2011-2013 Xiph.Org Foundation Written by Gregory Maxwell */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #if (!defined WIN32 && !defined _WIN32) || defined(__MINGW32__) #include #else #include #define getpid _getpid #endif #include "opus_multistream.h" #include "opus.h" #include "../src/opus_private.h" #include "test_opus_common.h" #define MAX_PACKET (1500) #define SAMPLES (48000*30) #define SSAMPLES (SAMPLES/3) #define MAX_FRAME_SAMP (5760) #define PI (3.141592653589793238462643f) #define RAND_SAMPLE(a) (a[fast_rand() % sizeof(a)/sizeof(a[0])]) void generate_music(short *buf, opus_int32 len) { opus_int32 a1,b1,a2,b2; opus_int32 c1,c2,d1,d2; opus_int32 i,j; a1=b1=a2=b2=0; c1=c2=d1=d2=0; j=0; /*60ms silence*/ for(i=0;i<2880;i++)buf[i*2]=buf[i*2+1]=0; for(i=2880;i>12)^((j>>10|j>>12)&26&j>>7)))&128)+128)<<15; r=fast_rand();v1+=r&65535;v1-=r>>16; r=fast_rand();v2+=r&65535;v2-=r>>16; b1=v1-a1+((b1*61+32)>>6);a1=v1; b2=v2-a2+((b2*61+32)>>6);a2=v2; c1=(30*(c1+b1+d1)+32)>>6;d1=b1; c2=(30*(c2+b2+d2)+32)>>6;d2=b2; v1=(c1+128)>>8; v2=(c2+128)>>8; buf[i*2]=v1>32767?32767:(v1<-32768?-32768:v1); buf[i*2+1]=v2>32767?32767:(v2<-32768?-32768:v2); if(i%6==0)j++; } } #if 0 static int save_ctr = 0; static void int_to_char(opus_uint32 i, unsigned char ch[4]) { ch[0] = i>>24; ch[1] = (i>>16)&0xFF; ch[2] = (i>>8)&0xFF; ch[3] = i&0xFF; } static OPUS_INLINE void save_packet(unsigned char* p, int len, opus_uint32 rng) { FILE *fout; unsigned char int_field[4]; char name[256]; snprintf(name,255,"test_opus_encode.%llu.%d.bit",(unsigned long long)iseed,save_ctr); fprintf(stdout,"writing %d byte packet to %s\n",len,name); fout=fopen(name, "wb+"); if(fout==NULL)test_failed(); int_to_char(len, int_field); fwrite(int_field, 1, 4, fout); int_to_char(rng, int_field); fwrite(int_field, 1, 4, fout); fwrite(p, 1, len, fout); fclose(fout); save_ctr++; } #endif int get_frame_size_enum(int frame_size, int sampling_rate) { int frame_size_enum; if(frame_size==sampling_rate/400) frame_size_enum = OPUS_FRAMESIZE_2_5_MS; else if(frame_size==sampling_rate/200) frame_size_enum = OPUS_FRAMESIZE_5_MS; else if(frame_size==sampling_rate/100) frame_size_enum = OPUS_FRAMESIZE_10_MS; else if(frame_size==sampling_rate/50) frame_size_enum = OPUS_FRAMESIZE_20_MS; else if(frame_size==sampling_rate/25) frame_size_enum = OPUS_FRAMESIZE_40_MS; else if(frame_size==3*sampling_rate/50) frame_size_enum = OPUS_FRAMESIZE_60_MS; else if(frame_size==4*sampling_rate/50) frame_size_enum = OPUS_FRAMESIZE_80_MS; else if(frame_size==5*sampling_rate/50) frame_size_enum = OPUS_FRAMESIZE_100_MS; else if(frame_size==6*sampling_rate/50) frame_size_enum = OPUS_FRAMESIZE_120_MS; else test_failed(); return frame_size_enum; } int test_encode(OpusEncoder *enc, int channels, int frame_size, OpusDecoder *dec) { int samp_count = 0; opus_int16 *inbuf; unsigned char packet[MAX_PACKET+257]; int len; opus_int16 *outbuf; int out_samples; int ret = 0; /* Generate input data */ inbuf = (opus_int16*)malloc(sizeof(*inbuf)*SSAMPLES); generate_music(inbuf, SSAMPLES/2); /* Allocate memory for output data */ outbuf = (opus_int16*)malloc(sizeof(*outbuf)*MAX_FRAME_SAMP*3); /* Encode data, then decode for sanity check */ do { len = opus_encode(enc, &inbuf[samp_count*channels], frame_size, packet, MAX_PACKET); if(len<0 || len>MAX_PACKET) { fprintf(stderr,"opus_encode() returned %d\n",len); ret = -1; break; } out_samples = opus_decode(dec, packet, len, outbuf, MAX_FRAME_SAMP, 0); if(out_samples!=frame_size) { fprintf(stderr,"opus_decode() returned %d\n",out_samples); ret = -1; break; } samp_count += frame_size; } while (samp_count < ((SSAMPLES/2)-MAX_FRAME_SAMP)); /* Clean up */ free(inbuf); free(outbuf); return ret; } void fuzz_encoder_settings(const int num_encoders, const int num_setting_changes) { OpusEncoder *enc; OpusDecoder *dec; int i,j,err; /* Parameters to fuzz. Some values are duplicated to increase their probability of being tested. */ int sampling_rates[5] = {8000, 12000, 16000, 24000, 48000}; int channels[2] = {1, 2}; int applications[3] = {OPUS_APPLICATION_AUDIO, OPUS_APPLICATION_VOIP, OPUS_APPLICATION_RESTRICTED_LOWDELAY}; int bitrates[11] = {6000, 12000, 16000, 24000, 32000, 48000, 64000, 96000, 510000, OPUS_AUTO, OPUS_BITRATE_MAX}; int force_channels[4] = {OPUS_AUTO, OPUS_AUTO, 1, 2}; int use_vbr[3] = {0, 1, 1}; int vbr_constraints[3] = {0, 1, 1}; int complexities[11] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; int max_bandwidths[6] = {OPUS_BANDWIDTH_NARROWBAND, OPUS_BANDWIDTH_MEDIUMBAND, OPUS_BANDWIDTH_WIDEBAND, OPUS_BANDWIDTH_SUPERWIDEBAND, OPUS_BANDWIDTH_FULLBAND, OPUS_BANDWIDTH_FULLBAND}; int signals[4] = {OPUS_AUTO, OPUS_AUTO, OPUS_SIGNAL_VOICE, OPUS_SIGNAL_MUSIC}; int inband_fecs[3] = {0, 0, 1}; int packet_loss_perc[4] = {0, 1, 2, 5}; int lsb_depths[2] = {8, 24}; int prediction_disabled[3] = {0, 0, 1}; int use_dtx[2] = {0, 1}; int frame_sizes_ms_x2[9] = {5, 10, 20, 40, 80, 120, 160, 200, 240}; /* x2 to avoid 2.5 ms */ for (i=0; i=64000?2:1)))!=OPUS_OK)test_failed(); if(opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY((count>>2)%11))!=OPUS_OK)test_failed(); if(opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC((fast_rand()&15)&(fast_rand()%15)))!=OPUS_OK)test_failed(); bw=modes[j]==0?OPUS_BANDWIDTH_NARROWBAND+(fast_rand()%3): modes[j]==1?OPUS_BANDWIDTH_SUPERWIDEBAND+(fast_rand()&1): OPUS_BANDWIDTH_NARROWBAND+(fast_rand()%5); if(modes[j]==2&&bw==OPUS_BANDWIDTH_MEDIUMBAND)bw+=3; if(opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(bw))!=OPUS_OK)test_failed(); len = opus_encode(enc, &inbuf[i<<1], frame_size, packet, MAX_PACKET); if(len<0 || len>MAX_PACKET)test_failed(); if(opus_encoder_ctl(enc, OPUS_GET_FINAL_RANGE(&enc_final_range))!=OPUS_OK)test_failed(); if((fast_rand()&3)==0) { if(opus_packet_pad(packet,len,len+1)!=OPUS_OK)test_failed(); len++; } if((fast_rand()&7)==0) { if(opus_packet_pad(packet,len,len+256)!=OPUS_OK)test_failed(); len+=256; } if((fast_rand()&3)==0) { len=opus_packet_unpad(packet,len); if(len<1)test_failed(); } out_samples = opus_decode(dec, packet, len, &outbuf[i<<1], MAX_FRAME_SAMP, 0); if(out_samples!=frame_size)test_failed(); if(opus_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(&dec_final_range))!=OPUS_OK)test_failed(); if(enc_final_range!=dec_final_range)test_failed(); /*LBRR decode*/ out_samples = opus_decode(dec_err[0], packet, len, out2buf, frame_size, (fast_rand()&3)!=0); if(out_samples!=frame_size)test_failed(); out_samples = opus_decode(dec_err[1], packet, (fast_rand()&3)==0?0:len, out2buf, MAX_FRAME_SAMP, (fast_rand()&7)!=0); if(out_samples<120)test_failed(); i+=frame_size; count++; }while(i<(SSAMPLES-MAX_FRAME_SAMP)); fprintf(stdout," Mode %s FB encode %s, %6d bps OK.\n",mstrings[modes[j]],rc==0?" VBR":rc==1?"CVBR":" CBR",rate); } } if(opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(OPUS_AUTO))!=OPUS_OK)test_failed(); if(opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(OPUS_AUTO))!=OPUS_OK)test_failed(); if(opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(0))!=OPUS_OK)test_failed(); if(opus_encoder_ctl(enc, OPUS_SET_DTX(0))!=OPUS_OK)test_failed(); for(rc=0;rc<3;rc++) { if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_VBR(rc<2))!=OPUS_OK)test_failed(); if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_VBR_CONSTRAINT(rc==1))!=OPUS_OK)test_failed(); if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_VBR_CONSTRAINT(rc==1))!=OPUS_OK)test_failed(); if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_INBAND_FEC(rc==0))!=OPUS_OK)test_failed(); for(j=0;j<16;j++) { int rate; int modes[16]={0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2}; int rates[16]={4000,12000,32000,8000,16000,32000,48000,88000,4000,12000,32000,8000,16000,32000,48000,88000}; int frame[16]={160*1,160,80,160,160,80,40,20,160*1,160,80,160,160,80,40,20}; if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_INBAND_FEC(rc==0&&j==1))!=OPUS_OK)test_failed(); if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_FORCE_MODE(MODE_SILK_ONLY+modes[j]))!=OPUS_OK)test_failed(); rate=rates[j]+fast_rand()%rates[j]; if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_DTX(fast_rand()&1))!=OPUS_OK)test_failed(); if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_BITRATE(rate))!=OPUS_OK)test_failed(); count=i=0; do { int len,out_samples,frame_size,loss; opus_int32 pred; if(opus_multistream_encoder_ctl(MSenc, OPUS_GET_PREDICTION_DISABLED(&pred))!=OPUS_OK)test_failed(); if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_PREDICTION_DISABLED((int)(fast_rand()&15)<(pred?11:4)))!=OPUS_OK)test_failed(); frame_size=frame[j]; if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_COMPLEXITY((count>>2)%11))!=OPUS_OK)test_failed(); if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_PACKET_LOSS_PERC((fast_rand()&15)&(fast_rand()%15)))!=OPUS_OK)test_failed(); if((fast_rand()&255)==0) { if(opus_multistream_encoder_ctl(MSenc, OPUS_RESET_STATE)!=OPUS_OK)test_failed(); if(opus_multistream_decoder_ctl(MSdec, OPUS_RESET_STATE)!=OPUS_OK)test_failed(); if((fast_rand()&3)!=0) { if(opus_multistream_decoder_ctl(MSdec_err, OPUS_RESET_STATE)!=OPUS_OK)test_failed(); } } if((fast_rand()&255)==0) { if(opus_multistream_decoder_ctl(MSdec_err, OPUS_RESET_STATE)!=OPUS_OK)test_failed(); } len = opus_multistream_encode(MSenc, &inbuf[i<<1], frame_size, packet, MAX_PACKET); if(len<0 || len>MAX_PACKET)test_failed(); if(opus_multistream_encoder_ctl(MSenc, OPUS_GET_FINAL_RANGE(&enc_final_range))!=OPUS_OK)test_failed(); if((fast_rand()&3)==0) { if(opus_multistream_packet_pad(packet,len,len+1,2)!=OPUS_OK)test_failed(); len++; } if((fast_rand()&7)==0) { if(opus_multistream_packet_pad(packet,len,len+256,2)!=OPUS_OK)test_failed(); len+=256; } if((fast_rand()&3)==0) { len=opus_multistream_packet_unpad(packet,len,2); if(len<1)test_failed(); } out_samples = opus_multistream_decode(MSdec, packet, len, out2buf, MAX_FRAME_SAMP, 0); if(out_samples!=frame_size*6)test_failed(); if(opus_multistream_decoder_ctl(MSdec, OPUS_GET_FINAL_RANGE(&dec_final_range))!=OPUS_OK)test_failed(); if(enc_final_range!=dec_final_range)test_failed(); /*LBRR decode*/ loss=(fast_rand()&63)==0; out_samples = opus_multistream_decode(MSdec_err, packet, loss?0:len, out2buf, frame_size*6, (fast_rand()&3)!=0); if(out_samples!=(frame_size*6))test_failed(); i+=frame_size; count++; }while(i<(SSAMPLES/12-MAX_FRAME_SAMP)); fprintf(stdout," Mode %s NB dual-mono MS encode %s, %6d bps OK.\n",mstrings[modes[j]],rc==0?" VBR":rc==1?"CVBR":" CBR",rate); } } bitrate_bps=512000; fsize=fast_rand()%31; fswitch=100; debruijn2(6,db62); count=i=0; do { unsigned char toc; const unsigned char *frames[48]; short size[48]; int payload_offset; opus_uint32 dec_final_range2; int jj,dec2; int len,out_samples; int frame_size=fsizes[db62[fsize]]; opus_int32 offset=i%(SAMPLES-MAX_FRAME_SAMP); opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps)); len = opus_encode(enc, &inbuf[offset<<1], frame_size, packet, MAX_PACKET); if(len<0 || len>MAX_PACKET)test_failed(); count++; opus_encoder_ctl(enc, OPUS_GET_FINAL_RANGE(&enc_final_range)); out_samples = opus_decode(dec, packet, len, &outbuf[offset<<1], MAX_FRAME_SAMP, 0); if(out_samples!=frame_size)test_failed(); opus_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(&dec_final_range)); /* compare final range encoder rng values of encoder and decoder */ if(dec_final_range!=enc_final_range)test_failed(); /* We fuzz the packet, but take care not to only corrupt the payload Corrupted headers are tested elsewhere and we need to actually run the decoders in order to compare them. */ if(opus_packet_parse(packet,len,&toc,frames,size,&payload_offset)<=0)test_failed(); if((fast_rand()&1023)==0)len=0; for(j=(opus_int32)(frames[0]-packet);j0?packet:NULL, len, out2buf, MAX_FRAME_SAMP, 0); if(out_samples<0||out_samples>MAX_FRAME_SAMP)test_failed(); if((len>0&&out_samples!=frame_size))test_failed(); /*FIXME use lastframe*/ opus_decoder_ctl(dec_err[0], OPUS_GET_FINAL_RANGE(&dec_final_range)); /*randomly select one of the decoders to compare with*/ dec2=fast_rand()%9+1; out_samples = opus_decode(dec_err[dec2], len>0?packet:NULL, len, out2buf, MAX_FRAME_SAMP, 0); if(out_samples<0||out_samples>MAX_FRAME_SAMP)test_failed(); /*FIXME, use factor, lastframe for loss*/ opus_decoder_ctl(dec_err[dec2], OPUS_GET_FINAL_RANGE(&dec_final_range2)); if(len>0&&dec_final_range!=dec_final_range2)test_failed(); fswitch--; if(fswitch<1) { int new_size; fsize=(fsize+1)%36; new_size=fsizes[db62[fsize]]; if(new_size==960||new_size==480)fswitch=2880/new_size*(fast_rand()%19+1); else fswitch=(fast_rand()%(2880/new_size))+1; } bitrate_bps=((fast_rand()%508000+4000)+bitrate_bps)>>1; i+=frame_size; }while(i] [-fuzz ]\n",_argv[0]); } int main(int _argc, char **_argv) { int args=1; char * strtol_str=NULL; const char * oversion; const char * env_seed; int env_used; int num_encoders_to_fuzz=5; int num_setting_changes=40; env_used=0; env_seed=getenv("SEED"); if(_argc>1) iseed=strtol(_argv[1], &strtol_str, 10); /* the first input argument might be the seed */ if(strtol_str!=NULL && strtol_str[0]=='\0') /* iseed is a valid number */ args++; else if(env_seed) { iseed=atoi(env_seed); env_used=1; } else iseed=(opus_uint32)time(NULL)^(((opus_uint32)getpid()&65535)<<16); Rw=Rz=iseed; while(args<_argc) { if(strcmp(_argv[args], "-fuzz")==0 && _argc==(args+3)) { num_encoders_to_fuzz=strtol(_argv[args+1], &strtol_str, 10); if(strtol_str[0]!='\0' || num_encoders_to_fuzz<=0) { print_usage(_argv); return EXIT_FAILURE; } num_setting_changes=strtol(_argv[args+2], &strtol_str, 10); if(strtol_str[0]!='\0' || num_setting_changes<=0) { print_usage(_argv); return EXIT_FAILURE; } args+=3; } else { print_usage(_argv); return EXIT_FAILURE; } } oversion=opus_get_version_string(); if(!oversion)test_failed(); fprintf(stderr,"Testing %s encoder. Random seed: %u (%.4X)\n", oversion, iseed, fast_rand() % 65535); if(env_used)fprintf(stderr," Random seed set from the environment (SEED=%s).\n", env_seed); regression_test(); /*Setting TEST_OPUS_NOFUZZ tells the tool not to send garbage data into the decoders. This is helpful because garbage data may cause the decoders to clip, which angers CLANG IOC.*/ run_test1(getenv("TEST_OPUS_NOFUZZ")!=NULL); /* Fuzz encoder settings online */ if(getenv("TEST_OPUS_NOFUZZ")==NULL) { fprintf(stderr,"Running fuzz_encoder_settings with %d encoder(s) and %d setting change(s) each.\n", num_encoders_to_fuzz, num_setting_changes); fuzz_encoder_settings(num_encoders_to_fuzz, num_setting_changes); } fprintf(stderr,"Tests completed successfully.\n"); return 0; } jamulus-3.9.1+dfsg/libs/opus/tests/test_opus_projection.c0000644000175000017500000003002614340334543022663 0ustar vimervimer/* Copyright (c) 2017 Google Inc. Written by Andrew Allen */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "float_cast.h" #include "opus.h" #include "test_opus_common.h" #include "opus_projection.h" #include "mathops.h" #include "../src/mapping_matrix.h" #include "mathops.h" #define BUFFER_SIZE 960 #define MAX_DATA_BYTES 32768 #define MAX_FRAME_SAMPLES 5760 #define ERROR_TOLERANCE 1 #define SIMPLE_MATRIX_SIZE 12 #define SIMPLE_MATRIX_FRAME_SIZE 10 #define SIMPLE_MATRIX_INPUT_SIZE 30 #define SIMPLE_MATRIX_OUTPUT_SIZE 40 int assert_is_equal( const opus_val16 *a, const opus_int16 *b, int size, opus_int16 tolerance) { int i; for (i = 0; i < size; i++) { #ifdef FIXED_POINT opus_int16 val = a[i]; #else opus_int16 val = FLOAT2INT16(a[i]); #endif if (abs(val - b[i]) > tolerance) return 1; } return 0; } int assert_is_equal_short( const opus_int16 *a, const opus_int16 *b, int size, opus_int16 tolerance) { int i; for (i = 0; i < size; i++) if (abs(a[i] - b[i]) > tolerance) return 1; return 0; } void test_simple_matrix(void) { const MappingMatrix simple_matrix_params = {4, 3, 0}; const opus_int16 simple_matrix_data[SIMPLE_MATRIX_SIZE] = {0, 32767, 0, 0, 32767, 0, 0, 0, 0, 0, 0, 32767}; const opus_int16 input_int16[SIMPLE_MATRIX_INPUT_SIZE] = { 32767, 0, -32768, 29491, -3277, -29491, 26214, -6554, -26214, 22938, -9830, -22938, 19661, -13107, -19661, 16384, -16384, -16384, 13107, -19661, -13107, 9830, -22938, -9830, 6554, -26214, -6554, 3277, -29491, -3277}; const opus_int16 expected_output_int16[SIMPLE_MATRIX_OUTPUT_SIZE] = { 0, 32767, 0, -32768, -3277, 29491, 0, -29491, -6554, 26214, 0, -26214, -9830, 22938, 0, -22938, -13107, 19661, 0, -19661, -16384, 16384, 0, -16384, -19661, 13107, 0, -13107, -22938, 9830, 0, -9830, -26214, 6554, 0, -6554, -29491, 3277, 0, -3277}; int i, ret; opus_int32 simple_matrix_size; opus_val16 *input_val16; opus_val16 *output_val16; opus_int16 *output_int16; MappingMatrix *simple_matrix; /* Allocate input/output buffers. */ input_val16 = (opus_val16 *)opus_alloc(sizeof(opus_val16) * SIMPLE_MATRIX_INPUT_SIZE); output_int16 = (opus_int16 *)opus_alloc(sizeof(opus_int16) * SIMPLE_MATRIX_OUTPUT_SIZE); output_val16 = (opus_val16 *)opus_alloc(sizeof(opus_val16) * SIMPLE_MATRIX_OUTPUT_SIZE); /* Initialize matrix */ simple_matrix_size = mapping_matrix_get_size(simple_matrix_params.rows, simple_matrix_params.cols); if (!simple_matrix_size) test_failed(); simple_matrix = (MappingMatrix *)opus_alloc(simple_matrix_size); mapping_matrix_init(simple_matrix, simple_matrix_params.rows, simple_matrix_params.cols, simple_matrix_params.gain, simple_matrix_data, sizeof(simple_matrix_data)); /* Copy inputs. */ for (i = 0; i < SIMPLE_MATRIX_INPUT_SIZE; i++) { #ifdef FIXED_POINT input_val16[i] = input_int16[i]; #else input_val16[i] = (1/32768.f)*input_int16[i]; #endif } /* _in_short */ for (i = 0; i < SIMPLE_MATRIX_OUTPUT_SIZE; i++) output_val16[i] = 0; for (i = 0; i < simple_matrix->rows; i++) { mapping_matrix_multiply_channel_in_short(simple_matrix, input_int16, simple_matrix->cols, &output_val16[i], i, simple_matrix->rows, SIMPLE_MATRIX_FRAME_SIZE); } ret = assert_is_equal(output_val16, expected_output_int16, SIMPLE_MATRIX_OUTPUT_SIZE, ERROR_TOLERANCE); if (ret) test_failed(); /* _out_short */ for (i = 0; i < SIMPLE_MATRIX_OUTPUT_SIZE; i++) output_int16[i] = 0; for (i = 0; i < simple_matrix->cols; i++) { mapping_matrix_multiply_channel_out_short(simple_matrix, &input_val16[i], i, simple_matrix->cols, output_int16, simple_matrix->rows, SIMPLE_MATRIX_FRAME_SIZE); } ret = assert_is_equal_short(output_int16, expected_output_int16, SIMPLE_MATRIX_OUTPUT_SIZE, ERROR_TOLERANCE); if (ret) test_failed(); #if !defined(DISABLE_FLOAT_API) && !defined(FIXED_POINT) /* _in_float */ for (i = 0; i < SIMPLE_MATRIX_OUTPUT_SIZE; i++) output_val16[i] = 0; for (i = 0; i < simple_matrix->rows; i++) { mapping_matrix_multiply_channel_in_float(simple_matrix, input_val16, simple_matrix->cols, &output_val16[i], i, simple_matrix->rows, SIMPLE_MATRIX_FRAME_SIZE); } ret = assert_is_equal(output_val16, expected_output_int16, SIMPLE_MATRIX_OUTPUT_SIZE, ERROR_TOLERANCE); if (ret) test_failed(); /* _out_float */ for (i = 0; i < SIMPLE_MATRIX_OUTPUT_SIZE; i++) output_val16[i] = 0; for (i = 0; i < simple_matrix->cols; i++) { mapping_matrix_multiply_channel_out_float(simple_matrix, &input_val16[i], i, simple_matrix->cols, output_val16, simple_matrix->rows, SIMPLE_MATRIX_FRAME_SIZE); } ret = assert_is_equal(output_val16, expected_output_int16, SIMPLE_MATRIX_OUTPUT_SIZE, ERROR_TOLERANCE); if (ret) test_failed(); #endif opus_free(input_val16); opus_free(output_int16); opus_free(output_val16); opus_free(simple_matrix); } void test_creation_arguments(const int channels, const int mapping_family) { int streams; int coupled_streams; int enc_error; int dec_error; int ret; OpusProjectionEncoder *st_enc = NULL; OpusProjectionDecoder *st_dec = NULL; const opus_int32 Fs = 48000; const int application = OPUS_APPLICATION_AUDIO; int order_plus_one = (int)floor(sqrt((float)channels)); int nondiegetic_channels = channels - order_plus_one * order_plus_one; int is_channels_valid = 0; int is_projection_valid = 0; st_enc = opus_projection_ambisonics_encoder_create(Fs, channels, mapping_family, &streams, &coupled_streams, application, &enc_error); if (st_enc != NULL) { opus_int32 matrix_size; unsigned char *matrix; ret = opus_projection_encoder_ctl(st_enc, OPUS_PROJECTION_GET_DEMIXING_MATRIX_SIZE_REQUEST, &matrix_size); if (ret != OPUS_OK || !matrix_size) test_failed(); matrix = (unsigned char *)opus_alloc(matrix_size); ret = opus_projection_encoder_ctl(st_enc, OPUS_PROJECTION_GET_DEMIXING_MATRIX_REQUEST, matrix, matrix_size); opus_projection_encoder_destroy(st_enc); st_dec = opus_projection_decoder_create(Fs, channels, streams, coupled_streams, matrix, matrix_size, &dec_error); if (st_dec != NULL) { opus_projection_decoder_destroy(st_dec); } opus_free(matrix); } is_channels_valid = (order_plus_one >= 2 && order_plus_one <= 4) && (nondiegetic_channels == 0 || nondiegetic_channels == 2); is_projection_valid = (enc_error == OPUS_OK && dec_error == OPUS_OK); if (is_channels_valid ^ is_projection_valid) { fprintf(stderr, "Channels: %d, Family: %d\n", channels, mapping_family); fprintf(stderr, "Order+1: %d, Non-diegetic Channels: %d\n", order_plus_one, nondiegetic_channels); fprintf(stderr, "Streams: %d, Coupled Streams: %d\n", streams, coupled_streams); test_failed(); } } void generate_music(short *buf, opus_int32 len, opus_int32 channels) { opus_int32 i,j,k; opus_int32 *a,*b,*c,*d; a = (opus_int32 *)malloc(sizeof(opus_int32) * channels); b = (opus_int32 *)malloc(sizeof(opus_int32) * channels); c = (opus_int32 *)malloc(sizeof(opus_int32) * channels); d = (opus_int32 *)malloc(sizeof(opus_int32) * channels); memset(a, 0, sizeof(opus_int32) * channels); memset(b, 0, sizeof(opus_int32) * channels); memset(c, 0, sizeof(opus_int32) * channels); memset(d, 0, sizeof(opus_int32) * channels); j=0; for(i=0;i>12)^((j>>10|j>>12)&26&j>>7)))&128)+128)<<15; r=fast_rand();v+=r&65535;v-=r>>16; b[k]=v-a[k]+((b[k]*61+32)>>6);a[k]=v; c[k]=(30*(c[k]+b[k]+d[k])+32)>>6;d[k]=b[k]; v=(c[k]+128)>>8; buf[i*channels+k]=v>32767?32767:(v<-32768?-32768:v); if(i%6==0)j++; } } free(a); free(b); free(c); free(d); } void test_encode_decode(opus_int32 bitrate, opus_int32 channels, const int mapping_family) { const opus_int32 Fs = 48000; const int application = OPUS_APPLICATION_AUDIO; OpusProjectionEncoder *st_enc; OpusProjectionDecoder *st_dec; int streams; int coupled; int error; short *buffer_in; short *buffer_out; unsigned char data[MAX_DATA_BYTES] = { 0 }; int len; int out_samples; opus_int32 matrix_size = 0; unsigned char *matrix = NULL; buffer_in = (short *)malloc(sizeof(short) * BUFFER_SIZE * channels); buffer_out = (short *)malloc(sizeof(short) * BUFFER_SIZE * channels); st_enc = opus_projection_ambisonics_encoder_create(Fs, channels, mapping_family, &streams, &coupled, application, &error); if (error != OPUS_OK) { fprintf(stderr, "Couldn\'t create encoder with %d channels and mapping family %d.\n", channels, mapping_family); free(buffer_in); free(buffer_out); test_failed(); } error = opus_projection_encoder_ctl(st_enc, OPUS_SET_BITRATE(bitrate * 1000 * (streams + coupled))); if (error != OPUS_OK) { goto bad_cleanup; } error = opus_projection_encoder_ctl(st_enc, OPUS_PROJECTION_GET_DEMIXING_MATRIX_SIZE_REQUEST, &matrix_size); if (error != OPUS_OK || !matrix_size) { goto bad_cleanup; } matrix = (unsigned char *)opus_alloc(matrix_size); error = opus_projection_encoder_ctl(st_enc, OPUS_PROJECTION_GET_DEMIXING_MATRIX_REQUEST, matrix, matrix_size); st_dec = opus_projection_decoder_create(Fs, channels, streams, coupled, matrix, matrix_size, &error); opus_free(matrix); if (error != OPUS_OK) { fprintf(stderr, "Couldn\'t create decoder with %d channels, %d streams " "and %d coupled streams.\n", channels, streams, coupled); goto bad_cleanup; } generate_music(buffer_in, BUFFER_SIZE, channels); len = opus_projection_encode( st_enc, buffer_in, BUFFER_SIZE, data, MAX_DATA_BYTES); if(len<0 || len>MAX_DATA_BYTES) { fprintf(stderr,"opus_encode() returned %d\n", len); goto bad_cleanup; } out_samples = opus_projection_decode( st_dec, data, len, buffer_out, MAX_FRAME_SAMPLES, 0); if(out_samples!=BUFFER_SIZE) { fprintf(stderr,"opus_decode() returned %d\n", out_samples); goto bad_cleanup; } opus_projection_decoder_destroy(st_dec); opus_projection_encoder_destroy(st_enc); free(buffer_in); free(buffer_out); return; bad_cleanup: free(buffer_in); free(buffer_out); test_failed(); } int main(int _argc, char **_argv) { unsigned int i; (void)_argc; (void)_argv; /* Test simple matrix multiplication routines. */ test_simple_matrix(); /* Test full range of channels in creation arguments. */ for (i = 0; i < 255; i++) test_creation_arguments(i, 3); /* Test encode/decode pipeline. */ test_encode_decode(64 * 18, 18, 3); fprintf(stderr, "All projection tests passed.\n"); return 0; } jamulus-3.9.1+dfsg/libs/opus/tests/run_vectors.sh0000755000175000017500000001160214340334543021145 0ustar vimervimer#!/bin/sh # Copyright (c) 2011-2012 Jean-Marc Valin # # This file is extracted from RFC6716. Please see that RFC for additional # information. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # - Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # - Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # - Neither the name of Internet Society, IETF or IETF Trust, nor the # names of specific contributors, may be used to endorse or promote # products derived from this software without specific prior written # permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER # OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. rm -f logs_mono.txt logs_mono2.txt rm -f logs_stereo.txt logs_stereo2.txt if [ "$#" -ne "3" ]; then echo "usage: run_vectors.sh " exit 1 fi CMD_PATH=$1 VECTOR_PATH=$2 RATE=$3 : ${OPUS_DEMO:=$CMD_PATH/opus_demo} : ${OPUS_COMPARE:=$CMD_PATH/opus_compare} if [ -d "$VECTOR_PATH" ]; then echo "Test vectors found in $VECTOR_PATH" else echo "No test vectors found" #Don't make the test fail here because the test vectors #will be distributed separately exit 0 fi if [ ! -x "$OPUS_COMPARE" ]; then echo "ERROR: Compare program not found: $OPUS_COMPARE" exit 1 fi if [ -x "$OPUS_DEMO" ]; then echo "Decoding with $OPUS_DEMO" else echo "ERROR: Decoder not found: $OPUS_DEMO" exit 1 fi echo "==============" echo "Testing mono" echo "==============" echo for file in 01 02 03 04 05 06 07 08 09 10 11 12 do if [ -e "$VECTOR_PATH/testvector$file.bit" ]; then echo "Testing testvector$file" else echo "Bitstream file not found: testvector$file.bit" fi if "$OPUS_DEMO" -d "$RATE" 1 "$VECTOR_PATH/testvector$file.bit" tmp.out >> logs_mono.txt 2>&1; then echo "successfully decoded" else echo "ERROR: decoding failed" exit 1 fi "$OPUS_COMPARE" -r "$RATE" "$VECTOR_PATH/testvector${file}.dec" tmp.out >> logs_mono.txt 2>&1 float_ret=$? "$OPUS_COMPARE" -r "$RATE" "$VECTOR_PATH/testvector${file}m.dec" tmp.out >> logs_mono2.txt 2>&1 float_ret2=$? if [ "$float_ret" -eq "0" ] || [ "$float_ret2" -eq "0" ]; then echo "output matches reference" else echo "ERROR: output does not match reference" exit 1 fi echo done echo "==============" echo Testing stereo echo "==============" echo for file in 01 02 03 04 05 06 07 08 09 10 11 12 do if [ -e "$VECTOR_PATH/testvector$file.bit" ]; then echo "Testing testvector$file" else echo "Bitstream file not found: testvector$file" fi if "$OPUS_DEMO" -d "$RATE" 2 "$VECTOR_PATH/testvector$file.bit" tmp.out >> logs_stereo.txt 2>&1; then echo "successfully decoded" else echo "ERROR: decoding failed" exit 1 fi "$OPUS_COMPARE" -s -r "$RATE" "$VECTOR_PATH/testvector${file}.dec" tmp.out >> logs_stereo.txt 2>&1 float_ret=$? "$OPUS_COMPARE" -s -r "$RATE" "$VECTOR_PATH/testvector${file}m.dec" tmp.out >> logs_stereo2.txt 2>&1 float_ret2=$? if [ "$float_ret" -eq "0" ] || [ "$float_ret2" -eq "0" ]; then echo "output matches reference" else echo "ERROR: output does not match reference" exit 1 fi echo done echo "All tests have passed successfully" mono1=`grep quality logs_mono.txt | awk '{sum+=$4}END{if (NR == 12) sum /= 12; else sum = 0; print sum}'` mono2=`grep quality logs_mono2.txt | awk '{sum+=$4}END{if (NR == 12) sum /= 12; else sum = 0; print sum}'` echo $mono1 $mono2 | awk '{if ($2 > $1) $1 = $2; print "Average mono quality is", $1, "%"}' stereo1=`grep quality logs_stereo.txt | awk '{sum+=$4}END{if (NR == 12) sum /= 12; else sum = 0; print sum}'` stereo2=`grep quality logs_stereo2.txt | awk '{sum+=$4}END{if (NR == 12) sum /= 12; else sum = 0; print sum}'` echo $stereo1 $stereo2 | awk '{if ($2 > $1) $1 = $2; print "Average stereo quality is", $1, "%"}' jamulus-3.9.1+dfsg/libs/opus/tests/test_opus_api.c0000644000175000017500000021161714340334543021267 0ustar vimervimer/* Copyright (c) 2011-2013 Xiph.Org Foundation Written by Gregory Maxwell */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* This tests the API presented by the libopus system. It does not attempt to extensively exercise the codec internals. The strategy here is to simply the API interface invariants: That sane options are accepted, insane options are rejected, and that nothing blows up. In particular we don't actually test that settings are heeded by the codec (though we do check that get after set returns a sane value when it should). Other tests check the actual codec behavior. In cases where its reasonable to do so we test exhaustively, but its not reasonable to do so in all cases. Although these tests are simple they found several library bugs when they were initially developed. */ /* These tests are more sensitive if compiled with -DVALGRIND and run inside valgrind. Malloc failure testing requires glibc. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "arch.h" #include "opus_multistream.h" #include "opus.h" #include "test_opus_common.h" #ifdef VALGRIND #include #define VG_UNDEF(x,y) VALGRIND_MAKE_MEM_UNDEFINED((x),(y)) #define VG_CHECK(x,y) VALGRIND_CHECK_MEM_IS_DEFINED((x),(y)) #else #define VG_UNDEF(x,y) #define VG_CHECK(x,y) #endif #if defined(HAVE___MALLOC_HOOK) #define MALLOC_FAIL #include "os_support.h" #include static const opus_int32 opus_apps[3] = {OPUS_APPLICATION_VOIP, OPUS_APPLICATION_AUDIO,OPUS_APPLICATION_RESTRICTED_LOWDELAY}; void *malloc_hook(__attribute__((unused)) size_t size, __attribute__((unused)) const void *caller) { return 0; } #endif opus_int32 *null_int_ptr = (opus_int32 *)NULL; opus_uint32 *null_uint_ptr = (opus_uint32 *)NULL; static const opus_int32 opus_rates[5] = {48000,24000,16000,12000,8000}; opus_int32 test_dec_api(void) { opus_uint32 dec_final_range; OpusDecoder *dec; OpusDecoder *dec2; opus_int32 i,j,cfgs; unsigned char packet[1276]; #ifndef DISABLE_FLOAT_API float fbuf[960*2]; #endif short sbuf[960*2]; int c,err; cfgs=0; /*First test invalid configurations which should fail*/ fprintf(stdout,"\n Decoder basic API tests\n"); fprintf(stdout," ---------------------------------------------------\n"); for(c=0;c<4;c++) { i=opus_decoder_get_size(c); if(((c==1||c==2)&&(i<=2048||i>1<<16))||((c!=1&&c!=2)&&i!=0))test_failed(); fprintf(stdout," opus_decoder_get_size(%d)=%d ...............%s OK.\n",c,i,i>0?"":"...."); cfgs++; } /*Test with unsupported sample rates*/ for(c=0;c<4;c++) { for(i=-7;i<=96000;i++) { int fs; if((i==8000||i==12000||i==16000||i==24000||i==48000)&&(c==1||c==2))continue; switch(i) { case(-5):fs=-8000;break; case(-6):fs=INT32_MAX;break; case(-7):fs=INT32_MIN;break; default:fs=i; } err = OPUS_OK; VG_UNDEF(&err,sizeof(err)); dec = opus_decoder_create(fs, c, &err); if(err!=OPUS_BAD_ARG || dec!=NULL)test_failed(); cfgs++; dec = opus_decoder_create(fs, c, 0); if(dec!=NULL)test_failed(); cfgs++; dec=malloc(opus_decoder_get_size(2)); if(dec==NULL)test_failed(); err = opus_decoder_init(dec,fs,c); if(err!=OPUS_BAD_ARG)test_failed(); cfgs++; free(dec); } } VG_UNDEF(&err,sizeof(err)); dec = opus_decoder_create(48000, 2, &err); if(err!=OPUS_OK || dec==NULL)test_failed(); VG_CHECK(dec,opus_decoder_get_size(2)); cfgs++; fprintf(stdout," opus_decoder_create() ........................ OK.\n"); fprintf(stdout," opus_decoder_init() .......................... OK.\n"); err=opus_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(null_uint_ptr)); if(err != OPUS_BAD_ARG)test_failed(); VG_UNDEF(&dec_final_range,sizeof(dec_final_range)); err=opus_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(&dec_final_range)); if(err!=OPUS_OK)test_failed(); VG_CHECK(&dec_final_range,sizeof(dec_final_range)); fprintf(stdout," OPUS_GET_FINAL_RANGE ......................... OK.\n"); cfgs++; err=opus_decoder_ctl(dec,OPUS_UNIMPLEMENTED); if(err!=OPUS_UNIMPLEMENTED)test_failed(); fprintf(stdout," OPUS_UNIMPLEMENTED ........................... OK.\n"); cfgs++; err=opus_decoder_ctl(dec, OPUS_GET_BANDWIDTH(null_int_ptr)); if(err != OPUS_BAD_ARG)test_failed(); VG_UNDEF(&i,sizeof(i)); err=opus_decoder_ctl(dec, OPUS_GET_BANDWIDTH(&i)); if(err != OPUS_OK || i!=0)test_failed(); fprintf(stdout," OPUS_GET_BANDWIDTH ........................... OK.\n"); cfgs++; err=opus_decoder_ctl(dec, OPUS_GET_SAMPLE_RATE(null_int_ptr)); if(err != OPUS_BAD_ARG)test_failed(); VG_UNDEF(&i,sizeof(i)); err=opus_decoder_ctl(dec, OPUS_GET_SAMPLE_RATE(&i)); if(err != OPUS_OK || i!=48000)test_failed(); fprintf(stdout," OPUS_GET_SAMPLE_RATE ......................... OK.\n"); cfgs++; /*GET_PITCH has different execution paths depending on the previously decoded frame.*/ err=opus_decoder_ctl(dec, OPUS_GET_PITCH(null_int_ptr)); if(err!=OPUS_BAD_ARG)test_failed(); cfgs++; VG_UNDEF(&i,sizeof(i)); err=opus_decoder_ctl(dec, OPUS_GET_PITCH(&i)); if(err != OPUS_OK || i>0 || i<-1)test_failed(); cfgs++; VG_UNDEF(packet,sizeof(packet)); packet[0]=63<<2;packet[1]=packet[2]=0; if(opus_decode(dec, packet, 3, sbuf, 960, 0)!=960)test_failed(); cfgs++; VG_UNDEF(&i,sizeof(i)); err=opus_decoder_ctl(dec, OPUS_GET_PITCH(&i)); if(err != OPUS_OK || i>0 || i<-1)test_failed(); cfgs++; packet[0]=1; if(opus_decode(dec, packet, 1, sbuf, 960, 0)!=960)test_failed(); cfgs++; VG_UNDEF(&i,sizeof(i)); err=opus_decoder_ctl(dec, OPUS_GET_PITCH(&i)); if(err != OPUS_OK || i>0 || i<-1)test_failed(); cfgs++; fprintf(stdout," OPUS_GET_PITCH ............................... OK.\n"); err=opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(null_int_ptr)); if(err != OPUS_BAD_ARG)test_failed(); VG_UNDEF(&i,sizeof(i)); err=opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&i)); if(err != OPUS_OK || i!=960)test_failed(); cfgs++; fprintf(stdout," OPUS_GET_LAST_PACKET_DURATION ................ OK.\n"); VG_UNDEF(&i,sizeof(i)); err=opus_decoder_ctl(dec, OPUS_GET_GAIN(&i)); VG_CHECK(&i,sizeof(i)); if(err != OPUS_OK || i!=0)test_failed(); cfgs++; err=opus_decoder_ctl(dec, OPUS_GET_GAIN(null_int_ptr)); if(err != OPUS_BAD_ARG)test_failed(); cfgs++; err=opus_decoder_ctl(dec, OPUS_SET_GAIN(-32769)); if(err != OPUS_BAD_ARG)test_failed(); cfgs++; err=opus_decoder_ctl(dec, OPUS_SET_GAIN(32768)); if(err != OPUS_BAD_ARG)test_failed(); cfgs++; err=opus_decoder_ctl(dec, OPUS_SET_GAIN(-15)); if(err != OPUS_OK)test_failed(); cfgs++; VG_UNDEF(&i,sizeof(i)); err=opus_decoder_ctl(dec, OPUS_GET_GAIN(&i)); VG_CHECK(&i,sizeof(i)); if(err != OPUS_OK || i!=-15)test_failed(); cfgs++; fprintf(stdout," OPUS_SET_GAIN ................................ OK.\n"); fprintf(stdout," OPUS_GET_GAIN ................................ OK.\n"); /*Reset the decoder*/ dec2=malloc(opus_decoder_get_size(2)); memcpy(dec2,dec,opus_decoder_get_size(2)); if(opus_decoder_ctl(dec, OPUS_RESET_STATE)!=OPUS_OK)test_failed(); if(memcmp(dec2,dec,opus_decoder_get_size(2))==0)test_failed(); free(dec2); fprintf(stdout," OPUS_RESET_STATE ............................. OK.\n"); cfgs++; VG_UNDEF(packet,sizeof(packet)); packet[0]=0; if(opus_decoder_get_nb_samples(dec,packet,1)!=480)test_failed(); if(opus_packet_get_nb_samples(packet,1,48000)!=480)test_failed(); if(opus_packet_get_nb_samples(packet,1,96000)!=960)test_failed(); if(opus_packet_get_nb_samples(packet,1,32000)!=320)test_failed(); if(opus_packet_get_nb_samples(packet,1,8000)!=80)test_failed(); packet[0]=3; if(opus_packet_get_nb_samples(packet,1,24000)!=OPUS_INVALID_PACKET)test_failed(); packet[0]=(63<<2)|3; packet[1]=63; if(opus_packet_get_nb_samples(packet,0,24000)!=OPUS_BAD_ARG)test_failed(); if(opus_packet_get_nb_samples(packet,2,48000)!=OPUS_INVALID_PACKET)test_failed(); if(opus_decoder_get_nb_samples(dec,packet,2)!=OPUS_INVALID_PACKET)test_failed(); fprintf(stdout," opus_{packet,decoder}_get_nb_samples() ....... OK.\n"); cfgs+=9; if(OPUS_BAD_ARG!=opus_packet_get_nb_frames(packet,0))test_failed(); for(i=0;i<256;i++) { int l1res[4]={1,2,2,OPUS_INVALID_PACKET}; packet[0]=i; if(l1res[packet[0]&3]!=opus_packet_get_nb_frames(packet,1))test_failed(); cfgs++; for(j=0;j<256;j++) { packet[1]=j; if(((packet[0]&3)!=3?l1res[packet[0]&3]:packet[1]&63)!=opus_packet_get_nb_frames(packet,2))test_failed(); cfgs++; } } fprintf(stdout," opus_packet_get_nb_frames() .................. OK.\n"); for(i=0;i<256;i++) { int bw; packet[0]=i; bw=packet[0]>>4; bw=OPUS_BANDWIDTH_NARROWBAND+(((((bw&7)*9)&(63-(bw&8)))+2+12*((bw&8)!=0))>>4); if(bw!=opus_packet_get_bandwidth(packet))test_failed(); cfgs++; } fprintf(stdout," opus_packet_get_bandwidth() .................. OK.\n"); for(i=0;i<256;i++) { int fp3s,rate; packet[0]=i; fp3s=packet[0]>>3; fp3s=((((3-(fp3s&3))*13&119)+9)>>2)*((fp3s>13)*(3-((fp3s&3)==3))+1)*25; for(rate=0;rate<5;rate++) { if((opus_rates[rate]*3/fp3s)!=opus_packet_get_samples_per_frame(packet,opus_rates[rate]))test_failed(); cfgs++; } } fprintf(stdout," opus_packet_get_samples_per_frame() .......... OK.\n"); packet[0]=(63<<2)+3; packet[1]=49; for(j=2;j<51;j++)packet[j]=0; VG_UNDEF(sbuf,sizeof(sbuf)); if(opus_decode(dec, packet, 51, sbuf, 960, 0)!=OPUS_INVALID_PACKET)test_failed(); cfgs++; packet[0]=(63<<2); packet[1]=packet[2]=0; if(opus_decode(dec, packet, -1, sbuf, 960, 0)!=OPUS_BAD_ARG)test_failed(); cfgs++; if(opus_decode(dec, packet, 3, sbuf, 60, 0)!=OPUS_BUFFER_TOO_SMALL)test_failed(); cfgs++; if(opus_decode(dec, packet, 3, sbuf, 480, 0)!=OPUS_BUFFER_TOO_SMALL)test_failed(); cfgs++; if(opus_decode(dec, packet, 3, sbuf, 960, 0)!=960)test_failed(); cfgs++; fprintf(stdout," opus_decode() ................................ OK.\n"); #ifndef DISABLE_FLOAT_API VG_UNDEF(fbuf,sizeof(fbuf)); if(opus_decode_float(dec, packet, 3, fbuf, 960, 0)!=960)test_failed(); cfgs++; fprintf(stdout," opus_decode_float() .......................... OK.\n"); #endif #if 0 /*These tests are disabled because the library crashes with null states*/ if(opus_decoder_ctl(0,OPUS_RESET_STATE) !=OPUS_INVALID_STATE)test_failed(); if(opus_decoder_init(0,48000,1) !=OPUS_INVALID_STATE)test_failed(); if(opus_decode(0,packet,1,outbuf,2880,0) !=OPUS_INVALID_STATE)test_failed(); if(opus_decode_float(0,packet,1,0,2880,0) !=OPUS_INVALID_STATE)test_failed(); if(opus_decoder_get_nb_samples(0,packet,1) !=OPUS_INVALID_STATE)test_failed(); if(opus_packet_get_nb_frames(NULL,1) !=OPUS_BAD_ARG)test_failed(); if(opus_packet_get_bandwidth(NULL) !=OPUS_BAD_ARG)test_failed(); if(opus_packet_get_samples_per_frame(NULL,48000)!=OPUS_BAD_ARG)test_failed(); #endif opus_decoder_destroy(dec); cfgs++; fprintf(stdout," All decoder interface tests passed\n"); fprintf(stdout," (%6d API invocations)\n",cfgs); return cfgs; } opus_int32 test_msdec_api(void) { opus_uint32 dec_final_range; OpusMSDecoder *dec; OpusDecoder *streamdec; opus_int32 i,j,cfgs; unsigned char packet[1276]; unsigned char mapping[256]; #ifndef DISABLE_FLOAT_API float fbuf[960*2]; #endif short sbuf[960*2]; int a,b,c,err; mapping[0]=0; mapping[1]=1; for(i=2;i<256;i++)VG_UNDEF(&mapping[i],sizeof(unsigned char)); cfgs=0; /*First test invalid configurations which should fail*/ fprintf(stdout,"\n Multistream decoder basic API tests\n"); fprintf(stdout," ---------------------------------------------------\n"); for(a=-1;a<4;a++) { for(b=-1;b<4;b++) { i=opus_multistream_decoder_get_size(a,b); if(((a>0&&b<=a&&b>=0)&&(i<=2048||i>((1<<16)*a)))||((a<1||b>a||b<0)&&i!=0))test_failed(); fprintf(stdout," opus_multistream_decoder_get_size(%2d,%2d)=%d %sOK.\n",a,b,i,i>0?"":"... "); cfgs++; } } /*Test with unsupported sample rates*/ for(c=1;c<3;c++) { for(i=-7;i<=96000;i++) { int fs; if((i==8000||i==12000||i==16000||i==24000||i==48000)&&(c==1||c==2))continue; switch(i) { case(-5):fs=-8000;break; case(-6):fs=INT32_MAX;break; case(-7):fs=INT32_MIN;break; default:fs=i; } err = OPUS_OK; VG_UNDEF(&err,sizeof(err)); dec = opus_multistream_decoder_create(fs, c, 1, c-1, mapping, &err); if(err!=OPUS_BAD_ARG || dec!=NULL)test_failed(); cfgs++; dec = opus_multistream_decoder_create(fs, c, 1, c-1, mapping, 0); if(dec!=NULL)test_failed(); cfgs++; dec=malloc(opus_multistream_decoder_get_size(1,1)); if(dec==NULL)test_failed(); err = opus_multistream_decoder_init(dec,fs,c,1,c-1, mapping); if(err!=OPUS_BAD_ARG)test_failed(); cfgs++; free(dec); } } for(c=0;c<2;c++) { int *ret_err; ret_err = c?0:&err; mapping[0]=0; mapping[1]=1; for(i=2;i<256;i++)VG_UNDEF(&mapping[i],sizeof(unsigned char)); VG_UNDEF(ret_err,sizeof(*ret_err)); dec = opus_multistream_decoder_create(48000, 2, 1, 0, mapping, ret_err); if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));} if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed(); cfgs++; VG_UNDEF(ret_err,sizeof(*ret_err)); mapping[0]=mapping[1]=0; dec = opus_multistream_decoder_create(48000, 2, 1, 0, mapping, ret_err); if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));} if((ret_err && *ret_err!=OPUS_OK) || dec==NULL)test_failed(); cfgs++; opus_multistream_decoder_destroy(dec); cfgs++; VG_UNDEF(ret_err,sizeof(*ret_err)); dec = opus_multistream_decoder_create(48000, 1, 4, 1, mapping, ret_err); if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));} if((ret_err && *ret_err!=OPUS_OK) || dec==NULL)test_failed(); cfgs++; err = opus_multistream_decoder_init(dec,48000, 1, 0, 0, mapping); if(err!=OPUS_BAD_ARG)test_failed(); cfgs++; err = opus_multistream_decoder_init(dec,48000, 1, 1, -1, mapping); if(err!=OPUS_BAD_ARG)test_failed(); cfgs++; opus_multistream_decoder_destroy(dec); cfgs++; VG_UNDEF(ret_err,sizeof(*ret_err)); dec = opus_multistream_decoder_create(48000, 2, 1, 1, mapping, ret_err); if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));} if((ret_err && *ret_err!=OPUS_OK) || dec==NULL)test_failed(); cfgs++; opus_multistream_decoder_destroy(dec); cfgs++; VG_UNDEF(ret_err,sizeof(*ret_err)); dec = opus_multistream_decoder_create(48000, 255, 255, 1, mapping, ret_err); if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));} if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed(); cfgs++; VG_UNDEF(ret_err,sizeof(*ret_err)); dec = opus_multistream_decoder_create(48000, -1, 1, 1, mapping, ret_err); if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));} if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed(); cfgs++; VG_UNDEF(ret_err,sizeof(*ret_err)); dec = opus_multistream_decoder_create(48000, 0, 1, 1, mapping, ret_err); if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));} if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed(); cfgs++; VG_UNDEF(ret_err,sizeof(*ret_err)); dec = opus_multistream_decoder_create(48000, 1, -1, 2, mapping, ret_err); if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));} if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed(); cfgs++; VG_UNDEF(ret_err,sizeof(*ret_err)); dec = opus_multistream_decoder_create(48000, 1, -1, -1, mapping, ret_err); if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));} if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed(); cfgs++; VG_UNDEF(ret_err,sizeof(*ret_err)); dec = opus_multistream_decoder_create(48000, 256, 255, 1, mapping, ret_err); if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));} if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed(); cfgs++; VG_UNDEF(ret_err,sizeof(*ret_err)); dec = opus_multistream_decoder_create(48000, 256, 255, 0, mapping, ret_err); if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));} if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed(); cfgs++; VG_UNDEF(ret_err,sizeof(*ret_err)); mapping[0]=255; mapping[1]=1; mapping[2]=2; dec = opus_multistream_decoder_create(48000, 3, 2, 0, mapping, ret_err); if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));} if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed(); cfgs++; VG_UNDEF(ret_err,sizeof(*ret_err)); mapping[0]=0; mapping[1]=0; mapping[2]=0; dec = opus_multistream_decoder_create(48000, 3, 2, 1, mapping, ret_err); if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));} if((ret_err && *ret_err!=OPUS_OK) || dec==NULL)test_failed(); cfgs++; opus_multistream_decoder_destroy(dec); cfgs++; VG_UNDEF(ret_err,sizeof(*ret_err)); mapping[0]=0; mapping[1]=255; mapping[2]=1; mapping[3]=2; mapping[4]=3; dec = opus_multistream_decoder_create(48001, 5, 4, 1, mapping, ret_err); if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));} if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed(); cfgs++; } VG_UNDEF(&err,sizeof(err)); mapping[0]=0; mapping[1]=255; mapping[2]=1; mapping[3]=2; dec = opus_multistream_decoder_create(48000, 4, 2, 1, mapping, &err); VG_CHECK(&err,sizeof(err)); if(err!=OPUS_OK || dec==NULL)test_failed(); cfgs++; fprintf(stdout," opus_multistream_decoder_create() ............ OK.\n"); fprintf(stdout," opus_multistream_decoder_init() .............. OK.\n"); VG_UNDEF(&dec_final_range,sizeof(dec_final_range)); err=opus_multistream_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(&dec_final_range)); if(err!=OPUS_OK)test_failed(); VG_CHECK(&dec_final_range,sizeof(dec_final_range)); fprintf(stdout," OPUS_GET_FINAL_RANGE ......................... OK.\n"); cfgs++; streamdec=0; VG_UNDEF(&streamdec,sizeof(streamdec)); err=opus_multistream_decoder_ctl(dec, OPUS_MULTISTREAM_GET_DECODER_STATE(-1,&streamdec)); if(err!=OPUS_BAD_ARG)test_failed(); cfgs++; err=opus_multistream_decoder_ctl(dec, OPUS_MULTISTREAM_GET_DECODER_STATE(1,&streamdec)); if(err!=OPUS_OK||streamdec==NULL)test_failed(); VG_CHECK(streamdec,opus_decoder_get_size(1)); cfgs++; err=opus_multistream_decoder_ctl(dec, OPUS_MULTISTREAM_GET_DECODER_STATE(2,&streamdec)); if(err!=OPUS_BAD_ARG)test_failed(); cfgs++; err=opus_multistream_decoder_ctl(dec, OPUS_MULTISTREAM_GET_DECODER_STATE(0,&streamdec)); if(err!=OPUS_OK||streamdec==NULL)test_failed(); VG_CHECK(streamdec,opus_decoder_get_size(1)); fprintf(stdout," OPUS_MULTISTREAM_GET_DECODER_STATE ........... OK.\n"); cfgs++; for(j=0;j<2;j++) { OpusDecoder *od; err=opus_multistream_decoder_ctl(dec,OPUS_MULTISTREAM_GET_DECODER_STATE(j,&od)); if(err != OPUS_OK)test_failed(); VG_UNDEF(&i,sizeof(i)); err=opus_decoder_ctl(od, OPUS_GET_GAIN(&i)); VG_CHECK(&i,sizeof(i)); if(err != OPUS_OK || i!=0)test_failed(); cfgs++; } err=opus_multistream_decoder_ctl(dec,OPUS_SET_GAIN(15)); if(err!=OPUS_OK)test_failed(); fprintf(stdout," OPUS_SET_GAIN ................................ OK.\n"); for(j=0;j<2;j++) { OpusDecoder *od; err=opus_multistream_decoder_ctl(dec,OPUS_MULTISTREAM_GET_DECODER_STATE(j,&od)); if(err != OPUS_OK)test_failed(); VG_UNDEF(&i,sizeof(i)); err=opus_decoder_ctl(od, OPUS_GET_GAIN(&i)); VG_CHECK(&i,sizeof(i)); if(err != OPUS_OK || i!=15)test_failed(); cfgs++; } fprintf(stdout," OPUS_GET_GAIN ................................ OK.\n"); VG_UNDEF(&i,sizeof(i)); err=opus_multistream_decoder_ctl(dec, OPUS_GET_BANDWIDTH(&i)); if(err != OPUS_OK || i!=0)test_failed(); fprintf(stdout," OPUS_GET_BANDWIDTH ........................... OK.\n"); cfgs++; err=opus_multistream_decoder_ctl(dec,OPUS_UNIMPLEMENTED); if(err!=OPUS_UNIMPLEMENTED)test_failed(); fprintf(stdout," OPUS_UNIMPLEMENTED ........................... OK.\n"); cfgs++; #if 0 /*Currently unimplemented for multistream*/ /*GET_PITCH has different execution paths depending on the previously decoded frame.*/ err=opus_multistream_decoder_ctl(dec, OPUS_GET_PITCH(null_int_ptr)); if(err!=OPUS_BAD_ARG)test_failed(); cfgs++; VG_UNDEF(&i,sizeof(i)); err=opus_multistream_decoder_ctl(dec, OPUS_GET_PITCH(&i)); if(err != OPUS_OK || i>0 || i<-1)test_failed(); cfgs++; VG_UNDEF(packet,sizeof(packet)); packet[0]=63<<2;packet[1]=packet[2]=0; if(opus_multistream_decode(dec, packet, 3, sbuf, 960, 0)!=960)test_failed(); cfgs++; VG_UNDEF(&i,sizeof(i)); err=opus_multistream_decoder_ctl(dec, OPUS_GET_PITCH(&i)); if(err != OPUS_OK || i>0 || i<-1)test_failed(); cfgs++; packet[0]=1; if(opus_multistream_decode(dec, packet, 1, sbuf, 960, 0)!=960)test_failed(); cfgs++; VG_UNDEF(&i,sizeof(i)); err=opus_multistream_decoder_ctl(dec, OPUS_GET_PITCH(&i)); if(err != OPUS_OK || i>0 || i<-1)test_failed(); cfgs++; fprintf(stdout," OPUS_GET_PITCH ............................... OK.\n"); #endif /*Reset the decoder*/ if(opus_multistream_decoder_ctl(dec, OPUS_RESET_STATE)!=OPUS_OK)test_failed(); fprintf(stdout," OPUS_RESET_STATE ............................. OK.\n"); cfgs++; opus_multistream_decoder_destroy(dec); cfgs++; VG_UNDEF(&err,sizeof(err)); dec = opus_multistream_decoder_create(48000, 2, 1, 1, mapping, &err); if(err!=OPUS_OK || dec==NULL)test_failed(); cfgs++; packet[0]=(63<<2)+3; packet[1]=49; for(j=2;j<51;j++)packet[j]=0; VG_UNDEF(sbuf,sizeof(sbuf)); if(opus_multistream_decode(dec, packet, 51, sbuf, 960, 0)!=OPUS_INVALID_PACKET)test_failed(); cfgs++; packet[0]=(63<<2); packet[1]=packet[2]=0; if(opus_multistream_decode(dec, packet, -1, sbuf, 960, 0)!=OPUS_BAD_ARG){printf("%d\n",opus_multistream_decode(dec, packet, -1, sbuf, 960, 0));test_failed();} cfgs++; if(opus_multistream_decode(dec, packet, 3, sbuf, -960, 0)!=OPUS_BAD_ARG)test_failed(); cfgs++; if(opus_multistream_decode(dec, packet, 3, sbuf, 60, 0)!=OPUS_BUFFER_TOO_SMALL)test_failed(); cfgs++; if(opus_multistream_decode(dec, packet, 3, sbuf, 480, 0)!=OPUS_BUFFER_TOO_SMALL)test_failed(); cfgs++; if(opus_multistream_decode(dec, packet, 3, sbuf, 960, 0)!=960)test_failed(); cfgs++; fprintf(stdout," opus_multistream_decode() .................... OK.\n"); #ifndef DISABLE_FLOAT_API VG_UNDEF(fbuf,sizeof(fbuf)); if(opus_multistream_decode_float(dec, packet, 3, fbuf, 960, 0)!=960)test_failed(); cfgs++; fprintf(stdout," opus_multistream_decode_float() .............. OK.\n"); #endif #if 0 /*These tests are disabled because the library crashes with null states*/ if(opus_multistream_decoder_ctl(0,OPUS_RESET_STATE) !=OPUS_INVALID_STATE)test_failed(); if(opus_multistream_decoder_init(0,48000,1) !=OPUS_INVALID_STATE)test_failed(); if(opus_multistream_decode(0,packet,1,outbuf,2880,0) !=OPUS_INVALID_STATE)test_failed(); if(opus_multistream_decode_float(0,packet,1,0,2880,0) !=OPUS_INVALID_STATE)test_failed(); if(opus_multistream_decoder_get_nb_samples(0,packet,1) !=OPUS_INVALID_STATE)test_failed(); #endif opus_multistream_decoder_destroy(dec); cfgs++; fprintf(stdout," All multistream decoder interface tests passed\n"); fprintf(stdout," (%6d API invocations)\n",cfgs); return cfgs; } #ifdef VALGRIND #define UNDEFINE_FOR_PARSE toc=-1; \ frames[0]=(unsigned char *)0; \ frames[1]=(unsigned char *)0; \ payload_offset=-1; \ VG_UNDEF(&toc,sizeof(toc)); \ VG_UNDEF(frames,sizeof(frames));\ VG_UNDEF(&payload_offset,sizeof(payload_offset)); #else #define UNDEFINE_FOR_PARSE toc=-1; \ frames[0]=(unsigned char *)0; \ frames[1]=(unsigned char *)0; \ payload_offset=-1; #endif /* This test exercises the heck out of the libopus parser. It is much larger than the parser itself in part because it tries to hit a lot of corner cases that could never fail with the libopus code, but might be problematic for other implementations. */ opus_int32 test_parse(void) { opus_int32 i,j,jj,sz; unsigned char packet[1276]; opus_int32 cfgs,cfgs_total; unsigned char toc; const unsigned char *frames[48]; short size[48]; int payload_offset, ret; fprintf(stdout,"\n Packet header parsing tests\n"); fprintf(stdout," ---------------------------------------------------\n"); memset(packet,0,sizeof(char)*1276); packet[0]=63<<2; if(opus_packet_parse(packet,1,&toc,frames,0,&payload_offset)!=OPUS_BAD_ARG)test_failed(); cfgs_total=cfgs=1; /*code 0*/ for(i=0;i<64;i++) { packet[0]=i<<2; UNDEFINE_FOR_PARSE ret=opus_packet_parse(packet,4,&toc,frames,size,&payload_offset); cfgs++; if(ret!=1)test_failed(); if(size[0]!=3)test_failed(); if(frames[0]!=packet+1)test_failed(); } fprintf(stdout," code 0 (%2d cases) ............................ OK.\n",cfgs); cfgs_total+=cfgs;cfgs=0; /*code 1, two frames of the same size*/ for(i=0;i<64;i++) { packet[0]=(i<<2)+1; for(jj=0;jj<=1275*2+3;jj++) { UNDEFINE_FOR_PARSE ret=opus_packet_parse(packet,jj,&toc,frames,size,&payload_offset); cfgs++; if((jj&1)==1 && jj<=2551) { /* Must pass if payload length even (packet length odd) and size<=2551, must fail otherwise. */ if(ret!=2)test_failed(); if(size[0]!=size[1] || size[0]!=((jj-1)>>1))test_failed(); if(frames[0]!=packet+1)test_failed(); if(frames[1]!=frames[0]+size[0])test_failed(); if((toc>>2)!=i)test_failed(); } else if(ret!=OPUS_INVALID_PACKET)test_failed(); } } fprintf(stdout," code 1 (%6d cases) ........................ OK.\n",cfgs); cfgs_total+=cfgs;cfgs=0; for(i=0;i<64;i++) { /*code 2, length code overflow*/ packet[0]=(i<<2)+2; UNDEFINE_FOR_PARSE ret=opus_packet_parse(packet,1,&toc,frames,size,&payload_offset); cfgs++; if(ret!=OPUS_INVALID_PACKET)test_failed(); packet[1]=252; UNDEFINE_FOR_PARSE ret=opus_packet_parse(packet,2,&toc,frames,size,&payload_offset); cfgs++; if(ret!=OPUS_INVALID_PACKET)test_failed(); for(j=0;j<1275;j++) { if(j<252)packet[1]=j; else{packet[1]=252+(j&3);packet[2]=(j-252)>>2;} /*Code 2, one too short*/ UNDEFINE_FOR_PARSE ret=opus_packet_parse(packet,j+(j<252?2:3)-1,&toc,frames,size,&payload_offset); cfgs++; if(ret!=OPUS_INVALID_PACKET)test_failed(); /*Code 2, one too long*/ UNDEFINE_FOR_PARSE ret=opus_packet_parse(packet,j+(j<252?2:3)+1276,&toc,frames,size,&payload_offset); cfgs++; if(ret!=OPUS_INVALID_PACKET)test_failed(); /*Code 2, second zero*/ UNDEFINE_FOR_PARSE ret=opus_packet_parse(packet,j+(j<252?2:3),&toc,frames,size,&payload_offset); cfgs++; if(ret!=2)test_failed(); if(size[0]!=j||size[1]!=0)test_failed(); if(frames[1]!=frames[0]+size[0])test_failed(); if((toc>>2)!=i)test_failed(); /*Code 2, normal*/ UNDEFINE_FOR_PARSE ret=opus_packet_parse(packet,(j<<1)+4,&toc,frames,size,&payload_offset); cfgs++; if(ret!=2)test_failed(); if(size[0]!=j||size[1]!=(j<<1)+3-j-(j<252?1:2))test_failed(); if(frames[1]!=frames[0]+size[0])test_failed(); if((toc>>2)!=i)test_failed(); } } fprintf(stdout," code 2 (%6d cases) ........................ OK.\n",cfgs); cfgs_total+=cfgs;cfgs=0; for(i=0;i<64;i++) { packet[0]=(i<<2)+3; /*code 3, length code overflow*/ UNDEFINE_FOR_PARSE ret=opus_packet_parse(packet,1,&toc,frames,size,&payload_offset); cfgs++; if(ret!=OPUS_INVALID_PACKET)test_failed(); } fprintf(stdout," code 3 m-truncation (%2d cases) ............... OK.\n",cfgs); cfgs_total+=cfgs;cfgs=0; for(i=0;i<64;i++) { /*code 3, m is zero or 49-63*/ packet[0]=(i<<2)+3; for(jj=49;jj<=64;jj++) { packet[1]=0+(jj&63); /*CBR, no padding*/ UNDEFINE_FOR_PARSE ret=opus_packet_parse(packet,1275,&toc,frames,size,&payload_offset); cfgs++; if(ret!=OPUS_INVALID_PACKET)test_failed(); packet[1]=128+(jj&63); /*VBR, no padding*/ UNDEFINE_FOR_PARSE ret=opus_packet_parse(packet,1275,&toc,frames,size,&payload_offset); cfgs++; if(ret!=OPUS_INVALID_PACKET)test_failed(); packet[1]=64+(jj&63); /*CBR, padding*/ UNDEFINE_FOR_PARSE ret=opus_packet_parse(packet,1275,&toc,frames,size,&payload_offset); cfgs++; if(ret!=OPUS_INVALID_PACKET)test_failed(); packet[1]=128+64+(jj&63); /*VBR, padding*/ UNDEFINE_FOR_PARSE ret=opus_packet_parse(packet,1275,&toc,frames,size,&payload_offset); cfgs++; if(ret!=OPUS_INVALID_PACKET)test_failed(); } } fprintf(stdout," code 3 m=0,49-64 (%2d cases) ................ OK.\n",cfgs); cfgs_total+=cfgs;cfgs=0; for(i=0;i<64;i++) { packet[0]=(i<<2)+3; /*code 3, m is one, cbr*/ packet[1]=1; for(j=0;j<1276;j++) { UNDEFINE_FOR_PARSE ret=opus_packet_parse(packet,j+2,&toc,frames,size,&payload_offset); cfgs++; if(ret!=1)test_failed(); if(size[0]!=j)test_failed(); if((toc>>2)!=i)test_failed(); } UNDEFINE_FOR_PARSE ret=opus_packet_parse(packet,1276+2,&toc,frames,size,&payload_offset); cfgs++; if(ret!=OPUS_INVALID_PACKET)test_failed(); } fprintf(stdout," code 3 m=1 CBR (%2d cases) ................. OK.\n",cfgs); cfgs_total+=cfgs;cfgs=0; for(i=0;i<64;i++) { int frame_samp; /*code 3, m>1 CBR*/ packet[0]=(i<<2)+3; frame_samp=opus_packet_get_samples_per_frame(packet,48000); for(j=2;j<49;j++) { packet[1]=j; for(sz=2;sz<((j+2)*1275);sz++) { UNDEFINE_FOR_PARSE ret=opus_packet_parse(packet,sz,&toc,frames,size,&payload_offset); cfgs++; /*Must be <=120ms, must be evenly divisible, can't have frames>1275 bytes*/ if(frame_samp*j<=5760 && (sz-2)%j==0 && (sz-2)/j<1276) { if(ret!=j)test_failed(); for(jj=1;jj>2)!=i)test_failed(); } else if(ret!=OPUS_INVALID_PACKET)test_failed(); } } /*Super jumbo packets*/ packet[1]=5760/frame_samp; UNDEFINE_FOR_PARSE ret=opus_packet_parse(packet,1275*packet[1]+2,&toc,frames,size,&payload_offset); cfgs++; if(ret!=packet[1])test_failed(); for(jj=0;jj>2)!=i)test_failed(); } UNDEFINE_FOR_PARSE ret=opus_packet_parse(packet,2+1276,&toc,frames,size,&payload_offset); cfgs++; if(ret!=OPUS_INVALID_PACKET)test_failed(); for(j=2;j<49;j++) { packet[1]=128+j; /*Length code overflow*/ UNDEFINE_FOR_PARSE ret=opus_packet_parse(packet,2+j-2,&toc,frames,size,&payload_offset); cfgs++; if(ret!=OPUS_INVALID_PACKET)test_failed(); packet[2]=252; packet[3]=0; for(jj=4;jj<2+j;jj++)packet[jj]=0; UNDEFINE_FOR_PARSE ret=opus_packet_parse(packet,2+j,&toc,frames,size,&payload_offset); cfgs++; if(ret!=OPUS_INVALID_PACKET)test_failed(); /*One byte too short*/ for(jj=2;jj<2+j;jj++)packet[jj]=0; UNDEFINE_FOR_PARSE ret=opus_packet_parse(packet,2+j-2,&toc,frames,size,&payload_offset); cfgs++; if(ret!=OPUS_INVALID_PACKET)test_failed(); /*One byte too short thanks to length coding*/ packet[2]=252; packet[3]=0; for(jj=4;jj<2+j;jj++)packet[jj]=0; UNDEFINE_FOR_PARSE ret=opus_packet_parse(packet,2+j+252-1,&toc,frames,size,&payload_offset); cfgs++; if(ret!=OPUS_INVALID_PACKET)test_failed(); /*Most expensive way of coding zeros*/ for(jj=2;jj<2+j;jj++)packet[jj]=0; UNDEFINE_FOR_PARSE ret=opus_packet_parse(packet,2+j-1,&toc,frames,size,&payload_offset); cfgs++; if(frame_samp*j<=5760){ if(ret!=j)test_failed(); for(jj=0;jj>2)!=i)test_failed(); } else if(ret!=OPUS_INVALID_PACKET)test_failed(); /*Quasi-CBR use of mode 3*/ for(sz=0;sz<8;sz++) { const int tsz[8]={50,201,403,700,1472,5110,20400,61298}; int pos=0; int as=(tsz[sz]+i-j-2)/j; for(jj=0;jj>2;pos+=2;} } UNDEFINE_FOR_PARSE ret=opus_packet_parse(packet,tsz[sz]+i,&toc,frames,size,&payload_offset); cfgs++; if(frame_samp*j<=5760 && as<1276 && (tsz[sz]+i-2-pos-as*(j-1))<1276){ if(ret!=j)test_failed(); for(jj=0;jj>2)!=i)test_failed(); } else if(ret!=OPUS_INVALID_PACKET)test_failed(); } } } fprintf(stdout," code 3 m=1-48 VBR (%2d cases) ............. OK.\n",cfgs); cfgs_total+=cfgs;cfgs=0; for(i=0;i<64;i++) { packet[0]=(i<<2)+3; /*Padding*/ packet[1]=128+1+64; /*Overflow the length coding*/ for(jj=2;jj<127;jj++)packet[jj]=255; UNDEFINE_FOR_PARSE ret=opus_packet_parse(packet,127,&toc,frames,size,&payload_offset); cfgs++; if(ret!=OPUS_INVALID_PACKET)test_failed(); for(sz=0;sz<4;sz++) { const int tsz[4]={0,72,512,1275}; for(jj=sz;jj<65025;jj+=11) { int pos; for(pos=0;pos>2)!=i)test_failed(); } else if (ret!=OPUS_INVALID_PACKET)test_failed(); } } } fprintf(stdout," code 3 padding (%2d cases) ............... OK.\n",cfgs); cfgs_total+=cfgs; fprintf(stdout," opus_packet_parse ............................ OK.\n"); fprintf(stdout," All packet parsing tests passed\n"); fprintf(stdout," (%d API invocations)\n",cfgs_total); return cfgs_total; } /* This is a helper macro for the encoder tests. The encoder api tests all have a pattern of set-must-fail, set-must-fail, set-must-pass, get-and-compare, set-must-pass, get-and-compare. */ #define CHECK_SETGET(setcall,getcall,badv,badv2,goodv,goodv2,sok,gok) \ i=(badv);\ if(opus_encoder_ctl(enc,setcall)==OPUS_OK)test_failed();\ i=(badv2);\ if(opus_encoder_ctl(enc,setcall)==OPUS_OK)test_failed();\ j=i=(goodv);\ if(opus_encoder_ctl(enc,setcall)!=OPUS_OK)test_failed();\ i=-12345;\ VG_UNDEF(&i,sizeof(i)); \ err=opus_encoder_ctl(enc,getcall);\ if(err!=OPUS_OK || i!=j)test_failed();\ j=i=(goodv2);\ if(opus_encoder_ctl(enc,setcall)!=OPUS_OK)test_failed();\ fprintf(stdout,sok);\ i=-12345;\ VG_UNDEF(&i,sizeof(i)); \ err=opus_encoder_ctl(enc,getcall);\ if(err!=OPUS_OK || i!=j)test_failed();\ fprintf(stdout,gok);\ cfgs+=6; opus_int32 test_enc_api(void) { opus_uint32 enc_final_range; OpusEncoder *enc; opus_int32 i,j; unsigned char packet[1276]; #ifndef DISABLE_FLOAT_API float fbuf[960*2]; #endif short sbuf[960*2]; int c,err,cfgs; cfgs=0; /*First test invalid configurations which should fail*/ fprintf(stdout,"\n Encoder basic API tests\n"); fprintf(stdout," ---------------------------------------------------\n"); for(c=0;c<4;c++) { i=opus_encoder_get_size(c); if(((c==1||c==2)&&(i<=2048||i>1<<17))||((c!=1&&c!=2)&&i!=0))test_failed(); fprintf(stdout," opus_encoder_get_size(%d)=%d ...............%s OK.\n",c,i,i>0?"":"...."); cfgs++; } /*Test with unsupported sample rates, channel counts*/ for(c=0;c<4;c++) { for(i=-7;i<=96000;i++) { int fs; if((i==8000||i==12000||i==16000||i==24000||i==48000)&&(c==1||c==2))continue; switch(i) { case(-5):fs=-8000;break; case(-6):fs=INT32_MAX;break; case(-7):fs=INT32_MIN;break; default:fs=i; } err = OPUS_OK; VG_UNDEF(&err,sizeof(err)); enc = opus_encoder_create(fs, c, OPUS_APPLICATION_VOIP, &err); if(err!=OPUS_BAD_ARG || enc!=NULL)test_failed(); cfgs++; enc = opus_encoder_create(fs, c, OPUS_APPLICATION_VOIP, 0); if(enc!=NULL)test_failed(); cfgs++; opus_encoder_destroy(enc); enc=malloc(opus_encoder_get_size(2)); if(enc==NULL)test_failed(); err = opus_encoder_init(enc, fs, c, OPUS_APPLICATION_VOIP); if(err!=OPUS_BAD_ARG)test_failed(); cfgs++; free(enc); } } enc = opus_encoder_create(48000, 2, OPUS_AUTO, NULL); if(enc!=NULL)test_failed(); cfgs++; VG_UNDEF(&err,sizeof(err)); enc = opus_encoder_create(48000, 2, OPUS_AUTO, &err); if(err!=OPUS_BAD_ARG || enc!=NULL)test_failed(); cfgs++; VG_UNDEF(&err,sizeof(err)); enc = opus_encoder_create(48000, 2, OPUS_APPLICATION_VOIP, NULL); if(enc==NULL)test_failed(); opus_encoder_destroy(enc); cfgs++; VG_UNDEF(&err,sizeof(err)); enc = opus_encoder_create(48000, 2, OPUS_APPLICATION_RESTRICTED_LOWDELAY, &err); if(err!=OPUS_OK || enc==NULL)test_failed(); cfgs++; err=opus_encoder_ctl(enc,OPUS_GET_LOOKAHEAD(&i)); if(err!=OPUS_OK || i<0 || i>32766)test_failed(); cfgs++; opus_encoder_destroy(enc); VG_UNDEF(&err,sizeof(err)); enc = opus_encoder_create(48000, 2, OPUS_APPLICATION_AUDIO, &err); if(err!=OPUS_OK || enc==NULL)test_failed(); cfgs++; err=opus_encoder_ctl(enc,OPUS_GET_LOOKAHEAD(&i)); if(err!=OPUS_OK || i<0 || i>32766)test_failed(); opus_encoder_destroy(enc); cfgs++; VG_UNDEF(&err,sizeof(err)); enc = opus_encoder_create(48000, 2, OPUS_APPLICATION_VOIP, &err); if(err!=OPUS_OK || enc==NULL)test_failed(); cfgs++; fprintf(stdout," opus_encoder_create() ........................ OK.\n"); fprintf(stdout," opus_encoder_init() .......................... OK.\n"); i=-12345; VG_UNDEF(&i,sizeof(i)); err=opus_encoder_ctl(enc,OPUS_GET_LOOKAHEAD(&i)); if(err!=OPUS_OK || i<0 || i>32766)test_failed(); cfgs++; err=opus_encoder_ctl(enc,OPUS_GET_LOOKAHEAD(null_int_ptr)); if(err!=OPUS_BAD_ARG)test_failed(); cfgs++; fprintf(stdout," OPUS_GET_LOOKAHEAD ........................... OK.\n"); err=opus_encoder_ctl(enc,OPUS_GET_SAMPLE_RATE(&i)); if(err!=OPUS_OK || i!=48000)test_failed(); cfgs++; err=opus_encoder_ctl(enc,OPUS_GET_SAMPLE_RATE(null_int_ptr)); if(err!=OPUS_BAD_ARG)test_failed(); cfgs++; fprintf(stdout," OPUS_GET_SAMPLE_RATE ......................... OK.\n"); if(opus_encoder_ctl(enc,OPUS_UNIMPLEMENTED)!=OPUS_UNIMPLEMENTED)test_failed(); fprintf(stdout," OPUS_UNIMPLEMENTED ........................... OK.\n"); cfgs++; err=opus_encoder_ctl(enc,OPUS_GET_APPLICATION(null_int_ptr)); if(err!=OPUS_BAD_ARG)test_failed(); cfgs++; CHECK_SETGET(OPUS_SET_APPLICATION(i),OPUS_GET_APPLICATION(&i),-1,OPUS_AUTO, OPUS_APPLICATION_AUDIO,OPUS_APPLICATION_RESTRICTED_LOWDELAY, " OPUS_SET_APPLICATION ......................... OK.\n", " OPUS_GET_APPLICATION ......................... OK.\n") err=opus_encoder_ctl(enc,OPUS_GET_BITRATE(null_int_ptr)); if(err!=OPUS_BAD_ARG)test_failed(); cfgs++; if(opus_encoder_ctl(enc,OPUS_SET_BITRATE(1073741832))!=OPUS_OK)test_failed(); cfgs++; VG_UNDEF(&i,sizeof(i)); if(opus_encoder_ctl(enc,OPUS_GET_BITRATE(&i))!=OPUS_OK)test_failed(); if(i>700000||i<256000)test_failed(); cfgs++; CHECK_SETGET(OPUS_SET_BITRATE(i),OPUS_GET_BITRATE(&i),-12345,0, 500,256000, " OPUS_SET_BITRATE ............................. OK.\n", " OPUS_GET_BITRATE ............................. OK.\n") err=opus_encoder_ctl(enc,OPUS_GET_FORCE_CHANNELS(null_int_ptr)); if(err!=OPUS_BAD_ARG)test_failed(); cfgs++; CHECK_SETGET(OPUS_SET_FORCE_CHANNELS(i),OPUS_GET_FORCE_CHANNELS(&i),-1,3, 1,OPUS_AUTO, " OPUS_SET_FORCE_CHANNELS ...................... OK.\n", " OPUS_GET_FORCE_CHANNELS ...................... OK.\n") i=-2; if(opus_encoder_ctl(enc,OPUS_SET_BANDWIDTH(i))==OPUS_OK)test_failed(); cfgs++; i=OPUS_BANDWIDTH_FULLBAND+1; if(opus_encoder_ctl(enc,OPUS_SET_BANDWIDTH(i))==OPUS_OK)test_failed(); cfgs++; i=OPUS_BANDWIDTH_NARROWBAND; if(opus_encoder_ctl(enc,OPUS_SET_BANDWIDTH(i))!=OPUS_OK)test_failed(); cfgs++; i=OPUS_BANDWIDTH_FULLBAND; if(opus_encoder_ctl(enc,OPUS_SET_BANDWIDTH(i))!=OPUS_OK)test_failed(); cfgs++; i=OPUS_BANDWIDTH_WIDEBAND; if(opus_encoder_ctl(enc,OPUS_SET_BANDWIDTH(i))!=OPUS_OK)test_failed(); cfgs++; i=OPUS_BANDWIDTH_MEDIUMBAND; if(opus_encoder_ctl(enc,OPUS_SET_BANDWIDTH(i))!=OPUS_OK)test_failed(); cfgs++; fprintf(stdout," OPUS_SET_BANDWIDTH ........................... OK.\n"); /*We don't test if the bandwidth has actually changed. because the change may be delayed until the encoder is advanced.*/ i=-12345; VG_UNDEF(&i,sizeof(i)); err=opus_encoder_ctl(enc,OPUS_GET_BANDWIDTH(&i)); if(err!=OPUS_OK || (i!=OPUS_BANDWIDTH_NARROWBAND&& i!=OPUS_BANDWIDTH_MEDIUMBAND&&i!=OPUS_BANDWIDTH_WIDEBAND&& i!=OPUS_BANDWIDTH_FULLBAND&&i!=OPUS_AUTO))test_failed(); cfgs++; if(opus_encoder_ctl(enc,OPUS_SET_BANDWIDTH(OPUS_AUTO))!=OPUS_OK)test_failed(); cfgs++; err=opus_encoder_ctl(enc,OPUS_GET_BANDWIDTH(null_int_ptr)); if(err!=OPUS_BAD_ARG)test_failed(); cfgs++; fprintf(stdout," OPUS_GET_BANDWIDTH ........................... OK.\n"); i=-2; if(opus_encoder_ctl(enc,OPUS_SET_MAX_BANDWIDTH(i))==OPUS_OK)test_failed(); cfgs++; i=OPUS_BANDWIDTH_FULLBAND+1; if(opus_encoder_ctl(enc,OPUS_SET_MAX_BANDWIDTH(i))==OPUS_OK)test_failed(); cfgs++; i=OPUS_BANDWIDTH_NARROWBAND; if(opus_encoder_ctl(enc,OPUS_SET_MAX_BANDWIDTH(i))!=OPUS_OK)test_failed(); cfgs++; i=OPUS_BANDWIDTH_FULLBAND; if(opus_encoder_ctl(enc,OPUS_SET_MAX_BANDWIDTH(i))!=OPUS_OK)test_failed(); cfgs++; i=OPUS_BANDWIDTH_WIDEBAND; if(opus_encoder_ctl(enc,OPUS_SET_MAX_BANDWIDTH(i))!=OPUS_OK)test_failed(); cfgs++; i=OPUS_BANDWIDTH_MEDIUMBAND; if(opus_encoder_ctl(enc,OPUS_SET_MAX_BANDWIDTH(i))!=OPUS_OK)test_failed(); cfgs++; fprintf(stdout," OPUS_SET_MAX_BANDWIDTH ....................... OK.\n"); /*We don't test if the bandwidth has actually changed. because the change may be delayed until the encoder is advanced.*/ i=-12345; VG_UNDEF(&i,sizeof(i)); err=opus_encoder_ctl(enc,OPUS_GET_MAX_BANDWIDTH(&i)); if(err!=OPUS_OK || (i!=OPUS_BANDWIDTH_NARROWBAND&& i!=OPUS_BANDWIDTH_MEDIUMBAND&&i!=OPUS_BANDWIDTH_WIDEBAND&& i!=OPUS_BANDWIDTH_FULLBAND))test_failed(); cfgs++; err=opus_encoder_ctl(enc,OPUS_GET_MAX_BANDWIDTH(null_int_ptr)); if(err!=OPUS_BAD_ARG)test_failed(); cfgs++; fprintf(stdout," OPUS_GET_MAX_BANDWIDTH ....................... OK.\n"); err=opus_encoder_ctl(enc,OPUS_GET_DTX(null_int_ptr)); if(err!=OPUS_BAD_ARG)test_failed(); cfgs++; CHECK_SETGET(OPUS_SET_DTX(i),OPUS_GET_DTX(&i),-1,2, 1,0, " OPUS_SET_DTX ................................. OK.\n", " OPUS_GET_DTX ................................. OK.\n") err=opus_encoder_ctl(enc,OPUS_GET_COMPLEXITY(null_int_ptr)); if(err!=OPUS_BAD_ARG)test_failed(); cfgs++; CHECK_SETGET(OPUS_SET_COMPLEXITY(i),OPUS_GET_COMPLEXITY(&i),-1,11, 0,10, " OPUS_SET_COMPLEXITY .......................... OK.\n", " OPUS_GET_COMPLEXITY .......................... OK.\n") err=opus_encoder_ctl(enc,OPUS_GET_INBAND_FEC(null_int_ptr)); if(err!=OPUS_BAD_ARG)test_failed(); cfgs++; CHECK_SETGET(OPUS_SET_INBAND_FEC(i),OPUS_GET_INBAND_FEC(&i),-1,2, 1,0, " OPUS_SET_INBAND_FEC .......................... OK.\n", " OPUS_GET_INBAND_FEC .......................... OK.\n") err=opus_encoder_ctl(enc,OPUS_GET_PACKET_LOSS_PERC(null_int_ptr)); if(err!=OPUS_BAD_ARG)test_failed(); cfgs++; CHECK_SETGET(OPUS_SET_PACKET_LOSS_PERC(i),OPUS_GET_PACKET_LOSS_PERC(&i),-1,101, 100,0, " OPUS_SET_PACKET_LOSS_PERC .................... OK.\n", " OPUS_GET_PACKET_LOSS_PERC .................... OK.\n") err=opus_encoder_ctl(enc,OPUS_GET_VBR(null_int_ptr)); if(err!=OPUS_BAD_ARG)test_failed(); cfgs++; CHECK_SETGET(OPUS_SET_VBR(i),OPUS_GET_VBR(&i),-1,2, 1,0, " OPUS_SET_VBR ................................. OK.\n", " OPUS_GET_VBR ................................. OK.\n") /* err=opus_encoder_ctl(enc,OPUS_GET_VOICE_RATIO(null_int_ptr)); if(err!=OPUS_BAD_ARG)test_failed(); cfgs++; CHECK_SETGET(OPUS_SET_VOICE_RATIO(i),OPUS_GET_VOICE_RATIO(&i),-2,101, 0,50, " OPUS_SET_VOICE_RATIO ......................... OK.\n", " OPUS_GET_VOICE_RATIO ......................... OK.\n")*/ err=opus_encoder_ctl(enc,OPUS_GET_VBR_CONSTRAINT(null_int_ptr)); if(err!=OPUS_BAD_ARG)test_failed(); cfgs++; CHECK_SETGET(OPUS_SET_VBR_CONSTRAINT(i),OPUS_GET_VBR_CONSTRAINT(&i),-1,2, 1,0, " OPUS_SET_VBR_CONSTRAINT ...................... OK.\n", " OPUS_GET_VBR_CONSTRAINT ...................... OK.\n") err=opus_encoder_ctl(enc,OPUS_GET_SIGNAL(null_int_ptr)); if(err!=OPUS_BAD_ARG)test_failed(); cfgs++; CHECK_SETGET(OPUS_SET_SIGNAL(i),OPUS_GET_SIGNAL(&i),-12345,0x7FFFFFFF, OPUS_SIGNAL_MUSIC,OPUS_AUTO, " OPUS_SET_SIGNAL .............................. OK.\n", " OPUS_GET_SIGNAL .............................. OK.\n") err=opus_encoder_ctl(enc,OPUS_GET_LSB_DEPTH(null_int_ptr)); if(err!=OPUS_BAD_ARG)test_failed(); cfgs++; CHECK_SETGET(OPUS_SET_LSB_DEPTH(i),OPUS_GET_LSB_DEPTH(&i),7,25,16,24, " OPUS_SET_LSB_DEPTH ........................... OK.\n", " OPUS_GET_LSB_DEPTH ........................... OK.\n") err=opus_encoder_ctl(enc,OPUS_GET_PREDICTION_DISABLED(&i)); if(i!=0)test_failed(); cfgs++; err=opus_encoder_ctl(enc,OPUS_GET_PREDICTION_DISABLED(null_int_ptr)); if(err!=OPUS_BAD_ARG)test_failed(); cfgs++; CHECK_SETGET(OPUS_SET_PREDICTION_DISABLED(i),OPUS_GET_PREDICTION_DISABLED(&i),-1,2,1,0, " OPUS_SET_PREDICTION_DISABLED ................. OK.\n", " OPUS_GET_PREDICTION_DISABLED ................. OK.\n") err=opus_encoder_ctl(enc,OPUS_GET_EXPERT_FRAME_DURATION(null_int_ptr)); if(err!=OPUS_BAD_ARG)test_failed(); cfgs++; err=opus_encoder_ctl(enc,OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_2_5_MS)); if(err!=OPUS_OK)test_failed(); cfgs++; err=opus_encoder_ctl(enc,OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_5_MS)); if(err!=OPUS_OK)test_failed(); cfgs++; err=opus_encoder_ctl(enc,OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_10_MS)); if(err!=OPUS_OK)test_failed(); cfgs++; err=opus_encoder_ctl(enc,OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_20_MS)); if(err!=OPUS_OK)test_failed(); cfgs++; err=opus_encoder_ctl(enc,OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_40_MS)); if(err!=OPUS_OK)test_failed(); cfgs++; err=opus_encoder_ctl(enc,OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_60_MS)); if(err!=OPUS_OK)test_failed(); cfgs++; err=opus_encoder_ctl(enc,OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_80_MS)); if(err!=OPUS_OK)test_failed(); cfgs++; err=opus_encoder_ctl(enc,OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_100_MS)); if(err!=OPUS_OK)test_failed(); cfgs++; err=opus_encoder_ctl(enc,OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_120_MS)); if(err!=OPUS_OK)test_failed(); cfgs++; CHECK_SETGET(OPUS_SET_EXPERT_FRAME_DURATION(i),OPUS_GET_EXPERT_FRAME_DURATION(&i),0,-1, OPUS_FRAMESIZE_60_MS,OPUS_FRAMESIZE_ARG, " OPUS_SET_EXPERT_FRAME_DURATION ............... OK.\n", " OPUS_GET_EXPERT_FRAME_DURATION ............... OK.\n") /*OPUS_SET_FORCE_MODE is not tested here because it's not a public API, however the encoder tests use it*/ err=opus_encoder_ctl(enc,OPUS_GET_FINAL_RANGE(null_uint_ptr)); if(err!=OPUS_BAD_ARG)test_failed(); cfgs++; if(opus_encoder_ctl(enc,OPUS_GET_FINAL_RANGE(&enc_final_range))!=OPUS_OK)test_failed(); cfgs++; fprintf(stdout," OPUS_GET_FINAL_RANGE ......................... OK.\n"); /*Reset the encoder*/ if(opus_encoder_ctl(enc, OPUS_RESET_STATE)!=OPUS_OK)test_failed(); cfgs++; fprintf(stdout," OPUS_RESET_STATE ............................. OK.\n"); memset(sbuf,0,sizeof(short)*2*960); VG_UNDEF(packet,sizeof(packet)); i=opus_encode(enc, sbuf, 960, packet, sizeof(packet)); if(i<1 || (i>(opus_int32)sizeof(packet)))test_failed(); VG_CHECK(packet,i); cfgs++; fprintf(stdout," opus_encode() ................................ OK.\n"); #ifndef DISABLE_FLOAT_API memset(fbuf,0,sizeof(float)*2*960); VG_UNDEF(packet,sizeof(packet)); i=opus_encode_float(enc, fbuf, 960, packet, sizeof(packet)); if(i<1 || (i>(opus_int32)sizeof(packet)))test_failed(); VG_CHECK(packet,i); cfgs++; fprintf(stdout," opus_encode_float() .......................... OK.\n"); #endif #if 0 /*These tests are disabled because the library crashes with null states*/ if(opus_encoder_ctl(0,OPUS_RESET_STATE) !=OPUS_INVALID_STATE)test_failed(); if(opus_encoder_init(0,48000,1,OPUS_APPLICATION_VOIP) !=OPUS_INVALID_STATE)test_failed(); if(opus_encode(0,sbuf,960,packet,sizeof(packet)) !=OPUS_INVALID_STATE)test_failed(); if(opus_encode_float(0,fbuf,960,packet,sizeof(packet))!=OPUS_INVALID_STATE)test_failed(); #endif opus_encoder_destroy(enc); cfgs++; fprintf(stdout," All encoder interface tests passed\n"); fprintf(stdout," (%d API invocations)\n",cfgs); return cfgs; } #define max_out (1276*48+48*2+2) int test_repacketizer_api(void) { int ret,cfgs,i,j,k; OpusRepacketizer *rp; unsigned char *packet; unsigned char *po; cfgs=0; fprintf(stdout,"\n Repacketizer tests\n"); fprintf(stdout," ---------------------------------------------------\n"); packet=malloc(max_out); if(packet==NULL)test_failed(); memset(packet,0,max_out); po=malloc(max_out+256); if(po==NULL)test_failed(); i=opus_repacketizer_get_size(); if(i<=0)test_failed(); cfgs++; fprintf(stdout," opus_repacketizer_get_size()=%d ............. OK.\n",i); rp=malloc(i); rp=opus_repacketizer_init(rp); if(rp==NULL)test_failed(); cfgs++; free(rp); fprintf(stdout," opus_repacketizer_init ....................... OK.\n"); rp=opus_repacketizer_create(); if(rp==NULL)test_failed(); cfgs++; fprintf(stdout," opus_repacketizer_create ..................... OK.\n"); if(opus_repacketizer_get_nb_frames(rp)!=0)test_failed(); cfgs++; fprintf(stdout," opus_repacketizer_get_nb_frames .............. OK.\n"); /*Length overflows*/ VG_UNDEF(packet,4); if(opus_repacketizer_cat(rp,packet,0)!=OPUS_INVALID_PACKET)test_failed(); /* Zero len */ cfgs++; packet[0]=1; if(opus_repacketizer_cat(rp,packet,2)!=OPUS_INVALID_PACKET)test_failed(); /* Odd payload code 1 */ cfgs++; packet[0]=2; if(opus_repacketizer_cat(rp,packet,1)!=OPUS_INVALID_PACKET)test_failed(); /* Code 2 overflow one */ cfgs++; packet[0]=3; if(opus_repacketizer_cat(rp,packet,1)!=OPUS_INVALID_PACKET)test_failed(); /* Code 3 no count */ cfgs++; packet[0]=2; packet[1]=255; if(opus_repacketizer_cat(rp,packet,2)!=OPUS_INVALID_PACKET)test_failed(); /* Code 2 overflow two */ cfgs++; packet[0]=2; packet[1]=250; if(opus_repacketizer_cat(rp,packet,251)!=OPUS_INVALID_PACKET)test_failed(); /* Code 2 overflow three */ cfgs++; packet[0]=3; packet[1]=0; if(opus_repacketizer_cat(rp,packet,2)!=OPUS_INVALID_PACKET)test_failed(); /* Code 3 m=0 */ cfgs++; packet[1]=49; if(opus_repacketizer_cat(rp,packet,100)!=OPUS_INVALID_PACKET)test_failed(); /* Code 3 m=49 */ cfgs++; packet[0]=0; if(opus_repacketizer_cat(rp,packet,3)!=OPUS_OK)test_failed(); cfgs++; packet[0]=1<<2; if(opus_repacketizer_cat(rp,packet,3)!=OPUS_INVALID_PACKET)test_failed(); /* Change in TOC */ cfgs++; /* Code 0,1,3 CBR -> Code 0,1,3 CBR */ opus_repacketizer_init(rp); for(j=0;j<32;j++) { /* TOC types, test half with stereo */ int maxi; packet[0]=((j<<1)+(j&1))<<2; maxi=960/opus_packet_get_samples_per_frame(packet,8000); for(i=1;i<=maxi;i++) { /* Number of CBR frames in the input packets */ int maxp; packet[0]=((j<<1)+(j&1))<<2; if(i>1)packet[0]+=i==2?1:3; packet[1]=i>2?i:0; maxp=960/(i*opus_packet_get_samples_per_frame(packet,8000)); for(k=0;k<=(1275+75);k+=3) { /*Payload size*/ opus_int32 cnt,rcnt; if(k%i!=0)continue; /* Only testing CBR here, payload must be a multiple of the count */ for(cnt=0;cnt0) { ret=opus_repacketizer_cat(rp,packet,k+(i>2?2:1)); if((cnt<=maxp&&k<=(1275*i))?ret!=OPUS_OK:ret!=OPUS_INVALID_PACKET)test_failed(); cfgs++; } rcnt=k<=(1275*i)?(cnt0) { int len; len=k*rcnt+((rcnt*i)>2?2:1); if(ret!=len)test_failed(); if((rcnt*i)<2&&(po[0]&3)!=0)test_failed(); /* Code 0 */ if((rcnt*i)==2&&(po[0]&3)!=1)test_failed(); /* Code 1 */ if((rcnt*i)>2&&(((po[0]&3)!=3)||(po[1]!=rcnt*i)))test_failed(); /* Code 3 CBR */ cfgs++; if(opus_repacketizer_out(rp,po,len)!=len)test_failed(); cfgs++; if(opus_packet_unpad(po,len)!=len)test_failed(); cfgs++; if(opus_packet_pad(po,len,len+1)!=OPUS_OK)test_failed(); cfgs++; if(opus_packet_pad(po,len+1,len+256)!=OPUS_OK)test_failed(); cfgs++; if(opus_packet_unpad(po,len+256)!=len)test_failed(); cfgs++; if(opus_multistream_packet_unpad(po,len,1)!=len)test_failed(); cfgs++; if(opus_multistream_packet_pad(po,len,len+1,1)!=OPUS_OK)test_failed(); cfgs++; if(opus_multistream_packet_pad(po,len+1,len+256,1)!=OPUS_OK)test_failed(); cfgs++; if(opus_multistream_packet_unpad(po,len+256,1)!=len)test_failed(); cfgs++; if(opus_repacketizer_out(rp,po,len-1)!=OPUS_BUFFER_TOO_SMALL)test_failed(); cfgs++; if(len>1) { if(opus_repacketizer_out(rp,po,1)!=OPUS_BUFFER_TOO_SMALL)test_failed(); cfgs++; } if(opus_repacketizer_out(rp,po,0)!=OPUS_BUFFER_TOO_SMALL)test_failed(); cfgs++; } else if (ret!=OPUS_BAD_ARG)test_failed(); /* M must not be 0 */ } opus_repacketizer_init(rp); } } } /*Change in input count code, CBR out*/ opus_repacketizer_init(rp); packet[0]=0; if(opus_repacketizer_cat(rp,packet,5)!=OPUS_OK)test_failed(); cfgs++; packet[0]+=1; if(opus_repacketizer_cat(rp,packet,9)!=OPUS_OK)test_failed(); cfgs++; i=opus_repacketizer_out(rp,po,max_out); if((i!=(4+8+2))||((po[0]&3)!=3)||((po[1]&63)!=3)||((po[1]>>7)!=0))test_failed(); cfgs++; i=opus_repacketizer_out_range(rp,0,1,po,max_out); if(i!=5||(po[0]&3)!=0)test_failed(); cfgs++; i=opus_repacketizer_out_range(rp,1,2,po,max_out); if(i!=5||(po[0]&3)!=0)test_failed(); cfgs++; /*Change in input count code, VBR out*/ opus_repacketizer_init(rp); packet[0]=1; if(opus_repacketizer_cat(rp,packet,9)!=OPUS_OK)test_failed(); cfgs++; packet[0]=0; if(opus_repacketizer_cat(rp,packet,3)!=OPUS_OK)test_failed(); cfgs++; i=opus_repacketizer_out(rp,po,max_out); if((i!=(2+8+2+2))||((po[0]&3)!=3)||((po[1]&63)!=3)||((po[1]>>7)!=1))test_failed(); cfgs++; /*VBR in, VBR out*/ opus_repacketizer_init(rp); packet[0]=2; packet[1]=4; if(opus_repacketizer_cat(rp,packet,8)!=OPUS_OK)test_failed(); cfgs++; if(opus_repacketizer_cat(rp,packet,8)!=OPUS_OK)test_failed(); cfgs++; i=opus_repacketizer_out(rp,po,max_out); if((i!=(2+1+1+1+4+2+4+2))||((po[0]&3)!=3)||((po[1]&63)!=4)||((po[1]>>7)!=1))test_failed(); cfgs++; /*VBR in, CBR out*/ opus_repacketizer_init(rp); packet[0]=2; packet[1]=4; if(opus_repacketizer_cat(rp,packet,10)!=OPUS_OK)test_failed(); cfgs++; if(opus_repacketizer_cat(rp,packet,10)!=OPUS_OK)test_failed(); cfgs++; i=opus_repacketizer_out(rp,po,max_out); if((i!=(2+4+4+4+4))||((po[0]&3)!=3)||((po[1]&63)!=4)||((po[1]>>7)!=0))test_failed(); cfgs++; /*Count 0 in, VBR out*/ for(j=0;j<32;j++) { /* TOC types, test half with stereo */ int maxi,sum,rcnt; packet[0]=((j<<1)+(j&1))<<2; maxi=960/opus_packet_get_samples_per_frame(packet,8000); sum=0; rcnt=0; opus_repacketizer_init(rp); for(i=1;i<=maxi+2;i++) { int len; ret=opus_repacketizer_cat(rp,packet,i); if(rcnt2&&(po[1]&63)!=rcnt)test_failed(); if(rcnt==2&&(po[0]&3)!=2)test_failed(); if(rcnt==1&&(po[0]&3)!=0)test_failed(); cfgs++; if(opus_repacketizer_out(rp,po,len)!=len)test_failed(); cfgs++; if(opus_packet_unpad(po,len)!=len)test_failed(); cfgs++; if(opus_packet_pad(po,len,len+1)!=OPUS_OK)test_failed(); cfgs++; if(opus_packet_pad(po,len+1,len+256)!=OPUS_OK)test_failed(); cfgs++; if(opus_packet_unpad(po,len+256)!=len)test_failed(); cfgs++; if(opus_multistream_packet_unpad(po,len,1)!=len)test_failed(); cfgs++; if(opus_multistream_packet_pad(po,len,len+1,1)!=OPUS_OK)test_failed(); cfgs++; if(opus_multistream_packet_pad(po,len+1,len+256,1)!=OPUS_OK)test_failed(); cfgs++; if(opus_multistream_packet_unpad(po,len+256,1)!=len)test_failed(); cfgs++; if(opus_repacketizer_out(rp,po,len-1)!=OPUS_BUFFER_TOO_SMALL)test_failed(); cfgs++; if(len>1) { if(opus_repacketizer_out(rp,po,1)!=OPUS_BUFFER_TOO_SMALL)test_failed(); cfgs++; } if(opus_repacketizer_out(rp,po,0)!=OPUS_BUFFER_TOO_SMALL)test_failed(); cfgs++; } } po[0]='O'; po[1]='p'; if(opus_packet_pad(po,4,4)!=OPUS_OK)test_failed(); cfgs++; if(opus_multistream_packet_pad(po,4,4,1)!=OPUS_OK)test_failed(); cfgs++; if(opus_packet_pad(po,4,5)!=OPUS_INVALID_PACKET)test_failed(); cfgs++; if(opus_multistream_packet_pad(po,4,5,1)!=OPUS_INVALID_PACKET)test_failed(); cfgs++; if(opus_packet_pad(po,0,5)!=OPUS_BAD_ARG)test_failed(); cfgs++; if(opus_multistream_packet_pad(po,0,5,1)!=OPUS_BAD_ARG)test_failed(); cfgs++; if(opus_packet_unpad(po,0)!=OPUS_BAD_ARG)test_failed(); cfgs++; if(opus_multistream_packet_unpad(po,0,1)!=OPUS_BAD_ARG)test_failed(); cfgs++; if(opus_packet_unpad(po,4)!=OPUS_INVALID_PACKET)test_failed(); cfgs++; if(opus_multistream_packet_unpad(po,4,1)!=OPUS_INVALID_PACKET)test_failed(); cfgs++; po[0]=0; po[1]=0; po[2]=0; if(opus_packet_pad(po,5,4)!=OPUS_BAD_ARG)test_failed(); cfgs++; if(opus_multistream_packet_pad(po,5,4,1)!=OPUS_BAD_ARG)test_failed(); cfgs++; fprintf(stdout," opus_repacketizer_cat ........................ OK.\n"); fprintf(stdout," opus_repacketizer_out ........................ OK.\n"); fprintf(stdout," opus_repacketizer_out_range .................. OK.\n"); fprintf(stdout," opus_packet_pad .............................. OK.\n"); fprintf(stdout," opus_packet_unpad ............................ OK.\n"); fprintf(stdout," opus_multistream_packet_pad .................. OK.\n"); fprintf(stdout," opus_multistream_packet_unpad ................ OK.\n"); opus_repacketizer_destroy(rp); cfgs++; free(packet); free(po); fprintf(stdout," All repacketizer tests passed\n"); fprintf(stdout," (%7d API invocations)\n",cfgs); return cfgs; } #ifdef MALLOC_FAIL /* GLIBC 2.14 declares __malloc_hook as deprecated, generating a warning * under GCC. However, this is the cleanest way to test malloc failure * handling in our codebase, and the lack of thread safety isn't an * issue here. We therefore disable the warning for this function. */ #if OPUS_GNUC_PREREQ(4,6) /* Save the current warning settings */ #pragma GCC diagnostic push #endif #pragma GCC diagnostic ignored "-Wdeprecated-declarations" typedef void *(*mhook)(size_t __size, __const void *); #endif int test_malloc_fail(void) { #ifdef MALLOC_FAIL OpusDecoder *dec; OpusEncoder *enc; OpusRepacketizer *rp; unsigned char mapping[256] = {0,1}; OpusMSDecoder *msdec; OpusMSEncoder *msenc; int rate,c,app,cfgs,err,useerr; int *ep; mhook orig_malloc; cfgs=0; #endif fprintf(stdout,"\n malloc() failure tests\n"); fprintf(stdout," ---------------------------------------------------\n"); #ifdef MALLOC_FAIL orig_malloc=__malloc_hook; __malloc_hook=malloc_hook; ep=(int *)opus_alloc(sizeof(int)); if(ep!=NULL) { if(ep)free(ep); __malloc_hook=orig_malloc; #endif fprintf(stdout," opus_decoder_create() ................... SKIPPED.\n"); fprintf(stdout," opus_encoder_create() ................... SKIPPED.\n"); fprintf(stdout," opus_repacketizer_create() .............. SKIPPED.\n"); fprintf(stdout," opus_multistream_decoder_create() ....... SKIPPED.\n"); fprintf(stdout," opus_multistream_encoder_create() ....... SKIPPED.\n"); fprintf(stdout,"(Test only supported with GLIBC and without valgrind)\n"); return 0; #ifdef MALLOC_FAIL } for(useerr=0;useerr<2;useerr++) { ep=useerr?&err:0; for(rate=0;rate<5;rate++) { for(c=1;c<3;c++) { err=1; if(useerr) { VG_UNDEF(&err,sizeof(err)); } dec=opus_decoder_create(opus_rates[rate], c, ep); if(dec!=NULL||(useerr&&err!=OPUS_ALLOC_FAIL)) { __malloc_hook=orig_malloc; test_failed(); } cfgs++; msdec=opus_multistream_decoder_create(opus_rates[rate], c, 1, c-1, mapping, ep); if(msdec!=NULL||(useerr&&err!=OPUS_ALLOC_FAIL)) { __malloc_hook=orig_malloc; test_failed(); } cfgs++; for(app=0;app<3;app++) { if(useerr) { VG_UNDEF(&err,sizeof(err)); } enc=opus_encoder_create(opus_rates[rate], c, opus_apps[app],ep); if(enc!=NULL||(useerr&&err!=OPUS_ALLOC_FAIL)) { __malloc_hook=orig_malloc; test_failed(); } cfgs++; msenc=opus_multistream_encoder_create(opus_rates[rate], c, 1, c-1, mapping, opus_apps[app],ep); if(msenc!=NULL||(useerr&&err!=OPUS_ALLOC_FAIL)) { __malloc_hook=orig_malloc; test_failed(); } cfgs++; } } } } rp=opus_repacketizer_create(); if(rp!=NULL) { __malloc_hook=orig_malloc; test_failed(); } cfgs++; __malloc_hook=orig_malloc; fprintf(stdout," opus_decoder_create() ........................ OK.\n"); fprintf(stdout," opus_encoder_create() ........................ OK.\n"); fprintf(stdout," opus_repacketizer_create() ................... OK.\n"); fprintf(stdout," opus_multistream_decoder_create() ............ OK.\n"); fprintf(stdout," opus_multistream_encoder_create() ............ OK.\n"); fprintf(stdout," All malloc failure tests passed\n"); fprintf(stdout," (%2d API invocations)\n",cfgs); return cfgs; #endif } #ifdef MALLOC_FAIL #if __GNUC_PREREQ(4,6) #pragma GCC diagnostic pop /* restore -Wdeprecated-declarations */ #endif #endif int main(int _argc, char **_argv) { opus_int32 total; const char * oversion; if(_argc>1) { fprintf(stderr,"Usage: %s\n",_argv[0]); return 1; } iseed=0; oversion=opus_get_version_string(); if(!oversion)test_failed(); fprintf(stderr,"Testing the %s API deterministically\n", oversion); if(opus_strerror(-32768)==NULL)test_failed(); if(opus_strerror(32767)==NULL)test_failed(); if(strlen(opus_strerror(0))<1)test_failed(); total=4; total+=test_dec_api(); total+=test_msdec_api(); total+=test_parse(); total+=test_enc_api(); total+=test_repacketizer_api(); total+=test_malloc_fail(); fprintf(stderr,"\nAll API tests passed.\nThe libopus API was invoked %d times.\n",total); return 0; } jamulus-3.9.1+dfsg/libs/opus/tests/test_opus_common.h0000644000175000017500000000563214340334543022011 0ustar vimervimer/* Copyright (c) 2011 Xiph.Org Foundation Written by Gregory Maxwell */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ static OPUS_INLINE void deb2_impl(unsigned char *_t,unsigned char **_p,int _k,int _x,int _y) { int i; if(_x>2){ if(_y<3)for(i=0;i<_y;i++)*(--*_p)=_t[i+1]; }else{ _t[_x]=_t[_x-_y]; deb2_impl(_t,_p,_k,_x+1,_y); for(i=_t[_x-_y]+1;i<_k;i++){ _t[_x]=i; deb2_impl(_t,_p,_k,_x+1,_x); } } } /*Generates a De Bruijn sequence (k,2) with length k^2*/ static OPUS_INLINE void debruijn2(int _k, unsigned char *_res) { unsigned char *p; unsigned char *t; t=malloc(sizeof(unsigned char)*_k*2); memset(t,0,sizeof(unsigned char)*_k*2); p=&_res[_k*_k]; deb2_impl(t,&p,_k,1,1); free(t); } /*MWC RNG of George Marsaglia*/ static opus_uint32 Rz, Rw; static OPUS_INLINE opus_uint32 fast_rand(void) { Rz=36969*(Rz&65535)+(Rz>>16); Rw=18000*(Rw&65535)+(Rw>>16); return (Rz<<16)+Rw; } static opus_uint32 iseed; #ifdef __GNUC__ __attribute__((noreturn)) #elif defined(_MSC_VER) __declspec(noreturn) #endif static OPUS_INLINE void _test_failed(const char *file, int line) { fprintf(stderr,"\n ***************************************************\n"); fprintf(stderr," *** A fatal error was detected. ***\n"); fprintf(stderr," ***************************************************\n"); fprintf(stderr,"Please report this failure and include\n"); fprintf(stderr,"'make check SEED=%u fails %s at line %d for %s'\n",iseed,file,line,opus_get_version_string()); fprintf(stderr,"and any relevant details about your system.\n\n"); abort(); } #define test_failed() _test_failed(__FILE__, __LINE__); void regression_test(void); jamulus-3.9.1+dfsg/libs/opus/tests/test_opus_decode.c0000644000175000017500000003725114340334543021741 0ustar vimervimer/* Copyright (c) 2011-2013 Xiph.Org Foundation Written by Gregory Maxwell */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #if (!defined WIN32 && !defined _WIN32) || defined(__MINGW32__) #include #else #include #define getpid _getpid #endif #include "opus.h" #include "test_opus_common.h" #define MAX_PACKET (1500) #define MAX_FRAME_SAMP (5760) int test_decoder_code0(int no_fuzz) { static const opus_int32 fsv[5]={48000,24000,16000,12000,8000}; int err,skip,plen; int out_samples,fec; int t; opus_int32 i; OpusDecoder *dec[5*2]; opus_int32 decsize; OpusDecoder *decbak; opus_uint32 dec_final_range1,dec_final_range2,dec_final_acc; unsigned char *packet; unsigned char modes[4096]; short *outbuf_int; short *outbuf; dec_final_range1=dec_final_range2=2; packet=malloc(sizeof(unsigned char)*MAX_PACKET); if(packet==NULL)test_failed(); outbuf_int=malloc(sizeof(short)*(MAX_FRAME_SAMP+16)*2); for(i=0;i<(MAX_FRAME_SAMP+16)*2;i++)outbuf_int[i]=32749; outbuf=&outbuf_int[8*2]; fprintf(stdout," Starting %d decoders...\n",5*2); for(t=0;t<5*2;t++) { int fs=fsv[t>>1]; int c=(t&1)+1; err=OPUS_INTERNAL_ERROR; dec[t] = opus_decoder_create(fs, c, &err); if(err!=OPUS_OK || dec[t]==NULL)test_failed(); fprintf(stdout," opus_decoder_create(%5d,%d) OK. Copy ",fs,c); { OpusDecoder *dec2; /*The opus state structures contain no pointers and can be freely copied*/ dec2=(OpusDecoder *)malloc(opus_decoder_get_size(c)); if(dec2==NULL)test_failed(); memcpy(dec2,dec[t],opus_decoder_get_size(c)); memset(dec[t],255,opus_decoder_get_size(c)); opus_decoder_destroy(dec[t]); printf("OK.\n"); dec[t]=dec2; } } decsize=opus_decoder_get_size(1); decbak=(OpusDecoder *)malloc(decsize); if(decbak==NULL)test_failed(); for(t=0;t<5*2;t++) { int factor=48000/fsv[t>>1]; for(fec=0;fec<2;fec++) { opus_int32 dur; /*Test PLC on a fresh decoder*/ out_samples = opus_decode(dec[t], 0, 0, outbuf, 120/factor, fec); if(out_samples!=120/factor)test_failed(); if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed(); if(dur!=120/factor)test_failed(); /*Test on a size which isn't a multiple of 2.5ms*/ out_samples = opus_decode(dec[t], 0, 0, outbuf, 120/factor+2, fec); if(out_samples!=OPUS_BAD_ARG)test_failed(); /*Test null pointer input*/ out_samples = opus_decode(dec[t], 0, -1, outbuf, 120/factor, fec); if(out_samples!=120/factor)test_failed(); out_samples = opus_decode(dec[t], 0, 1, outbuf, 120/factor, fec); if(out_samples!=120/factor)test_failed(); out_samples = opus_decode(dec[t], 0, 10, outbuf, 120/factor, fec); if(out_samples!=120/factor)test_failed(); out_samples = opus_decode(dec[t], 0, fast_rand(), outbuf, 120/factor, fec); if(out_samples!=120/factor)test_failed(); if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed(); if(dur!=120/factor)test_failed(); /*Zero lengths*/ out_samples = opus_decode(dec[t], packet, 0, outbuf, 120/factor, fec); if(out_samples!=120/factor)test_failed(); /*Zero buffer*/ outbuf[0]=32749; out_samples = opus_decode(dec[t], packet, 0, outbuf, 0, fec); if(out_samples>0)test_failed(); #if !defined(OPUS_BUILD) && (OPUS_GNUC_PREREQ(4, 6) || (defined(__clang_major__) && __clang_major__ >= 3)) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wnonnull" #endif out_samples = opus_decode(dec[t], packet, 0, 0, 0, fec); #if !defined(OPUS_BUILD) && (OPUS_GNUC_PREREQ(4, 6) || (defined(__clang_major__) && __clang_major__ >= 3)) #pragma GCC diagnostic pop #endif if(out_samples>0)test_failed(); if(outbuf[0]!=32749)test_failed(); /*Invalid lengths*/ out_samples = opus_decode(dec[t], packet, -1, outbuf, MAX_FRAME_SAMP, fec); if(out_samples>=0)test_failed(); out_samples = opus_decode(dec[t], packet, INT_MIN, outbuf, MAX_FRAME_SAMP, fec); if(out_samples>=0)test_failed(); out_samples = opus_decode(dec[t], packet, -1, outbuf, -1, fec); if(out_samples>=0)test_failed(); /*Crazy FEC values*/ out_samples = opus_decode(dec[t], packet, 1, outbuf, MAX_FRAME_SAMP, fec?-1:2); if(out_samples>=0)test_failed(); /*Reset the decoder*/ if(opus_decoder_ctl(dec[t], OPUS_RESET_STATE)!=OPUS_OK)test_failed(); } } fprintf(stdout," dec[all] initial frame PLC OK.\n"); /*Count code 0 tests*/ for(i=0;i<64;i++) { opus_int32 dur; int j,expected[5*2]; packet[0]=i<<2; packet[1]=255; packet[2]=255; err=opus_packet_get_nb_channels(packet); if(err!=(i&1)+1)test_failed(); for(t=0;t<5*2;t++){ expected[t]=opus_decoder_get_nb_samples(dec[t],packet,1); if(expected[t]>2880)test_failed(); } for(j=0;j<256;j++) { packet[1]=j; for(t=0;t<5*2;t++) { out_samples = opus_decode(dec[t], packet, 3, outbuf, MAX_FRAME_SAMP, 0); if(out_samples!=expected[t])test_failed(); if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed(); if(dur!=out_samples)test_failed(); opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1)); if(t==0)dec_final_range2=dec_final_range1; else if(dec_final_range1!=dec_final_range2)test_failed(); } } for(t=0;t<5*2;t++){ int factor=48000/fsv[t>>1]; /* The PLC is run for 6 frames in order to get better PLC coverage. */ for(j=0;j<6;j++) { out_samples = opus_decode(dec[t], 0, 0, outbuf, expected[t], 0); if(out_samples!=expected[t])test_failed(); if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed(); if(dur!=out_samples)test_failed(); } /* Run the PLC once at 2.5ms, as a simulation of someone trying to do small drift corrections. */ if(expected[t]!=120/factor) { out_samples = opus_decode(dec[t], 0, 0, outbuf, 120/factor, 0); if(out_samples!=120/factor)test_failed(); if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed(); if(dur!=out_samples)test_failed(); } out_samples = opus_decode(dec[t], packet, 2, outbuf, expected[t]-1, 0); if(out_samples>0)test_failed(); } } fprintf(stdout," dec[all] all 2-byte prefix for length 3 and PLC, all modes (64) OK.\n"); if(no_fuzz) { fprintf(stdout," Skipping many tests which fuzz the decoder as requested.\n"); free(decbak); for(t=0;t<5*2;t++)opus_decoder_destroy(dec[t]); printf(" Decoders stopped.\n"); err=0; for(i=0;i<8*2;i++)err|=outbuf_int[i]!=32749; for(i=MAX_FRAME_SAMP*2;i<(MAX_FRAME_SAMP+8)*2;i++)err|=outbuf[i]!=32749; if(err)test_failed(); free(outbuf_int); free(packet); return 0; } { /*We only test a subset of the modes here simply because the longer durations end up taking a long time.*/ static const int cmodes[4]={16,20,24,28}; static const opus_uint32 cres[4]={116290185,2172123586u,2172123586u,2172123586u}; static const opus_uint32 lres[3]={3285687739u,1481572662,694350475}; static const int lmodes[3]={0,4,8}; int mode=fast_rand()%4; packet[0]=cmodes[mode]<<3; dec_final_acc=0; t=fast_rand()%10; for(i=0;i<65536;i++) { int factor=48000/fsv[t>>1]; packet[1]=i>>8; packet[2]=i&255; packet[3]=255; out_samples = opus_decode(dec[t], packet, 4, outbuf, MAX_FRAME_SAMP, 0); if(out_samples!=120/factor)test_failed(); opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1)); dec_final_acc+=dec_final_range1; } if(dec_final_acc!=cres[mode])test_failed(); fprintf(stdout," dec[%3d] all 3-byte prefix for length 4, mode %2d OK.\n",t,cmodes[mode]); mode=fast_rand()%3; packet[0]=lmodes[mode]<<3; dec_final_acc=0; t=fast_rand()%10; for(i=0;i<65536;i++) { int factor=48000/fsv[t>>1]; packet[1]=i>>8; packet[2]=i&255; packet[3]=255; out_samples = opus_decode(dec[t], packet, 4, outbuf, MAX_FRAME_SAMP, 0); if(out_samples!=480/factor)test_failed(); opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1)); dec_final_acc+=dec_final_range1; } if(dec_final_acc!=lres[mode])test_failed(); fprintf(stdout," dec[%3d] all 3-byte prefix for length 4, mode %2d OK.\n",t,lmodes[mode]); } skip=fast_rand()%7; for(i=0;i<64;i++) { int j,expected[5*2]; packet[0]=i<<2; for(t=0;t<5*2;t++)expected[t]=opus_decoder_get_nb_samples(dec[t],packet,1); for(j=2+skip;j<1275;j+=4) { int jj; for(jj=0;jj1.f)test_failed(); if(x[j]<-1.f)test_failed(); } } for(i=1;i<9;i++) { for (j=0;j<1024;j++) { x[j]=(j&255)*(1/32.f)-4.f; } opus_pcm_soft_clip(x,1024/i,i,s); for (j=0;j<(1024/i)*i;j++) { if(x[j]>1.f)test_failed(); if(x[j]<-1.f)test_failed(); } } opus_pcm_soft_clip(x,0,1,s); opus_pcm_soft_clip(x,1,0,s); opus_pcm_soft_clip(x,1,1,0); opus_pcm_soft_clip(x,1,-1,s); opus_pcm_soft_clip(x,-1,1,s); opus_pcm_soft_clip(0,1,1,s); printf("OK.\n"); } #endif int main(int _argc, char **_argv) { const char * oversion; const char * env_seed; int env_used; if(_argc>2) { fprintf(stderr,"Usage: %s []\n",_argv[0]); return 1; } env_used=0; env_seed=getenv("SEED"); if(_argc>1)iseed=atoi(_argv[1]); else if(env_seed) { iseed=atoi(env_seed); env_used=1; } else iseed=(opus_uint32)time(NULL)^(((opus_uint32)getpid()&65535)<<16); Rw=Rz=iseed; oversion=opus_get_version_string(); if(!oversion)test_failed(); fprintf(stderr,"Testing %s decoder. Random seed: %u (%.4X)\n", oversion, iseed, fast_rand() % 65535); if(env_used)fprintf(stderr," Random seed set from the environment (SEED=%s).\n", env_seed); /*Setting TEST_OPUS_NOFUZZ tells the tool not to send garbage data into the decoders. This is helpful because garbage data may cause the decoders to clip, which angers CLANG IOC.*/ test_decoder_code0(getenv("TEST_OPUS_NOFUZZ")!=NULL); #ifndef DISABLE_FLOAT_API test_soft_clip(); #endif return 0; } jamulus-3.9.1+dfsg/libs/opus/silk/0000755000175000017500000000000014340334543016035 5ustar vimervimerjamulus-3.9.1+dfsg/libs/opus/silk/tables_pulses_per_block.c0000644000175000017500000002623714340334543023100 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "tables.h" const opus_uint8 silk_max_pulses_table[ 4 ] = { 8, 10, 12, 16 }; const opus_uint8 silk_pulses_per_block_iCDF[ 10 ][ 18 ] = { { 125, 51, 26, 18, 15, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }, { 198, 105, 45, 22, 15, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }, { 213, 162, 116, 83, 59, 43, 32, 24, 18, 15, 12, 9, 7, 6, 5, 3, 2, 0 }, { 239, 187, 116, 59, 28, 16, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }, { 250, 229, 188, 135, 86, 51, 30, 19, 13, 10, 8, 6, 5, 4, 3, 2, 1, 0 }, { 249, 235, 213, 185, 156, 128, 103, 83, 66, 53, 42, 33, 26, 21, 17, 13, 10, 0 }, { 254, 249, 235, 206, 164, 118, 77, 46, 27, 16, 10, 7, 5, 4, 3, 2, 1, 0 }, { 255, 253, 249, 239, 220, 191, 156, 119, 85, 57, 37, 23, 15, 10, 6, 4, 2, 0 }, { 255, 253, 251, 246, 237, 223, 203, 179, 152, 124, 98, 75, 55, 40, 29, 21, 15, 0 }, { 255, 254, 253, 247, 220, 162, 106, 67, 42, 28, 18, 12, 9, 6, 4, 3, 2, 0 } }; const opus_uint8 silk_pulses_per_block_BITS_Q5[ 9 ][ 18 ] = { { 31, 57, 107, 160, 205, 205, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 69, 47, 67, 111, 166, 205, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 82, 74, 79, 95, 109, 128, 145, 160, 173, 205, 205, 205, 224, 255, 255, 224, 255, 224 }, { 125, 74, 59, 69, 97, 141, 182, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, { 173, 115, 85, 73, 76, 92, 115, 145, 173, 205, 224, 224, 255, 255, 255, 255, 255, 255 }, { 166, 134, 113, 102, 101, 102, 107, 118, 125, 138, 145, 155, 166, 182, 192, 192, 205, 150 }, { 224, 182, 134, 101, 83, 79, 85, 97, 120, 145, 173, 205, 224, 255, 255, 255, 255, 255 }, { 255, 224, 192, 150, 120, 101, 92, 89, 93, 102, 118, 134, 160, 182, 192, 224, 224, 224 }, { 255, 224, 224, 182, 155, 134, 118, 109, 104, 102, 106, 111, 118, 131, 145, 160, 173, 131 } }; const opus_uint8 silk_rate_levels_iCDF[ 2 ][ 9 ] = { { 241, 190, 178, 132, 87, 74, 41, 14, 0 }, { 223, 193, 157, 140, 106, 57, 39, 18, 0 } }; const opus_uint8 silk_rate_levels_BITS_Q5[ 2 ][ 9 ] = { { 131, 74, 141, 79, 80, 138, 95, 104, 134 }, { 95, 99, 91, 125, 93, 76, 123, 115, 123 } }; const opus_uint8 silk_shell_code_table0[ 152 ] = { 128, 0, 214, 42, 0, 235, 128, 21, 0, 244, 184, 72, 11, 0, 248, 214, 128, 42, 7, 0, 248, 225, 170, 80, 25, 5, 0, 251, 236, 198, 126, 54, 18, 3, 0, 250, 238, 211, 159, 82, 35, 15, 5, 0, 250, 231, 203, 168, 128, 88, 53, 25, 6, 0, 252, 238, 216, 185, 148, 108, 71, 40, 18, 4, 0, 253, 243, 225, 199, 166, 128, 90, 57, 31, 13, 3, 0, 254, 246, 233, 212, 183, 147, 109, 73, 44, 23, 10, 2, 0, 255, 250, 240, 223, 198, 166, 128, 90, 58, 33, 16, 6, 1, 0, 255, 251, 244, 231, 210, 181, 146, 110, 75, 46, 25, 12, 5, 1, 0, 255, 253, 248, 238, 221, 196, 164, 128, 92, 60, 35, 18, 8, 3, 1, 0, 255, 253, 249, 242, 229, 208, 180, 146, 110, 76, 48, 27, 14, 7, 3, 1, 0 }; const opus_uint8 silk_shell_code_table1[ 152 ] = { 129, 0, 207, 50, 0, 236, 129, 20, 0, 245, 185, 72, 10, 0, 249, 213, 129, 42, 6, 0, 250, 226, 169, 87, 27, 4, 0, 251, 233, 194, 130, 62, 20, 4, 0, 250, 236, 207, 160, 99, 47, 17, 3, 0, 255, 240, 217, 182, 131, 81, 41, 11, 1, 0, 255, 254, 233, 201, 159, 107, 61, 20, 2, 1, 0, 255, 249, 233, 206, 170, 128, 86, 50, 23, 7, 1, 0, 255, 250, 238, 217, 186, 148, 108, 70, 39, 18, 6, 1, 0, 255, 252, 243, 226, 200, 166, 128, 90, 56, 30, 13, 4, 1, 0, 255, 252, 245, 231, 209, 180, 146, 110, 76, 47, 25, 11, 4, 1, 0, 255, 253, 248, 237, 219, 194, 163, 128, 93, 62, 37, 19, 8, 3, 1, 0, 255, 254, 250, 241, 226, 205, 177, 145, 111, 79, 51, 30, 15, 6, 2, 1, 0 }; const opus_uint8 silk_shell_code_table2[ 152 ] = { 129, 0, 203, 54, 0, 234, 129, 23, 0, 245, 184, 73, 10, 0, 250, 215, 129, 41, 5, 0, 252, 232, 173, 86, 24, 3, 0, 253, 240, 200, 129, 56, 15, 2, 0, 253, 244, 217, 164, 94, 38, 10, 1, 0, 253, 245, 226, 189, 132, 71, 27, 7, 1, 0, 253, 246, 231, 203, 159, 105, 56, 23, 6, 1, 0, 255, 248, 235, 213, 179, 133, 85, 47, 19, 5, 1, 0, 255, 254, 243, 221, 194, 159, 117, 70, 37, 12, 2, 1, 0, 255, 254, 248, 234, 208, 171, 128, 85, 48, 22, 8, 2, 1, 0, 255, 254, 250, 240, 220, 189, 149, 107, 67, 36, 16, 6, 2, 1, 0, 255, 254, 251, 243, 227, 201, 166, 128, 90, 55, 29, 13, 5, 2, 1, 0, 255, 254, 252, 246, 234, 213, 183, 147, 109, 73, 43, 22, 10, 4, 2, 1, 0 }; const opus_uint8 silk_shell_code_table3[ 152 ] = { 130, 0, 200, 58, 0, 231, 130, 26, 0, 244, 184, 76, 12, 0, 249, 214, 130, 43, 6, 0, 252, 232, 173, 87, 24, 3, 0, 253, 241, 203, 131, 56, 14, 2, 0, 254, 246, 221, 167, 94, 35, 8, 1, 0, 254, 249, 232, 193, 130, 65, 23, 5, 1, 0, 255, 251, 239, 211, 162, 99, 45, 15, 4, 1, 0, 255, 251, 243, 223, 186, 131, 74, 33, 11, 3, 1, 0, 255, 252, 245, 230, 202, 158, 105, 57, 24, 8, 2, 1, 0, 255, 253, 247, 235, 214, 179, 132, 84, 44, 19, 7, 2, 1, 0, 255, 254, 250, 240, 223, 196, 159, 112, 69, 36, 15, 6, 2, 1, 0, 255, 254, 253, 245, 231, 209, 176, 136, 93, 55, 27, 11, 3, 2, 1, 0, 255, 254, 253, 252, 239, 221, 194, 158, 117, 76, 42, 18, 4, 3, 2, 1, 0 }; const opus_uint8 silk_shell_code_table_offsets[ 17 ] = { 0, 0, 2, 5, 9, 14, 20, 27, 35, 44, 54, 65, 77, 90, 104, 119, 135 }; const opus_uint8 silk_sign_iCDF[ 42 ] = { 254, 49, 67, 77, 82, 93, 99, 198, 11, 18, 24, 31, 36, 45, 255, 46, 66, 78, 87, 94, 104, 208, 14, 21, 32, 42, 51, 66, 255, 94, 104, 109, 112, 115, 118, 248, 53, 69, 80, 88, 95, 102 }; jamulus-3.9.1+dfsg/libs/opus/silk/gain_quant.c0000644000175000017500000001542014340334543020331 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" #define OFFSET ( ( MIN_QGAIN_DB * 128 ) / 6 + 16 * 128 ) #define SCALE_Q16 ( ( 65536 * ( N_LEVELS_QGAIN - 1 ) ) / ( ( ( MAX_QGAIN_DB - MIN_QGAIN_DB ) * 128 ) / 6 ) ) #define INV_SCALE_Q16 ( ( 65536 * ( ( ( MAX_QGAIN_DB - MIN_QGAIN_DB ) * 128 ) / 6 ) ) / ( N_LEVELS_QGAIN - 1 ) ) /* Gain scalar quantization with hysteresis, uniform on log scale */ void silk_gains_quant( opus_int8 ind[ MAX_NB_SUBFR ], /* O gain indices */ opus_int32 gain_Q16[ MAX_NB_SUBFR ], /* I/O gains (quantized out) */ opus_int8 *prev_ind, /* I/O last index in previous frame */ const opus_int conditional, /* I first gain is delta coded if 1 */ const opus_int nb_subfr /* I number of subframes */ ) { opus_int k, double_step_size_threshold; for( k = 0; k < nb_subfr; k++ ) { /* Convert to log scale, scale, floor() */ ind[ k ] = silk_SMULWB( SCALE_Q16, silk_lin2log( gain_Q16[ k ] ) - OFFSET ); /* Round towards previous quantized gain (hysteresis) */ if( ind[ k ] < *prev_ind ) { ind[ k ]++; } ind[ k ] = silk_LIMIT_int( ind[ k ], 0, N_LEVELS_QGAIN - 1 ); /* Compute delta indices and limit */ if( k == 0 && conditional == 0 ) { /* Full index */ ind[ k ] = silk_LIMIT_int( ind[ k ], *prev_ind + MIN_DELTA_GAIN_QUANT, N_LEVELS_QGAIN - 1 ); *prev_ind = ind[ k ]; } else { /* Delta index */ ind[ k ] = ind[ k ] - *prev_ind; /* Double the quantization step size for large gain increases, so that the max gain level can be reached */ double_step_size_threshold = 2 * MAX_DELTA_GAIN_QUANT - N_LEVELS_QGAIN + *prev_ind; if( ind[ k ] > double_step_size_threshold ) { ind[ k ] = double_step_size_threshold + silk_RSHIFT( ind[ k ] - double_step_size_threshold + 1, 1 ); } ind[ k ] = silk_LIMIT_int( ind[ k ], MIN_DELTA_GAIN_QUANT, MAX_DELTA_GAIN_QUANT ); /* Accumulate deltas */ if( ind[ k ] > double_step_size_threshold ) { *prev_ind += silk_LSHIFT( ind[ k ], 1 ) - double_step_size_threshold; *prev_ind = silk_min_int( *prev_ind, N_LEVELS_QGAIN - 1 ); } else { *prev_ind += ind[ k ]; } /* Shift to make non-negative */ ind[ k ] -= MIN_DELTA_GAIN_QUANT; } /* Scale and convert to linear scale */ gain_Q16[ k ] = silk_log2lin( silk_min_32( silk_SMULWB( INV_SCALE_Q16, *prev_ind ) + OFFSET, 3967 ) ); /* 3967 = 31 in Q7 */ } } /* Gains scalar dequantization, uniform on log scale */ void silk_gains_dequant( opus_int32 gain_Q16[ MAX_NB_SUBFR ], /* O quantized gains */ const opus_int8 ind[ MAX_NB_SUBFR ], /* I gain indices */ opus_int8 *prev_ind, /* I/O last index in previous frame */ const opus_int conditional, /* I first gain is delta coded if 1 */ const opus_int nb_subfr /* I number of subframes */ ) { opus_int k, ind_tmp, double_step_size_threshold; for( k = 0; k < nb_subfr; k++ ) { if( k == 0 && conditional == 0 ) { /* Gain index is not allowed to go down more than 16 steps (~21.8 dB) */ *prev_ind = silk_max_int( ind[ k ], *prev_ind - 16 ); } else { /* Delta index */ ind_tmp = ind[ k ] + MIN_DELTA_GAIN_QUANT; /* Accumulate deltas */ double_step_size_threshold = 2 * MAX_DELTA_GAIN_QUANT - N_LEVELS_QGAIN + *prev_ind; if( ind_tmp > double_step_size_threshold ) { *prev_ind += silk_LSHIFT( ind_tmp, 1 ) - double_step_size_threshold; } else { *prev_ind += ind_tmp; } } *prev_ind = silk_LIMIT_int( *prev_ind, 0, N_LEVELS_QGAIN - 1 ); /* Scale and convert to linear scale */ gain_Q16[ k ] = silk_log2lin( silk_min_32( silk_SMULWB( INV_SCALE_Q16, *prev_ind ) + OFFSET, 3967 ) ); /* 3967 = 31 in Q7 */ } } /* Compute unique identifier of gain indices vector */ opus_int32 silk_gains_ID( /* O returns unique identifier of gains */ const opus_int8 ind[ MAX_NB_SUBFR ], /* I gain indices */ const opus_int nb_subfr /* I number of subframes */ ) { opus_int k; opus_int32 gainsID; gainsID = 0; for( k = 0; k < nb_subfr; k++ ) { gainsID = silk_ADD_LSHIFT32( ind[ k ], gainsID, 8 ); } return gainsID; } jamulus-3.9.1+dfsg/libs/opus/silk/API.h0000644000175000017500000001617214340334543016626 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SILK_API_H #define SILK_API_H #include "control.h" #include "typedef.h" #include "errors.h" #include "entenc.h" #include "entdec.h" #ifdef __cplusplus extern "C" { #endif #define SILK_MAX_FRAMES_PER_PACKET 3 /* Struct for TOC (Table of Contents) */ typedef struct { opus_int VADFlag; /* Voice activity for packet */ opus_int VADFlags[ SILK_MAX_FRAMES_PER_PACKET ]; /* Voice activity for each frame in packet */ opus_int inbandFECFlag; /* Flag indicating if packet contains in-band FEC */ } silk_TOC_struct; /****************************************/ /* Encoder functions */ /****************************************/ /***********************************************/ /* Get size in bytes of the Silk encoder state */ /***********************************************/ opus_int silk_Get_Encoder_Size( /* O Returns error code */ opus_int *encSizeBytes /* O Number of bytes in SILK encoder state */ ); /*************************/ /* Init or reset encoder */ /*************************/ opus_int silk_InitEncoder( /* O Returns error code */ void *encState, /* I/O State */ int arch, /* I Run-time architecture */ silk_EncControlStruct *encStatus /* O Encoder Status */ ); /**************************/ /* Encode frame with Silk */ /**************************/ /* Note: if prefillFlag is set, the input must contain 10 ms of audio, irrespective of what */ /* encControl->payloadSize_ms is set to */ opus_int silk_Encode( /* O Returns error code */ void *encState, /* I/O State */ silk_EncControlStruct *encControl, /* I Control status */ const opus_int16 *samplesIn, /* I Speech sample input vector */ opus_int nSamplesIn, /* I Number of samples in input vector */ ec_enc *psRangeEnc, /* I/O Compressor data structure */ opus_int32 *nBytesOut, /* I/O Number of bytes in payload (input: Max bytes) */ const opus_int prefillFlag, /* I Flag to indicate prefilling buffers no coding */ int activity /* I Decision of Opus voice activity detector */ ); /****************************************/ /* Decoder functions */ /****************************************/ /***********************************************/ /* Get size in bytes of the Silk decoder state */ /***********************************************/ opus_int silk_Get_Decoder_Size( /* O Returns error code */ opus_int *decSizeBytes /* O Number of bytes in SILK decoder state */ ); /*************************/ /* Init or Reset decoder */ /*************************/ opus_int silk_InitDecoder( /* O Returns error code */ void *decState /* I/O State */ ); /******************/ /* Decode a frame */ /******************/ opus_int silk_Decode( /* O Returns error code */ void* decState, /* I/O State */ silk_DecControlStruct* decControl, /* I/O Control Structure */ opus_int lostFlag, /* I 0: no loss, 1 loss, 2 decode fec */ opus_int newPacketFlag, /* I Indicates first decoder call for this packet */ ec_dec *psRangeDec, /* I/O Compressor data structure */ opus_int16 *samplesOut, /* O Decoded output speech vector */ opus_int32 *nSamplesOut, /* O Number of samples decoded */ int arch /* I Run-time architecture */ ); #if 0 /**************************************/ /* Get table of contents for a packet */ /**************************************/ opus_int silk_get_TOC( const opus_uint8 *payload, /* I Payload data */ const opus_int nBytesIn, /* I Number of input bytes */ const opus_int nFramesPerPayload, /* I Number of SILK frames per payload */ silk_TOC_struct *Silk_TOC /* O Type of content */ ); #endif #ifdef __cplusplus } #endif #endif jamulus-3.9.1+dfsg/libs/opus/silk/decode_frame.c0000644000175000017500000001401014340334543020572 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" #include "stack_alloc.h" #include "PLC.h" /****************/ /* Decode frame */ /****************/ opus_int silk_decode_frame( silk_decoder_state *psDec, /* I/O Pointer to Silk decoder state */ ec_dec *psRangeDec, /* I/O Compressor data structure */ opus_int16 pOut[], /* O Pointer to output speech frame */ opus_int32 *pN, /* O Pointer to size of output frame */ opus_int lostFlag, /* I 0: no loss, 1 loss, 2 decode fec */ opus_int condCoding, /* I The type of conditional coding to use */ int arch /* I Run-time architecture */ ) { VARDECL( silk_decoder_control, psDecCtrl ); opus_int L, mv_len, ret = 0; SAVE_STACK; L = psDec->frame_length; ALLOC( psDecCtrl, 1, silk_decoder_control ); psDecCtrl->LTP_scale_Q14 = 0; /* Safety checks */ celt_assert( L > 0 && L <= MAX_FRAME_LENGTH ); if( lostFlag == FLAG_DECODE_NORMAL || ( lostFlag == FLAG_DECODE_LBRR && psDec->LBRR_flags[ psDec->nFramesDecoded ] == 1 ) ) { VARDECL( opus_int16, pulses ); ALLOC( pulses, (L + SHELL_CODEC_FRAME_LENGTH - 1) & ~(SHELL_CODEC_FRAME_LENGTH - 1), opus_int16 ); /*********************************************/ /* Decode quantization indices of side info */ /*********************************************/ silk_decode_indices( psDec, psRangeDec, psDec->nFramesDecoded, lostFlag, condCoding ); /*********************************************/ /* Decode quantization indices of excitation */ /*********************************************/ silk_decode_pulses( psRangeDec, pulses, psDec->indices.signalType, psDec->indices.quantOffsetType, psDec->frame_length ); /********************************************/ /* Decode parameters and pulse signal */ /********************************************/ silk_decode_parameters( psDec, psDecCtrl, condCoding ); /********************************************************/ /* Run inverse NSQ */ /********************************************************/ silk_decode_core( psDec, psDecCtrl, pOut, pulses, arch ); /********************************************************/ /* Update PLC state */ /********************************************************/ silk_PLC( psDec, psDecCtrl, pOut, 0, arch ); psDec->lossCnt = 0; psDec->prevSignalType = psDec->indices.signalType; celt_assert( psDec->prevSignalType >= 0 && psDec->prevSignalType <= 2 ); /* A frame has been decoded without errors */ psDec->first_frame_after_reset = 0; } else { /* Handle packet loss by extrapolation */ psDec->indices.signalType = psDec->prevSignalType; silk_PLC( psDec, psDecCtrl, pOut, 1, arch ); } /*************************/ /* Update output buffer. */ /*************************/ celt_assert( psDec->ltp_mem_length >= psDec->frame_length ); mv_len = psDec->ltp_mem_length - psDec->frame_length; silk_memmove( psDec->outBuf, &psDec->outBuf[ psDec->frame_length ], mv_len * sizeof(opus_int16) ); silk_memcpy( &psDec->outBuf[ mv_len ], pOut, psDec->frame_length * sizeof( opus_int16 ) ); /************************************************/ /* Comfort noise generation / estimation */ /************************************************/ silk_CNG( psDec, psDecCtrl, pOut, L ); /****************************************************************/ /* Ensure smooth connection of extrapolated and good frames */ /****************************************************************/ silk_PLC_glue_frames( psDec, pOut, L ); /* Update some decoder state variables */ psDec->lagPrev = psDecCtrl->pitchL[ psDec->nb_subfr - 1 ]; /* Set output frame length */ *pN = L; RESTORE_STACK; return ret; } jamulus-3.9.1+dfsg/libs/opus/silk/quant_LTP_gains.c0000644000175000017500000001626214340334543021240 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" #include "tuning_parameters.h" void silk_quant_LTP_gains( opus_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ], /* O Quantized LTP gains */ opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook Index */ opus_int8 *periodicity_index, /* O Periodicity Index */ opus_int32 *sum_log_gain_Q7, /* I/O Cumulative max prediction gain */ opus_int *pred_gain_dB_Q7, /* O LTP prediction gain */ const opus_int32 XX_Q17[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ], /* I Correlation matrix in Q18 */ const opus_int32 xX_Q17[ MAX_NB_SUBFR*LTP_ORDER ], /* I Correlation vector in Q18 */ const opus_int subfr_len, /* I Number of samples per subframe */ const opus_int nb_subfr, /* I Number of subframes */ int arch /* I Run-time architecture */ ) { opus_int j, k, cbk_size; opus_int8 temp_idx[ MAX_NB_SUBFR ]; const opus_uint8 *cl_ptr_Q5; const opus_int8 *cbk_ptr_Q7; const opus_uint8 *cbk_gain_ptr_Q7; const opus_int32 *XX_Q17_ptr, *xX_Q17_ptr; opus_int32 res_nrg_Q15_subfr, res_nrg_Q15, rate_dist_Q7_subfr, rate_dist_Q7, min_rate_dist_Q7; opus_int32 sum_log_gain_tmp_Q7, best_sum_log_gain_Q7, max_gain_Q7; opus_int gain_Q7; /***************************************************/ /* iterate over different codebooks with different */ /* rates/distortions, and choose best */ /***************************************************/ min_rate_dist_Q7 = silk_int32_MAX; best_sum_log_gain_Q7 = 0; for( k = 0; k < 3; k++ ) { /* Safety margin for pitch gain control, to take into account factors such as state rescaling/rewhitening. */ opus_int32 gain_safety = SILK_FIX_CONST( 0.4, 7 ); cl_ptr_Q5 = silk_LTP_gain_BITS_Q5_ptrs[ k ]; cbk_ptr_Q7 = silk_LTP_vq_ptrs_Q7[ k ]; cbk_gain_ptr_Q7 = silk_LTP_vq_gain_ptrs_Q7[ k ]; cbk_size = silk_LTP_vq_sizes[ k ]; /* Set up pointers to first subframe */ XX_Q17_ptr = XX_Q17; xX_Q17_ptr = xX_Q17; res_nrg_Q15 = 0; rate_dist_Q7 = 0; sum_log_gain_tmp_Q7 = *sum_log_gain_Q7; for( j = 0; j < nb_subfr; j++ ) { max_gain_Q7 = silk_log2lin( ( SILK_FIX_CONST( MAX_SUM_LOG_GAIN_DB / 6.0, 7 ) - sum_log_gain_tmp_Q7 ) + SILK_FIX_CONST( 7, 7 ) ) - gain_safety; silk_VQ_WMat_EC( &temp_idx[ j ], /* O index of best codebook vector */ &res_nrg_Q15_subfr, /* O residual energy */ &rate_dist_Q7_subfr, /* O best weighted quantization error + mu * rate */ &gain_Q7, /* O sum of absolute LTP coefficients */ XX_Q17_ptr, /* I correlation matrix */ xX_Q17_ptr, /* I correlation vector */ cbk_ptr_Q7, /* I codebook */ cbk_gain_ptr_Q7, /* I codebook effective gains */ cl_ptr_Q5, /* I code length for each codebook vector */ subfr_len, /* I number of samples per subframe */ max_gain_Q7, /* I maximum sum of absolute LTP coefficients */ cbk_size, /* I number of vectors in codebook */ arch /* I Run-time architecture */ ); res_nrg_Q15 = silk_ADD_POS_SAT32( res_nrg_Q15, res_nrg_Q15_subfr ); rate_dist_Q7 = silk_ADD_POS_SAT32( rate_dist_Q7, rate_dist_Q7_subfr ); sum_log_gain_tmp_Q7 = silk_max(0, sum_log_gain_tmp_Q7 + silk_lin2log( gain_safety + gain_Q7 ) - SILK_FIX_CONST( 7, 7 )); XX_Q17_ptr += LTP_ORDER * LTP_ORDER; xX_Q17_ptr += LTP_ORDER; } if( rate_dist_Q7 <= min_rate_dist_Q7 ) { min_rate_dist_Q7 = rate_dist_Q7; *periodicity_index = (opus_int8)k; silk_memcpy( cbk_index, temp_idx, nb_subfr * sizeof( opus_int8 ) ); best_sum_log_gain_Q7 = sum_log_gain_tmp_Q7; } } cbk_ptr_Q7 = silk_LTP_vq_ptrs_Q7[ *periodicity_index ]; for( j = 0; j < nb_subfr; j++ ) { for( k = 0; k < LTP_ORDER; k++ ) { B_Q14[ j * LTP_ORDER + k ] = silk_LSHIFT( cbk_ptr_Q7[ cbk_index[ j ] * LTP_ORDER + k ], 7 ); } } if( nb_subfr == 2 ) { res_nrg_Q15 = silk_RSHIFT32( res_nrg_Q15, 1 ); } else { res_nrg_Q15 = silk_RSHIFT32( res_nrg_Q15, 2 ); } *sum_log_gain_Q7 = best_sum_log_gain_Q7; *pred_gain_dB_Q7 = (opus_int)silk_SMULBB( -3, silk_lin2log( res_nrg_Q15 ) - ( 15 << 7 ) ); } jamulus-3.9.1+dfsg/libs/opus/silk/control_codec.c0000644000175000017500000005015714340334543021026 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef FIXED_POINT #include "main_FIX.h" #define silk_encoder_state_Fxx silk_encoder_state_FIX #else #include "main_FLP.h" #define silk_encoder_state_Fxx silk_encoder_state_FLP #endif #include "stack_alloc.h" #include "tuning_parameters.h" #include "pitch_est_defines.h" static opus_int silk_setup_resamplers( silk_encoder_state_Fxx *psEnc, /* I/O */ opus_int fs_kHz /* I */ ); static opus_int silk_setup_fs( silk_encoder_state_Fxx *psEnc, /* I/O */ opus_int fs_kHz, /* I */ opus_int PacketSize_ms /* I */ ); static opus_int silk_setup_complexity( silk_encoder_state *psEncC, /* I/O */ opus_int Complexity /* I */ ); static OPUS_INLINE opus_int silk_setup_LBRR( silk_encoder_state *psEncC, /* I/O */ const silk_EncControlStruct *encControl /* I */ ); /* Control encoder */ opus_int silk_control_encoder( silk_encoder_state_Fxx *psEnc, /* I/O Pointer to Silk encoder state */ silk_EncControlStruct *encControl, /* I Control structure */ const opus_int allow_bw_switch, /* I Flag to allow switching audio bandwidth */ const opus_int channelNb, /* I Channel number */ const opus_int force_fs_kHz ) { opus_int fs_kHz, ret = 0; psEnc->sCmn.useDTX = encControl->useDTX; psEnc->sCmn.useCBR = encControl->useCBR; psEnc->sCmn.API_fs_Hz = encControl->API_sampleRate; psEnc->sCmn.maxInternal_fs_Hz = encControl->maxInternalSampleRate; psEnc->sCmn.minInternal_fs_Hz = encControl->minInternalSampleRate; psEnc->sCmn.desiredInternal_fs_Hz = encControl->desiredInternalSampleRate; psEnc->sCmn.useInBandFEC = encControl->useInBandFEC; psEnc->sCmn.nChannelsAPI = encControl->nChannelsAPI; psEnc->sCmn.nChannelsInternal = encControl->nChannelsInternal; psEnc->sCmn.allow_bandwidth_switch = allow_bw_switch; psEnc->sCmn.channelNb = channelNb; if( psEnc->sCmn.controlled_since_last_payload != 0 && psEnc->sCmn.prefillFlag == 0 ) { if( psEnc->sCmn.API_fs_Hz != psEnc->sCmn.prev_API_fs_Hz && psEnc->sCmn.fs_kHz > 0 ) { /* Change in API sampling rate in the middle of encoding a packet */ ret += silk_setup_resamplers( psEnc, psEnc->sCmn.fs_kHz ); } return ret; } /* Beyond this point we know that there are no previously coded frames in the payload buffer */ /********************************************/ /* Determine internal sampling rate */ /********************************************/ fs_kHz = silk_control_audio_bandwidth( &psEnc->sCmn, encControl ); if( force_fs_kHz ) { fs_kHz = force_fs_kHz; } /********************************************/ /* Prepare resampler and buffered data */ /********************************************/ ret += silk_setup_resamplers( psEnc, fs_kHz ); /********************************************/ /* Set internal sampling frequency */ /********************************************/ ret += silk_setup_fs( psEnc, fs_kHz, encControl->payloadSize_ms ); /********************************************/ /* Set encoding complexity */ /********************************************/ ret += silk_setup_complexity( &psEnc->sCmn, encControl->complexity ); /********************************************/ /* Set packet loss rate measured by farend */ /********************************************/ psEnc->sCmn.PacketLoss_perc = encControl->packetLossPercentage; /********************************************/ /* Set LBRR usage */ /********************************************/ ret += silk_setup_LBRR( &psEnc->sCmn, encControl ); psEnc->sCmn.controlled_since_last_payload = 1; return ret; } static opus_int silk_setup_resamplers( silk_encoder_state_Fxx *psEnc, /* I/O */ opus_int fs_kHz /* I */ ) { opus_int ret = SILK_NO_ERROR; SAVE_STACK; if( psEnc->sCmn.fs_kHz != fs_kHz || psEnc->sCmn.prev_API_fs_Hz != psEnc->sCmn.API_fs_Hz ) { if( psEnc->sCmn.fs_kHz == 0 ) { /* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */ ret += silk_resampler_init( &psEnc->sCmn.resampler_state, psEnc->sCmn.API_fs_Hz, fs_kHz * 1000, 1 ); } else { VARDECL( opus_int16, x_buf_API_fs_Hz ); VARDECL( silk_resampler_state_struct, temp_resampler_state ); #ifdef FIXED_POINT opus_int16 *x_bufFIX = psEnc->x_buf; #else VARDECL( opus_int16, x_bufFIX ); opus_int32 new_buf_samples; #endif opus_int32 api_buf_samples; opus_int32 old_buf_samples; opus_int32 buf_length_ms; buf_length_ms = silk_LSHIFT( psEnc->sCmn.nb_subfr * 5, 1 ) + LA_SHAPE_MS; old_buf_samples = buf_length_ms * psEnc->sCmn.fs_kHz; #ifndef FIXED_POINT new_buf_samples = buf_length_ms * fs_kHz; ALLOC( x_bufFIX, silk_max( old_buf_samples, new_buf_samples ), opus_int16 ); silk_float2short_array( x_bufFIX, psEnc->x_buf, old_buf_samples ); #endif /* Initialize resampler for temporary resampling of x_buf data to API_fs_Hz */ ALLOC( temp_resampler_state, 1, silk_resampler_state_struct ); ret += silk_resampler_init( temp_resampler_state, silk_SMULBB( psEnc->sCmn.fs_kHz, 1000 ), psEnc->sCmn.API_fs_Hz, 0 ); /* Calculate number of samples to temporarily upsample */ api_buf_samples = buf_length_ms * silk_DIV32_16( psEnc->sCmn.API_fs_Hz, 1000 ); /* Temporary resampling of x_buf data to API_fs_Hz */ ALLOC( x_buf_API_fs_Hz, api_buf_samples, opus_int16 ); ret += silk_resampler( temp_resampler_state, x_buf_API_fs_Hz, x_bufFIX, old_buf_samples ); /* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */ ret += silk_resampler_init( &psEnc->sCmn.resampler_state, psEnc->sCmn.API_fs_Hz, silk_SMULBB( fs_kHz, 1000 ), 1 ); /* Correct resampler state by resampling buffered data from API_fs_Hz to fs_kHz */ ret += silk_resampler( &psEnc->sCmn.resampler_state, x_bufFIX, x_buf_API_fs_Hz, api_buf_samples ); #ifndef FIXED_POINT silk_short2float_array( psEnc->x_buf, x_bufFIX, new_buf_samples); #endif } } psEnc->sCmn.prev_API_fs_Hz = psEnc->sCmn.API_fs_Hz; RESTORE_STACK; return ret; } static opus_int silk_setup_fs( silk_encoder_state_Fxx *psEnc, /* I/O */ opus_int fs_kHz, /* I */ opus_int PacketSize_ms /* I */ ) { opus_int ret = SILK_NO_ERROR; /* Set packet size */ if( PacketSize_ms != psEnc->sCmn.PacketSize_ms ) { if( ( PacketSize_ms != 10 ) && ( PacketSize_ms != 20 ) && ( PacketSize_ms != 40 ) && ( PacketSize_ms != 60 ) ) { ret = SILK_ENC_PACKET_SIZE_NOT_SUPPORTED; } if( PacketSize_ms <= 10 ) { psEnc->sCmn.nFramesPerPacket = 1; psEnc->sCmn.nb_subfr = PacketSize_ms == 10 ? 2 : 1; psEnc->sCmn.frame_length = silk_SMULBB( PacketSize_ms, fs_kHz ); psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS_2_SF, fs_kHz ); if( psEnc->sCmn.fs_kHz == 8 ) { psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_NB_iCDF; } else { psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_iCDF; } } else { psEnc->sCmn.nFramesPerPacket = silk_DIV32_16( PacketSize_ms, MAX_FRAME_LENGTH_MS ); psEnc->sCmn.nb_subfr = MAX_NB_SUBFR; psEnc->sCmn.frame_length = silk_SMULBB( 20, fs_kHz ); psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS, fs_kHz ); if( psEnc->sCmn.fs_kHz == 8 ) { psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_NB_iCDF; } else { psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_iCDF; } } psEnc->sCmn.PacketSize_ms = PacketSize_ms; psEnc->sCmn.TargetRate_bps = 0; /* trigger new SNR computation */ } /* Set internal sampling frequency */ celt_assert( fs_kHz == 8 || fs_kHz == 12 || fs_kHz == 16 ); celt_assert( psEnc->sCmn.nb_subfr == 2 || psEnc->sCmn.nb_subfr == 4 ); if( psEnc->sCmn.fs_kHz != fs_kHz ) { /* reset part of the state */ silk_memset( &psEnc->sShape, 0, sizeof( psEnc->sShape ) ); silk_memset( &psEnc->sCmn.sNSQ, 0, sizeof( psEnc->sCmn.sNSQ ) ); silk_memset( psEnc->sCmn.prev_NLSFq_Q15, 0, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) ); silk_memset( &psEnc->sCmn.sLP.In_LP_State, 0, sizeof( psEnc->sCmn.sLP.In_LP_State ) ); psEnc->sCmn.inputBufIx = 0; psEnc->sCmn.nFramesEncoded = 0; psEnc->sCmn.TargetRate_bps = 0; /* trigger new SNR computation */ /* Initialize non-zero parameters */ psEnc->sCmn.prevLag = 100; psEnc->sCmn.first_frame_after_reset = 1; psEnc->sShape.LastGainIndex = 10; psEnc->sCmn.sNSQ.lagPrev = 100; psEnc->sCmn.sNSQ.prev_gain_Q16 = 65536; psEnc->sCmn.prevSignalType = TYPE_NO_VOICE_ACTIVITY; psEnc->sCmn.fs_kHz = fs_kHz; if( psEnc->sCmn.fs_kHz == 8 ) { if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR ) { psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_NB_iCDF; } else { psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_NB_iCDF; } } else { if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR ) { psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_iCDF; } else { psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_iCDF; } } if( psEnc->sCmn.fs_kHz == 8 || psEnc->sCmn.fs_kHz == 12 ) { psEnc->sCmn.predictLPCOrder = MIN_LPC_ORDER; psEnc->sCmn.psNLSF_CB = &silk_NLSF_CB_NB_MB; } else { psEnc->sCmn.predictLPCOrder = MAX_LPC_ORDER; psEnc->sCmn.psNLSF_CB = &silk_NLSF_CB_WB; } psEnc->sCmn.subfr_length = SUB_FRAME_LENGTH_MS * fs_kHz; psEnc->sCmn.frame_length = silk_SMULBB( psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr ); psEnc->sCmn.ltp_mem_length = silk_SMULBB( LTP_MEM_LENGTH_MS, fs_kHz ); psEnc->sCmn.la_pitch = silk_SMULBB( LA_PITCH_MS, fs_kHz ); psEnc->sCmn.max_pitch_lag = silk_SMULBB( 18, fs_kHz ); if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR ) { psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS, fs_kHz ); } else { psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS_2_SF, fs_kHz ); } if( psEnc->sCmn.fs_kHz == 16 ) { psEnc->sCmn.pitch_lag_low_bits_iCDF = silk_uniform8_iCDF; } else if( psEnc->sCmn.fs_kHz == 12 ) { psEnc->sCmn.pitch_lag_low_bits_iCDF = silk_uniform6_iCDF; } else { psEnc->sCmn.pitch_lag_low_bits_iCDF = silk_uniform4_iCDF; } } /* Check that settings are valid */ celt_assert( ( psEnc->sCmn.subfr_length * psEnc->sCmn.nb_subfr ) == psEnc->sCmn.frame_length ); return ret; } static opus_int silk_setup_complexity( silk_encoder_state *psEncC, /* I/O */ opus_int Complexity /* I */ ) { opus_int ret = 0; /* Set encoding complexity */ celt_assert( Complexity >= 0 && Complexity <= 10 ); if( Complexity < 1 ) { psEncC->pitchEstimationComplexity = SILK_PE_MIN_COMPLEX; psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.8, 16 ); psEncC->pitchEstimationLPCOrder = 6; psEncC->shapingLPCOrder = 12; psEncC->la_shape = 3 * psEncC->fs_kHz; psEncC->nStatesDelayedDecision = 1; psEncC->useInterpolatedNLSFs = 0; psEncC->NLSF_MSVQ_Survivors = 2; psEncC->warping_Q16 = 0; } else if( Complexity < 2 ) { psEncC->pitchEstimationComplexity = SILK_PE_MID_COMPLEX; psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.76, 16 ); psEncC->pitchEstimationLPCOrder = 8; psEncC->shapingLPCOrder = 14; psEncC->la_shape = 5 * psEncC->fs_kHz; psEncC->nStatesDelayedDecision = 1; psEncC->useInterpolatedNLSFs = 0; psEncC->NLSF_MSVQ_Survivors = 3; psEncC->warping_Q16 = 0; } else if( Complexity < 3 ) { psEncC->pitchEstimationComplexity = SILK_PE_MIN_COMPLEX; psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.8, 16 ); psEncC->pitchEstimationLPCOrder = 6; psEncC->shapingLPCOrder = 12; psEncC->la_shape = 3 * psEncC->fs_kHz; psEncC->nStatesDelayedDecision = 2; psEncC->useInterpolatedNLSFs = 0; psEncC->NLSF_MSVQ_Survivors = 2; psEncC->warping_Q16 = 0; } else if( Complexity < 4 ) { psEncC->pitchEstimationComplexity = SILK_PE_MID_COMPLEX; psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.76, 16 ); psEncC->pitchEstimationLPCOrder = 8; psEncC->shapingLPCOrder = 14; psEncC->la_shape = 5 * psEncC->fs_kHz; psEncC->nStatesDelayedDecision = 2; psEncC->useInterpolatedNLSFs = 0; psEncC->NLSF_MSVQ_Survivors = 4; psEncC->warping_Q16 = 0; } else if( Complexity < 6 ) { psEncC->pitchEstimationComplexity = SILK_PE_MID_COMPLEX; psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.74, 16 ); psEncC->pitchEstimationLPCOrder = 10; psEncC->shapingLPCOrder = 16; psEncC->la_shape = 5 * psEncC->fs_kHz; psEncC->nStatesDelayedDecision = 2; psEncC->useInterpolatedNLSFs = 1; psEncC->NLSF_MSVQ_Survivors = 6; psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 ); } else if( Complexity < 8 ) { psEncC->pitchEstimationComplexity = SILK_PE_MID_COMPLEX; psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.72, 16 ); psEncC->pitchEstimationLPCOrder = 12; psEncC->shapingLPCOrder = 20; psEncC->la_shape = 5 * psEncC->fs_kHz; psEncC->nStatesDelayedDecision = 3; psEncC->useInterpolatedNLSFs = 1; psEncC->NLSF_MSVQ_Survivors = 8; psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 ); } else { psEncC->pitchEstimationComplexity = SILK_PE_MAX_COMPLEX; psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.7, 16 ); psEncC->pitchEstimationLPCOrder = 16; psEncC->shapingLPCOrder = 24; psEncC->la_shape = 5 * psEncC->fs_kHz; psEncC->nStatesDelayedDecision = MAX_DEL_DEC_STATES; psEncC->useInterpolatedNLSFs = 1; psEncC->NLSF_MSVQ_Survivors = 16; psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 ); } /* Do not allow higher pitch estimation LPC order than predict LPC order */ psEncC->pitchEstimationLPCOrder = silk_min_int( psEncC->pitchEstimationLPCOrder, psEncC->predictLPCOrder ); psEncC->shapeWinLength = SUB_FRAME_LENGTH_MS * psEncC->fs_kHz + 2 * psEncC->la_shape; psEncC->Complexity = Complexity; celt_assert( psEncC->pitchEstimationLPCOrder <= MAX_FIND_PITCH_LPC_ORDER ); celt_assert( psEncC->shapingLPCOrder <= MAX_SHAPE_LPC_ORDER ); celt_assert( psEncC->nStatesDelayedDecision <= MAX_DEL_DEC_STATES ); celt_assert( psEncC->warping_Q16 <= 32767 ); celt_assert( psEncC->la_shape <= LA_SHAPE_MAX ); celt_assert( psEncC->shapeWinLength <= SHAPE_LPC_WIN_MAX ); return ret; } static OPUS_INLINE opus_int silk_setup_LBRR( silk_encoder_state *psEncC, /* I/O */ const silk_EncControlStruct *encControl /* I */ ) { opus_int LBRR_in_previous_packet, ret = SILK_NO_ERROR; LBRR_in_previous_packet = psEncC->LBRR_enabled; psEncC->LBRR_enabled = encControl->LBRR_coded; if( psEncC->LBRR_enabled ) { /* Set gain increase for coding LBRR excitation */ if( LBRR_in_previous_packet == 0 ) { /* Previous packet did not have LBRR, and was therefore coded at a higher bitrate */ psEncC->LBRR_GainIncreases = 7; } else { psEncC->LBRR_GainIncreases = silk_max_int( 7 - silk_SMULWB( (opus_int32)psEncC->PacketLoss_perc, SILK_FIX_CONST( 0.4, 16 ) ), 2 ); } } return ret; } jamulus-3.9.1+dfsg/libs/opus/silk/tables_NLSF_CB_NB_MB.c0000644000175000017500000002504114340334543021600 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "tables.h" static const opus_uint8 silk_NLSF_CB1_NB_MB_Q8[ 320 ] = { 12, 35, 60, 83, 108, 132, 157, 180, 206, 228, 15, 32, 55, 77, 101, 125, 151, 175, 201, 225, 19, 42, 66, 89, 114, 137, 162, 184, 209, 230, 12, 25, 50, 72, 97, 120, 147, 172, 200, 223, 26, 44, 69, 90, 114, 135, 159, 180, 205, 225, 13, 22, 53, 80, 106, 130, 156, 180, 205, 228, 15, 25, 44, 64, 90, 115, 142, 168, 196, 222, 19, 24, 62, 82, 100, 120, 145, 168, 190, 214, 22, 31, 50, 79, 103, 120, 151, 170, 203, 227, 21, 29, 45, 65, 106, 124, 150, 171, 196, 224, 30, 49, 75, 97, 121, 142, 165, 186, 209, 229, 19, 25, 52, 70, 93, 116, 143, 166, 192, 219, 26, 34, 62, 75, 97, 118, 145, 167, 194, 217, 25, 33, 56, 70, 91, 113, 143, 165, 196, 223, 21, 34, 51, 72, 97, 117, 145, 171, 196, 222, 20, 29, 50, 67, 90, 117, 144, 168, 197, 221, 22, 31, 48, 66, 95, 117, 146, 168, 196, 222, 24, 33, 51, 77, 116, 134, 158, 180, 200, 224, 21, 28, 70, 87, 106, 124, 149, 170, 194, 217, 26, 33, 53, 64, 83, 117, 152, 173, 204, 225, 27, 34, 65, 95, 108, 129, 155, 174, 210, 225, 20, 26, 72, 99, 113, 131, 154, 176, 200, 219, 34, 43, 61, 78, 93, 114, 155, 177, 205, 229, 23, 29, 54, 97, 124, 138, 163, 179, 209, 229, 30, 38, 56, 89, 118, 129, 158, 178, 200, 231, 21, 29, 49, 63, 85, 111, 142, 163, 193, 222, 27, 48, 77, 103, 133, 158, 179, 196, 215, 232, 29, 47, 74, 99, 124, 151, 176, 198, 220, 237, 33, 42, 61, 76, 93, 121, 155, 174, 207, 225, 29, 53, 87, 112, 136, 154, 170, 188, 208, 227, 24, 30, 52, 84, 131, 150, 166, 186, 203, 229, 37, 48, 64, 84, 104, 118, 156, 177, 201, 230 }; static const opus_int16 silk_NLSF_CB1_Wght_Q9[ 320 ] = { 2897, 2314, 2314, 2314, 2287, 2287, 2314, 2300, 2327, 2287, 2888, 2580, 2394, 2367, 2314, 2274, 2274, 2274, 2274, 2194, 2487, 2340, 2340, 2314, 2314, 2314, 2340, 2340, 2367, 2354, 3216, 2766, 2340, 2340, 2314, 2274, 2221, 2207, 2261, 2194, 2460, 2474, 2367, 2394, 2394, 2394, 2394, 2367, 2407, 2314, 3479, 3056, 2127, 2207, 2274, 2274, 2274, 2287, 2314, 2261, 3282, 3141, 2580, 2394, 2247, 2221, 2207, 2194, 2194, 2114, 4096, 3845, 2221, 2620, 2620, 2407, 2314, 2394, 2367, 2074, 3178, 3244, 2367, 2221, 2553, 2434, 2340, 2314, 2167, 2221, 3338, 3488, 2726, 2194, 2261, 2460, 2354, 2367, 2207, 2101, 2354, 2420, 2327, 2367, 2394, 2420, 2420, 2420, 2460, 2367, 3779, 3629, 2434, 2527, 2367, 2274, 2274, 2300, 2207, 2048, 3254, 3225, 2713, 2846, 2447, 2327, 2300, 2300, 2274, 2127, 3263, 3300, 2753, 2806, 2447, 2261, 2261, 2247, 2127, 2101, 2873, 2981, 2633, 2367, 2407, 2354, 2194, 2247, 2247, 2114, 3225, 3197, 2633, 2580, 2274, 2181, 2247, 2221, 2221, 2141, 3178, 3310, 2740, 2407, 2274, 2274, 2274, 2287, 2194, 2114, 3141, 3272, 2460, 2061, 2287, 2500, 2367, 2487, 2434, 2181, 3507, 3282, 2314, 2700, 2647, 2474, 2367, 2394, 2340, 2127, 3423, 3535, 3038, 3056, 2300, 1950, 2221, 2274, 2274, 2274, 3404, 3366, 2087, 2687, 2873, 2354, 2420, 2274, 2474, 2540, 3760, 3488, 1950, 2660, 2897, 2527, 2394, 2367, 2460, 2261, 3028, 3272, 2740, 2888, 2740, 2154, 2127, 2287, 2234, 2247, 3695, 3657, 2025, 1969, 2660, 2700, 2580, 2500, 2327, 2367, 3207, 3413, 2354, 2074, 2888, 2888, 2340, 2487, 2247, 2167, 3338, 3366, 2846, 2780, 2327, 2154, 2274, 2287, 2114, 2061, 2327, 2300, 2181, 2167, 2181, 2367, 2633, 2700, 2700, 2553, 2407, 2434, 2221, 2261, 2221, 2221, 2340, 2420, 2607, 2700, 3038, 3244, 2806, 2888, 2474, 2074, 2300, 2314, 2354, 2380, 2221, 2154, 2127, 2287, 2500, 2793, 2793, 2620, 2580, 2367, 3676, 3713, 2234, 1838, 2181, 2753, 2726, 2673, 2513, 2207, 2793, 3160, 2726, 2553, 2846, 2513, 2181, 2394, 2221, 2181 }; static const opus_uint8 silk_NLSF_CB1_iCDF_NB_MB[ 64 ] = { 212, 178, 148, 129, 108, 96, 85, 82, 79, 77, 61, 59, 57, 56, 51, 49, 48, 45, 42, 41, 40, 38, 36, 34, 31, 30, 21, 12, 10, 3, 1, 0, 255, 245, 244, 236, 233, 225, 217, 203, 190, 176, 175, 161, 149, 136, 125, 114, 102, 91, 81, 71, 60, 52, 43, 35, 28, 20, 19, 18, 12, 11, 5, 0 }; static const opus_uint8 silk_NLSF_CB2_SELECT_NB_MB[ 160 ] = { 16, 0, 0, 0, 0, 99, 66, 36, 36, 34, 36, 34, 34, 34, 34, 83, 69, 36, 52, 34, 116, 102, 70, 68, 68, 176, 102, 68, 68, 34, 65, 85, 68, 84, 36, 116, 141, 152, 139, 170, 132, 187, 184, 216, 137, 132, 249, 168, 185, 139, 104, 102, 100, 68, 68, 178, 218, 185, 185, 170, 244, 216, 187, 187, 170, 244, 187, 187, 219, 138, 103, 155, 184, 185, 137, 116, 183, 155, 152, 136, 132, 217, 184, 184, 170, 164, 217, 171, 155, 139, 244, 169, 184, 185, 170, 164, 216, 223, 218, 138, 214, 143, 188, 218, 168, 244, 141, 136, 155, 170, 168, 138, 220, 219, 139, 164, 219, 202, 216, 137, 168, 186, 246, 185, 139, 116, 185, 219, 185, 138, 100, 100, 134, 100, 102, 34, 68, 68, 100, 68, 168, 203, 221, 218, 168, 167, 154, 136, 104, 70, 164, 246, 171, 137, 139, 137, 155, 218, 219, 139 }; static const opus_uint8 silk_NLSF_CB2_iCDF_NB_MB[ 72 ] = { 255, 254, 253, 238, 14, 3, 2, 1, 0, 255, 254, 252, 218, 35, 3, 2, 1, 0, 255, 254, 250, 208, 59, 4, 2, 1, 0, 255, 254, 246, 194, 71, 10, 2, 1, 0, 255, 252, 236, 183, 82, 8, 2, 1, 0, 255, 252, 235, 180, 90, 17, 2, 1, 0, 255, 248, 224, 171, 97, 30, 4, 1, 0, 255, 254, 236, 173, 95, 37, 7, 1, 0 }; static const opus_uint8 silk_NLSF_CB2_BITS_NB_MB_Q5[ 72 ] = { 255, 255, 255, 131, 6, 145, 255, 255, 255, 255, 255, 236, 93, 15, 96, 255, 255, 255, 255, 255, 194, 83, 25, 71, 221, 255, 255, 255, 255, 162, 73, 34, 66, 162, 255, 255, 255, 210, 126, 73, 43, 57, 173, 255, 255, 255, 201, 125, 71, 48, 58, 130, 255, 255, 255, 166, 110, 73, 57, 62, 104, 210, 255, 255, 251, 123, 65, 55, 68, 100, 171, 255 }; static const opus_uint8 silk_NLSF_PRED_NB_MB_Q8[ 18 ] = { 179, 138, 140, 148, 151, 149, 153, 151, 163, 116, 67, 82, 59, 92, 72, 100, 89, 92 }; static const opus_int16 silk_NLSF_DELTA_MIN_NB_MB_Q15[ 11 ] = { 250, 3, 6, 3, 3, 3, 4, 3, 3, 3, 461 }; const silk_NLSF_CB_struct silk_NLSF_CB_NB_MB = { 32, 10, SILK_FIX_CONST( 0.18, 16 ), SILK_FIX_CONST( 1.0 / 0.18, 6 ), silk_NLSF_CB1_NB_MB_Q8, silk_NLSF_CB1_Wght_Q9, silk_NLSF_CB1_iCDF_NB_MB, silk_NLSF_PRED_NB_MB_Q8, silk_NLSF_CB2_SELECT_NB_MB, silk_NLSF_CB2_iCDF_NB_MB, silk_NLSF_CB2_BITS_NB_MB_Q5, silk_NLSF_DELTA_MIN_NB_MB_Q15, }; jamulus-3.9.1+dfsg/libs/opus/silk/debug.c0000644000175000017500000001530114340334543017267 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "debug.h" #include "SigProc_FIX.h" #if SILK_TIC_TOC #ifdef _WIN32 #if (defined(_WIN32) || defined(_WINCE)) #include /* timer */ #else /* Linux or Mac*/ #include #endif unsigned long silk_GetHighResolutionTime(void) /* O time in usec*/ { /* Returns a time counter in microsec */ /* the resolution is platform dependent */ /* but is typically 1.62 us resolution */ LARGE_INTEGER lpPerformanceCount; LARGE_INTEGER lpFrequency; QueryPerformanceCounter(&lpPerformanceCount); QueryPerformanceFrequency(&lpFrequency); return (unsigned long)((1000000*(lpPerformanceCount.QuadPart)) / lpFrequency.QuadPart); } #else /* Linux or Mac*/ unsigned long GetHighResolutionTime(void) /* O time in usec*/ { struct timeval tv; gettimeofday(&tv, 0); return((tv.tv_sec*1000000)+(tv.tv_usec)); } #endif int silk_Timer_nTimers = 0; int silk_Timer_depth_ctr = 0; char silk_Timer_tags[silk_NUM_TIMERS_MAX][silk_NUM_TIMERS_MAX_TAG_LEN]; #ifdef WIN32 LARGE_INTEGER silk_Timer_start[silk_NUM_TIMERS_MAX]; #else unsigned long silk_Timer_start[silk_NUM_TIMERS_MAX]; #endif unsigned int silk_Timer_cnt[silk_NUM_TIMERS_MAX]; opus_int64 silk_Timer_min[silk_NUM_TIMERS_MAX]; opus_int64 silk_Timer_sum[silk_NUM_TIMERS_MAX]; opus_int64 silk_Timer_max[silk_NUM_TIMERS_MAX]; opus_int64 silk_Timer_depth[silk_NUM_TIMERS_MAX]; #ifdef WIN32 void silk_TimerSave(char *file_name) { if( silk_Timer_nTimers > 0 ) { int k; FILE *fp; LARGE_INTEGER lpFrequency; LARGE_INTEGER lpPerformanceCount1, lpPerformanceCount2; int del = 0x7FFFFFFF; double avg, sum_avg; /* estimate overhead of calling performance counters */ for( k = 0; k < 1000; k++ ) { QueryPerformanceCounter(&lpPerformanceCount1); QueryPerformanceCounter(&lpPerformanceCount2); lpPerformanceCount2.QuadPart -= lpPerformanceCount1.QuadPart; if( (int)lpPerformanceCount2.LowPart < del ) del = lpPerformanceCount2.LowPart; } QueryPerformanceFrequency(&lpFrequency); /* print results to file */ sum_avg = 0.0f; for( k = 0; k < silk_Timer_nTimers; k++ ) { if (silk_Timer_depth[k] == 0) { sum_avg += (1e6 * silk_Timer_sum[k] / silk_Timer_cnt[k] - del) / lpFrequency.QuadPart * silk_Timer_cnt[k]; } } fp = fopen(file_name, "w"); fprintf(fp, " min avg %% max count\n"); for( k = 0; k < silk_Timer_nTimers; k++ ) { if (silk_Timer_depth[k] == 0) { fprintf(fp, "%-28s", silk_Timer_tags[k]); } else if (silk_Timer_depth[k] == 1) { fprintf(fp, " %-27s", silk_Timer_tags[k]); } else if (silk_Timer_depth[k] == 2) { fprintf(fp, " %-26s", silk_Timer_tags[k]); } else if (silk_Timer_depth[k] == 3) { fprintf(fp, " %-25s", silk_Timer_tags[k]); } else { fprintf(fp, " %-24s", silk_Timer_tags[k]); } avg = (1e6 * silk_Timer_sum[k] / silk_Timer_cnt[k] - del) / lpFrequency.QuadPart; fprintf(fp, "%8.2f", (1e6 * (silk_max_64(silk_Timer_min[k] - del, 0))) / lpFrequency.QuadPart); fprintf(fp, "%12.2f %6.2f", avg, 100.0 * avg / sum_avg * silk_Timer_cnt[k]); fprintf(fp, "%12.2f", (1e6 * (silk_max_64(silk_Timer_max[k] - del, 0))) / lpFrequency.QuadPart); fprintf(fp, "%10d\n", silk_Timer_cnt[k]); } fprintf(fp, " microseconds\n"); fclose(fp); } } #else void silk_TimerSave(char *file_name) { if( silk_Timer_nTimers > 0 ) { int k; FILE *fp; /* print results to file */ fp = fopen(file_name, "w"); fprintf(fp, " min avg max count\n"); for( k = 0; k < silk_Timer_nTimers; k++ ) { if (silk_Timer_depth[k] == 0) { fprintf(fp, "%-28s", silk_Timer_tags[k]); } else if (silk_Timer_depth[k] == 1) { fprintf(fp, " %-27s", silk_Timer_tags[k]); } else if (silk_Timer_depth[k] == 2) { fprintf(fp, " %-26s", silk_Timer_tags[k]); } else if (silk_Timer_depth[k] == 3) { fprintf(fp, " %-25s", silk_Timer_tags[k]); } else { fprintf(fp, " %-24s", silk_Timer_tags[k]); } fprintf(fp, "%d ", silk_Timer_min[k]); fprintf(fp, "%f ", (double)silk_Timer_sum[k] / (double)silk_Timer_cnt[k]); fprintf(fp, "%d ", silk_Timer_max[k]); fprintf(fp, "%10d\n", silk_Timer_cnt[k]); } fprintf(fp, " microseconds\n"); fclose(fp); } } #endif #endif /* SILK_TIC_TOC */ #if SILK_DEBUG FILE *silk_debug_store_fp[ silk_NUM_STORES_MAX ]; int silk_debug_store_count = 0; #endif /* SILK_DEBUG */ jamulus-3.9.1+dfsg/libs/opus/silk/tables.h0000644000175000017500000001601214340334543017460 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SILK_TABLES_H #define SILK_TABLES_H #include "define.h" #include "structs.h" #ifdef __cplusplus extern "C" { #endif /* Entropy coding tables (with size in bytes indicated) */ extern const opus_uint8 silk_gain_iCDF[ 3 ][ N_LEVELS_QGAIN / 8 ]; /* 24 */ extern const opus_uint8 silk_delta_gain_iCDF[ MAX_DELTA_GAIN_QUANT - MIN_DELTA_GAIN_QUANT + 1 ]; /* 41 */ extern const opus_uint8 silk_pitch_lag_iCDF[ 2 * ( PITCH_EST_MAX_LAG_MS - PITCH_EST_MIN_LAG_MS ) ];/* 32 */ extern const opus_uint8 silk_pitch_delta_iCDF[ 21 ]; /* 21 */ extern const opus_uint8 silk_pitch_contour_iCDF[ 34 ]; /* 34 */ extern const opus_uint8 silk_pitch_contour_NB_iCDF[ 11 ]; /* 11 */ extern const opus_uint8 silk_pitch_contour_10_ms_iCDF[ 12 ]; /* 12 */ extern const opus_uint8 silk_pitch_contour_10_ms_NB_iCDF[ 3 ]; /* 3 */ extern const opus_uint8 silk_pulses_per_block_iCDF[ N_RATE_LEVELS ][ SILK_MAX_PULSES + 2 ]; /* 180 */ extern const opus_uint8 silk_pulses_per_block_BITS_Q5[ N_RATE_LEVELS - 1 ][ SILK_MAX_PULSES + 2 ]; /* 162 */ extern const opus_uint8 silk_rate_levels_iCDF[ 2 ][ N_RATE_LEVELS - 1 ]; /* 18 */ extern const opus_uint8 silk_rate_levels_BITS_Q5[ 2 ][ N_RATE_LEVELS - 1 ]; /* 18 */ extern const opus_uint8 silk_max_pulses_table[ 4 ]; /* 4 */ extern const opus_uint8 silk_shell_code_table0[ 152 ]; /* 152 */ extern const opus_uint8 silk_shell_code_table1[ 152 ]; /* 152 */ extern const opus_uint8 silk_shell_code_table2[ 152 ]; /* 152 */ extern const opus_uint8 silk_shell_code_table3[ 152 ]; /* 152 */ extern const opus_uint8 silk_shell_code_table_offsets[ SILK_MAX_PULSES + 1 ]; /* 17 */ extern const opus_uint8 silk_lsb_iCDF[ 2 ]; /* 2 */ extern const opus_uint8 silk_sign_iCDF[ 42 ]; /* 42 */ extern const opus_uint8 silk_uniform3_iCDF[ 3 ]; /* 3 */ extern const opus_uint8 silk_uniform4_iCDF[ 4 ]; /* 4 */ extern const opus_uint8 silk_uniform5_iCDF[ 5 ]; /* 5 */ extern const opus_uint8 silk_uniform6_iCDF[ 6 ]; /* 6 */ extern const opus_uint8 silk_uniform8_iCDF[ 8 ]; /* 8 */ extern const opus_uint8 silk_NLSF_EXT_iCDF[ 7 ]; /* 7 */ extern const opus_uint8 silk_LTP_per_index_iCDF[ 3 ]; /* 3 */ extern const opus_uint8 * const silk_LTP_gain_iCDF_ptrs[ NB_LTP_CBKS ]; /* 3 */ extern const opus_uint8 * const silk_LTP_gain_BITS_Q5_ptrs[ NB_LTP_CBKS ]; /* 3 */ extern const opus_int8 * const silk_LTP_vq_ptrs_Q7[ NB_LTP_CBKS ]; /* 168 */ extern const opus_uint8 * const silk_LTP_vq_gain_ptrs_Q7[NB_LTP_CBKS]; extern const opus_int8 silk_LTP_vq_sizes[ NB_LTP_CBKS ]; /* 3 */ extern const opus_uint8 silk_LTPscale_iCDF[ 3 ]; /* 4 */ extern const opus_int16 silk_LTPScales_table_Q14[ 3 ]; /* 6 */ extern const opus_uint8 silk_type_offset_VAD_iCDF[ 4 ]; /* 4 */ extern const opus_uint8 silk_type_offset_no_VAD_iCDF[ 2 ]; /* 2 */ extern const opus_int16 silk_stereo_pred_quant_Q13[ STEREO_QUANT_TAB_SIZE ]; /* 32 */ extern const opus_uint8 silk_stereo_pred_joint_iCDF[ 25 ]; /* 25 */ extern const opus_uint8 silk_stereo_only_code_mid_iCDF[ 2 ]; /* 2 */ extern const opus_uint8 * const silk_LBRR_flags_iCDF_ptr[ 2 ]; /* 10 */ extern const opus_uint8 silk_NLSF_interpolation_factor_iCDF[ 5 ]; /* 5 */ extern const silk_NLSF_CB_struct silk_NLSF_CB_WB; /* 1040 */ extern const silk_NLSF_CB_struct silk_NLSF_CB_NB_MB; /* 728 */ /* Quantization offsets */ extern const opus_int16 silk_Quantization_Offsets_Q10[ 2 ][ 2 ]; /* 8 */ /* Interpolation points for filter coefficients used in the bandwidth transition smoother */ extern const opus_int32 silk_Transition_LP_B_Q28[ TRANSITION_INT_NUM ][ TRANSITION_NB ]; /* 60 */ extern const opus_int32 silk_Transition_LP_A_Q28[ TRANSITION_INT_NUM ][ TRANSITION_NA ]; /* 60 */ /* Rom table with cosine values */ extern const opus_int16 silk_LSFCosTab_FIX_Q12[ LSF_COS_TAB_SZ_FIX + 1 ]; /* 258 */ #ifdef __cplusplus } #endif #endif jamulus-3.9.1+dfsg/libs/opus/silk/tables_LTP.c0000644000175000017500000001641014340334543020174 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "tables.h" const opus_uint8 silk_LTP_per_index_iCDF[3] = { 179, 99, 0 }; static const opus_uint8 silk_LTP_gain_iCDF_0[8] = { 71, 56, 43, 30, 21, 12, 6, 0 }; static const opus_uint8 silk_LTP_gain_iCDF_1[16] = { 199, 165, 144, 124, 109, 96, 84, 71, 61, 51, 42, 32, 23, 15, 8, 0 }; static const opus_uint8 silk_LTP_gain_iCDF_2[32] = { 241, 225, 211, 199, 187, 175, 164, 153, 142, 132, 123, 114, 105, 96, 88, 80, 72, 64, 57, 50, 44, 38, 33, 29, 24, 20, 16, 12, 9, 5, 2, 0 }; static const opus_uint8 silk_LTP_gain_BITS_Q5_0[8] = { 15, 131, 138, 138, 155, 155, 173, 173 }; static const opus_uint8 silk_LTP_gain_BITS_Q5_1[16] = { 69, 93, 115, 118, 131, 138, 141, 138, 150, 150, 155, 150, 155, 160, 166, 160 }; static const opus_uint8 silk_LTP_gain_BITS_Q5_2[32] = { 131, 128, 134, 141, 141, 141, 145, 145, 145, 150, 155, 155, 155, 155, 160, 160, 160, 160, 166, 166, 173, 173, 182, 192, 182, 192, 192, 192, 205, 192, 205, 224 }; const opus_uint8 * const silk_LTP_gain_iCDF_ptrs[NB_LTP_CBKS] = { silk_LTP_gain_iCDF_0, silk_LTP_gain_iCDF_1, silk_LTP_gain_iCDF_2 }; const opus_uint8 * const silk_LTP_gain_BITS_Q5_ptrs[NB_LTP_CBKS] = { silk_LTP_gain_BITS_Q5_0, silk_LTP_gain_BITS_Q5_1, silk_LTP_gain_BITS_Q5_2 }; static const opus_int8 silk_LTP_gain_vq_0[8][5] = { { 4, 6, 24, 7, 5 }, { 0, 0, 2, 0, 0 }, { 12, 28, 41, 13, -4 }, { -9, 15, 42, 25, 14 }, { 1, -2, 62, 41, -9 }, { -10, 37, 65, -4, 3 }, { -6, 4, 66, 7, -8 }, { 16, 14, 38, -3, 33 } }; static const opus_int8 silk_LTP_gain_vq_1[16][5] = { { 13, 22, 39, 23, 12 }, { -1, 36, 64, 27, -6 }, { -7, 10, 55, 43, 17 }, { 1, 1, 8, 1, 1 }, { 6, -11, 74, 53, -9 }, { -12, 55, 76, -12, 8 }, { -3, 3, 93, 27, -4 }, { 26, 39, 59, 3, -8 }, { 2, 0, 77, 11, 9 }, { -8, 22, 44, -6, 7 }, { 40, 9, 26, 3, 9 }, { -7, 20, 101, -7, 4 }, { 3, -8, 42, 26, 0 }, { -15, 33, 68, 2, 23 }, { -2, 55, 46, -2, 15 }, { 3, -1, 21, 16, 41 } }; static const opus_int8 silk_LTP_gain_vq_2[32][5] = { { -6, 27, 61, 39, 5 }, { -11, 42, 88, 4, 1 }, { -2, 60, 65, 6, -4 }, { -1, -5, 73, 56, 1 }, { -9, 19, 94, 29, -9 }, { 0, 12, 99, 6, 4 }, { 8, -19, 102, 46, -13 }, { 3, 2, 13, 3, 2 }, { 9, -21, 84, 72, -18 }, { -11, 46, 104, -22, 8 }, { 18, 38, 48, 23, 0 }, { -16, 70, 83, -21, 11 }, { 5, -11, 117, 22, -8 }, { -6, 23, 117, -12, 3 }, { 3, -8, 95, 28, 4 }, { -10, 15, 77, 60, -15 }, { -1, 4, 124, 2, -4 }, { 3, 38, 84, 24, -25 }, { 2, 13, 42, 13, 31 }, { 21, -4, 56, 46, -1 }, { -1, 35, 79, -13, 19 }, { -7, 65, 88, -9, -14 }, { 20, 4, 81, 49, -29 }, { 20, 0, 75, 3, -17 }, { 5, -9, 44, 92, -8 }, { 1, -3, 22, 69, 31 }, { -6, 95, 41, -12, 5 }, { 39, 67, 16, -4, 1 }, { 0, -6, 120, 55, -36 }, { -13, 44, 122, 4, -24 }, { 81, 5, 11, 3, 7 }, { 2, 0, 9, 10, 88 } }; const opus_int8 * const silk_LTP_vq_ptrs_Q7[NB_LTP_CBKS] = { (opus_int8 *)&silk_LTP_gain_vq_0[0][0], (opus_int8 *)&silk_LTP_gain_vq_1[0][0], (opus_int8 *)&silk_LTP_gain_vq_2[0][0] }; /* Maximum frequency-dependent response of the pitch taps above, computed as max(abs(freqz(taps))) */ static const opus_uint8 silk_LTP_gain_vq_0_gain[8] = { 46, 2, 90, 87, 93, 91, 82, 98 }; static const opus_uint8 silk_LTP_gain_vq_1_gain[16] = { 109, 120, 118, 12, 113, 115, 117, 119, 99, 59, 87, 111, 63, 111, 112, 80 }; static const opus_uint8 silk_LTP_gain_vq_2_gain[32] = { 126, 124, 125, 124, 129, 121, 126, 23, 132, 127, 127, 127, 126, 127, 122, 133, 130, 134, 101, 118, 119, 145, 126, 86, 124, 120, 123, 119, 170, 173, 107, 109 }; const opus_uint8 * const silk_LTP_vq_gain_ptrs_Q7[NB_LTP_CBKS] = { &silk_LTP_gain_vq_0_gain[0], &silk_LTP_gain_vq_1_gain[0], &silk_LTP_gain_vq_2_gain[0] }; const opus_int8 silk_LTP_vq_sizes[NB_LTP_CBKS] = { 8, 16, 32 }; jamulus-3.9.1+dfsg/libs/opus/silk/resampler_rom.h0000644000175000017500000000633614340334543021065 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SILK_FIX_RESAMPLER_ROM_H #define SILK_FIX_RESAMPLER_ROM_H #ifdef __cplusplus extern "C" { #endif #include "typedef.h" #include "resampler_structs.h" #define RESAMPLER_DOWN_ORDER_FIR0 18 #define RESAMPLER_DOWN_ORDER_FIR1 24 #define RESAMPLER_DOWN_ORDER_FIR2 36 #define RESAMPLER_ORDER_FIR_12 8 /* Tables for 2x downsampler */ static const opus_int16 silk_resampler_down2_0 = 9872; static const opus_int16 silk_resampler_down2_1 = 39809 - 65536; /* Tables for 2x upsampler, high quality */ static const opus_int16 silk_resampler_up2_hq_0[ 3 ] = { 1746, 14986, 39083 - 65536 }; static const opus_int16 silk_resampler_up2_hq_1[ 3 ] = { 6854, 25769, 55542 - 65536 }; /* Tables with IIR and FIR coefficients for fractional downsamplers */ extern const opus_int16 silk_Resampler_3_4_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ]; extern const opus_int16 silk_Resampler_2_3_COEFS[ 2 + 2 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ]; extern const opus_int16 silk_Resampler_1_2_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR1 / 2 ]; extern const opus_int16 silk_Resampler_1_3_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ]; extern const opus_int16 silk_Resampler_1_4_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ]; extern const opus_int16 silk_Resampler_1_6_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ]; extern const opus_int16 silk_Resampler_2_3_COEFS_LQ[ 2 + 2 * 2 ]; /* Table with interplation fractions of 1/24, 3/24, ..., 23/24 */ extern const opus_int16 silk_resampler_frac_FIR_12[ 12 ][ RESAMPLER_ORDER_FIR_12 / 2 ]; #ifdef __cplusplus } #endif #endif /* SILK_FIX_RESAMPLER_ROM_H */ jamulus-3.9.1+dfsg/libs/opus/silk/resampler_private.h0000644000175000017500000001071114340334543021732 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SILK_RESAMPLER_PRIVATE_H #define SILK_RESAMPLER_PRIVATE_H #ifdef __cplusplus extern "C" { #endif #include "SigProc_FIX.h" #include "resampler_structs.h" #include "resampler_rom.h" /* Number of input samples to process in the inner loop */ #define RESAMPLER_MAX_BATCH_SIZE_MS 10 #define RESAMPLER_MAX_FS_KHZ 48 #define RESAMPLER_MAX_BATCH_SIZE_IN ( RESAMPLER_MAX_BATCH_SIZE_MS * RESAMPLER_MAX_FS_KHZ ) /* Description: Hybrid IIR/FIR polyphase implementation of resampling */ void silk_resampler_private_IIR_FIR( void *SS, /* I/O Resampler state */ opus_int16 out[], /* O Output signal */ const opus_int16 in[], /* I Input signal */ opus_int32 inLen /* I Number of input samples */ ); /* Description: Hybrid IIR/FIR polyphase implementation of resampling */ void silk_resampler_private_down_FIR( void *SS, /* I/O Resampler state */ opus_int16 out[], /* O Output signal */ const opus_int16 in[], /* I Input signal */ opus_int32 inLen /* I Number of input samples */ ); /* Upsample by a factor 2, high quality */ void silk_resampler_private_up2_HQ_wrapper( void *SS, /* I/O Resampler state (unused) */ opus_int16 *out, /* O Output signal [ 2 * len ] */ const opus_int16 *in, /* I Input signal [ len ] */ opus_int32 len /* I Number of input samples */ ); /* Upsample by a factor 2, high quality */ void silk_resampler_private_up2_HQ( opus_int32 *S, /* I/O Resampler state [ 6 ] */ opus_int16 *out, /* O Output signal [ 2 * len ] */ const opus_int16 *in, /* I Input signal [ len ] */ opus_int32 len /* I Number of input samples */ ); /* Second order AR filter */ void silk_resampler_private_AR2( opus_int32 S[], /* I/O State vector [ 2 ] */ opus_int32 out_Q8[], /* O Output signal */ const opus_int16 in[], /* I Input signal */ const opus_int16 A_Q14[], /* I AR coefficients, Q14 */ opus_int32 len /* I Signal length */ ); #ifdef __cplusplus } #endif #endif /* SILK_RESAMPLER_PRIVATE_H */ jamulus-3.9.1+dfsg/libs/opus/silk/define.h0000644000175000017500000002314314340334543017443 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SILK_DEFINE_H #define SILK_DEFINE_H #include "errors.h" #include "typedef.h" #ifdef __cplusplus extern "C" { #endif /* Max number of encoder channels (1/2) */ #define ENCODER_NUM_CHANNELS 2 /* Number of decoder channels (1/2) */ #define DECODER_NUM_CHANNELS 2 #define MAX_FRAMES_PER_PACKET 3 /* Limits on bitrate */ #define MIN_TARGET_RATE_BPS 5000 #define MAX_TARGET_RATE_BPS 80000 /* LBRR thresholds */ #define LBRR_NB_MIN_RATE_BPS 12000 #define LBRR_MB_MIN_RATE_BPS 14000 #define LBRR_WB_MIN_RATE_BPS 16000 /* DTX settings */ #define NB_SPEECH_FRAMES_BEFORE_DTX 10 /* eq 200 ms */ #define MAX_CONSECUTIVE_DTX 20 /* eq 400 ms */ #define DTX_ACTIVITY_THRESHOLD 0.1f /* VAD decision */ #define VAD_NO_DECISION -1 #define VAD_NO_ACTIVITY 0 #define VAD_ACTIVITY 1 /* Maximum sampling frequency */ #define MAX_FS_KHZ 16 #define MAX_API_FS_KHZ 48 /* Signal types */ #define TYPE_NO_VOICE_ACTIVITY 0 #define TYPE_UNVOICED 1 #define TYPE_VOICED 2 /* Conditional coding types */ #define CODE_INDEPENDENTLY 0 #define CODE_INDEPENDENTLY_NO_LTP_SCALING 1 #define CODE_CONDITIONALLY 2 /* Settings for stereo processing */ #define STEREO_QUANT_TAB_SIZE 16 #define STEREO_QUANT_SUB_STEPS 5 #define STEREO_INTERP_LEN_MS 8 /* must be even */ #define STEREO_RATIO_SMOOTH_COEF 0.01 /* smoothing coef for signal norms and stereo width */ /* Range of pitch lag estimates */ #define PITCH_EST_MIN_LAG_MS 2 /* 2 ms -> 500 Hz */ #define PITCH_EST_MAX_LAG_MS 18 /* 18 ms -> 56 Hz */ /* Maximum number of subframes */ #define MAX_NB_SUBFR 4 /* Number of samples per frame */ #define LTP_MEM_LENGTH_MS 20 #define SUB_FRAME_LENGTH_MS 5 #define MAX_SUB_FRAME_LENGTH ( SUB_FRAME_LENGTH_MS * MAX_FS_KHZ ) #define MAX_FRAME_LENGTH_MS ( SUB_FRAME_LENGTH_MS * MAX_NB_SUBFR ) #define MAX_FRAME_LENGTH ( MAX_FRAME_LENGTH_MS * MAX_FS_KHZ ) /* Milliseconds of lookahead for pitch analysis */ #define LA_PITCH_MS 2 #define LA_PITCH_MAX ( LA_PITCH_MS * MAX_FS_KHZ ) /* Order of LPC used in find pitch */ #define MAX_FIND_PITCH_LPC_ORDER 16 /* Length of LPC window used in find pitch */ #define FIND_PITCH_LPC_WIN_MS ( 20 + (LA_PITCH_MS << 1) ) #define FIND_PITCH_LPC_WIN_MS_2_SF ( 10 + (LA_PITCH_MS << 1) ) #define FIND_PITCH_LPC_WIN_MAX ( FIND_PITCH_LPC_WIN_MS * MAX_FS_KHZ ) /* Milliseconds of lookahead for noise shape analysis */ #define LA_SHAPE_MS 5 #define LA_SHAPE_MAX ( LA_SHAPE_MS * MAX_FS_KHZ ) /* Maximum length of LPC window used in noise shape analysis */ #define SHAPE_LPC_WIN_MAX ( 15 * MAX_FS_KHZ ) /* dB level of lowest gain quantization level */ #define MIN_QGAIN_DB 2 /* dB level of highest gain quantization level */ #define MAX_QGAIN_DB 88 /* Number of gain quantization levels */ #define N_LEVELS_QGAIN 64 /* Max increase in gain quantization index */ #define MAX_DELTA_GAIN_QUANT 36 /* Max decrease in gain quantization index */ #define MIN_DELTA_GAIN_QUANT -4 /* Quantization offsets (multiples of 4) */ #define OFFSET_VL_Q10 32 #define OFFSET_VH_Q10 100 #define OFFSET_UVL_Q10 100 #define OFFSET_UVH_Q10 240 #define QUANT_LEVEL_ADJUST_Q10 80 /* Maximum numbers of iterations used to stabilize an LPC vector */ #define MAX_LPC_STABILIZE_ITERATIONS 16 #define MAX_PREDICTION_POWER_GAIN 1e4f #define MAX_PREDICTION_POWER_GAIN_AFTER_RESET 1e2f #define MAX_LPC_ORDER 16 #define MIN_LPC_ORDER 10 /* Find Pred Coef defines */ #define LTP_ORDER 5 /* LTP quantization settings */ #define NB_LTP_CBKS 3 /* Flag to use harmonic noise shaping */ #define USE_HARM_SHAPING 1 /* Max LPC order of noise shaping filters */ #define MAX_SHAPE_LPC_ORDER 24 #define HARM_SHAPE_FIR_TAPS 3 /* Maximum number of delayed decision states */ #define MAX_DEL_DEC_STATES 4 #define LTP_BUF_LENGTH 512 #define LTP_MASK ( LTP_BUF_LENGTH - 1 ) #define DECISION_DELAY 40 /* Number of subframes for excitation entropy coding */ #define SHELL_CODEC_FRAME_LENGTH 16 #define LOG2_SHELL_CODEC_FRAME_LENGTH 4 #define MAX_NB_SHELL_BLOCKS ( MAX_FRAME_LENGTH / SHELL_CODEC_FRAME_LENGTH ) /* Number of rate levels, for entropy coding of excitation */ #define N_RATE_LEVELS 10 /* Maximum sum of pulses per shell coding frame */ #define SILK_MAX_PULSES 16 #define MAX_MATRIX_SIZE MAX_LPC_ORDER /* Max of LPC Order and LTP order */ # define NSQ_LPC_BUF_LENGTH MAX_LPC_ORDER /***************************/ /* Voice activity detector */ /***************************/ #define VAD_N_BANDS 4 #define VAD_INTERNAL_SUBFRAMES_LOG2 2 #define VAD_INTERNAL_SUBFRAMES ( 1 << VAD_INTERNAL_SUBFRAMES_LOG2 ) #define VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 1024 /* Must be < 4096 */ #define VAD_NOISE_LEVELS_BIAS 50 /* Sigmoid settings */ #define VAD_NEGATIVE_OFFSET_Q5 128 /* sigmoid is 0 at -128 */ #define VAD_SNR_FACTOR_Q16 45000 /* smoothing for SNR measurement */ #define VAD_SNR_SMOOTH_COEF_Q18 4096 /* Size of the piecewise linear cosine approximation table for the LSFs */ #define LSF_COS_TAB_SZ_FIX 128 /******************/ /* NLSF quantizer */ /******************/ #define NLSF_W_Q 2 #define NLSF_VQ_MAX_VECTORS 32 #define NLSF_QUANT_MAX_AMPLITUDE 4 #define NLSF_QUANT_MAX_AMPLITUDE_EXT 10 #define NLSF_QUANT_LEVEL_ADJ 0.1 #define NLSF_QUANT_DEL_DEC_STATES_LOG2 2 #define NLSF_QUANT_DEL_DEC_STATES ( 1 << NLSF_QUANT_DEL_DEC_STATES_LOG2 ) /* Transition filtering for mode switching */ #define TRANSITION_TIME_MS 5120 /* 5120 = 64 * FRAME_LENGTH_MS * ( TRANSITION_INT_NUM - 1 ) = 64*(20*4)*/ #define TRANSITION_NB 3 /* Hardcoded in tables */ #define TRANSITION_NA 2 /* Hardcoded in tables */ #define TRANSITION_INT_NUM 5 /* Hardcoded in tables */ #define TRANSITION_FRAMES ( TRANSITION_TIME_MS / MAX_FRAME_LENGTH_MS ) #define TRANSITION_INT_STEPS ( TRANSITION_FRAMES / ( TRANSITION_INT_NUM - 1 ) ) /* BWE factors to apply after packet loss */ #define BWE_AFTER_LOSS_Q16 63570 /* Defines for CN generation */ #define CNG_BUF_MASK_MAX 255 /* 2^floor(log2(MAX_FRAME_LENGTH))-1 */ #define CNG_GAIN_SMTH_Q16 4634 /* 0.25^(1/4) */ #define CNG_NLSF_SMTH_Q16 16348 /* 0.25 */ #ifdef __cplusplus } #endif #endif jamulus-3.9.1+dfsg/libs/opus/silk/tuning_parameters.h0000644000175000017500000001405714340334543021744 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SILK_TUNING_PARAMETERS_H #define SILK_TUNING_PARAMETERS_H #ifdef __cplusplus extern "C" { #endif /* Decay time for bitreservoir */ #define BITRESERVOIR_DECAY_TIME_MS 500 /*******************/ /* Pitch estimator */ /*******************/ /* Level of noise floor for whitening filter LPC analysis in pitch analysis */ #define FIND_PITCH_WHITE_NOISE_FRACTION 1e-3f /* Bandwidth expansion for whitening filter in pitch analysis */ #define FIND_PITCH_BANDWIDTH_EXPANSION 0.99f /*********************/ /* Linear prediction */ /*********************/ /* LPC analysis regularization */ #define FIND_LPC_COND_FAC 1e-5f /* Max cumulative LTP gain */ #define MAX_SUM_LOG_GAIN_DB 250.0f /* LTP analysis defines */ #define LTP_CORR_INV_MAX 0.03f /***********************/ /* High pass filtering */ /***********************/ /* Smoothing parameters for low end of pitch frequency range estimation */ #define VARIABLE_HP_SMTH_COEF1 0.1f #define VARIABLE_HP_SMTH_COEF2 0.015f #define VARIABLE_HP_MAX_DELTA_FREQ 0.4f /* Min and max cut-off frequency values (-3 dB points) */ #define VARIABLE_HP_MIN_CUTOFF_HZ 60 #define VARIABLE_HP_MAX_CUTOFF_HZ 100 /***********/ /* Various */ /***********/ /* VAD threshold */ #define SPEECH_ACTIVITY_DTX_THRES 0.05f /* Speech Activity LBRR enable threshold */ #define LBRR_SPEECH_ACTIVITY_THRES 0.3f /*************************/ /* Perceptual parameters */ /*************************/ /* reduction in coding SNR during low speech activity */ #define BG_SNR_DECR_dB 2.0f /* factor for reducing quantization noise during voiced speech */ #define HARM_SNR_INCR_dB 2.0f /* factor for reducing quantization noise for unvoiced sparse signals */ #define SPARSE_SNR_INCR_dB 2.0f /* threshold for sparseness measure above which to use lower quantization offset during unvoiced */ #define ENERGY_VARIATION_THRESHOLD_QNT_OFFSET 0.6f /* warping control */ #define WARPING_MULTIPLIER 0.015f /* fraction added to first autocorrelation value */ #define SHAPE_WHITE_NOISE_FRACTION 3e-5f /* noise shaping filter chirp factor */ #define BANDWIDTH_EXPANSION 0.94f /* harmonic noise shaping */ #define HARMONIC_SHAPING 0.3f /* extra harmonic noise shaping for high bitrates or noisy input */ #define HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING 0.2f /* parameter for shaping noise towards higher frequencies */ #define HP_NOISE_COEF 0.25f /* parameter for shaping noise even more towards higher frequencies during voiced speech */ #define HARM_HP_NOISE_COEF 0.35f /* parameter for applying a high-pass tilt to the input signal */ #define INPUT_TILT 0.05f /* parameter for extra high-pass tilt to the input signal at high rates */ #define HIGH_RATE_INPUT_TILT 0.1f /* parameter for reducing noise at the very low frequencies */ #define LOW_FREQ_SHAPING 4.0f /* less reduction of noise at the very low frequencies for signals with low SNR at low frequencies */ #define LOW_QUALITY_LOW_FREQ_SHAPING_DECR 0.5f /* subframe smoothing coefficient for HarmBoost, HarmShapeGain, Tilt (lower -> more smoothing) */ #define SUBFR_SMTH_COEF 0.4f /* parameters defining the R/D tradeoff in the residual quantizer */ #define LAMBDA_OFFSET 1.2f #define LAMBDA_SPEECH_ACT -0.2f #define LAMBDA_DELAYED_DECISIONS -0.05f #define LAMBDA_INPUT_QUALITY -0.1f #define LAMBDA_CODING_QUALITY -0.2f #define LAMBDA_QUANT_OFFSET 0.8f /* Compensation in bitrate calculations for 10 ms modes */ #define REDUCE_BITRATE_10_MS_BPS 2200 /* Maximum time before allowing a bandwidth transition */ #define MAX_BANDWIDTH_SWITCH_DELAY_MS 5000 #ifdef __cplusplus } #endif #endif /* SILK_TUNING_PARAMETERS_H */ jamulus-3.9.1+dfsg/libs/opus/silk/VQ_WMat_EC.c0000644000175000017500000001574214340334543020037 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" /* Entropy constrained matrix-weighted VQ, hard-coded to 5-element vectors, for a single input data vector */ void silk_VQ_WMat_EC_c( opus_int8 *ind, /* O index of best codebook vector */ opus_int32 *res_nrg_Q15, /* O best residual energy */ opus_int32 *rate_dist_Q8, /* O best total bitrate */ opus_int *gain_Q7, /* O sum of absolute LTP coefficients */ const opus_int32 *XX_Q17, /* I correlation matrix */ const opus_int32 *xX_Q17, /* I correlation vector */ const opus_int8 *cb_Q7, /* I codebook */ const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */ const opus_uint8 *cl_Q5, /* I code length for each codebook vector */ const opus_int subfr_len, /* I number of samples per subframe */ const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */ const opus_int L /* I number of vectors in codebook */ ) { opus_int k, gain_tmp_Q7; const opus_int8 *cb_row_Q7; opus_int32 neg_xX_Q24[ 5 ]; opus_int32 sum1_Q15, sum2_Q24; opus_int32 bits_res_Q8, bits_tot_Q8; /* Negate and convert to new Q domain */ neg_xX_Q24[ 0 ] = -silk_LSHIFT32( xX_Q17[ 0 ], 7 ); neg_xX_Q24[ 1 ] = -silk_LSHIFT32( xX_Q17[ 1 ], 7 ); neg_xX_Q24[ 2 ] = -silk_LSHIFT32( xX_Q17[ 2 ], 7 ); neg_xX_Q24[ 3 ] = -silk_LSHIFT32( xX_Q17[ 3 ], 7 ); neg_xX_Q24[ 4 ] = -silk_LSHIFT32( xX_Q17[ 4 ], 7 ); /* Loop over codebook */ *rate_dist_Q8 = silk_int32_MAX; *res_nrg_Q15 = silk_int32_MAX; cb_row_Q7 = cb_Q7; /* In things go really bad, at least *ind is set to something safe. */ *ind = 0; for( k = 0; k < L; k++ ) { opus_int32 penalty; gain_tmp_Q7 = cb_gain_Q7[k]; /* Weighted rate */ /* Quantization error: 1 - 2 * xX * cb + cb' * XX * cb */ sum1_Q15 = SILK_FIX_CONST( 1.001, 15 ); /* Penalty for too large gain */ penalty = silk_LSHIFT32( silk_max( silk_SUB32( gain_tmp_Q7, max_gain_Q7 ), 0 ), 11 ); /* first row of XX_Q17 */ sum2_Q24 = silk_MLA( neg_xX_Q24[ 0 ], XX_Q17[ 1 ], cb_row_Q7[ 1 ] ); sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 2 ], cb_row_Q7[ 2 ] ); sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 3 ], cb_row_Q7[ 3 ] ); sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 4 ], cb_row_Q7[ 4 ] ); sum2_Q24 = silk_LSHIFT32( sum2_Q24, 1 ); sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 0 ], cb_row_Q7[ 0 ] ); sum1_Q15 = silk_SMLAWB( sum1_Q15, sum2_Q24, cb_row_Q7[ 0 ] ); /* second row of XX_Q17 */ sum2_Q24 = silk_MLA( neg_xX_Q24[ 1 ], XX_Q17[ 7 ], cb_row_Q7[ 2 ] ); sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 8 ], cb_row_Q7[ 3 ] ); sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 9 ], cb_row_Q7[ 4 ] ); sum2_Q24 = silk_LSHIFT32( sum2_Q24, 1 ); sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 6 ], cb_row_Q7[ 1 ] ); sum1_Q15 = silk_SMLAWB( sum1_Q15, sum2_Q24, cb_row_Q7[ 1 ] ); /* third row of XX_Q17 */ sum2_Q24 = silk_MLA( neg_xX_Q24[ 2 ], XX_Q17[ 13 ], cb_row_Q7[ 3 ] ); sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 14 ], cb_row_Q7[ 4 ] ); sum2_Q24 = silk_LSHIFT32( sum2_Q24, 1 ); sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 12 ], cb_row_Q7[ 2 ] ); sum1_Q15 = silk_SMLAWB( sum1_Q15, sum2_Q24, cb_row_Q7[ 2 ] ); /* fourth row of XX_Q17 */ sum2_Q24 = silk_MLA( neg_xX_Q24[ 3 ], XX_Q17[ 19 ], cb_row_Q7[ 4 ] ); sum2_Q24 = silk_LSHIFT32( sum2_Q24, 1 ); sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 18 ], cb_row_Q7[ 3 ] ); sum1_Q15 = silk_SMLAWB( sum1_Q15, sum2_Q24, cb_row_Q7[ 3 ] ); /* last row of XX_Q17 */ sum2_Q24 = silk_LSHIFT32( neg_xX_Q24[ 4 ], 1 ); sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 24 ], cb_row_Q7[ 4 ] ); sum1_Q15 = silk_SMLAWB( sum1_Q15, sum2_Q24, cb_row_Q7[ 4 ] ); /* find best */ if( sum1_Q15 >= 0 ) { /* Translate residual energy to bits using high-rate assumption (6 dB ==> 1 bit/sample) */ bits_res_Q8 = silk_SMULBB( subfr_len, silk_lin2log( sum1_Q15 + penalty) - (15 << 7) ); /* In the following line we reduce the codelength component by half ("-1"); seems to slghtly improve quality */ bits_tot_Q8 = silk_ADD_LSHIFT32( bits_res_Q8, cl_Q5[ k ], 3-1 ); if( bits_tot_Q8 <= *rate_dist_Q8 ) { *rate_dist_Q8 = bits_tot_Q8; *res_nrg_Q15 = sum1_Q15 + penalty; *ind = (opus_int8)k; *gain_Q7 = gain_tmp_Q7; } } /* Go to next cbk vector */ cb_row_Q7 += LTP_ORDER; } } jamulus-3.9.1+dfsg/libs/opus/silk/errors.h0000644000175000017500000000707014340334543017526 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SILK_ERRORS_H #define SILK_ERRORS_H #ifdef __cplusplus extern "C" { #endif /******************/ /* Error messages */ /******************/ #define SILK_NO_ERROR 0 /**************************/ /* Encoder error messages */ /**************************/ /* Input length is not a multiple of 10 ms, or length is longer than the packet length */ #define SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES -101 /* Sampling frequency not 8000, 12000 or 16000 Hertz */ #define SILK_ENC_FS_NOT_SUPPORTED -102 /* Packet size not 10, 20, 40, or 60 ms */ #define SILK_ENC_PACKET_SIZE_NOT_SUPPORTED -103 /* Allocated payload buffer too short */ #define SILK_ENC_PAYLOAD_BUF_TOO_SHORT -104 /* Loss rate not between 0 and 100 percent */ #define SILK_ENC_INVALID_LOSS_RATE -105 /* Complexity setting not valid, use 0...10 */ #define SILK_ENC_INVALID_COMPLEXITY_SETTING -106 /* Inband FEC setting not valid, use 0 or 1 */ #define SILK_ENC_INVALID_INBAND_FEC_SETTING -107 /* DTX setting not valid, use 0 or 1 */ #define SILK_ENC_INVALID_DTX_SETTING -108 /* CBR setting not valid, use 0 or 1 */ #define SILK_ENC_INVALID_CBR_SETTING -109 /* Internal encoder error */ #define SILK_ENC_INTERNAL_ERROR -110 /* Internal encoder error */ #define SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR -111 /**************************/ /* Decoder error messages */ /**************************/ /* Output sampling frequency lower than internal decoded sampling frequency */ #define SILK_DEC_INVALID_SAMPLING_FREQUENCY -200 /* Payload size exceeded the maximum allowed 1024 bytes */ #define SILK_DEC_PAYLOAD_TOO_LARGE -201 /* Payload has bit errors */ #define SILK_DEC_PAYLOAD_ERROR -202 /* Payload has bit errors */ #define SILK_DEC_INVALID_FRAME_SIZE -203 #ifdef __cplusplus } #endif #endif jamulus-3.9.1+dfsg/libs/opus/silk/SigProc_FIX.h0000644000175000017500000011451114340334543020265 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SILK_SIGPROC_FIX_H #define SILK_SIGPROC_FIX_H #ifdef __cplusplus extern "C" { #endif /*#define silk_MACRO_COUNT */ /* Used to enable WMOPS counting */ #define SILK_MAX_ORDER_LPC 24 /* max order of the LPC analysis in schur() and k2a() */ #include /* for memset(), memcpy(), memmove() */ #include "typedef.h" #include "resampler_structs.h" #include "macros.h" #include "cpu_support.h" #if defined(OPUS_X86_MAY_HAVE_SSE4_1) #include "x86/SigProc_FIX_sse.h" #endif #if (defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)) #include "arm/biquad_alt_arm.h" #include "arm/LPC_inv_pred_gain_arm.h" #endif /********************************************************************/ /* SIGNAL PROCESSING FUNCTIONS */ /********************************************************************/ /*! * Initialize/reset the resampler state for a given pair of input/output sampling rates */ opus_int silk_resampler_init( silk_resampler_state_struct *S, /* I/O Resampler state */ opus_int32 Fs_Hz_in, /* I Input sampling rate (Hz) */ opus_int32 Fs_Hz_out, /* I Output sampling rate (Hz) */ opus_int forEnc /* I If 1: encoder; if 0: decoder */ ); /*! * Resampler: convert from one sampling rate to another */ opus_int silk_resampler( silk_resampler_state_struct *S, /* I/O Resampler state */ opus_int16 out[], /* O Output signal */ const opus_int16 in[], /* I Input signal */ opus_int32 inLen /* I Number of input samples */ ); /*! * Downsample 2x, mediocre quality */ void silk_resampler_down2( opus_int32 *S, /* I/O State vector [ 2 ] */ opus_int16 *out, /* O Output signal [ len ] */ const opus_int16 *in, /* I Input signal [ floor(len/2) ] */ opus_int32 inLen /* I Number of input samples */ ); /*! * Downsample by a factor 2/3, low quality */ void silk_resampler_down2_3( opus_int32 *S, /* I/O State vector [ 6 ] */ opus_int16 *out, /* O Output signal [ floor(2*inLen/3) ] */ const opus_int16 *in, /* I Input signal [ inLen ] */ opus_int32 inLen /* I Number of input samples */ ); /*! * second order ARMA filter; * slower than biquad() but uses more precise coefficients * can handle (slowly) varying coefficients */ void silk_biquad_alt_stride1( const opus_int16 *in, /* I input signal */ const opus_int32 *B_Q28, /* I MA coefficients [3] */ const opus_int32 *A_Q28, /* I AR coefficients [2] */ opus_int32 *S, /* I/O State vector [2] */ opus_int16 *out, /* O output signal */ const opus_int32 len /* I signal length (must be even) */ ); void silk_biquad_alt_stride2_c( const opus_int16 *in, /* I input signal */ const opus_int32 *B_Q28, /* I MA coefficients [3] */ const opus_int32 *A_Q28, /* I AR coefficients [2] */ opus_int32 *S, /* I/O State vector [4] */ opus_int16 *out, /* O output signal */ const opus_int32 len /* I signal length (must be even) */ ); /* Variable order MA prediction error filter. */ void silk_LPC_analysis_filter( opus_int16 *out, /* O Output signal */ const opus_int16 *in, /* I Input signal */ const opus_int16 *B, /* I MA prediction coefficients, Q12 [order] */ const opus_int32 len, /* I Signal length */ const opus_int32 d, /* I Filter order */ int arch /* I Run-time architecture */ ); /* Chirp (bandwidth expand) LP AR filter */ void silk_bwexpander( opus_int16 *ar, /* I/O AR filter to be expanded (without leading 1) */ const opus_int d, /* I Length of ar */ opus_int32 chirp_Q16 /* I Chirp factor (typically in the range 0 to 1) */ ); /* Chirp (bandwidth expand) LP AR filter */ void silk_bwexpander_32( opus_int32 *ar, /* I/O AR filter to be expanded (without leading 1) */ const opus_int d, /* I Length of ar */ opus_int32 chirp_Q16 /* I Chirp factor in Q16 */ ); /* Compute inverse of LPC prediction gain, and */ /* test if LPC coefficients are stable (all poles within unit circle) */ opus_int32 silk_LPC_inverse_pred_gain_c( /* O Returns inverse prediction gain in energy domain, Q30 */ const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */ const opus_int order /* I Prediction order */ ); /* Split signal in two decimated bands using first-order allpass filters */ void silk_ana_filt_bank_1( const opus_int16 *in, /* I Input signal [N] */ opus_int32 *S, /* I/O State vector [2] */ opus_int16 *outL, /* O Low band [N/2] */ opus_int16 *outH, /* O High band [N/2] */ const opus_int32 N /* I Number of input samples */ ); #if !defined(OVERRIDE_silk_biquad_alt_stride2) #define silk_biquad_alt_stride2(in, B_Q28, A_Q28, S, out, len, arch) ((void)(arch), silk_biquad_alt_stride2_c(in, B_Q28, A_Q28, S, out, len)) #endif #if !defined(OVERRIDE_silk_LPC_inverse_pred_gain) #define silk_LPC_inverse_pred_gain(A_Q12, order, arch) ((void)(arch), silk_LPC_inverse_pred_gain_c(A_Q12, order)) #endif /********************************************************************/ /* SCALAR FUNCTIONS */ /********************************************************************/ /* Approximation of 128 * log2() (exact inverse of approx 2^() below) */ /* Convert input to a log scale */ opus_int32 silk_lin2log( const opus_int32 inLin /* I input in linear scale */ ); /* Approximation of a sigmoid function */ opus_int silk_sigm_Q15( opus_int in_Q5 /* I */ ); /* Approximation of 2^() (exact inverse of approx log2() above) */ /* Convert input to a linear scale */ opus_int32 silk_log2lin( const opus_int32 inLog_Q7 /* I input on log scale */ ); /* Compute number of bits to right shift the sum of squares of a vector */ /* of int16s to make it fit in an int32 */ void silk_sum_sqr_shift( opus_int32 *energy, /* O Energy of x, after shifting to the right */ opus_int *shift, /* O Number of bits right shift applied to energy */ const opus_int16 *x, /* I Input vector */ opus_int len /* I Length of input vector */ ); /* Calculates the reflection coefficients from the correlation sequence */ /* Faster than schur64(), but much less accurate. */ /* uses SMLAWB(), requiring armv5E and higher. */ opus_int32 silk_schur( /* O Returns residual energy */ opus_int16 *rc_Q15, /* O reflection coefficients [order] Q15 */ const opus_int32 *c, /* I correlations [order+1] */ const opus_int32 order /* I prediction order */ ); /* Calculates the reflection coefficients from the correlation sequence */ /* Slower than schur(), but more accurate. */ /* Uses SMULL(), available on armv4 */ opus_int32 silk_schur64( /* O returns residual energy */ opus_int32 rc_Q16[], /* O Reflection coefficients [order] Q16 */ const opus_int32 c[], /* I Correlations [order+1] */ opus_int32 order /* I Prediction order */ ); /* Step up function, converts reflection coefficients to prediction coefficients */ void silk_k2a( opus_int32 *A_Q24, /* O Prediction coefficients [order] Q24 */ const opus_int16 *rc_Q15, /* I Reflection coefficients [order] Q15 */ const opus_int32 order /* I Prediction order */ ); /* Step up function, converts reflection coefficients to prediction coefficients */ void silk_k2a_Q16( opus_int32 *A_Q24, /* O Prediction coefficients [order] Q24 */ const opus_int32 *rc_Q16, /* I Reflection coefficients [order] Q16 */ const opus_int32 order /* I Prediction order */ ); /* Apply sine window to signal vector. */ /* Window types: */ /* 1 -> sine window from 0 to pi/2 */ /* 2 -> sine window from pi/2 to pi */ /* every other sample of window is linearly interpolated, for speed */ void silk_apply_sine_window( opus_int16 px_win[], /* O Pointer to windowed signal */ const opus_int16 px[], /* I Pointer to input signal */ const opus_int win_type, /* I Selects a window type */ const opus_int length /* I Window length, multiple of 4 */ ); /* Compute autocorrelation */ void silk_autocorr( opus_int32 *results, /* O Result (length correlationCount) */ opus_int *scale, /* O Scaling of the correlation vector */ const opus_int16 *inputData, /* I Input data to correlate */ const opus_int inputDataSize, /* I Length of input */ const opus_int correlationCount, /* I Number of correlation taps to compute */ int arch /* I Run-time architecture */ ); void silk_decode_pitch( opus_int16 lagIndex, /* I */ opus_int8 contourIndex, /* O */ opus_int pitch_lags[], /* O 4 pitch values */ const opus_int Fs_kHz, /* I sampling frequency (kHz) */ const opus_int nb_subfr /* I number of sub frames */ ); opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 voiced, 1 unvoiced */ const opus_int16 *frame, /* I Signal of length PE_FRAME_LENGTH_MS*Fs_kHz */ opus_int *pitch_out, /* O 4 pitch lag values */ opus_int16 *lagIndex, /* O Lag Index */ opus_int8 *contourIndex, /* O Pitch contour Index */ opus_int *LTPCorr_Q15, /* I/O Normalized correlation; input: value from previous frame */ opus_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */ const opus_int32 search_thres1_Q16, /* I First stage threshold for lag candidates 0 - 1 */ const opus_int search_thres2_Q13, /* I Final threshold for lag candidates 0 - 1 */ const opus_int Fs_kHz, /* I Sample frequency (kHz) */ const opus_int complexity, /* I Complexity setting, 0-2, where 2 is highest */ const opus_int nb_subfr, /* I number of 5 ms subframes */ int arch /* I Run-time architecture */ ); /* Compute Normalized Line Spectral Frequencies (NLSFs) from whitening filter coefficients */ /* If not all roots are found, the a_Q16 coefficients are bandwidth expanded until convergence. */ void silk_A2NLSF( opus_int16 *NLSF, /* O Normalized Line Spectral Frequencies in Q15 (0..2^15-1) [d] */ opus_int32 *a_Q16, /* I/O Monic whitening filter coefficients in Q16 [d] */ const opus_int d /* I Filter order (must be even) */ ); /* compute whitening filter coefficients from normalized line spectral frequencies */ void silk_NLSF2A( opus_int16 *a_Q12, /* O monic whitening filter coefficients in Q12, [ d ] */ const opus_int16 *NLSF, /* I normalized line spectral frequencies in Q15, [ d ] */ const opus_int d, /* I filter order (should be even) */ int arch /* I Run-time architecture */ ); /* Convert int32 coefficients to int16 coefs and make sure there's no wrap-around */ void silk_LPC_fit( opus_int16 *a_QOUT, /* O Output signal */ opus_int32 *a_QIN, /* I/O Input signal */ const opus_int QOUT, /* I Input Q domain */ const opus_int QIN, /* I Input Q domain */ const opus_int d /* I Filter order */ ); void silk_insertion_sort_increasing( opus_int32 *a, /* I/O Unsorted / Sorted vector */ opus_int *idx, /* O Index vector for the sorted elements */ const opus_int L, /* I Vector length */ const opus_int K /* I Number of correctly sorted positions */ ); void silk_insertion_sort_decreasing_int16( opus_int16 *a, /* I/O Unsorted / Sorted vector */ opus_int *idx, /* O Index vector for the sorted elements */ const opus_int L, /* I Vector length */ const opus_int K /* I Number of correctly sorted positions */ ); void silk_insertion_sort_increasing_all_values_int16( opus_int16 *a, /* I/O Unsorted / Sorted vector */ const opus_int L /* I Vector length */ ); /* NLSF stabilizer, for a single input data vector */ void silk_NLSF_stabilize( opus_int16 *NLSF_Q15, /* I/O Unstable/stabilized normalized LSF vector in Q15 [L] */ const opus_int16 *NDeltaMin_Q15, /* I Min distance vector, NDeltaMin_Q15[L] must be >= 1 [L+1] */ const opus_int L /* I Number of NLSF parameters in the input vector */ ); /* Laroia low complexity NLSF weights */ void silk_NLSF_VQ_weights_laroia( opus_int16 *pNLSFW_Q_OUT, /* O Pointer to input vector weights [D] */ const opus_int16 *pNLSF_Q15, /* I Pointer to input vector [D] */ const opus_int D /* I Input vector dimension (even) */ ); /* Compute reflection coefficients from input signal */ void silk_burg_modified_c( opus_int32 *res_nrg, /* O Residual energy */ opus_int *res_nrg_Q, /* O Residual energy Q value */ opus_int32 A_Q16[], /* O Prediction coefficients (length order) */ const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */ const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */ const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */ const opus_int nb_subfr, /* I Number of subframes stacked in x */ const opus_int D, /* I Order */ int arch /* I Run-time architecture */ ); /* Copy and multiply a vector by a constant */ void silk_scale_copy_vector16( opus_int16 *data_out, const opus_int16 *data_in, opus_int32 gain_Q16, /* I Gain in Q16 */ const opus_int dataSize /* I Length */ ); /* Some for the LTP related function requires Q26 to work.*/ void silk_scale_vector32_Q26_lshift_18( opus_int32 *data1, /* I/O Q0/Q18 */ opus_int32 gain_Q26, /* I Q26 */ opus_int dataSize /* I length */ ); /********************************************************************/ /* INLINE ARM MATH */ /********************************************************************/ /* return sum( inVec1[i] * inVec2[i] ) */ opus_int32 silk_inner_prod_aligned( const opus_int16 *const inVec1, /* I input vector 1 */ const opus_int16 *const inVec2, /* I input vector 2 */ const opus_int len, /* I vector lengths */ int arch /* I Run-time architecture */ ); opus_int32 silk_inner_prod_aligned_scale( const opus_int16 *const inVec1, /* I input vector 1 */ const opus_int16 *const inVec2, /* I input vector 2 */ const opus_int scale, /* I number of bits to shift */ const opus_int len /* I vector lengths */ ); opus_int64 silk_inner_prod16_aligned_64_c( const opus_int16 *inVec1, /* I input vector 1 */ const opus_int16 *inVec2, /* I input vector 2 */ const opus_int len /* I vector lengths */ ); /********************************************************************/ /* MACROS */ /********************************************************************/ /* Rotate a32 right by 'rot' bits. Negative rot values result in rotating left. Output is 32bit int. Note: contemporary compilers recognize the C expression below and compile it into a 'ror' instruction if available. No need for OPUS_INLINE ASM! */ static OPUS_INLINE opus_int32 silk_ROR32( opus_int32 a32, opus_int rot ) { opus_uint32 x = (opus_uint32) a32; opus_uint32 r = (opus_uint32) rot; opus_uint32 m = (opus_uint32) -rot; if( rot == 0 ) { return a32; } else if( rot < 0 ) { return (opus_int32) ((x << m) | (x >> (32 - m))); } else { return (opus_int32) ((x << (32 - r)) | (x >> r)); } } /* Allocate opus_int16 aligned to 4-byte memory address */ #if EMBEDDED_ARM #define silk_DWORD_ALIGN __attribute__((aligned(4))) #else #define silk_DWORD_ALIGN #endif /* Useful Macros that can be adjusted to other platforms */ #define silk_memcpy(dest, src, size) memcpy((dest), (src), (size)) #define silk_memset(dest, src, size) memset((dest), (src), (size)) #define silk_memmove(dest, src, size) memmove((dest), (src), (size)) /* Fixed point macros */ /* (a32 * b32) output have to be 32bit int */ #define silk_MUL(a32, b32) ((a32) * (b32)) /* (a32 * b32) output have to be 32bit uint */ #define silk_MUL_uint(a32, b32) silk_MUL(a32, b32) /* a32 + (b32 * c32) output have to be 32bit int */ #define silk_MLA(a32, b32, c32) silk_ADD32((a32),((b32) * (c32))) /* a32 + (b32 * c32) output have to be 32bit uint */ #define silk_MLA_uint(a32, b32, c32) silk_MLA(a32, b32, c32) /* ((a32 >> 16) * (b32 >> 16)) output have to be 32bit int */ #define silk_SMULTT(a32, b32) (((a32) >> 16) * ((b32) >> 16)) /* a32 + ((a32 >> 16) * (b32 >> 16)) output have to be 32bit int */ #define silk_SMLATT(a32, b32, c32) silk_ADD32((a32),((b32) >> 16) * ((c32) >> 16)) #define silk_SMLALBB(a64, b16, c16) silk_ADD64((a64),(opus_int64)((opus_int32)(b16) * (opus_int32)(c16))) /* (a32 * b32) */ #define silk_SMULL(a32, b32) ((opus_int64)(a32) * /*(opus_int64)*/(b32)) /* Adds two signed 32-bit values in a way that can overflow, while not relying on undefined behaviour (just standard two's complement implementation-specific behaviour) */ #define silk_ADD32_ovflw(a, b) ((opus_int32)((opus_uint32)(a) + (opus_uint32)(b))) /* Subtractss two signed 32-bit values in a way that can overflow, while not relying on undefined behaviour (just standard two's complement implementation-specific behaviour) */ #define silk_SUB32_ovflw(a, b) ((opus_int32)((opus_uint32)(a) - (opus_uint32)(b))) /* Multiply-accumulate macros that allow overflow in the addition (ie, no asserts in debug mode) */ #define silk_MLA_ovflw(a32, b32, c32) silk_ADD32_ovflw((a32), (opus_uint32)(b32) * (opus_uint32)(c32)) #define silk_SMLABB_ovflw(a32, b32, c32) (silk_ADD32_ovflw((a32) , ((opus_int32)((opus_int16)(b32))) * (opus_int32)((opus_int16)(c32)))) #define silk_DIV32_16(a32, b16) ((opus_int32)((a32) / (b16))) #define silk_DIV32(a32, b32) ((opus_int32)((a32) / (b32))) /* These macros enables checking for overflow in silk_API_Debug.h*/ #define silk_ADD16(a, b) ((a) + (b)) #define silk_ADD32(a, b) ((a) + (b)) #define silk_ADD64(a, b) ((a) + (b)) #define silk_SUB16(a, b) ((a) - (b)) #define silk_SUB32(a, b) ((a) - (b)) #define silk_SUB64(a, b) ((a) - (b)) #define silk_SAT8(a) ((a) > silk_int8_MAX ? silk_int8_MAX : \ ((a) < silk_int8_MIN ? silk_int8_MIN : (a))) #define silk_SAT16(a) ((a) > silk_int16_MAX ? silk_int16_MAX : \ ((a) < silk_int16_MIN ? silk_int16_MIN : (a))) #define silk_SAT32(a) ((a) > silk_int32_MAX ? silk_int32_MAX : \ ((a) < silk_int32_MIN ? silk_int32_MIN : (a))) #define silk_CHECK_FIT8(a) (a) #define silk_CHECK_FIT16(a) (a) #define silk_CHECK_FIT32(a) (a) #define silk_ADD_SAT16(a, b) (opus_int16)silk_SAT16( silk_ADD32( (opus_int32)(a), (b) ) ) #define silk_ADD_SAT64(a, b) ((((a) + (b)) & 0x8000000000000000LL) == 0 ? \ ((((a) & (b)) & 0x8000000000000000LL) != 0 ? silk_int64_MIN : (a)+(b)) : \ ((((a) | (b)) & 0x8000000000000000LL) == 0 ? silk_int64_MAX : (a)+(b)) ) #define silk_SUB_SAT16(a, b) (opus_int16)silk_SAT16( silk_SUB32( (opus_int32)(a), (b) ) ) #define silk_SUB_SAT64(a, b) ((((a)-(b)) & 0x8000000000000000LL) == 0 ? \ (( (a) & ((b)^0x8000000000000000LL) & 0x8000000000000000LL) ? silk_int64_MIN : (a)-(b)) : \ ((((a)^0x8000000000000000LL) & (b) & 0x8000000000000000LL) ? silk_int64_MAX : (a)-(b)) ) /* Saturation for positive input values */ #define silk_POS_SAT32(a) ((a) > silk_int32_MAX ? silk_int32_MAX : (a)) /* Add with saturation for positive input values */ #define silk_ADD_POS_SAT8(a, b) ((((a)+(b)) & 0x80) ? silk_int8_MAX : ((a)+(b))) #define silk_ADD_POS_SAT16(a, b) ((((a)+(b)) & 0x8000) ? silk_int16_MAX : ((a)+(b))) #define silk_ADD_POS_SAT32(a, b) ((((opus_uint32)(a)+(opus_uint32)(b)) & 0x80000000) ? silk_int32_MAX : ((a)+(b))) #define silk_LSHIFT8(a, shift) ((opus_int8)((opus_uint8)(a)<<(shift))) /* shift >= 0, shift < 8 */ #define silk_LSHIFT16(a, shift) ((opus_int16)((opus_uint16)(a)<<(shift))) /* shift >= 0, shift < 16 */ #define silk_LSHIFT32(a, shift) ((opus_int32)((opus_uint32)(a)<<(shift))) /* shift >= 0, shift < 32 */ #define silk_LSHIFT64(a, shift) ((opus_int64)((opus_uint64)(a)<<(shift))) /* shift >= 0, shift < 64 */ #define silk_LSHIFT(a, shift) silk_LSHIFT32(a, shift) /* shift >= 0, shift < 32 */ #define silk_RSHIFT8(a, shift) ((a)>>(shift)) /* shift >= 0, shift < 8 */ #define silk_RSHIFT16(a, shift) ((a)>>(shift)) /* shift >= 0, shift < 16 */ #define silk_RSHIFT32(a, shift) ((a)>>(shift)) /* shift >= 0, shift < 32 */ #define silk_RSHIFT64(a, shift) ((a)>>(shift)) /* shift >= 0, shift < 64 */ #define silk_RSHIFT(a, shift) silk_RSHIFT32(a, shift) /* shift >= 0, shift < 32 */ /* saturates before shifting */ #define silk_LSHIFT_SAT32(a, shift) (silk_LSHIFT32( silk_LIMIT( (a), silk_RSHIFT32( silk_int32_MIN, (shift) ), \ silk_RSHIFT32( silk_int32_MAX, (shift) ) ), (shift) )) #define silk_LSHIFT_ovflw(a, shift) ((opus_int32)((opus_uint32)(a) << (shift))) /* shift >= 0, allowed to overflow */ #define silk_LSHIFT_uint(a, shift) ((a) << (shift)) /* shift >= 0 */ #define silk_RSHIFT_uint(a, shift) ((a) >> (shift)) /* shift >= 0 */ #define silk_ADD_LSHIFT(a, b, shift) ((a) + silk_LSHIFT((b), (shift))) /* shift >= 0 */ #define silk_ADD_LSHIFT32(a, b, shift) silk_ADD32((a), silk_LSHIFT32((b), (shift))) /* shift >= 0 */ #define silk_ADD_LSHIFT_uint(a, b, shift) ((a) + silk_LSHIFT_uint((b), (shift))) /* shift >= 0 */ #define silk_ADD_RSHIFT(a, b, shift) ((a) + silk_RSHIFT((b), (shift))) /* shift >= 0 */ #define silk_ADD_RSHIFT32(a, b, shift) silk_ADD32((a), silk_RSHIFT32((b), (shift))) /* shift >= 0 */ #define silk_ADD_RSHIFT_uint(a, b, shift) ((a) + silk_RSHIFT_uint((b), (shift))) /* shift >= 0 */ #define silk_SUB_LSHIFT32(a, b, shift) silk_SUB32((a), silk_LSHIFT32((b), (shift))) /* shift >= 0 */ #define silk_SUB_RSHIFT32(a, b, shift) silk_SUB32((a), silk_RSHIFT32((b), (shift))) /* shift >= 0 */ /* Requires that shift > 0 */ #define silk_RSHIFT_ROUND(a, shift) ((shift) == 1 ? ((a) >> 1) + ((a) & 1) : (((a) >> ((shift) - 1)) + 1) >> 1) #define silk_RSHIFT_ROUND64(a, shift) ((shift) == 1 ? ((a) >> 1) + ((a) & 1) : (((a) >> ((shift) - 1)) + 1) >> 1) /* Number of rightshift required to fit the multiplication */ #define silk_NSHIFT_MUL_32_32(a, b) ( -(31- (32-silk_CLZ32(silk_abs(a)) + (32-silk_CLZ32(silk_abs(b))))) ) #define silk_NSHIFT_MUL_16_16(a, b) ( -(15- (16-silk_CLZ16(silk_abs(a)) + (16-silk_CLZ16(silk_abs(b))))) ) #define silk_min(a, b) (((a) < (b)) ? (a) : (b)) #define silk_max(a, b) (((a) > (b)) ? (a) : (b)) /* Macro to convert floating-point constants to fixed-point */ #define SILK_FIX_CONST( C, Q ) ((opus_int32)((C) * ((opus_int64)1 << (Q)) + 0.5)) /* silk_min() versions with typecast in the function call */ static OPUS_INLINE opus_int silk_min_int(opus_int a, opus_int b) { return (((a) < (b)) ? (a) : (b)); } static OPUS_INLINE opus_int16 silk_min_16(opus_int16 a, opus_int16 b) { return (((a) < (b)) ? (a) : (b)); } static OPUS_INLINE opus_int32 silk_min_32(opus_int32 a, opus_int32 b) { return (((a) < (b)) ? (a) : (b)); } static OPUS_INLINE opus_int64 silk_min_64(opus_int64 a, opus_int64 b) { return (((a) < (b)) ? (a) : (b)); } /* silk_min() versions with typecast in the function call */ static OPUS_INLINE opus_int silk_max_int(opus_int a, opus_int b) { return (((a) > (b)) ? (a) : (b)); } static OPUS_INLINE opus_int16 silk_max_16(opus_int16 a, opus_int16 b) { return (((a) > (b)) ? (a) : (b)); } static OPUS_INLINE opus_int32 silk_max_32(opus_int32 a, opus_int32 b) { return (((a) > (b)) ? (a) : (b)); } static OPUS_INLINE opus_int64 silk_max_64(opus_int64 a, opus_int64 b) { return (((a) > (b)) ? (a) : (b)); } #define silk_LIMIT( a, limit1, limit2) ((limit1) > (limit2) ? ((a) > (limit1) ? (limit1) : ((a) < (limit2) ? (limit2) : (a))) \ : ((a) > (limit2) ? (limit2) : ((a) < (limit1) ? (limit1) : (a)))) #define silk_LIMIT_int silk_LIMIT #define silk_LIMIT_16 silk_LIMIT #define silk_LIMIT_32 silk_LIMIT #define silk_abs(a) (((a) > 0) ? (a) : -(a)) /* Be careful, silk_abs returns wrong when input equals to silk_intXX_MIN */ #define silk_abs_int(a) (((a) ^ ((a) >> (8 * sizeof(a) - 1))) - ((a) >> (8 * sizeof(a) - 1))) #define silk_abs_int32(a) (((a) ^ ((a) >> 31)) - ((a) >> 31)) #define silk_abs_int64(a) (((a) > 0) ? (a) : -(a)) #define silk_sign(a) ((a) > 0 ? 1 : ( (a) < 0 ? -1 : 0 )) /* PSEUDO-RANDOM GENERATOR */ /* Make sure to store the result as the seed for the next call (also in between */ /* frames), otherwise result won't be random at all. When only using some of the */ /* bits, take the most significant bits by right-shifting. */ #define RAND_MULTIPLIER 196314165 #define RAND_INCREMENT 907633515 #define silk_RAND(seed) (silk_MLA_ovflw((RAND_INCREMENT), (seed), (RAND_MULTIPLIER))) /* Add some multiplication functions that can be easily mapped to ARM. */ /* silk_SMMUL: Signed top word multiply. ARMv6 2 instruction cycles. ARMv3M+ 3 instruction cycles. use SMULL and ignore LSB registers.(except xM)*/ /*#define silk_SMMUL(a32, b32) (opus_int32)silk_RSHIFT(silk_SMLAL(silk_SMULWB((a32), (b32)), (a32), silk_RSHIFT_ROUND((b32), 16)), 16)*/ /* the following seems faster on x86 */ #define silk_SMMUL(a32, b32) (opus_int32)silk_RSHIFT64(silk_SMULL((a32), (b32)), 32) #if !defined(OPUS_X86_MAY_HAVE_SSE4_1) #define silk_burg_modified(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch) \ ((void)(arch), silk_burg_modified_c(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch)) #define silk_inner_prod16_aligned_64(inVec1, inVec2, len, arch) \ ((void)(arch),silk_inner_prod16_aligned_64_c(inVec1, inVec2, len)) #endif #include "Inlines.h" #include "MacroCount.h" #include "MacroDebug.h" #ifdef OPUS_ARM_INLINE_ASM #include "arm/SigProc_FIX_armv4.h" #endif #ifdef OPUS_ARM_INLINE_EDSP #include "arm/SigProc_FIX_armv5e.h" #endif #if defined(MIPSr1_ASM) #include "mips/sigproc_fix_mipsr1.h" #endif #ifdef __cplusplus } #endif #endif /* SILK_SIGPROC_FIX_H */ jamulus-3.9.1+dfsg/libs/opus/silk/pitch_est_defines.h0000644000175000017500000000773514340334543021701 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SILK_PE_DEFINES_H #define SILK_PE_DEFINES_H #include "SigProc_FIX.h" /********************************************************/ /* Definitions for pitch estimator */ /********************************************************/ #define PE_MAX_FS_KHZ 16 /* Maximum sampling frequency used */ #define PE_MAX_NB_SUBFR 4 #define PE_SUBFR_LENGTH_MS 5 /* 5 ms */ #define PE_LTP_MEM_LENGTH_MS ( 4 * PE_SUBFR_LENGTH_MS ) #define PE_MAX_FRAME_LENGTH_MS ( PE_LTP_MEM_LENGTH_MS + PE_MAX_NB_SUBFR * PE_SUBFR_LENGTH_MS ) #define PE_MAX_FRAME_LENGTH ( PE_MAX_FRAME_LENGTH_MS * PE_MAX_FS_KHZ ) #define PE_MAX_FRAME_LENGTH_ST_1 ( PE_MAX_FRAME_LENGTH >> 2 ) #define PE_MAX_FRAME_LENGTH_ST_2 ( PE_MAX_FRAME_LENGTH >> 1 ) #define PE_MAX_LAG_MS 18 /* 18 ms -> 56 Hz */ #define PE_MIN_LAG_MS 2 /* 2 ms -> 500 Hz */ #define PE_MAX_LAG ( PE_MAX_LAG_MS * PE_MAX_FS_KHZ ) #define PE_MIN_LAG ( PE_MIN_LAG_MS * PE_MAX_FS_KHZ ) #define PE_D_SRCH_LENGTH 24 #define PE_NB_STAGE3_LAGS 5 #define PE_NB_CBKS_STAGE2 3 #define PE_NB_CBKS_STAGE2_EXT 11 #define PE_NB_CBKS_STAGE3_MAX 34 #define PE_NB_CBKS_STAGE3_MID 24 #define PE_NB_CBKS_STAGE3_MIN 16 #define PE_NB_CBKS_STAGE3_10MS 12 #define PE_NB_CBKS_STAGE2_10MS 3 #define PE_SHORTLAG_BIAS 0.2f /* for logarithmic weighting */ #define PE_PREVLAG_BIAS 0.2f /* for logarithmic weighting */ #define PE_FLATCONTOUR_BIAS 0.05f #define SILK_PE_MIN_COMPLEX 0 #define SILK_PE_MID_COMPLEX 1 #define SILK_PE_MAX_COMPLEX 2 /* Tables for 20 ms frames */ extern const opus_int8 silk_CB_lags_stage2[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE2_EXT ]; extern const opus_int8 silk_CB_lags_stage3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ]; extern const opus_int8 silk_Lag_range_stage3[ SILK_PE_MAX_COMPLEX + 1 ] [ PE_MAX_NB_SUBFR ][ 2 ]; extern const opus_int8 silk_nb_cbk_searchs_stage3[ SILK_PE_MAX_COMPLEX + 1 ]; /* Tables for 10 ms frames */ extern const opus_int8 silk_CB_lags_stage2_10_ms[ PE_MAX_NB_SUBFR >> 1][ 3 ]; extern const opus_int8 silk_CB_lags_stage3_10_ms[ PE_MAX_NB_SUBFR >> 1 ][ 12 ]; extern const opus_int8 silk_Lag_range_stage3_10_ms[ PE_MAX_NB_SUBFR >> 1 ][ 2 ]; #endif jamulus-3.9.1+dfsg/libs/opus/silk/resampler_structs.h0000644000175000017500000000506714340334543021777 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SILK_RESAMPLER_STRUCTS_H #define SILK_RESAMPLER_STRUCTS_H #ifdef __cplusplus extern "C" { #endif #define SILK_RESAMPLER_MAX_FIR_ORDER 36 #define SILK_RESAMPLER_MAX_IIR_ORDER 6 typedef struct _silk_resampler_state_struct{ opus_int32 sIIR[ SILK_RESAMPLER_MAX_IIR_ORDER ]; /* this must be the first element of this struct */ union{ opus_int32 i32[ SILK_RESAMPLER_MAX_FIR_ORDER ]; opus_int16 i16[ SILK_RESAMPLER_MAX_FIR_ORDER ]; } sFIR; opus_int16 delayBuf[ 48 ]; opus_int resampler_function; opus_int batchSize; opus_int32 invRatio_Q16; opus_int FIR_Order; opus_int FIR_Fracs; opus_int Fs_in_kHz; opus_int Fs_out_kHz; opus_int inputDelay; const opus_int16 *Coefs; } silk_resampler_state_struct; #ifdef __cplusplus } #endif #endif /* SILK_RESAMPLER_STRUCTS_H */ jamulus-3.9.1+dfsg/libs/opus/silk/sigm_Q15.c0000644000175000017500000000613414340334543017572 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* Approximate sigmoid function */ #include "SigProc_FIX.h" /* fprintf(1, '%d, ', round(1024 * ([1 ./ (1 + exp(-(1:5))), 1] - 1 ./ (1 + exp(-(0:5)))))); */ static const opus_int32 sigm_LUT_slope_Q10[ 6 ] = { 237, 153, 73, 30, 12, 7 }; /* fprintf(1, '%d, ', round(32767 * 1 ./ (1 + exp(-(0:5))))); */ static const opus_int32 sigm_LUT_pos_Q15[ 6 ] = { 16384, 23955, 28861, 31213, 32178, 32548 }; /* fprintf(1, '%d, ', round(32767 * 1 ./ (1 + exp((0:5))))); */ static const opus_int32 sigm_LUT_neg_Q15[ 6 ] = { 16384, 8812, 3906, 1554, 589, 219 }; opus_int silk_sigm_Q15( opus_int in_Q5 /* I */ ) { opus_int ind; if( in_Q5 < 0 ) { /* Negative input */ in_Q5 = -in_Q5; if( in_Q5 >= 6 * 32 ) { return 0; /* Clip */ } else { /* Linear interpolation of look up table */ ind = silk_RSHIFT( in_Q5, 5 ); return( sigm_LUT_neg_Q15[ ind ] - silk_SMULBB( sigm_LUT_slope_Q10[ ind ], in_Q5 & 0x1F ) ); } } else { /* Positive input */ if( in_Q5 >= 6 * 32 ) { return 32767; /* clip */ } else { /* Linear interpolation of look up table */ ind = silk_RSHIFT( in_Q5, 5 ); return( sigm_LUT_pos_Q15[ ind ] + silk_SMULBB( sigm_LUT_slope_Q10[ ind ], in_Q5 & 0x1F ) ); } } } jamulus-3.9.1+dfsg/libs/opus/silk/Inlines.h0000644000175000017500000001622214340334543017612 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ /*! \file silk_Inlines.h * \brief silk_Inlines.h defines OPUS_INLINE signal processing functions. */ #ifndef SILK_FIX_INLINES_H #define SILK_FIX_INLINES_H #ifdef __cplusplus extern "C" { #endif /* count leading zeros of opus_int64 */ static OPUS_INLINE opus_int32 silk_CLZ64( opus_int64 in ) { opus_int32 in_upper; in_upper = (opus_int32)silk_RSHIFT64(in, 32); if (in_upper == 0) { /* Search in the lower 32 bits */ return 32 + silk_CLZ32( (opus_int32) in ); } else { /* Search in the upper 32 bits */ return silk_CLZ32( in_upper ); } } /* get number of leading zeros and fractional part (the bits right after the leading one */ static OPUS_INLINE void silk_CLZ_FRAC( opus_int32 in, /* I input */ opus_int32 *lz, /* O number of leading zeros */ opus_int32 *frac_Q7 /* O the 7 bits right after the leading one */ ) { opus_int32 lzeros = silk_CLZ32(in); * lz = lzeros; * frac_Q7 = silk_ROR32(in, 24 - lzeros) & 0x7f; } /* Approximation of square root */ /* Accuracy: < +/- 10% for output values > 15 */ /* < +/- 2.5% for output values > 120 */ static OPUS_INLINE opus_int32 silk_SQRT_APPROX( opus_int32 x ) { opus_int32 y, lz, frac_Q7; if( x <= 0 ) { return 0; } silk_CLZ_FRAC(x, &lz, &frac_Q7); if( lz & 1 ) { y = 32768; } else { y = 46214; /* 46214 = sqrt(2) * 32768 */ } /* get scaling right */ y >>= silk_RSHIFT(lz, 1); /* increment using fractional part of input */ y = silk_SMLAWB(y, y, silk_SMULBB(213, frac_Q7)); return y; } /* Divide two int32 values and return result as int32 in a given Q-domain */ static OPUS_INLINE opus_int32 silk_DIV32_varQ( /* O returns a good approximation of "(a32 << Qres) / b32" */ const opus_int32 a32, /* I numerator (Q0) */ const opus_int32 b32, /* I denominator (Q0) */ const opus_int Qres /* I Q-domain of result (>= 0) */ ) { opus_int a_headrm, b_headrm, lshift; opus_int32 b32_inv, a32_nrm, b32_nrm, result; silk_assert( b32 != 0 ); silk_assert( Qres >= 0 ); /* Compute number of bits head room and normalize inputs */ a_headrm = silk_CLZ32( silk_abs(a32) ) - 1; a32_nrm = silk_LSHIFT(a32, a_headrm); /* Q: a_headrm */ b_headrm = silk_CLZ32( silk_abs(b32) ) - 1; b32_nrm = silk_LSHIFT(b32, b_headrm); /* Q: b_headrm */ /* Inverse of b32, with 14 bits of precision */ b32_inv = silk_DIV32_16( silk_int32_MAX >> 2, silk_RSHIFT(b32_nrm, 16) ); /* Q: 29 + 16 - b_headrm */ /* First approximation */ result = silk_SMULWB(a32_nrm, b32_inv); /* Q: 29 + a_headrm - b_headrm */ /* Compute residual by subtracting product of denominator and first approximation */ /* It's OK to overflow because the final value of a32_nrm should always be small */ a32_nrm = silk_SUB32_ovflw(a32_nrm, silk_LSHIFT_ovflw( silk_SMMUL(b32_nrm, result), 3 )); /* Q: a_headrm */ /* Refinement */ result = silk_SMLAWB(result, a32_nrm, b32_inv); /* Q: 29 + a_headrm - b_headrm */ /* Convert to Qres domain */ lshift = 29 + a_headrm - b_headrm - Qres; if( lshift < 0 ) { return silk_LSHIFT_SAT32(result, -lshift); } else { if( lshift < 32){ return silk_RSHIFT(result, lshift); } else { /* Avoid undefined result */ return 0; } } } /* Invert int32 value and return result as int32 in a given Q-domain */ static OPUS_INLINE opus_int32 silk_INVERSE32_varQ( /* O returns a good approximation of "(1 << Qres) / b32" */ const opus_int32 b32, /* I denominator (Q0) */ const opus_int Qres /* I Q-domain of result (> 0) */ ) { opus_int b_headrm, lshift; opus_int32 b32_inv, b32_nrm, err_Q32, result; silk_assert( b32 != 0 ); silk_assert( Qres > 0 ); /* Compute number of bits head room and normalize input */ b_headrm = silk_CLZ32( silk_abs(b32) ) - 1; b32_nrm = silk_LSHIFT(b32, b_headrm); /* Q: b_headrm */ /* Inverse of b32, with 14 bits of precision */ b32_inv = silk_DIV32_16( silk_int32_MAX >> 2, silk_RSHIFT(b32_nrm, 16) ); /* Q: 29 + 16 - b_headrm */ /* First approximation */ result = silk_LSHIFT(b32_inv, 16); /* Q: 61 - b_headrm */ /* Compute residual by subtracting product of denominator and first approximation from one */ err_Q32 = silk_LSHIFT( ((opus_int32)1<<29) - silk_SMULWB(b32_nrm, b32_inv), 3 ); /* Q32 */ /* Refinement */ result = silk_SMLAWW(result, err_Q32, b32_inv); /* Q: 61 - b_headrm */ /* Convert to Qres domain */ lshift = 61 - b_headrm - Qres; if( lshift <= 0 ) { return silk_LSHIFT_SAT32(result, -lshift); } else { if( lshift < 32){ return silk_RSHIFT(result, lshift); }else{ /* Avoid undefined result */ return 0; } } } #ifdef __cplusplus } #endif #endif /* SILK_FIX_INLINES_H */ jamulus-3.9.1+dfsg/libs/opus/silk/decode_pulses.c0000644000175000017500000001273614340334543021030 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" /*********************************************/ /* Decode quantization indices of excitation */ /*********************************************/ void silk_decode_pulses( ec_dec *psRangeDec, /* I/O Compressor data structure */ opus_int16 pulses[], /* O Excitation signal */ const opus_int signalType, /* I Sigtype */ const opus_int quantOffsetType, /* I quantOffsetType */ const opus_int frame_length /* I Frame length */ ) { opus_int i, j, k, iter, abs_q, nLS, RateLevelIndex; opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ], nLshifts[ MAX_NB_SHELL_BLOCKS ]; opus_int16 *pulses_ptr; const opus_uint8 *cdf_ptr; /*********************/ /* Decode rate level */ /*********************/ RateLevelIndex = ec_dec_icdf( psRangeDec, silk_rate_levels_iCDF[ signalType >> 1 ], 8 ); /* Calculate number of shell blocks */ silk_assert( 1 << LOG2_SHELL_CODEC_FRAME_LENGTH == SHELL_CODEC_FRAME_LENGTH ); iter = silk_RSHIFT( frame_length, LOG2_SHELL_CODEC_FRAME_LENGTH ); if( iter * SHELL_CODEC_FRAME_LENGTH < frame_length ) { celt_assert( frame_length == 12 * 10 ); /* Make sure only happens for 10 ms @ 12 kHz */ iter++; } /***************************************************/ /* Sum-Weighted-Pulses Decoding */ /***************************************************/ cdf_ptr = silk_pulses_per_block_iCDF[ RateLevelIndex ]; for( i = 0; i < iter; i++ ) { nLshifts[ i ] = 0; sum_pulses[ i ] = ec_dec_icdf( psRangeDec, cdf_ptr, 8 ); /* LSB indication */ while( sum_pulses[ i ] == SILK_MAX_PULSES + 1 ) { nLshifts[ i ]++; /* When we've already got 10 LSBs, we shift the table to not allow (SILK_MAX_PULSES + 1) */ sum_pulses[ i ] = ec_dec_icdf( psRangeDec, silk_pulses_per_block_iCDF[ N_RATE_LEVELS - 1] + ( nLshifts[ i ] == 10 ), 8 ); } } /***************************************************/ /* Shell decoding */ /***************************************************/ for( i = 0; i < iter; i++ ) { if( sum_pulses[ i ] > 0 ) { silk_shell_decoder( &pulses[ silk_SMULBB( i, SHELL_CODEC_FRAME_LENGTH ) ], psRangeDec, sum_pulses[ i ] ); } else { silk_memset( &pulses[ silk_SMULBB( i, SHELL_CODEC_FRAME_LENGTH ) ], 0, SHELL_CODEC_FRAME_LENGTH * sizeof( pulses[0] ) ); } } /***************************************************/ /* LSB Decoding */ /***************************************************/ for( i = 0; i < iter; i++ ) { if( nLshifts[ i ] > 0 ) { nLS = nLshifts[ i ]; pulses_ptr = &pulses[ silk_SMULBB( i, SHELL_CODEC_FRAME_LENGTH ) ]; for( k = 0; k < SHELL_CODEC_FRAME_LENGTH; k++ ) { abs_q = pulses_ptr[ k ]; for( j = 0; j < nLS; j++ ) { abs_q = silk_LSHIFT( abs_q, 1 ); abs_q += ec_dec_icdf( psRangeDec, silk_lsb_iCDF, 8 ); } pulses_ptr[ k ] = abs_q; } /* Mark the number of pulses non-zero for sign decoding. */ sum_pulses[ i ] |= nLS << 5; } } /****************************************/ /* Decode and add signs to pulse signal */ /****************************************/ silk_decode_signs( psRangeDec, pulses, frame_length, signalType, quantOffsetType, sum_pulses ); } jamulus-3.9.1+dfsg/libs/opus/silk/resampler_private_AR2.c0000644000175000017500000000515114340334543022373 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FIX.h" #include "resampler_private.h" /* Second order AR filter with single delay elements */ void silk_resampler_private_AR2( opus_int32 S[], /* I/O State vector [ 2 ] */ opus_int32 out_Q8[], /* O Output signal */ const opus_int16 in[], /* I Input signal */ const opus_int16 A_Q14[], /* I AR coefficients, Q14 */ opus_int32 len /* I Signal length */ ) { opus_int32 k; opus_int32 out32; for( k = 0; k < len; k++ ) { out32 = silk_ADD_LSHIFT32( S[ 0 ], (opus_int32)in[ k ], 8 ); out_Q8[ k ] = out32; out32 = silk_LSHIFT( out32, 2 ); S[ 0 ] = silk_SMLAWB( S[ 1 ], out32, A_Q14[ 0 ] ); S[ 1 ] = silk_SMULWB( out32, A_Q14[ 1 ] ); } } jamulus-3.9.1+dfsg/libs/opus/silk/decode_parameters.c0000644000175000017500000001262714340334543021657 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" /* Decode parameters from payload */ void silk_decode_parameters( silk_decoder_state *psDec, /* I/O State */ silk_decoder_control *psDecCtrl, /* I/O Decoder control */ opus_int condCoding /* I The type of conditional coding to use */ ) { opus_int i, k, Ix; opus_int16 pNLSF_Q15[ MAX_LPC_ORDER ], pNLSF0_Q15[ MAX_LPC_ORDER ]; const opus_int8 *cbk_ptr_Q7; /* Dequant Gains */ silk_gains_dequant( psDecCtrl->Gains_Q16, psDec->indices.GainsIndices, &psDec->LastGainIndex, condCoding == CODE_CONDITIONALLY, psDec->nb_subfr ); /****************/ /* Decode NLSFs */ /****************/ silk_NLSF_decode( pNLSF_Q15, psDec->indices.NLSFIndices, psDec->psNLSF_CB ); /* Convert NLSF parameters to AR prediction filter coefficients */ silk_NLSF2A( psDecCtrl->PredCoef_Q12[ 1 ], pNLSF_Q15, psDec->LPC_order, psDec->arch ); /* If just reset, e.g., because internal Fs changed, do not allow interpolation */ /* improves the case of packet loss in the first frame after a switch */ if( psDec->first_frame_after_reset == 1 ) { psDec->indices.NLSFInterpCoef_Q2 = 4; } if( psDec->indices.NLSFInterpCoef_Q2 < 4 ) { /* Calculation of the interpolated NLSF0 vector from the interpolation factor, */ /* the previous NLSF1, and the current NLSF1 */ for( i = 0; i < psDec->LPC_order; i++ ) { pNLSF0_Q15[ i ] = psDec->prevNLSF_Q15[ i ] + silk_RSHIFT( silk_MUL( psDec->indices.NLSFInterpCoef_Q2, pNLSF_Q15[ i ] - psDec->prevNLSF_Q15[ i ] ), 2 ); } /* Convert NLSF parameters to AR prediction filter coefficients */ silk_NLSF2A( psDecCtrl->PredCoef_Q12[ 0 ], pNLSF0_Q15, psDec->LPC_order, psDec->arch ); } else { /* Copy LPC coefficients for first half from second half */ silk_memcpy( psDecCtrl->PredCoef_Q12[ 0 ], psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order * sizeof( opus_int16 ) ); } silk_memcpy( psDec->prevNLSF_Q15, pNLSF_Q15, psDec->LPC_order * sizeof( opus_int16 ) ); /* After a packet loss do BWE of LPC coefs */ if( psDec->lossCnt ) { silk_bwexpander( psDecCtrl->PredCoef_Q12[ 0 ], psDec->LPC_order, BWE_AFTER_LOSS_Q16 ); silk_bwexpander( psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order, BWE_AFTER_LOSS_Q16 ); } if( psDec->indices.signalType == TYPE_VOICED ) { /*********************/ /* Decode pitch lags */ /*********************/ /* Decode pitch values */ silk_decode_pitch( psDec->indices.lagIndex, psDec->indices.contourIndex, psDecCtrl->pitchL, psDec->fs_kHz, psDec->nb_subfr ); /* Decode Codebook Index */ cbk_ptr_Q7 = silk_LTP_vq_ptrs_Q7[ psDec->indices.PERIndex ]; /* set pointer to start of codebook */ for( k = 0; k < psDec->nb_subfr; k++ ) { Ix = psDec->indices.LTPIndex[ k ]; for( i = 0; i < LTP_ORDER; i++ ) { psDecCtrl->LTPCoef_Q14[ k * LTP_ORDER + i ] = silk_LSHIFT( cbk_ptr_Q7[ Ix * LTP_ORDER + i ], 7 ); } } /**********************/ /* Decode LTP scaling */ /**********************/ Ix = psDec->indices.LTP_scaleIndex; psDecCtrl->LTP_scale_Q14 = silk_LTPScales_table_Q14[ Ix ]; } else { silk_memset( psDecCtrl->pitchL, 0, psDec->nb_subfr * sizeof( opus_int ) ); silk_memset( psDecCtrl->LTPCoef_Q14, 0, LTP_ORDER * psDec->nb_subfr * sizeof( opus_int16 ) ); psDec->indices.PERIndex = 0; psDecCtrl->LTP_scale_Q14 = 0; } } jamulus-3.9.1+dfsg/libs/opus/silk/control_audio_bandwidth.c0000644000175000017500000001343714340334543023076 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" #include "tuning_parameters.h" /* Control internal sampling rate */ opus_int silk_control_audio_bandwidth( silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */ silk_EncControlStruct *encControl /* I Control structure */ ) { opus_int fs_kHz; opus_int orig_kHz; opus_int32 fs_Hz; orig_kHz = psEncC->fs_kHz; /* Handle a bandwidth-switching reset where we need to be aware what the last sampling rate was. */ if( orig_kHz == 0 ) { orig_kHz = psEncC->sLP.saved_fs_kHz; } fs_kHz = orig_kHz; fs_Hz = silk_SMULBB( fs_kHz, 1000 ); if( fs_Hz == 0 ) { /* Encoder has just been initialized */ fs_Hz = silk_min( psEncC->desiredInternal_fs_Hz, psEncC->API_fs_Hz ); fs_kHz = silk_DIV32_16( fs_Hz, 1000 ); } else if( fs_Hz > psEncC->API_fs_Hz || fs_Hz > psEncC->maxInternal_fs_Hz || fs_Hz < psEncC->minInternal_fs_Hz ) { /* Make sure internal rate is not higher than external rate or maximum allowed, or lower than minimum allowed */ fs_Hz = psEncC->API_fs_Hz; fs_Hz = silk_min( fs_Hz, psEncC->maxInternal_fs_Hz ); fs_Hz = silk_max( fs_Hz, psEncC->minInternal_fs_Hz ); fs_kHz = silk_DIV32_16( fs_Hz, 1000 ); } else { /* State machine for the internal sampling rate switching */ if( psEncC->sLP.transition_frame_no >= TRANSITION_FRAMES ) { /* Stop transition phase */ psEncC->sLP.mode = 0; } if( psEncC->allow_bandwidth_switch || encControl->opusCanSwitch ) { /* Check if we should switch down */ if( silk_SMULBB( orig_kHz, 1000 ) > psEncC->desiredInternal_fs_Hz ) { /* Switch down */ if( psEncC->sLP.mode == 0 ) { /* New transition */ psEncC->sLP.transition_frame_no = TRANSITION_FRAMES; /* Reset transition filter state */ silk_memset( psEncC->sLP.In_LP_State, 0, sizeof( psEncC->sLP.In_LP_State ) ); } if( encControl->opusCanSwitch ) { /* Stop transition phase */ psEncC->sLP.mode = 0; /* Switch to a lower sample frequency */ fs_kHz = orig_kHz == 16 ? 12 : 8; } else { if( psEncC->sLP.transition_frame_no <= 0 ) { encControl->switchReady = 1; /* Make room for redundancy */ encControl->maxBits -= encControl->maxBits * 5 / ( encControl->payloadSize_ms + 5 ); } else { /* Direction: down (at double speed) */ psEncC->sLP.mode = -2; } } } else /* Check if we should switch up */ if( silk_SMULBB( orig_kHz, 1000 ) < psEncC->desiredInternal_fs_Hz ) { /* Switch up */ if( encControl->opusCanSwitch ) { /* Switch to a higher sample frequency */ fs_kHz = orig_kHz == 8 ? 12 : 16; /* New transition */ psEncC->sLP.transition_frame_no = 0; /* Reset transition filter state */ silk_memset( psEncC->sLP.In_LP_State, 0, sizeof( psEncC->sLP.In_LP_State ) ); /* Direction: up */ psEncC->sLP.mode = 1; } else { if( psEncC->sLP.mode == 0 ) { encControl->switchReady = 1; /* Make room for redundancy */ encControl->maxBits -= encControl->maxBits * 5 / ( encControl->payloadSize_ms + 5 ); } else { /* Direction: up */ psEncC->sLP.mode = 1; } } } else { if (psEncC->sLP.mode<0) psEncC->sLP.mode = 1; } } } return fs_kHz; } jamulus-3.9.1+dfsg/libs/opus/silk/NSQ_del_dec.c0000644000175000017500000011501214340334543020301 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" #include "stack_alloc.h" #include "NSQ.h" typedef struct { opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ]; opus_int32 RandState[ DECISION_DELAY ]; opus_int32 Q_Q10[ DECISION_DELAY ]; opus_int32 Xq_Q14[ DECISION_DELAY ]; opus_int32 Pred_Q15[ DECISION_DELAY ]; opus_int32 Shape_Q14[ DECISION_DELAY ]; opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ]; opus_int32 LF_AR_Q14; opus_int32 Diff_Q14; opus_int32 Seed; opus_int32 SeedInit; opus_int32 RD_Q10; } NSQ_del_dec_struct; typedef struct { opus_int32 Q_Q10; opus_int32 RD_Q10; opus_int32 xq_Q14; opus_int32 LF_AR_Q14; opus_int32 Diff_Q14; opus_int32 sLTP_shp_Q14; opus_int32 LPC_exc_Q14; } NSQ_sample_struct; typedef NSQ_sample_struct NSQ_sample_pair[ 2 ]; #if defined(MIPSr1_ASM) #include "mips/NSQ_del_dec_mipsr1.h" #endif static OPUS_INLINE void silk_nsq_del_dec_scale_states( const silk_encoder_state *psEncC, /* I Encoder State */ silk_nsq_state *NSQ, /* I/O NSQ state */ NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ const opus_int16 x16[], /* I Input */ opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */ const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */ opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ opus_int subfr, /* I Subframe number */ opus_int nStatesDelayedDecision, /* I Number of del dec states */ const opus_int LTP_scale_Q14, /* I LTP state scaling */ const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ const opus_int signal_type, /* I Signal type */ const opus_int decisionDelay /* I Decision delay */ ); /******************************************/ /* Noise shape quantizer for one subframe */ /******************************************/ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec( silk_nsq_state *NSQ, /* I/O NSQ state */ NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ opus_int signalType, /* I Signal type */ const opus_int32 x_Q10[], /* I */ opus_int8 pulses[], /* O */ opus_int16 xq[], /* O */ opus_int32 sLTP_Q15[], /* I/O LTP filter state */ opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */ const opus_int16 a_Q12[], /* I Short term prediction coefs */ const opus_int16 b_Q14[], /* I Long term prediction coefs */ const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */ opus_int lag, /* I Pitch lag */ opus_int32 HarmShapeFIRPacked_Q14, /* I */ opus_int Tilt_Q14, /* I Spectral tilt */ opus_int32 LF_shp_Q14, /* I */ opus_int32 Gain_Q16, /* I */ opus_int Lambda_Q10, /* I */ opus_int offset_Q10, /* I */ opus_int length, /* I Input length */ opus_int subfr, /* I Subframe number */ opus_int shapingLPCOrder, /* I Shaping LPC filter order */ opus_int predictLPCOrder, /* I Prediction filter order */ opus_int warping_Q16, /* I */ opus_int nStatesDelayedDecision, /* I Number of states in decision tree */ opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */ opus_int decisionDelay, /* I */ int arch /* I */ ); void silk_NSQ_del_dec_c( const silk_encoder_state *psEncC, /* I Encoder State */ silk_nsq_state *NSQ, /* I/O NSQ state */ SideInfoIndices *psIndices, /* I/O Quantization Indices */ const opus_int16 x16[], /* I Input */ opus_int8 pulses[], /* O Quantized pulse signal */ const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ const opus_int LTP_scale_Q14 /* I LTP state scaling */ ) { opus_int i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr; opus_int last_smple_idx, smpl_buf_idx, decisionDelay; const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13; opus_int16 *pxq; VARDECL( opus_int32, sLTP_Q15 ); VARDECL( opus_int16, sLTP ); opus_int32 HarmShapeFIRPacked_Q14; opus_int offset_Q10; opus_int32 RDmin_Q10, Gain_Q10; VARDECL( opus_int32, x_sc_Q10 ); VARDECL( opus_int32, delayedGain_Q10 ); VARDECL( NSQ_del_dec_struct, psDelDec ); NSQ_del_dec_struct *psDD; SAVE_STACK; /* Set unvoiced lag to the previous one, overwrite later for voiced */ lag = NSQ->lagPrev; silk_assert( NSQ->prev_gain_Q16 != 0 ); /* Initialize delayed decision states */ ALLOC( psDelDec, psEncC->nStatesDelayedDecision, NSQ_del_dec_struct ); silk_memset( psDelDec, 0, psEncC->nStatesDelayedDecision * sizeof( NSQ_del_dec_struct ) ); for( k = 0; k < psEncC->nStatesDelayedDecision; k++ ) { psDD = &psDelDec[ k ]; psDD->Seed = ( k + psIndices->Seed ) & 3; psDD->SeedInit = psDD->Seed; psDD->RD_Q10 = 0; psDD->LF_AR_Q14 = NSQ->sLF_AR_shp_Q14; psDD->Diff_Q14 = NSQ->sDiff_shp_Q14; psDD->Shape_Q14[ 0 ] = NSQ->sLTP_shp_Q14[ psEncC->ltp_mem_length - 1 ]; silk_memcpy( psDD->sLPC_Q14, NSQ->sLPC_Q14, NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); silk_memcpy( psDD->sAR2_Q14, NSQ->sAR2_Q14, sizeof( NSQ->sAR2_Q14 ) ); } offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ]; smpl_buf_idx = 0; /* index of oldest samples */ decisionDelay = silk_min_int( DECISION_DELAY, psEncC->subfr_length ); /* For voiced frames limit the decision delay to lower than the pitch lag */ if( psIndices->signalType == TYPE_VOICED ) { for( k = 0; k < psEncC->nb_subfr; k++ ) { decisionDelay = silk_min_int( decisionDelay, pitchL[ k ] - LTP_ORDER / 2 - 1 ); } } else { if( lag > 0 ) { decisionDelay = silk_min_int( decisionDelay, lag - LTP_ORDER / 2 - 1 ); } } if( psIndices->NLSFInterpCoef_Q2 == 4 ) { LSF_interpolation_flag = 0; } else { LSF_interpolation_flag = 1; } ALLOC( sLTP_Q15, psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 ); ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 ); ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 ); ALLOC( delayedGain_Q10, DECISION_DELAY, opus_int32 ); /* Set up pointers to start of sub frame */ pxq = &NSQ->xq[ psEncC->ltp_mem_length ]; NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length; NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; subfr = 0; for( k = 0; k < psEncC->nb_subfr; k++ ) { A_Q12 = &PredCoef_Q12[ ( ( k >> 1 ) | ( 1 - LSF_interpolation_flag ) ) * MAX_LPC_ORDER ]; B_Q14 = <PCoef_Q14[ k * LTP_ORDER ]; AR_shp_Q13 = &AR_Q13[ k * MAX_SHAPE_LPC_ORDER ]; /* Noise shape parameters */ silk_assert( HarmShapeGain_Q14[ k ] >= 0 ); HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 ); HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 ); NSQ->rewhite_flag = 0; if( psIndices->signalType == TYPE_VOICED ) { /* Voiced */ lag = pitchL[ k ]; /* Re-whitening */ if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) { if( k == 2 ) { /* RESET DELAYED DECISIONS */ /* Find winner */ RDmin_Q10 = psDelDec[ 0 ].RD_Q10; Winner_ind = 0; for( i = 1; i < psEncC->nStatesDelayedDecision; i++ ) { if( psDelDec[ i ].RD_Q10 < RDmin_Q10 ) { RDmin_Q10 = psDelDec[ i ].RD_Q10; Winner_ind = i; } } for( i = 0; i < psEncC->nStatesDelayedDecision; i++ ) { if( i != Winner_ind ) { psDelDec[ i ].RD_Q10 += ( silk_int32_MAX >> 4 ); silk_assert( psDelDec[ i ].RD_Q10 >= 0 ); } } /* Copy final part of signals from winner state to output and long-term filter states */ psDD = &psDelDec[ Winner_ind ]; last_smple_idx = smpl_buf_idx + decisionDelay; for( i = 0; i < decisionDelay; i++ ) { last_smple_idx = ( last_smple_idx - 1 ) % DECISION_DELAY; if( last_smple_idx < 0 ) last_smple_idx += DECISION_DELAY; pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 ); pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gains_Q16[ 1 ] ), 14 ) ); NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ]; } subfr = 0; } /* Rewhiten with new A coefs */ start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2; celt_assert( start_idx > 0 ); silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ], A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch ); NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; NSQ->rewhite_flag = 1; } } silk_nsq_del_dec_scale_states( psEncC, NSQ, psDelDec, x16, x_sc_Q10, sLTP, sLTP_Q15, k, psEncC->nStatesDelayedDecision, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType, decisionDelay ); silk_noise_shape_quantizer_del_dec( NSQ, psDelDec, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, delayedGain_Q10, A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder, psEncC->predictLPCOrder, psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay, psEncC->arch ); x16 += psEncC->subfr_length; pulses += psEncC->subfr_length; pxq += psEncC->subfr_length; } /* Find winner */ RDmin_Q10 = psDelDec[ 0 ].RD_Q10; Winner_ind = 0; for( k = 1; k < psEncC->nStatesDelayedDecision; k++ ) { if( psDelDec[ k ].RD_Q10 < RDmin_Q10 ) { RDmin_Q10 = psDelDec[ k ].RD_Q10; Winner_ind = k; } } /* Copy final part of signals from winner state to output and long-term filter states */ psDD = &psDelDec[ Winner_ind ]; psIndices->Seed = psDD->SeedInit; last_smple_idx = smpl_buf_idx + decisionDelay; Gain_Q10 = silk_RSHIFT32( Gains_Q16[ psEncC->nb_subfr - 1 ], 6 ); for( i = 0; i < decisionDelay; i++ ) { last_smple_idx = ( last_smple_idx - 1 ) % DECISION_DELAY; if( last_smple_idx < 0 ) last_smple_idx += DECISION_DELAY; pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 ); pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gain_Q10 ), 8 ) ); NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ]; } silk_memcpy( NSQ->sLPC_Q14, &psDD->sLPC_Q14[ psEncC->subfr_length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); silk_memcpy( NSQ->sAR2_Q14, psDD->sAR2_Q14, sizeof( psDD->sAR2_Q14 ) ); /* Update states */ NSQ->sLF_AR_shp_Q14 = psDD->LF_AR_Q14; NSQ->sDiff_shp_Q14 = psDD->Diff_Q14; NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ]; /* Save quantized speech signal */ silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) ); silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) ); RESTORE_STACK; } /******************************************/ /* Noise shape quantizer for one subframe */ /******************************************/ #ifndef OVERRIDE_silk_noise_shape_quantizer_del_dec static OPUS_INLINE void silk_noise_shape_quantizer_del_dec( silk_nsq_state *NSQ, /* I/O NSQ state */ NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ opus_int signalType, /* I Signal type */ const opus_int32 x_Q10[], /* I */ opus_int8 pulses[], /* O */ opus_int16 xq[], /* O */ opus_int32 sLTP_Q15[], /* I/O LTP filter state */ opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */ const opus_int16 a_Q12[], /* I Short term prediction coefs */ const opus_int16 b_Q14[], /* I Long term prediction coefs */ const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */ opus_int lag, /* I Pitch lag */ opus_int32 HarmShapeFIRPacked_Q14, /* I */ opus_int Tilt_Q14, /* I Spectral tilt */ opus_int32 LF_shp_Q14, /* I */ opus_int32 Gain_Q16, /* I */ opus_int Lambda_Q10, /* I */ opus_int offset_Q10, /* I */ opus_int length, /* I Input length */ opus_int subfr, /* I Subframe number */ opus_int shapingLPCOrder, /* I Shaping LPC filter order */ opus_int predictLPCOrder, /* I Prediction filter order */ opus_int warping_Q16, /* I */ opus_int nStatesDelayedDecision, /* I Number of states in decision tree */ opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */ opus_int decisionDelay, /* I */ int arch /* I */ ) { opus_int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx; opus_int32 Winner_rand_state; opus_int32 LTP_pred_Q14, LPC_pred_Q14, n_AR_Q14, n_LTP_Q14; opus_int32 n_LF_Q14, r_Q10, rr_Q10, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10; opus_int32 q1_Q0, q1_Q10, q2_Q10, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10; opus_int32 tmp1, tmp2, sLF_AR_shp_Q14; opus_int32 *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14; #ifdef silk_short_prediction_create_arch_coef opus_int32 a_Q12_arch[MAX_LPC_ORDER]; #endif VARDECL( NSQ_sample_pair, psSampleState ); NSQ_del_dec_struct *psDD; NSQ_sample_struct *psSS; SAVE_STACK; celt_assert( nStatesDelayedDecision > 0 ); ALLOC( psSampleState, nStatesDelayedDecision, NSQ_sample_pair ); shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ]; pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ]; Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 ); #ifdef silk_short_prediction_create_arch_coef silk_short_prediction_create_arch_coef(a_Q12_arch, a_Q12, predictLPCOrder); #endif for( i = 0; i < length; i++ ) { /* Perform common calculations used in all states */ /* Long-term prediction */ if( signalType == TYPE_VOICED ) { /* Unrolled loop */ /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ LTP_pred_Q14 = 2; LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ 0 ], b_Q14[ 0 ] ); LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], b_Q14[ 1 ] ); LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], b_Q14[ 2 ] ); LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], b_Q14[ 3 ] ); LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] ); LTP_pred_Q14 = silk_LSHIFT( LTP_pred_Q14, 1 ); /* Q13 -> Q14 */ pred_lag_ptr++; } else { LTP_pred_Q14 = 0; } /* Long-term shaping */ if( lag > 0 ) { /* Symmetric, packed FIR coefficients */ n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 ); n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 ); n_LTP_Q14 = silk_SUB_LSHIFT32( LTP_pred_Q14, n_LTP_Q14, 2 ); /* Q12 -> Q14 */ shp_lag_ptr++; } else { n_LTP_Q14 = 0; } for( k = 0; k < nStatesDelayedDecision; k++ ) { /* Delayed decision state */ psDD = &psDelDec[ k ]; /* Sample state */ psSS = psSampleState[ k ]; /* Generate dither */ psDD->Seed = silk_RAND( psDD->Seed ); /* Pointer used in short term prediction and shaping */ psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ]; /* Short-term prediction */ LPC_pred_Q14 = silk_noise_shape_quantizer_short_prediction(psLPC_Q14, a_Q12, a_Q12_arch, predictLPCOrder, arch); LPC_pred_Q14 = silk_LSHIFT( LPC_pred_Q14, 4 ); /* Q10 -> Q14 */ /* Noise shape feedback */ celt_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */ /* Output of lowpass section */ tmp2 = silk_SMLAWB( psDD->Diff_Q14, psDD->sAR2_Q14[ 0 ], warping_Q16 ); /* Output of allpass section */ tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ 0 ], psDD->sAR2_Q14[ 1 ] - tmp2, warping_Q16 ); psDD->sAR2_Q14[ 0 ] = tmp2; n_AR_Q14 = silk_RSHIFT( shapingLPCOrder, 1 ); n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ 0 ] ); /* Loop over allpass sections */ for( j = 2; j < shapingLPCOrder; j += 2 ) { /* Output of allpass section */ tmp2 = silk_SMLAWB( psDD->sAR2_Q14[ j - 1 ], psDD->sAR2_Q14[ j + 0 ] - tmp1, warping_Q16 ); psDD->sAR2_Q14[ j - 1 ] = tmp1; n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ j - 1 ] ); /* Output of allpass section */ tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ j + 0 ], psDD->sAR2_Q14[ j + 1 ] - tmp2, warping_Q16 ); psDD->sAR2_Q14[ j + 0 ] = tmp2; n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ j ] ); } psDD->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1; n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] ); n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 1 ); /* Q11 -> Q12 */ n_AR_Q14 = silk_SMLAWB( n_AR_Q14, psDD->LF_AR_Q14, Tilt_Q14 ); /* Q12 */ n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 2 ); /* Q12 -> Q14 */ n_LF_Q14 = silk_SMULWB( psDD->Shape_Q14[ *smpl_buf_idx ], LF_shp_Q14 ); /* Q12 */ n_LF_Q14 = silk_SMLAWT( n_LF_Q14, psDD->LF_AR_Q14, LF_shp_Q14 ); /* Q12 */ n_LF_Q14 = silk_LSHIFT( n_LF_Q14, 2 ); /* Q12 -> Q14 */ /* Input minus prediction plus noise feedback */ /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP */ tmp1 = silk_ADD32( n_AR_Q14, n_LF_Q14 ); /* Q14 */ tmp2 = silk_ADD32( n_LTP_Q14, LPC_pred_Q14 ); /* Q13 */ tmp1 = silk_SUB32( tmp2, tmp1 ); /* Q13 */ tmp1 = silk_RSHIFT_ROUND( tmp1, 4 ); /* Q10 */ r_Q10 = silk_SUB32( x_Q10[ i ], tmp1 ); /* residual error Q10 */ /* Flip sign depending on dither */ if ( psDD->Seed < 0 ) { r_Q10 = -r_Q10; } r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 ); /* Find two quantization level candidates and measure their rate-distortion */ q1_Q10 = silk_SUB32( r_Q10, offset_Q10 ); q1_Q0 = silk_RSHIFT( q1_Q10, 10 ); if (Lambda_Q10 > 2048) { /* For aggressive RDO, the bias becomes more than one pulse. */ int rdo_offset = Lambda_Q10/2 - 512; if (q1_Q10 > rdo_offset) { q1_Q0 = silk_RSHIFT( q1_Q10 - rdo_offset, 10 ); } else if (q1_Q10 < -rdo_offset) { q1_Q0 = silk_RSHIFT( q1_Q10 + rdo_offset, 10 ); } else if (q1_Q10 < 0) { q1_Q0 = -1; } else { q1_Q0 = 0; } } if( q1_Q0 > 0 ) { q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); q2_Q10 = silk_ADD32( q1_Q10, 1024 ); rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 ); rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 ); } else if( q1_Q0 == 0 ) { q1_Q10 = offset_Q10; q2_Q10 = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 ); rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 ); rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 ); } else if( q1_Q0 == -1 ) { q2_Q10 = offset_Q10; q1_Q10 = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 ); rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 ); rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 ); } else { /* q1_Q0 < -1 */ q1_Q10 = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); q2_Q10 = silk_ADD32( q1_Q10, 1024 ); rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 ); rd2_Q10 = silk_SMULBB( -q2_Q10, Lambda_Q10 ); } rr_Q10 = silk_SUB32( r_Q10, q1_Q10 ); rd1_Q10 = silk_RSHIFT( silk_SMLABB( rd1_Q10, rr_Q10, rr_Q10 ), 10 ); rr_Q10 = silk_SUB32( r_Q10, q2_Q10 ); rd2_Q10 = silk_RSHIFT( silk_SMLABB( rd2_Q10, rr_Q10, rr_Q10 ), 10 ); if( rd1_Q10 < rd2_Q10 ) { psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 ); psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 ); psSS[ 0 ].Q_Q10 = q1_Q10; psSS[ 1 ].Q_Q10 = q2_Q10; } else { psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 ); psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 ); psSS[ 0 ].Q_Q10 = q2_Q10; psSS[ 1 ].Q_Q10 = q1_Q10; } /* Update states for best quantization */ /* Quantized excitation */ exc_Q14 = silk_LSHIFT32( psSS[ 0 ].Q_Q10, 4 ); if ( psDD->Seed < 0 ) { exc_Q14 = -exc_Q14; } /* Add predictions */ LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 ); xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 ); /* Update states */ psSS[ 0 ].Diff_Q14 = silk_SUB_LSHIFT32( xq_Q14, x_Q10[ i ], 4 ); sLF_AR_shp_Q14 = silk_SUB32( psSS[ 0 ].Diff_Q14, n_AR_Q14 ); psSS[ 0 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 ); psSS[ 0 ].LF_AR_Q14 = sLF_AR_shp_Q14; psSS[ 0 ].LPC_exc_Q14 = LPC_exc_Q14; psSS[ 0 ].xq_Q14 = xq_Q14; /* Update states for second best quantization */ /* Quantized excitation */ exc_Q14 = silk_LSHIFT32( psSS[ 1 ].Q_Q10, 4 ); if ( psDD->Seed < 0 ) { exc_Q14 = -exc_Q14; } /* Add predictions */ LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 ); xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 ); /* Update states */ psSS[ 1 ].Diff_Q14 = silk_SUB_LSHIFT32( xq_Q14, x_Q10[ i ], 4 ); sLF_AR_shp_Q14 = silk_SUB32( psSS[ 1 ].Diff_Q14, n_AR_Q14 ); psSS[ 1 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 ); psSS[ 1 ].LF_AR_Q14 = sLF_AR_shp_Q14; psSS[ 1 ].LPC_exc_Q14 = LPC_exc_Q14; psSS[ 1 ].xq_Q14 = xq_Q14; } *smpl_buf_idx = ( *smpl_buf_idx - 1 ) % DECISION_DELAY; if( *smpl_buf_idx < 0 ) *smpl_buf_idx += DECISION_DELAY; last_smple_idx = ( *smpl_buf_idx + decisionDelay ) % DECISION_DELAY; /* Find winner */ RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10; Winner_ind = 0; for( k = 1; k < nStatesDelayedDecision; k++ ) { if( psSampleState[ k ][ 0 ].RD_Q10 < RDmin_Q10 ) { RDmin_Q10 = psSampleState[ k ][ 0 ].RD_Q10; Winner_ind = k; } } /* Increase RD values of expired states */ Winner_rand_state = psDelDec[ Winner_ind ].RandState[ last_smple_idx ]; for( k = 0; k < nStatesDelayedDecision; k++ ) { if( psDelDec[ k ].RandState[ last_smple_idx ] != Winner_rand_state ) { psSampleState[ k ][ 0 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 0 ].RD_Q10, silk_int32_MAX >> 4 ); psSampleState[ k ][ 1 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 1 ].RD_Q10, silk_int32_MAX >> 4 ); silk_assert( psSampleState[ k ][ 0 ].RD_Q10 >= 0 ); } } /* Find worst in first set and best in second set */ RDmax_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10; RDmin_Q10 = psSampleState[ 0 ][ 1 ].RD_Q10; RDmax_ind = 0; RDmin_ind = 0; for( k = 1; k < nStatesDelayedDecision; k++ ) { /* find worst in first set */ if( psSampleState[ k ][ 0 ].RD_Q10 > RDmax_Q10 ) { RDmax_Q10 = psSampleState[ k ][ 0 ].RD_Q10; RDmax_ind = k; } /* find best in second set */ if( psSampleState[ k ][ 1 ].RD_Q10 < RDmin_Q10 ) { RDmin_Q10 = psSampleState[ k ][ 1 ].RD_Q10; RDmin_ind = k; } } /* Replace a state if best from second set outperforms worst in first set */ if( RDmin_Q10 < RDmax_Q10 ) { silk_memcpy( ( (opus_int32 *)&psDelDec[ RDmax_ind ] ) + i, ( (opus_int32 *)&psDelDec[ RDmin_ind ] ) + i, sizeof( NSQ_del_dec_struct ) - i * sizeof( opus_int32) ); silk_memcpy( &psSampleState[ RDmax_ind ][ 0 ], &psSampleState[ RDmin_ind ][ 1 ], sizeof( NSQ_sample_struct ) ); } /* Write samples from winner to output and long-term filter states */ psDD = &psDelDec[ Winner_ind ]; if( subfr > 0 || i >= decisionDelay ) { pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 ); xq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], delayedGain_Q10[ last_smple_idx ] ), 8 ) ); NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDD->Shape_Q14[ last_smple_idx ]; sLTP_Q15[ NSQ->sLTP_buf_idx - decisionDelay ] = psDD->Pred_Q15[ last_smple_idx ]; } NSQ->sLTP_shp_buf_idx++; NSQ->sLTP_buf_idx++; /* Update states */ for( k = 0; k < nStatesDelayedDecision; k++ ) { psDD = &psDelDec[ k ]; psSS = &psSampleState[ k ][ 0 ]; psDD->LF_AR_Q14 = psSS->LF_AR_Q14; psDD->Diff_Q14 = psSS->Diff_Q14; psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ] = psSS->xq_Q14; psDD->Xq_Q14[ *smpl_buf_idx ] = psSS->xq_Q14; psDD->Q_Q10[ *smpl_buf_idx ] = psSS->Q_Q10; psDD->Pred_Q15[ *smpl_buf_idx ] = silk_LSHIFT32( psSS->LPC_exc_Q14, 1 ); psDD->Shape_Q14[ *smpl_buf_idx ] = psSS->sLTP_shp_Q14; psDD->Seed = silk_ADD32_ovflw( psDD->Seed, silk_RSHIFT_ROUND( psSS->Q_Q10, 10 ) ); psDD->RandState[ *smpl_buf_idx ] = psDD->Seed; psDD->RD_Q10 = psSS->RD_Q10; } delayedGain_Q10[ *smpl_buf_idx ] = Gain_Q10; } /* Update LPC states */ for( k = 0; k < nStatesDelayedDecision; k++ ) { psDD = &psDelDec[ k ]; silk_memcpy( psDD->sLPC_Q14, &psDD->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); } RESTORE_STACK; } #endif /* OVERRIDE_silk_noise_shape_quantizer_del_dec */ static OPUS_INLINE void silk_nsq_del_dec_scale_states( const silk_encoder_state *psEncC, /* I Encoder State */ silk_nsq_state *NSQ, /* I/O NSQ state */ NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ const opus_int16 x16[], /* I Input */ opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */ const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */ opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ opus_int subfr, /* I Subframe number */ opus_int nStatesDelayedDecision, /* I Number of del dec states */ const opus_int LTP_scale_Q14, /* I LTP state scaling */ const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ const opus_int signal_type, /* I Signal type */ const opus_int decisionDelay /* I Decision delay */ ) { opus_int i, k, lag; opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q26; NSQ_del_dec_struct *psDD; lag = pitchL[ subfr ]; inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 ); silk_assert( inv_gain_Q31 != 0 ); /* Scale input */ inv_gain_Q26 = silk_RSHIFT_ROUND( inv_gain_Q31, 5 ); for( i = 0; i < psEncC->subfr_length; i++ ) { x_sc_Q10[ i ] = silk_SMULWW( x16[ i ], inv_gain_Q26 ); } /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */ if( NSQ->rewhite_flag ) { if( subfr == 0 ) { /* Do LTP downscaling */ inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 ); } for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) { silk_assert( i < MAX_FRAME_LENGTH ); sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] ); } } /* Adjust for changing gain */ if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) { gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 ); /* Scale long-term shaping state */ for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx; i++ ) { NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] ); } /* Scale long-term prediction state */ if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) { for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx - decisionDelay; i++ ) { sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] ); } } for( k = 0; k < nStatesDelayedDecision; k++ ) { psDD = &psDelDec[ k ]; /* Scale scalar states */ psDD->LF_AR_Q14 = silk_SMULWW( gain_adj_Q16, psDD->LF_AR_Q14 ); psDD->Diff_Q14 = silk_SMULWW( gain_adj_Q16, psDD->Diff_Q14 ); /* Scale short-term prediction and shaping states */ for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) { psDD->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sLPC_Q14[ i ] ); } for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) { psDD->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sAR2_Q14[ i ] ); } for( i = 0; i < DECISION_DELAY; i++ ) { psDD->Pred_Q15[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Pred_Q15[ i ] ); psDD->Shape_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Shape_Q14[ i ] ); } } /* Save inverse gain */ NSQ->prev_gain_Q16 = Gains_Q16[ subfr ]; } } jamulus-3.9.1+dfsg/libs/opus/silk/NLSF_unpack.c0000644000175000017500000000560514340334543020312 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" /* Unpack predictor values and indices for entropy coding tables */ void silk_NLSF_unpack( opus_int16 ec_ix[], /* O Indices to entropy tables [ LPC_ORDER ] */ opus_uint8 pred_Q8[], /* O LSF predictor [ LPC_ORDER ] */ const silk_NLSF_CB_struct *psNLSF_CB, /* I Codebook object */ const opus_int CB1_index /* I Index of vector in first LSF codebook */ ) { opus_int i; opus_uint8 entry; const opus_uint8 *ec_sel_ptr; ec_sel_ptr = &psNLSF_CB->ec_sel[ CB1_index * psNLSF_CB->order / 2 ]; for( i = 0; i < psNLSF_CB->order; i += 2 ) { entry = *ec_sel_ptr++; ec_ix [ i ] = silk_SMULBB( silk_RSHIFT( entry, 1 ) & 7, 2 * NLSF_QUANT_MAX_AMPLITUDE + 1 ); pred_Q8[ i ] = psNLSF_CB->pred_Q8[ i + ( entry & 1 ) * ( psNLSF_CB->order - 1 ) ]; ec_ix [ i + 1 ] = silk_SMULBB( silk_RSHIFT( entry, 5 ) & 7, 2 * NLSF_QUANT_MAX_AMPLITUDE + 1 ); pred_Q8[ i + 1 ] = psNLSF_CB->pred_Q8[ i + ( silk_RSHIFT( entry, 4 ) & 1 ) * ( psNLSF_CB->order - 1 ) + 1 ]; } } jamulus-3.9.1+dfsg/libs/opus/silk/tables_other.c0000644000175000017500000001125714340334543020662 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "structs.h" #include "define.h" #include "tables.h" #ifdef __cplusplus extern "C" { #endif /* Tables for stereo predictor coding */ const opus_int16 silk_stereo_pred_quant_Q13[ STEREO_QUANT_TAB_SIZE ] = { -13732, -10050, -8266, -7526, -6500, -5000, -2950, -820, 820, 2950, 5000, 6500, 7526, 8266, 10050, 13732 }; const opus_uint8 silk_stereo_pred_joint_iCDF[ 25 ] = { 249, 247, 246, 245, 244, 234, 210, 202, 201, 200, 197, 174, 82, 59, 56, 55, 54, 46, 22, 12, 11, 10, 9, 7, 0 }; const opus_uint8 silk_stereo_only_code_mid_iCDF[ 2 ] = { 64, 0 }; /* Tables for LBRR flags */ static const opus_uint8 silk_LBRR_flags_2_iCDF[ 3 ] = { 203, 150, 0 }; static const opus_uint8 silk_LBRR_flags_3_iCDF[ 7 ] = { 215, 195, 166, 125, 110, 82, 0 }; const opus_uint8 * const silk_LBRR_flags_iCDF_ptr[ 2 ] = { silk_LBRR_flags_2_iCDF, silk_LBRR_flags_3_iCDF }; /* Table for LSB coding */ const opus_uint8 silk_lsb_iCDF[ 2 ] = { 120, 0 }; /* Tables for LTPScale */ const opus_uint8 silk_LTPscale_iCDF[ 3 ] = { 128, 64, 0 }; /* Tables for signal type and offset coding */ const opus_uint8 silk_type_offset_VAD_iCDF[ 4 ] = { 232, 158, 10, 0 }; const opus_uint8 silk_type_offset_no_VAD_iCDF[ 2 ] = { 230, 0 }; /* Tables for NLSF interpolation factor */ const opus_uint8 silk_NLSF_interpolation_factor_iCDF[ 5 ] = { 243, 221, 192, 181, 0 }; /* Quantization offsets */ const opus_int16 silk_Quantization_Offsets_Q10[ 2 ][ 2 ] = { { OFFSET_UVL_Q10, OFFSET_UVH_Q10 }, { OFFSET_VL_Q10, OFFSET_VH_Q10 } }; /* Table for LTPScale */ const opus_int16 silk_LTPScales_table_Q14[ 3 ] = { 15565, 12288, 8192 }; /* Uniform entropy tables */ const opus_uint8 silk_uniform3_iCDF[ 3 ] = { 171, 85, 0 }; const opus_uint8 silk_uniform4_iCDF[ 4 ] = { 192, 128, 64, 0 }; const opus_uint8 silk_uniform5_iCDF[ 5 ] = { 205, 154, 102, 51, 0 }; const opus_uint8 silk_uniform6_iCDF[ 6 ] = { 213, 171, 128, 85, 43, 0 }; const opus_uint8 silk_uniform8_iCDF[ 8 ] = { 224, 192, 160, 128, 96, 64, 32, 0 }; const opus_uint8 silk_NLSF_EXT_iCDF[ 7 ] = { 100, 40, 16, 7, 3, 1, 0 }; /* Elliptic/Cauer filters designed with 0.1 dB passband ripple, 80 dB minimum stopband attenuation, and [0.95 : 0.15 : 0.35] normalized cut off frequencies. */ /* Interpolation points for filter coefficients used in the bandwidth transition smoother */ const opus_int32 silk_Transition_LP_B_Q28[ TRANSITION_INT_NUM ][ TRANSITION_NB ] = { { 250767114, 501534038, 250767114 }, { 209867381, 419732057, 209867381 }, { 170987846, 341967853, 170987846 }, { 131531482, 263046905, 131531482 }, { 89306658, 178584282, 89306658 } }; /* Interpolation points for filter coefficients used in the bandwidth transition smoother */ const opus_int32 silk_Transition_LP_A_Q28[ TRANSITION_INT_NUM ][ TRANSITION_NA ] = { { 506393414, 239854379 }, { 411067935, 169683996 }, { 306733530, 116694253 }, { 185807084, 77959395 }, { 35497197, 57401098 } }; #ifdef __cplusplus } #endif jamulus-3.9.1+dfsg/libs/opus/silk/NLSF_VQ_weights_laroia.c0000644000175000017500000000754114340334543022441 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "define.h" #include "SigProc_FIX.h" /* R. Laroia, N. Phamdo and N. Farvardin, "Robust and Efficient Quantization of Speech LSP Parameters Using Structured Vector Quantization", Proc. IEEE Int. Conf. Acoust., Speech, Signal Processing, pp. 641-644, 1991. */ /* Laroia low complexity NLSF weights */ void silk_NLSF_VQ_weights_laroia( opus_int16 *pNLSFW_Q_OUT, /* O Pointer to input vector weights [D] */ const opus_int16 *pNLSF_Q15, /* I Pointer to input vector [D] */ const opus_int D /* I Input vector dimension (even) */ ) { opus_int k; opus_int32 tmp1_int, tmp2_int; celt_assert( D > 0 ); celt_assert( ( D & 1 ) == 0 ); /* First value */ tmp1_int = silk_max_int( pNLSF_Q15[ 0 ], 1 ); tmp1_int = silk_DIV32_16( (opus_int32)1 << ( 15 + NLSF_W_Q ), tmp1_int ); tmp2_int = silk_max_int( pNLSF_Q15[ 1 ] - pNLSF_Q15[ 0 ], 1 ); tmp2_int = silk_DIV32_16( (opus_int32)1 << ( 15 + NLSF_W_Q ), tmp2_int ); pNLSFW_Q_OUT[ 0 ] = (opus_int16)silk_min_int( tmp1_int + tmp2_int, silk_int16_MAX ); silk_assert( pNLSFW_Q_OUT[ 0 ] > 0 ); /* Main loop */ for( k = 1; k < D - 1; k += 2 ) { tmp1_int = silk_max_int( pNLSF_Q15[ k + 1 ] - pNLSF_Q15[ k ], 1 ); tmp1_int = silk_DIV32_16( (opus_int32)1 << ( 15 + NLSF_W_Q ), tmp1_int ); pNLSFW_Q_OUT[ k ] = (opus_int16)silk_min_int( tmp1_int + tmp2_int, silk_int16_MAX ); silk_assert( pNLSFW_Q_OUT[ k ] > 0 ); tmp2_int = silk_max_int( pNLSF_Q15[ k + 2 ] - pNLSF_Q15[ k + 1 ], 1 ); tmp2_int = silk_DIV32_16( (opus_int32)1 << ( 15 + NLSF_W_Q ), tmp2_int ); pNLSFW_Q_OUT[ k + 1 ] = (opus_int16)silk_min_int( tmp1_int + tmp2_int, silk_int16_MAX ); silk_assert( pNLSFW_Q_OUT[ k + 1 ] > 0 ); } /* Last value */ tmp1_int = silk_max_int( ( 1 << 15 ) - pNLSF_Q15[ D - 1 ], 1 ); tmp1_int = silk_DIV32_16( (opus_int32)1 << ( 15 + NLSF_W_Q ), tmp1_int ); pNLSFW_Q_OUT[ D - 1 ] = (opus_int16)silk_min_int( tmp1_int + tmp2_int, silk_int16_MAX ); silk_assert( pNLSFW_Q_OUT[ D - 1 ] > 0 ); } jamulus-3.9.1+dfsg/libs/opus/silk/biquad_alt.c0000644000175000017500000001534614340334543020317 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ /* * * silk_biquad_alt.c * * * * Second order ARMA filter * * Can handle slowly varying filter coefficients * * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FIX.h" /* Second order ARMA filter, alternative implementation */ void silk_biquad_alt_stride1( const opus_int16 *in, /* I input signal */ const opus_int32 *B_Q28, /* I MA coefficients [3] */ const opus_int32 *A_Q28, /* I AR coefficients [2] */ opus_int32 *S, /* I/O State vector [2] */ opus_int16 *out, /* O output signal */ const opus_int32 len /* I signal length (must be even) */ ) { /* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */ opus_int k; opus_int32 inval, A0_U_Q28, A0_L_Q28, A1_U_Q28, A1_L_Q28, out32_Q14; /* Negate A_Q28 values and split in two parts */ A0_L_Q28 = ( -A_Q28[ 0 ] ) & 0x00003FFF; /* lower part */ A0_U_Q28 = silk_RSHIFT( -A_Q28[ 0 ], 14 ); /* upper part */ A1_L_Q28 = ( -A_Q28[ 1 ] ) & 0x00003FFF; /* lower part */ A1_U_Q28 = silk_RSHIFT( -A_Q28[ 1 ], 14 ); /* upper part */ for( k = 0; k < len; k++ ) { /* S[ 0 ], S[ 1 ]: Q12 */ inval = in[ k ]; out32_Q14 = silk_LSHIFT( silk_SMLAWB( S[ 0 ], B_Q28[ 0 ], inval ), 2 ); S[ 0 ] = S[1] + silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14, A0_L_Q28 ), 14 ); S[ 0 ] = silk_SMLAWB( S[ 0 ], out32_Q14, A0_U_Q28 ); S[ 0 ] = silk_SMLAWB( S[ 0 ], B_Q28[ 1 ], inval); S[ 1 ] = silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14, A1_L_Q28 ), 14 ); S[ 1 ] = silk_SMLAWB( S[ 1 ], out32_Q14, A1_U_Q28 ); S[ 1 ] = silk_SMLAWB( S[ 1 ], B_Q28[ 2 ], inval ); /* Scale back to Q0 and saturate */ out[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14 + (1<<14) - 1, 14 ) ); } } void silk_biquad_alt_stride2_c( const opus_int16 *in, /* I input signal */ const opus_int32 *B_Q28, /* I MA coefficients [3] */ const opus_int32 *A_Q28, /* I AR coefficients [2] */ opus_int32 *S, /* I/O State vector [4] */ opus_int16 *out, /* O output signal */ const opus_int32 len /* I signal length (must be even) */ ) { /* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */ opus_int k; opus_int32 A0_U_Q28, A0_L_Q28, A1_U_Q28, A1_L_Q28, out32_Q14[ 2 ]; /* Negate A_Q28 values and split in two parts */ A0_L_Q28 = ( -A_Q28[ 0 ] ) & 0x00003FFF; /* lower part */ A0_U_Q28 = silk_RSHIFT( -A_Q28[ 0 ], 14 ); /* upper part */ A1_L_Q28 = ( -A_Q28[ 1 ] ) & 0x00003FFF; /* lower part */ A1_U_Q28 = silk_RSHIFT( -A_Q28[ 1 ], 14 ); /* upper part */ for( k = 0; k < len; k++ ) { /* S[ 0 ], S[ 1 ], S[ 2 ], S[ 3 ]: Q12 */ out32_Q14[ 0 ] = silk_LSHIFT( silk_SMLAWB( S[ 0 ], B_Q28[ 0 ], in[ 2 * k + 0 ] ), 2 ); out32_Q14[ 1 ] = silk_LSHIFT( silk_SMLAWB( S[ 2 ], B_Q28[ 0 ], in[ 2 * k + 1 ] ), 2 ); S[ 0 ] = S[ 1 ] + silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14[ 0 ], A0_L_Q28 ), 14 ); S[ 2 ] = S[ 3 ] + silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14[ 1 ], A0_L_Q28 ), 14 ); S[ 0 ] = silk_SMLAWB( S[ 0 ], out32_Q14[ 0 ], A0_U_Q28 ); S[ 2 ] = silk_SMLAWB( S[ 2 ], out32_Q14[ 1 ], A0_U_Q28 ); S[ 0 ] = silk_SMLAWB( S[ 0 ], B_Q28[ 1 ], in[ 2 * k + 0 ] ); S[ 2 ] = silk_SMLAWB( S[ 2 ], B_Q28[ 1 ], in[ 2 * k + 1 ] ); S[ 1 ] = silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14[ 0 ], A1_L_Q28 ), 14 ); S[ 3 ] = silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14[ 1 ], A1_L_Q28 ), 14 ); S[ 1 ] = silk_SMLAWB( S[ 1 ], out32_Q14[ 0 ], A1_U_Q28 ); S[ 3 ] = silk_SMLAWB( S[ 3 ], out32_Q14[ 1 ], A1_U_Q28 ); S[ 1 ] = silk_SMLAWB( S[ 1 ], B_Q28[ 2 ], in[ 2 * k + 0 ] ); S[ 3 ] = silk_SMLAWB( S[ 3 ], B_Q28[ 2 ], in[ 2 * k + 1 ] ); /* Scale back to Q0 and saturate */ out[ 2 * k + 0 ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14[ 0 ] + (1<<14) - 1, 14 ) ); out[ 2 * k + 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14[ 1 ] + (1<<14) - 1, 14 ) ); } } jamulus-3.9.1+dfsg/libs/opus/silk/resampler_private_IIR_FIR.c0000644000175000017500000001215714340334543023136 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FIX.h" #include "resampler_private.h" #include "stack_alloc.h" static OPUS_INLINE opus_int16 *silk_resampler_private_IIR_FIR_INTERPOL( opus_int16 *out, opus_int16 *buf, opus_int32 max_index_Q16, opus_int32 index_increment_Q16 ) { opus_int32 index_Q16, res_Q15; opus_int16 *buf_ptr; opus_int32 table_index; /* Interpolate upsampled signal and store in output array */ for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) { table_index = silk_SMULWB( index_Q16 & 0xFFFF, 12 ); buf_ptr = &buf[ index_Q16 >> 16 ]; res_Q15 = silk_SMULBB( buf_ptr[ 0 ], silk_resampler_frac_FIR_12[ table_index ][ 0 ] ); res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 1 ], silk_resampler_frac_FIR_12[ table_index ][ 1 ] ); res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 2 ], silk_resampler_frac_FIR_12[ table_index ][ 2 ] ); res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 3 ], silk_resampler_frac_FIR_12[ table_index ][ 3 ] ); res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 4 ], silk_resampler_frac_FIR_12[ 11 - table_index ][ 3 ] ); res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 5 ], silk_resampler_frac_FIR_12[ 11 - table_index ][ 2 ] ); res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 6 ], silk_resampler_frac_FIR_12[ 11 - table_index ][ 1 ] ); res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 7 ], silk_resampler_frac_FIR_12[ 11 - table_index ][ 0 ] ); *out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q15, 15 ) ); } return out; } /* Upsample using a combination of allpass-based 2x upsampling and FIR interpolation */ void silk_resampler_private_IIR_FIR( void *SS, /* I/O Resampler state */ opus_int16 out[], /* O Output signal */ const opus_int16 in[], /* I Input signal */ opus_int32 inLen /* I Number of input samples */ ) { silk_resampler_state_struct *S = (silk_resampler_state_struct *)SS; opus_int32 nSamplesIn; opus_int32 max_index_Q16, index_increment_Q16; VARDECL( opus_int16, buf ); SAVE_STACK; ALLOC( buf, 2 * S->batchSize + RESAMPLER_ORDER_FIR_12, opus_int16 ); /* Copy buffered samples to start of buffer */ silk_memcpy( buf, S->sFIR.i16, RESAMPLER_ORDER_FIR_12 * sizeof( opus_int16 ) ); /* Iterate over blocks of frameSizeIn input samples */ index_increment_Q16 = S->invRatio_Q16; while( 1 ) { nSamplesIn = silk_min( inLen, S->batchSize ); /* Upsample 2x */ silk_resampler_private_up2_HQ( S->sIIR, &buf[ RESAMPLER_ORDER_FIR_12 ], in, nSamplesIn ); max_index_Q16 = silk_LSHIFT32( nSamplesIn, 16 + 1 ); /* + 1 because 2x upsampling */ out = silk_resampler_private_IIR_FIR_INTERPOL( out, buf, max_index_Q16, index_increment_Q16 ); in += nSamplesIn; inLen -= nSamplesIn; if( inLen > 0 ) { /* More iterations to do; copy last part of filtered signal to beginning of buffer */ silk_memcpy( buf, &buf[ nSamplesIn << 1 ], RESAMPLER_ORDER_FIR_12 * sizeof( opus_int16 ) ); } else { break; } } /* Copy last part of filtered signal to the state for the next call */ silk_memcpy( S->sFIR.i16, &buf[ nSamplesIn << 1 ], RESAMPLER_ORDER_FIR_12 * sizeof( opus_int16 ) ); RESTORE_STACK; } jamulus-3.9.1+dfsg/libs/opus/silk/stereo_find_predictor.c0000644000175000017500000001042614340334543022560 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" /* Find least-squares prediction gain for one signal based on another and quantize it */ opus_int32 silk_stereo_find_predictor( /* O Returns predictor in Q13 */ opus_int32 *ratio_Q14, /* O Ratio of residual and mid energies */ const opus_int16 x[], /* I Basis signal */ const opus_int16 y[], /* I Target signal */ opus_int32 mid_res_amp_Q0[], /* I/O Smoothed mid, residual norms */ opus_int length, /* I Number of samples */ opus_int smooth_coef_Q16 /* I Smoothing coefficient */ ) { opus_int scale, scale1, scale2; opus_int32 nrgx, nrgy, corr, pred_Q13, pred2_Q10; /* Find predictor */ silk_sum_sqr_shift( &nrgx, &scale1, x, length ); silk_sum_sqr_shift( &nrgy, &scale2, y, length ); scale = silk_max_int( scale1, scale2 ); scale = scale + ( scale & 1 ); /* make even */ nrgy = silk_RSHIFT32( nrgy, scale - scale2 ); nrgx = silk_RSHIFT32( nrgx, scale - scale1 ); nrgx = silk_max_int( nrgx, 1 ); corr = silk_inner_prod_aligned_scale( x, y, scale, length ); pred_Q13 = silk_DIV32_varQ( corr, nrgx, 13 ); pred_Q13 = silk_LIMIT( pred_Q13, -(1 << 14), 1 << 14 ); pred2_Q10 = silk_SMULWB( pred_Q13, pred_Q13 ); /* Faster update for signals with large prediction parameters */ smooth_coef_Q16 = (opus_int)silk_max_int( smooth_coef_Q16, silk_abs( pred2_Q10 ) ); /* Smoothed mid and residual norms */ silk_assert( smooth_coef_Q16 < 32768 ); scale = silk_RSHIFT( scale, 1 ); mid_res_amp_Q0[ 0 ] = silk_SMLAWB( mid_res_amp_Q0[ 0 ], silk_LSHIFT( silk_SQRT_APPROX( nrgx ), scale ) - mid_res_amp_Q0[ 0 ], smooth_coef_Q16 ); /* Residual energy = nrgy - 2 * pred * corr + pred^2 * nrgx */ nrgy = silk_SUB_LSHIFT32( nrgy, silk_SMULWB( corr, pred_Q13 ), 3 + 1 ); nrgy = silk_ADD_LSHIFT32( nrgy, silk_SMULWB( nrgx, pred2_Q10 ), 6 ); mid_res_amp_Q0[ 1 ] = silk_SMLAWB( mid_res_amp_Q0[ 1 ], silk_LSHIFT( silk_SQRT_APPROX( nrgy ), scale ) - mid_res_amp_Q0[ 1 ], smooth_coef_Q16 ); /* Ratio of smoothed residual and mid norms */ *ratio_Q14 = silk_DIV32_varQ( mid_res_amp_Q0[ 1 ], silk_max( mid_res_amp_Q0[ 0 ], 1 ), 14 ); *ratio_Q14 = silk_LIMIT( *ratio_Q14, 0, 32767 ); return pred_Q13; } jamulus-3.9.1+dfsg/libs/opus/silk/control_SNR.c0000644000175000017500000001250714340334543020410 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" #include "tuning_parameters.h" /* These tables hold SNR values divided by 21 (so they fit in 8 bits) for different target bitrates spaced at 400 bps interval. The first 10 values are omitted (0-4 kb/s) because they're all zeros. These tables were obtained by running different SNRs through the encoder and measuring the active bitrate. */ static const unsigned char silk_TargetRate_NB_21[117 - 10] = { 0, 15, 39, 52, 61, 68, 74, 79, 84, 88, 92, 95, 99,102,105,108,111,114,117,119,122,124, 126,129,131,133,135,137,139,142,143,145,147,149,151,153,155,157, 158,160,162,163,165,167,168,170,171,173,174,176,177,179,180,182, 183,185,186,187,189,190,192,193,194,196,197,199,200,201,203,204, 205,207,208,209,211,212,213,215,216,217,219,220,221,223,224,225, 227,228,230,231,232,234,235,236,238,239,241,242,243,245,246,248, 249,250,252,253,255 }; static const unsigned char silk_TargetRate_MB_21[165 - 10] = { 0, 0, 28, 43, 52, 59, 65, 70, 74, 78, 81, 85, 87, 90, 93, 95, 98,100,102,105,107,109, 111,113,115,116,118,120,122,123,125,127,128,130,131,133,134,136, 137,138,140,141,143,144,145,147,148,149,151,152,153,154,156,157, 158,159,160,162,163,164,165,166,167,168,169,171,172,173,174,175, 176,177,178,179,180,181,182,183,184,185,186,187,188,188,189,190, 191,192,193,194,195,196,197,198,199,200,201,202,203,203,204,205, 206,207,208,209,210,211,212,213,214,214,215,216,217,218,219,220, 221,222,223,224,224,225,226,227,228,229,230,231,232,233,234,235, 236,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250, 251,252,253,254,255 }; static const unsigned char silk_TargetRate_WB_21[201 - 10] = { 0, 0, 0, 8, 29, 41, 49, 56, 62, 66, 70, 74, 77, 80, 83, 86, 88, 91, 93, 95, 97, 99, 101,103,105,107,108,110,112,113,115,116,118,119,121,122,123,125, 126,127,129,130,131,132,134,135,136,137,138,140,141,142,143,144, 145,146,147,148,149,150,151,152,153,154,156,157,158,159,159,160, 161,162,163,164,165,166,167,168,169,170,171,171,172,173,174,175, 176,177,177,178,179,180,181,181,182,183,184,185,185,186,187,188, 189,189,190,191,192,192,193,194,195,195,196,197,198,198,199,200, 200,201,202,203,203,204,205,206,206,207,208,209,209,210,211,211, 212,213,214,214,215,216,216,217,218,219,219,220,221,221,222,223, 224,224,225,226,226,227,228,229,229,230,231,232,232,233,234,234, 235,236,237,237,238,239,240,240,241,242,243,243,244,245,246,246, 247,248,249,249,250,251,252,253,255 }; /* Control SNR of residual quantizer */ opus_int silk_control_SNR( silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */ opus_int32 TargetRate_bps /* I Target max bitrate (bps) */ ) { int id; int bound; const unsigned char *snr_table; psEncC->TargetRate_bps = TargetRate_bps; if( psEncC->nb_subfr == 2 ) { TargetRate_bps -= 2000 + psEncC->fs_kHz/16; } if( psEncC->fs_kHz == 8 ) { bound = sizeof(silk_TargetRate_NB_21); snr_table = silk_TargetRate_NB_21; } else if( psEncC->fs_kHz == 12 ) { bound = sizeof(silk_TargetRate_MB_21); snr_table = silk_TargetRate_MB_21; } else { bound = sizeof(silk_TargetRate_WB_21); snr_table = silk_TargetRate_WB_21; } id = (TargetRate_bps+200)/400; id = silk_min(id - 10, bound-1); if( id <= 0 ) { psEncC->SNR_dB_Q7 = 0; } else { psEncC->SNR_dB_Q7 = snr_table[id]*21; } return SILK_NO_ERROR; } jamulus-3.9.1+dfsg/libs/opus/silk/lin2log.c0000644000175000017500000000425414340334543017554 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FIX.h" /* Approximation of 128 * log2() (very close inverse of silk_log2lin()) */ /* Convert input to a log scale */ opus_int32 silk_lin2log( const opus_int32 inLin /* I input in linear scale */ ) { opus_int32 lz, frac_Q7; silk_CLZ_FRAC( inLin, &lz, &frac_Q7 ); /* Piece-wise parabolic approximation */ return silk_ADD_LSHIFT32( silk_SMLAWB( frac_Q7, silk_MUL( frac_Q7, 128 - frac_Q7 ), 179 ), 31 - lz, 7 ); } jamulus-3.9.1+dfsg/libs/opus/silk/sum_sqr_shift.c0000644000175000017500000000731614340334543021076 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FIX.h" /* Compute number of bits to right shift the sum of squares of a vector */ /* of int16s to make it fit in an int32 */ void silk_sum_sqr_shift( opus_int32 *energy, /* O Energy of x, after shifting to the right */ opus_int *shift, /* O Number of bits right shift applied to energy */ const opus_int16 *x, /* I Input vector */ opus_int len /* I Length of input vector */ ) { opus_int i, shft; opus_uint32 nrg_tmp; opus_int32 nrg; /* Do a first run with the maximum shift we could have. */ shft = 31-silk_CLZ32(len); /* Let's be conservative with rounding and start with nrg=len. */ nrg = len; for( i = 0; i < len - 1; i += 2 ) { nrg_tmp = silk_SMULBB( x[ i ], x[ i ] ); nrg_tmp = silk_SMLABB_ovflw( nrg_tmp, x[ i + 1 ], x[ i + 1 ] ); nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft ); } if( i < len ) { /* One sample left to process */ nrg_tmp = silk_SMULBB( x[ i ], x[ i ] ); nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft ); } silk_assert( nrg >= 0 ); /* Make sure the result will fit in a 32-bit signed integer with two bits of headroom. */ shft = silk_max_32(0, shft+3 - silk_CLZ32(nrg)); nrg = 0; for( i = 0 ; i < len - 1; i += 2 ) { nrg_tmp = silk_SMULBB( x[ i ], x[ i ] ); nrg_tmp = silk_SMLABB_ovflw( nrg_tmp, x[ i + 1 ], x[ i + 1 ] ); nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft ); } if( i < len ) { /* One sample left to process */ nrg_tmp = silk_SMULBB( x[ i ], x[ i ] ); nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft ); } silk_assert( nrg >= 0 ); /* Output arguments */ *shift = shft; *energy = nrg; } jamulus-3.9.1+dfsg/libs/opus/silk/enc_API.c0000644000175000017500000007526114340334543017452 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "define.h" #include "API.h" #include "control.h" #include "typedef.h" #include "stack_alloc.h" #include "structs.h" #include "tuning_parameters.h" #ifdef FIXED_POINT #include "main_FIX.h" #else #include "main_FLP.h" #endif /***************************************/ /* Read control structure from encoder */ /***************************************/ static opus_int silk_QueryEncoder( /* O Returns error code */ const void *encState, /* I State */ silk_EncControlStruct *encStatus /* O Encoder Status */ ); /****************************************/ /* Encoder functions */ /****************************************/ opus_int silk_Get_Encoder_Size( /* O Returns error code */ opus_int *encSizeBytes /* O Number of bytes in SILK encoder state */ ) { opus_int ret = SILK_NO_ERROR; *encSizeBytes = sizeof( silk_encoder ); return ret; } /*************************/ /* Init or Reset encoder */ /*************************/ opus_int silk_InitEncoder( /* O Returns error code */ void *encState, /* I/O State */ int arch, /* I Run-time architecture */ silk_EncControlStruct *encStatus /* O Encoder Status */ ) { silk_encoder *psEnc; opus_int n, ret = SILK_NO_ERROR; psEnc = (silk_encoder *)encState; /* Reset encoder */ silk_memset( psEnc, 0, sizeof( silk_encoder ) ); for( n = 0; n < ENCODER_NUM_CHANNELS; n++ ) { if( ret += silk_init_encoder( &psEnc->state_Fxx[ n ], arch ) ) { celt_assert( 0 ); } } psEnc->nChannelsAPI = 1; psEnc->nChannelsInternal = 1; /* Read control structure */ if( ret += silk_QueryEncoder( encState, encStatus ) ) { celt_assert( 0 ); } return ret; } /***************************************/ /* Read control structure from encoder */ /***************************************/ static opus_int silk_QueryEncoder( /* O Returns error code */ const void *encState, /* I State */ silk_EncControlStruct *encStatus /* O Encoder Status */ ) { opus_int ret = SILK_NO_ERROR; silk_encoder_state_Fxx *state_Fxx; silk_encoder *psEnc = (silk_encoder *)encState; state_Fxx = psEnc->state_Fxx; encStatus->nChannelsAPI = psEnc->nChannelsAPI; encStatus->nChannelsInternal = psEnc->nChannelsInternal; encStatus->API_sampleRate = state_Fxx[ 0 ].sCmn.API_fs_Hz; encStatus->maxInternalSampleRate = state_Fxx[ 0 ].sCmn.maxInternal_fs_Hz; encStatus->minInternalSampleRate = state_Fxx[ 0 ].sCmn.minInternal_fs_Hz; encStatus->desiredInternalSampleRate = state_Fxx[ 0 ].sCmn.desiredInternal_fs_Hz; encStatus->payloadSize_ms = state_Fxx[ 0 ].sCmn.PacketSize_ms; encStatus->bitRate = state_Fxx[ 0 ].sCmn.TargetRate_bps; encStatus->packetLossPercentage = state_Fxx[ 0 ].sCmn.PacketLoss_perc; encStatus->complexity = state_Fxx[ 0 ].sCmn.Complexity; encStatus->useInBandFEC = state_Fxx[ 0 ].sCmn.useInBandFEC; encStatus->useDTX = state_Fxx[ 0 ].sCmn.useDTX; encStatus->useCBR = state_Fxx[ 0 ].sCmn.useCBR; encStatus->internalSampleRate = silk_SMULBB( state_Fxx[ 0 ].sCmn.fs_kHz, 1000 ); encStatus->allowBandwidthSwitch = state_Fxx[ 0 ].sCmn.allow_bandwidth_switch; encStatus->inWBmodeWithoutVariableLP = state_Fxx[ 0 ].sCmn.fs_kHz == 16 && state_Fxx[ 0 ].sCmn.sLP.mode == 0; return ret; } /**************************/ /* Encode frame with Silk */ /**************************/ /* Note: if prefillFlag is set, the input must contain 10 ms of audio, irrespective of what */ /* encControl->payloadSize_ms is set to */ opus_int silk_Encode( /* O Returns error code */ void *encState, /* I/O State */ silk_EncControlStruct *encControl, /* I Control status */ const opus_int16 *samplesIn, /* I Speech sample input vector */ opus_int nSamplesIn, /* I Number of samples in input vector */ ec_enc *psRangeEnc, /* I/O Compressor data structure */ opus_int32 *nBytesOut, /* I/O Number of bytes in payload (input: Max bytes) */ const opus_int prefillFlag, /* I Flag to indicate prefilling buffers no coding */ opus_int activity /* I Decision of Opus voice activity detector */ ) { opus_int n, i, nBits, flags, tmp_payloadSize_ms = 0, tmp_complexity = 0, ret = 0; opus_int nSamplesToBuffer, nSamplesToBufferMax, nBlocksOf10ms; opus_int nSamplesFromInput = 0, nSamplesFromInputMax; opus_int speech_act_thr_for_switch_Q8; opus_int32 TargetRate_bps, MStargetRates_bps[ 2 ], channelRate_bps, LBRR_symbol, sum; silk_encoder *psEnc = ( silk_encoder * )encState; VARDECL( opus_int16, buf ); opus_int transition, curr_block, tot_blocks; SAVE_STACK; if (encControl->reducedDependency) { psEnc->state_Fxx[0].sCmn.first_frame_after_reset = 1; psEnc->state_Fxx[1].sCmn.first_frame_after_reset = 1; } psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded = psEnc->state_Fxx[ 1 ].sCmn.nFramesEncoded = 0; /* Check values in encoder control structure */ if( ( ret = check_control_input( encControl ) ) != 0 ) { celt_assert( 0 ); RESTORE_STACK; return ret; } encControl->switchReady = 0; if( encControl->nChannelsInternal > psEnc->nChannelsInternal ) { /* Mono -> Stereo transition: init state of second channel and stereo state */ ret += silk_init_encoder( &psEnc->state_Fxx[ 1 ], psEnc->state_Fxx[ 0 ].sCmn.arch ); silk_memset( psEnc->sStereo.pred_prev_Q13, 0, sizeof( psEnc->sStereo.pred_prev_Q13 ) ); silk_memset( psEnc->sStereo.sSide, 0, sizeof( psEnc->sStereo.sSide ) ); psEnc->sStereo.mid_side_amp_Q0[ 0 ] = 0; psEnc->sStereo.mid_side_amp_Q0[ 1 ] = 1; psEnc->sStereo.mid_side_amp_Q0[ 2 ] = 0; psEnc->sStereo.mid_side_amp_Q0[ 3 ] = 1; psEnc->sStereo.width_prev_Q14 = 0; psEnc->sStereo.smth_width_Q14 = SILK_FIX_CONST( 1, 14 ); if( psEnc->nChannelsAPI == 2 ) { silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, sizeof( silk_resampler_state_struct ) ); silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.In_HP_State, &psEnc->state_Fxx[ 0 ].sCmn.In_HP_State, sizeof( psEnc->state_Fxx[ 1 ].sCmn.In_HP_State ) ); } } transition = (encControl->payloadSize_ms != psEnc->state_Fxx[ 0 ].sCmn.PacketSize_ms) || (psEnc->nChannelsInternal != encControl->nChannelsInternal); psEnc->nChannelsAPI = encControl->nChannelsAPI; psEnc->nChannelsInternal = encControl->nChannelsInternal; nBlocksOf10ms = silk_DIV32( 100 * nSamplesIn, encControl->API_sampleRate ); tot_blocks = ( nBlocksOf10ms > 1 ) ? nBlocksOf10ms >> 1 : 1; curr_block = 0; if( prefillFlag ) { silk_LP_state save_LP; /* Only accept input length of 10 ms */ if( nBlocksOf10ms != 1 ) { celt_assert( 0 ); RESTORE_STACK; return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES; } if ( prefillFlag == 2 ) { save_LP = psEnc->state_Fxx[ 0 ].sCmn.sLP; /* Save the sampling rate so the bandwidth switching code can keep handling transitions. */ save_LP.saved_fs_kHz = psEnc->state_Fxx[ 0 ].sCmn.fs_kHz; } /* Reset Encoder */ for( n = 0; n < encControl->nChannelsInternal; n++ ) { ret = silk_init_encoder( &psEnc->state_Fxx[ n ], psEnc->state_Fxx[ n ].sCmn.arch ); /* Restore the variable LP state. */ if ( prefillFlag == 2 ) { psEnc->state_Fxx[ n ].sCmn.sLP = save_LP; } celt_assert( !ret ); } tmp_payloadSize_ms = encControl->payloadSize_ms; encControl->payloadSize_ms = 10; tmp_complexity = encControl->complexity; encControl->complexity = 0; for( n = 0; n < encControl->nChannelsInternal; n++ ) { psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0; psEnc->state_Fxx[ n ].sCmn.prefillFlag = 1; } } else { /* Only accept input lengths that are a multiple of 10 ms */ if( nBlocksOf10ms * encControl->API_sampleRate != 100 * nSamplesIn || nSamplesIn < 0 ) { celt_assert( 0 ); RESTORE_STACK; return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES; } /* Make sure no more than one packet can be produced */ if( 1000 * (opus_int32)nSamplesIn > encControl->payloadSize_ms * encControl->API_sampleRate ) { celt_assert( 0 ); RESTORE_STACK; return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES; } } for( n = 0; n < encControl->nChannelsInternal; n++ ) { /* Force the side channel to the same rate as the mid */ opus_int force_fs_kHz = (n==1) ? psEnc->state_Fxx[0].sCmn.fs_kHz : 0; if( ( ret = silk_control_encoder( &psEnc->state_Fxx[ n ], encControl, psEnc->allowBandwidthSwitch, n, force_fs_kHz ) ) != 0 ) { silk_assert( 0 ); RESTORE_STACK; return ret; } if( psEnc->state_Fxx[n].sCmn.first_frame_after_reset || transition ) { for( i = 0; i < psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket; i++ ) { psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ] = 0; } } psEnc->state_Fxx[ n ].sCmn.inDTX = psEnc->state_Fxx[ n ].sCmn.useDTX; } celt_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 0 ].sCmn.fs_kHz == psEnc->state_Fxx[ 1 ].sCmn.fs_kHz ); /* Input buffering/resampling and encoding */ nSamplesToBufferMax = 10 * nBlocksOf10ms * psEnc->state_Fxx[ 0 ].sCmn.fs_kHz; nSamplesFromInputMax = silk_DIV32_16( nSamplesToBufferMax * psEnc->state_Fxx[ 0 ].sCmn.API_fs_Hz, psEnc->state_Fxx[ 0 ].sCmn.fs_kHz * 1000 ); ALLOC( buf, nSamplesFromInputMax, opus_int16 ); while( 1 ) { nSamplesToBuffer = psEnc->state_Fxx[ 0 ].sCmn.frame_length - psEnc->state_Fxx[ 0 ].sCmn.inputBufIx; nSamplesToBuffer = silk_min( nSamplesToBuffer, nSamplesToBufferMax ); nSamplesFromInput = silk_DIV32_16( nSamplesToBuffer * psEnc->state_Fxx[ 0 ].sCmn.API_fs_Hz, psEnc->state_Fxx[ 0 ].sCmn.fs_kHz * 1000 ); /* Resample and write to buffer */ if( encControl->nChannelsAPI == 2 && encControl->nChannelsInternal == 2 ) { opus_int id = psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded; for( n = 0; n < nSamplesFromInput; n++ ) { buf[ n ] = samplesIn[ 2 * n ]; } /* Making sure to start both resamplers from the same state when switching from mono to stereo */ if( psEnc->nPrevChannelsInternal == 1 && id==0 ) { silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, sizeof(psEnc->state_Fxx[ 1 ].sCmn.resampler_state)); } ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput ); psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer; nSamplesToBuffer = psEnc->state_Fxx[ 1 ].sCmn.frame_length - psEnc->state_Fxx[ 1 ].sCmn.inputBufIx; nSamplesToBuffer = silk_min( nSamplesToBuffer, 10 * nBlocksOf10ms * psEnc->state_Fxx[ 1 ].sCmn.fs_kHz ); for( n = 0; n < nSamplesFromInput; n++ ) { buf[ n ] = samplesIn[ 2 * n + 1 ]; } ret += silk_resampler( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, &psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput ); psEnc->state_Fxx[ 1 ].sCmn.inputBufIx += nSamplesToBuffer; } else if( encControl->nChannelsAPI == 2 && encControl->nChannelsInternal == 1 ) { /* Combine left and right channels before resampling */ for( n = 0; n < nSamplesFromInput; n++ ) { sum = samplesIn[ 2 * n ] + samplesIn[ 2 * n + 1 ]; buf[ n ] = (opus_int16)silk_RSHIFT_ROUND( sum, 1 ); } ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput ); /* On the first mono frame, average the results for the two resampler states */ if( psEnc->nPrevChannelsInternal == 2 && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == 0 ) { ret += silk_resampler( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, &psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput ); for( n = 0; n < psEnc->state_Fxx[ 0 ].sCmn.frame_length; n++ ) { psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx+n+2 ] = silk_RSHIFT(psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx+n+2 ] + psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx+n+2 ], 1); } } psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer; } else { celt_assert( encControl->nChannelsAPI == 1 && encControl->nChannelsInternal == 1 ); silk_memcpy(buf, samplesIn, nSamplesFromInput*sizeof(opus_int16)); ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput ); psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer; } samplesIn += nSamplesFromInput * encControl->nChannelsAPI; nSamplesIn -= nSamplesFromInput; /* Default */ psEnc->allowBandwidthSwitch = 0; /* Silk encoder */ if( psEnc->state_Fxx[ 0 ].sCmn.inputBufIx >= psEnc->state_Fxx[ 0 ].sCmn.frame_length ) { /* Enough data in input buffer, so encode */ celt_assert( psEnc->state_Fxx[ 0 ].sCmn.inputBufIx == psEnc->state_Fxx[ 0 ].sCmn.frame_length ); celt_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 1 ].sCmn.inputBufIx == psEnc->state_Fxx[ 1 ].sCmn.frame_length ); /* Deal with LBRR data */ if( psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == 0 && !prefillFlag ) { /* Create space at start of payload for VAD and FEC flags */ opus_uint8 iCDF[ 2 ] = { 0, 0 }; iCDF[ 0 ] = 256 - silk_RSHIFT( 256, ( psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket + 1 ) * encControl->nChannelsInternal ); ec_enc_icdf( psRangeEnc, 0, iCDF, 8 ); /* Encode any LBRR data from previous packet */ /* Encode LBRR flags */ for( n = 0; n < encControl->nChannelsInternal; n++ ) { LBRR_symbol = 0; for( i = 0; i < psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket; i++ ) { LBRR_symbol |= silk_LSHIFT( psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ], i ); } psEnc->state_Fxx[ n ].sCmn.LBRR_flag = LBRR_symbol > 0 ? 1 : 0; if( LBRR_symbol && psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket > 1 ) { ec_enc_icdf( psRangeEnc, LBRR_symbol - 1, silk_LBRR_flags_iCDF_ptr[ psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket - 2 ], 8 ); } } /* Code LBRR indices and excitation signals */ for( i = 0; i < psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket; i++ ) { for( n = 0; n < encControl->nChannelsInternal; n++ ) { if( psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ] ) { opus_int condCoding; if( encControl->nChannelsInternal == 2 && n == 0 ) { silk_stereo_encode_pred( psRangeEnc, psEnc->sStereo.predIx[ i ] ); /* For LBRR data there's no need to code the mid-only flag if the side-channel LBRR flag is set */ if( psEnc->state_Fxx[ 1 ].sCmn.LBRR_flags[ i ] == 0 ) { silk_stereo_encode_mid_only( psRangeEnc, psEnc->sStereo.mid_only_flags[ i ] ); } } /* Use conditional coding if previous frame available */ if( i > 0 && psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i - 1 ] ) { condCoding = CODE_CONDITIONALLY; } else { condCoding = CODE_INDEPENDENTLY; } silk_encode_indices( &psEnc->state_Fxx[ n ].sCmn, psRangeEnc, i, 1, condCoding ); silk_encode_pulses( psRangeEnc, psEnc->state_Fxx[ n ].sCmn.indices_LBRR[i].signalType, psEnc->state_Fxx[ n ].sCmn.indices_LBRR[i].quantOffsetType, psEnc->state_Fxx[ n ].sCmn.pulses_LBRR[ i ], psEnc->state_Fxx[ n ].sCmn.frame_length ); } } } /* Reset LBRR flags */ for( n = 0; n < encControl->nChannelsInternal; n++ ) { silk_memset( psEnc->state_Fxx[ n ].sCmn.LBRR_flags, 0, sizeof( psEnc->state_Fxx[ n ].sCmn.LBRR_flags ) ); } psEnc->nBitsUsedLBRR = ec_tell( psRangeEnc ); } silk_HP_variable_cutoff( psEnc->state_Fxx ); /* Total target bits for packet */ nBits = silk_DIV32_16( silk_MUL( encControl->bitRate, encControl->payloadSize_ms ), 1000 ); /* Subtract bits used for LBRR */ if( !prefillFlag ) { nBits -= psEnc->nBitsUsedLBRR; } /* Divide by number of uncoded frames left in packet */ nBits = silk_DIV32_16( nBits, psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket ); /* Convert to bits/second */ if( encControl->payloadSize_ms == 10 ) { TargetRate_bps = silk_SMULBB( nBits, 100 ); } else { TargetRate_bps = silk_SMULBB( nBits, 50 ); } /* Subtract fraction of bits in excess of target in previous frames and packets */ TargetRate_bps -= silk_DIV32_16( silk_MUL( psEnc->nBitsExceeded, 1000 ), BITRESERVOIR_DECAY_TIME_MS ); if( !prefillFlag && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded > 0 ) { /* Compare actual vs target bits so far in this packet */ opus_int32 bitsBalance = ec_tell( psRangeEnc ) - psEnc->nBitsUsedLBRR - nBits * psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded; TargetRate_bps -= silk_DIV32_16( silk_MUL( bitsBalance, 1000 ), BITRESERVOIR_DECAY_TIME_MS ); } /* Never exceed input bitrate */ TargetRate_bps = silk_LIMIT( TargetRate_bps, encControl->bitRate, 5000 ); /* Convert Left/Right to Mid/Side */ if( encControl->nChannelsInternal == 2 ) { silk_stereo_LR_to_MS( &psEnc->sStereo, &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ 2 ], &psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ 2 ], psEnc->sStereo.predIx[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ], &psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ], MStargetRates_bps, TargetRate_bps, psEnc->state_Fxx[ 0 ].sCmn.speech_activity_Q8, encControl->toMono, psEnc->state_Fxx[ 0 ].sCmn.fs_kHz, psEnc->state_Fxx[ 0 ].sCmn.frame_length ); if( psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] == 0 ) { /* Reset side channel encoder memory for first frame with side coding */ if( psEnc->prev_decode_only_middle == 1 ) { silk_memset( &psEnc->state_Fxx[ 1 ].sShape, 0, sizeof( psEnc->state_Fxx[ 1 ].sShape ) ); silk_memset( &psEnc->state_Fxx[ 1 ].sCmn.sNSQ, 0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.sNSQ ) ); silk_memset( psEnc->state_Fxx[ 1 ].sCmn.prev_NLSFq_Q15, 0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.prev_NLSFq_Q15 ) ); silk_memset( &psEnc->state_Fxx[ 1 ].sCmn.sLP.In_LP_State, 0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.sLP.In_LP_State ) ); psEnc->state_Fxx[ 1 ].sCmn.prevLag = 100; psEnc->state_Fxx[ 1 ].sCmn.sNSQ.lagPrev = 100; psEnc->state_Fxx[ 1 ].sShape.LastGainIndex = 10; psEnc->state_Fxx[ 1 ].sCmn.prevSignalType = TYPE_NO_VOICE_ACTIVITY; psEnc->state_Fxx[ 1 ].sCmn.sNSQ.prev_gain_Q16 = 65536; psEnc->state_Fxx[ 1 ].sCmn.first_frame_after_reset = 1; } silk_encode_do_VAD_Fxx( &psEnc->state_Fxx[ 1 ], activity ); } else { psEnc->state_Fxx[ 1 ].sCmn.VAD_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] = 0; } if( !prefillFlag ) { silk_stereo_encode_pred( psRangeEnc, psEnc->sStereo.predIx[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] ); if( psEnc->state_Fxx[ 1 ].sCmn.VAD_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] == 0 ) { silk_stereo_encode_mid_only( psRangeEnc, psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] ); } } } else { /* Buffering */ silk_memcpy( psEnc->state_Fxx[ 0 ].sCmn.inputBuf, psEnc->sStereo.sMid, 2 * sizeof( opus_int16 ) ); silk_memcpy( psEnc->sStereo.sMid, &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.frame_length ], 2 * sizeof( opus_int16 ) ); } silk_encode_do_VAD_Fxx( &psEnc->state_Fxx[ 0 ], activity ); /* Encode */ for( n = 0; n < encControl->nChannelsInternal; n++ ) { opus_int maxBits, useCBR; /* Handling rate constraints */ maxBits = encControl->maxBits; if( tot_blocks == 2 && curr_block == 0 ) { maxBits = maxBits * 3 / 5; } else if( tot_blocks == 3 ) { if( curr_block == 0 ) { maxBits = maxBits * 2 / 5; } else if( curr_block == 1 ) { maxBits = maxBits * 3 / 4; } } useCBR = encControl->useCBR && curr_block == tot_blocks - 1; if( encControl->nChannelsInternal == 1 ) { channelRate_bps = TargetRate_bps; } else { channelRate_bps = MStargetRates_bps[ n ]; if( n == 0 && MStargetRates_bps[ 1 ] > 0 ) { useCBR = 0; /* Give mid up to 1/2 of the max bits for that frame */ maxBits -= encControl->maxBits / ( tot_blocks * 2 ); } } if( channelRate_bps > 0 ) { opus_int condCoding; silk_control_SNR( &psEnc->state_Fxx[ n ].sCmn, channelRate_bps ); /* Use independent coding if no previous frame available */ if( psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded - n <= 0 ) { condCoding = CODE_INDEPENDENTLY; } else if( n > 0 && psEnc->prev_decode_only_middle ) { /* If we skipped a side frame in this packet, we don't need LTP scaling; the LTP state is well-defined. */ condCoding = CODE_INDEPENDENTLY_NO_LTP_SCALING; } else { condCoding = CODE_CONDITIONALLY; } if( ( ret = silk_encode_frame_Fxx( &psEnc->state_Fxx[ n ], nBytesOut, psRangeEnc, condCoding, maxBits, useCBR ) ) != 0 ) { silk_assert( 0 ); } } psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0; psEnc->state_Fxx[ n ].sCmn.inputBufIx = 0; psEnc->state_Fxx[ n ].sCmn.nFramesEncoded++; } psEnc->prev_decode_only_middle = psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded - 1 ]; /* Insert VAD and FEC flags at beginning of bitstream */ if( *nBytesOut > 0 && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket) { flags = 0; for( n = 0; n < encControl->nChannelsInternal; n++ ) { for( i = 0; i < psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket; i++ ) { flags = silk_LSHIFT( flags, 1 ); flags |= psEnc->state_Fxx[ n ].sCmn.VAD_flags[ i ]; } flags = silk_LSHIFT( flags, 1 ); flags |= psEnc->state_Fxx[ n ].sCmn.LBRR_flag; } if( !prefillFlag ) { ec_enc_patch_initial_bits( psRangeEnc, flags, ( psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket + 1 ) * encControl->nChannelsInternal ); } /* Return zero bytes if all channels DTXed */ if( psEnc->state_Fxx[ 0 ].sCmn.inDTX && ( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 1 ].sCmn.inDTX ) ) { *nBytesOut = 0; } psEnc->nBitsExceeded += *nBytesOut * 8; psEnc->nBitsExceeded -= silk_DIV32_16( silk_MUL( encControl->bitRate, encControl->payloadSize_ms ), 1000 ); psEnc->nBitsExceeded = silk_LIMIT( psEnc->nBitsExceeded, 0, 10000 ); /* Update flag indicating if bandwidth switching is allowed */ speech_act_thr_for_switch_Q8 = silk_SMLAWB( SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ), SILK_FIX_CONST( ( 1 - SPEECH_ACTIVITY_DTX_THRES ) / MAX_BANDWIDTH_SWITCH_DELAY_MS, 16 + 8 ), psEnc->timeSinceSwitchAllowed_ms ); if( psEnc->state_Fxx[ 0 ].sCmn.speech_activity_Q8 < speech_act_thr_for_switch_Q8 ) { psEnc->allowBandwidthSwitch = 1; psEnc->timeSinceSwitchAllowed_ms = 0; } else { psEnc->allowBandwidthSwitch = 0; psEnc->timeSinceSwitchAllowed_ms += encControl->payloadSize_ms; } } if( nSamplesIn == 0 ) { break; } } else { break; } curr_block++; } psEnc->nPrevChannelsInternal = encControl->nChannelsInternal; encControl->allowBandwidthSwitch = psEnc->allowBandwidthSwitch; encControl->inWBmodeWithoutVariableLP = psEnc->state_Fxx[ 0 ].sCmn.fs_kHz == 16 && psEnc->state_Fxx[ 0 ].sCmn.sLP.mode == 0; encControl->internalSampleRate = silk_SMULBB( psEnc->state_Fxx[ 0 ].sCmn.fs_kHz, 1000 ); encControl->stereoWidth_Q14 = encControl->toMono ? 0 : psEnc->sStereo.smth_width_Q14; if( prefillFlag ) { encControl->payloadSize_ms = tmp_payloadSize_ms; encControl->complexity = tmp_complexity; for( n = 0; n < encControl->nChannelsInternal; n++ ) { psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0; psEnc->state_Fxx[ n ].sCmn.prefillFlag = 0; } } encControl->signalType = psEnc->state_Fxx[0].sCmn.indices.signalType; encControl->offset = silk_Quantization_Offsets_Q10 [ psEnc->state_Fxx[0].sCmn.indices.signalType >> 1 ] [ psEnc->state_Fxx[0].sCmn.indices.quantOffsetType ]; RESTORE_STACK; return ret; } jamulus-3.9.1+dfsg/libs/opus/silk/float/0000755000175000017500000000000014340334543017142 5ustar vimervimerjamulus-3.9.1+dfsg/libs/opus/silk/float/k2a_FLP.c0000644000175000017500000000474714340334543020500 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FLP.h" /* step up function, converts reflection coefficients to prediction coefficients */ void silk_k2a_FLP( silk_float *A, /* O prediction coefficients [order] */ const silk_float *rc, /* I reflection coefficients [order] */ opus_int32 order /* I prediction order */ ) { opus_int k, n; silk_float rck, tmp1, tmp2; for( k = 0; k < order; k++ ) { rck = rc[ k ]; for( n = 0; n < (k + 1) >> 1; n++ ) { tmp1 = A[ n ]; tmp2 = A[ k - n - 1 ]; A[ n ] = tmp1 + tmp2 * rck; A[ k - n - 1 ] = tmp2 + tmp1 * rck; } A[ k ] = -rck; } } jamulus-3.9.1+dfsg/libs/opus/silk/float/LTP_scale_ctrl_FLP.c0000644000175000017500000000520714340334543022645 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main_FLP.h" void silk_LTP_scale_ctrl_FLP( silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ opus_int condCoding /* I The type of conditional coding to use */ ) { opus_int round_loss; if( condCoding == CODE_INDEPENDENTLY ) { /* Only scale if first frame in packet */ round_loss = psEnc->sCmn.PacketLoss_perc + psEnc->sCmn.nFramesPerPacket; psEnc->sCmn.indices.LTP_scaleIndex = (opus_int8)silk_LIMIT( round_loss * psEncCtrl->LTPredCodGain * 0.1f, 0.0f, 2.0f ); } else { /* Default is minimum scaling */ psEnc->sCmn.indices.LTP_scaleIndex = 0; } psEncCtrl->LTP_scale = (silk_float)silk_LTPScales_table_Q14[ psEnc->sCmn.indices.LTP_scaleIndex ] / 16384.0f; } jamulus-3.9.1+dfsg/libs/opus/silk/float/SigProc_FLP.h0000644000175000017500000002255314340334543021371 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SILK_SIGPROC_FLP_H #define SILK_SIGPROC_FLP_H #include "SigProc_FIX.h" #include "float_cast.h" #include #ifdef __cplusplus extern "C" { #endif /********************************************************************/ /* SIGNAL PROCESSING FUNCTIONS */ /********************************************************************/ /* Chirp (bw expand) LP AR filter */ void silk_bwexpander_FLP( silk_float *ar, /* I/O AR filter to be expanded (without leading 1) */ const opus_int d, /* I length of ar */ const silk_float chirp /* I chirp factor (typically in range (0..1) ) */ ); /* compute inverse of LPC prediction gain, and */ /* test if LPC coefficients are stable (all poles within unit circle) */ /* this code is based on silk_FLP_a2k() */ silk_float silk_LPC_inverse_pred_gain_FLP( /* O return inverse prediction gain, energy domain */ const silk_float *A, /* I prediction coefficients [order] */ opus_int32 order /* I prediction order */ ); silk_float silk_schur_FLP( /* O returns residual energy */ silk_float refl_coef[], /* O reflection coefficients (length order) */ const silk_float auto_corr[], /* I autocorrelation sequence (length order+1) */ opus_int order /* I order */ ); void silk_k2a_FLP( silk_float *A, /* O prediction coefficients [order] */ const silk_float *rc, /* I reflection coefficients [order] */ opus_int32 order /* I prediction order */ ); /* compute autocorrelation */ void silk_autocorrelation_FLP( silk_float *results, /* O result (length correlationCount) */ const silk_float *inputData, /* I input data to correlate */ opus_int inputDataSize, /* I length of input */ opus_int correlationCount /* I number of correlation taps to compute */ ); opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced, 1 unvoiced */ const silk_float *frame, /* I Signal of length PE_FRAME_LENGTH_MS*Fs_kHz */ opus_int *pitch_out, /* O Pitch lag values [nb_subfr] */ opus_int16 *lagIndex, /* O Lag Index */ opus_int8 *contourIndex, /* O Pitch contour Index */ silk_float *LTPCorr, /* I/O Normalized correlation; input: value from previous frame */ opus_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */ const silk_float search_thres1, /* I First stage threshold for lag candidates 0 - 1 */ const silk_float search_thres2, /* I Final threshold for lag candidates 0 - 1 */ const opus_int Fs_kHz, /* I sample frequency (kHz) */ const opus_int complexity, /* I Complexity setting, 0-2, where 2 is highest */ const opus_int nb_subfr, /* I Number of 5 ms subframes */ int arch /* I Run-time architecture */ ); void silk_insertion_sort_decreasing_FLP( silk_float *a, /* I/O Unsorted / Sorted vector */ opus_int *idx, /* O Index vector for the sorted elements */ const opus_int L, /* I Vector length */ const opus_int K /* I Number of correctly sorted positions */ ); /* Compute reflection coefficients from input signal */ silk_float silk_burg_modified_FLP( /* O returns residual energy */ silk_float A[], /* O prediction coefficients (length order) */ const silk_float x[], /* I input signal, length: nb_subfr*(D+L_sub) */ const silk_float minInvGain, /* I minimum inverse prediction gain */ const opus_int subfr_length, /* I input signal subframe length (incl. D preceding samples) */ const opus_int nb_subfr, /* I number of subframes stacked in x */ const opus_int D /* I order */ ); /* multiply a vector by a constant */ void silk_scale_vector_FLP( silk_float *data1, silk_float gain, opus_int dataSize ); /* copy and multiply a vector by a constant */ void silk_scale_copy_vector_FLP( silk_float *data_out, const silk_float *data_in, silk_float gain, opus_int dataSize ); /* inner product of two silk_float arrays, with result as double */ double silk_inner_product_FLP( const silk_float *data1, const silk_float *data2, opus_int dataSize ); /* sum of squares of a silk_float array, with result as double */ double silk_energy_FLP( const silk_float *data, opus_int dataSize ); /********************************************************************/ /* MACROS */ /********************************************************************/ #define PI (3.1415926536f) #define silk_min_float( a, b ) (((a) < (b)) ? (a) : (b)) #define silk_max_float( a, b ) (((a) > (b)) ? (a) : (b)) #define silk_abs_float( a ) ((silk_float)fabs(a)) /* sigmoid function */ static OPUS_INLINE silk_float silk_sigmoid( silk_float x ) { return (silk_float)(1.0 / (1.0 + exp(-x))); } /* floating-point to integer conversion (rounding) */ static OPUS_INLINE opus_int32 silk_float2int( silk_float x ) { return (opus_int32)float2int( x ); } /* floating-point to integer conversion (rounding) */ static OPUS_INLINE void silk_float2short_array( opus_int16 *out, const silk_float *in, opus_int32 length ) { opus_int32 k; for( k = length - 1; k >= 0; k-- ) { out[k] = silk_SAT16( (opus_int32)float2int( in[k] ) ); } } /* integer to floating-point conversion */ static OPUS_INLINE void silk_short2float_array( silk_float *out, const opus_int16 *in, opus_int32 length ) { opus_int32 k; for( k = length - 1; k >= 0; k-- ) { out[k] = (silk_float)in[k]; } } /* using log2() helps the fixed-point conversion */ static OPUS_INLINE silk_float silk_log2( double x ) { return ( silk_float )( 3.32192809488736 * log10( x ) ); } #ifdef __cplusplus } #endif #endif /* SILK_SIGPROC_FLP_H */ jamulus-3.9.1+dfsg/libs/opus/silk/float/schur_FLP.c0000644000175000017500000000577114340334543021145 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FLP.h" silk_float silk_schur_FLP( /* O returns residual energy */ silk_float refl_coef[], /* O reflection coefficients (length order) */ const silk_float auto_corr[], /* I autocorrelation sequence (length order+1) */ opus_int order /* I order */ ) { opus_int k, n; double C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ]; double Ctmp1, Ctmp2, rc_tmp; celt_assert( order >= 0 && order <= SILK_MAX_ORDER_LPC ); /* Copy correlations */ k = 0; do { C[ k ][ 0 ] = C[ k ][ 1 ] = auto_corr[ k ]; } while( ++k <= order ); for( k = 0; k < order; k++ ) { /* Get reflection coefficient */ rc_tmp = -C[ k + 1 ][ 0 ] / silk_max_float( C[ 0 ][ 1 ], 1e-9f ); /* Save the output */ refl_coef[ k ] = (silk_float)rc_tmp; /* Update correlations */ for( n = 0; n < order - k; n++ ) { Ctmp1 = C[ n + k + 1 ][ 0 ]; Ctmp2 = C[ n ][ 1 ]; C[ n + k + 1 ][ 0 ] = Ctmp1 + Ctmp2 * rc_tmp; C[ n ][ 1 ] = Ctmp2 + Ctmp1 * rc_tmp; } } /* Return residual energy */ return (silk_float)C[ 0 ][ 1 ]; } jamulus-3.9.1+dfsg/libs/opus/silk/float/warped_autocorrelation_FLP.c0000644000175000017500000000662514340334543024574 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main_FLP.h" /* Autocorrelations for a warped frequency axis */ void silk_warped_autocorrelation_FLP( silk_float *corr, /* O Result [order + 1] */ const silk_float *input, /* I Input data to correlate */ const silk_float warping, /* I Warping coefficient */ const opus_int length, /* I Length of input */ const opus_int order /* I Correlation order (even) */ ) { opus_int n, i; double tmp1, tmp2; double state[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; double C[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; /* Order must be even */ celt_assert( ( order & 1 ) == 0 ); /* Loop over samples */ for( n = 0; n < length; n++ ) { tmp1 = input[ n ]; /* Loop over allpass sections */ for( i = 0; i < order; i += 2 ) { /* Output of allpass section */ tmp2 = state[ i ] + warping * ( state[ i + 1 ] - tmp1 ); state[ i ] = tmp1; C[ i ] += state[ 0 ] * tmp1; /* Output of allpass section */ tmp1 = state[ i + 1 ] + warping * ( state[ i + 2 ] - tmp2 ); state[ i + 1 ] = tmp2; C[ i + 1 ] += state[ 0 ] * tmp2; } state[ order ] = tmp1; C[ order ] += state[ 0 ] * tmp1; } /* Copy correlations in silk_float output format */ for( i = 0; i < order + 1; i++ ) { corr[ i ] = ( silk_float )C[ i ]; } } jamulus-3.9.1+dfsg/libs/opus/silk/float/LPC_inv_pred_gain_FLP.c0000644000175000017500000000633114340334543023314 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FIX.h" #include "SigProc_FLP.h" #include "define.h" /* compute inverse of LPC prediction gain, and */ /* test if LPC coefficients are stable (all poles within unit circle) */ /* this code is based on silk_a2k_FLP() */ silk_float silk_LPC_inverse_pred_gain_FLP( /* O return inverse prediction gain, energy domain */ const silk_float *A, /* I prediction coefficients [order] */ opus_int32 order /* I prediction order */ ) { opus_int k, n; double invGain, rc, rc_mult1, rc_mult2, tmp1, tmp2; silk_float Atmp[ SILK_MAX_ORDER_LPC ]; silk_memcpy( Atmp, A, order * sizeof(silk_float) ); invGain = 1.0; for( k = order - 1; k > 0; k-- ) { rc = -Atmp[ k ]; rc_mult1 = 1.0f - rc * rc; invGain *= rc_mult1; if( invGain * MAX_PREDICTION_POWER_GAIN < 1.0f ) { return 0.0f; } rc_mult2 = 1.0f / rc_mult1; for( n = 0; n < (k + 1) >> 1; n++ ) { tmp1 = Atmp[ n ]; tmp2 = Atmp[ k - n - 1 ]; Atmp[ n ] = (silk_float)( ( tmp1 - tmp2 * rc ) * rc_mult2 ); Atmp[ k - n - 1 ] = (silk_float)( ( tmp2 - tmp1 * rc ) * rc_mult2 ); } } rc = -Atmp[ 0 ]; rc_mult1 = 1.0f - rc * rc; invGain *= rc_mult1; if( invGain * MAX_PREDICTION_POWER_GAIN < 1.0f ) { return 0.0f; } return (silk_float)invGain; } jamulus-3.9.1+dfsg/libs/opus/silk/float/scale_copy_vector_FLP.c0000644000175000017500000000455514340334543023523 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FLP.h" /* copy and multiply a vector by a constant */ void silk_scale_copy_vector_FLP( silk_float *data_out, const silk_float *data_in, silk_float gain, opus_int dataSize ) { opus_int i, dataSize4; /* 4x unrolled loop */ dataSize4 = dataSize & 0xFFFC; for( i = 0; i < dataSize4; i += 4 ) { data_out[ i + 0 ] = gain * data_in[ i + 0 ]; data_out[ i + 1 ] = gain * data_in[ i + 1 ]; data_out[ i + 2 ] = gain * data_in[ i + 2 ]; data_out[ i + 3 ] = gain * data_in[ i + 3 ]; } /* any remaining elements */ for( ; i < dataSize; i++ ) { data_out[ i ] = gain * data_in[ i ]; } } jamulus-3.9.1+dfsg/libs/opus/silk/float/noise_shape_analysis_FLP.c0000644000175000017500000003572114340334543024217 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main_FLP.h" #include "tuning_parameters.h" /* Compute gain to make warped filter coefficients have a zero mean log frequency response on a */ /* non-warped frequency scale. (So that it can be implemented with a minimum-phase monic filter.) */ /* Note: A monic filter is one with the first coefficient equal to 1.0. In Silk we omit the first */ /* coefficient in an array of coefficients, for monic filters. */ static OPUS_INLINE silk_float warped_gain( const silk_float *coefs, silk_float lambda, opus_int order ) { opus_int i; silk_float gain; lambda = -lambda; gain = coefs[ order - 1 ]; for( i = order - 2; i >= 0; i-- ) { gain = lambda * gain + coefs[ i ]; } return (silk_float)( 1.0f / ( 1.0f - lambda * gain ) ); } /* Convert warped filter coefficients to monic pseudo-warped coefficients and limit maximum */ /* amplitude of monic warped coefficients by using bandwidth expansion on the true coefficients */ static OPUS_INLINE void warped_true2monic_coefs( silk_float *coefs, silk_float lambda, silk_float limit, opus_int order ) { opus_int i, iter, ind = 0; silk_float tmp, maxabs, chirp, gain; /* Convert to monic coefficients */ for( i = order - 1; i > 0; i-- ) { coefs[ i - 1 ] -= lambda * coefs[ i ]; } gain = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs[ 0 ] ); for( i = 0; i < order; i++ ) { coefs[ i ] *= gain; } /* Limit */ for( iter = 0; iter < 10; iter++ ) { /* Find maximum absolute value */ maxabs = -1.0f; for( i = 0; i < order; i++ ) { tmp = silk_abs_float( coefs[ i ] ); if( tmp > maxabs ) { maxabs = tmp; ind = i; } } if( maxabs <= limit ) { /* Coefficients are within range - done */ return; } /* Convert back to true warped coefficients */ for( i = 1; i < order; i++ ) { coefs[ i - 1 ] += lambda * coefs[ i ]; } gain = 1.0f / gain; for( i = 0; i < order; i++ ) { coefs[ i ] *= gain; } /* Apply bandwidth expansion */ chirp = 0.99f - ( 0.8f + 0.1f * iter ) * ( maxabs - limit ) / ( maxabs * ( ind + 1 ) ); silk_bwexpander_FLP( coefs, order, chirp ); /* Convert to monic warped coefficients */ for( i = order - 1; i > 0; i-- ) { coefs[ i - 1 ] -= lambda * coefs[ i ]; } gain = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs[ 0 ] ); for( i = 0; i < order; i++ ) { coefs[ i ] *= gain; } } silk_assert( 0 ); } static OPUS_INLINE void limit_coefs( silk_float *coefs, silk_float limit, opus_int order ) { opus_int i, iter, ind = 0; silk_float tmp, maxabs, chirp; for( iter = 0; iter < 10; iter++ ) { /* Find maximum absolute value */ maxabs = -1.0f; for( i = 0; i < order; i++ ) { tmp = silk_abs_float( coefs[ i ] ); if( tmp > maxabs ) { maxabs = tmp; ind = i; } } if( maxabs <= limit ) { /* Coefficients are within range - done */ return; } /* Apply bandwidth expansion */ chirp = 0.99f - ( 0.8f + 0.1f * iter ) * ( maxabs - limit ) / ( maxabs * ( ind + 1 ) ); silk_bwexpander_FLP( coefs, order, chirp ); } silk_assert( 0 ); } /* Compute noise shaping coefficients and initial gain values */ void silk_noise_shape_analysis_FLP( silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ const silk_float *pitch_res, /* I LPC residual from pitch analysis */ const silk_float *x /* I Input signal [frame_length + la_shape] */ ) { silk_shape_state_FLP *psShapeSt = &psEnc->sShape; opus_int k, nSamples, nSegs; silk_float SNR_adj_dB, HarmShapeGain, Tilt; silk_float nrg, log_energy, log_energy_prev, energy_variation; silk_float BWExp, gain_mult, gain_add, strength, b, warping; silk_float x_windowed[ SHAPE_LPC_WIN_MAX ]; silk_float auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ]; silk_float rc[ MAX_SHAPE_LPC_ORDER + 1 ]; const silk_float *x_ptr, *pitch_res_ptr; /* Point to start of first LPC analysis block */ x_ptr = x - psEnc->sCmn.la_shape; /****************/ /* GAIN CONTROL */ /****************/ SNR_adj_dB = psEnc->sCmn.SNR_dB_Q7 * ( 1 / 128.0f ); /* Input quality is the average of the quality in the lowest two VAD bands */ psEncCtrl->input_quality = 0.5f * ( psEnc->sCmn.input_quality_bands_Q15[ 0 ] + psEnc->sCmn.input_quality_bands_Q15[ 1 ] ) * ( 1.0f / 32768.0f ); /* Coding quality level, between 0.0 and 1.0 */ psEncCtrl->coding_quality = silk_sigmoid( 0.25f * ( SNR_adj_dB - 20.0f ) ); if( psEnc->sCmn.useCBR == 0 ) { /* Reduce coding SNR during low speech activity */ b = 1.0f - psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f ); SNR_adj_dB -= BG_SNR_DECR_dB * psEncCtrl->coding_quality * ( 0.5f + 0.5f * psEncCtrl->input_quality ) * b * b; } if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { /* Reduce gains for periodic signals */ SNR_adj_dB += HARM_SNR_INCR_dB * psEnc->LTPCorr; } else { /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */ SNR_adj_dB += ( -0.4f * psEnc->sCmn.SNR_dB_Q7 * ( 1 / 128.0f ) + 6.0f ) * ( 1.0f - psEncCtrl->input_quality ); } /*************************/ /* SPARSENESS PROCESSING */ /*************************/ /* Set quantizer offset */ if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { /* Initially set to 0; may be overruled in process_gains(..) */ psEnc->sCmn.indices.quantOffsetType = 0; } else { /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */ nSamples = 2 * psEnc->sCmn.fs_kHz; energy_variation = 0.0f; log_energy_prev = 0.0f; pitch_res_ptr = pitch_res; nSegs = silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2; for( k = 0; k < nSegs; k++ ) { nrg = ( silk_float )nSamples + ( silk_float )silk_energy_FLP( pitch_res_ptr, nSamples ); log_energy = silk_log2( nrg ); if( k > 0 ) { energy_variation += silk_abs_float( log_energy - log_energy_prev ); } log_energy_prev = log_energy; pitch_res_ptr += nSamples; } /* Set quantization offset depending on sparseness measure */ if( energy_variation > ENERGY_VARIATION_THRESHOLD_QNT_OFFSET * (nSegs-1) ) { psEnc->sCmn.indices.quantOffsetType = 0; } else { psEnc->sCmn.indices.quantOffsetType = 1; } } /*******************************/ /* Control bandwidth expansion */ /*******************************/ /* More BWE for signals with high prediction gain */ strength = FIND_PITCH_WHITE_NOISE_FRACTION * psEncCtrl->predGain; /* between 0.0 and 1.0 */ BWExp = BANDWIDTH_EXPANSION / ( 1.0f + strength * strength ); /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */ warping = (silk_float)psEnc->sCmn.warping_Q16 / 65536.0f + 0.01f * psEncCtrl->coding_quality; /********************************************/ /* Compute noise shaping AR coefs and gains */ /********************************************/ for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { /* Apply window: sine slope followed by flat part followed by cosine slope */ opus_int shift, slope_part, flat_part; flat_part = psEnc->sCmn.fs_kHz * 3; slope_part = ( psEnc->sCmn.shapeWinLength - flat_part ) / 2; silk_apply_sine_window_FLP( x_windowed, x_ptr, 1, slope_part ); shift = slope_part; silk_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(silk_float) ); shift += flat_part; silk_apply_sine_window_FLP( x_windowed + shift, x_ptr + shift, 2, slope_part ); /* Update pointer: next LPC analysis block */ x_ptr += psEnc->sCmn.subfr_length; if( psEnc->sCmn.warping_Q16 > 0 ) { /* Calculate warped auto correlation */ silk_warped_autocorrelation_FLP( auto_corr, x_windowed, warping, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder ); } else { /* Calculate regular auto correlation */ silk_autocorrelation_FLP( auto_corr, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1 ); } /* Add white noise, as a fraction of energy */ auto_corr[ 0 ] += auto_corr[ 0 ] * SHAPE_WHITE_NOISE_FRACTION + 1.0f; /* Convert correlations to prediction coefficients, and compute residual energy */ nrg = silk_schur_FLP( rc, auto_corr, psEnc->sCmn.shapingLPCOrder ); silk_k2a_FLP( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], rc, psEnc->sCmn.shapingLPCOrder ); psEncCtrl->Gains[ k ] = ( silk_float )sqrt( nrg ); if( psEnc->sCmn.warping_Q16 > 0 ) { /* Adjust gain for warping */ psEncCtrl->Gains[ k ] *= warped_gain( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], warping, psEnc->sCmn.shapingLPCOrder ); } /* Bandwidth expansion for synthesis filter shaping */ silk_bwexpander_FLP( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder, BWExp ); if( psEnc->sCmn.warping_Q16 > 0 ) { /* Convert to monic warped prediction coefficients and limit absolute values */ warped_true2monic_coefs( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], warping, 3.999f, psEnc->sCmn.shapingLPCOrder ); } else { /* Limit absolute values */ limit_coefs( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], 3.999f, psEnc->sCmn.shapingLPCOrder ); } } /*****************/ /* Gain tweaking */ /*****************/ /* Increase gains during low speech activity */ gain_mult = (silk_float)pow( 2.0f, -0.16f * SNR_adj_dB ); gain_add = (silk_float)pow( 2.0f, 0.16f * MIN_QGAIN_DB ); for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { psEncCtrl->Gains[ k ] *= gain_mult; psEncCtrl->Gains[ k ] += gain_add; } /************************************************/ /* Control low-frequency shaping and noise tilt */ /************************************************/ /* Less low frequency shaping for noisy inputs */ strength = LOW_FREQ_SHAPING * ( 1.0f + LOW_QUALITY_LOW_FREQ_SHAPING_DECR * ( psEnc->sCmn.input_quality_bands_Q15[ 0 ] * ( 1.0f / 32768.0f ) - 1.0f ) ); strength *= psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f ); if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { /* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */ /*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/ for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { b = 0.2f / psEnc->sCmn.fs_kHz + 3.0f / psEncCtrl->pitchL[ k ]; psEncCtrl->LF_MA_shp[ k ] = -1.0f + b; psEncCtrl->LF_AR_shp[ k ] = 1.0f - b - b * strength; } Tilt = - HP_NOISE_COEF - (1 - HP_NOISE_COEF) * HARM_HP_NOISE_COEF * psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f ); } else { b = 1.3f / psEnc->sCmn.fs_kHz; psEncCtrl->LF_MA_shp[ 0 ] = -1.0f + b; psEncCtrl->LF_AR_shp[ 0 ] = 1.0f - b - b * strength * 0.6f; for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) { psEncCtrl->LF_MA_shp[ k ] = psEncCtrl->LF_MA_shp[ 0 ]; psEncCtrl->LF_AR_shp[ k ] = psEncCtrl->LF_AR_shp[ 0 ]; } Tilt = -HP_NOISE_COEF; } /****************************/ /* HARMONIC SHAPING CONTROL */ /****************************/ if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) { /* Harmonic noise shaping */ HarmShapeGain = HARMONIC_SHAPING; /* More harmonic noise shaping for high bitrates or noisy input */ HarmShapeGain += HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING * ( 1.0f - ( 1.0f - psEncCtrl->coding_quality ) * psEncCtrl->input_quality ); /* Less harmonic noise shaping for less periodic signals */ HarmShapeGain *= ( silk_float )sqrt( psEnc->LTPCorr ); } else { HarmShapeGain = 0.0f; } /*************************/ /* Smooth over subframes */ /*************************/ for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { psShapeSt->HarmShapeGain_smth += SUBFR_SMTH_COEF * ( HarmShapeGain - psShapeSt->HarmShapeGain_smth ); psEncCtrl->HarmShapeGain[ k ] = psShapeSt->HarmShapeGain_smth; psShapeSt->Tilt_smth += SUBFR_SMTH_COEF * ( Tilt - psShapeSt->Tilt_smth ); psEncCtrl->Tilt[ k ] = psShapeSt->Tilt_smth; } } jamulus-3.9.1+dfsg/libs/opus/silk/float/apply_sine_window_FLP.c0000644000175000017500000000655514340334543023554 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main_FLP.h" /* Apply sine window to signal vector */ /* Window types: */ /* 1 -> sine window from 0 to pi/2 */ /* 2 -> sine window from pi/2 to pi */ void silk_apply_sine_window_FLP( silk_float px_win[], /* O Pointer to windowed signal */ const silk_float px[], /* I Pointer to input signal */ const opus_int win_type, /* I Selects a window type */ const opus_int length /* I Window length, multiple of 4 */ ) { opus_int k; silk_float freq, c, S0, S1; celt_assert( win_type == 1 || win_type == 2 ); /* Length must be multiple of 4 */ celt_assert( ( length & 3 ) == 0 ); freq = PI / ( length + 1 ); /* Approximation of 2 * cos(f) */ c = 2.0f - freq * freq; /* Initialize state */ if( win_type < 2 ) { /* Start from 0 */ S0 = 0.0f; /* Approximation of sin(f) */ S1 = freq; } else { /* Start from 1 */ S0 = 1.0f; /* Approximation of cos(f) */ S1 = 0.5f * c; } /* Uses the recursive equation: sin(n*f) = 2 * cos(f) * sin((n-1)*f) - sin((n-2)*f) */ /* 4 samples at a time */ for( k = 0; k < length; k += 4 ) { px_win[ k + 0 ] = px[ k + 0 ] * 0.5f * ( S0 + S1 ); px_win[ k + 1 ] = px[ k + 1 ] * S1; S0 = c * S1 - S0; px_win[ k + 2 ] = px[ k + 2 ] * 0.5f * ( S1 + S0 ); px_win[ k + 3 ] = px[ k + 3 ] * S0; S1 = c * S0 - S1; } } jamulus-3.9.1+dfsg/libs/opus/silk/float/residual_energy_FLP.c0000644000175000017500000001347314340334543023200 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main_FLP.h" #define MAX_ITERATIONS_RESIDUAL_NRG 10 #define REGULARIZATION_FACTOR 1e-8f /* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */ silk_float silk_residual_energy_covar_FLP( /* O Weighted residual energy */ const silk_float *c, /* I Filter coefficients */ silk_float *wXX, /* I/O Weighted correlation matrix, reg. out */ const silk_float *wXx, /* I Weighted correlation vector */ const silk_float wxx, /* I Weighted correlation value */ const opus_int D /* I Dimension */ ) { opus_int i, j, k; silk_float tmp, nrg = 0.0f, regularization; /* Safety checks */ celt_assert( D >= 0 ); regularization = REGULARIZATION_FACTOR * ( wXX[ 0 ] + wXX[ D * D - 1 ] ); for( k = 0; k < MAX_ITERATIONS_RESIDUAL_NRG; k++ ) { nrg = wxx; tmp = 0.0f; for( i = 0; i < D; i++ ) { tmp += wXx[ i ] * c[ i ]; } nrg -= 2.0f * tmp; /* compute c' * wXX * c, assuming wXX is symmetric */ for( i = 0; i < D; i++ ) { tmp = 0.0f; for( j = i + 1; j < D; j++ ) { tmp += matrix_c_ptr( wXX, i, j, D ) * c[ j ]; } nrg += c[ i ] * ( 2.0f * tmp + matrix_c_ptr( wXX, i, i, D ) * c[ i ] ); } if( nrg > 0 ) { break; } else { /* Add white noise */ for( i = 0; i < D; i++ ) { matrix_c_ptr( wXX, i, i, D ) += regularization; } /* Increase noise for next run */ regularization *= 2.0f; } } if( k == MAX_ITERATIONS_RESIDUAL_NRG ) { silk_assert( nrg == 0 ); nrg = 1.0f; } return nrg; } /* Calculates residual energies of input subframes where all subframes have LPC_order */ /* of preceding samples */ void silk_residual_energy_FLP( silk_float nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */ const silk_float x[], /* I Input signal */ silk_float a[ 2 ][ MAX_LPC_ORDER ], /* I AR coefs for each frame half */ const silk_float gains[], /* I Quantization gains */ const opus_int subfr_length, /* I Subframe length */ const opus_int nb_subfr, /* I number of subframes */ const opus_int LPC_order /* I LPC order */ ) { opus_int shift; silk_float *LPC_res_ptr, LPC_res[ ( MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ) / 2 ]; LPC_res_ptr = LPC_res + LPC_order; shift = LPC_order + subfr_length; /* Filter input to create the LPC residual for each frame half, and measure subframe energies */ silk_LPC_analysis_filter_FLP( LPC_res, a[ 0 ], x + 0 * shift, 2 * shift, LPC_order ); nrgs[ 0 ] = ( silk_float )( gains[ 0 ] * gains[ 0 ] * silk_energy_FLP( LPC_res_ptr + 0 * shift, subfr_length ) ); nrgs[ 1 ] = ( silk_float )( gains[ 1 ] * gains[ 1 ] * silk_energy_FLP( LPC_res_ptr + 1 * shift, subfr_length ) ); if( nb_subfr == MAX_NB_SUBFR ) { silk_LPC_analysis_filter_FLP( LPC_res, a[ 1 ], x + 2 * shift, 2 * shift, LPC_order ); nrgs[ 2 ] = ( silk_float )( gains[ 2 ] * gains[ 2 ] * silk_energy_FLP( LPC_res_ptr + 0 * shift, subfr_length ) ); nrgs[ 3 ] = ( silk_float )( gains[ 3 ] * gains[ 3 ] * silk_energy_FLP( LPC_res_ptr + 1 * shift, subfr_length ) ); } } jamulus-3.9.1+dfsg/libs/opus/silk/float/main_FLP.h0000644000175000017500000004564014340334543020751 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SILK_MAIN_FLP_H #define SILK_MAIN_FLP_H #include "SigProc_FLP.h" #include "SigProc_FIX.h" #include "structs_FLP.h" #include "main.h" #include "define.h" #include "debug.h" #include "entenc.h" #ifdef __cplusplus extern "C" { #endif #define silk_encoder_state_Fxx silk_encoder_state_FLP #define silk_encode_do_VAD_Fxx silk_encode_do_VAD_FLP #define silk_encode_frame_Fxx silk_encode_frame_FLP /*********************/ /* Encoder Functions */ /*********************/ /* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */ void silk_HP_variable_cutoff( silk_encoder_state_Fxx state_Fxx[] /* I/O Encoder states */ ); /* Encoder main function */ void silk_encode_do_VAD_FLP( silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ opus_int activity /* I Decision of Opus voice activity detector */ ); /* Encoder main function */ opus_int silk_encode_frame_FLP( silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ opus_int32 *pnBytesOut, /* O Number of payload bytes; */ ec_enc *psRangeEnc, /* I/O compressor data structure */ opus_int condCoding, /* I The type of conditional coding to use */ opus_int maxBits, /* I If > 0: maximum number of output bits */ opus_int useCBR /* I Flag to force constant-bitrate operation */ ); /* Initializes the Silk encoder state */ opus_int silk_init_encoder( silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ int arch /* I Run-tim architecture */ ); /* Control the Silk encoder */ opus_int silk_control_encoder( silk_encoder_state_FLP *psEnc, /* I/O Pointer to Silk encoder state FLP */ silk_EncControlStruct *encControl, /* I Control structure */ const opus_int allow_bw_switch, /* I Flag to allow switching audio bandwidth */ const opus_int channelNb, /* I Channel number */ const opus_int force_fs_kHz ); /**************************/ /* Noise shaping analysis */ /**************************/ /* Compute noise shaping coefficients and initial gain values */ void silk_noise_shape_analysis_FLP( silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ const silk_float *pitch_res, /* I LPC residual from pitch analysis */ const silk_float *x /* I Input signal [frame_length + la_shape] */ ); /* Autocorrelations for a warped frequency axis */ void silk_warped_autocorrelation_FLP( silk_float *corr, /* O Result [order + 1] */ const silk_float *input, /* I Input data to correlate */ const silk_float warping, /* I Warping coefficient */ const opus_int length, /* I Length of input */ const opus_int order /* I Correlation order (even) */ ); /* Calculation of LTP state scaling */ void silk_LTP_scale_ctrl_FLP( silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ opus_int condCoding /* I The type of conditional coding to use */ ); /**********************************************/ /* Prediction Analysis */ /**********************************************/ /* Find pitch lags */ void silk_find_pitch_lags_FLP( silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ silk_float res[], /* O Residual */ const silk_float x[], /* I Speech signal */ int arch /* I Run-time architecture */ ); /* Find LPC and LTP coefficients */ void silk_find_pred_coefs_FLP( silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ const silk_float res_pitch[], /* I Residual from pitch analysis */ const silk_float x[], /* I Speech signal */ opus_int condCoding /* I The type of conditional coding to use */ ); /* LPC analysis */ void silk_find_LPC_FLP( silk_encoder_state *psEncC, /* I/O Encoder state */ opus_int16 NLSF_Q15[], /* O NLSFs */ const silk_float x[], /* I Input signal */ const silk_float minInvGain /* I Prediction gain from LTP (dB) */ ); /* LTP analysis */ void silk_find_LTP_FLP( silk_float XX[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */ silk_float xX[ MAX_NB_SUBFR * LTP_ORDER ], /* O Weight for LTP quantization */ const silk_float r_ptr[], /* I LPC residual */ const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */ const opus_int subfr_length, /* I Subframe length */ const opus_int nb_subfr /* I number of subframes */ ); void silk_LTP_analysis_filter_FLP( silk_float *LTP_res, /* O LTP res MAX_NB_SUBFR*(pre_lgth+subfr_lngth) */ const silk_float *x, /* I Input signal, with preceding samples */ const silk_float B[ LTP_ORDER * MAX_NB_SUBFR ], /* I LTP coefficients for each subframe */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ const silk_float invGains[ MAX_NB_SUBFR ], /* I Inverse quantization gains */ const opus_int subfr_length, /* I Length of each subframe */ const opus_int nb_subfr, /* I number of subframes */ const opus_int pre_length /* I Preceding samples for each subframe */ ); /* Calculates residual energies of input subframes where all subframes have LPC_order */ /* of preceding samples */ void silk_residual_energy_FLP( silk_float nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */ const silk_float x[], /* I Input signal */ silk_float a[ 2 ][ MAX_LPC_ORDER ], /* I AR coefs for each frame half */ const silk_float gains[], /* I Quantization gains */ const opus_int subfr_length, /* I Subframe length */ const opus_int nb_subfr, /* I number of subframes */ const opus_int LPC_order /* I LPC order */ ); /* 16th order LPC analysis filter */ void silk_LPC_analysis_filter_FLP( silk_float r_LPC[], /* O LPC residual signal */ const silk_float PredCoef[], /* I LPC coefficients */ const silk_float s[], /* I Input signal */ const opus_int length, /* I Length of input signal */ const opus_int Order /* I LPC order */ ); /* LTP tap quantizer */ void silk_quant_LTP_gains_FLP( silk_float B[ MAX_NB_SUBFR * LTP_ORDER ], /* O Quantized LTP gains */ opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook index */ opus_int8 *periodicity_index, /* O Periodicity index */ opus_int32 *sum_log_gain_Q7, /* I/O Cumulative max prediction gain */ silk_float *pred_gain_dB, /* O LTP prediction gain */ const silk_float XX[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* I Correlation matrix */ const silk_float xX[ MAX_NB_SUBFR * LTP_ORDER ], /* I Correlation vector */ const opus_int subfr_len, /* I Number of samples per subframe */ const opus_int nb_subfr, /* I Number of subframes */ int arch /* I Run-time architecture */ ); /* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */ silk_float silk_residual_energy_covar_FLP( /* O Weighted residual energy */ const silk_float *c, /* I Filter coefficients */ silk_float *wXX, /* I/O Weighted correlation matrix, reg. out */ const silk_float *wXx, /* I Weighted correlation vector */ const silk_float wxx, /* I Weighted correlation value */ const opus_int D /* I Dimension */ ); /* Processing of gains */ void silk_process_gains_FLP( silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ opus_int condCoding /* I The type of conditional coding to use */ ); /******************/ /* Linear Algebra */ /******************/ /* Calculates correlation matrix X'*X */ void silk_corrMatrix_FLP( const silk_float *x, /* I x vector [ L+order-1 ] used to create X */ const opus_int L, /* I Length of vectors */ const opus_int Order, /* I Max lag for correlation */ silk_float *XX /* O X'*X correlation matrix [order x order] */ ); /* Calculates correlation vector X'*t */ void silk_corrVector_FLP( const silk_float *x, /* I x vector [L+order-1] used to create X */ const silk_float *t, /* I Target vector [L] */ const opus_int L, /* I Length of vecors */ const opus_int Order, /* I Max lag for correlation */ silk_float *Xt /* O X'*t correlation vector [order] */ ); /* Apply sine window to signal vector. */ /* Window types: */ /* 1 -> sine window from 0 to pi/2 */ /* 2 -> sine window from pi/2 to pi */ void silk_apply_sine_window_FLP( silk_float px_win[], /* O Pointer to windowed signal */ const silk_float px[], /* I Pointer to input signal */ const opus_int win_type, /* I Selects a window type */ const opus_int length /* I Window length, multiple of 4 */ ); /* Wrapper functions. Call flp / fix code */ /* Convert AR filter coefficients to NLSF parameters */ void silk_A2NLSF_FLP( opus_int16 *NLSF_Q15, /* O NLSF vector [ LPC_order ] */ const silk_float *pAR, /* I LPC coefficients [ LPC_order ] */ const opus_int LPC_order /* I LPC order */ ); /* Convert NLSF parameters to AR prediction filter coefficients */ void silk_NLSF2A_FLP( silk_float *pAR, /* O LPC coefficients [ LPC_order ] */ const opus_int16 *NLSF_Q15, /* I NLSF vector [ LPC_order ] */ const opus_int LPC_order, /* I LPC order */ int arch /* I Run-time architecture */ ); /* Limit, stabilize, and quantize NLSFs */ void silk_process_NLSFs_FLP( silk_encoder_state *psEncC, /* I/O Encoder state */ silk_float PredCoef[ 2 ][ MAX_LPC_ORDER ], /* O Prediction coefficients */ opus_int16 NLSF_Q15[ MAX_LPC_ORDER ], /* I/O Normalized LSFs (quant out) (0 - (2^15-1)) */ const opus_int16 prev_NLSF_Q15[ MAX_LPC_ORDER ] /* I Previous Normalized LSFs (0 - (2^15-1)) */ ); /* Floating-point Silk NSQ wrapper */ void silk_NSQ_wrapper_FLP( silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ SideInfoIndices *psIndices, /* I/O Quantization indices */ silk_nsq_state *psNSQ, /* I/O Noise Shaping Quantzation state */ opus_int8 pulses[], /* O Quantized pulse signal */ const silk_float x[] /* I Prefiltered input signal */ ); #ifdef __cplusplus } #endif #endif jamulus-3.9.1+dfsg/libs/opus/silk/float/bwexpander_FLP.c0000644000175000017500000000440414340334543022150 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FLP.h" /* Chirp (bw expand) LP AR filter */ void silk_bwexpander_FLP( silk_float *ar, /* I/O AR filter to be expanded (without leading 1) */ const opus_int d, /* I length of ar */ const silk_float chirp /* I chirp factor (typically in range (0..1) ) */ ) { opus_int i; silk_float cfac = chirp; for( i = 0; i < d - 1; i++ ) { ar[ i ] *= cfac; cfac *= chirp; } ar[ d - 1 ] *= cfac; } jamulus-3.9.1+dfsg/libs/opus/silk/float/regularize_correlations_FLP.c0000644000175000017500000000460514340334543024751 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main_FLP.h" /* Add noise to matrix diagonal */ void silk_regularize_correlations_FLP( silk_float *XX, /* I/O Correlation matrices */ silk_float *xx, /* I/O Correlation values */ const silk_float noise, /* I Noise energy to add */ const opus_int D /* I Dimension of XX */ ) { opus_int i; for( i = 0; i < D; i++ ) { matrix_ptr( &XX[ 0 ], i, i, D ) += noise; } xx[ 0 ] += noise; } jamulus-3.9.1+dfsg/libs/opus/silk/float/sort_FLP.c0000644000175000017500000000714414340334543021004 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* Insertion sort (fast for already almost sorted arrays): */ /* Best case: O(n) for an already sorted array */ /* Worst case: O(n^2) for an inversely sorted array */ #include "typedef.h" #include "SigProc_FLP.h" void silk_insertion_sort_decreasing_FLP( silk_float *a, /* I/O Unsorted / Sorted vector */ opus_int *idx, /* O Index vector for the sorted elements */ const opus_int L, /* I Vector length */ const opus_int K /* I Number of correctly sorted positions */ ) { silk_float value; opus_int i, j; /* Safety checks */ celt_assert( K > 0 ); celt_assert( L > 0 ); celt_assert( L >= K ); /* Write start indices in index vector */ for( i = 0; i < K; i++ ) { idx[ i ] = i; } /* Sort vector elements by value, decreasing order */ for( i = 1; i < K; i++ ) { value = a[ i ]; for( j = i - 1; ( j >= 0 ) && ( value > a[ j ] ); j-- ) { a[ j + 1 ] = a[ j ]; /* Shift value */ idx[ j + 1 ] = idx[ j ]; /* Shift index */ } a[ j + 1 ] = value; /* Write value */ idx[ j + 1 ] = i; /* Write index */ } /* If less than L values are asked check the remaining values, */ /* but only spend CPU to ensure that the K first values are correct */ for( i = K; i < L; i++ ) { value = a[ i ]; if( value > a[ K - 1 ] ) { for( j = K - 2; ( j >= 0 ) && ( value > a[ j ] ); j-- ) { a[ j + 1 ] = a[ j ]; /* Shift value */ idx[ j + 1 ] = idx[ j ]; /* Shift index */ } a[ j + 1 ] = value; /* Write value */ idx[ j + 1 ] = i; /* Write index */ } } } jamulus-3.9.1+dfsg/libs/opus/silk/float/burg_modified_FLP.c0000644000175000017500000001736014340334543022615 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FLP.h" #include "tuning_parameters.h" #include "define.h" #define MAX_FRAME_SIZE 384 /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384*/ /* Compute reflection coefficients from input signal */ silk_float silk_burg_modified_FLP( /* O returns residual energy */ silk_float A[], /* O prediction coefficients (length order) */ const silk_float x[], /* I input signal, length: nb_subfr*(D+L_sub) */ const silk_float minInvGain, /* I minimum inverse prediction gain */ const opus_int subfr_length, /* I input signal subframe length (incl. D preceding samples) */ const opus_int nb_subfr, /* I number of subframes stacked in x */ const opus_int D /* I order */ ) { opus_int k, n, s, reached_max_gain; double C0, invGain, num, nrg_f, nrg_b, rc, Atmp, tmp1, tmp2; const silk_float *x_ptr; double C_first_row[ SILK_MAX_ORDER_LPC ], C_last_row[ SILK_MAX_ORDER_LPC ]; double CAf[ SILK_MAX_ORDER_LPC + 1 ], CAb[ SILK_MAX_ORDER_LPC + 1 ]; double Af[ SILK_MAX_ORDER_LPC ]; celt_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE ); /* Compute autocorrelations, added over subframes */ C0 = silk_energy_FLP( x, nb_subfr * subfr_length ); silk_memset( C_first_row, 0, SILK_MAX_ORDER_LPC * sizeof( double ) ); for( s = 0; s < nb_subfr; s++ ) { x_ptr = x + s * subfr_length; for( n = 1; n < D + 1; n++ ) { C_first_row[ n - 1 ] += silk_inner_product_FLP( x_ptr, x_ptr + n, subfr_length - n ); } } silk_memcpy( C_last_row, C_first_row, SILK_MAX_ORDER_LPC * sizeof( double ) ); /* Initialize */ CAb[ 0 ] = CAf[ 0 ] = C0 + FIND_LPC_COND_FAC * C0 + 1e-9f; invGain = 1.0f; reached_max_gain = 0; for( n = 0; n < D; n++ ) { /* Update first row of correlation matrix (without first element) */ /* Update last row of correlation matrix (without last element, stored in reversed order) */ /* Update C * Af */ /* Update C * flipud(Af) (stored in reversed order) */ for( s = 0; s < nb_subfr; s++ ) { x_ptr = x + s * subfr_length; tmp1 = x_ptr[ n ]; tmp2 = x_ptr[ subfr_length - n - 1 ]; for( k = 0; k < n; k++ ) { C_first_row[ k ] -= x_ptr[ n ] * x_ptr[ n - k - 1 ]; C_last_row[ k ] -= x_ptr[ subfr_length - n - 1 ] * x_ptr[ subfr_length - n + k ]; Atmp = Af[ k ]; tmp1 += x_ptr[ n - k - 1 ] * Atmp; tmp2 += x_ptr[ subfr_length - n + k ] * Atmp; } for( k = 0; k <= n; k++ ) { CAf[ k ] -= tmp1 * x_ptr[ n - k ]; CAb[ k ] -= tmp2 * x_ptr[ subfr_length - n + k - 1 ]; } } tmp1 = C_first_row[ n ]; tmp2 = C_last_row[ n ]; for( k = 0; k < n; k++ ) { Atmp = Af[ k ]; tmp1 += C_last_row[ n - k - 1 ] * Atmp; tmp2 += C_first_row[ n - k - 1 ] * Atmp; } CAf[ n + 1 ] = tmp1; CAb[ n + 1 ] = tmp2; /* Calculate nominator and denominator for the next order reflection (parcor) coefficient */ num = CAb[ n + 1 ]; nrg_b = CAb[ 0 ]; nrg_f = CAf[ 0 ]; for( k = 0; k < n; k++ ) { Atmp = Af[ k ]; num += CAb[ n - k ] * Atmp; nrg_b += CAb[ k + 1 ] * Atmp; nrg_f += CAf[ k + 1 ] * Atmp; } silk_assert( nrg_f > 0.0 ); silk_assert( nrg_b > 0.0 ); /* Calculate the next order reflection (parcor) coefficient */ rc = -2.0 * num / ( nrg_f + nrg_b ); silk_assert( rc > -1.0 && rc < 1.0 ); /* Update inverse prediction gain */ tmp1 = invGain * ( 1.0 - rc * rc ); if( tmp1 <= minInvGain ) { /* Max prediction gain exceeded; set reflection coefficient such that max prediction gain is exactly hit */ rc = sqrt( 1.0 - minInvGain / invGain ); if( num > 0 ) { /* Ensure adjusted reflection coefficients has the original sign */ rc = -rc; } invGain = minInvGain; reached_max_gain = 1; } else { invGain = tmp1; } /* Update the AR coefficients */ for( k = 0; k < (n + 1) >> 1; k++ ) { tmp1 = Af[ k ]; tmp2 = Af[ n - k - 1 ]; Af[ k ] = tmp1 + rc * tmp2; Af[ n - k - 1 ] = tmp2 + rc * tmp1; } Af[ n ] = rc; if( reached_max_gain ) { /* Reached max prediction gain; set remaining coefficients to zero and exit loop */ for( k = n + 1; k < D; k++ ) { Af[ k ] = 0.0; } break; } /* Update C * Af and C * Ab */ for( k = 0; k <= n + 1; k++ ) { tmp1 = CAf[ k ]; CAf[ k ] += rc * CAb[ n - k + 1 ]; CAb[ n - k + 1 ] += rc * tmp1; } } if( reached_max_gain ) { /* Convert to silk_float */ for( k = 0; k < D; k++ ) { A[ k ] = (silk_float)( -Af[ k ] ); } /* Subtract energy of preceding samples from C0 */ for( s = 0; s < nb_subfr; s++ ) { C0 -= silk_energy_FLP( x + s * subfr_length, D ); } /* Approximate residual energy */ nrg_f = C0 * invGain; } else { /* Compute residual energy and store coefficients as silk_float */ nrg_f = CAf[ 0 ]; tmp1 = 1.0; for( k = 0; k < D; k++ ) { Atmp = Af[ k ]; nrg_f += CAf[ k + 1 ] * Atmp; tmp1 += Atmp * Atmp; A[ k ] = (silk_float)(-Atmp); } nrg_f -= FIND_LPC_COND_FAC * C0 * tmp1; } /* Return residual energy */ return (silk_float)nrg_f; } jamulus-3.9.1+dfsg/libs/opus/silk/float/wrappers_FLP.c0000644000175000017500000002442714340334543021663 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main_FLP.h" /* Wrappers. Calls flp / fix code */ /* Convert AR filter coefficients to NLSF parameters */ void silk_A2NLSF_FLP( opus_int16 *NLSF_Q15, /* O NLSF vector [ LPC_order ] */ const silk_float *pAR, /* I LPC coefficients [ LPC_order ] */ const opus_int LPC_order /* I LPC order */ ) { opus_int i; opus_int32 a_fix_Q16[ MAX_LPC_ORDER ]; for( i = 0; i < LPC_order; i++ ) { a_fix_Q16[ i ] = silk_float2int( pAR[ i ] * 65536.0f ); } silk_A2NLSF( NLSF_Q15, a_fix_Q16, LPC_order ); } /* Convert LSF parameters to AR prediction filter coefficients */ void silk_NLSF2A_FLP( silk_float *pAR, /* O LPC coefficients [ LPC_order ] */ const opus_int16 *NLSF_Q15, /* I NLSF vector [ LPC_order ] */ const opus_int LPC_order, /* I LPC order */ int arch /* I Run-time architecture */ ) { opus_int i; opus_int16 a_fix_Q12[ MAX_LPC_ORDER ]; silk_NLSF2A( a_fix_Q12, NLSF_Q15, LPC_order, arch ); for( i = 0; i < LPC_order; i++ ) { pAR[ i ] = ( silk_float )a_fix_Q12[ i ] * ( 1.0f / 4096.0f ); } } /******************************************/ /* Floating-point NLSF processing wrapper */ /******************************************/ void silk_process_NLSFs_FLP( silk_encoder_state *psEncC, /* I/O Encoder state */ silk_float PredCoef[ 2 ][ MAX_LPC_ORDER ], /* O Prediction coefficients */ opus_int16 NLSF_Q15[ MAX_LPC_ORDER ], /* I/O Normalized LSFs (quant out) (0 - (2^15-1)) */ const opus_int16 prev_NLSF_Q15[ MAX_LPC_ORDER ] /* I Previous Normalized LSFs (0 - (2^15-1)) */ ) { opus_int i, j; opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ]; silk_process_NLSFs( psEncC, PredCoef_Q12, NLSF_Q15, prev_NLSF_Q15); for( j = 0; j < 2; j++ ) { for( i = 0; i < psEncC->predictLPCOrder; i++ ) { PredCoef[ j ][ i ] = ( silk_float )PredCoef_Q12[ j ][ i ] * ( 1.0f / 4096.0f ); } } } /****************************************/ /* Floating-point Silk NSQ wrapper */ /****************************************/ void silk_NSQ_wrapper_FLP( silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ SideInfoIndices *psIndices, /* I/O Quantization indices */ silk_nsq_state *psNSQ, /* I/O Noise Shaping Quantzation state */ opus_int8 pulses[], /* O Quantized pulse signal */ const silk_float x[] /* I Prefiltered input signal */ ) { opus_int i, j; opus_int16 x16[ MAX_FRAME_LENGTH ]; opus_int32 Gains_Q16[ MAX_NB_SUBFR ]; silk_DWORD_ALIGN opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ]; opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ]; opus_int LTP_scale_Q14; /* Noise shaping parameters */ opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ]; opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ]; /* Packs two int16 coefficients per int32 value */ opus_int Lambda_Q10; opus_int Tilt_Q14[ MAX_NB_SUBFR ]; opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ]; /* Convert control struct to fix control struct */ /* Noise shape parameters */ for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { for( j = 0; j < psEnc->sCmn.shapingLPCOrder; j++ ) { AR_Q13[ i * MAX_SHAPE_LPC_ORDER + j ] = silk_float2int( psEncCtrl->AR[ i * MAX_SHAPE_LPC_ORDER + j ] * 8192.0f ); } } for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { LF_shp_Q14[ i ] = silk_LSHIFT32( silk_float2int( psEncCtrl->LF_AR_shp[ i ] * 16384.0f ), 16 ) | (opus_uint16)silk_float2int( psEncCtrl->LF_MA_shp[ i ] * 16384.0f ); Tilt_Q14[ i ] = (opus_int)silk_float2int( psEncCtrl->Tilt[ i ] * 16384.0f ); HarmShapeGain_Q14[ i ] = (opus_int)silk_float2int( psEncCtrl->HarmShapeGain[ i ] * 16384.0f ); } Lambda_Q10 = ( opus_int )silk_float2int( psEncCtrl->Lambda * 1024.0f ); /* prediction and coding parameters */ for( i = 0; i < psEnc->sCmn.nb_subfr * LTP_ORDER; i++ ) { LTPCoef_Q14[ i ] = (opus_int16)silk_float2int( psEncCtrl->LTPCoef[ i ] * 16384.0f ); } for( j = 0; j < 2; j++ ) { for( i = 0; i < psEnc->sCmn.predictLPCOrder; i++ ) { PredCoef_Q12[ j ][ i ] = (opus_int16)silk_float2int( psEncCtrl->PredCoef[ j ][ i ] * 4096.0f ); } } for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { Gains_Q16[ i ] = silk_float2int( psEncCtrl->Gains[ i ] * 65536.0f ); silk_assert( Gains_Q16[ i ] > 0 ); } if( psIndices->signalType == TYPE_VOICED ) { LTP_scale_Q14 = silk_LTPScales_table_Q14[ psIndices->LTP_scaleIndex ]; } else { LTP_scale_Q14 = 0; } /* Convert input to fix */ for( i = 0; i < psEnc->sCmn.frame_length; i++ ) { x16[ i ] = silk_float2int( x[ i ] ); } /* Call NSQ */ if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) { silk_NSQ_del_dec( &psEnc->sCmn, psNSQ, psIndices, x16, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14, psEnc->sCmn.arch ); } else { silk_NSQ( &psEnc->sCmn, psNSQ, psIndices, x16, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14, psEnc->sCmn.arch ); } } /***********************************************/ /* Floating-point Silk LTP quantiation wrapper */ /***********************************************/ void silk_quant_LTP_gains_FLP( silk_float B[ MAX_NB_SUBFR * LTP_ORDER ], /* O Quantized LTP gains */ opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook index */ opus_int8 *periodicity_index, /* O Periodicity index */ opus_int32 *sum_log_gain_Q7, /* I/O Cumulative max prediction gain */ silk_float *pred_gain_dB, /* O LTP prediction gain */ const silk_float XX[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* I Correlation matrix */ const silk_float xX[ MAX_NB_SUBFR * LTP_ORDER ], /* I Correlation vector */ const opus_int subfr_len, /* I Number of samples per subframe */ const opus_int nb_subfr, /* I Number of subframes */ int arch /* I Run-time architecture */ ) { opus_int i, pred_gain_dB_Q7; opus_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ]; opus_int32 XX_Q17[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ]; opus_int32 xX_Q17[ MAX_NB_SUBFR * LTP_ORDER ]; for( i = 0; i < nb_subfr * LTP_ORDER * LTP_ORDER; i++ ) { XX_Q17[ i ] = (opus_int32)silk_float2int( XX[ i ] * 131072.0f ); } for( i = 0; i < nb_subfr * LTP_ORDER; i++ ) { xX_Q17[ i ] = (opus_int32)silk_float2int( xX[ i ] * 131072.0f ); } silk_quant_LTP_gains( B_Q14, cbk_index, periodicity_index, sum_log_gain_Q7, &pred_gain_dB_Q7, XX_Q17, xX_Q17, subfr_len, nb_subfr, arch ); for( i = 0; i < nb_subfr * LTP_ORDER; i++ ) { B[ i ] = (silk_float)B_Q14[ i ] * ( 1.0f / 16384.0f ); } *pred_gain_dB = (silk_float)pred_gain_dB_Q7 * ( 1.0f / 128.0f ); } jamulus-3.9.1+dfsg/libs/opus/silk/float/pitch_analysis_core_FLP.c0000644000175000017500000007136714340334543024047 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif /***************************************************************************** * Pitch analyser function ******************************************************************************/ #include "SigProc_FLP.h" #include "SigProc_FIX.h" #include "pitch_est_defines.h" #include "pitch.h" #define SCRATCH_SIZE 22 /************************************************************/ /* Internally used functions */ /************************************************************/ static void silk_P_Ana_calc_corr_st3( silk_float cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */ const silk_float frame[], /* I vector to correlate */ opus_int start_lag, /* I start lag */ opus_int sf_length, /* I sub frame length */ opus_int nb_subfr, /* I number of subframes */ opus_int complexity, /* I Complexity setting */ int arch /* I Run-time architecture */ ); static void silk_P_Ana_calc_energy_st3( silk_float energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */ const silk_float frame[], /* I vector to correlate */ opus_int start_lag, /* I start lag */ opus_int sf_length, /* I sub frame length */ opus_int nb_subfr, /* I number of subframes */ opus_int complexity /* I Complexity setting */ ); /************************************************************/ /* CORE PITCH ANALYSIS FUNCTION */ /************************************************************/ opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced, 1 unvoiced */ const silk_float *frame, /* I Signal of length PE_FRAME_LENGTH_MS*Fs_kHz */ opus_int *pitch_out, /* O Pitch lag values [nb_subfr] */ opus_int16 *lagIndex, /* O Lag Index */ opus_int8 *contourIndex, /* O Pitch contour Index */ silk_float *LTPCorr, /* I/O Normalized correlation; input: value from previous frame */ opus_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */ const silk_float search_thres1, /* I First stage threshold for lag candidates 0 - 1 */ const silk_float search_thres2, /* I Final threshold for lag candidates 0 - 1 */ const opus_int Fs_kHz, /* I sample frequency (kHz) */ const opus_int complexity, /* I Complexity setting, 0-2, where 2 is highest */ const opus_int nb_subfr, /* I Number of 5 ms subframes */ int arch /* I Run-time architecture */ ) { opus_int i, k, d, j; silk_float frame_8kHz[ PE_MAX_FRAME_LENGTH_MS * 8 ]; silk_float frame_4kHz[ PE_MAX_FRAME_LENGTH_MS * 4 ]; opus_int16 frame_8_FIX[ PE_MAX_FRAME_LENGTH_MS * 8 ]; opus_int16 frame_4_FIX[ PE_MAX_FRAME_LENGTH_MS * 4 ]; opus_int32 filt_state[ 6 ]; silk_float threshold, contour_bias; silk_float C[ PE_MAX_NB_SUBFR][ (PE_MAX_LAG >> 1) + 5 ]; opus_val32 xcorr[ PE_MAX_LAG_MS * 4 - PE_MIN_LAG_MS * 4 + 1 ]; silk_float CC[ PE_NB_CBKS_STAGE2_EXT ]; const silk_float *target_ptr, *basis_ptr; double cross_corr, normalizer, energy, energy_tmp; opus_int d_srch[ PE_D_SRCH_LENGTH ]; opus_int16 d_comp[ (PE_MAX_LAG >> 1) + 5 ]; opus_int length_d_srch, length_d_comp; silk_float Cmax, CCmax, CCmax_b, CCmax_new_b, CCmax_new; opus_int CBimax, CBimax_new, lag, start_lag, end_lag, lag_new; opus_int cbk_size; silk_float lag_log2, prevLag_log2, delta_lag_log2_sqr; silk_float energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ]; silk_float cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ]; opus_int lag_counter; opus_int frame_length, frame_length_8kHz, frame_length_4kHz; opus_int sf_length, sf_length_8kHz, sf_length_4kHz; opus_int min_lag, min_lag_8kHz, min_lag_4kHz; opus_int max_lag, max_lag_8kHz, max_lag_4kHz; opus_int nb_cbk_search; const opus_int8 *Lag_CB_ptr; /* Check for valid sampling frequency */ celt_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 ); /* Check for valid complexity setting */ celt_assert( complexity >= SILK_PE_MIN_COMPLEX ); celt_assert( complexity <= SILK_PE_MAX_COMPLEX ); silk_assert( search_thres1 >= 0.0f && search_thres1 <= 1.0f ); silk_assert( search_thres2 >= 0.0f && search_thres2 <= 1.0f ); /* Set up frame lengths max / min lag for the sampling frequency */ frame_length = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * Fs_kHz; frame_length_4kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 4; frame_length_8kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 8; sf_length = PE_SUBFR_LENGTH_MS * Fs_kHz; sf_length_4kHz = PE_SUBFR_LENGTH_MS * 4; sf_length_8kHz = PE_SUBFR_LENGTH_MS * 8; min_lag = PE_MIN_LAG_MS * Fs_kHz; min_lag_4kHz = PE_MIN_LAG_MS * 4; min_lag_8kHz = PE_MIN_LAG_MS * 8; max_lag = PE_MAX_LAG_MS * Fs_kHz - 1; max_lag_4kHz = PE_MAX_LAG_MS * 4; max_lag_8kHz = PE_MAX_LAG_MS * 8 - 1; /* Resample from input sampled at Fs_kHz to 8 kHz */ if( Fs_kHz == 16 ) { /* Resample to 16 -> 8 khz */ opus_int16 frame_16_FIX[ 16 * PE_MAX_FRAME_LENGTH_MS ]; silk_float2short_array( frame_16_FIX, frame, frame_length ); silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) ); silk_resampler_down2( filt_state, frame_8_FIX, frame_16_FIX, frame_length ); silk_short2float_array( frame_8kHz, frame_8_FIX, frame_length_8kHz ); } else if( Fs_kHz == 12 ) { /* Resample to 12 -> 8 khz */ opus_int16 frame_12_FIX[ 12 * PE_MAX_FRAME_LENGTH_MS ]; silk_float2short_array( frame_12_FIX, frame, frame_length ); silk_memset( filt_state, 0, 6 * sizeof( opus_int32 ) ); silk_resampler_down2_3( filt_state, frame_8_FIX, frame_12_FIX, frame_length ); silk_short2float_array( frame_8kHz, frame_8_FIX, frame_length_8kHz ); } else { celt_assert( Fs_kHz == 8 ); silk_float2short_array( frame_8_FIX, frame, frame_length_8kHz ); } /* Decimate again to 4 kHz */ silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) ); silk_resampler_down2( filt_state, frame_4_FIX, frame_8_FIX, frame_length_8kHz ); silk_short2float_array( frame_4kHz, frame_4_FIX, frame_length_4kHz ); /* Low-pass filter */ for( i = frame_length_4kHz - 1; i > 0; i-- ) { frame_4kHz[ i ] = silk_ADD_SAT16( frame_4kHz[ i ], frame_4kHz[ i - 1 ] ); } /****************************************************************************** * FIRST STAGE, operating in 4 khz ******************************************************************************/ silk_memset(C, 0, sizeof(silk_float) * nb_subfr * ((PE_MAX_LAG >> 1) + 5)); target_ptr = &frame_4kHz[ silk_LSHIFT( sf_length_4kHz, 2 ) ]; for( k = 0; k < nb_subfr >> 1; k++ ) { /* Check that we are within range of the array */ celt_assert( target_ptr >= frame_4kHz ); celt_assert( target_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz ); basis_ptr = target_ptr - min_lag_4kHz; /* Check that we are within range of the array */ celt_assert( basis_ptr >= frame_4kHz ); celt_assert( basis_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz ); celt_pitch_xcorr( target_ptr, target_ptr-max_lag_4kHz, xcorr, sf_length_8kHz, max_lag_4kHz - min_lag_4kHz + 1, arch ); /* Calculate first vector products before loop */ cross_corr = xcorr[ max_lag_4kHz - min_lag_4kHz ]; normalizer = silk_energy_FLP( target_ptr, sf_length_8kHz ) + silk_energy_FLP( basis_ptr, sf_length_8kHz ) + sf_length_8kHz * 4000.0f; C[ 0 ][ min_lag_4kHz ] += (silk_float)( 2 * cross_corr / normalizer ); /* From now on normalizer is computed recursively */ for( d = min_lag_4kHz + 1; d <= max_lag_4kHz; d++ ) { basis_ptr--; /* Check that we are within range of the array */ silk_assert( basis_ptr >= frame_4kHz ); silk_assert( basis_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz ); cross_corr = xcorr[ max_lag_4kHz - d ]; /* Add contribution of new sample and remove contribution from oldest sample */ normalizer += basis_ptr[ 0 ] * (double)basis_ptr[ 0 ] - basis_ptr[ sf_length_8kHz ] * (double)basis_ptr[ sf_length_8kHz ]; C[ 0 ][ d ] += (silk_float)( 2 * cross_corr / normalizer ); } /* Update target pointer */ target_ptr += sf_length_8kHz; } /* Apply short-lag bias */ for( i = max_lag_4kHz; i >= min_lag_4kHz; i-- ) { C[ 0 ][ i ] -= C[ 0 ][ i ] * i / 4096.0f; } /* Sort */ length_d_srch = 4 + 2 * complexity; celt_assert( 3 * length_d_srch <= PE_D_SRCH_LENGTH ); silk_insertion_sort_decreasing_FLP( &C[ 0 ][ min_lag_4kHz ], d_srch, max_lag_4kHz - min_lag_4kHz + 1, length_d_srch ); /* Escape if correlation is very low already here */ Cmax = C[ 0 ][ min_lag_4kHz ]; if( Cmax < 0.2f ) { silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) ); *LTPCorr = 0.0f; *lagIndex = 0; *contourIndex = 0; return 1; } threshold = search_thres1 * Cmax; for( i = 0; i < length_d_srch; i++ ) { /* Convert to 8 kHz indices for the sorted correlation that exceeds the threshold */ if( C[ 0 ][ min_lag_4kHz + i ] > threshold ) { d_srch[ i ] = silk_LSHIFT( d_srch[ i ] + min_lag_4kHz, 1 ); } else { length_d_srch = i; break; } } celt_assert( length_d_srch > 0 ); for( i = min_lag_8kHz - 5; i < max_lag_8kHz + 5; i++ ) { d_comp[ i ] = 0; } for( i = 0; i < length_d_srch; i++ ) { d_comp[ d_srch[ i ] ] = 1; } /* Convolution */ for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) { d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ]; } length_d_srch = 0; for( i = min_lag_8kHz; i < max_lag_8kHz + 1; i++ ) { if( d_comp[ i + 1 ] > 0 ) { d_srch[ length_d_srch ] = i; length_d_srch++; } } /* Convolution */ for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) { d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ] + d_comp[ i - 3 ]; } length_d_comp = 0; for( i = min_lag_8kHz; i < max_lag_8kHz + 4; i++ ) { if( d_comp[ i ] > 0 ) { d_comp[ length_d_comp ] = (opus_int16)( i - 2 ); length_d_comp++; } } /********************************************************************************** ** SECOND STAGE, operating at 8 kHz, on lag sections with high correlation *************************************************************************************/ /********************************************************************************* * Find energy of each subframe projected onto its history, for a range of delays *********************************************************************************/ silk_memset( C, 0, PE_MAX_NB_SUBFR*((PE_MAX_LAG >> 1) + 5) * sizeof(silk_float)); if( Fs_kHz == 8 ) { target_ptr = &frame[ PE_LTP_MEM_LENGTH_MS * 8 ]; } else { target_ptr = &frame_8kHz[ PE_LTP_MEM_LENGTH_MS * 8 ]; } for( k = 0; k < nb_subfr; k++ ) { energy_tmp = silk_energy_FLP( target_ptr, sf_length_8kHz ) + 1.0; for( j = 0; j < length_d_comp; j++ ) { d = d_comp[ j ]; basis_ptr = target_ptr - d; cross_corr = silk_inner_product_FLP( basis_ptr, target_ptr, sf_length_8kHz ); if( cross_corr > 0.0f ) { energy = silk_energy_FLP( basis_ptr, sf_length_8kHz ); C[ k ][ d ] = (silk_float)( 2 * cross_corr / ( energy + energy_tmp ) ); } else { C[ k ][ d ] = 0.0f; } } target_ptr += sf_length_8kHz; } /* search over lag range and lags codebook */ /* scale factor for lag codebook, as a function of center lag */ CCmax = 0.0f; /* This value doesn't matter */ CCmax_b = -1000.0f; CBimax = 0; /* To avoid returning undefined lag values */ lag = -1; /* To check if lag with strong enough correlation has been found */ if( prevLag > 0 ) { if( Fs_kHz == 12 ) { prevLag = silk_LSHIFT( prevLag, 1 ) / 3; } else if( Fs_kHz == 16 ) { prevLag = silk_RSHIFT( prevLag, 1 ); } prevLag_log2 = silk_log2( (silk_float)prevLag ); } else { prevLag_log2 = 0; } /* Set up stage 2 codebook based on number of subframes */ if( nb_subfr == PE_MAX_NB_SUBFR ) { cbk_size = PE_NB_CBKS_STAGE2_EXT; Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ]; if( Fs_kHz == 8 && complexity > SILK_PE_MIN_COMPLEX ) { /* If input is 8 khz use a larger codebook here because it is last stage */ nb_cbk_search = PE_NB_CBKS_STAGE2_EXT; } else { nb_cbk_search = PE_NB_CBKS_STAGE2; } } else { cbk_size = PE_NB_CBKS_STAGE2_10MS; Lag_CB_ptr = &silk_CB_lags_stage2_10_ms[ 0 ][ 0 ]; nb_cbk_search = PE_NB_CBKS_STAGE2_10MS; } for( k = 0; k < length_d_srch; k++ ) { d = d_srch[ k ]; for( j = 0; j < nb_cbk_search; j++ ) { CC[j] = 0.0f; for( i = 0; i < nb_subfr; i++ ) { /* Try all codebooks */ CC[ j ] += C[ i ][ d + matrix_ptr( Lag_CB_ptr, i, j, cbk_size )]; } } /* Find best codebook */ CCmax_new = -1000.0f; CBimax_new = 0; for( i = 0; i < nb_cbk_search; i++ ) { if( CC[ i ] > CCmax_new ) { CCmax_new = CC[ i ]; CBimax_new = i; } } /* Bias towards shorter lags */ lag_log2 = silk_log2( (silk_float)d ); CCmax_new_b = CCmax_new - PE_SHORTLAG_BIAS * nb_subfr * lag_log2; /* Bias towards previous lag */ if( prevLag > 0 ) { delta_lag_log2_sqr = lag_log2 - prevLag_log2; delta_lag_log2_sqr *= delta_lag_log2_sqr; CCmax_new_b -= PE_PREVLAG_BIAS * nb_subfr * (*LTPCorr) * delta_lag_log2_sqr / ( delta_lag_log2_sqr + 0.5f ); } if( CCmax_new_b > CCmax_b && /* Find maximum biased correlation */ CCmax_new > nb_subfr * search_thres2 /* Correlation needs to be high enough to be voiced */ ) { CCmax_b = CCmax_new_b; CCmax = CCmax_new; lag = d; CBimax = CBimax_new; } } if( lag == -1 ) { /* No suitable candidate found */ silk_memset( pitch_out, 0, PE_MAX_NB_SUBFR * sizeof(opus_int) ); *LTPCorr = 0.0f; *lagIndex = 0; *contourIndex = 0; return 1; } /* Output normalized correlation */ *LTPCorr = (silk_float)( CCmax / nb_subfr ); silk_assert( *LTPCorr >= 0.0f ); if( Fs_kHz > 8 ) { /* Search in original signal */ /* Compensate for decimation */ silk_assert( lag == silk_SAT16( lag ) ); if( Fs_kHz == 12 ) { lag = silk_RSHIFT_ROUND( silk_SMULBB( lag, 3 ), 1 ); } else { /* Fs_kHz == 16 */ lag = silk_LSHIFT( lag, 1 ); } lag = silk_LIMIT_int( lag, min_lag, max_lag ); start_lag = silk_max_int( lag - 2, min_lag ); end_lag = silk_min_int( lag + 2, max_lag ); lag_new = lag; /* to avoid undefined lag */ CBimax = 0; /* to avoid undefined lag */ CCmax = -1000.0f; /* Calculate the correlations and energies needed in stage 3 */ silk_P_Ana_calc_corr_st3( cross_corr_st3, frame, start_lag, sf_length, nb_subfr, complexity, arch ); silk_P_Ana_calc_energy_st3( energies_st3, frame, start_lag, sf_length, nb_subfr, complexity ); lag_counter = 0; silk_assert( lag == silk_SAT16( lag ) ); contour_bias = PE_FLATCONTOUR_BIAS / lag; /* Set up cbk parameters according to complexity setting and frame length */ if( nb_subfr == PE_MAX_NB_SUBFR ) { nb_cbk_search = (opus_int)silk_nb_cbk_searchs_stage3[ complexity ]; cbk_size = PE_NB_CBKS_STAGE3_MAX; Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ]; } else { nb_cbk_search = PE_NB_CBKS_STAGE3_10MS; cbk_size = PE_NB_CBKS_STAGE3_10MS; Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; } target_ptr = &frame[ PE_LTP_MEM_LENGTH_MS * Fs_kHz ]; energy_tmp = silk_energy_FLP( target_ptr, nb_subfr * sf_length ) + 1.0; for( d = start_lag; d <= end_lag; d++ ) { for( j = 0; j < nb_cbk_search; j++ ) { cross_corr = 0.0; energy = energy_tmp; for( k = 0; k < nb_subfr; k++ ) { cross_corr += cross_corr_st3[ k ][ j ][ lag_counter ]; energy += energies_st3[ k ][ j ][ lag_counter ]; } if( cross_corr > 0.0 ) { CCmax_new = (silk_float)( 2 * cross_corr / energy ); /* Reduce depending on flatness of contour */ CCmax_new *= 1.0f - contour_bias * j; } else { CCmax_new = 0.0f; } if( CCmax_new > CCmax && ( d + (opus_int)silk_CB_lags_stage3[ 0 ][ j ] ) <= max_lag ) { CCmax = CCmax_new; lag_new = d; CBimax = j; } } lag_counter++; } for( k = 0; k < nb_subfr; k++ ) { pitch_out[ k ] = lag_new + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size ); pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag, PE_MAX_LAG_MS * Fs_kHz ); } *lagIndex = (opus_int16)( lag_new - min_lag ); *contourIndex = (opus_int8)CBimax; } else { /* Fs_kHz == 8 */ /* Save Lags */ for( k = 0; k < nb_subfr; k++ ) { pitch_out[ k ] = lag + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size ); pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag_8kHz, PE_MAX_LAG_MS * 8 ); } *lagIndex = (opus_int16)( lag - min_lag_8kHz ); *contourIndex = (opus_int8)CBimax; } celt_assert( *lagIndex >= 0 ); /* return as voiced */ return 0; } /*********************************************************************** * Calculates the correlations used in stage 3 search. In order to cover * the whole lag codebook for all the searched offset lags (lag +- 2), * the following correlations are needed in each sub frame: * * sf1: lag range [-8,...,7] total 16 correlations * sf2: lag range [-4,...,4] total 9 correlations * sf3: lag range [-3,....4] total 8 correltions * sf4: lag range [-6,....8] total 15 correlations * * In total 48 correlations. The direct implementation computed in worst * case 4*12*5 = 240 correlations, but more likely around 120. ***********************************************************************/ static void silk_P_Ana_calc_corr_st3( silk_float cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */ const silk_float frame[], /* I vector to correlate */ opus_int start_lag, /* I start lag */ opus_int sf_length, /* I sub frame length */ opus_int nb_subfr, /* I number of subframes */ opus_int complexity, /* I Complexity setting */ int arch /* I Run-time architecture */ ) { const silk_float *target_ptr; opus_int i, j, k, lag_counter, lag_low, lag_high; opus_int nb_cbk_search, delta, idx, cbk_size; silk_float scratch_mem[ SCRATCH_SIZE ]; opus_val32 xcorr[ SCRATCH_SIZE ]; const opus_int8 *Lag_range_ptr, *Lag_CB_ptr; celt_assert( complexity >= SILK_PE_MIN_COMPLEX ); celt_assert( complexity <= SILK_PE_MAX_COMPLEX ); if( nb_subfr == PE_MAX_NB_SUBFR ) { Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ]; Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ]; nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ]; cbk_size = PE_NB_CBKS_STAGE3_MAX; } else { celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1); Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ]; Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; nb_cbk_search = PE_NB_CBKS_STAGE3_10MS; cbk_size = PE_NB_CBKS_STAGE3_10MS; } target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ]; /* Pointer to middle of frame */ for( k = 0; k < nb_subfr; k++ ) { lag_counter = 0; /* Calculate the correlations for each subframe */ lag_low = matrix_ptr( Lag_range_ptr, k, 0, 2 ); lag_high = matrix_ptr( Lag_range_ptr, k, 1, 2 ); silk_assert(lag_high-lag_low+1 <= SCRATCH_SIZE); celt_pitch_xcorr( target_ptr, target_ptr - start_lag - lag_high, xcorr, sf_length, lag_high - lag_low + 1, arch ); for( j = lag_low; j <= lag_high; j++ ) { silk_assert( lag_counter < SCRATCH_SIZE ); scratch_mem[ lag_counter ] = xcorr[ lag_high - j ]; lag_counter++; } delta = matrix_ptr( Lag_range_ptr, k, 0, 2 ); for( i = 0; i < nb_cbk_search; i++ ) { /* Fill out the 3 dim array that stores the correlations for */ /* each code_book vector for each start lag */ idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta; for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) { silk_assert( idx + j < SCRATCH_SIZE ); silk_assert( idx + j < lag_counter ); cross_corr_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ]; } } target_ptr += sf_length; } } /********************************************************************/ /* Calculate the energies for first two subframes. The energies are */ /* calculated recursively. */ /********************************************************************/ static void silk_P_Ana_calc_energy_st3( silk_float energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */ const silk_float frame[], /* I vector to correlate */ opus_int start_lag, /* I start lag */ opus_int sf_length, /* I sub frame length */ opus_int nb_subfr, /* I number of subframes */ opus_int complexity /* I Complexity setting */ ) { const silk_float *target_ptr, *basis_ptr; double energy; opus_int k, i, j, lag_counter; opus_int nb_cbk_search, delta, idx, cbk_size, lag_diff; silk_float scratch_mem[ SCRATCH_SIZE ]; const opus_int8 *Lag_range_ptr, *Lag_CB_ptr; celt_assert( complexity >= SILK_PE_MIN_COMPLEX ); celt_assert( complexity <= SILK_PE_MAX_COMPLEX ); if( nb_subfr == PE_MAX_NB_SUBFR ) { Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ]; Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ]; nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ]; cbk_size = PE_NB_CBKS_STAGE3_MAX; } else { celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1); Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ]; Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; nb_cbk_search = PE_NB_CBKS_STAGE3_10MS; cbk_size = PE_NB_CBKS_STAGE3_10MS; } target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ]; for( k = 0; k < nb_subfr; k++ ) { lag_counter = 0; /* Calculate the energy for first lag */ basis_ptr = target_ptr - ( start_lag + matrix_ptr( Lag_range_ptr, k, 0, 2 ) ); energy = silk_energy_FLP( basis_ptr, sf_length ) + 1e-3; silk_assert( energy >= 0.0 ); scratch_mem[lag_counter] = (silk_float)energy; lag_counter++; lag_diff = ( matrix_ptr( Lag_range_ptr, k, 1, 2 ) - matrix_ptr( Lag_range_ptr, k, 0, 2 ) + 1 ); for( i = 1; i < lag_diff; i++ ) { /* remove part outside new window */ energy -= basis_ptr[sf_length - i] * (double)basis_ptr[sf_length - i]; silk_assert( energy >= 0.0 ); /* add part that comes into window */ energy += basis_ptr[ -i ] * (double)basis_ptr[ -i ]; silk_assert( energy >= 0.0 ); silk_assert( lag_counter < SCRATCH_SIZE ); scratch_mem[lag_counter] = (silk_float)energy; lag_counter++; } delta = matrix_ptr( Lag_range_ptr, k, 0, 2 ); for( i = 0; i < nb_cbk_search; i++ ) { /* Fill out the 3 dim array that stores the correlations for */ /* each code_book vector for each start lag */ idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta; for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) { silk_assert( idx + j < SCRATCH_SIZE ); silk_assert( idx + j < lag_counter ); energies_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ]; silk_assert( energies_st3[ k ][ i ][ j ] >= 0.0f ); } } target_ptr += sf_length; } } jamulus-3.9.1+dfsg/libs/opus/silk/float/autocorrelation_FLP.c0000644000175000017500000000476014340334543023230 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "typedef.h" #include "SigProc_FLP.h" /* compute autocorrelation */ void silk_autocorrelation_FLP( silk_float *results, /* O result (length correlationCount) */ const silk_float *inputData, /* I input data to correlate */ opus_int inputDataSize, /* I length of input */ opus_int correlationCount /* I number of correlation taps to compute */ ) { opus_int i; if( correlationCount > inputDataSize ) { correlationCount = inputDataSize; } for( i = 0; i < correlationCount; i++ ) { results[ i ] = (silk_float)silk_inner_product_FLP( inputData, inputData + i, inputDataSize - i ); } } jamulus-3.9.1+dfsg/libs/opus/silk/float/corrMatrix_FLP.c0000644000175000017500000001135014340334543022141 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif /********************************************************************** * Correlation matrix computations for LS estimate. **********************************************************************/ #include "main_FLP.h" /* Calculates correlation vector X'*t */ void silk_corrVector_FLP( const silk_float *x, /* I x vector [L+order-1] used to create X */ const silk_float *t, /* I Target vector [L] */ const opus_int L, /* I Length of vecors */ const opus_int Order, /* I Max lag for correlation */ silk_float *Xt /* O X'*t correlation vector [order] */ ) { opus_int lag; const silk_float *ptr1; ptr1 = &x[ Order - 1 ]; /* Points to first sample of column 0 of X: X[:,0] */ for( lag = 0; lag < Order; lag++ ) { /* Calculate X[:,lag]'*t */ Xt[ lag ] = (silk_float)silk_inner_product_FLP( ptr1, t, L ); ptr1--; /* Next column of X */ } } /* Calculates correlation matrix X'*X */ void silk_corrMatrix_FLP( const silk_float *x, /* I x vector [ L+order-1 ] used to create X */ const opus_int L, /* I Length of vectors */ const opus_int Order, /* I Max lag for correlation */ silk_float *XX /* O X'*X correlation matrix [order x order] */ ) { opus_int j, lag; double energy; const silk_float *ptr1, *ptr2; ptr1 = &x[ Order - 1 ]; /* First sample of column 0 of X */ energy = silk_energy_FLP( ptr1, L ); /* X[:,0]'*X[:,0] */ matrix_ptr( XX, 0, 0, Order ) = ( silk_float )energy; for( j = 1; j < Order; j++ ) { /* Calculate X[:,j]'*X[:,j] */ energy += ptr1[ -j ] * ptr1[ -j ] - ptr1[ L - j ] * ptr1[ L - j ]; matrix_ptr( XX, j, j, Order ) = ( silk_float )energy; } ptr2 = &x[ Order - 2 ]; /* First sample of column 1 of X */ for( lag = 1; lag < Order; lag++ ) { /* Calculate X[:,0]'*X[:,lag] */ energy = silk_inner_product_FLP( ptr1, ptr2, L ); matrix_ptr( XX, lag, 0, Order ) = ( silk_float )energy; matrix_ptr( XX, 0, lag, Order ) = ( silk_float )energy; /* Calculate X[:,j]'*X[:,j + lag] */ for( j = 1; j < ( Order - lag ); j++ ) { energy += ptr1[ -j ] * ptr2[ -j ] - ptr1[ L - j ] * ptr2[ L - j ]; matrix_ptr( XX, lag + j, j, Order ) = ( silk_float )energy; matrix_ptr( XX, j, lag + j, Order ) = ( silk_float )energy; } ptr2--; /* Next column of X */ } } jamulus-3.9.1+dfsg/libs/opus/silk/float/LPC_analysis_filter_FLP.c0000644000175000017500000002445314340334543023705 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "main_FLP.h" /************************************************/ /* LPC analysis filter */ /* NB! State is kept internally and the */ /* filter always starts with zero state */ /* first Order output samples are set to zero */ /************************************************/ /* 16th order LPC analysis filter, does not write first 16 samples */ static OPUS_INLINE void silk_LPC_analysis_filter16_FLP( silk_float r_LPC[], /* O LPC residual signal */ const silk_float PredCoef[], /* I LPC coefficients */ const silk_float s[], /* I Input signal */ const opus_int length /* I Length of input signal */ ) { opus_int ix; silk_float LPC_pred; const silk_float *s_ptr; for( ix = 16; ix < length; ix++ ) { s_ptr = &s[ix - 1]; /* short-term prediction */ LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] + s_ptr[ -1 ] * PredCoef[ 1 ] + s_ptr[ -2 ] * PredCoef[ 2 ] + s_ptr[ -3 ] * PredCoef[ 3 ] + s_ptr[ -4 ] * PredCoef[ 4 ] + s_ptr[ -5 ] * PredCoef[ 5 ] + s_ptr[ -6 ] * PredCoef[ 6 ] + s_ptr[ -7 ] * PredCoef[ 7 ] + s_ptr[ -8 ] * PredCoef[ 8 ] + s_ptr[ -9 ] * PredCoef[ 9 ] + s_ptr[ -10 ] * PredCoef[ 10 ] + s_ptr[ -11 ] * PredCoef[ 11 ] + s_ptr[ -12 ] * PredCoef[ 12 ] + s_ptr[ -13 ] * PredCoef[ 13 ] + s_ptr[ -14 ] * PredCoef[ 14 ] + s_ptr[ -15 ] * PredCoef[ 15 ]; /* prediction error */ r_LPC[ix] = s_ptr[ 1 ] - LPC_pred; } } /* 12th order LPC analysis filter, does not write first 12 samples */ static OPUS_INLINE void silk_LPC_analysis_filter12_FLP( silk_float r_LPC[], /* O LPC residual signal */ const silk_float PredCoef[], /* I LPC coefficients */ const silk_float s[], /* I Input signal */ const opus_int length /* I Length of input signal */ ) { opus_int ix; silk_float LPC_pred; const silk_float *s_ptr; for( ix = 12; ix < length; ix++ ) { s_ptr = &s[ix - 1]; /* short-term prediction */ LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] + s_ptr[ -1 ] * PredCoef[ 1 ] + s_ptr[ -2 ] * PredCoef[ 2 ] + s_ptr[ -3 ] * PredCoef[ 3 ] + s_ptr[ -4 ] * PredCoef[ 4 ] + s_ptr[ -5 ] * PredCoef[ 5 ] + s_ptr[ -6 ] * PredCoef[ 6 ] + s_ptr[ -7 ] * PredCoef[ 7 ] + s_ptr[ -8 ] * PredCoef[ 8 ] + s_ptr[ -9 ] * PredCoef[ 9 ] + s_ptr[ -10 ] * PredCoef[ 10 ] + s_ptr[ -11 ] * PredCoef[ 11 ]; /* prediction error */ r_LPC[ix] = s_ptr[ 1 ] - LPC_pred; } } /* 10th order LPC analysis filter, does not write first 10 samples */ static OPUS_INLINE void silk_LPC_analysis_filter10_FLP( silk_float r_LPC[], /* O LPC residual signal */ const silk_float PredCoef[], /* I LPC coefficients */ const silk_float s[], /* I Input signal */ const opus_int length /* I Length of input signal */ ) { opus_int ix; silk_float LPC_pred; const silk_float *s_ptr; for( ix = 10; ix < length; ix++ ) { s_ptr = &s[ix - 1]; /* short-term prediction */ LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] + s_ptr[ -1 ] * PredCoef[ 1 ] + s_ptr[ -2 ] * PredCoef[ 2 ] + s_ptr[ -3 ] * PredCoef[ 3 ] + s_ptr[ -4 ] * PredCoef[ 4 ] + s_ptr[ -5 ] * PredCoef[ 5 ] + s_ptr[ -6 ] * PredCoef[ 6 ] + s_ptr[ -7 ] * PredCoef[ 7 ] + s_ptr[ -8 ] * PredCoef[ 8 ] + s_ptr[ -9 ] * PredCoef[ 9 ]; /* prediction error */ r_LPC[ix] = s_ptr[ 1 ] - LPC_pred; } } /* 8th order LPC analysis filter, does not write first 8 samples */ static OPUS_INLINE void silk_LPC_analysis_filter8_FLP( silk_float r_LPC[], /* O LPC residual signal */ const silk_float PredCoef[], /* I LPC coefficients */ const silk_float s[], /* I Input signal */ const opus_int length /* I Length of input signal */ ) { opus_int ix; silk_float LPC_pred; const silk_float *s_ptr; for( ix = 8; ix < length; ix++ ) { s_ptr = &s[ix - 1]; /* short-term prediction */ LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] + s_ptr[ -1 ] * PredCoef[ 1 ] + s_ptr[ -2 ] * PredCoef[ 2 ] + s_ptr[ -3 ] * PredCoef[ 3 ] + s_ptr[ -4 ] * PredCoef[ 4 ] + s_ptr[ -5 ] * PredCoef[ 5 ] + s_ptr[ -6 ] * PredCoef[ 6 ] + s_ptr[ -7 ] * PredCoef[ 7 ]; /* prediction error */ r_LPC[ix] = s_ptr[ 1 ] - LPC_pred; } } /* 6th order LPC analysis filter, does not write first 6 samples */ static OPUS_INLINE void silk_LPC_analysis_filter6_FLP( silk_float r_LPC[], /* O LPC residual signal */ const silk_float PredCoef[], /* I LPC coefficients */ const silk_float s[], /* I Input signal */ const opus_int length /* I Length of input signal */ ) { opus_int ix; silk_float LPC_pred; const silk_float *s_ptr; for( ix = 6; ix < length; ix++ ) { s_ptr = &s[ix - 1]; /* short-term prediction */ LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] + s_ptr[ -1 ] * PredCoef[ 1 ] + s_ptr[ -2 ] * PredCoef[ 2 ] + s_ptr[ -3 ] * PredCoef[ 3 ] + s_ptr[ -4 ] * PredCoef[ 4 ] + s_ptr[ -5 ] * PredCoef[ 5 ]; /* prediction error */ r_LPC[ix] = s_ptr[ 1 ] - LPC_pred; } } /************************************************/ /* LPC analysis filter */ /* NB! State is kept internally and the */ /* filter always starts with zero state */ /* first Order output samples are set to zero */ /************************************************/ void silk_LPC_analysis_filter_FLP( silk_float r_LPC[], /* O LPC residual signal */ const silk_float PredCoef[], /* I LPC coefficients */ const silk_float s[], /* I Input signal */ const opus_int length, /* I Length of input signal */ const opus_int Order /* I LPC order */ ) { celt_assert( Order <= length ); switch( Order ) { case 6: silk_LPC_analysis_filter6_FLP( r_LPC, PredCoef, s, length ); break; case 8: silk_LPC_analysis_filter8_FLP( r_LPC, PredCoef, s, length ); break; case 10: silk_LPC_analysis_filter10_FLP( r_LPC, PredCoef, s, length ); break; case 12: silk_LPC_analysis_filter12_FLP( r_LPC, PredCoef, s, length ); break; case 16: silk_LPC_analysis_filter16_FLP( r_LPC, PredCoef, s, length ); break; default: celt_assert( 0 ); break; } /* Set first Order output samples to zero */ silk_memset( r_LPC, 0, Order * sizeof( silk_float ) ); } jamulus-3.9.1+dfsg/libs/opus/silk/float/LTP_analysis_filter_FLP.c0000644000175000017500000000722114340334543023720 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main_FLP.h" void silk_LTP_analysis_filter_FLP( silk_float *LTP_res, /* O LTP res MAX_NB_SUBFR*(pre_lgth+subfr_lngth) */ const silk_float *x, /* I Input signal, with preceding samples */ const silk_float B[ LTP_ORDER * MAX_NB_SUBFR ], /* I LTP coefficients for each subframe */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ const silk_float invGains[ MAX_NB_SUBFR ], /* I Inverse quantization gains */ const opus_int subfr_length, /* I Length of each subframe */ const opus_int nb_subfr, /* I number of subframes */ const opus_int pre_length /* I Preceding samples for each subframe */ ) { const silk_float *x_ptr, *x_lag_ptr; silk_float Btmp[ LTP_ORDER ]; silk_float *LTP_res_ptr; silk_float inv_gain; opus_int k, i, j; x_ptr = x; LTP_res_ptr = LTP_res; for( k = 0; k < nb_subfr; k++ ) { x_lag_ptr = x_ptr - pitchL[ k ]; inv_gain = invGains[ k ]; for( i = 0; i < LTP_ORDER; i++ ) { Btmp[ i ] = B[ k * LTP_ORDER + i ]; } /* LTP analysis FIR filter */ for( i = 0; i < subfr_length + pre_length; i++ ) { LTP_res_ptr[ i ] = x_ptr[ i ]; /* Subtract long-term prediction */ for( j = 0; j < LTP_ORDER; j++ ) { LTP_res_ptr[ i ] -= Btmp[ j ] * x_lag_ptr[ LTP_ORDER / 2 - j ]; } LTP_res_ptr[ i ] *= inv_gain; x_lag_ptr++; } /* Update pointers */ LTP_res_ptr += subfr_length + pre_length; x_ptr += subfr_length; } } jamulus-3.9.1+dfsg/libs/opus/silk/float/structs_FLP.h0000644000175000017500000001130614340334543021524 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SILK_STRUCTS_FLP_H #define SILK_STRUCTS_FLP_H #include "typedef.h" #include "main.h" #include "structs.h" #ifdef __cplusplus extern "C" { #endif /********************************/ /* Noise shaping analysis state */ /********************************/ typedef struct { opus_int8 LastGainIndex; silk_float HarmShapeGain_smth; silk_float Tilt_smth; } silk_shape_state_FLP; /********************************/ /* Encoder state FLP */ /********************************/ typedef struct { silk_encoder_state sCmn; /* Common struct, shared with fixed-point code */ silk_shape_state_FLP sShape; /* Noise shaping state */ /* Buffer for find pitch and noise shape analysis */ silk_float x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ];/* Buffer for find pitch and noise shape analysis */ silk_float LTPCorr; /* Normalized correlation from pitch lag estimator */ } silk_encoder_state_FLP; /************************/ /* Encoder control FLP */ /************************/ typedef struct { /* Prediction and coding parameters */ silk_float Gains[ MAX_NB_SUBFR ]; silk_float PredCoef[ 2 ][ MAX_LPC_ORDER ]; /* holds interpolated and final coefficients */ silk_float LTPCoef[LTP_ORDER * MAX_NB_SUBFR]; silk_float LTP_scale; opus_int pitchL[ MAX_NB_SUBFR ]; /* Noise shaping parameters */ silk_float AR[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ]; silk_float LF_MA_shp[ MAX_NB_SUBFR ]; silk_float LF_AR_shp[ MAX_NB_SUBFR ]; silk_float Tilt[ MAX_NB_SUBFR ]; silk_float HarmShapeGain[ MAX_NB_SUBFR ]; silk_float Lambda; silk_float input_quality; silk_float coding_quality; /* Measures */ silk_float predGain; silk_float LTPredCodGain; silk_float ResNrg[ MAX_NB_SUBFR ]; /* Residual energy per subframe */ /* Parameters for CBR mode */ opus_int32 GainsUnq_Q16[ MAX_NB_SUBFR ]; opus_int8 lastGainIndexPrev; } silk_encoder_control_FLP; /************************/ /* Encoder Super Struct */ /************************/ typedef struct { silk_encoder_state_FLP state_Fxx[ ENCODER_NUM_CHANNELS ]; stereo_enc_state sStereo; opus_int32 nBitsUsedLBRR; opus_int32 nBitsExceeded; opus_int nChannelsAPI; opus_int nChannelsInternal; opus_int nPrevChannelsInternal; opus_int timeSinceSwitchAllowed_ms; opus_int allowBandwidthSwitch; opus_int prev_decode_only_middle; } silk_encoder; #ifdef __cplusplus } #endif #endif jamulus-3.9.1+dfsg/libs/opus/silk/float/process_gains_FLP.c0000644000175000017500000001176314340334543022656 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main_FLP.h" #include "tuning_parameters.h" /* Processing of gains */ void silk_process_gains_FLP( silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ opus_int condCoding /* I The type of conditional coding to use */ ) { silk_shape_state_FLP *psShapeSt = &psEnc->sShape; opus_int k; opus_int32 pGains_Q16[ MAX_NB_SUBFR ]; silk_float s, InvMaxSqrVal, gain, quant_offset; /* Gain reduction when LTP coding gain is high */ if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { s = 1.0f - 0.5f * silk_sigmoid( 0.25f * ( psEncCtrl->LTPredCodGain - 12.0f ) ); for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { psEncCtrl->Gains[ k ] *= s; } } /* Limit the quantized signal */ InvMaxSqrVal = ( silk_float )( pow( 2.0f, 0.33f * ( 21.0f - psEnc->sCmn.SNR_dB_Q7 * ( 1 / 128.0f ) ) ) / psEnc->sCmn.subfr_length ); for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { /* Soft limit on ratio residual energy and squared gains */ gain = psEncCtrl->Gains[ k ]; gain = ( silk_float )sqrt( gain * gain + psEncCtrl->ResNrg[ k ] * InvMaxSqrVal ); psEncCtrl->Gains[ k ] = silk_min_float( gain, 32767.0f ); } /* Prepare gains for noise shaping quantization */ for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { pGains_Q16[ k ] = (opus_int32)( psEncCtrl->Gains[ k ] * 65536.0f ); } /* Save unquantized gains and gain Index */ silk_memcpy( psEncCtrl->GainsUnq_Q16, pGains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) ); psEncCtrl->lastGainIndexPrev = psShapeSt->LastGainIndex; /* Quantize gains */ silk_gains_quant( psEnc->sCmn.indices.GainsIndices, pGains_Q16, &psShapeSt->LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); /* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */ for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { psEncCtrl->Gains[ k ] = pGains_Q16[ k ] / 65536.0f; } /* Set quantizer offset for voiced signals. Larger offset when LTP coding gain is low or tilt is high (ie low-pass) */ if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { if( psEncCtrl->LTPredCodGain + psEnc->sCmn.input_tilt_Q15 * ( 1.0f / 32768.0f ) > 1.0f ) { psEnc->sCmn.indices.quantOffsetType = 0; } else { psEnc->sCmn.indices.quantOffsetType = 1; } } /* Quantizer boundary adjustment */ quant_offset = silk_Quantization_Offsets_Q10[ psEnc->sCmn.indices.signalType >> 1 ][ psEnc->sCmn.indices.quantOffsetType ] / 1024.0f; psEncCtrl->Lambda = LAMBDA_OFFSET + LAMBDA_DELAYED_DECISIONS * psEnc->sCmn.nStatesDelayedDecision + LAMBDA_SPEECH_ACT * psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f ) + LAMBDA_INPUT_QUALITY * psEncCtrl->input_quality + LAMBDA_CODING_QUALITY * psEncCtrl->coding_quality + LAMBDA_QUANT_OFFSET * quant_offset; silk_assert( psEncCtrl->Lambda > 0.0f ); silk_assert( psEncCtrl->Lambda < 2.0f ); } jamulus-3.9.1+dfsg/libs/opus/silk/float/find_pred_coefs_FLP.c0000644000175000017500000001352114340334543023122 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main_FLP.h" /* Find LPC and LTP coefficients */ void silk_find_pred_coefs_FLP( silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ const silk_float res_pitch[], /* I Residual from pitch analysis */ const silk_float x[], /* I Speech signal */ opus_int condCoding /* I The type of conditional coding to use */ ) { opus_int i; silk_float XXLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ]; silk_float xXLTP[ MAX_NB_SUBFR * LTP_ORDER ]; silk_float invGains[ MAX_NB_SUBFR ]; opus_int16 NLSF_Q15[ MAX_LPC_ORDER ]; const silk_float *x_ptr; silk_float *x_pre_ptr, LPC_in_pre[ MAX_NB_SUBFR * MAX_LPC_ORDER + MAX_FRAME_LENGTH ]; silk_float minInvGain; /* Weighting for weighted least squares */ for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { silk_assert( psEncCtrl->Gains[ i ] > 0.0f ); invGains[ i ] = 1.0f / psEncCtrl->Gains[ i ]; } if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { /**********/ /* VOICED */ /**********/ celt_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 ); /* LTP analysis */ silk_find_LTP_FLP( XXLTP, xXLTP, res_pitch, psEncCtrl->pitchL, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr ); /* Quantize LTP gain parameters */ silk_quant_LTP_gains_FLP( psEncCtrl->LTPCoef, psEnc->sCmn.indices.LTPIndex, &psEnc->sCmn.indices.PERIndex, &psEnc->sCmn.sum_log_gain_Q7, &psEncCtrl->LTPredCodGain, XXLTP, xXLTP, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.arch ); /* Control LTP scaling */ silk_LTP_scale_ctrl_FLP( psEnc, psEncCtrl, condCoding ); /* Create LTP residual */ silk_LTP_analysis_filter_FLP( LPC_in_pre, x - psEnc->sCmn.predictLPCOrder, psEncCtrl->LTPCoef, psEncCtrl->pitchL, invGains, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder ); } else { /************/ /* UNVOICED */ /************/ /* Create signal with prepended subframes, scaled by inverse gains */ x_ptr = x - psEnc->sCmn.predictLPCOrder; x_pre_ptr = LPC_in_pre; for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { silk_scale_copy_vector_FLP( x_pre_ptr, x_ptr, invGains[ i ], psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder ); x_pre_ptr += psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder; x_ptr += psEnc->sCmn.subfr_length; } silk_memset( psEncCtrl->LTPCoef, 0, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( silk_float ) ); psEncCtrl->LTPredCodGain = 0.0f; psEnc->sCmn.sum_log_gain_Q7 = 0; } /* Limit on total predictive coding gain */ if( psEnc->sCmn.first_frame_after_reset ) { minInvGain = 1.0f / MAX_PREDICTION_POWER_GAIN_AFTER_RESET; } else { minInvGain = (silk_float)pow( 2, psEncCtrl->LTPredCodGain / 3 ) / MAX_PREDICTION_POWER_GAIN; minInvGain /= 0.25f + 0.75f * psEncCtrl->coding_quality; } /* LPC_in_pre contains the LTP-filtered input for voiced, and the unfiltered input for unvoiced */ silk_find_LPC_FLP( &psEnc->sCmn, NLSF_Q15, LPC_in_pre, minInvGain ); /* Quantize LSFs */ silk_process_NLSFs_FLP( &psEnc->sCmn, psEncCtrl->PredCoef, NLSF_Q15, psEnc->sCmn.prev_NLSFq_Q15 ); /* Calculate residual energy using quantized LPC coefficients */ silk_residual_energy_FLP( psEncCtrl->ResNrg, LPC_in_pre, psEncCtrl->PredCoef, psEncCtrl->Gains, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder ); /* Copy to prediction struct for use in next frame for interpolation */ silk_memcpy( psEnc->sCmn.prev_NLSFq_Q15, NLSF_Q15, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) ); } jamulus-3.9.1+dfsg/libs/opus/silk/float/find_LPC_FLP.c0000644000175000017500000001251314340334543021427 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "define.h" #include "main_FLP.h" #include "tuning_parameters.h" /* LPC analysis */ void silk_find_LPC_FLP( silk_encoder_state *psEncC, /* I/O Encoder state */ opus_int16 NLSF_Q15[], /* O NLSFs */ const silk_float x[], /* I Input signal */ const silk_float minInvGain /* I Inverse of max prediction gain */ ) { opus_int k, subfr_length; silk_float a[ MAX_LPC_ORDER ]; /* Used only for NLSF interpolation */ silk_float res_nrg, res_nrg_2nd, res_nrg_interp; opus_int16 NLSF0_Q15[ MAX_LPC_ORDER ]; silk_float a_tmp[ MAX_LPC_ORDER ]; silk_float LPC_res[ MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ]; subfr_length = psEncC->subfr_length + psEncC->predictLPCOrder; /* Default: No interpolation */ psEncC->indices.NLSFInterpCoef_Q2 = 4; /* Burg AR analysis for the full frame */ res_nrg = silk_burg_modified_FLP( a, x, minInvGain, subfr_length, psEncC->nb_subfr, psEncC->predictLPCOrder ); if( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) { /* Optimal solution for last 10 ms; subtract residual energy here, as that's easier than */ /* adding it to the residual energy of the first 10 ms in each iteration of the search below */ res_nrg -= silk_burg_modified_FLP( a_tmp, x + ( MAX_NB_SUBFR / 2 ) * subfr_length, minInvGain, subfr_length, MAX_NB_SUBFR / 2, psEncC->predictLPCOrder ); /* Convert to NLSFs */ silk_A2NLSF_FLP( NLSF_Q15, a_tmp, psEncC->predictLPCOrder ); /* Search over interpolation indices to find the one with lowest residual energy */ res_nrg_2nd = silk_float_MAX; for( k = 3; k >= 0; k-- ) { /* Interpolate NLSFs for first half */ silk_interpolate( NLSF0_Q15, psEncC->prev_NLSFq_Q15, NLSF_Q15, k, psEncC->predictLPCOrder ); /* Convert to LPC for residual energy evaluation */ silk_NLSF2A_FLP( a_tmp, NLSF0_Q15, psEncC->predictLPCOrder, psEncC->arch ); /* Calculate residual energy with LSF interpolation */ silk_LPC_analysis_filter_FLP( LPC_res, a_tmp, x, 2 * subfr_length, psEncC->predictLPCOrder ); res_nrg_interp = (silk_float)( silk_energy_FLP( LPC_res + psEncC->predictLPCOrder, subfr_length - psEncC->predictLPCOrder ) + silk_energy_FLP( LPC_res + psEncC->predictLPCOrder + subfr_length, subfr_length - psEncC->predictLPCOrder ) ); /* Determine whether current interpolated NLSFs are best so far */ if( res_nrg_interp < res_nrg ) { /* Interpolation has lower residual energy */ res_nrg = res_nrg_interp; psEncC->indices.NLSFInterpCoef_Q2 = (opus_int8)k; } else if( res_nrg_interp > res_nrg_2nd ) { /* No reason to continue iterating - residual energies will continue to climb */ break; } res_nrg_2nd = res_nrg_interp; } } if( psEncC->indices.NLSFInterpCoef_Q2 == 4 ) { /* NLSF interpolation is currently inactive, calculate NLSFs from full frame AR coefficients */ silk_A2NLSF_FLP( NLSF_Q15, a, psEncC->predictLPCOrder ); } celt_assert( psEncC->indices.NLSFInterpCoef_Q2 == 4 || ( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) ); } jamulus-3.9.1+dfsg/libs/opus/silk/float/inner_product_FLP.c0000644000175000017500000000462114340334543022665 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FLP.h" /* inner product of two silk_float arrays, with result as double */ double silk_inner_product_FLP( const silk_float *data1, const silk_float *data2, opus_int dataSize ) { opus_int i; double result; /* 4x unrolled loop */ result = 0.0; for( i = 0; i < dataSize - 3; i += 4 ) { result += data1[ i + 0 ] * (double)data2[ i + 0 ] + data1[ i + 1 ] * (double)data2[ i + 1 ] + data1[ i + 2 ] * (double)data2[ i + 2 ] + data1[ i + 3 ] * (double)data2[ i + 3 ]; } /* add any remaining products */ for( ; i < dataSize; i++ ) { result += data1[ i ] * (double)data2[ i ]; } return result; } jamulus-3.9.1+dfsg/libs/opus/silk/float/scale_vector_FLP.c0000644000175000017500000000432514340334543022464 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FLP.h" /* multiply a vector by a constant */ void silk_scale_vector_FLP( silk_float *data1, silk_float gain, opus_int dataSize ) { opus_int i, dataSize4; /* 4x unrolled loop */ dataSize4 = dataSize & 0xFFFC; for( i = 0; i < dataSize4; i += 4 ) { data1[ i + 0 ] *= gain; data1[ i + 1 ] *= gain; data1[ i + 2 ] *= gain; data1[ i + 3 ] *= gain; } /* any remaining elements */ for( ; i < dataSize; i++ ) { data1[ i ] *= gain; } } jamulus-3.9.1+dfsg/libs/opus/silk/float/find_pitch_lags_FLP.c0000644000175000017500000001452014340334543023126 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "main_FLP.h" #include "tuning_parameters.h" void silk_find_pitch_lags_FLP( silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ silk_float res[], /* O Residual */ const silk_float x[], /* I Speech signal */ int arch /* I Run-time architecture */ ) { opus_int buf_len; silk_float thrhld, res_nrg; const silk_float *x_buf_ptr, *x_buf; silk_float auto_corr[ MAX_FIND_PITCH_LPC_ORDER + 1 ]; silk_float A[ MAX_FIND_PITCH_LPC_ORDER ]; silk_float refl_coef[ MAX_FIND_PITCH_LPC_ORDER ]; silk_float Wsig[ FIND_PITCH_LPC_WIN_MAX ]; silk_float *Wsig_ptr; /******************************************/ /* Set up buffer lengths etc based on Fs */ /******************************************/ buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length; /* Safety check */ celt_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length ); x_buf = x - psEnc->sCmn.ltp_mem_length; /******************************************/ /* Estimate LPC AR coefficients */ /******************************************/ /* Calculate windowed signal */ /* First LA_LTP samples */ x_buf_ptr = x_buf + buf_len - psEnc->sCmn.pitch_LPC_win_length; Wsig_ptr = Wsig; silk_apply_sine_window_FLP( Wsig_ptr, x_buf_ptr, 1, psEnc->sCmn.la_pitch ); /* Middle non-windowed samples */ Wsig_ptr += psEnc->sCmn.la_pitch; x_buf_ptr += psEnc->sCmn.la_pitch; silk_memcpy( Wsig_ptr, x_buf_ptr, ( psEnc->sCmn.pitch_LPC_win_length - ( psEnc->sCmn.la_pitch << 1 ) ) * sizeof( silk_float ) ); /* Last LA_LTP samples */ Wsig_ptr += psEnc->sCmn.pitch_LPC_win_length - ( psEnc->sCmn.la_pitch << 1 ); x_buf_ptr += psEnc->sCmn.pitch_LPC_win_length - ( psEnc->sCmn.la_pitch << 1 ); silk_apply_sine_window_FLP( Wsig_ptr, x_buf_ptr, 2, psEnc->sCmn.la_pitch ); /* Calculate autocorrelation sequence */ silk_autocorrelation_FLP( auto_corr, Wsig, psEnc->sCmn.pitch_LPC_win_length, psEnc->sCmn.pitchEstimationLPCOrder + 1 ); /* Add white noise, as a fraction of the energy */ auto_corr[ 0 ] += auto_corr[ 0 ] * FIND_PITCH_WHITE_NOISE_FRACTION + 1; /* Calculate the reflection coefficients using Schur */ res_nrg = silk_schur_FLP( refl_coef, auto_corr, psEnc->sCmn.pitchEstimationLPCOrder ); /* Prediction gain */ psEncCtrl->predGain = auto_corr[ 0 ] / silk_max_float( res_nrg, 1.0f ); /* Convert reflection coefficients to prediction coefficients */ silk_k2a_FLP( A, refl_coef, psEnc->sCmn.pitchEstimationLPCOrder ); /* Bandwidth expansion */ silk_bwexpander_FLP( A, psEnc->sCmn.pitchEstimationLPCOrder, FIND_PITCH_BANDWIDTH_EXPANSION ); /*****************************************/ /* LPC analysis filtering */ /*****************************************/ silk_LPC_analysis_filter_FLP( res, A, x_buf, buf_len, psEnc->sCmn.pitchEstimationLPCOrder ); if( psEnc->sCmn.indices.signalType != TYPE_NO_VOICE_ACTIVITY && psEnc->sCmn.first_frame_after_reset == 0 ) { /* Threshold for pitch estimator */ thrhld = 0.6f; thrhld -= 0.004f * psEnc->sCmn.pitchEstimationLPCOrder; thrhld -= 0.1f * psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f ); thrhld -= 0.15f * (psEnc->sCmn.prevSignalType >> 1); thrhld -= 0.1f * psEnc->sCmn.input_tilt_Q15 * ( 1.0f / 32768.0f ); /*****************************************/ /* Call Pitch estimator */ /*****************************************/ if( silk_pitch_analysis_core_FLP( res, psEncCtrl->pitchL, &psEnc->sCmn.indices.lagIndex, &psEnc->sCmn.indices.contourIndex, &psEnc->LTPCorr, psEnc->sCmn.prevLag, psEnc->sCmn.pitchEstimationThreshold_Q16 / 65536.0f, thrhld, psEnc->sCmn.fs_kHz, psEnc->sCmn.pitchEstimationComplexity, psEnc->sCmn.nb_subfr, arch ) == 0 ) { psEnc->sCmn.indices.signalType = TYPE_VOICED; } else { psEnc->sCmn.indices.signalType = TYPE_UNVOICED; } } else { silk_memset( psEncCtrl->pitchL, 0, sizeof( psEncCtrl->pitchL ) ); psEnc->sCmn.indices.lagIndex = 0; psEnc->sCmn.indices.contourIndex = 0; psEnc->LTPCorr = 0; } } jamulus-3.9.1+dfsg/libs/opus/silk/float/find_LTP_FLP.c0000644000175000017500000000643214340334543021453 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main_FLP.h" #include "tuning_parameters.h" void silk_find_LTP_FLP( silk_float XX[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */ silk_float xX[ MAX_NB_SUBFR * LTP_ORDER ], /* O Weight for LTP quantization */ const silk_float r_ptr[], /* I LPC residual */ const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */ const opus_int subfr_length, /* I Subframe length */ const opus_int nb_subfr /* I number of subframes */ ) { opus_int k; silk_float *xX_ptr, *XX_ptr; const silk_float *lag_ptr; silk_float xx, temp; xX_ptr = xX; XX_ptr = XX; for( k = 0; k < nb_subfr; k++ ) { lag_ptr = r_ptr - ( lag[ k ] + LTP_ORDER / 2 ); silk_corrMatrix_FLP( lag_ptr, subfr_length, LTP_ORDER, XX_ptr ); silk_corrVector_FLP( lag_ptr, r_ptr, subfr_length, LTP_ORDER, xX_ptr ); xx = ( silk_float )silk_energy_FLP( r_ptr, subfr_length + LTP_ORDER ); temp = 1.0f / silk_max( xx, LTP_CORR_INV_MAX * 0.5f * ( XX_ptr[ 0 ] + XX_ptr[ 24 ] ) + 1.0f ); silk_scale_vector_FLP( XX_ptr, temp, LTP_ORDER * LTP_ORDER ); silk_scale_vector_FLP( xX_ptr, temp, LTP_ORDER ); r_ptr += subfr_length; XX_ptr += LTP_ORDER * LTP_ORDER; xX_ptr += LTP_ORDER; } } jamulus-3.9.1+dfsg/libs/opus/silk/float/encode_frame_FLP.c0000644000175000017500000005323514340334543022426 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "main_FLP.h" #include "tuning_parameters.h" /* Low Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode with lower bitrate */ static OPUS_INLINE void silk_LBRR_encode_FLP( silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ const silk_float xfw[], /* I Input signal */ opus_int condCoding /* I The type of conditional coding used so far for this frame */ ); void silk_encode_do_VAD_FLP( silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ opus_int activity /* I Decision of Opus voice activity detector */ ) { const opus_int activity_threshold = SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ); /****************************/ /* Voice Activity Detection */ /****************************/ silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.arch ); /* If Opus VAD is inactive and Silk VAD is active: lower Silk VAD to just under the threshold */ if( activity == VAD_NO_ACTIVITY && psEnc->sCmn.speech_activity_Q8 >= activity_threshold ) { psEnc->sCmn.speech_activity_Q8 = activity_threshold - 1; } /**************************************************/ /* Convert speech activity into VAD and DTX flags */ /**************************************************/ if( psEnc->sCmn.speech_activity_Q8 < activity_threshold ) { psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY; psEnc->sCmn.noSpeechCounter++; if( psEnc->sCmn.noSpeechCounter <= NB_SPEECH_FRAMES_BEFORE_DTX ) { psEnc->sCmn.inDTX = 0; } else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) { psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX; psEnc->sCmn.inDTX = 0; } psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 0; } else { psEnc->sCmn.noSpeechCounter = 0; psEnc->sCmn.inDTX = 0; psEnc->sCmn.indices.signalType = TYPE_UNVOICED; psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 1; } } /****************/ /* Encode frame */ /****************/ opus_int silk_encode_frame_FLP( silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ opus_int32 *pnBytesOut, /* O Number of payload bytes; */ ec_enc *psRangeEnc, /* I/O compressor data structure */ opus_int condCoding, /* I The type of conditional coding to use */ opus_int maxBits, /* I If > 0: maximum number of output bits */ opus_int useCBR /* I Flag to force constant-bitrate operation */ ) { silk_encoder_control_FLP sEncCtrl; opus_int i, iter, maxIter, found_upper, found_lower, ret = 0; silk_float *x_frame, *res_pitch_frame; silk_float res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ]; ec_enc sRangeEnc_copy, sRangeEnc_copy2; silk_nsq_state sNSQ_copy, sNSQ_copy2; opus_int32 seed_copy, nBits, nBits_lower, nBits_upper, gainMult_lower, gainMult_upper; opus_int32 gainsID, gainsID_lower, gainsID_upper; opus_int16 gainMult_Q8; opus_int16 ec_prevLagIndex_copy; opus_int ec_prevSignalType_copy; opus_int8 LastGainIndex_copy2; opus_int32 pGains_Q16[ MAX_NB_SUBFR ]; opus_uint8 ec_buf_copy[ 1275 ]; opus_int gain_lock[ MAX_NB_SUBFR ] = {0}; opus_int16 best_gain_mult[ MAX_NB_SUBFR ]; opus_int best_sum[ MAX_NB_SUBFR ]; /* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */ LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower = gainMult_upper = 0; psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3; /**************************************************************/ /* Set up Input Pointers, and insert frame in input buffer */ /**************************************************************/ /* pointers aligned with start of frame to encode */ x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length; /* start of frame to encode */ res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length; /* start of pitch LPC residual frame */ /***************************************/ /* Ensure smooth bandwidth transitions */ /***************************************/ silk_LP_variable_cutoff( &psEnc->sCmn.sLP, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length ); /*******************************************/ /* Copy new frame to front of input buffer */ /*******************************************/ silk_short2float_array( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length ); /* Add tiny signal to avoid high CPU load from denormalized floating point numbers */ for( i = 0; i < 8; i++ ) { x_frame[ LA_SHAPE_MS * psEnc->sCmn.fs_kHz + i * ( psEnc->sCmn.frame_length >> 3 ) ] += ( 1 - ( i & 2 ) ) * 1e-6f; } if( !psEnc->sCmn.prefillFlag ) { /*****************************************/ /* Find pitch lags, initial LPC analysis */ /*****************************************/ silk_find_pitch_lags_FLP( psEnc, &sEncCtrl, res_pitch, x_frame, psEnc->sCmn.arch ); /************************/ /* Noise shape analysis */ /************************/ silk_noise_shape_analysis_FLP( psEnc, &sEncCtrl, res_pitch_frame, x_frame ); /***************************************************/ /* Find linear prediction coefficients (LPC + LTP) */ /***************************************************/ silk_find_pred_coefs_FLP( psEnc, &sEncCtrl, res_pitch_frame, x_frame, condCoding ); /****************************************/ /* Process gains */ /****************************************/ silk_process_gains_FLP( psEnc, &sEncCtrl, condCoding ); /****************************************/ /* Low Bitrate Redundant Encoding */ /****************************************/ silk_LBRR_encode_FLP( psEnc, &sEncCtrl, x_frame, condCoding ); /* Loop over quantizer and entroy coding to control bitrate */ maxIter = 6; gainMult_Q8 = SILK_FIX_CONST( 1, 8 ); found_lower = 0; found_upper = 0; gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr ); gainsID_lower = -1; gainsID_upper = -1; /* Copy part of the input state */ silk_memcpy( &sRangeEnc_copy, psRangeEnc, sizeof( ec_enc ) ); silk_memcpy( &sNSQ_copy, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); seed_copy = psEnc->sCmn.indices.Seed; ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex; ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType; for( iter = 0; ; iter++ ) { if( gainsID == gainsID_lower ) { nBits = nBits_lower; } else if( gainsID == gainsID_upper ) { nBits = nBits_upper; } else { /* Restore part of the input state */ if( iter > 0 ) { silk_memcpy( psRangeEnc, &sRangeEnc_copy, sizeof( ec_enc ) ); silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy, sizeof( silk_nsq_state ) ); psEnc->sCmn.indices.Seed = seed_copy; psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy; psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy; } /*****************************************/ /* Noise shaping quantization */ /*****************************************/ silk_NSQ_wrapper_FLP( psEnc, &sEncCtrl, &psEnc->sCmn.indices, &psEnc->sCmn.sNSQ, psEnc->sCmn.pulses, x_frame ); if ( iter == maxIter && !found_lower ) { silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) ); } /****************************************/ /* Encode Parameters */ /****************************************/ silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding ); /****************************************/ /* Encode Excitation Signal */ /****************************************/ silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType, psEnc->sCmn.pulses, psEnc->sCmn.frame_length ); nBits = ec_tell( psRangeEnc ); /* If we still bust after the last iteration, do some damage control. */ if ( iter == maxIter && !found_lower && nBits > maxBits ) { silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) ); /* Keep gains the same as the last frame. */ psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev; for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { psEnc->sCmn.indices.GainsIndices[ i ] = 4; } if (condCoding != CODE_CONDITIONALLY) { psEnc->sCmn.indices.GainsIndices[ 0 ] = sEncCtrl.lastGainIndexPrev; } psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy; psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy; /* Clear all pulses. */ for ( i = 0; i < psEnc->sCmn.frame_length; i++ ) { psEnc->sCmn.pulses[ i ] = 0; } silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding ); silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType, psEnc->sCmn.pulses, psEnc->sCmn.frame_length ); nBits = ec_tell( psRangeEnc ); } if( useCBR == 0 && iter == 0 && nBits <= maxBits ) { break; } } if( iter == maxIter ) { if( found_lower && ( gainsID == gainsID_lower || nBits > maxBits ) ) { /* Restore output state from earlier iteration that did meet the bitrate budget */ silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) ); celt_assert( sRangeEnc_copy2.offs <= 1275 ); silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs ); silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof( silk_nsq_state ) ); psEnc->sShape.LastGainIndex = LastGainIndex_copy2; } break; } if( nBits > maxBits ) { if( found_lower == 0 && iter >= 2 ) { /* Adjust the quantizer's rate/distortion tradeoff and discard previous "upper" results */ sEncCtrl.Lambda = silk_max_float(sEncCtrl.Lambda*1.5f, 1.5f); /* Reducing dithering can help us hit the target. */ psEnc->sCmn.indices.quantOffsetType = 0; found_upper = 0; gainsID_upper = -1; } else { found_upper = 1; nBits_upper = nBits; gainMult_upper = gainMult_Q8; gainsID_upper = gainsID; } } else if( nBits < maxBits - 5 ) { found_lower = 1; nBits_lower = nBits; gainMult_lower = gainMult_Q8; if( gainsID != gainsID_lower ) { gainsID_lower = gainsID; /* Copy part of the output state */ silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) ); celt_assert( psRangeEnc->offs <= 1275 ); silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs ); silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); LastGainIndex_copy2 = psEnc->sShape.LastGainIndex; } } else { /* Within 5 bits of budget: close enough */ break; } if ( !found_lower && nBits > maxBits ) { int j; for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { int sum=0; for ( j = i*psEnc->sCmn.subfr_length; j < (i+1)*psEnc->sCmn.subfr_length; j++ ) { sum += abs( psEnc->sCmn.pulses[j] ); } if ( iter == 0 || (sum < best_sum[i] && !gain_lock[i]) ) { best_sum[i] = sum; best_gain_mult[i] = gainMult_Q8; } else { gain_lock[i] = 1; } } } if( ( found_lower & found_upper ) == 0 ) { /* Adjust gain according to high-rate rate/distortion curve */ if( nBits > maxBits ) { if (gainMult_Q8 < 16384) { gainMult_Q8 *= 2; } else { gainMult_Q8 = 32767; } } else { opus_int32 gain_factor_Q16; gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) ); gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 ); } } else { /* Adjust gain by interpolating */ gainMult_Q8 = gainMult_lower + ( ( gainMult_upper - gainMult_lower ) * ( maxBits - nBits_lower ) ) / ( nBits_upper - nBits_lower ); /* New gain multplier must be between 25% and 75% of old range (note that gainMult_upper < gainMult_lower) */ if( gainMult_Q8 > silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ) ) { gainMult_Q8 = silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ); } else if( gainMult_Q8 < silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ) ) { gainMult_Q8 = silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ); } } for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { opus_int16 tmp; if ( gain_lock[i] ) { tmp = best_gain_mult[i]; } else { tmp = gainMult_Q8; } pGains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], tmp ), 8 ); } /* Quantize gains */ psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev; silk_gains_quant( psEnc->sCmn.indices.GainsIndices, pGains_Q16, &psEnc->sShape.LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); /* Unique identifier of gains vector */ gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr ); /* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */ for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { sEncCtrl.Gains[ i ] = pGains_Q16[ i ] / 65536.0f; } } } /* Update input buffer */ silk_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ], ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( silk_float ) ); /* Exit without entropy coding */ if( psEnc->sCmn.prefillFlag ) { /* No payload */ *pnBytesOut = 0; return ret; } /* Parameters needed for next frame */ psEnc->sCmn.prevLag = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ]; psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType; /****************************************/ /* Finalize payload */ /****************************************/ psEnc->sCmn.first_frame_after_reset = 0; /* Payload size */ *pnBytesOut = silk_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 ); return ret; } /* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate */ static OPUS_INLINE void silk_LBRR_encode_FLP( silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ const silk_float xfw[], /* I Input signal */ opus_int condCoding /* I The type of conditional coding used so far for this frame */ ) { opus_int k; opus_int32 Gains_Q16[ MAX_NB_SUBFR ]; silk_float TempGains[ MAX_NB_SUBFR ]; SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesEncoded ]; silk_nsq_state sNSQ_LBRR; /*******************************************/ /* Control use of inband LBRR */ /*******************************************/ if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SILK_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) { psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded ] = 1; /* Copy noise shaping quantizer state and quantization indices from regular encoding */ silk_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); silk_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) ); /* Save original gains */ silk_memcpy( TempGains, psEncCtrl->Gains, psEnc->sCmn.nb_subfr * sizeof( silk_float ) ); if( psEnc->sCmn.nFramesEncoded == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded - 1 ] == 0 ) { /* First frame in packet or previous frame not LBRR coded */ psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex; /* Increase Gains to get target LBRR rate */ psIndices_LBRR->GainsIndices[ 0 ] += psEnc->sCmn.LBRR_GainIncreases; psIndices_LBRR->GainsIndices[ 0 ] = silk_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 ); } /* Decode to get gains in sync with decoder */ silk_gains_dequant( Gains_Q16, psIndices_LBRR->GainsIndices, &psEnc->sCmn.LBRRprevLastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); /* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */ for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { psEncCtrl->Gains[ k ] = Gains_Q16[ k ] * ( 1.0f / 65536.0f ); } /*****************************************/ /* Noise shaping quantization */ /*****************************************/ silk_NSQ_wrapper_FLP( psEnc, psEncCtrl, psIndices_LBRR, &sNSQ_LBRR, psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], xfw ); /* Restore original gains */ silk_memcpy( psEncCtrl->Gains, TempGains, psEnc->sCmn.nb_subfr * sizeof( silk_float ) ); } } jamulus-3.9.1+dfsg/libs/opus/silk/float/energy_FLP.c0000644000175000017500000000457714340334543021315 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FLP.h" /* sum of squares of a silk_float array, with result as double */ double silk_energy_FLP( const silk_float *data, opus_int dataSize ) { opus_int i; double result; /* 4x unrolled loop */ result = 0.0; for( i = 0; i < dataSize - 3; i += 4 ) { result += data[ i + 0 ] * (double)data[ i + 0 ] + data[ i + 1 ] * (double)data[ i + 1 ] + data[ i + 2 ] * (double)data[ i + 2 ] + data[ i + 3 ] * (double)data[ i + 3 ]; } /* add any remaining products */ for( ; i < dataSize; i++ ) { result += data[ i ] * (double)data[ i ]; } silk_assert( result >= 0.0 ); return result; } jamulus-3.9.1+dfsg/libs/opus/silk/resampler_private_up2_HQ.c0000644000175000017500000001236714340334543023114 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FIX.h" #include "resampler_private.h" /* Upsample by a factor 2, high quality */ /* Uses 2nd order allpass filters for the 2x upsampling, followed by a */ /* notch filter just above Nyquist. */ void silk_resampler_private_up2_HQ( opus_int32 *S, /* I/O Resampler state [ 6 ] */ opus_int16 *out, /* O Output signal [ 2 * len ] */ const opus_int16 *in, /* I Input signal [ len ] */ opus_int32 len /* I Number of input samples */ ) { opus_int32 k; opus_int32 in32, out32_1, out32_2, Y, X; silk_assert( silk_resampler_up2_hq_0[ 0 ] > 0 ); silk_assert( silk_resampler_up2_hq_0[ 1 ] > 0 ); silk_assert( silk_resampler_up2_hq_0[ 2 ] < 0 ); silk_assert( silk_resampler_up2_hq_1[ 0 ] > 0 ); silk_assert( silk_resampler_up2_hq_1[ 1 ] > 0 ); silk_assert( silk_resampler_up2_hq_1[ 2 ] < 0 ); /* Internal variables and state are in Q10 format */ for( k = 0; k < len; k++ ) { /* Convert to Q10 */ in32 = silk_LSHIFT( (opus_int32)in[ k ], 10 ); /* First all-pass section for even output sample */ Y = silk_SUB32( in32, S[ 0 ] ); X = silk_SMULWB( Y, silk_resampler_up2_hq_0[ 0 ] ); out32_1 = silk_ADD32( S[ 0 ], X ); S[ 0 ] = silk_ADD32( in32, X ); /* Second all-pass section for even output sample */ Y = silk_SUB32( out32_1, S[ 1 ] ); X = silk_SMULWB( Y, silk_resampler_up2_hq_0[ 1 ] ); out32_2 = silk_ADD32( S[ 1 ], X ); S[ 1 ] = silk_ADD32( out32_1, X ); /* Third all-pass section for even output sample */ Y = silk_SUB32( out32_2, S[ 2 ] ); X = silk_SMLAWB( Y, Y, silk_resampler_up2_hq_0[ 2 ] ); out32_1 = silk_ADD32( S[ 2 ], X ); S[ 2 ] = silk_ADD32( out32_2, X ); /* Apply gain in Q15, convert back to int16 and store to output */ out[ 2 * k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( out32_1, 10 ) ); /* First all-pass section for odd output sample */ Y = silk_SUB32( in32, S[ 3 ] ); X = silk_SMULWB( Y, silk_resampler_up2_hq_1[ 0 ] ); out32_1 = silk_ADD32( S[ 3 ], X ); S[ 3 ] = silk_ADD32( in32, X ); /* Second all-pass section for odd output sample */ Y = silk_SUB32( out32_1, S[ 4 ] ); X = silk_SMULWB( Y, silk_resampler_up2_hq_1[ 1 ] ); out32_2 = silk_ADD32( S[ 4 ], X ); S[ 4 ] = silk_ADD32( out32_1, X ); /* Third all-pass section for odd output sample */ Y = silk_SUB32( out32_2, S[ 5 ] ); X = silk_SMLAWB( Y, Y, silk_resampler_up2_hq_1[ 2 ] ); out32_1 = silk_ADD32( S[ 5 ], X ); S[ 5 ] = silk_ADD32( out32_2, X ); /* Apply gain in Q15, convert back to int16 and store to output */ out[ 2 * k + 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( out32_1, 10 ) ); } } void silk_resampler_private_up2_HQ_wrapper( void *SS, /* I/O Resampler state (unused) */ opus_int16 *out, /* O Output signal [ 2 * len ] */ const opus_int16 *in, /* I Input signal [ len ] */ opus_int32 len /* I Number of input samples */ ) { silk_resampler_state_struct *S = (silk_resampler_state_struct *)SS; silk_resampler_private_up2_HQ( S->sIIR, out, in, len ); } jamulus-3.9.1+dfsg/libs/opus/silk/VAD.c0000644000175000017500000003523714340334543016625 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" #include "stack_alloc.h" /* Silk VAD noise level estimation */ # if !defined(OPUS_X86_MAY_HAVE_SSE4_1) static OPUS_INLINE void silk_VAD_GetNoiseLevels( const opus_int32 pX[ VAD_N_BANDS ], /* I subband energies */ silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */ ); #endif /**********************************/ /* Initialization of the Silk VAD */ /**********************************/ opus_int silk_VAD_Init( /* O Return value, 0 if success */ silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */ ) { opus_int b, ret = 0; /* reset state memory */ silk_memset( psSilk_VAD, 0, sizeof( silk_VAD_state ) ); /* init noise levels */ /* Initialize array with approx pink noise levels (psd proportional to inverse of frequency) */ for( b = 0; b < VAD_N_BANDS; b++ ) { psSilk_VAD->NoiseLevelBias[ b ] = silk_max_32( silk_DIV32_16( VAD_NOISE_LEVELS_BIAS, b + 1 ), 1 ); } /* Initialize state */ for( b = 0; b < VAD_N_BANDS; b++ ) { psSilk_VAD->NL[ b ] = silk_MUL( 100, psSilk_VAD->NoiseLevelBias[ b ] ); psSilk_VAD->inv_NL[ b ] = silk_DIV32( silk_int32_MAX, psSilk_VAD->NL[ b ] ); } psSilk_VAD->counter = 15; /* init smoothed energy-to-noise ratio*/ for( b = 0; b < VAD_N_BANDS; b++ ) { psSilk_VAD->NrgRatioSmth_Q8[ b ] = 100 * 256; /* 100 * 256 --> 20 dB SNR */ } return( ret ); } /* Weighting factors for tilt measure */ static const opus_int32 tiltWeights[ VAD_N_BANDS ] = { 30000, 6000, -12000, -12000 }; /***************************************/ /* Get the speech activity level in Q8 */ /***************************************/ opus_int silk_VAD_GetSA_Q8_c( /* O Return value, 0 if success */ silk_encoder_state *psEncC, /* I/O Encoder state */ const opus_int16 pIn[] /* I PCM input */ ) { opus_int SA_Q15, pSNR_dB_Q7, input_tilt; opus_int decimated_framelength1, decimated_framelength2; opus_int decimated_framelength; opus_int dec_subframe_length, dec_subframe_offset, SNR_Q7, i, b, s; opus_int32 sumSquared, smooth_coef_Q16; opus_int16 HPstateTmp; VARDECL( opus_int16, X ); opus_int32 Xnrg[ VAD_N_BANDS ]; opus_int32 NrgToNoiseRatio_Q8[ VAD_N_BANDS ]; opus_int32 speech_nrg, x_tmp; opus_int X_offset[ VAD_N_BANDS ]; opus_int ret = 0; silk_VAD_state *psSilk_VAD = &psEncC->sVAD; SAVE_STACK; /* Safety checks */ silk_assert( VAD_N_BANDS == 4 ); celt_assert( MAX_FRAME_LENGTH >= psEncC->frame_length ); celt_assert( psEncC->frame_length <= 512 ); celt_assert( psEncC->frame_length == 8 * silk_RSHIFT( psEncC->frame_length, 3 ) ); /***********************/ /* Filter and Decimate */ /***********************/ decimated_framelength1 = silk_RSHIFT( psEncC->frame_length, 1 ); decimated_framelength2 = silk_RSHIFT( psEncC->frame_length, 2 ); decimated_framelength = silk_RSHIFT( psEncC->frame_length, 3 ); /* Decimate into 4 bands: 0 L 3L L 3L 5L - -- - -- -- 8 8 2 4 4 [0-1 kHz| temp. |1-2 kHz| 2-4 kHz | 4-8 kHz | They're arranged to allow the minimal ( frame_length / 4 ) extra scratch space during the downsampling process */ X_offset[ 0 ] = 0; X_offset[ 1 ] = decimated_framelength + decimated_framelength2; X_offset[ 2 ] = X_offset[ 1 ] + decimated_framelength; X_offset[ 3 ] = X_offset[ 2 ] + decimated_framelength2; ALLOC( X, X_offset[ 3 ] + decimated_framelength1, opus_int16 ); /* 0-8 kHz to 0-4 kHz and 4-8 kHz */ silk_ana_filt_bank_1( pIn, &psSilk_VAD->AnaState[ 0 ], X, &X[ X_offset[ 3 ] ], psEncC->frame_length ); /* 0-4 kHz to 0-2 kHz and 2-4 kHz */ silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState1[ 0 ], X, &X[ X_offset[ 2 ] ], decimated_framelength1 ); /* 0-2 kHz to 0-1 kHz and 1-2 kHz */ silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState2[ 0 ], X, &X[ X_offset[ 1 ] ], decimated_framelength2 ); /*********************************************/ /* HP filter on lowest band (differentiator) */ /*********************************************/ X[ decimated_framelength - 1 ] = silk_RSHIFT( X[ decimated_framelength - 1 ], 1 ); HPstateTmp = X[ decimated_framelength - 1 ]; for( i = decimated_framelength - 1; i > 0; i-- ) { X[ i - 1 ] = silk_RSHIFT( X[ i - 1 ], 1 ); X[ i ] -= X[ i - 1 ]; } X[ 0 ] -= psSilk_VAD->HPstate; psSilk_VAD->HPstate = HPstateTmp; /*************************************/ /* Calculate the energy in each band */ /*************************************/ for( b = 0; b < VAD_N_BANDS; b++ ) { /* Find the decimated framelength in the non-uniformly divided bands */ decimated_framelength = silk_RSHIFT( psEncC->frame_length, silk_min_int( VAD_N_BANDS - b, VAD_N_BANDS - 1 ) ); /* Split length into subframe lengths */ dec_subframe_length = silk_RSHIFT( decimated_framelength, VAD_INTERNAL_SUBFRAMES_LOG2 ); dec_subframe_offset = 0; /* Compute energy per sub-frame */ /* initialize with summed energy of last subframe */ Xnrg[ b ] = psSilk_VAD->XnrgSubfr[ b ]; for( s = 0; s < VAD_INTERNAL_SUBFRAMES; s++ ) { sumSquared = 0; for( i = 0; i < dec_subframe_length; i++ ) { /* The energy will be less than dec_subframe_length * ( silk_int16_MIN / 8 ) ^ 2. */ /* Therefore we can accumulate with no risk of overflow (unless dec_subframe_length > 128) */ x_tmp = silk_RSHIFT( X[ X_offset[ b ] + i + dec_subframe_offset ], 3 ); sumSquared = silk_SMLABB( sumSquared, x_tmp, x_tmp ); /* Safety check */ silk_assert( sumSquared >= 0 ); } /* Add/saturate summed energy of current subframe */ if( s < VAD_INTERNAL_SUBFRAMES - 1 ) { Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], sumSquared ); } else { /* Look-ahead subframe */ Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], silk_RSHIFT( sumSquared, 1 ) ); } dec_subframe_offset += dec_subframe_length; } psSilk_VAD->XnrgSubfr[ b ] = sumSquared; } /********************/ /* Noise estimation */ /********************/ silk_VAD_GetNoiseLevels( &Xnrg[ 0 ], psSilk_VAD ); /***********************************************/ /* Signal-plus-noise to noise ratio estimation */ /***********************************************/ sumSquared = 0; input_tilt = 0; for( b = 0; b < VAD_N_BANDS; b++ ) { speech_nrg = Xnrg[ b ] - psSilk_VAD->NL[ b ]; if( speech_nrg > 0 ) { /* Divide, with sufficient resolution */ if( ( Xnrg[ b ] & 0xFF800000 ) == 0 ) { NrgToNoiseRatio_Q8[ b ] = silk_DIV32( silk_LSHIFT( Xnrg[ b ], 8 ), psSilk_VAD->NL[ b ] + 1 ); } else { NrgToNoiseRatio_Q8[ b ] = silk_DIV32( Xnrg[ b ], silk_RSHIFT( psSilk_VAD->NL[ b ], 8 ) + 1 ); } /* Convert to log domain */ SNR_Q7 = silk_lin2log( NrgToNoiseRatio_Q8[ b ] ) - 8 * 128; /* Sum-of-squares */ sumSquared = silk_SMLABB( sumSquared, SNR_Q7, SNR_Q7 ); /* Q14 */ /* Tilt measure */ if( speech_nrg < ( (opus_int32)1 << 20 ) ) { /* Scale down SNR value for small subband speech energies */ SNR_Q7 = silk_SMULWB( silk_LSHIFT( silk_SQRT_APPROX( speech_nrg ), 6 ), SNR_Q7 ); } input_tilt = silk_SMLAWB( input_tilt, tiltWeights[ b ], SNR_Q7 ); } else { NrgToNoiseRatio_Q8[ b ] = 256; } } /* Mean-of-squares */ sumSquared = silk_DIV32_16( sumSquared, VAD_N_BANDS ); /* Q14 */ /* Root-mean-square approximation, scale to dBs, and write to output pointer */ pSNR_dB_Q7 = (opus_int16)( 3 * silk_SQRT_APPROX( sumSquared ) ); /* Q7 */ /*********************************/ /* Speech Probability Estimation */ /*********************************/ SA_Q15 = silk_sigm_Q15( silk_SMULWB( VAD_SNR_FACTOR_Q16, pSNR_dB_Q7 ) - VAD_NEGATIVE_OFFSET_Q5 ); /**************************/ /* Frequency Tilt Measure */ /**************************/ psEncC->input_tilt_Q15 = silk_LSHIFT( silk_sigm_Q15( input_tilt ) - 16384, 1 ); /**************************************************/ /* Scale the sigmoid output based on power levels */ /**************************************************/ speech_nrg = 0; for( b = 0; b < VAD_N_BANDS; b++ ) { /* Accumulate signal-without-noise energies, higher frequency bands have more weight */ speech_nrg += ( b + 1 ) * silk_RSHIFT( Xnrg[ b ] - psSilk_VAD->NL[ b ], 4 ); } if( psEncC->frame_length == 20 * psEncC->fs_kHz ) { speech_nrg = silk_RSHIFT32( speech_nrg, 1 ); } /* Power scaling */ if( speech_nrg <= 0 ) { SA_Q15 = silk_RSHIFT( SA_Q15, 1 ); } else if( speech_nrg < 16384 ) { speech_nrg = silk_LSHIFT32( speech_nrg, 16 ); /* square-root */ speech_nrg = silk_SQRT_APPROX( speech_nrg ); SA_Q15 = silk_SMULWB( 32768 + speech_nrg, SA_Q15 ); } /* Copy the resulting speech activity in Q8 */ psEncC->speech_activity_Q8 = silk_min_int( silk_RSHIFT( SA_Q15, 7 ), silk_uint8_MAX ); /***********************************/ /* Energy Level and SNR estimation */ /***********************************/ /* Smoothing coefficient */ smooth_coef_Q16 = silk_SMULWB( VAD_SNR_SMOOTH_COEF_Q18, silk_SMULWB( (opus_int32)SA_Q15, SA_Q15 ) ); if( psEncC->frame_length == 10 * psEncC->fs_kHz ) { smooth_coef_Q16 >>= 1; } for( b = 0; b < VAD_N_BANDS; b++ ) { /* compute smoothed energy-to-noise ratio per band */ psSilk_VAD->NrgRatioSmth_Q8[ b ] = silk_SMLAWB( psSilk_VAD->NrgRatioSmth_Q8[ b ], NrgToNoiseRatio_Q8[ b ] - psSilk_VAD->NrgRatioSmth_Q8[ b ], smooth_coef_Q16 ); /* signal to noise ratio in dB per band */ SNR_Q7 = 3 * ( silk_lin2log( psSilk_VAD->NrgRatioSmth_Q8[b] ) - 8 * 128 ); /* quality = sigmoid( 0.25 * ( SNR_dB - 16 ) ); */ psEncC->input_quality_bands_Q15[ b ] = silk_sigm_Q15( silk_RSHIFT( SNR_Q7 - 16 * 128, 4 ) ); } RESTORE_STACK; return( ret ); } /**************************/ /* Noise level estimation */ /**************************/ # if !defined(OPUS_X86_MAY_HAVE_SSE4_1) static OPUS_INLINE #endif void silk_VAD_GetNoiseLevels( const opus_int32 pX[ VAD_N_BANDS ], /* I subband energies */ silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */ ) { opus_int k; opus_int32 nl, nrg, inv_nrg; opus_int coef, min_coef; /* Initially faster smoothing */ if( psSilk_VAD->counter < 1000 ) { /* 1000 = 20 sec */ min_coef = silk_DIV32_16( silk_int16_MAX, silk_RSHIFT( psSilk_VAD->counter, 4 ) + 1 ); /* Increment frame counter */ psSilk_VAD->counter++; } else { min_coef = 0; } for( k = 0; k < VAD_N_BANDS; k++ ) { /* Get old noise level estimate for current band */ nl = psSilk_VAD->NL[ k ]; silk_assert( nl >= 0 ); /* Add bias */ nrg = silk_ADD_POS_SAT32( pX[ k ], psSilk_VAD->NoiseLevelBias[ k ] ); silk_assert( nrg > 0 ); /* Invert energies */ inv_nrg = silk_DIV32( silk_int32_MAX, nrg ); silk_assert( inv_nrg >= 0 ); /* Less update when subband energy is high */ if( nrg > silk_LSHIFT( nl, 3 ) ) { coef = VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 >> 3; } else if( nrg < nl ) { coef = VAD_NOISE_LEVEL_SMOOTH_COEF_Q16; } else { coef = silk_SMULWB( silk_SMULWW( inv_nrg, nl ), VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 << 1 ); } /* Initially faster smoothing */ coef = silk_max_int( coef, min_coef ); /* Smooth inverse energies */ psSilk_VAD->inv_NL[ k ] = silk_SMLAWB( psSilk_VAD->inv_NL[ k ], inv_nrg - psSilk_VAD->inv_NL[ k ], coef ); silk_assert( psSilk_VAD->inv_NL[ k ] >= 0 ); /* Compute noise level by inverting again */ nl = silk_DIV32( silk_int32_MAX, psSilk_VAD->inv_NL[ k ] ); silk_assert( nl >= 0 ); /* Limit noise levels (guarantee 7 bits of head room) */ nl = silk_min( nl, 0x00FFFFFF ); /* Store as part of state */ psSilk_VAD->NL[ k ] = nl; } } jamulus-3.9.1+dfsg/libs/opus/silk/fixed/0000755000175000017500000000000014340334543017134 5ustar vimervimerjamulus-3.9.1+dfsg/libs/opus/silk/fixed/noise_shape_analysis_FIX.c0000644000175000017500000005027714340334543024221 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main_FIX.h" #include "stack_alloc.h" #include "tuning_parameters.h" /* Compute gain to make warped filter coefficients have a zero mean log frequency response on a */ /* non-warped frequency scale. (So that it can be implemented with a minimum-phase monic filter.) */ /* Note: A monic filter is one with the first coefficient equal to 1.0. In Silk we omit the first */ /* coefficient in an array of coefficients, for monic filters. */ static OPUS_INLINE opus_int32 warped_gain( /* gain in Q16*/ const opus_int32 *coefs_Q24, opus_int lambda_Q16, opus_int order ) { opus_int i; opus_int32 gain_Q24; lambda_Q16 = -lambda_Q16; gain_Q24 = coefs_Q24[ order - 1 ]; for( i = order - 2; i >= 0; i-- ) { gain_Q24 = silk_SMLAWB( coefs_Q24[ i ], gain_Q24, lambda_Q16 ); } gain_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), gain_Q24, -lambda_Q16 ); return silk_INVERSE32_varQ( gain_Q24, 40 ); } /* Convert warped filter coefficients to monic pseudo-warped coefficients and limit maximum */ /* amplitude of monic warped coefficients by using bandwidth expansion on the true coefficients */ static OPUS_INLINE void limit_warped_coefs( opus_int32 *coefs_Q24, opus_int lambda_Q16, opus_int32 limit_Q24, opus_int order ) { opus_int i, iter, ind = 0; opus_int32 tmp, maxabs_Q24, chirp_Q16, gain_Q16; opus_int32 nom_Q16, den_Q24; opus_int32 limit_Q20, maxabs_Q20; /* Convert to monic coefficients */ lambda_Q16 = -lambda_Q16; for( i = order - 1; i > 0; i-- ) { coefs_Q24[ i - 1 ] = silk_SMLAWB( coefs_Q24[ i - 1 ], coefs_Q24[ i ], lambda_Q16 ); } lambda_Q16 = -lambda_Q16; nom_Q16 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -(opus_int32)lambda_Q16, lambda_Q16 ); den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_Q24[ 0 ], lambda_Q16 ); gain_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 ); for( i = 0; i < order; i++ ) { coefs_Q24[ i ] = silk_SMULWW( gain_Q16, coefs_Q24[ i ] ); } limit_Q20 = silk_RSHIFT(limit_Q24, 4); for( iter = 0; iter < 10; iter++ ) { /* Find maximum absolute value */ maxabs_Q24 = -1; for( i = 0; i < order; i++ ) { tmp = silk_abs_int32( coefs_Q24[ i ] ); if( tmp > maxabs_Q24 ) { maxabs_Q24 = tmp; ind = i; } } /* Use Q20 to avoid any overflow when multiplying by (ind + 1) later. */ maxabs_Q20 = silk_RSHIFT(maxabs_Q24, 4); if( maxabs_Q20 <= limit_Q20 ) { /* Coefficients are within range - done */ return; } /* Convert back to true warped coefficients */ for( i = 1; i < order; i++ ) { coefs_Q24[ i - 1 ] = silk_SMLAWB( coefs_Q24[ i - 1 ], coefs_Q24[ i ], lambda_Q16 ); } gain_Q16 = silk_INVERSE32_varQ( gain_Q16, 32 ); for( i = 0; i < order; i++ ) { coefs_Q24[ i ] = silk_SMULWW( gain_Q16, coefs_Q24[ i ] ); } /* Apply bandwidth expansion */ chirp_Q16 = SILK_FIX_CONST( 0.99, 16 ) - silk_DIV32_varQ( silk_SMULWB( maxabs_Q20 - limit_Q20, silk_SMLABB( SILK_FIX_CONST( 0.8, 10 ), SILK_FIX_CONST( 0.1, 10 ), iter ) ), silk_MUL( maxabs_Q20, ind + 1 ), 22 ); silk_bwexpander_32( coefs_Q24, order, chirp_Q16 ); /* Convert to monic warped coefficients */ lambda_Q16 = -lambda_Q16; for( i = order - 1; i > 0; i-- ) { coefs_Q24[ i - 1 ] = silk_SMLAWB( coefs_Q24[ i - 1 ], coefs_Q24[ i ], lambda_Q16 ); } lambda_Q16 = -lambda_Q16; nom_Q16 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -(opus_int32)lambda_Q16, lambda_Q16 ); den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_Q24[ 0 ], lambda_Q16 ); gain_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 ); for( i = 0; i < order; i++ ) { coefs_Q24[ i ] = silk_SMULWW( gain_Q16, coefs_Q24[ i ] ); } } silk_assert( 0 ); } /* Disable MIPS version until it's updated. */ #if 0 && defined(MIPSr1_ASM) #include "mips/noise_shape_analysis_FIX_mipsr1.h" #endif /**************************************************************/ /* Compute noise shaping coefficients and initial gain values */ /**************************************************************/ #ifndef OVERRIDE_silk_noise_shape_analysis_FIX void silk_noise_shape_analysis_FIX( silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */ silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */ const opus_int16 *pitch_res, /* I LPC residual from pitch analysis */ const opus_int16 *x, /* I Input signal [ frame_length + la_shape ] */ int arch /* I Run-time architecture */ ) { silk_shape_state_FIX *psShapeSt = &psEnc->sShape; opus_int k, i, nSamples, nSegs, Qnrg, b_Q14, warping_Q16, scale = 0; opus_int32 SNR_adj_dB_Q7, HarmShapeGain_Q16, Tilt_Q16, tmp32; opus_int32 nrg, log_energy_Q7, log_energy_prev_Q7, energy_variation_Q7; opus_int32 BWExp_Q16, gain_mult_Q16, gain_add_Q16, strength_Q16, b_Q8; opus_int32 auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ]; opus_int32 refl_coef_Q16[ MAX_SHAPE_LPC_ORDER ]; opus_int32 AR_Q24[ MAX_SHAPE_LPC_ORDER ]; VARDECL( opus_int16, x_windowed ); const opus_int16 *x_ptr, *pitch_res_ptr; SAVE_STACK; /* Point to start of first LPC analysis block */ x_ptr = x - psEnc->sCmn.la_shape; /****************/ /* GAIN CONTROL */ /****************/ SNR_adj_dB_Q7 = psEnc->sCmn.SNR_dB_Q7; /* Input quality is the average of the quality in the lowest two VAD bands */ psEncCtrl->input_quality_Q14 = ( opus_int )silk_RSHIFT( (opus_int32)psEnc->sCmn.input_quality_bands_Q15[ 0 ] + psEnc->sCmn.input_quality_bands_Q15[ 1 ], 2 ); /* Coding quality level, between 0.0_Q0 and 1.0_Q0, but in Q14 */ psEncCtrl->coding_quality_Q14 = silk_RSHIFT( silk_sigm_Q15( silk_RSHIFT_ROUND( SNR_adj_dB_Q7 - SILK_FIX_CONST( 20.0, 7 ), 4 ) ), 1 ); /* Reduce coding SNR during low speech activity */ if( psEnc->sCmn.useCBR == 0 ) { b_Q8 = SILK_FIX_CONST( 1.0, 8 ) - psEnc->sCmn.speech_activity_Q8; b_Q8 = silk_SMULWB( silk_LSHIFT( b_Q8, 8 ), b_Q8 ); SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, silk_SMULBB( SILK_FIX_CONST( -BG_SNR_DECR_dB, 7 ) >> ( 4 + 1 ), b_Q8 ), /* Q11*/ silk_SMULWB( SILK_FIX_CONST( 1.0, 14 ) + psEncCtrl->input_quality_Q14, psEncCtrl->coding_quality_Q14 ) ); /* Q12*/ } if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { /* Reduce gains for periodic signals */ SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( HARM_SNR_INCR_dB, 8 ), psEnc->LTPCorr_Q15 ); } else { /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */ SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, silk_SMLAWB( SILK_FIX_CONST( 6.0, 9 ), -SILK_FIX_CONST( 0.4, 18 ), psEnc->sCmn.SNR_dB_Q7 ), SILK_FIX_CONST( 1.0, 14 ) - psEncCtrl->input_quality_Q14 ); } /*************************/ /* SPARSENESS PROCESSING */ /*************************/ /* Set quantizer offset */ if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { /* Initially set to 0; may be overruled in process_gains(..) */ psEnc->sCmn.indices.quantOffsetType = 0; } else { /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */ nSamples = silk_LSHIFT( psEnc->sCmn.fs_kHz, 1 ); energy_variation_Q7 = 0; log_energy_prev_Q7 = 0; pitch_res_ptr = pitch_res; nSegs = silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2; for( k = 0; k < nSegs; k++ ) { silk_sum_sqr_shift( &nrg, &scale, pitch_res_ptr, nSamples ); nrg += silk_RSHIFT( nSamples, scale ); /* Q(-scale)*/ log_energy_Q7 = silk_lin2log( nrg ); if( k > 0 ) { energy_variation_Q7 += silk_abs( log_energy_Q7 - log_energy_prev_Q7 ); } log_energy_prev_Q7 = log_energy_Q7; pitch_res_ptr += nSamples; } /* Set quantization offset depending on sparseness measure */ if( energy_variation_Q7 > SILK_FIX_CONST( ENERGY_VARIATION_THRESHOLD_QNT_OFFSET, 7 ) * (nSegs-1) ) { psEnc->sCmn.indices.quantOffsetType = 0; } else { psEnc->sCmn.indices.quantOffsetType = 1; } } /*******************************/ /* Control bandwidth expansion */ /*******************************/ /* More BWE for signals with high prediction gain */ strength_Q16 = silk_SMULWB( psEncCtrl->predGain_Q16, SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) ); BWExp_Q16 = silk_DIV32_varQ( SILK_FIX_CONST( BANDWIDTH_EXPANSION, 16 ), silk_SMLAWW( SILK_FIX_CONST( 1.0, 16 ), strength_Q16, strength_Q16 ), 16 ); if( psEnc->sCmn.warping_Q16 > 0 ) { /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */ warping_Q16 = silk_SMLAWB( psEnc->sCmn.warping_Q16, (opus_int32)psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( 0.01, 18 ) ); } else { warping_Q16 = 0; } /********************************************/ /* Compute noise shaping AR coefs and gains */ /********************************************/ ALLOC( x_windowed, psEnc->sCmn.shapeWinLength, opus_int16 ); for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { /* Apply window: sine slope followed by flat part followed by cosine slope */ opus_int shift, slope_part, flat_part; flat_part = psEnc->sCmn.fs_kHz * 3; slope_part = silk_RSHIFT( psEnc->sCmn.shapeWinLength - flat_part, 1 ); silk_apply_sine_window( x_windowed, x_ptr, 1, slope_part ); shift = slope_part; silk_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(opus_int16) ); shift += flat_part; silk_apply_sine_window( x_windowed + shift, x_ptr + shift, 2, slope_part ); /* Update pointer: next LPC analysis block */ x_ptr += psEnc->sCmn.subfr_length; if( psEnc->sCmn.warping_Q16 > 0 ) { /* Calculate warped auto correlation */ silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder, arch ); } else { /* Calculate regular auto correlation */ silk_autocorr( auto_corr, &scale, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1, arch ); } /* Add white noise, as a fraction of energy */ auto_corr[0] = silk_ADD32( auto_corr[0], silk_max_32( silk_SMULWB( silk_RSHIFT( auto_corr[ 0 ], 4 ), SILK_FIX_CONST( SHAPE_WHITE_NOISE_FRACTION, 20 ) ), 1 ) ); /* Calculate the reflection coefficients using schur */ nrg = silk_schur64( refl_coef_Q16, auto_corr, psEnc->sCmn.shapingLPCOrder ); silk_assert( nrg >= 0 ); /* Convert reflection coefficients to prediction coefficients */ silk_k2a_Q16( AR_Q24, refl_coef_Q16, psEnc->sCmn.shapingLPCOrder ); Qnrg = -scale; /* range: -12...30*/ silk_assert( Qnrg >= -12 ); silk_assert( Qnrg <= 30 ); /* Make sure that Qnrg is an even number */ if( Qnrg & 1 ) { Qnrg -= 1; nrg >>= 1; } tmp32 = silk_SQRT_APPROX( nrg ); Qnrg >>= 1; /* range: -6...15*/ psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT_SAT32( tmp32, 16 - Qnrg ); if( psEnc->sCmn.warping_Q16 > 0 ) { /* Adjust gain for warping */ gain_mult_Q16 = warped_gain( AR_Q24, warping_Q16, psEnc->sCmn.shapingLPCOrder ); silk_assert( psEncCtrl->Gains_Q16[ k ] > 0 ); if( psEncCtrl->Gains_Q16[ k ] < SILK_FIX_CONST( 0.25, 16 ) ) { psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 ); } else { psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( silk_RSHIFT_ROUND( psEncCtrl->Gains_Q16[ k ], 1 ), gain_mult_Q16 ); if ( psEncCtrl->Gains_Q16[ k ] >= ( silk_int32_MAX >> 1 ) ) { psEncCtrl->Gains_Q16[ k ] = silk_int32_MAX; } else { psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT32( psEncCtrl->Gains_Q16[ k ], 1 ); } } silk_assert( psEncCtrl->Gains_Q16[ k ] > 0 ); } /* Bandwidth expansion */ silk_bwexpander_32( AR_Q24, psEnc->sCmn.shapingLPCOrder, BWExp_Q16 ); if( psEnc->sCmn.warping_Q16 > 0 ) { /* Convert to monic warped prediction coefficients and limit absolute values */ limit_warped_coefs( AR_Q24, warping_Q16, SILK_FIX_CONST( 3.999, 24 ), psEnc->sCmn.shapingLPCOrder ); /* Convert from Q24 to Q13 and store in int16 */ for( i = 0; i < psEnc->sCmn.shapingLPCOrder; i++ ) { psEncCtrl->AR_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR_Q24[ i ], 11 ) ); } } else { silk_LPC_fit( &psEncCtrl->AR_Q13[ k * MAX_SHAPE_LPC_ORDER ], AR_Q24, 13, 24, psEnc->sCmn.shapingLPCOrder ); } } /*****************/ /* Gain tweaking */ /*****************/ /* Increase gains during low speech activity and put lower limit on gains */ gain_mult_Q16 = silk_log2lin( -silk_SMLAWB( -SILK_FIX_CONST( 16.0, 7 ), SNR_adj_dB_Q7, SILK_FIX_CONST( 0.16, 16 ) ) ); gain_add_Q16 = silk_log2lin( silk_SMLAWB( SILK_FIX_CONST( 16.0, 7 ), SILK_FIX_CONST( MIN_QGAIN_DB, 7 ), SILK_FIX_CONST( 0.16, 16 ) ) ); silk_assert( gain_mult_Q16 > 0 ); for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 ); silk_assert( psEncCtrl->Gains_Q16[ k ] >= 0 ); psEncCtrl->Gains_Q16[ k ] = silk_ADD_POS_SAT32( psEncCtrl->Gains_Q16[ k ], gain_add_Q16 ); } /************************************************/ /* Control low-frequency shaping and noise tilt */ /************************************************/ /* Less low frequency shaping for noisy inputs */ strength_Q16 = silk_MUL( SILK_FIX_CONST( LOW_FREQ_SHAPING, 4 ), silk_SMLAWB( SILK_FIX_CONST( 1.0, 12 ), SILK_FIX_CONST( LOW_QUALITY_LOW_FREQ_SHAPING_DECR, 13 ), psEnc->sCmn.input_quality_bands_Q15[ 0 ] - SILK_FIX_CONST( 1.0, 15 ) ) ); strength_Q16 = silk_RSHIFT( silk_MUL( strength_Q16, psEnc->sCmn.speech_activity_Q8 ), 8 ); if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { /* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */ /*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/ opus_int fs_kHz_inv = silk_DIV32_16( SILK_FIX_CONST( 0.2, 14 ), psEnc->sCmn.fs_kHz ); for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { b_Q14 = fs_kHz_inv + silk_DIV32_16( SILK_FIX_CONST( 3.0, 14 ), psEncCtrl->pitchL[ k ] ); /* Pack two coefficients in one int32 */ psEncCtrl->LF_shp_Q14[ k ] = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 - silk_SMULWB( strength_Q16, b_Q14 ), 16 ); psEncCtrl->LF_shp_Q14[ k ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) ); } silk_assert( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ) < SILK_FIX_CONST( 0.5, 24 ) ); /* Guarantees that second argument to SMULWB() is within range of an opus_int16*/ Tilt_Q16 = - SILK_FIX_CONST( HP_NOISE_COEF, 16 ) - silk_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - SILK_FIX_CONST( HP_NOISE_COEF, 16 ), silk_SMULWB( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ), psEnc->sCmn.speech_activity_Q8 ) ); } else { b_Q14 = silk_DIV32_16( 21299, psEnc->sCmn.fs_kHz ); /* 1.3_Q0 = 21299_Q14*/ /* Pack two coefficients in one int32 */ psEncCtrl->LF_shp_Q14[ 0 ] = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 - silk_SMULWB( strength_Q16, silk_SMULWB( SILK_FIX_CONST( 0.6, 16 ), b_Q14 ) ), 16 ); psEncCtrl->LF_shp_Q14[ 0 ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) ); for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) { psEncCtrl->LF_shp_Q14[ k ] = psEncCtrl->LF_shp_Q14[ 0 ]; } Tilt_Q16 = -SILK_FIX_CONST( HP_NOISE_COEF, 16 ); } /****************************/ /* HARMONIC SHAPING CONTROL */ /****************************/ if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) { /* More harmonic noise shaping for high bitrates or noisy input */ HarmShapeGain_Q16 = silk_SMLAWB( SILK_FIX_CONST( HARMONIC_SHAPING, 16 ), SILK_FIX_CONST( 1.0, 16 ) - silk_SMULWB( SILK_FIX_CONST( 1.0, 18 ) - silk_LSHIFT( psEncCtrl->coding_quality_Q14, 4 ), psEncCtrl->input_quality_Q14 ), SILK_FIX_CONST( HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING, 16 ) ); /* Less harmonic noise shaping for less periodic signals */ HarmShapeGain_Q16 = silk_SMULWB( silk_LSHIFT( HarmShapeGain_Q16, 1 ), silk_SQRT_APPROX( silk_LSHIFT( psEnc->LTPCorr_Q15, 15 ) ) ); } else { HarmShapeGain_Q16 = 0; } /*************************/ /* Smooth over subframes */ /*************************/ for( k = 0; k < MAX_NB_SUBFR; k++ ) { psShapeSt->HarmShapeGain_smth_Q16 = silk_SMLAWB( psShapeSt->HarmShapeGain_smth_Q16, HarmShapeGain_Q16 - psShapeSt->HarmShapeGain_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) ); psShapeSt->Tilt_smth_Q16 = silk_SMLAWB( psShapeSt->Tilt_smth_Q16, Tilt_Q16 - psShapeSt->Tilt_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) ); psEncCtrl->HarmShapeGain_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmShapeGain_smth_Q16, 2 ); psEncCtrl->Tilt_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->Tilt_smth_Q16, 2 ); } RESTORE_STACK; } #endif /* OVERRIDE_silk_noise_shape_analysis_FIX */ jamulus-3.9.1+dfsg/libs/opus/silk/fixed/vector_ops_FIX.c0000644000175000017500000001125214340334543022172 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FIX.h" #include "pitch.h" /* Copy and multiply a vector by a constant */ void silk_scale_copy_vector16( opus_int16 *data_out, const opus_int16 *data_in, opus_int32 gain_Q16, /* I Gain in Q16 */ const opus_int dataSize /* I Length */ ) { opus_int i; opus_int32 tmp32; for( i = 0; i < dataSize; i++ ) { tmp32 = silk_SMULWB( gain_Q16, data_in[ i ] ); data_out[ i ] = (opus_int16)silk_CHECK_FIT16( tmp32 ); } } /* Multiply a vector by a constant */ void silk_scale_vector32_Q26_lshift_18( opus_int32 *data1, /* I/O Q0/Q18 */ opus_int32 gain_Q26, /* I Q26 */ opus_int dataSize /* I length */ ) { opus_int i; for( i = 0; i < dataSize; i++ ) { data1[ i ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( silk_SMULL( data1[ i ], gain_Q26 ), 8 ) ); /* OUTPUT: Q18 */ } } /* sum = for(i=0;i6, memory access can be reduced by half. */ opus_int32 silk_inner_prod_aligned( const opus_int16 *const inVec1, /* I input vector 1 */ const opus_int16 *const inVec2, /* I input vector 2 */ const opus_int len, /* I vector lengths */ int arch /* I Run-time architecture */ ) { #ifdef FIXED_POINT return celt_inner_prod(inVec1, inVec2, len, arch); #else opus_int i; opus_int32 sum = 0; for( i = 0; i < len; i++ ) { sum = silk_SMLABB( sum, inVec1[ i ], inVec2[ i ] ); } return sum; #endif } opus_int64 silk_inner_prod16_aligned_64_c( const opus_int16 *inVec1, /* I input vector 1 */ const opus_int16 *inVec2, /* I input vector 2 */ const opus_int len /* I vector lengths */ ) { opus_int i; opus_int64 sum = 0; for( i = 0; i < len; i++ ) { sum = silk_SMLALBB( sum, inVec1[ i ], inVec2[ i ] ); } return sum; } jamulus-3.9.1+dfsg/libs/opus/silk/fixed/encode_frame_FIX.c0000644000175000017500000005661714340334543022434 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "main_FIX.h" #include "stack_alloc.h" #include "tuning_parameters.h" /* Low Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode with lower bitrate */ static OPUS_INLINE void silk_LBRR_encode_FIX( silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */ const opus_int16 x16[], /* I Input signal */ opus_int condCoding /* I The type of conditional coding used so far for this frame */ ); void silk_encode_do_VAD_FIX( silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ opus_int activity /* I Decision of Opus voice activity detector */ ) { const opus_int activity_threshold = SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ); /****************************/ /* Voice Activity Detection */ /****************************/ silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.arch ); /* If Opus VAD is inactive and Silk VAD is active: lower Silk VAD to just under the threshold */ if( activity == VAD_NO_ACTIVITY && psEnc->sCmn.speech_activity_Q8 >= activity_threshold ) { psEnc->sCmn.speech_activity_Q8 = activity_threshold - 1; } /**************************************************/ /* Convert speech activity into VAD and DTX flags */ /**************************************************/ if( psEnc->sCmn.speech_activity_Q8 < activity_threshold ) { psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY; psEnc->sCmn.noSpeechCounter++; if( psEnc->sCmn.noSpeechCounter <= NB_SPEECH_FRAMES_BEFORE_DTX ) { psEnc->sCmn.inDTX = 0; } else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) { psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX; psEnc->sCmn.inDTX = 0; } psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 0; } else { psEnc->sCmn.noSpeechCounter = 0; psEnc->sCmn.inDTX = 0; psEnc->sCmn.indices.signalType = TYPE_UNVOICED; psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 1; } } /****************/ /* Encode frame */ /****************/ opus_int silk_encode_frame_FIX( silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ opus_int32 *pnBytesOut, /* O Pointer to number of payload bytes; */ ec_enc *psRangeEnc, /* I/O compressor data structure */ opus_int condCoding, /* I The type of conditional coding to use */ opus_int maxBits, /* I If > 0: maximum number of output bits */ opus_int useCBR /* I Flag to force constant-bitrate operation */ ) { silk_encoder_control_FIX sEncCtrl; opus_int i, iter, maxIter, found_upper, found_lower, ret = 0; opus_int16 *x_frame; ec_enc sRangeEnc_copy, sRangeEnc_copy2; silk_nsq_state sNSQ_copy, sNSQ_copy2; opus_int32 seed_copy, nBits, nBits_lower, nBits_upper, gainMult_lower, gainMult_upper; opus_int32 gainsID, gainsID_lower, gainsID_upper; opus_int16 gainMult_Q8; opus_int16 ec_prevLagIndex_copy; opus_int ec_prevSignalType_copy; opus_int8 LastGainIndex_copy2; opus_int gain_lock[ MAX_NB_SUBFR ] = {0}; opus_int16 best_gain_mult[ MAX_NB_SUBFR ]; opus_int best_sum[ MAX_NB_SUBFR ]; SAVE_STACK; /* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */ LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower = gainMult_upper = 0; psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3; /**************************************************************/ /* Set up Input Pointers, and insert frame in input buffer */ /*************************************************************/ /* start of frame to encode */ x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length; /***************************************/ /* Ensure smooth bandwidth transitions */ /***************************************/ silk_LP_variable_cutoff( &psEnc->sCmn.sLP, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length ); /*******************************************/ /* Copy new frame to front of input buffer */ /*******************************************/ silk_memcpy( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length * sizeof( opus_int16 ) ); if( !psEnc->sCmn.prefillFlag ) { VARDECL( opus_int16, res_pitch ); VARDECL( opus_uint8, ec_buf_copy ); opus_int16 *res_pitch_frame; ALLOC( res_pitch, psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length, opus_int16 ); /* start of pitch LPC residual frame */ res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length; /*****************************************/ /* Find pitch lags, initial LPC analysis */ /*****************************************/ silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame - psEnc->sCmn.ltp_mem_length, psEnc->sCmn.arch ); /************************/ /* Noise shape analysis */ /************************/ silk_noise_shape_analysis_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame, psEnc->sCmn.arch ); /***************************************************/ /* Find linear prediction coefficients (LPC + LTP) */ /***************************************************/ silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame, condCoding ); /****************************************/ /* Process gains */ /****************************************/ silk_process_gains_FIX( psEnc, &sEncCtrl, condCoding ); /****************************************/ /* Low Bitrate Redundant Encoding */ /****************************************/ silk_LBRR_encode_FIX( psEnc, &sEncCtrl, x_frame, condCoding ); /* Loop over quantizer and entropy coding to control bitrate */ maxIter = 6; gainMult_Q8 = SILK_FIX_CONST( 1, 8 ); found_lower = 0; found_upper = 0; gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr ); gainsID_lower = -1; gainsID_upper = -1; /* Copy part of the input state */ silk_memcpy( &sRangeEnc_copy, psRangeEnc, sizeof( ec_enc ) ); silk_memcpy( &sNSQ_copy, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); seed_copy = psEnc->sCmn.indices.Seed; ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex; ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType; ALLOC( ec_buf_copy, 1275, opus_uint8 ); for( iter = 0; ; iter++ ) { if( gainsID == gainsID_lower ) { nBits = nBits_lower; } else if( gainsID == gainsID_upper ) { nBits = nBits_upper; } else { /* Restore part of the input state */ if( iter > 0 ) { silk_memcpy( psRangeEnc, &sRangeEnc_copy, sizeof( ec_enc ) ); silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy, sizeof( silk_nsq_state ) ); psEnc->sCmn.indices.Seed = seed_copy; psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy; psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy; } /*****************************************/ /* Noise shaping quantization */ /*****************************************/ if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) { silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, x_frame, psEnc->sCmn.pulses, sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR_Q13, sEncCtrl.HarmShapeGain_Q14, sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14, psEnc->sCmn.arch ); } else { silk_NSQ( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, x_frame, psEnc->sCmn.pulses, sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR_Q13, sEncCtrl.HarmShapeGain_Q14, sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14, psEnc->sCmn.arch); } if ( iter == maxIter && !found_lower ) { silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) ); } /****************************************/ /* Encode Parameters */ /****************************************/ silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding ); /****************************************/ /* Encode Excitation Signal */ /****************************************/ silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType, psEnc->sCmn.pulses, psEnc->sCmn.frame_length ); nBits = ec_tell( psRangeEnc ); /* If we still bust after the last iteration, do some damage control. */ if ( iter == maxIter && !found_lower && nBits > maxBits ) { silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) ); /* Keep gains the same as the last frame. */ psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev; for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { psEnc->sCmn.indices.GainsIndices[ i ] = 4; } if (condCoding != CODE_CONDITIONALLY) { psEnc->sCmn.indices.GainsIndices[ 0 ] = sEncCtrl.lastGainIndexPrev; } psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy; psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy; /* Clear all pulses. */ for ( i = 0; i < psEnc->sCmn.frame_length; i++ ) { psEnc->sCmn.pulses[ i ] = 0; } silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding ); silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType, psEnc->sCmn.pulses, psEnc->sCmn.frame_length ); nBits = ec_tell( psRangeEnc ); } if( useCBR == 0 && iter == 0 && nBits <= maxBits ) { break; } } if( iter == maxIter ) { if( found_lower && ( gainsID == gainsID_lower || nBits > maxBits ) ) { /* Restore output state from earlier iteration that did meet the bitrate budget */ silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) ); celt_assert( sRangeEnc_copy2.offs <= 1275 ); silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs ); silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof( silk_nsq_state ) ); psEnc->sShape.LastGainIndex = LastGainIndex_copy2; } break; } if( nBits > maxBits ) { if( found_lower == 0 && iter >= 2 ) { /* Adjust the quantizer's rate/distortion tradeoff and discard previous "upper" results */ sEncCtrl.Lambda_Q10 = silk_ADD_RSHIFT32( sEncCtrl.Lambda_Q10, sEncCtrl.Lambda_Q10, 1 ); found_upper = 0; gainsID_upper = -1; } else { found_upper = 1; nBits_upper = nBits; gainMult_upper = gainMult_Q8; gainsID_upper = gainsID; } } else if( nBits < maxBits - 5 ) { found_lower = 1; nBits_lower = nBits; gainMult_lower = gainMult_Q8; if( gainsID != gainsID_lower ) { gainsID_lower = gainsID; /* Copy part of the output state */ silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) ); celt_assert( psRangeEnc->offs <= 1275 ); silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs ); silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); LastGainIndex_copy2 = psEnc->sShape.LastGainIndex; } } else { /* Within 5 bits of budget: close enough */ break; } if ( !found_lower && nBits > maxBits ) { int j; for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { int sum=0; for ( j = i*psEnc->sCmn.subfr_length; j < (i+1)*psEnc->sCmn.subfr_length; j++ ) { sum += abs( psEnc->sCmn.pulses[j] ); } if ( iter == 0 || (sum < best_sum[i] && !gain_lock[i]) ) { best_sum[i] = sum; best_gain_mult[i] = gainMult_Q8; } else { gain_lock[i] = 1; } } } if( ( found_lower & found_upper ) == 0 ) { /* Adjust gain according to high-rate rate/distortion curve */ if( nBits > maxBits ) { if (gainMult_Q8 < 16384) { gainMult_Q8 *= 2; } else { gainMult_Q8 = 32767; } } else { opus_int32 gain_factor_Q16; gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) ); gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 ); } } else { /* Adjust gain by interpolating */ gainMult_Q8 = gainMult_lower + silk_DIV32_16( silk_MUL( gainMult_upper - gainMult_lower, maxBits - nBits_lower ), nBits_upper - nBits_lower ); /* New gain multplier must be between 25% and 75% of old range (note that gainMult_upper < gainMult_lower) */ if( gainMult_Q8 > silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ) ) { gainMult_Q8 = silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ); } else if( gainMult_Q8 < silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ) ) { gainMult_Q8 = silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ); } } for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { opus_int16 tmp; if ( gain_lock[i] ) { tmp = best_gain_mult[i]; } else { tmp = gainMult_Q8; } sEncCtrl.Gains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], tmp ), 8 ); } /* Quantize gains */ psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev; silk_gains_quant( psEnc->sCmn.indices.GainsIndices, sEncCtrl.Gains_Q16, &psEnc->sShape.LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); /* Unique identifier of gains vector */ gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr ); } } /* Update input buffer */ silk_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ], ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( opus_int16 ) ); /* Exit without entropy coding */ if( psEnc->sCmn.prefillFlag ) { /* No payload */ *pnBytesOut = 0; RESTORE_STACK; return ret; } /* Parameters needed for next frame */ psEnc->sCmn.prevLag = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ]; psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType; /****************************************/ /* Finalize payload */ /****************************************/ psEnc->sCmn.first_frame_after_reset = 0; /* Payload size */ *pnBytesOut = silk_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 ); RESTORE_STACK; return ret; } /* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate */ static OPUS_INLINE void silk_LBRR_encode_FIX( silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */ const opus_int16 x16[], /* I Input signal */ opus_int condCoding /* I The type of conditional coding used so far for this frame */ ) { opus_int32 TempGains_Q16[ MAX_NB_SUBFR ]; SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesEncoded ]; silk_nsq_state sNSQ_LBRR; /*******************************************/ /* Control use of inband LBRR */ /*******************************************/ if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SILK_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) { psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded ] = 1; /* Copy noise shaping quantizer state and quantization indices from regular encoding */ silk_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); silk_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) ); /* Save original gains */ silk_memcpy( TempGains_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) ); if( psEnc->sCmn.nFramesEncoded == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded - 1 ] == 0 ) { /* First frame in packet or previous frame not LBRR coded */ psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex; /* Increase Gains to get target LBRR rate */ psIndices_LBRR->GainsIndices[ 0 ] = psIndices_LBRR->GainsIndices[ 0 ] + psEnc->sCmn.LBRR_GainIncreases; psIndices_LBRR->GainsIndices[ 0 ] = silk_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 ); } /* Decode to get gains in sync with decoder */ /* Overwrite unquantized gains with quantized gains */ silk_gains_dequant( psEncCtrl->Gains_Q16, psIndices_LBRR->GainsIndices, &psEnc->sCmn.LBRRprevLastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); /*****************************************/ /* Noise shaping quantization */ /*****************************************/ if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) { silk_NSQ_del_dec( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, x16, psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, psEncCtrl->AR_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14, psEnc->sCmn.arch ); } else { silk_NSQ( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, x16, psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, psEncCtrl->AR_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14, psEnc->sCmn.arch ); } /* Restore original gains */ silk_memcpy( psEncCtrl->Gains_Q16, TempGains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) ); } } jamulus-3.9.1+dfsg/libs/opus/silk/fixed/warped_autocorrelation_FIX.c0000644000175000017500000001123314340334543024562 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main_FIX.h" #if defined(MIPSr1_ASM) #include "mips/warped_autocorrelation_FIX_mipsr1.h" #endif /* Autocorrelations for a warped frequency axis */ #ifndef OVERRIDE_silk_warped_autocorrelation_FIX_c void silk_warped_autocorrelation_FIX_c( opus_int32 *corr, /* O Result [order + 1] */ opus_int *scale, /* O Scaling of the correlation vector */ const opus_int16 *input, /* I Input data to correlate */ const opus_int warping_Q16, /* I Warping coefficient */ const opus_int length, /* I Length of input */ const opus_int order /* I Correlation order (even) */ ) { opus_int n, i, lsh; opus_int32 tmp1_QS, tmp2_QS; opus_int32 state_QS[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; opus_int64 corr_QC[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; /* Order must be even */ celt_assert( ( order & 1 ) == 0 ); silk_assert( 2 * QS - QC >= 0 ); /* Loop over samples */ for( n = 0; n < length; n++ ) { tmp1_QS = silk_LSHIFT32( (opus_int32)input[ n ], QS ); /* Loop over allpass sections */ for( i = 0; i < order; i += 2 ) { /* Output of allpass section */ tmp2_QS = silk_SMLAWB( state_QS[ i ], state_QS[ i + 1 ] - tmp1_QS, warping_Q16 ); state_QS[ i ] = tmp1_QS; corr_QC[ i ] += silk_RSHIFT64( silk_SMULL( tmp1_QS, state_QS[ 0 ] ), 2 * QS - QC ); /* Output of allpass section */ tmp1_QS = silk_SMLAWB( state_QS[ i + 1 ], state_QS[ i + 2 ] - tmp2_QS, warping_Q16 ); state_QS[ i + 1 ] = tmp2_QS; corr_QC[ i + 1 ] += silk_RSHIFT64( silk_SMULL( tmp2_QS, state_QS[ 0 ] ), 2 * QS - QC ); } state_QS[ order ] = tmp1_QS; corr_QC[ order ] += silk_RSHIFT64( silk_SMULL( tmp1_QS, state_QS[ 0 ] ), 2 * QS - QC ); } lsh = silk_CLZ64( corr_QC[ 0 ] ) - 35; lsh = silk_LIMIT( lsh, -12 - QC, 30 - QC ); *scale = -( QC + lsh ); silk_assert( *scale >= -30 && *scale <= 12 ); if( lsh >= 0 ) { for( i = 0; i < order + 1; i++ ) { corr[ i ] = (opus_int32)silk_CHECK_FIT32( silk_LSHIFT64( corr_QC[ i ], lsh ) ); } } else { for( i = 0; i < order + 1; i++ ) { corr[ i ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( corr_QC[ i ], -lsh ) ); } } silk_assert( corr_QC[ 0 ] >= 0 ); /* If breaking, decrease QC*/ } #endif /* OVERRIDE_silk_warped_autocorrelation_FIX_c */ jamulus-3.9.1+dfsg/libs/opus/silk/fixed/k2a_FIX.c0000644000175000017500000000516314340334543020470 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FIX.h" /* Step up function, converts reflection coefficients to prediction coefficients */ void silk_k2a( opus_int32 *A_Q24, /* O Prediction coefficients [order] Q24 */ const opus_int16 *rc_Q15, /* I Reflection coefficients [order] Q15 */ const opus_int32 order /* I Prediction order */ ) { opus_int k, n; opus_int32 rc, tmp1, tmp2; for( k = 0; k < order; k++ ) { rc = rc_Q15[ k ]; for( n = 0; n < (k + 1) >> 1; n++ ) { tmp1 = A_Q24[ n ]; tmp2 = A_Q24[ k - n - 1 ]; A_Q24[ n ] = silk_SMLAWB( tmp1, silk_LSHIFT( tmp2, 1 ), rc ); A_Q24[ k - n - 1 ] = silk_SMLAWB( tmp2, silk_LSHIFT( tmp1, 1 ), rc ); } A_Q24[ k ] = -silk_LSHIFT( (opus_int32)rc_Q15[ k ], 9 ); } } jamulus-3.9.1+dfsg/libs/opus/silk/fixed/schur64_FIX.c0000644000175000017500000000763214340334543021314 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FIX.h" /* Slower than schur(), but more accurate. */ /* Uses SMULL(), available on armv4 */ opus_int32 silk_schur64( /* O returns residual energy */ opus_int32 rc_Q16[], /* O Reflection coefficients [order] Q16 */ const opus_int32 c[], /* I Correlations [order+1] */ opus_int32 order /* I Prediction order */ ) { opus_int k, n; opus_int32 C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ]; opus_int32 Ctmp1_Q30, Ctmp2_Q30, rc_tmp_Q31; celt_assert( order >= 0 && order <= SILK_MAX_ORDER_LPC ); /* Check for invalid input */ if( c[ 0 ] <= 0 ) { silk_memset( rc_Q16, 0, order * sizeof( opus_int32 ) ); return 0; } k = 0; do { C[ k ][ 0 ] = C[ k ][ 1 ] = c[ k ]; } while( ++k <= order ); for( k = 0; k < order; k++ ) { /* Check that we won't be getting an unstable rc, otherwise stop here. */ if (silk_abs_int32(C[ k + 1 ][ 0 ]) >= C[ 0 ][ 1 ]) { if ( C[ k + 1 ][ 0 ] > 0 ) { rc_Q16[ k ] = -SILK_FIX_CONST( .99f, 16 ); } else { rc_Q16[ k ] = SILK_FIX_CONST( .99f, 16 ); } k++; break; } /* Get reflection coefficient: divide two Q30 values and get result in Q31 */ rc_tmp_Q31 = silk_DIV32_varQ( -C[ k + 1 ][ 0 ], C[ 0 ][ 1 ], 31 ); /* Save the output */ rc_Q16[ k ] = silk_RSHIFT_ROUND( rc_tmp_Q31, 15 ); /* Update correlations */ for( n = 0; n < order - k; n++ ) { Ctmp1_Q30 = C[ n + k + 1 ][ 0 ]; Ctmp2_Q30 = C[ n ][ 1 ]; /* Multiply and add the highest int32 */ C[ n + k + 1 ][ 0 ] = Ctmp1_Q30 + silk_SMMUL( silk_LSHIFT( Ctmp2_Q30, 1 ), rc_tmp_Q31 ); C[ n ][ 1 ] = Ctmp2_Q30 + silk_SMMUL( silk_LSHIFT( Ctmp1_Q30, 1 ), rc_tmp_Q31 ); } } for(; k < order; k++ ) { rc_Q16[ k ] = 0; } return silk_max_32( 1, C[ 0 ][ 1 ] ); } jamulus-3.9.1+dfsg/libs/opus/silk/fixed/find_LTP_FIX.c0000644000175000017500000001245614340334543021455 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main_FIX.h" #include "tuning_parameters.h" void silk_find_LTP_FIX( opus_int32 XXLTP_Q17[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Correlation matrix */ opus_int32 xXLTP_Q17[ MAX_NB_SUBFR * LTP_ORDER ], /* O Correlation vector */ const opus_int16 r_ptr[], /* I Residual signal after LPC */ const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */ const opus_int subfr_length, /* I Subframe length */ const opus_int nb_subfr, /* I Number of subframes */ int arch /* I Run-time architecture */ ) { opus_int i, k, extra_shifts; opus_int xx_shifts, xX_shifts, XX_shifts; const opus_int16 *lag_ptr; opus_int32 *XXLTP_Q17_ptr, *xXLTP_Q17_ptr; opus_int32 xx, nrg, temp; xXLTP_Q17_ptr = xXLTP_Q17; XXLTP_Q17_ptr = XXLTP_Q17; for( k = 0; k < nb_subfr; k++ ) { lag_ptr = r_ptr - ( lag[ k ] + LTP_ORDER / 2 ); silk_sum_sqr_shift( &xx, &xx_shifts, r_ptr, subfr_length + LTP_ORDER ); /* xx in Q( -xx_shifts ) */ silk_corrMatrix_FIX( lag_ptr, subfr_length, LTP_ORDER, XXLTP_Q17_ptr, &nrg, &XX_shifts, arch ); /* XXLTP_Q17_ptr and nrg in Q( -XX_shifts ) */ extra_shifts = xx_shifts - XX_shifts; if( extra_shifts > 0 ) { /* Shift XX */ xX_shifts = xx_shifts; for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) { XXLTP_Q17_ptr[ i ] = silk_RSHIFT32( XXLTP_Q17_ptr[ i ], extra_shifts ); /* Q( -xX_shifts ) */ } nrg = silk_RSHIFT32( nrg, extra_shifts ); /* Q( -xX_shifts ) */ } else if( extra_shifts < 0 ) { /* Shift xx */ xX_shifts = XX_shifts; xx = silk_RSHIFT32( xx, -extra_shifts ); /* Q( -xX_shifts ) */ } else { xX_shifts = xx_shifts; } silk_corrVector_FIX( lag_ptr, r_ptr, subfr_length, LTP_ORDER, xXLTP_Q17_ptr, xX_shifts, arch ); /* xXLTP_Q17_ptr in Q( -xX_shifts ) */ /* At this point all correlations are in Q(-xX_shifts) */ temp = silk_SMLAWB( 1, nrg, SILK_FIX_CONST( LTP_CORR_INV_MAX, 16 ) ); temp = silk_max( temp, xx ); TIC(div) #if 0 for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) { XXLTP_Q17_ptr[ i ] = silk_DIV32_varQ( XXLTP_Q17_ptr[ i ], temp, 17 ); } for( i = 0; i < LTP_ORDER; i++ ) { xXLTP_Q17_ptr[ i ] = silk_DIV32_varQ( xXLTP_Q17_ptr[ i ], temp, 17 ); } #else for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) { XXLTP_Q17_ptr[ i ] = (opus_int32)( silk_LSHIFT64( (opus_int64)XXLTP_Q17_ptr[ i ], 17 ) / temp ); } for( i = 0; i < LTP_ORDER; i++ ) { xXLTP_Q17_ptr[ i ] = (opus_int32)( silk_LSHIFT64( (opus_int64)xXLTP_Q17_ptr[ i ], 17 ) / temp ); } #endif TOC(div) r_ptr += subfr_length; XXLTP_Q17_ptr += LTP_ORDER * LTP_ORDER; xXLTP_Q17_ptr += LTP_ORDER; } } jamulus-3.9.1+dfsg/libs/opus/silk/fixed/find_LPC_FIX.c0000644000175000017500000001630114340334543021425 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main_FIX.h" #include "stack_alloc.h" #include "tuning_parameters.h" /* Finds LPC vector from correlations, and converts to NLSF */ void silk_find_LPC_FIX( silk_encoder_state *psEncC, /* I/O Encoder state */ opus_int16 NLSF_Q15[], /* O NLSFs */ const opus_int16 x[], /* I Input signal */ const opus_int32 minInvGain_Q30 /* I Inverse of max prediction gain */ ) { opus_int k, subfr_length; opus_int32 a_Q16[ MAX_LPC_ORDER ]; opus_int isInterpLower, shift; opus_int32 res_nrg0, res_nrg1; opus_int rshift0, rshift1; /* Used only for LSF interpolation */ opus_int32 a_tmp_Q16[ MAX_LPC_ORDER ], res_nrg_interp, res_nrg, res_tmp_nrg; opus_int res_nrg_interp_Q, res_nrg_Q, res_tmp_nrg_Q; opus_int16 a_tmp_Q12[ MAX_LPC_ORDER ]; opus_int16 NLSF0_Q15[ MAX_LPC_ORDER ]; SAVE_STACK; subfr_length = psEncC->subfr_length + psEncC->predictLPCOrder; /* Default: no interpolation */ psEncC->indices.NLSFInterpCoef_Q2 = 4; /* Burg AR analysis for the full frame */ silk_burg_modified( &res_nrg, &res_nrg_Q, a_Q16, x, minInvGain_Q30, subfr_length, psEncC->nb_subfr, psEncC->predictLPCOrder, psEncC->arch ); if( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) { VARDECL( opus_int16, LPC_res ); /* Optimal solution for last 10 ms */ silk_burg_modified( &res_tmp_nrg, &res_tmp_nrg_Q, a_tmp_Q16, x + 2 * subfr_length, minInvGain_Q30, subfr_length, 2, psEncC->predictLPCOrder, psEncC->arch ); /* subtract residual energy here, as that's easier than adding it to the */ /* residual energy of the first 10 ms in each iteration of the search below */ shift = res_tmp_nrg_Q - res_nrg_Q; if( shift >= 0 ) { if( shift < 32 ) { res_nrg = res_nrg - silk_RSHIFT( res_tmp_nrg, shift ); } } else { silk_assert( shift > -32 ); res_nrg = silk_RSHIFT( res_nrg, -shift ) - res_tmp_nrg; res_nrg_Q = res_tmp_nrg_Q; } /* Convert to NLSFs */ silk_A2NLSF( NLSF_Q15, a_tmp_Q16, psEncC->predictLPCOrder ); ALLOC( LPC_res, 2 * subfr_length, opus_int16 ); /* Search over interpolation indices to find the one with lowest residual energy */ for( k = 3; k >= 0; k-- ) { /* Interpolate NLSFs for first half */ silk_interpolate( NLSF0_Q15, psEncC->prev_NLSFq_Q15, NLSF_Q15, k, psEncC->predictLPCOrder ); /* Convert to LPC for residual energy evaluation */ silk_NLSF2A( a_tmp_Q12, NLSF0_Q15, psEncC->predictLPCOrder, psEncC->arch ); /* Calculate residual energy with NLSF interpolation */ silk_LPC_analysis_filter( LPC_res, x, a_tmp_Q12, 2 * subfr_length, psEncC->predictLPCOrder, psEncC->arch ); silk_sum_sqr_shift( &res_nrg0, &rshift0, LPC_res + psEncC->predictLPCOrder, subfr_length - psEncC->predictLPCOrder ); silk_sum_sqr_shift( &res_nrg1, &rshift1, LPC_res + psEncC->predictLPCOrder + subfr_length, subfr_length - psEncC->predictLPCOrder ); /* Add subframe energies from first half frame */ shift = rshift0 - rshift1; if( shift >= 0 ) { res_nrg1 = silk_RSHIFT( res_nrg1, shift ); res_nrg_interp_Q = -rshift0; } else { res_nrg0 = silk_RSHIFT( res_nrg0, -shift ); res_nrg_interp_Q = -rshift1; } res_nrg_interp = silk_ADD32( res_nrg0, res_nrg1 ); /* Compare with first half energy without NLSF interpolation, or best interpolated value so far */ shift = res_nrg_interp_Q - res_nrg_Q; if( shift >= 0 ) { if( silk_RSHIFT( res_nrg_interp, shift ) < res_nrg ) { isInterpLower = silk_TRUE; } else { isInterpLower = silk_FALSE; } } else { if( -shift < 32 ) { if( res_nrg_interp < silk_RSHIFT( res_nrg, -shift ) ) { isInterpLower = silk_TRUE; } else { isInterpLower = silk_FALSE; } } else { isInterpLower = silk_FALSE; } } /* Determine whether current interpolated NLSFs are best so far */ if( isInterpLower == silk_TRUE ) { /* Interpolation has lower residual energy */ res_nrg = res_nrg_interp; res_nrg_Q = res_nrg_interp_Q; psEncC->indices.NLSFInterpCoef_Q2 = (opus_int8)k; } } } if( psEncC->indices.NLSFInterpCoef_Q2 == 4 ) { /* NLSF interpolation is currently inactive, calculate NLSFs from full frame AR coefficients */ silk_A2NLSF( NLSF_Q15, a_Q16, psEncC->predictLPCOrder ); } celt_assert( psEncC->indices.NLSFInterpCoef_Q2 == 4 || ( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) ); RESTORE_STACK; } jamulus-3.9.1+dfsg/libs/opus/silk/fixed/find_pitch_lags_FIX.c0000644000175000017500000001624214340334543023130 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main_FIX.h" #include "stack_alloc.h" #include "tuning_parameters.h" /* Find pitch lags */ void silk_find_pitch_lags_FIX( silk_encoder_state_FIX *psEnc, /* I/O encoder state */ silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ opus_int16 res[], /* O residual */ const opus_int16 x[], /* I Speech signal */ int arch /* I Run-time architecture */ ) { opus_int buf_len, i, scale; opus_int32 thrhld_Q13, res_nrg; const opus_int16 *x_ptr; VARDECL( opus_int16, Wsig ); opus_int16 *Wsig_ptr; opus_int32 auto_corr[ MAX_FIND_PITCH_LPC_ORDER + 1 ]; opus_int16 rc_Q15[ MAX_FIND_PITCH_LPC_ORDER ]; opus_int32 A_Q24[ MAX_FIND_PITCH_LPC_ORDER ]; opus_int16 A_Q12[ MAX_FIND_PITCH_LPC_ORDER ]; SAVE_STACK; /******************************************/ /* Set up buffer lengths etc based on Fs */ /******************************************/ buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length; /* Safety check */ celt_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length ); /*************************************/ /* Estimate LPC AR coefficients */ /*************************************/ /* Calculate windowed signal */ ALLOC( Wsig, psEnc->sCmn.pitch_LPC_win_length, opus_int16 ); /* First LA_LTP samples */ x_ptr = x + buf_len - psEnc->sCmn.pitch_LPC_win_length; Wsig_ptr = Wsig; silk_apply_sine_window( Wsig_ptr, x_ptr, 1, psEnc->sCmn.la_pitch ); /* Middle un - windowed samples */ Wsig_ptr += psEnc->sCmn.la_pitch; x_ptr += psEnc->sCmn.la_pitch; silk_memcpy( Wsig_ptr, x_ptr, ( psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 ) ) * sizeof( opus_int16 ) ); /* Last LA_LTP samples */ Wsig_ptr += psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 ); x_ptr += psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 ); silk_apply_sine_window( Wsig_ptr, x_ptr, 2, psEnc->sCmn.la_pitch ); /* Calculate autocorrelation sequence */ silk_autocorr( auto_corr, &scale, Wsig, psEnc->sCmn.pitch_LPC_win_length, psEnc->sCmn.pitchEstimationLPCOrder + 1, arch ); /* Add white noise, as fraction of energy */ auto_corr[ 0 ] = silk_SMLAWB( auto_corr[ 0 ], auto_corr[ 0 ], SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) ) + 1; /* Calculate the reflection coefficients using schur */ res_nrg = silk_schur( rc_Q15, auto_corr, psEnc->sCmn.pitchEstimationLPCOrder ); /* Prediction gain */ psEncCtrl->predGain_Q16 = silk_DIV32_varQ( auto_corr[ 0 ], silk_max_int( res_nrg, 1 ), 16 ); /* Convert reflection coefficients to prediction coefficients */ silk_k2a( A_Q24, rc_Q15, psEnc->sCmn.pitchEstimationLPCOrder ); /* Convert From 32 bit Q24 to 16 bit Q12 coefs */ for( i = 0; i < psEnc->sCmn.pitchEstimationLPCOrder; i++ ) { A_Q12[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT( A_Q24[ i ], 12 ) ); } /* Do BWE */ silk_bwexpander( A_Q12, psEnc->sCmn.pitchEstimationLPCOrder, SILK_FIX_CONST( FIND_PITCH_BANDWIDTH_EXPANSION, 16 ) ); /*****************************************/ /* LPC analysis filtering */ /*****************************************/ silk_LPC_analysis_filter( res, x, A_Q12, buf_len, psEnc->sCmn.pitchEstimationLPCOrder, psEnc->sCmn.arch ); if( psEnc->sCmn.indices.signalType != TYPE_NO_VOICE_ACTIVITY && psEnc->sCmn.first_frame_after_reset == 0 ) { /* Threshold for pitch estimator */ thrhld_Q13 = SILK_FIX_CONST( 0.6, 13 ); thrhld_Q13 = silk_SMLABB( thrhld_Q13, SILK_FIX_CONST( -0.004, 13 ), psEnc->sCmn.pitchEstimationLPCOrder ); thrhld_Q13 = silk_SMLAWB( thrhld_Q13, SILK_FIX_CONST( -0.1, 21 ), psEnc->sCmn.speech_activity_Q8 ); thrhld_Q13 = silk_SMLABB( thrhld_Q13, SILK_FIX_CONST( -0.15, 13 ), silk_RSHIFT( psEnc->sCmn.prevSignalType, 1 ) ); thrhld_Q13 = silk_SMLAWB( thrhld_Q13, SILK_FIX_CONST( -0.1, 14 ), psEnc->sCmn.input_tilt_Q15 ); thrhld_Q13 = silk_SAT16( thrhld_Q13 ); /*****************************************/ /* Call pitch estimator */ /*****************************************/ if( silk_pitch_analysis_core( res, psEncCtrl->pitchL, &psEnc->sCmn.indices.lagIndex, &psEnc->sCmn.indices.contourIndex, &psEnc->LTPCorr_Q15, psEnc->sCmn.prevLag, psEnc->sCmn.pitchEstimationThreshold_Q16, (opus_int)thrhld_Q13, psEnc->sCmn.fs_kHz, psEnc->sCmn.pitchEstimationComplexity, psEnc->sCmn.nb_subfr, psEnc->sCmn.arch) == 0 ) { psEnc->sCmn.indices.signalType = TYPE_VOICED; } else { psEnc->sCmn.indices.signalType = TYPE_UNVOICED; } } else { silk_memset( psEncCtrl->pitchL, 0, sizeof( psEncCtrl->pitchL ) ); psEnc->sCmn.indices.lagIndex = 0; psEnc->sCmn.indices.contourIndex = 0; psEnc->LTPCorr_Q15 = 0; } RESTORE_STACK; } jamulus-3.9.1+dfsg/libs/opus/silk/fixed/burg_modified_FIX.c0000644000175000017500000004063014340334543022610 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FIX.h" #include "define.h" #include "tuning_parameters.h" #include "pitch.h" #define MAX_FRAME_SIZE 384 /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384 */ #define QA 25 #define N_BITS_HEAD_ROOM 3 #define MIN_RSHIFTS -16 #define MAX_RSHIFTS (32 - QA) /* Compute reflection coefficients from input signal */ void silk_burg_modified_c( opus_int32 *res_nrg, /* O Residual energy */ opus_int *res_nrg_Q, /* O Residual energy Q value */ opus_int32 A_Q16[], /* O Prediction coefficients (length order) */ const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */ const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */ const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */ const opus_int nb_subfr, /* I Number of subframes stacked in x */ const opus_int D, /* I Order */ int arch /* I Run-time architecture */ ) { opus_int k, n, s, lz, rshifts, reached_max_gain; opus_int32 C0, num, nrg, rc_Q31, invGain_Q30, Atmp_QA, Atmp1, tmp1, tmp2, x1, x2; const opus_int16 *x_ptr; opus_int32 C_first_row[ SILK_MAX_ORDER_LPC ]; opus_int32 C_last_row[ SILK_MAX_ORDER_LPC ]; opus_int32 Af_QA[ SILK_MAX_ORDER_LPC ]; opus_int32 CAf[ SILK_MAX_ORDER_LPC + 1 ]; opus_int32 CAb[ SILK_MAX_ORDER_LPC + 1 ]; opus_int32 xcorr[ SILK_MAX_ORDER_LPC ]; opus_int64 C0_64; celt_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE ); /* Compute autocorrelations, added over subframes */ C0_64 = silk_inner_prod16_aligned_64( x, x, subfr_length*nb_subfr, arch ); lz = silk_CLZ64(C0_64); rshifts = 32 + 1 + N_BITS_HEAD_ROOM - lz; if (rshifts > MAX_RSHIFTS) rshifts = MAX_RSHIFTS; if (rshifts < MIN_RSHIFTS) rshifts = MIN_RSHIFTS; if (rshifts > 0) { C0 = (opus_int32)silk_RSHIFT64(C0_64, rshifts ); } else { C0 = silk_LSHIFT32((opus_int32)C0_64, -rshifts ); } CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1; /* Q(-rshifts) */ silk_memset( C_first_row, 0, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) ); if( rshifts > 0 ) { for( s = 0; s < nb_subfr; s++ ) { x_ptr = x + s * subfr_length; for( n = 1; n < D + 1; n++ ) { C_first_row[ n - 1 ] += (opus_int32)silk_RSHIFT64( silk_inner_prod16_aligned_64( x_ptr, x_ptr + n, subfr_length - n, arch ), rshifts ); } } } else { for( s = 0; s < nb_subfr; s++ ) { int i; opus_int32 d; x_ptr = x + s * subfr_length; celt_pitch_xcorr(x_ptr, x_ptr + 1, xcorr, subfr_length - D, D, arch ); for( n = 1; n < D + 1; n++ ) { for ( i = n + subfr_length - D, d = 0; i < subfr_length; i++ ) d = MAC16_16( d, x_ptr[ i ], x_ptr[ i - n ] ); xcorr[ n - 1 ] += d; } for( n = 1; n < D + 1; n++ ) { C_first_row[ n - 1 ] += silk_LSHIFT32( xcorr[ n - 1 ], -rshifts ); } } } silk_memcpy( C_last_row, C_first_row, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) ); /* Initialize */ CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1; /* Q(-rshifts) */ invGain_Q30 = (opus_int32)1 << 30; reached_max_gain = 0; for( n = 0; n < D; n++ ) { /* Update first row of correlation matrix (without first element) */ /* Update last row of correlation matrix (without last element, stored in reversed order) */ /* Update C * Af */ /* Update C * flipud(Af) (stored in reversed order) */ if( rshifts > -2 ) { for( s = 0; s < nb_subfr; s++ ) { x_ptr = x + s * subfr_length; x1 = -silk_LSHIFT32( (opus_int32)x_ptr[ n ], 16 - rshifts ); /* Q(16-rshifts) */ x2 = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 16 - rshifts ); /* Q(16-rshifts) */ tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ], QA - 16 ); /* Q(QA-16) */ tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], QA - 16 ); /* Q(QA-16) */ for( k = 0; k < n; k++ ) { C_first_row[ k ] = silk_SMLAWB( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts ) */ C_last_row[ k ] = silk_SMLAWB( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */ Atmp_QA = Af_QA[ k ]; tmp1 = silk_SMLAWB( tmp1, Atmp_QA, x_ptr[ n - k - 1 ] ); /* Q(QA-16) */ tmp2 = silk_SMLAWB( tmp2, Atmp_QA, x_ptr[ subfr_length - n + k ] ); /* Q(QA-16) */ } tmp1 = silk_LSHIFT32( -tmp1, 32 - QA - rshifts ); /* Q(16-rshifts) */ tmp2 = silk_LSHIFT32( -tmp2, 32 - QA - rshifts ); /* Q(16-rshifts) */ for( k = 0; k <= n; k++ ) { CAf[ k ] = silk_SMLAWB( CAf[ k ], tmp1, x_ptr[ n - k ] ); /* Q( -rshift ) */ CAb[ k ] = silk_SMLAWB( CAb[ k ], tmp2, x_ptr[ subfr_length - n + k - 1 ] ); /* Q( -rshift ) */ } } } else { for( s = 0; s < nb_subfr; s++ ) { x_ptr = x + s * subfr_length; x1 = -silk_LSHIFT32( (opus_int32)x_ptr[ n ], -rshifts ); /* Q( -rshifts ) */ x2 = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], -rshifts ); /* Q( -rshifts ) */ tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ], 17 ); /* Q17 */ tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 17 ); /* Q17 */ for( k = 0; k < n; k++ ) { C_first_row[ k ] = silk_MLA( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts ) */ C_last_row[ k ] = silk_MLA( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */ Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 17 ); /* Q17 */ /* We sometimes have get overflows in the multiplications (even beyond +/- 2^32), but they cancel each other and the real result seems to always fit in a 32-bit signed integer. This was determined experimentally, not theoretically (unfortunately). */ tmp1 = silk_MLA_ovflw( tmp1, x_ptr[ n - k - 1 ], Atmp1 ); /* Q17 */ tmp2 = silk_MLA_ovflw( tmp2, x_ptr[ subfr_length - n + k ], Atmp1 ); /* Q17 */ } tmp1 = -tmp1; /* Q17 */ tmp2 = -tmp2; /* Q17 */ for( k = 0; k <= n; k++ ) { CAf[ k ] = silk_SMLAWW( CAf[ k ], tmp1, silk_LSHIFT32( (opus_int32)x_ptr[ n - k ], -rshifts - 1 ) ); /* Q( -rshift ) */ CAb[ k ] = silk_SMLAWW( CAb[ k ], tmp2, silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n + k - 1 ], -rshifts - 1 ) ); /* Q( -rshift ) */ } } } /* Calculate nominator and denominator for the next order reflection (parcor) coefficient */ tmp1 = C_first_row[ n ]; /* Q( -rshifts ) */ tmp2 = C_last_row[ n ]; /* Q( -rshifts ) */ num = 0; /* Q( -rshifts ) */ nrg = silk_ADD32( CAb[ 0 ], CAf[ 0 ] ); /* Q( 1-rshifts ) */ for( k = 0; k < n; k++ ) { Atmp_QA = Af_QA[ k ]; lz = silk_CLZ32( silk_abs( Atmp_QA ) ) - 1; lz = silk_min( 32 - QA, lz ); Atmp1 = silk_LSHIFT32( Atmp_QA, lz ); /* Q( QA + lz ) */ tmp1 = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( C_last_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */ tmp2 = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( C_first_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */ num = silk_ADD_LSHIFT32( num, silk_SMMUL( CAb[ n - k ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */ nrg = silk_ADD_LSHIFT32( nrg, silk_SMMUL( silk_ADD32( CAb[ k + 1 ], CAf[ k + 1 ] ), Atmp1 ), 32 - QA - lz ); /* Q( 1-rshifts ) */ } CAf[ n + 1 ] = tmp1; /* Q( -rshifts ) */ CAb[ n + 1 ] = tmp2; /* Q( -rshifts ) */ num = silk_ADD32( num, tmp2 ); /* Q( -rshifts ) */ num = silk_LSHIFT32( -num, 1 ); /* Q( 1-rshifts ) */ /* Calculate the next order reflection (parcor) coefficient */ if( silk_abs( num ) < nrg ) { rc_Q31 = silk_DIV32_varQ( num, nrg, 31 ); } else { rc_Q31 = ( num > 0 ) ? silk_int32_MAX : silk_int32_MIN; } /* Update inverse prediction gain */ tmp1 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 ); tmp1 = silk_LSHIFT( silk_SMMUL( invGain_Q30, tmp1 ), 2 ); if( tmp1 <= minInvGain_Q30 ) { /* Max prediction gain exceeded; set reflection coefficient such that max prediction gain is exactly hit */ tmp2 = ( (opus_int32)1 << 30 ) - silk_DIV32_varQ( minInvGain_Q30, invGain_Q30, 30 ); /* Q30 */ rc_Q31 = silk_SQRT_APPROX( tmp2 ); /* Q15 */ if( rc_Q31 > 0 ) { /* Newton-Raphson iteration */ rc_Q31 = silk_RSHIFT32( rc_Q31 + silk_DIV32( tmp2, rc_Q31 ), 1 ); /* Q15 */ rc_Q31 = silk_LSHIFT32( rc_Q31, 16 ); /* Q31 */ if( num < 0 ) { /* Ensure adjusted reflection coefficients has the original sign */ rc_Q31 = -rc_Q31; } } invGain_Q30 = minInvGain_Q30; reached_max_gain = 1; } else { invGain_Q30 = tmp1; } /* Update the AR coefficients */ for( k = 0; k < (n + 1) >> 1; k++ ) { tmp1 = Af_QA[ k ]; /* QA */ tmp2 = Af_QA[ n - k - 1 ]; /* QA */ Af_QA[ k ] = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 ); /* QA */ Af_QA[ n - k - 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 ); /* QA */ } Af_QA[ n ] = silk_RSHIFT32( rc_Q31, 31 - QA ); /* QA */ if( reached_max_gain ) { /* Reached max prediction gain; set remaining coefficients to zero and exit loop */ for( k = n + 1; k < D; k++ ) { Af_QA[ k ] = 0; } break; } /* Update C * Af and C * Ab */ for( k = 0; k <= n + 1; k++ ) { tmp1 = CAf[ k ]; /* Q( -rshifts ) */ tmp2 = CAb[ n - k + 1 ]; /* Q( -rshifts ) */ CAf[ k ] = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 ); /* Q( -rshifts ) */ CAb[ n - k + 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 ); /* Q( -rshifts ) */ } } if( reached_max_gain ) { for( k = 0; k < D; k++ ) { /* Scale coefficients */ A_Q16[ k ] = -silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 ); } /* Subtract energy of preceding samples from C0 */ if( rshifts > 0 ) { for( s = 0; s < nb_subfr; s++ ) { x_ptr = x + s * subfr_length; C0 -= (opus_int32)silk_RSHIFT64( silk_inner_prod16_aligned_64( x_ptr, x_ptr, D, arch ), rshifts ); } } else { for( s = 0; s < nb_subfr; s++ ) { x_ptr = x + s * subfr_length; C0 -= silk_LSHIFT32( silk_inner_prod_aligned( x_ptr, x_ptr, D, arch), -rshifts); } } /* Approximate residual energy */ *res_nrg = silk_LSHIFT( silk_SMMUL( invGain_Q30, C0 ), 2 ); *res_nrg_Q = -rshifts; } else { /* Return residual energy */ nrg = CAf[ 0 ]; /* Q( -rshifts ) */ tmp1 = (opus_int32)1 << 16; /* Q16 */ for( k = 0; k < D; k++ ) { Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 ); /* Q16 */ nrg = silk_SMLAWW( nrg, CAf[ k + 1 ], Atmp1 ); /* Q( -rshifts ) */ tmp1 = silk_SMLAWW( tmp1, Atmp1, Atmp1 ); /* Q16 */ A_Q16[ k ] = -Atmp1; } *res_nrg = silk_SMLAWW( nrg, silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ), -tmp1 );/* Q( -rshifts ) */ *res_nrg_Q = -rshifts; } } jamulus-3.9.1+dfsg/libs/opus/silk/fixed/autocorr_FIX.c0000644000175000017500000000524514340334543021652 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FIX.h" #include "celt_lpc.h" /* Compute autocorrelation */ void silk_autocorr( opus_int32 *results, /* O Result (length correlationCount) */ opus_int *scale, /* O Scaling of the correlation vector */ const opus_int16 *inputData, /* I Input data to correlate */ const opus_int inputDataSize, /* I Length of input */ const opus_int correlationCount, /* I Number of correlation taps to compute */ int arch /* I Run-time architecture */ ) { opus_int corrCount; corrCount = silk_min_int( inputDataSize, correlationCount ); *scale = _celt_autocorr(inputData, results, NULL, 0, corrCount-1, inputDataSize, arch); } jamulus-3.9.1+dfsg/libs/opus/silk/fixed/structs_FIX.h0000644000175000017500000001204014340334543021517 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SILK_STRUCTS_FIX_H #define SILK_STRUCTS_FIX_H #include "typedef.h" #include "main.h" #include "structs.h" #ifdef __cplusplus extern "C" { #endif /********************************/ /* Noise shaping analysis state */ /********************************/ typedef struct { opus_int8 LastGainIndex; opus_int32 HarmBoost_smth_Q16; opus_int32 HarmShapeGain_smth_Q16; opus_int32 Tilt_smth_Q16; } silk_shape_state_FIX; /********************************/ /* Encoder state FIX */ /********************************/ typedef struct { silk_encoder_state sCmn; /* Common struct, shared with floating-point code */ silk_shape_state_FIX sShape; /* Shape state */ /* Buffer for find pitch and noise shape analysis */ silk_DWORD_ALIGN opus_int16 x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ];/* Buffer for find pitch and noise shape analysis */ opus_int LTPCorr_Q15; /* Normalized correlation from pitch lag estimator */ opus_int32 resNrgSmth; } silk_encoder_state_FIX; /************************/ /* Encoder control FIX */ /************************/ typedef struct { /* Prediction and coding parameters */ opus_int32 Gains_Q16[ MAX_NB_SUBFR ]; silk_DWORD_ALIGN opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ]; opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ]; opus_int LTP_scale_Q14; opus_int pitchL[ MAX_NB_SUBFR ]; /* Noise shaping parameters */ /* Testing */ silk_DWORD_ALIGN opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ]; opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ]; /* Packs two int16 coefficients per int32 value */ opus_int Tilt_Q14[ MAX_NB_SUBFR ]; opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ]; opus_int Lambda_Q10; opus_int input_quality_Q14; opus_int coding_quality_Q14; /* measures */ opus_int32 predGain_Q16; opus_int LTPredCodGain_Q7; opus_int32 ResNrg[ MAX_NB_SUBFR ]; /* Residual energy per subframe */ opus_int ResNrgQ[ MAX_NB_SUBFR ]; /* Q domain for the residual energy > 0 */ /* Parameters for CBR mode */ opus_int32 GainsUnq_Q16[ MAX_NB_SUBFR ]; opus_int8 lastGainIndexPrev; } silk_encoder_control_FIX; /************************/ /* Encoder Super Struct */ /************************/ typedef struct { silk_encoder_state_FIX state_Fxx[ ENCODER_NUM_CHANNELS ]; stereo_enc_state sStereo; opus_int32 nBitsUsedLBRR; opus_int32 nBitsExceeded; opus_int nChannelsAPI; opus_int nChannelsInternal; opus_int nPrevChannelsInternal; opus_int timeSinceSwitchAllowed_ms; opus_int allowBandwidthSwitch; opus_int prev_decode_only_middle; } silk_encoder; #ifdef __cplusplus } #endif #endif jamulus-3.9.1+dfsg/libs/opus/silk/fixed/schur_FIX.c0000644000175000017500000001053714340334543021140 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FIX.h" /* Faster than schur64(), but much less accurate. */ /* uses SMLAWB(), requiring armv5E and higher. */ opus_int32 silk_schur( /* O Returns residual energy */ opus_int16 *rc_Q15, /* O reflection coefficients [order] Q15 */ const opus_int32 *c, /* I correlations [order+1] */ const opus_int32 order /* I prediction order */ ) { opus_int k, n, lz; opus_int32 C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ]; opus_int32 Ctmp1, Ctmp2, rc_tmp_Q15; celt_assert( order >= 0 && order <= SILK_MAX_ORDER_LPC ); /* Get number of leading zeros */ lz = silk_CLZ32( c[ 0 ] ); /* Copy correlations and adjust level to Q30 */ k = 0; if( lz < 2 ) { /* lz must be 1, so shift one to the right */ do { C[ k ][ 0 ] = C[ k ][ 1 ] = silk_RSHIFT( c[ k ], 1 ); } while( ++k <= order ); } else if( lz > 2 ) { /* Shift to the left */ lz -= 2; do { C[ k ][ 0 ] = C[ k ][ 1 ] = silk_LSHIFT( c[ k ], lz ); } while( ++k <= order ); } else { /* No need to shift */ do { C[ k ][ 0 ] = C[ k ][ 1 ] = c[ k ]; } while( ++k <= order ); } for( k = 0; k < order; k++ ) { /* Check that we won't be getting an unstable rc, otherwise stop here. */ if (silk_abs_int32(C[ k + 1 ][ 0 ]) >= C[ 0 ][ 1 ]) { if ( C[ k + 1 ][ 0 ] > 0 ) { rc_Q15[ k ] = -SILK_FIX_CONST( .99f, 15 ); } else { rc_Q15[ k ] = SILK_FIX_CONST( .99f, 15 ); } k++; break; } /* Get reflection coefficient */ rc_tmp_Q15 = -silk_DIV32_16( C[ k + 1 ][ 0 ], silk_max_32( silk_RSHIFT( C[ 0 ][ 1 ], 15 ), 1 ) ); /* Clip (shouldn't happen for properly conditioned inputs) */ rc_tmp_Q15 = silk_SAT16( rc_tmp_Q15 ); /* Store */ rc_Q15[ k ] = (opus_int16)rc_tmp_Q15; /* Update correlations */ for( n = 0; n < order - k; n++ ) { Ctmp1 = C[ n + k + 1 ][ 0 ]; Ctmp2 = C[ n ][ 1 ]; C[ n + k + 1 ][ 0 ] = silk_SMLAWB( Ctmp1, silk_LSHIFT( Ctmp2, 1 ), rc_tmp_Q15 ); C[ n ][ 1 ] = silk_SMLAWB( Ctmp2, silk_LSHIFT( Ctmp1, 1 ), rc_tmp_Q15 ); } } for(; k < order; k++ ) { rc_Q15[ k ] = 0; } /* return residual energy */ return silk_max_32( 1, C[ 0 ][ 1 ] ); } jamulus-3.9.1+dfsg/libs/opus/silk/fixed/LTP_analysis_filter_FIX.c0000644000175000017500000001117214340334543023717 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main_FIX.h" void silk_LTP_analysis_filter_FIX( opus_int16 *LTP_res, /* O LTP residual signal of length MAX_NB_SUBFR * ( pre_length + subfr_length ) */ const opus_int16 *x, /* I Pointer to input signal with at least max( pitchL ) preceding samples */ const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],/* I LTP_ORDER LTP coefficients for each MAX_NB_SUBFR subframe */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag, one for each subframe */ const opus_int32 invGains_Q16[ MAX_NB_SUBFR ], /* I Inverse quantization gains, one for each subframe */ const opus_int subfr_length, /* I Length of each subframe */ const opus_int nb_subfr, /* I Number of subframes */ const opus_int pre_length /* I Length of the preceding samples starting at &x[0] for each subframe */ ) { const opus_int16 *x_ptr, *x_lag_ptr; opus_int16 Btmp_Q14[ LTP_ORDER ]; opus_int16 *LTP_res_ptr; opus_int k, i; opus_int32 LTP_est; x_ptr = x; LTP_res_ptr = LTP_res; for( k = 0; k < nb_subfr; k++ ) { x_lag_ptr = x_ptr - pitchL[ k ]; Btmp_Q14[ 0 ] = LTPCoef_Q14[ k * LTP_ORDER ]; Btmp_Q14[ 1 ] = LTPCoef_Q14[ k * LTP_ORDER + 1 ]; Btmp_Q14[ 2 ] = LTPCoef_Q14[ k * LTP_ORDER + 2 ]; Btmp_Q14[ 3 ] = LTPCoef_Q14[ k * LTP_ORDER + 3 ]; Btmp_Q14[ 4 ] = LTPCoef_Q14[ k * LTP_ORDER + 4 ]; /* LTP analysis FIR filter */ for( i = 0; i < subfr_length + pre_length; i++ ) { LTP_res_ptr[ i ] = x_ptr[ i ]; /* Long-term prediction */ LTP_est = silk_SMULBB( x_lag_ptr[ LTP_ORDER / 2 ], Btmp_Q14[ 0 ] ); LTP_est = silk_SMLABB_ovflw( LTP_est, x_lag_ptr[ 1 ], Btmp_Q14[ 1 ] ); LTP_est = silk_SMLABB_ovflw( LTP_est, x_lag_ptr[ 0 ], Btmp_Q14[ 2 ] ); LTP_est = silk_SMLABB_ovflw( LTP_est, x_lag_ptr[ -1 ], Btmp_Q14[ 3 ] ); LTP_est = silk_SMLABB_ovflw( LTP_est, x_lag_ptr[ -2 ], Btmp_Q14[ 4 ] ); LTP_est = silk_RSHIFT_ROUND( LTP_est, 14 ); /* round and -> Q0*/ /* Subtract long-term prediction */ LTP_res_ptr[ i ] = (opus_int16)silk_SAT16( (opus_int32)x_ptr[ i ] - LTP_est ); /* Scale residual */ LTP_res_ptr[ i ] = silk_SMULWB( invGains_Q16[ k ], LTP_res_ptr[ i ] ); x_lag_ptr++; } /* Update pointers */ LTP_res_ptr += subfr_length + pre_length; x_ptr += subfr_length; } } jamulus-3.9.1+dfsg/libs/opus/silk/fixed/apply_sine_window_FIX.c0000644000175000017500000001147114340334543023544 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FIX.h" /* Apply sine window to signal vector. */ /* Window types: */ /* 1 -> sine window from 0 to pi/2 */ /* 2 -> sine window from pi/2 to pi */ /* Every other sample is linearly interpolated, for speed. */ /* Window length must be between 16 and 120 (incl) and a multiple of 4. */ /* Matlab code for table: for k=16:9*4:16+2*9*4, fprintf(' %7.d,', -round(65536*pi ./ (k:4:k+8*4))); fprintf('\n'); end */ static const opus_int16 freq_table_Q16[ 27 ] = { 12111, 9804, 8235, 7100, 6239, 5565, 5022, 4575, 4202, 3885, 3612, 3375, 3167, 2984, 2820, 2674, 2542, 2422, 2313, 2214, 2123, 2038, 1961, 1889, 1822, 1760, 1702, }; void silk_apply_sine_window( opus_int16 px_win[], /* O Pointer to windowed signal */ const opus_int16 px[], /* I Pointer to input signal */ const opus_int win_type, /* I Selects a window type */ const opus_int length /* I Window length, multiple of 4 */ ) { opus_int k, f_Q16, c_Q16; opus_int32 S0_Q16, S1_Q16; celt_assert( win_type == 1 || win_type == 2 ); /* Length must be in a range from 16 to 120 and a multiple of 4 */ celt_assert( length >= 16 && length <= 120 ); celt_assert( ( length & 3 ) == 0 ); /* Frequency */ k = ( length >> 2 ) - 4; celt_assert( k >= 0 && k <= 26 ); f_Q16 = (opus_int)freq_table_Q16[ k ]; /* Factor used for cosine approximation */ c_Q16 = silk_SMULWB( (opus_int32)f_Q16, -f_Q16 ); silk_assert( c_Q16 >= -32768 ); /* initialize state */ if( win_type == 1 ) { /* start from 0 */ S0_Q16 = 0; /* approximation of sin(f) */ S1_Q16 = f_Q16 + silk_RSHIFT( length, 3 ); } else { /* start from 1 */ S0_Q16 = ( (opus_int32)1 << 16 ); /* approximation of cos(f) */ S1_Q16 = ( (opus_int32)1 << 16 ) + silk_RSHIFT( c_Q16, 1 ) + silk_RSHIFT( length, 4 ); } /* Uses the recursive equation: sin(n*f) = 2 * cos(f) * sin((n-1)*f) - sin((n-2)*f) */ /* 4 samples at a time */ for( k = 0; k < length; k += 4 ) { px_win[ k ] = (opus_int16)silk_SMULWB( silk_RSHIFT( S0_Q16 + S1_Q16, 1 ), px[ k ] ); px_win[ k + 1 ] = (opus_int16)silk_SMULWB( S1_Q16, px[ k + 1] ); S0_Q16 = silk_SMULWB( S1_Q16, c_Q16 ) + silk_LSHIFT( S1_Q16, 1 ) - S0_Q16 + 1; S0_Q16 = silk_min( S0_Q16, ( (opus_int32)1 << 16 ) ); px_win[ k + 2 ] = (opus_int16)silk_SMULWB( silk_RSHIFT( S0_Q16 + S1_Q16, 1 ), px[ k + 2] ); px_win[ k + 3 ] = (opus_int16)silk_SMULWB( S0_Q16, px[ k + 3 ] ); S1_Q16 = silk_SMULWB( S0_Q16, c_Q16 ) + silk_LSHIFT( S0_Q16, 1 ) - S1_Q16; S1_Q16 = silk_min( S1_Q16, ( (opus_int32)1 << 16 ) ); } } jamulus-3.9.1+dfsg/libs/opus/silk/fixed/k2a_Q16_FIX.c0000644000175000017500000000507614340334543021122 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FIX.h" /* Step up function, converts reflection coefficients to prediction coefficients */ void silk_k2a_Q16( opus_int32 *A_Q24, /* O Prediction coefficients [order] Q24 */ const opus_int32 *rc_Q16, /* I Reflection coefficients [order] Q16 */ const opus_int32 order /* I Prediction order */ ) { opus_int k, n; opus_int32 rc, tmp1, tmp2; for( k = 0; k < order; k++ ) { rc = rc_Q16[ k ]; for( n = 0; n < (k + 1) >> 1; n++ ) { tmp1 = A_Q24[ n ]; tmp2 = A_Q24[ k - n - 1 ]; A_Q24[ n ] = silk_SMLAWW( tmp1, tmp2, rc ); A_Q24[ k - n - 1 ] = silk_SMLAWW( tmp2, tmp1, rc ); } A_Q24[ k ] = -silk_LSHIFT( rc, 8 ); } } jamulus-3.9.1+dfsg/libs/opus/silk/fixed/LTP_scale_ctrl_FIX.c0000644000175000017500000000547514340334543022653 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main_FIX.h" /* Calculation of LTP state scaling */ void silk_LTP_scale_ctrl_FIX( silk_encoder_state_FIX *psEnc, /* I/O encoder state */ silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ opus_int condCoding /* I The type of conditional coding to use */ ) { opus_int round_loss; if( condCoding == CODE_INDEPENDENTLY ) { /* Only scale if first frame in packet */ round_loss = psEnc->sCmn.PacketLoss_perc + psEnc->sCmn.nFramesPerPacket; psEnc->sCmn.indices.LTP_scaleIndex = (opus_int8)silk_LIMIT( silk_SMULWB( silk_SMULBB( round_loss, psEncCtrl->LTPredCodGain_Q7 ), SILK_FIX_CONST( 0.1, 9 ) ), 0, 2 ); } else { /* Default is minimum scaling */ psEnc->sCmn.indices.LTP_scaleIndex = 0; } psEncCtrl->LTP_scale_Q14 = silk_LTPScales_table_Q14[ psEnc->sCmn.indices.LTP_scaleIndex ]; } jamulus-3.9.1+dfsg/libs/opus/silk/fixed/find_pred_coefs_FIX.c0000644000175000017500000001656714340334543023136 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main_FIX.h" #include "stack_alloc.h" void silk_find_pred_coefs_FIX( silk_encoder_state_FIX *psEnc, /* I/O encoder state */ silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ const opus_int16 res_pitch[], /* I Residual from pitch analysis */ const opus_int16 x[], /* I Speech signal */ opus_int condCoding /* I The type of conditional coding to use */ ) { opus_int i; opus_int32 invGains_Q16[ MAX_NB_SUBFR ], local_gains[ MAX_NB_SUBFR ]; opus_int16 NLSF_Q15[ MAX_LPC_ORDER ]; const opus_int16 *x_ptr; opus_int16 *x_pre_ptr; VARDECL( opus_int16, LPC_in_pre ); opus_int32 min_gain_Q16, minInvGain_Q30; SAVE_STACK; /* weighting for weighted least squares */ min_gain_Q16 = silk_int32_MAX >> 6; for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { min_gain_Q16 = silk_min( min_gain_Q16, psEncCtrl->Gains_Q16[ i ] ); } for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { /* Divide to Q16 */ silk_assert( psEncCtrl->Gains_Q16[ i ] > 0 ); /* Invert and normalize gains, and ensure that maximum invGains_Q16 is within range of a 16 bit int */ invGains_Q16[ i ] = silk_DIV32_varQ( min_gain_Q16, psEncCtrl->Gains_Q16[ i ], 16 - 2 ); /* Limit inverse */ invGains_Q16[ i ] = silk_max( invGains_Q16[ i ], 100 ); /* Square the inverted gains */ silk_assert( invGains_Q16[ i ] == silk_SAT16( invGains_Q16[ i ] ) ); /* Invert the inverted and normalized gains */ local_gains[ i ] = silk_DIV32( ( (opus_int32)1 << 16 ), invGains_Q16[ i ] ); } ALLOC( LPC_in_pre, psEnc->sCmn.nb_subfr * psEnc->sCmn.predictLPCOrder + psEnc->sCmn.frame_length, opus_int16 ); if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { VARDECL( opus_int32, xXLTP_Q17 ); VARDECL( opus_int32, XXLTP_Q17 ); /**********/ /* VOICED */ /**********/ celt_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 ); ALLOC( xXLTP_Q17, psEnc->sCmn.nb_subfr * LTP_ORDER, opus_int32 ); ALLOC( XXLTP_Q17, psEnc->sCmn.nb_subfr * LTP_ORDER * LTP_ORDER, opus_int32 ); /* LTP analysis */ silk_find_LTP_FIX( XXLTP_Q17, xXLTP_Q17, res_pitch, psEncCtrl->pitchL, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.arch ); /* Quantize LTP gain parameters */ silk_quant_LTP_gains( psEncCtrl->LTPCoef_Q14, psEnc->sCmn.indices.LTPIndex, &psEnc->sCmn.indices.PERIndex, &psEnc->sCmn.sum_log_gain_Q7, &psEncCtrl->LTPredCodGain_Q7, XXLTP_Q17, xXLTP_Q17, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.arch ); /* Control LTP scaling */ silk_LTP_scale_ctrl_FIX( psEnc, psEncCtrl, condCoding ); /* Create LTP residual */ silk_LTP_analysis_filter_FIX( LPC_in_pre, x - psEnc->sCmn.predictLPCOrder, psEncCtrl->LTPCoef_Q14, psEncCtrl->pitchL, invGains_Q16, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder ); } else { /************/ /* UNVOICED */ /************/ /* Create signal with prepended subframes, scaled by inverse gains */ x_ptr = x - psEnc->sCmn.predictLPCOrder; x_pre_ptr = LPC_in_pre; for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { silk_scale_copy_vector16( x_pre_ptr, x_ptr, invGains_Q16[ i ], psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder ); x_pre_ptr += psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder; x_ptr += psEnc->sCmn.subfr_length; } silk_memset( psEncCtrl->LTPCoef_Q14, 0, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( opus_int16 ) ); psEncCtrl->LTPredCodGain_Q7 = 0; psEnc->sCmn.sum_log_gain_Q7 = 0; } /* Limit on total predictive coding gain */ if( psEnc->sCmn.first_frame_after_reset ) { minInvGain_Q30 = SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN_AFTER_RESET, 30 ); } else { minInvGain_Q30 = silk_log2lin( silk_SMLAWB( 16 << 7, (opus_int32)psEncCtrl->LTPredCodGain_Q7, SILK_FIX_CONST( 1.0 / 3, 16 ) ) ); /* Q16 */ minInvGain_Q30 = silk_DIV32_varQ( minInvGain_Q30, silk_SMULWW( SILK_FIX_CONST( MAX_PREDICTION_POWER_GAIN, 0 ), silk_SMLAWB( SILK_FIX_CONST( 0.25, 18 ), SILK_FIX_CONST( 0.75, 18 ), psEncCtrl->coding_quality_Q14 ) ), 14 ); } /* LPC_in_pre contains the LTP-filtered input for voiced, and the unfiltered input for unvoiced */ silk_find_LPC_FIX( &psEnc->sCmn, NLSF_Q15, LPC_in_pre, minInvGain_Q30 ); /* Quantize LSFs */ silk_process_NLSFs( &psEnc->sCmn, psEncCtrl->PredCoef_Q12, NLSF_Q15, psEnc->sCmn.prev_NLSFq_Q15 ); /* Calculate residual energy using quantized LPC coefficients */ silk_residual_energy_FIX( psEncCtrl->ResNrg, psEncCtrl->ResNrgQ, LPC_in_pre, psEncCtrl->PredCoef_Q12, local_gains, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder, psEnc->sCmn.arch ); /* Copy to prediction struct for use in next frame for interpolation */ silk_memcpy( psEnc->sCmn.prev_NLSFq_Q15, NLSF_Q15, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) ); RESTORE_STACK; } jamulus-3.9.1+dfsg/libs/opus/silk/fixed/regularize_correlations_FIX.c0000644000175000017500000000510214340334543024741 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main_FIX.h" /* Add noise to matrix diagonal */ void silk_regularize_correlations_FIX( opus_int32 *XX, /* I/O Correlation matrices */ opus_int32 *xx, /* I/O Correlation values */ opus_int32 noise, /* I Noise to add */ opus_int D /* I Dimension of XX */ ) { opus_int i; for( i = 0; i < D; i++ ) { matrix_ptr( &XX[ 0 ], i, i, D ) = silk_ADD32( matrix_ptr( &XX[ 0 ], i, i, D ), noise ); } xx[ 0 ] += noise; } jamulus-3.9.1+dfsg/libs/opus/silk/fixed/residual_energy16_FIX.c0000644000175000017500000001134514340334543023342 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main_FIX.h" /* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */ opus_int32 silk_residual_energy16_covar_FIX( const opus_int16 *c, /* I Prediction vector */ const opus_int32 *wXX, /* I Correlation matrix */ const opus_int32 *wXx, /* I Correlation vector */ opus_int32 wxx, /* I Signal energy */ opus_int D, /* I Dimension */ opus_int cQ /* I Q value for c vector 0 - 15 */ ) { opus_int i, j, lshifts, Qxtra; opus_int32 c_max, w_max, tmp, tmp2, nrg; opus_int cn[ MAX_MATRIX_SIZE ]; const opus_int32 *pRow; /* Safety checks */ celt_assert( D >= 0 ); celt_assert( D <= 16 ); celt_assert( cQ > 0 ); celt_assert( cQ < 16 ); lshifts = 16 - cQ; Qxtra = lshifts; c_max = 0; for( i = 0; i < D; i++ ) { c_max = silk_max_32( c_max, silk_abs( (opus_int32)c[ i ] ) ); } Qxtra = silk_min_int( Qxtra, silk_CLZ32( c_max ) - 17 ); w_max = silk_max_32( wXX[ 0 ], wXX[ D * D - 1 ] ); Qxtra = silk_min_int( Qxtra, silk_CLZ32( silk_MUL( D, silk_RSHIFT( silk_SMULWB( w_max, c_max ), 4 ) ) ) - 5 ); Qxtra = silk_max_int( Qxtra, 0 ); for( i = 0; i < D; i++ ) { cn[ i ] = silk_LSHIFT( ( opus_int )c[ i ], Qxtra ); silk_assert( silk_abs(cn[i]) <= ( silk_int16_MAX + 1 ) ); /* Check that silk_SMLAWB can be used */ } lshifts -= Qxtra; /* Compute wxx - 2 * wXx * c */ tmp = 0; for( i = 0; i < D; i++ ) { tmp = silk_SMLAWB( tmp, wXx[ i ], cn[ i ] ); } nrg = silk_RSHIFT( wxx, 1 + lshifts ) - tmp; /* Q: -lshifts - 1 */ /* Add c' * wXX * c, assuming wXX is symmetric */ tmp2 = 0; for( i = 0; i < D; i++ ) { tmp = 0; pRow = &wXX[ i * D ]; for( j = i + 1; j < D; j++ ) { tmp = silk_SMLAWB( tmp, pRow[ j ], cn[ j ] ); } tmp = silk_SMLAWB( tmp, silk_RSHIFT( pRow[ i ], 1 ), cn[ i ] ); tmp2 = silk_SMLAWB( tmp2, tmp, cn[ i ] ); } nrg = silk_ADD_LSHIFT32( nrg, tmp2, lshifts ); /* Q: -lshifts - 1 */ /* Keep one bit free always, because we add them for LSF interpolation */ if( nrg < 1 ) { nrg = 1; } else if( nrg > silk_RSHIFT( silk_int32_MAX, lshifts + 2 ) ) { nrg = silk_int32_MAX >> 1; } else { nrg = silk_LSHIFT( nrg, lshifts + 1 ); /* Q0 */ } return nrg; } jamulus-3.9.1+dfsg/libs/opus/silk/fixed/pitch_analysis_core_FIX.c0000644000175000017500000010305114340334543024030 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif /*********************************************************** * Pitch analyser function ********************************************************** */ #include "SigProc_FIX.h" #include "pitch_est_defines.h" #include "stack_alloc.h" #include "debug.h" #include "pitch.h" #define SCRATCH_SIZE 22 #define SF_LENGTH_4KHZ ( PE_SUBFR_LENGTH_MS * 4 ) #define SF_LENGTH_8KHZ ( PE_SUBFR_LENGTH_MS * 8 ) #define MIN_LAG_4KHZ ( PE_MIN_LAG_MS * 4 ) #define MIN_LAG_8KHZ ( PE_MIN_LAG_MS * 8 ) #define MAX_LAG_4KHZ ( PE_MAX_LAG_MS * 4 ) #define MAX_LAG_8KHZ ( PE_MAX_LAG_MS * 8 - 1 ) #define CSTRIDE_4KHZ ( MAX_LAG_4KHZ + 1 - MIN_LAG_4KHZ ) #define CSTRIDE_8KHZ ( MAX_LAG_8KHZ + 3 - ( MIN_LAG_8KHZ - 2 ) ) #define D_COMP_MIN ( MIN_LAG_8KHZ - 3 ) #define D_COMP_MAX ( MAX_LAG_8KHZ + 4 ) #define D_COMP_STRIDE ( D_COMP_MAX - D_COMP_MIN ) typedef opus_int32 silk_pe_stage3_vals[ PE_NB_STAGE3_LAGS ]; /************************************************************/ /* Internally used functions */ /************************************************************/ static void silk_P_Ana_calc_corr_st3( silk_pe_stage3_vals cross_corr_st3[], /* O 3 DIM correlation array */ const opus_int16 frame[], /* I vector to correlate */ opus_int start_lag, /* I lag offset to search around */ opus_int sf_length, /* I length of a 5 ms subframe */ opus_int nb_subfr, /* I number of subframes */ opus_int complexity, /* I Complexity setting */ int arch /* I Run-time architecture */ ); static void silk_P_Ana_calc_energy_st3( silk_pe_stage3_vals energies_st3[], /* O 3 DIM energy array */ const opus_int16 frame[], /* I vector to calc energy in */ opus_int start_lag, /* I lag offset to search around */ opus_int sf_length, /* I length of one 5 ms subframe */ opus_int nb_subfr, /* I number of subframes */ opus_int complexity, /* I Complexity setting */ int arch /* I Run-time architecture */ ); /*************************************************************/ /* FIXED POINT CORE PITCH ANALYSIS FUNCTION */ /*************************************************************/ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 voiced, 1 unvoiced */ const opus_int16 *frame_unscaled, /* I Signal of length PE_FRAME_LENGTH_MS*Fs_kHz */ opus_int *pitch_out, /* O 4 pitch lag values */ opus_int16 *lagIndex, /* O Lag Index */ opus_int8 *contourIndex, /* O Pitch contour Index */ opus_int *LTPCorr_Q15, /* I/O Normalized correlation; input: value from previous frame */ opus_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */ const opus_int32 search_thres1_Q16, /* I First stage threshold for lag candidates 0 - 1 */ const opus_int search_thres2_Q13, /* I Final threshold for lag candidates 0 - 1 */ const opus_int Fs_kHz, /* I Sample frequency (kHz) */ const opus_int complexity, /* I Complexity setting, 0-2, where 2 is highest */ const opus_int nb_subfr, /* I number of 5 ms subframes */ int arch /* I Run-time architecture */ ) { VARDECL( opus_int16, frame_8kHz_buf ); VARDECL( opus_int16, frame_4kHz ); VARDECL( opus_int16, frame_scaled ); opus_int32 filt_state[ 6 ]; const opus_int16 *frame, *frame_8kHz; opus_int i, k, d, j; VARDECL( opus_int16, C ); VARDECL( opus_int32, xcorr32 ); const opus_int16 *target_ptr, *basis_ptr; opus_int32 cross_corr, normalizer, energy, energy_basis, energy_target; opus_int d_srch[ PE_D_SRCH_LENGTH ], Cmax, length_d_srch, length_d_comp, shift; VARDECL( opus_int16, d_comp ); opus_int32 sum, threshold, lag_counter; opus_int CBimax, CBimax_new, CBimax_old, lag, start_lag, end_lag, lag_new; opus_int32 CC[ PE_NB_CBKS_STAGE2_EXT ], CCmax, CCmax_b, CCmax_new_b, CCmax_new; VARDECL( silk_pe_stage3_vals, energies_st3 ); VARDECL( silk_pe_stage3_vals, cross_corr_st3 ); opus_int frame_length, frame_length_8kHz, frame_length_4kHz; opus_int sf_length; opus_int min_lag; opus_int max_lag; opus_int32 contour_bias_Q15, diff; opus_int nb_cbk_search, cbk_size; opus_int32 delta_lag_log2_sqr_Q7, lag_log2_Q7, prevLag_log2_Q7, prev_lag_bias_Q13; const opus_int8 *Lag_CB_ptr; SAVE_STACK; /* Check for valid sampling frequency */ celt_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 ); /* Check for valid complexity setting */ celt_assert( complexity >= SILK_PE_MIN_COMPLEX ); celt_assert( complexity <= SILK_PE_MAX_COMPLEX ); silk_assert( search_thres1_Q16 >= 0 && search_thres1_Q16 <= (1<<16) ); silk_assert( search_thres2_Q13 >= 0 && search_thres2_Q13 <= (1<<13) ); /* Set up frame lengths max / min lag for the sampling frequency */ frame_length = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * Fs_kHz; frame_length_4kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 4; frame_length_8kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 8; sf_length = PE_SUBFR_LENGTH_MS * Fs_kHz; min_lag = PE_MIN_LAG_MS * Fs_kHz; max_lag = PE_MAX_LAG_MS * Fs_kHz - 1; /* Downscale input if necessary */ silk_sum_sqr_shift( &energy, &shift, frame_unscaled, frame_length ); shift += 3 - silk_CLZ32( energy ); /* at least two bits headroom */ ALLOC( frame_scaled, frame_length, opus_int16 ); if( shift > 0 ) { shift = silk_RSHIFT( shift + 1, 1 ); for( i = 0; i < frame_length; i++ ) { frame_scaled[ i ] = silk_RSHIFT( frame_unscaled[ i ], shift ); } frame = frame_scaled; } else { frame = frame_unscaled; } ALLOC( frame_8kHz_buf, ( Fs_kHz == 8 ) ? 1 : frame_length_8kHz, opus_int16 ); /* Resample from input sampled at Fs_kHz to 8 kHz */ if( Fs_kHz == 16 ) { silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) ); silk_resampler_down2( filt_state, frame_8kHz_buf, frame, frame_length ); frame_8kHz = frame_8kHz_buf; } else if( Fs_kHz == 12 ) { silk_memset( filt_state, 0, 6 * sizeof( opus_int32 ) ); silk_resampler_down2_3( filt_state, frame_8kHz_buf, frame, frame_length ); frame_8kHz = frame_8kHz_buf; } else { celt_assert( Fs_kHz == 8 ); frame_8kHz = frame; } /* Decimate again to 4 kHz */ silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) );/* Set state to zero */ ALLOC( frame_4kHz, frame_length_4kHz, opus_int16 ); silk_resampler_down2( filt_state, frame_4kHz, frame_8kHz, frame_length_8kHz ); /* Low-pass filter */ for( i = frame_length_4kHz - 1; i > 0; i-- ) { frame_4kHz[ i ] = silk_ADD_SAT16( frame_4kHz[ i ], frame_4kHz[ i - 1 ] ); } /****************************************************************************** * FIRST STAGE, operating in 4 khz ******************************************************************************/ ALLOC( C, nb_subfr * CSTRIDE_8KHZ, opus_int16 ); ALLOC( xcorr32, MAX_LAG_4KHZ-MIN_LAG_4KHZ+1, opus_int32 ); silk_memset( C, 0, (nb_subfr >> 1) * CSTRIDE_4KHZ * sizeof( opus_int16 ) ); target_ptr = &frame_4kHz[ silk_LSHIFT( SF_LENGTH_4KHZ, 2 ) ]; for( k = 0; k < nb_subfr >> 1; k++ ) { /* Check that we are within range of the array */ celt_assert( target_ptr >= frame_4kHz ); celt_assert( target_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz ); basis_ptr = target_ptr - MIN_LAG_4KHZ; /* Check that we are within range of the array */ celt_assert( basis_ptr >= frame_4kHz ); celt_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz ); celt_pitch_xcorr( target_ptr, target_ptr - MAX_LAG_4KHZ, xcorr32, SF_LENGTH_8KHZ, MAX_LAG_4KHZ - MIN_LAG_4KHZ + 1, arch ); /* Calculate first vector products before loop */ cross_corr = xcorr32[ MAX_LAG_4KHZ - MIN_LAG_4KHZ ]; normalizer = silk_inner_prod_aligned( target_ptr, target_ptr, SF_LENGTH_8KHZ, arch ); normalizer = silk_ADD32( normalizer, silk_inner_prod_aligned( basis_ptr, basis_ptr, SF_LENGTH_8KHZ, arch ) ); normalizer = silk_ADD32( normalizer, silk_SMULBB( SF_LENGTH_8KHZ, 4000 ) ); matrix_ptr( C, k, 0, CSTRIDE_4KHZ ) = (opus_int16)silk_DIV32_varQ( cross_corr, normalizer, 13 + 1 ); /* Q13 */ /* From now on normalizer is computed recursively */ for( d = MIN_LAG_4KHZ + 1; d <= MAX_LAG_4KHZ; d++ ) { basis_ptr--; /* Check that we are within range of the array */ silk_assert( basis_ptr >= frame_4kHz ); silk_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz ); cross_corr = xcorr32[ MAX_LAG_4KHZ - d ]; /* Add contribution of new sample and remove contribution from oldest sample */ normalizer = silk_ADD32( normalizer, silk_SMULBB( basis_ptr[ 0 ], basis_ptr[ 0 ] ) - silk_SMULBB( basis_ptr[ SF_LENGTH_8KHZ ], basis_ptr[ SF_LENGTH_8KHZ ] ) ); matrix_ptr( C, k, d - MIN_LAG_4KHZ, CSTRIDE_4KHZ) = (opus_int16)silk_DIV32_varQ( cross_corr, normalizer, 13 + 1 ); /* Q13 */ } /* Update target pointer */ target_ptr += SF_LENGTH_8KHZ; } /* Combine two subframes into single correlation measure and apply short-lag bias */ if( nb_subfr == PE_MAX_NB_SUBFR ) { for( i = MAX_LAG_4KHZ; i >= MIN_LAG_4KHZ; i-- ) { sum = (opus_int32)matrix_ptr( C, 0, i - MIN_LAG_4KHZ, CSTRIDE_4KHZ ) + (opus_int32)matrix_ptr( C, 1, i - MIN_LAG_4KHZ, CSTRIDE_4KHZ ); /* Q14 */ sum = silk_SMLAWB( sum, sum, silk_LSHIFT( -i, 4 ) ); /* Q14 */ C[ i - MIN_LAG_4KHZ ] = (opus_int16)sum; /* Q14 */ } } else { /* Only short-lag bias */ for( i = MAX_LAG_4KHZ; i >= MIN_LAG_4KHZ; i-- ) { sum = silk_LSHIFT( (opus_int32)C[ i - MIN_LAG_4KHZ ], 1 ); /* Q14 */ sum = silk_SMLAWB( sum, sum, silk_LSHIFT( -i, 4 ) ); /* Q14 */ C[ i - MIN_LAG_4KHZ ] = (opus_int16)sum; /* Q14 */ } } /* Sort */ length_d_srch = silk_ADD_LSHIFT32( 4, complexity, 1 ); celt_assert( 3 * length_d_srch <= PE_D_SRCH_LENGTH ); silk_insertion_sort_decreasing_int16( C, d_srch, CSTRIDE_4KHZ, length_d_srch ); /* Escape if correlation is very low already here */ Cmax = (opus_int)C[ 0 ]; /* Q14 */ if( Cmax < SILK_FIX_CONST( 0.2, 14 ) ) { silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) ); *LTPCorr_Q15 = 0; *lagIndex = 0; *contourIndex = 0; RESTORE_STACK; return 1; } threshold = silk_SMULWB( search_thres1_Q16, Cmax ); for( i = 0; i < length_d_srch; i++ ) { /* Convert to 8 kHz indices for the sorted correlation that exceeds the threshold */ if( C[ i ] > threshold ) { d_srch[ i ] = silk_LSHIFT( d_srch[ i ] + MIN_LAG_4KHZ, 1 ); } else { length_d_srch = i; break; } } celt_assert( length_d_srch > 0 ); ALLOC( d_comp, D_COMP_STRIDE, opus_int16 ); for( i = D_COMP_MIN; i < D_COMP_MAX; i++ ) { d_comp[ i - D_COMP_MIN ] = 0; } for( i = 0; i < length_d_srch; i++ ) { d_comp[ d_srch[ i ] - D_COMP_MIN ] = 1; } /* Convolution */ for( i = D_COMP_MAX - 1; i >= MIN_LAG_8KHZ; i-- ) { d_comp[ i - D_COMP_MIN ] += d_comp[ i - 1 - D_COMP_MIN ] + d_comp[ i - 2 - D_COMP_MIN ]; } length_d_srch = 0; for( i = MIN_LAG_8KHZ; i < MAX_LAG_8KHZ + 1; i++ ) { if( d_comp[ i + 1 - D_COMP_MIN ] > 0 ) { d_srch[ length_d_srch ] = i; length_d_srch++; } } /* Convolution */ for( i = D_COMP_MAX - 1; i >= MIN_LAG_8KHZ; i-- ) { d_comp[ i - D_COMP_MIN ] += d_comp[ i - 1 - D_COMP_MIN ] + d_comp[ i - 2 - D_COMP_MIN ] + d_comp[ i - 3 - D_COMP_MIN ]; } length_d_comp = 0; for( i = MIN_LAG_8KHZ; i < D_COMP_MAX; i++ ) { if( d_comp[ i - D_COMP_MIN ] > 0 ) { d_comp[ length_d_comp ] = i - 2; length_d_comp++; } } /********************************************************************************** ** SECOND STAGE, operating at 8 kHz, on lag sections with high correlation *************************************************************************************/ /********************************************************************************* * Find energy of each subframe projected onto its history, for a range of delays *********************************************************************************/ silk_memset( C, 0, nb_subfr * CSTRIDE_8KHZ * sizeof( opus_int16 ) ); target_ptr = &frame_8kHz[ PE_LTP_MEM_LENGTH_MS * 8 ]; for( k = 0; k < nb_subfr; k++ ) { /* Check that we are within range of the array */ celt_assert( target_ptr >= frame_8kHz ); celt_assert( target_ptr + SF_LENGTH_8KHZ <= frame_8kHz + frame_length_8kHz ); energy_target = silk_ADD32( silk_inner_prod_aligned( target_ptr, target_ptr, SF_LENGTH_8KHZ, arch ), 1 ); for( j = 0; j < length_d_comp; j++ ) { d = d_comp[ j ]; basis_ptr = target_ptr - d; /* Check that we are within range of the array */ silk_assert( basis_ptr >= frame_8kHz ); silk_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_8kHz + frame_length_8kHz ); cross_corr = silk_inner_prod_aligned( target_ptr, basis_ptr, SF_LENGTH_8KHZ, arch ); if( cross_corr > 0 ) { energy_basis = silk_inner_prod_aligned( basis_ptr, basis_ptr, SF_LENGTH_8KHZ, arch ); matrix_ptr( C, k, d - ( MIN_LAG_8KHZ - 2 ), CSTRIDE_8KHZ ) = (opus_int16)silk_DIV32_varQ( cross_corr, silk_ADD32( energy_target, energy_basis ), 13 + 1 ); /* Q13 */ } else { matrix_ptr( C, k, d - ( MIN_LAG_8KHZ - 2 ), CSTRIDE_8KHZ ) = 0; } } target_ptr += SF_LENGTH_8KHZ; } /* search over lag range and lags codebook */ /* scale factor for lag codebook, as a function of center lag */ CCmax = silk_int32_MIN; CCmax_b = silk_int32_MIN; CBimax = 0; /* To avoid returning undefined lag values */ lag = -1; /* To check if lag with strong enough correlation has been found */ if( prevLag > 0 ) { if( Fs_kHz == 12 ) { prevLag = silk_DIV32_16( silk_LSHIFT( prevLag, 1 ), 3 ); } else if( Fs_kHz == 16 ) { prevLag = silk_RSHIFT( prevLag, 1 ); } prevLag_log2_Q7 = silk_lin2log( (opus_int32)prevLag ); } else { prevLag_log2_Q7 = 0; } silk_assert( search_thres2_Q13 == silk_SAT16( search_thres2_Q13 ) ); /* Set up stage 2 codebook based on number of subframes */ if( nb_subfr == PE_MAX_NB_SUBFR ) { cbk_size = PE_NB_CBKS_STAGE2_EXT; Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ]; if( Fs_kHz == 8 && complexity > SILK_PE_MIN_COMPLEX ) { /* If input is 8 khz use a larger codebook here because it is last stage */ nb_cbk_search = PE_NB_CBKS_STAGE2_EXT; } else { nb_cbk_search = PE_NB_CBKS_STAGE2; } } else { cbk_size = PE_NB_CBKS_STAGE2_10MS; Lag_CB_ptr = &silk_CB_lags_stage2_10_ms[ 0 ][ 0 ]; nb_cbk_search = PE_NB_CBKS_STAGE2_10MS; } for( k = 0; k < length_d_srch; k++ ) { d = d_srch[ k ]; for( j = 0; j < nb_cbk_search; j++ ) { CC[ j ] = 0; for( i = 0; i < nb_subfr; i++ ) { opus_int d_subfr; /* Try all codebooks */ d_subfr = d + matrix_ptr( Lag_CB_ptr, i, j, cbk_size ); CC[ j ] = CC[ j ] + (opus_int32)matrix_ptr( C, i, d_subfr - ( MIN_LAG_8KHZ - 2 ), CSTRIDE_8KHZ ); } } /* Find best codebook */ CCmax_new = silk_int32_MIN; CBimax_new = 0; for( i = 0; i < nb_cbk_search; i++ ) { if( CC[ i ] > CCmax_new ) { CCmax_new = CC[ i ]; CBimax_new = i; } } /* Bias towards shorter lags */ lag_log2_Q7 = silk_lin2log( d ); /* Q7 */ silk_assert( lag_log2_Q7 == silk_SAT16( lag_log2_Q7 ) ); silk_assert( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 13 ) == silk_SAT16( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 13 ) ) ); CCmax_new_b = CCmax_new - silk_RSHIFT( silk_SMULBB( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 13 ), lag_log2_Q7 ), 7 ); /* Q13 */ /* Bias towards previous lag */ silk_assert( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 13 ) == silk_SAT16( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 13 ) ) ); if( prevLag > 0 ) { delta_lag_log2_sqr_Q7 = lag_log2_Q7 - prevLag_log2_Q7; silk_assert( delta_lag_log2_sqr_Q7 == silk_SAT16( delta_lag_log2_sqr_Q7 ) ); delta_lag_log2_sqr_Q7 = silk_RSHIFT( silk_SMULBB( delta_lag_log2_sqr_Q7, delta_lag_log2_sqr_Q7 ), 7 ); prev_lag_bias_Q13 = silk_RSHIFT( silk_SMULBB( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 13 ), *LTPCorr_Q15 ), 15 ); /* Q13 */ prev_lag_bias_Q13 = silk_DIV32( silk_MUL( prev_lag_bias_Q13, delta_lag_log2_sqr_Q7 ), delta_lag_log2_sqr_Q7 + SILK_FIX_CONST( 0.5, 7 ) ); CCmax_new_b -= prev_lag_bias_Q13; /* Q13 */ } if( CCmax_new_b > CCmax_b && /* Find maximum biased correlation */ CCmax_new > silk_SMULBB( nb_subfr, search_thres2_Q13 ) && /* Correlation needs to be high enough to be voiced */ silk_CB_lags_stage2[ 0 ][ CBimax_new ] <= MIN_LAG_8KHZ /* Lag must be in range */ ) { CCmax_b = CCmax_new_b; CCmax = CCmax_new; lag = d; CBimax = CBimax_new; } } if( lag == -1 ) { /* No suitable candidate found */ silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) ); *LTPCorr_Q15 = 0; *lagIndex = 0; *contourIndex = 0; RESTORE_STACK; return 1; } /* Output normalized correlation */ *LTPCorr_Q15 = (opus_int)silk_LSHIFT( silk_DIV32_16( CCmax, nb_subfr ), 2 ); silk_assert( *LTPCorr_Q15 >= 0 ); if( Fs_kHz > 8 ) { /* Search in original signal */ CBimax_old = CBimax; /* Compensate for decimation */ silk_assert( lag == silk_SAT16( lag ) ); if( Fs_kHz == 12 ) { lag = silk_RSHIFT( silk_SMULBB( lag, 3 ), 1 ); } else if( Fs_kHz == 16 ) { lag = silk_LSHIFT( lag, 1 ); } else { lag = silk_SMULBB( lag, 3 ); } lag = silk_LIMIT_int( lag, min_lag, max_lag ); start_lag = silk_max_int( lag - 2, min_lag ); end_lag = silk_min_int( lag + 2, max_lag ); lag_new = lag; /* to avoid undefined lag */ CBimax = 0; /* to avoid undefined lag */ CCmax = silk_int32_MIN; /* pitch lags according to second stage */ for( k = 0; k < nb_subfr; k++ ) { pitch_out[ k ] = lag + 2 * silk_CB_lags_stage2[ k ][ CBimax_old ]; } /* Set up codebook parameters according to complexity setting and frame length */ if( nb_subfr == PE_MAX_NB_SUBFR ) { nb_cbk_search = (opus_int)silk_nb_cbk_searchs_stage3[ complexity ]; cbk_size = PE_NB_CBKS_STAGE3_MAX; Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ]; } else { nb_cbk_search = PE_NB_CBKS_STAGE3_10MS; cbk_size = PE_NB_CBKS_STAGE3_10MS; Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; } /* Calculate the correlations and energies needed in stage 3 */ ALLOC( energies_st3, nb_subfr * nb_cbk_search, silk_pe_stage3_vals ); ALLOC( cross_corr_st3, nb_subfr * nb_cbk_search, silk_pe_stage3_vals ); silk_P_Ana_calc_corr_st3( cross_corr_st3, frame, start_lag, sf_length, nb_subfr, complexity, arch ); silk_P_Ana_calc_energy_st3( energies_st3, frame, start_lag, sf_length, nb_subfr, complexity, arch ); lag_counter = 0; silk_assert( lag == silk_SAT16( lag ) ); contour_bias_Q15 = silk_DIV32_16( SILK_FIX_CONST( PE_FLATCONTOUR_BIAS, 15 ), lag ); target_ptr = &frame[ PE_LTP_MEM_LENGTH_MS * Fs_kHz ]; energy_target = silk_ADD32( silk_inner_prod_aligned( target_ptr, target_ptr, nb_subfr * sf_length, arch ), 1 ); for( d = start_lag; d <= end_lag; d++ ) { for( j = 0; j < nb_cbk_search; j++ ) { cross_corr = 0; energy = energy_target; for( k = 0; k < nb_subfr; k++ ) { cross_corr = silk_ADD32( cross_corr, matrix_ptr( cross_corr_st3, k, j, nb_cbk_search )[ lag_counter ] ); energy = silk_ADD32( energy, matrix_ptr( energies_st3, k, j, nb_cbk_search )[ lag_counter ] ); silk_assert( energy >= 0 ); } if( cross_corr > 0 ) { CCmax_new = silk_DIV32_varQ( cross_corr, energy, 13 + 1 ); /* Q13 */ /* Reduce depending on flatness of contour */ diff = silk_int16_MAX - silk_MUL( contour_bias_Q15, j ); /* Q15 */ silk_assert( diff == silk_SAT16( diff ) ); CCmax_new = silk_SMULWB( CCmax_new, diff ); /* Q14 */ } else { CCmax_new = 0; } if( CCmax_new > CCmax && ( d + silk_CB_lags_stage3[ 0 ][ j ] ) <= max_lag ) { CCmax = CCmax_new; lag_new = d; CBimax = j; } } lag_counter++; } for( k = 0; k < nb_subfr; k++ ) { pitch_out[ k ] = lag_new + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size ); pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag, PE_MAX_LAG_MS * Fs_kHz ); } *lagIndex = (opus_int16)( lag_new - min_lag); *contourIndex = (opus_int8)CBimax; } else { /* Fs_kHz == 8 */ /* Save Lags */ for( k = 0; k < nb_subfr; k++ ) { pitch_out[ k ] = lag + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size ); pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], MIN_LAG_8KHZ, PE_MAX_LAG_MS * 8 ); } *lagIndex = (opus_int16)( lag - MIN_LAG_8KHZ ); *contourIndex = (opus_int8)CBimax; } celt_assert( *lagIndex >= 0 ); /* return as voiced */ RESTORE_STACK; return 0; } /*********************************************************************** * Calculates the correlations used in stage 3 search. In order to cover * the whole lag codebook for all the searched offset lags (lag +- 2), * the following correlations are needed in each sub frame: * * sf1: lag range [-8,...,7] total 16 correlations * sf2: lag range [-4,...,4] total 9 correlations * sf3: lag range [-3,....4] total 8 correltions * sf4: lag range [-6,....8] total 15 correlations * * In total 48 correlations. The direct implementation computed in worst * case 4*12*5 = 240 correlations, but more likely around 120. ***********************************************************************/ static void silk_P_Ana_calc_corr_st3( silk_pe_stage3_vals cross_corr_st3[], /* O 3 DIM correlation array */ const opus_int16 frame[], /* I vector to correlate */ opus_int start_lag, /* I lag offset to search around */ opus_int sf_length, /* I length of a 5 ms subframe */ opus_int nb_subfr, /* I number of subframes */ opus_int complexity, /* I Complexity setting */ int arch /* I Run-time architecture */ ) { const opus_int16 *target_ptr; opus_int i, j, k, lag_counter, lag_low, lag_high; opus_int nb_cbk_search, delta, idx, cbk_size; VARDECL( opus_int32, scratch_mem ); VARDECL( opus_int32, xcorr32 ); const opus_int8 *Lag_range_ptr, *Lag_CB_ptr; SAVE_STACK; celt_assert( complexity >= SILK_PE_MIN_COMPLEX ); celt_assert( complexity <= SILK_PE_MAX_COMPLEX ); if( nb_subfr == PE_MAX_NB_SUBFR ) { Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ]; Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ]; nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ]; cbk_size = PE_NB_CBKS_STAGE3_MAX; } else { celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1); Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ]; Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; nb_cbk_search = PE_NB_CBKS_STAGE3_10MS; cbk_size = PE_NB_CBKS_STAGE3_10MS; } ALLOC( scratch_mem, SCRATCH_SIZE, opus_int32 ); ALLOC( xcorr32, SCRATCH_SIZE, opus_int32 ); target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ]; /* Pointer to middle of frame */ for( k = 0; k < nb_subfr; k++ ) { lag_counter = 0; /* Calculate the correlations for each subframe */ lag_low = matrix_ptr( Lag_range_ptr, k, 0, 2 ); lag_high = matrix_ptr( Lag_range_ptr, k, 1, 2 ); celt_assert(lag_high-lag_low+1 <= SCRATCH_SIZE); celt_pitch_xcorr( target_ptr, target_ptr - start_lag - lag_high, xcorr32, sf_length, lag_high - lag_low + 1, arch ); for( j = lag_low; j <= lag_high; j++ ) { silk_assert( lag_counter < SCRATCH_SIZE ); scratch_mem[ lag_counter ] = xcorr32[ lag_high - j ]; lag_counter++; } delta = matrix_ptr( Lag_range_ptr, k, 0, 2 ); for( i = 0; i < nb_cbk_search; i++ ) { /* Fill out the 3 dim array that stores the correlations for */ /* each code_book vector for each start lag */ idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta; for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) { silk_assert( idx + j < SCRATCH_SIZE ); silk_assert( idx + j < lag_counter ); matrix_ptr( cross_corr_st3, k, i, nb_cbk_search )[ j ] = scratch_mem[ idx + j ]; } } target_ptr += sf_length; } RESTORE_STACK; } /********************************************************************/ /* Calculate the energies for first two subframes. The energies are */ /* calculated recursively. */ /********************************************************************/ static void silk_P_Ana_calc_energy_st3( silk_pe_stage3_vals energies_st3[], /* O 3 DIM energy array */ const opus_int16 frame[], /* I vector to calc energy in */ opus_int start_lag, /* I lag offset to search around */ opus_int sf_length, /* I length of one 5 ms subframe */ opus_int nb_subfr, /* I number of subframes */ opus_int complexity, /* I Complexity setting */ int arch /* I Run-time architecture */ ) { const opus_int16 *target_ptr, *basis_ptr; opus_int32 energy; opus_int k, i, j, lag_counter; opus_int nb_cbk_search, delta, idx, cbk_size, lag_diff; VARDECL( opus_int32, scratch_mem ); const opus_int8 *Lag_range_ptr, *Lag_CB_ptr; SAVE_STACK; celt_assert( complexity >= SILK_PE_MIN_COMPLEX ); celt_assert( complexity <= SILK_PE_MAX_COMPLEX ); if( nb_subfr == PE_MAX_NB_SUBFR ) { Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ]; Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ]; nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ]; cbk_size = PE_NB_CBKS_STAGE3_MAX; } else { celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1); Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ]; Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; nb_cbk_search = PE_NB_CBKS_STAGE3_10MS; cbk_size = PE_NB_CBKS_STAGE3_10MS; } ALLOC( scratch_mem, SCRATCH_SIZE, opus_int32 ); target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ]; for( k = 0; k < nb_subfr; k++ ) { lag_counter = 0; /* Calculate the energy for first lag */ basis_ptr = target_ptr - ( start_lag + matrix_ptr( Lag_range_ptr, k, 0, 2 ) ); energy = silk_inner_prod_aligned( basis_ptr, basis_ptr, sf_length, arch ); silk_assert( energy >= 0 ); scratch_mem[ lag_counter ] = energy; lag_counter++; lag_diff = ( matrix_ptr( Lag_range_ptr, k, 1, 2 ) - matrix_ptr( Lag_range_ptr, k, 0, 2 ) + 1 ); for( i = 1; i < lag_diff; i++ ) { /* remove part outside new window */ energy -= silk_SMULBB( basis_ptr[ sf_length - i ], basis_ptr[ sf_length - i ] ); silk_assert( energy >= 0 ); /* add part that comes into window */ energy = silk_ADD_SAT32( energy, silk_SMULBB( basis_ptr[ -i ], basis_ptr[ -i ] ) ); silk_assert( energy >= 0 ); silk_assert( lag_counter < SCRATCH_SIZE ); scratch_mem[ lag_counter ] = energy; lag_counter++; } delta = matrix_ptr( Lag_range_ptr, k, 0, 2 ); for( i = 0; i < nb_cbk_search; i++ ) { /* Fill out the 3 dim array that stores the correlations for */ /* each code_book vector for each start lag */ idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta; for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) { silk_assert( idx + j < SCRATCH_SIZE ); silk_assert( idx + j < lag_counter ); matrix_ptr( energies_st3, k, i, nb_cbk_search )[ j ] = scratch_mem[ idx + j ]; silk_assert( matrix_ptr( energies_st3, k, i, nb_cbk_search )[ j ] >= 0 ); } } target_ptr += sf_length; } RESTORE_STACK; } jamulus-3.9.1+dfsg/libs/opus/silk/fixed/corrMatrix_FIX.c0000644000175000017500000002021714340334543022142 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif /********************************************************************** * Correlation Matrix Computations for LS estimate. **********************************************************************/ #include "main_FIX.h" /* Calculates correlation vector X'*t */ void silk_corrVector_FIX( const opus_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */ const opus_int16 *t, /* I Target vector [L] */ const opus_int L, /* I Length of vectors */ const opus_int order, /* I Max lag for correlation */ opus_int32 *Xt, /* O Pointer to X'*t correlation vector [order] */ const opus_int rshifts, /* I Right shifts of correlations */ int arch /* I Run-time architecture */ ) { opus_int lag, i; const opus_int16 *ptr1, *ptr2; opus_int32 inner_prod; ptr1 = &x[ order - 1 ]; /* Points to first sample of column 0 of X: X[:,0] */ ptr2 = t; /* Calculate X'*t */ if( rshifts > 0 ) { /* Right shifting used */ for( lag = 0; lag < order; lag++ ) { inner_prod = 0; for( i = 0; i < L; i++ ) { inner_prod = silk_ADD_RSHIFT32( inner_prod, silk_SMULBB( ptr1[ i ], ptr2[i] ), rshifts ); } Xt[ lag ] = inner_prod; /* X[:,lag]'*t */ ptr1--; /* Go to next column of X */ } } else { silk_assert( rshifts == 0 ); for( lag = 0; lag < order; lag++ ) { Xt[ lag ] = silk_inner_prod_aligned( ptr1, ptr2, L, arch ); /* X[:,lag]'*t */ ptr1--; /* Go to next column of X */ } } } /* Calculates correlation matrix X'*X */ void silk_corrMatrix_FIX( const opus_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */ const opus_int L, /* I Length of vectors */ const opus_int order, /* I Max lag for correlation */ opus_int32 *XX, /* O Pointer to X'*X correlation matrix [ order x order ] */ opus_int32 *nrg, /* O Energy of x vector */ opus_int *rshifts, /* O Right shifts of correlations and energy */ int arch /* I Run-time architecture */ ) { opus_int i, j, lag; opus_int32 energy; const opus_int16 *ptr1, *ptr2; /* Calculate energy to find shift used to fit in 32 bits */ silk_sum_sqr_shift( nrg, rshifts, x, L + order - 1 ); energy = *nrg; /* Calculate energy of first column (0) of X: X[:,0]'*X[:,0] */ /* Remove contribution of first order - 1 samples */ for( i = 0; i < order - 1; i++ ) { energy -= silk_RSHIFT32( silk_SMULBB( x[ i ], x[ i ] ), *rshifts ); } /* Calculate energy of remaining columns of X: X[:,j]'*X[:,j] */ /* Fill out the diagonal of the correlation matrix */ matrix_ptr( XX, 0, 0, order ) = energy; silk_assert( energy >= 0 ); ptr1 = &x[ order - 1 ]; /* First sample of column 0 of X */ for( j = 1; j < order; j++ ) { energy = silk_SUB32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ L - j ], ptr1[ L - j ] ), *rshifts ) ); energy = silk_ADD32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ -j ], ptr1[ -j ] ), *rshifts ) ); matrix_ptr( XX, j, j, order ) = energy; silk_assert( energy >= 0 ); } ptr2 = &x[ order - 2 ]; /* First sample of column 1 of X */ /* Calculate the remaining elements of the correlation matrix */ if( *rshifts > 0 ) { /* Right shifting used */ for( lag = 1; lag < order; lag++ ) { /* Inner product of column 0 and column lag: X[:,0]'*X[:,lag] */ energy = 0; for( i = 0; i < L; i++ ) { energy += silk_RSHIFT32( silk_SMULBB( ptr1[ i ], ptr2[i] ), *rshifts ); } /* Calculate remaining off diagonal: X[:,j]'*X[:,j + lag] */ matrix_ptr( XX, lag, 0, order ) = energy; matrix_ptr( XX, 0, lag, order ) = energy; for( j = 1; j < ( order - lag ); j++ ) { energy = silk_SUB32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ), *rshifts ) ); energy = silk_ADD32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ -j ], ptr2[ -j ] ), *rshifts ) ); matrix_ptr( XX, lag + j, j, order ) = energy; matrix_ptr( XX, j, lag + j, order ) = energy; } ptr2--; /* Update pointer to first sample of next column (lag) in X */ } } else { for( lag = 1; lag < order; lag++ ) { /* Inner product of column 0 and column lag: X[:,0]'*X[:,lag] */ energy = silk_inner_prod_aligned( ptr1, ptr2, L, arch ); matrix_ptr( XX, lag, 0, order ) = energy; matrix_ptr( XX, 0, lag, order ) = energy; /* Calculate remaining off diagonal: X[:,j]'*X[:,j + lag] */ for( j = 1; j < ( order - lag ); j++ ) { energy = silk_SUB32( energy, silk_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ) ); energy = silk_SMLABB( energy, ptr1[ -j ], ptr2[ -j ] ); matrix_ptr( XX, lag + j, j, order ) = energy; matrix_ptr( XX, j, lag + j, order ) = energy; } ptr2--;/* Update pointer to first sample of next column (lag) in X */ } } } jamulus-3.9.1+dfsg/libs/opus/silk/fixed/residual_energy_FIX.c0000644000175000017500000001241514340334543023172 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main_FIX.h" #include "stack_alloc.h" /* Calculates residual energies of input subframes where all subframes have LPC_order */ /* of preceding samples */ void silk_residual_energy_FIX( opus_int32 nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */ opus_int nrgsQ[ MAX_NB_SUBFR ], /* O Q value per subframe */ const opus_int16 x[], /* I Input signal */ opus_int16 a_Q12[ 2 ][ MAX_LPC_ORDER ], /* I AR coefs for each frame half */ const opus_int32 gains[ MAX_NB_SUBFR ], /* I Quantization gains */ const opus_int subfr_length, /* I Subframe length */ const opus_int nb_subfr, /* I Number of subframes */ const opus_int LPC_order, /* I LPC order */ int arch /* I Run-time architecture */ ) { opus_int offset, i, j, rshift, lz1, lz2; opus_int16 *LPC_res_ptr; VARDECL( opus_int16, LPC_res ); const opus_int16 *x_ptr; opus_int32 tmp32; SAVE_STACK; x_ptr = x; offset = LPC_order + subfr_length; /* Filter input to create the LPC residual for each frame half, and measure subframe energies */ ALLOC( LPC_res, ( MAX_NB_SUBFR >> 1 ) * offset, opus_int16 ); celt_assert( ( nb_subfr >> 1 ) * ( MAX_NB_SUBFR >> 1 ) == nb_subfr ); for( i = 0; i < nb_subfr >> 1; i++ ) { /* Calculate half frame LPC residual signal including preceding samples */ silk_LPC_analysis_filter( LPC_res, x_ptr, a_Q12[ i ], ( MAX_NB_SUBFR >> 1 ) * offset, LPC_order, arch ); /* Point to first subframe of the just calculated LPC residual signal */ LPC_res_ptr = LPC_res + LPC_order; for( j = 0; j < ( MAX_NB_SUBFR >> 1 ); j++ ) { /* Measure subframe energy */ silk_sum_sqr_shift( &nrgs[ i * ( MAX_NB_SUBFR >> 1 ) + j ], &rshift, LPC_res_ptr, subfr_length ); /* Set Q values for the measured energy */ nrgsQ[ i * ( MAX_NB_SUBFR >> 1 ) + j ] = -rshift; /* Move to next subframe */ LPC_res_ptr += offset; } /* Move to next frame half */ x_ptr += ( MAX_NB_SUBFR >> 1 ) * offset; } /* Apply the squared subframe gains */ for( i = 0; i < nb_subfr; i++ ) { /* Fully upscale gains and energies */ lz1 = silk_CLZ32( nrgs[ i ] ) - 1; lz2 = silk_CLZ32( gains[ i ] ) - 1; tmp32 = silk_LSHIFT32( gains[ i ], lz2 ); /* Find squared gains */ tmp32 = silk_SMMUL( tmp32, tmp32 ); /* Q( 2 * lz2 - 32 )*/ /* Scale energies */ nrgs[ i ] = silk_SMMUL( tmp32, silk_LSHIFT32( nrgs[ i ], lz1 ) ); /* Q( nrgsQ[ i ] + lz1 + 2 * lz2 - 32 - 32 )*/ nrgsQ[ i ] += lz1 + 2 * lz2 - 32 - 32; } RESTORE_STACK; } jamulus-3.9.1+dfsg/libs/opus/silk/fixed/process_gains_FIX.c0000644000175000017500000001470314340334543022652 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main_FIX.h" #include "tuning_parameters.h" /* Processing of gains */ void silk_process_gains_FIX( silk_encoder_state_FIX *psEnc, /* I/O Encoder state */ silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control */ opus_int condCoding /* I The type of conditional coding to use */ ) { silk_shape_state_FIX *psShapeSt = &psEnc->sShape; opus_int k; opus_int32 s_Q16, InvMaxSqrVal_Q16, gain, gain_squared, ResNrg, ResNrgPart, quant_offset_Q10; /* Gain reduction when LTP coding gain is high */ if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { /*s = -0.5f * silk_sigmoid( 0.25f * ( psEncCtrl->LTPredCodGain - 12.0f ) ); */ s_Q16 = -silk_sigm_Q15( silk_RSHIFT_ROUND( psEncCtrl->LTPredCodGain_Q7 - SILK_FIX_CONST( 12.0, 7 ), 4 ) ); for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { psEncCtrl->Gains_Q16[ k ] = silk_SMLAWB( psEncCtrl->Gains_Q16[ k ], psEncCtrl->Gains_Q16[ k ], s_Q16 ); } } /* Limit the quantized signal */ /* InvMaxSqrVal = pow( 2.0f, 0.33f * ( 21.0f - SNR_dB ) ) / subfr_length; */ InvMaxSqrVal_Q16 = silk_DIV32_16( silk_log2lin( silk_SMULWB( SILK_FIX_CONST( 21 + 16 / 0.33, 7 ) - psEnc->sCmn.SNR_dB_Q7, SILK_FIX_CONST( 0.33, 16 ) ) ), psEnc->sCmn.subfr_length ); for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { /* Soft limit on ratio residual energy and squared gains */ ResNrg = psEncCtrl->ResNrg[ k ]; ResNrgPart = silk_SMULWW( ResNrg, InvMaxSqrVal_Q16 ); if( psEncCtrl->ResNrgQ[ k ] > 0 ) { ResNrgPart = silk_RSHIFT_ROUND( ResNrgPart, psEncCtrl->ResNrgQ[ k ] ); } else { if( ResNrgPart >= silk_RSHIFT( silk_int32_MAX, -psEncCtrl->ResNrgQ[ k ] ) ) { ResNrgPart = silk_int32_MAX; } else { ResNrgPart = silk_LSHIFT( ResNrgPart, -psEncCtrl->ResNrgQ[ k ] ); } } gain = psEncCtrl->Gains_Q16[ k ]; gain_squared = silk_ADD_SAT32( ResNrgPart, silk_SMMUL( gain, gain ) ); if( gain_squared < silk_int16_MAX ) { /* recalculate with higher precision */ gain_squared = silk_SMLAWW( silk_LSHIFT( ResNrgPart, 16 ), gain, gain ); silk_assert( gain_squared > 0 ); gain = silk_SQRT_APPROX( gain_squared ); /* Q8 */ gain = silk_min( gain, silk_int32_MAX >> 8 ); psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT_SAT32( gain, 8 ); /* Q16 */ } else { gain = silk_SQRT_APPROX( gain_squared ); /* Q0 */ gain = silk_min( gain, silk_int32_MAX >> 16 ); psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT_SAT32( gain, 16 ); /* Q16 */ } } /* Save unquantized gains and gain Index */ silk_memcpy( psEncCtrl->GainsUnq_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) ); psEncCtrl->lastGainIndexPrev = psShapeSt->LastGainIndex; /* Quantize gains */ silk_gains_quant( psEnc->sCmn.indices.GainsIndices, psEncCtrl->Gains_Q16, &psShapeSt->LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); /* Set quantizer offset for voiced signals. Larger offset when LTP coding gain is low or tilt is high (ie low-pass) */ if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { if( psEncCtrl->LTPredCodGain_Q7 + silk_RSHIFT( psEnc->sCmn.input_tilt_Q15, 8 ) > SILK_FIX_CONST( 1.0, 7 ) ) { psEnc->sCmn.indices.quantOffsetType = 0; } else { psEnc->sCmn.indices.quantOffsetType = 1; } } /* Quantizer boundary adjustment */ quant_offset_Q10 = silk_Quantization_Offsets_Q10[ psEnc->sCmn.indices.signalType >> 1 ][ psEnc->sCmn.indices.quantOffsetType ]; psEncCtrl->Lambda_Q10 = SILK_FIX_CONST( LAMBDA_OFFSET, 10 ) + silk_SMULBB( SILK_FIX_CONST( LAMBDA_DELAYED_DECISIONS, 10 ), psEnc->sCmn.nStatesDelayedDecision ) + silk_SMULWB( SILK_FIX_CONST( LAMBDA_SPEECH_ACT, 18 ), psEnc->sCmn.speech_activity_Q8 ) + silk_SMULWB( SILK_FIX_CONST( LAMBDA_INPUT_QUALITY, 12 ), psEncCtrl->input_quality_Q14 ) + silk_SMULWB( SILK_FIX_CONST( LAMBDA_CODING_QUALITY, 12 ), psEncCtrl->coding_quality_Q14 ) + silk_SMULWB( SILK_FIX_CONST( LAMBDA_QUANT_OFFSET, 16 ), quant_offset_Q10 ); silk_assert( psEncCtrl->Lambda_Q10 > 0 ); silk_assert( psEncCtrl->Lambda_Q10 < SILK_FIX_CONST( 2, 10 ) ); } jamulus-3.9.1+dfsg/libs/opus/silk/fixed/mips/0000755000175000017500000000000014340334543020104 5ustar vimervimerjamulus-3.9.1+dfsg/libs/opus/silk/fixed/mips/warped_autocorrelation_FIX_mipsr1.h0000644000175000017500000001724414340334543027042 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef __WARPED_AUTOCORRELATION_FIX_MIPSR1_H__ #define __WARPED_AUTOCORRELATION_FIX_MIPSR1_H__ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main_FIX.h" #undef QC #define QC 10 #undef QS #define QS 14 /* Autocorrelations for a warped frequency axis */ #define OVERRIDE_silk_warped_autocorrelation_FIX_c void silk_warped_autocorrelation_FIX_c( opus_int32 *corr, /* O Result [order + 1] */ opus_int *scale, /* O Scaling of the correlation vector */ const opus_int16 *input, /* I Input data to correlate */ const opus_int warping_Q16, /* I Warping coefficient */ const opus_int length, /* I Length of input */ const opus_int order /* I Correlation order (even) */ ) { opus_int n, i, lsh; opus_int32 tmp1_QS=0, tmp2_QS=0, tmp3_QS=0, tmp4_QS=0, tmp5_QS=0, tmp6_QS=0, tmp7_QS=0, tmp8_QS=0, start_1=0, start_2=0, start_3=0; opus_int32 state_QS[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; opus_int64 corr_QC[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; opus_int64 temp64; opus_int32 val; val = 2 * QS - QC; /* Order must be even */ silk_assert( ( order & 1 ) == 0 ); silk_assert( 2 * QS - QC >= 0 ); /* Loop over samples */ for( n = 0; n < length; n=n+4 ) { tmp1_QS = silk_LSHIFT32( (opus_int32)input[ n ], QS ); start_1 = tmp1_QS; tmp3_QS = silk_LSHIFT32( (opus_int32)input[ n+1], QS ); start_2 = tmp3_QS; tmp5_QS = silk_LSHIFT32( (opus_int32)input[ n+2], QS ); start_3 = tmp5_QS; tmp7_QS = silk_LSHIFT32( (opus_int32)input[ n+3], QS ); /* Loop over allpass sections */ for( i = 0; i < order; i += 2 ) { /* Output of allpass section */ tmp2_QS = silk_SMLAWB( state_QS[ i ], state_QS[ i + 1 ] - tmp1_QS, warping_Q16 ); corr_QC[ i ] = __builtin_mips_madd( corr_QC[ i ], tmp1_QS, start_1); tmp4_QS = silk_SMLAWB( tmp1_QS, tmp2_QS - tmp3_QS, warping_Q16 ); corr_QC[ i ] = __builtin_mips_madd( corr_QC[ i ], tmp3_QS, start_2); tmp6_QS = silk_SMLAWB( tmp3_QS, tmp4_QS - tmp5_QS, warping_Q16 ); corr_QC[ i ] = __builtin_mips_madd( corr_QC[ i ], tmp5_QS, start_3); tmp8_QS = silk_SMLAWB( tmp5_QS, tmp6_QS - tmp7_QS, warping_Q16 ); state_QS[ i ] = tmp7_QS; corr_QC[ i ] = __builtin_mips_madd( corr_QC[ i ], tmp7_QS, state_QS[0]); /* Output of allpass section */ tmp1_QS = silk_SMLAWB( state_QS[ i + 1 ], state_QS[ i + 2 ] - tmp2_QS, warping_Q16 ); corr_QC[ i+1 ] = __builtin_mips_madd( corr_QC[ i+1 ], tmp2_QS, start_1); tmp3_QS = silk_SMLAWB( tmp2_QS, tmp1_QS - tmp4_QS, warping_Q16 ); corr_QC[ i+1 ] = __builtin_mips_madd( corr_QC[ i+1 ], tmp4_QS, start_2); tmp5_QS = silk_SMLAWB( tmp4_QS, tmp3_QS - tmp6_QS, warping_Q16 ); corr_QC[ i+1 ] = __builtin_mips_madd( corr_QC[ i+1 ], tmp6_QS, start_3); tmp7_QS = silk_SMLAWB( tmp6_QS, tmp5_QS - tmp8_QS, warping_Q16 ); state_QS[ i + 1 ] = tmp8_QS; corr_QC[ i+1 ] = __builtin_mips_madd( corr_QC[ i+1 ], tmp8_QS, state_QS[ 0 ]); } state_QS[ order ] = tmp7_QS; corr_QC[ order ] = __builtin_mips_madd( corr_QC[ order ], tmp1_QS, start_1); corr_QC[ order ] = __builtin_mips_madd( corr_QC[ order ], tmp3_QS, start_2); corr_QC[ order ] = __builtin_mips_madd( corr_QC[ order ], tmp5_QS, start_3); corr_QC[ order ] = __builtin_mips_madd( corr_QC[ order ], tmp7_QS, state_QS[ 0 ]); } for(;n< length; n++ ) { tmp1_QS = silk_LSHIFT32( (opus_int32)input[ n ], QS ); /* Loop over allpass sections */ for( i = 0; i < order; i += 2 ) { /* Output of allpass section */ tmp2_QS = silk_SMLAWB( state_QS[ i ], state_QS[ i + 1 ] - tmp1_QS, warping_Q16 ); state_QS[ i ] = tmp1_QS; corr_QC[ i ] = __builtin_mips_madd( corr_QC[ i ], tmp1_QS, state_QS[ 0 ]); /* Output of allpass section */ tmp1_QS = silk_SMLAWB( state_QS[ i + 1 ], state_QS[ i + 2 ] - tmp2_QS, warping_Q16 ); state_QS[ i + 1 ] = tmp2_QS; corr_QC[ i+1 ] = __builtin_mips_madd( corr_QC[ i+1 ], tmp2_QS, state_QS[ 0 ]); } state_QS[ order ] = tmp1_QS; corr_QC[ order ] = __builtin_mips_madd( corr_QC[ order ], tmp1_QS, state_QS[ 0 ]); } temp64 = corr_QC[ 0 ]; temp64 = __builtin_mips_shilo(temp64, val); lsh = silk_CLZ64( temp64 ) - 35; lsh = silk_LIMIT( lsh, -12 - QC, 30 - QC ); *scale = -( QC + lsh ); silk_assert( *scale >= -30 && *scale <= 12 ); if( lsh >= 0 ) { for( i = 0; i < order + 1; i++ ) { temp64 = corr_QC[ i ]; //temp64 = __builtin_mips_shilo(temp64, val); temp64 = (val >= 0) ? (temp64 >> val) : (temp64 << -val); corr[ i ] = (opus_int32)silk_CHECK_FIT32( __builtin_mips_shilo( temp64, -lsh ) ); } } else { for( i = 0; i < order + 1; i++ ) { temp64 = corr_QC[ i ]; //temp64 = __builtin_mips_shilo(temp64, val); temp64 = (val >= 0) ? (temp64 >> val) : (temp64 << -val); corr[ i ] = (opus_int32)silk_CHECK_FIT32( __builtin_mips_shilo( temp64, -lsh ) ); } } corr_QC[ 0 ] = __builtin_mips_shilo(corr_QC[ 0 ], val); silk_assert( corr_QC[ 0 ] >= 0 ); /* If breaking, decrease QC*/ } #endif /* __WARPED_AUTOCORRELATION_FIX_MIPSR1_H__ */ jamulus-3.9.1+dfsg/libs/opus/silk/fixed/mips/noise_shape_analysis_FIX_mipsr1.h0000644000175000017500000004521514340334543026465 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ /**************************************************************/ /* Compute noise shaping coefficients and initial gain values */ /**************************************************************/ #define OVERRIDE_silk_noise_shape_analysis_FIX void silk_noise_shape_analysis_FIX( silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */ silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */ const opus_int16 *pitch_res, /* I LPC residual from pitch analysis */ const opus_int16 *x, /* I Input signal [ frame_length + la_shape ] */ int arch /* I Run-time architecture */ ) { silk_shape_state_FIX *psShapeSt = &psEnc->sShape; opus_int k, i, nSamples, Qnrg, b_Q14, warping_Q16, scale = 0; opus_int32 SNR_adj_dB_Q7, HarmBoost_Q16, HarmShapeGain_Q16, Tilt_Q16, tmp32; opus_int32 nrg, pre_nrg_Q30, log_energy_Q7, log_energy_prev_Q7, energy_variation_Q7; opus_int32 delta_Q16, BWExp1_Q16, BWExp2_Q16, gain_mult_Q16, gain_add_Q16, strength_Q16, b_Q8; opus_int32 auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ]; opus_int32 refl_coef_Q16[ MAX_SHAPE_LPC_ORDER ]; opus_int32 AR1_Q24[ MAX_SHAPE_LPC_ORDER ]; opus_int32 AR2_Q24[ MAX_SHAPE_LPC_ORDER ]; VARDECL( opus_int16, x_windowed ); const opus_int16 *x_ptr, *pitch_res_ptr; SAVE_STACK; /* Point to start of first LPC analysis block */ x_ptr = x - psEnc->sCmn.la_shape; /****************/ /* GAIN CONTROL */ /****************/ SNR_adj_dB_Q7 = psEnc->sCmn.SNR_dB_Q7; /* Input quality is the average of the quality in the lowest two VAD bands */ psEncCtrl->input_quality_Q14 = ( opus_int )silk_RSHIFT( (opus_int32)psEnc->sCmn.input_quality_bands_Q15[ 0 ] + psEnc->sCmn.input_quality_bands_Q15[ 1 ], 2 ); /* Coding quality level, between 0.0_Q0 and 1.0_Q0, but in Q14 */ psEncCtrl->coding_quality_Q14 = silk_RSHIFT( silk_sigm_Q15( silk_RSHIFT_ROUND( SNR_adj_dB_Q7 - SILK_FIX_CONST( 20.0, 7 ), 4 ) ), 1 ); /* Reduce coding SNR during low speech activity */ if( psEnc->sCmn.useCBR == 0 ) { b_Q8 = SILK_FIX_CONST( 1.0, 8 ) - psEnc->sCmn.speech_activity_Q8; b_Q8 = silk_SMULWB( silk_LSHIFT( b_Q8, 8 ), b_Q8 ); SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, silk_SMULBB( SILK_FIX_CONST( -BG_SNR_DECR_dB, 7 ) >> ( 4 + 1 ), b_Q8 ), /* Q11*/ silk_SMULWB( SILK_FIX_CONST( 1.0, 14 ) + psEncCtrl->input_quality_Q14, psEncCtrl->coding_quality_Q14 ) ); /* Q12*/ } if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { /* Reduce gains for periodic signals */ SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( HARM_SNR_INCR_dB, 8 ), psEnc->LTPCorr_Q15 ); } else { /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */ SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, silk_SMLAWB( SILK_FIX_CONST( 6.0, 9 ), -SILK_FIX_CONST( 0.4, 18 ), psEnc->sCmn.SNR_dB_Q7 ), SILK_FIX_CONST( 1.0, 14 ) - psEncCtrl->input_quality_Q14 ); } /*************************/ /* SPARSENESS PROCESSING */ /*************************/ /* Set quantizer offset */ if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { /* Initially set to 0; may be overruled in process_gains(..) */ psEnc->sCmn.indices.quantOffsetType = 0; psEncCtrl->sparseness_Q8 = 0; } else { /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */ nSamples = silk_LSHIFT( psEnc->sCmn.fs_kHz, 1 ); energy_variation_Q7 = 0; log_energy_prev_Q7 = 0; pitch_res_ptr = pitch_res; for( k = 0; k < silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2; k++ ) { silk_sum_sqr_shift( &nrg, &scale, pitch_res_ptr, nSamples ); nrg += silk_RSHIFT( nSamples, scale ); /* Q(-scale)*/ log_energy_Q7 = silk_lin2log( nrg ); if( k > 0 ) { energy_variation_Q7 += silk_abs( log_energy_Q7 - log_energy_prev_Q7 ); } log_energy_prev_Q7 = log_energy_Q7; pitch_res_ptr += nSamples; } psEncCtrl->sparseness_Q8 = silk_RSHIFT( silk_sigm_Q15( silk_SMULWB( energy_variation_Q7 - SILK_FIX_CONST( 5.0, 7 ), SILK_FIX_CONST( 0.1, 16 ) ) ), 7 ); /* Set quantization offset depending on sparseness measure */ if( psEncCtrl->sparseness_Q8 > SILK_FIX_CONST( SPARSENESS_THRESHOLD_QNT_OFFSET, 8 ) ) { psEnc->sCmn.indices.quantOffsetType = 0; } else { psEnc->sCmn.indices.quantOffsetType = 1; } /* Increase coding SNR for sparse signals */ SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( SPARSE_SNR_INCR_dB, 15 ), psEncCtrl->sparseness_Q8 - SILK_FIX_CONST( 0.5, 8 ) ); } /*******************************/ /* Control bandwidth expansion */ /*******************************/ /* More BWE for signals with high prediction gain */ strength_Q16 = silk_SMULWB( psEncCtrl->predGain_Q16, SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) ); BWExp1_Q16 = BWExp2_Q16 = silk_DIV32_varQ( SILK_FIX_CONST( BANDWIDTH_EXPANSION, 16 ), silk_SMLAWW( SILK_FIX_CONST( 1.0, 16 ), strength_Q16, strength_Q16 ), 16 ); delta_Q16 = silk_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - silk_SMULBB( 3, psEncCtrl->coding_quality_Q14 ), SILK_FIX_CONST( LOW_RATE_BANDWIDTH_EXPANSION_DELTA, 16 ) ); BWExp1_Q16 = silk_SUB32( BWExp1_Q16, delta_Q16 ); BWExp2_Q16 = silk_ADD32( BWExp2_Q16, delta_Q16 ); /* BWExp1 will be applied after BWExp2, so make it relative */ BWExp1_Q16 = silk_DIV32_16( silk_LSHIFT( BWExp1_Q16, 14 ), silk_RSHIFT( BWExp2_Q16, 2 ) ); if( psEnc->sCmn.warping_Q16 > 0 ) { /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */ warping_Q16 = silk_SMLAWB( psEnc->sCmn.warping_Q16, (opus_int32)psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( 0.01, 18 ) ); } else { warping_Q16 = 0; } /********************************************/ /* Compute noise shaping AR coefs and gains */ /********************************************/ ALLOC( x_windowed, psEnc->sCmn.shapeWinLength, opus_int16 ); for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { /* Apply window: sine slope followed by flat part followed by cosine slope */ opus_int shift, slope_part, flat_part; flat_part = psEnc->sCmn.fs_kHz * 3; slope_part = silk_RSHIFT( psEnc->sCmn.shapeWinLength - flat_part, 1 ); silk_apply_sine_window( x_windowed, x_ptr, 1, slope_part ); shift = slope_part; silk_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(opus_int16) ); shift += flat_part; silk_apply_sine_window( x_windowed + shift, x_ptr + shift, 2, slope_part ); /* Update pointer: next LPC analysis block */ x_ptr += psEnc->sCmn.subfr_length; if( psEnc->sCmn.warping_Q16 > 0 ) { /* Calculate warped auto correlation */ silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder, arch ); } else { /* Calculate regular auto correlation */ silk_autocorr( auto_corr, &scale, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1, arch ); } /* Add white noise, as a fraction of energy */ auto_corr[0] = silk_ADD32( auto_corr[0], silk_max_32( silk_SMULWB( silk_RSHIFT( auto_corr[ 0 ], 4 ), SILK_FIX_CONST( SHAPE_WHITE_NOISE_FRACTION, 20 ) ), 1 ) ); /* Calculate the reflection coefficients using schur */ nrg = silk_schur64( refl_coef_Q16, auto_corr, psEnc->sCmn.shapingLPCOrder ); silk_assert( nrg >= 0 ); /* Convert reflection coefficients to prediction coefficients */ silk_k2a_Q16( AR2_Q24, refl_coef_Q16, psEnc->sCmn.shapingLPCOrder ); Qnrg = -scale; /* range: -12...30*/ silk_assert( Qnrg >= -12 ); silk_assert( Qnrg <= 30 ); /* Make sure that Qnrg is an even number */ if( Qnrg & 1 ) { Qnrg -= 1; nrg >>= 1; } tmp32 = silk_SQRT_APPROX( nrg ); Qnrg >>= 1; /* range: -6...15*/ psEncCtrl->Gains_Q16[ k ] = (silk_LSHIFT32( silk_LIMIT( (tmp32), silk_RSHIFT32( silk_int32_MIN, (16 - Qnrg) ), \ silk_RSHIFT32( silk_int32_MAX, (16 - Qnrg) ) ), (16 - Qnrg) )); if( psEnc->sCmn.warping_Q16 > 0 ) { /* Adjust gain for warping */ gain_mult_Q16 = warped_gain( AR2_Q24, warping_Q16, psEnc->sCmn.shapingLPCOrder ); silk_assert( psEncCtrl->Gains_Q16[ k ] >= 0 ); if ( silk_SMULWW( silk_RSHIFT_ROUND( psEncCtrl->Gains_Q16[ k ], 1 ), gain_mult_Q16 ) >= ( silk_int32_MAX >> 1 ) ) { psEncCtrl->Gains_Q16[ k ] = silk_int32_MAX; } else { psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 ); } } /* Bandwidth expansion for synthesis filter shaping */ silk_bwexpander_32( AR2_Q24, psEnc->sCmn.shapingLPCOrder, BWExp2_Q16 ); /* Compute noise shaping filter coefficients */ silk_memcpy( AR1_Q24, AR2_Q24, psEnc->sCmn.shapingLPCOrder * sizeof( opus_int32 ) ); /* Bandwidth expansion for analysis filter shaping */ silk_assert( BWExp1_Q16 <= SILK_FIX_CONST( 1.0, 16 ) ); silk_bwexpander_32( AR1_Q24, psEnc->sCmn.shapingLPCOrder, BWExp1_Q16 ); /* Ratio of prediction gains, in energy domain */ pre_nrg_Q30 = silk_LPC_inverse_pred_gain_Q24( AR2_Q24, psEnc->sCmn.shapingLPCOrder, arch ); nrg = silk_LPC_inverse_pred_gain_Q24( AR1_Q24, psEnc->sCmn.shapingLPCOrder, arch ); /*psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg ) = 0.3f + 0.7f * pre_nrg / nrg;*/ pre_nrg_Q30 = silk_LSHIFT32( silk_SMULWB( pre_nrg_Q30, SILK_FIX_CONST( 0.7, 15 ) ), 1 ); psEncCtrl->GainsPre_Q14[ k ] = ( opus_int ) SILK_FIX_CONST( 0.3, 14 ) + silk_DIV32_varQ( pre_nrg_Q30, nrg, 14 ); /* Convert to monic warped prediction coefficients and limit absolute values */ limit_warped_coefs( AR2_Q24, AR1_Q24, warping_Q16, SILK_FIX_CONST( 3.999, 24 ), psEnc->sCmn.shapingLPCOrder ); /* Convert from Q24 to Q13 and store in int16 */ for( i = 0; i < psEnc->sCmn.shapingLPCOrder; i++ ) { psEncCtrl->AR1_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR1_Q24[ i ], 11 ) ); psEncCtrl->AR2_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR2_Q24[ i ], 11 ) ); } } /*****************/ /* Gain tweaking */ /*****************/ /* Increase gains during low speech activity and put lower limit on gains */ gain_mult_Q16 = silk_log2lin( -silk_SMLAWB( -SILK_FIX_CONST( 16.0, 7 ), SNR_adj_dB_Q7, SILK_FIX_CONST( 0.16, 16 ) ) ); gain_add_Q16 = silk_log2lin( silk_SMLAWB( SILK_FIX_CONST( 16.0, 7 ), SILK_FIX_CONST( MIN_QGAIN_DB, 7 ), SILK_FIX_CONST( 0.16, 16 ) ) ); silk_assert( gain_mult_Q16 > 0 ); for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 ); silk_assert( psEncCtrl->Gains_Q16[ k ] >= 0 ); psEncCtrl->Gains_Q16[ k ] = silk_ADD_POS_SAT32( psEncCtrl->Gains_Q16[ k ], gain_add_Q16 ); } gain_mult_Q16 = SILK_FIX_CONST( 1.0, 16 ) + silk_RSHIFT_ROUND( silk_MLA( SILK_FIX_CONST( INPUT_TILT, 26 ), psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) ), 10 ); for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { psEncCtrl->GainsPre_Q14[ k ] = silk_SMULWB( gain_mult_Q16, psEncCtrl->GainsPre_Q14[ k ] ); } /************************************************/ /* Control low-frequency shaping and noise tilt */ /************************************************/ /* Less low frequency shaping for noisy inputs */ strength_Q16 = silk_MUL( SILK_FIX_CONST( LOW_FREQ_SHAPING, 4 ), silk_SMLAWB( SILK_FIX_CONST( 1.0, 12 ), SILK_FIX_CONST( LOW_QUALITY_LOW_FREQ_SHAPING_DECR, 13 ), psEnc->sCmn.input_quality_bands_Q15[ 0 ] - SILK_FIX_CONST( 1.0, 15 ) ) ); strength_Q16 = silk_RSHIFT( silk_MUL( strength_Q16, psEnc->sCmn.speech_activity_Q8 ), 8 ); if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { /* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */ /*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/ opus_int fs_kHz_inv = silk_DIV32_16( SILK_FIX_CONST( 0.2, 14 ), psEnc->sCmn.fs_kHz ); for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { b_Q14 = fs_kHz_inv + silk_DIV32_16( SILK_FIX_CONST( 3.0, 14 ), psEncCtrl->pitchL[ k ] ); /* Pack two coefficients in one int32 */ psEncCtrl->LF_shp_Q14[ k ] = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 - silk_SMULWB( strength_Q16, b_Q14 ), 16 ); psEncCtrl->LF_shp_Q14[ k ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) ); } silk_assert( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ) < SILK_FIX_CONST( 0.5, 24 ) ); /* Guarantees that second argument to SMULWB() is within range of an opus_int16*/ Tilt_Q16 = - SILK_FIX_CONST( HP_NOISE_COEF, 16 ) - silk_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - SILK_FIX_CONST( HP_NOISE_COEF, 16 ), silk_SMULWB( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ), psEnc->sCmn.speech_activity_Q8 ) ); } else { b_Q14 = silk_DIV32_16( 21299, psEnc->sCmn.fs_kHz ); /* 1.3_Q0 = 21299_Q14*/ /* Pack two coefficients in one int32 */ psEncCtrl->LF_shp_Q14[ 0 ] = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 - silk_SMULWB( strength_Q16, silk_SMULWB( SILK_FIX_CONST( 0.6, 16 ), b_Q14 ) ), 16 ); psEncCtrl->LF_shp_Q14[ 0 ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) ); for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) { psEncCtrl->LF_shp_Q14[ k ] = psEncCtrl->LF_shp_Q14[ 0 ]; } Tilt_Q16 = -SILK_FIX_CONST( HP_NOISE_COEF, 16 ); } /****************************/ /* HARMONIC SHAPING CONTROL */ /****************************/ /* Control boosting of harmonic frequencies */ HarmBoost_Q16 = silk_SMULWB( silk_SMULWB( SILK_FIX_CONST( 1.0, 17 ) - silk_LSHIFT( psEncCtrl->coding_quality_Q14, 3 ), psEnc->LTPCorr_Q15 ), SILK_FIX_CONST( LOW_RATE_HARMONIC_BOOST, 16 ) ); /* More harmonic boost for noisy input signals */ HarmBoost_Q16 = silk_SMLAWB( HarmBoost_Q16, SILK_FIX_CONST( 1.0, 16 ) - silk_LSHIFT( psEncCtrl->input_quality_Q14, 2 ), SILK_FIX_CONST( LOW_INPUT_QUALITY_HARMONIC_BOOST, 16 ) ); if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) { /* More harmonic noise shaping for high bitrates or noisy input */ HarmShapeGain_Q16 = silk_SMLAWB( SILK_FIX_CONST( HARMONIC_SHAPING, 16 ), SILK_FIX_CONST( 1.0, 16 ) - silk_SMULWB( SILK_FIX_CONST( 1.0, 18 ) - silk_LSHIFT( psEncCtrl->coding_quality_Q14, 4 ), psEncCtrl->input_quality_Q14 ), SILK_FIX_CONST( HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING, 16 ) ); /* Less harmonic noise shaping for less periodic signals */ HarmShapeGain_Q16 = silk_SMULWB( silk_LSHIFT( HarmShapeGain_Q16, 1 ), silk_SQRT_APPROX( silk_LSHIFT( psEnc->LTPCorr_Q15, 15 ) ) ); } else { HarmShapeGain_Q16 = 0; } /*************************/ /* Smooth over subframes */ /*************************/ for( k = 0; k < MAX_NB_SUBFR; k++ ) { psShapeSt->HarmBoost_smth_Q16 = silk_SMLAWB( psShapeSt->HarmBoost_smth_Q16, HarmBoost_Q16 - psShapeSt->HarmBoost_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) ); psShapeSt->HarmShapeGain_smth_Q16 = silk_SMLAWB( psShapeSt->HarmShapeGain_smth_Q16, HarmShapeGain_Q16 - psShapeSt->HarmShapeGain_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) ); psShapeSt->Tilt_smth_Q16 = silk_SMLAWB( psShapeSt->Tilt_smth_Q16, Tilt_Q16 - psShapeSt->Tilt_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) ); psEncCtrl->HarmBoost_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmBoost_smth_Q16, 2 ); psEncCtrl->HarmShapeGain_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmShapeGain_smth_Q16, 2 ); psEncCtrl->Tilt_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->Tilt_smth_Q16, 2 ); } RESTORE_STACK; } jamulus-3.9.1+dfsg/libs/opus/silk/fixed/x86/0000755000175000017500000000000014340334543017561 5ustar vimervimerjamulus-3.9.1+dfsg/libs/opus/silk/fixed/x86/burg_modified_FIX_sse4_1.c0000644000175000017500000005175414340334543024424 0ustar vimervimer/* Copyright (c) 2014, Cisco Systems, INC Written by XiangMingZhu WeiZhou MinPeng YanWang Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "SigProc_FIX.h" #include "define.h" #include "tuning_parameters.h" #include "pitch.h" #include "celt/x86/x86cpu.h" #define MAX_FRAME_SIZE 384 /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384 */ #define QA 25 #define N_BITS_HEAD_ROOM 2 #define MIN_RSHIFTS -16 #define MAX_RSHIFTS (32 - QA) /* Compute reflection coefficients from input signal */ void silk_burg_modified_sse4_1( opus_int32 *res_nrg, /* O Residual energy */ opus_int *res_nrg_Q, /* O Residual energy Q value */ opus_int32 A_Q16[], /* O Prediction coefficients (length order) */ const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */ const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */ const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */ const opus_int nb_subfr, /* I Number of subframes stacked in x */ const opus_int D, /* I Order */ int arch /* I Run-time architecture */ ) { opus_int k, n, s, lz, rshifts, rshifts_extra, reached_max_gain; opus_int32 C0, num, nrg, rc_Q31, invGain_Q30, Atmp_QA, Atmp1, tmp1, tmp2, x1, x2; const opus_int16 *x_ptr; opus_int32 C_first_row[ SILK_MAX_ORDER_LPC ]; opus_int32 C_last_row[ SILK_MAX_ORDER_LPC ]; opus_int32 Af_QA[ SILK_MAX_ORDER_LPC ]; opus_int32 CAf[ SILK_MAX_ORDER_LPC + 1 ]; opus_int32 CAb[ SILK_MAX_ORDER_LPC + 1 ]; opus_int32 xcorr[ SILK_MAX_ORDER_LPC ]; __m128i FIRST_3210, LAST_3210, ATMP_3210, TMP1_3210, TMP2_3210, T1_3210, T2_3210, PTR_3210, SUBFR_3210, X1_3210, X2_3210; __m128i CONST1 = _mm_set1_epi32(1); celt_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE ); /* Compute autocorrelations, added over subframes */ silk_sum_sqr_shift( &C0, &rshifts, x, nb_subfr * subfr_length ); if( rshifts > MAX_RSHIFTS ) { C0 = silk_LSHIFT32( C0, rshifts - MAX_RSHIFTS ); silk_assert( C0 > 0 ); rshifts = MAX_RSHIFTS; } else { lz = silk_CLZ32( C0 ) - 1; rshifts_extra = N_BITS_HEAD_ROOM - lz; if( rshifts_extra > 0 ) { rshifts_extra = silk_min( rshifts_extra, MAX_RSHIFTS - rshifts ); C0 = silk_RSHIFT32( C0, rshifts_extra ); } else { rshifts_extra = silk_max( rshifts_extra, MIN_RSHIFTS - rshifts ); C0 = silk_LSHIFT32( C0, -rshifts_extra ); } rshifts += rshifts_extra; } CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1; /* Q(-rshifts) */ silk_memset( C_first_row, 0, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) ); if( rshifts > 0 ) { for( s = 0; s < nb_subfr; s++ ) { x_ptr = x + s * subfr_length; for( n = 1; n < D + 1; n++ ) { C_first_row[ n - 1 ] += (opus_int32)silk_RSHIFT64( silk_inner_prod16_aligned_64( x_ptr, x_ptr + n, subfr_length - n, arch ), rshifts ); } } } else { for( s = 0; s < nb_subfr; s++ ) { int i; opus_int32 d; x_ptr = x + s * subfr_length; celt_pitch_xcorr(x_ptr, x_ptr + 1, xcorr, subfr_length - D, D, arch ); for( n = 1; n < D + 1; n++ ) { for ( i = n + subfr_length - D, d = 0; i < subfr_length; i++ ) d = MAC16_16( d, x_ptr[ i ], x_ptr[ i - n ] ); xcorr[ n - 1 ] += d; } for( n = 1; n < D + 1; n++ ) { C_first_row[ n - 1 ] += silk_LSHIFT32( xcorr[ n - 1 ], -rshifts ); } } } silk_memcpy( C_last_row, C_first_row, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) ); /* Initialize */ CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1; /* Q(-rshifts) */ invGain_Q30 = (opus_int32)1 << 30; reached_max_gain = 0; for( n = 0; n < D; n++ ) { /* Update first row of correlation matrix (without first element) */ /* Update last row of correlation matrix (without last element, stored in reversed order) */ /* Update C * Af */ /* Update C * flipud(Af) (stored in reversed order) */ if( rshifts > -2 ) { for( s = 0; s < nb_subfr; s++ ) { x_ptr = x + s * subfr_length; x1 = -silk_LSHIFT32( (opus_int32)x_ptr[ n ], 16 - rshifts ); /* Q(16-rshifts) */ x2 = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 16 - rshifts ); /* Q(16-rshifts) */ tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ], QA - 16 ); /* Q(QA-16) */ tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], QA - 16 ); /* Q(QA-16) */ for( k = 0; k < n; k++ ) { C_first_row[ k ] = silk_SMLAWB( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts ) */ C_last_row[ k ] = silk_SMLAWB( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */ Atmp_QA = Af_QA[ k ]; tmp1 = silk_SMLAWB( tmp1, Atmp_QA, x_ptr[ n - k - 1 ] ); /* Q(QA-16) */ tmp2 = silk_SMLAWB( tmp2, Atmp_QA, x_ptr[ subfr_length - n + k ] ); /* Q(QA-16) */ } tmp1 = silk_LSHIFT32( -tmp1, 32 - QA - rshifts ); /* Q(16-rshifts) */ tmp2 = silk_LSHIFT32( -tmp2, 32 - QA - rshifts ); /* Q(16-rshifts) */ for( k = 0; k <= n; k++ ) { CAf[ k ] = silk_SMLAWB( CAf[ k ], tmp1, x_ptr[ n - k ] ); /* Q( -rshift ) */ CAb[ k ] = silk_SMLAWB( CAb[ k ], tmp2, x_ptr[ subfr_length - n + k - 1 ] ); /* Q( -rshift ) */ } } } else { for( s = 0; s < nb_subfr; s++ ) { x_ptr = x + s * subfr_length; x1 = -silk_LSHIFT32( (opus_int32)x_ptr[ n ], -rshifts ); /* Q( -rshifts ) */ x2 = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], -rshifts ); /* Q( -rshifts ) */ tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ], 17 ); /* Q17 */ tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 17 ); /* Q17 */ X1_3210 = _mm_set1_epi32( x1 ); X2_3210 = _mm_set1_epi32( x2 ); TMP1_3210 = _mm_setzero_si128(); TMP2_3210 = _mm_setzero_si128(); for( k = 0; k < n - 3; k += 4 ) { PTR_3210 = OP_CVTEPI16_EPI32_M64( &x_ptr[ n - k - 1 - 3 ] ); SUBFR_3210 = OP_CVTEPI16_EPI32_M64( &x_ptr[ subfr_length - n + k ] ); FIRST_3210 = _mm_loadu_si128( (__m128i *)&C_first_row[ k ] ); PTR_3210 = _mm_shuffle_epi32( PTR_3210, _MM_SHUFFLE( 0, 1, 2, 3 ) ); LAST_3210 = _mm_loadu_si128( (__m128i *)&C_last_row[ k ] ); ATMP_3210 = _mm_loadu_si128( (__m128i *)&Af_QA[ k ] ); T1_3210 = _mm_mullo_epi32( PTR_3210, X1_3210 ); T2_3210 = _mm_mullo_epi32( SUBFR_3210, X2_3210 ); ATMP_3210 = _mm_srai_epi32( ATMP_3210, 7 ); ATMP_3210 = _mm_add_epi32( ATMP_3210, CONST1 ); ATMP_3210 = _mm_srai_epi32( ATMP_3210, 1 ); FIRST_3210 = _mm_add_epi32( FIRST_3210, T1_3210 ); LAST_3210 = _mm_add_epi32( LAST_3210, T2_3210 ); PTR_3210 = _mm_mullo_epi32( ATMP_3210, PTR_3210 ); SUBFR_3210 = _mm_mullo_epi32( ATMP_3210, SUBFR_3210 ); _mm_storeu_si128( (__m128i *)&C_first_row[ k ], FIRST_3210 ); _mm_storeu_si128( (__m128i *)&C_last_row[ k ], LAST_3210 ); TMP1_3210 = _mm_add_epi32( TMP1_3210, PTR_3210 ); TMP2_3210 = _mm_add_epi32( TMP2_3210, SUBFR_3210 ); } TMP1_3210 = _mm_add_epi32( TMP1_3210, _mm_unpackhi_epi64(TMP1_3210, TMP1_3210 ) ); TMP2_3210 = _mm_add_epi32( TMP2_3210, _mm_unpackhi_epi64(TMP2_3210, TMP2_3210 ) ); TMP1_3210 = _mm_add_epi32( TMP1_3210, _mm_shufflelo_epi16(TMP1_3210, 0x0E ) ); TMP2_3210 = _mm_add_epi32( TMP2_3210, _mm_shufflelo_epi16(TMP2_3210, 0x0E ) ); tmp1 += _mm_cvtsi128_si32( TMP1_3210 ); tmp2 += _mm_cvtsi128_si32( TMP2_3210 ); for( ; k < n; k++ ) { C_first_row[ k ] = silk_MLA( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts ) */ C_last_row[ k ] = silk_MLA( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */ Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 17 ); /* Q17 */ tmp1 = silk_MLA( tmp1, x_ptr[ n - k - 1 ], Atmp1 ); /* Q17 */ tmp2 = silk_MLA( tmp2, x_ptr[ subfr_length - n + k ], Atmp1 ); /* Q17 */ } tmp1 = -tmp1; /* Q17 */ tmp2 = -tmp2; /* Q17 */ { __m128i xmm_tmp1, xmm_tmp2; __m128i xmm_x_ptr_n_k_x2x0, xmm_x_ptr_n_k_x3x1; __m128i xmm_x_ptr_sub_x2x0, xmm_x_ptr_sub_x3x1; xmm_tmp1 = _mm_set1_epi32( tmp1 ); xmm_tmp2 = _mm_set1_epi32( tmp2 ); for( k = 0; k <= n - 3; k += 4 ) { xmm_x_ptr_n_k_x2x0 = OP_CVTEPI16_EPI32_M64( &x_ptr[ n - k - 3 ] ); xmm_x_ptr_sub_x2x0 = OP_CVTEPI16_EPI32_M64( &x_ptr[ subfr_length - n + k - 1 ] ); xmm_x_ptr_n_k_x2x0 = _mm_shuffle_epi32( xmm_x_ptr_n_k_x2x0, _MM_SHUFFLE( 0, 1, 2, 3 ) ); xmm_x_ptr_n_k_x2x0 = _mm_slli_epi32( xmm_x_ptr_n_k_x2x0, -rshifts - 1 ); xmm_x_ptr_sub_x2x0 = _mm_slli_epi32( xmm_x_ptr_sub_x2x0, -rshifts - 1 ); /* equal shift right 4 bytes, xmm_x_ptr_n_k_x3x1 = _mm_srli_si128(xmm_x_ptr_n_k_x2x0, 4)*/ xmm_x_ptr_n_k_x3x1 = _mm_shuffle_epi32( xmm_x_ptr_n_k_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) ); xmm_x_ptr_sub_x3x1 = _mm_shuffle_epi32( xmm_x_ptr_sub_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) ); xmm_x_ptr_n_k_x2x0 = _mm_mul_epi32( xmm_x_ptr_n_k_x2x0, xmm_tmp1 ); xmm_x_ptr_n_k_x3x1 = _mm_mul_epi32( xmm_x_ptr_n_k_x3x1, xmm_tmp1 ); xmm_x_ptr_sub_x2x0 = _mm_mul_epi32( xmm_x_ptr_sub_x2x0, xmm_tmp2 ); xmm_x_ptr_sub_x3x1 = _mm_mul_epi32( xmm_x_ptr_sub_x3x1, xmm_tmp2 ); xmm_x_ptr_n_k_x2x0 = _mm_srli_epi64( xmm_x_ptr_n_k_x2x0, 16 ); xmm_x_ptr_n_k_x3x1 = _mm_slli_epi64( xmm_x_ptr_n_k_x3x1, 16 ); xmm_x_ptr_sub_x2x0 = _mm_srli_epi64( xmm_x_ptr_sub_x2x0, 16 ); xmm_x_ptr_sub_x3x1 = _mm_slli_epi64( xmm_x_ptr_sub_x3x1, 16 ); xmm_x_ptr_n_k_x2x0 = _mm_blend_epi16( xmm_x_ptr_n_k_x2x0, xmm_x_ptr_n_k_x3x1, 0xCC ); xmm_x_ptr_sub_x2x0 = _mm_blend_epi16( xmm_x_ptr_sub_x2x0, xmm_x_ptr_sub_x3x1, 0xCC ); X1_3210 = _mm_loadu_si128( (__m128i *)&CAf[ k ] ); PTR_3210 = _mm_loadu_si128( (__m128i *)&CAb[ k ] ); X1_3210 = _mm_add_epi32( X1_3210, xmm_x_ptr_n_k_x2x0 ); PTR_3210 = _mm_add_epi32( PTR_3210, xmm_x_ptr_sub_x2x0 ); _mm_storeu_si128( (__m128i *)&CAf[ k ], X1_3210 ); _mm_storeu_si128( (__m128i *)&CAb[ k ], PTR_3210 ); } for( ; k <= n; k++ ) { CAf[ k ] = silk_SMLAWW( CAf[ k ], tmp1, silk_LSHIFT32( (opus_int32)x_ptr[ n - k ], -rshifts - 1 ) ); /* Q( -rshift ) */ CAb[ k ] = silk_SMLAWW( CAb[ k ], tmp2, silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n + k - 1 ], -rshifts - 1 ) ); /* Q( -rshift ) */ } } } } /* Calculate nominator and denominator for the next order reflection (parcor) coefficient */ tmp1 = C_first_row[ n ]; /* Q( -rshifts ) */ tmp2 = C_last_row[ n ]; /* Q( -rshifts ) */ num = 0; /* Q( -rshifts ) */ nrg = silk_ADD32( CAb[ 0 ], CAf[ 0 ] ); /* Q( 1-rshifts ) */ for( k = 0; k < n; k++ ) { Atmp_QA = Af_QA[ k ]; lz = silk_CLZ32( silk_abs( Atmp_QA ) ) - 1; lz = silk_min( 32 - QA, lz ); Atmp1 = silk_LSHIFT32( Atmp_QA, lz ); /* Q( QA + lz ) */ tmp1 = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( C_last_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */ tmp2 = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( C_first_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */ num = silk_ADD_LSHIFT32( num, silk_SMMUL( CAb[ n - k ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */ nrg = silk_ADD_LSHIFT32( nrg, silk_SMMUL( silk_ADD32( CAb[ k + 1 ], CAf[ k + 1 ] ), Atmp1 ), 32 - QA - lz ); /* Q( 1-rshifts ) */ } CAf[ n + 1 ] = tmp1; /* Q( -rshifts ) */ CAb[ n + 1 ] = tmp2; /* Q( -rshifts ) */ num = silk_ADD32( num, tmp2 ); /* Q( -rshifts ) */ num = silk_LSHIFT32( -num, 1 ); /* Q( 1-rshifts ) */ /* Calculate the next order reflection (parcor) coefficient */ if( silk_abs( num ) < nrg ) { rc_Q31 = silk_DIV32_varQ( num, nrg, 31 ); } else { rc_Q31 = ( num > 0 ) ? silk_int32_MAX : silk_int32_MIN; } /* Update inverse prediction gain */ tmp1 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 ); tmp1 = silk_LSHIFT( silk_SMMUL( invGain_Q30, tmp1 ), 2 ); if( tmp1 <= minInvGain_Q30 ) { /* Max prediction gain exceeded; set reflection coefficient such that max prediction gain is exactly hit */ tmp2 = ( (opus_int32)1 << 30 ) - silk_DIV32_varQ( minInvGain_Q30, invGain_Q30, 30 ); /* Q30 */ rc_Q31 = silk_SQRT_APPROX( tmp2 ); /* Q15 */ if( rc_Q31 > 0 ) { /* Newton-Raphson iteration */ rc_Q31 = silk_RSHIFT32( rc_Q31 + silk_DIV32( tmp2, rc_Q31 ), 1 ); /* Q15 */ rc_Q31 = silk_LSHIFT32( rc_Q31, 16 ); /* Q31 */ if( num < 0 ) { /* Ensure adjusted reflection coefficients has the original sign */ rc_Q31 = -rc_Q31; } } invGain_Q30 = minInvGain_Q30; reached_max_gain = 1; } else { invGain_Q30 = tmp1; } /* Update the AR coefficients */ for( k = 0; k < (n + 1) >> 1; k++ ) { tmp1 = Af_QA[ k ]; /* QA */ tmp2 = Af_QA[ n - k - 1 ]; /* QA */ Af_QA[ k ] = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 ); /* QA */ Af_QA[ n - k - 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 ); /* QA */ } Af_QA[ n ] = silk_RSHIFT32( rc_Q31, 31 - QA ); /* QA */ if( reached_max_gain ) { /* Reached max prediction gain; set remaining coefficients to zero and exit loop */ for( k = n + 1; k < D; k++ ) { Af_QA[ k ] = 0; } break; } /* Update C * Af and C * Ab */ for( k = 0; k <= n + 1; k++ ) { tmp1 = CAf[ k ]; /* Q( -rshifts ) */ tmp2 = CAb[ n - k + 1 ]; /* Q( -rshifts ) */ CAf[ k ] = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 ); /* Q( -rshifts ) */ CAb[ n - k + 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 ); /* Q( -rshifts ) */ } } if( reached_max_gain ) { for( k = 0; k < D; k++ ) { /* Scale coefficients */ A_Q16[ k ] = -silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 ); } /* Subtract energy of preceding samples from C0 */ if( rshifts > 0 ) { for( s = 0; s < nb_subfr; s++ ) { x_ptr = x + s * subfr_length; C0 -= (opus_int32)silk_RSHIFT64( silk_inner_prod16_aligned_64( x_ptr, x_ptr, D, arch ), rshifts ); } } else { for( s = 0; s < nb_subfr; s++ ) { x_ptr = x + s * subfr_length; C0 -= silk_LSHIFT32( silk_inner_prod_aligned( x_ptr, x_ptr, D, arch ), -rshifts ); } } /* Approximate residual energy */ *res_nrg = silk_LSHIFT( silk_SMMUL( invGain_Q30, C0 ), 2 ); *res_nrg_Q = -rshifts; } else { /* Return residual energy */ nrg = CAf[ 0 ]; /* Q( -rshifts ) */ tmp1 = (opus_int32)1 << 16; /* Q16 */ for( k = 0; k < D; k++ ) { Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 ); /* Q16 */ nrg = silk_SMLAWW( nrg, CAf[ k + 1 ], Atmp1 ); /* Q( -rshifts ) */ tmp1 = silk_SMLAWW( tmp1, Atmp1, Atmp1 ); /* Q16 */ A_Q16[ k ] = -Atmp1; } *res_nrg = silk_SMLAWW( nrg, silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ), -tmp1 );/* Q( -rshifts ) */ *res_nrg_Q = -rshifts; } } jamulus-3.9.1+dfsg/libs/opus/silk/fixed/x86/vector_ops_FIX_sse4_1.c0000644000175000017500000000636614340334543024007 0ustar vimervimer/* Copyright (c) 2014, Cisco Systems, INC Written by XiangMingZhu WeiZhou MinPeng YanWang Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "main.h" #include "SigProc_FIX.h" #include "pitch.h" opus_int64 silk_inner_prod16_aligned_64_sse4_1( const opus_int16 *inVec1, /* I input vector 1 */ const opus_int16 *inVec2, /* I input vector 2 */ const opus_int len /* I vector lengths */ ) { opus_int i, dataSize8; opus_int64 sum; __m128i xmm_tempa; __m128i inVec1_76543210, acc1; __m128i inVec2_76543210, acc2; sum = 0; dataSize8 = len & ~7; acc1 = _mm_setzero_si128(); acc2 = _mm_setzero_si128(); for( i = 0; i < dataSize8; i += 8 ) { inVec1_76543210 = _mm_loadu_si128( (__m128i *)(&inVec1[i + 0] ) ); inVec2_76543210 = _mm_loadu_si128( (__m128i *)(&inVec2[i + 0] ) ); /* only when all 4 operands are -32768 (0x8000), this results in wrap around */ inVec1_76543210 = _mm_madd_epi16( inVec1_76543210, inVec2_76543210 ); xmm_tempa = _mm_cvtepi32_epi64( inVec1_76543210 ); /* equal shift right 8 bytes */ inVec1_76543210 = _mm_shuffle_epi32( inVec1_76543210, _MM_SHUFFLE( 0, 0, 3, 2 ) ); inVec1_76543210 = _mm_cvtepi32_epi64( inVec1_76543210 ); acc1 = _mm_add_epi64( acc1, xmm_tempa ); acc2 = _mm_add_epi64( acc2, inVec1_76543210 ); } acc1 = _mm_add_epi64( acc1, acc2 ); /* equal shift right 8 bytes */ acc2 = _mm_shuffle_epi32( acc1, _MM_SHUFFLE( 0, 0, 3, 2 ) ); acc1 = _mm_add_epi64( acc1, acc2 ); _mm_storel_epi64( (__m128i *)&sum, acc1 ); for( ; i < len; i++ ) { sum = silk_SMLABB( sum, inVec1[ i ], inVec2[ i ] ); } return sum; } jamulus-3.9.1+dfsg/libs/opus/silk/fixed/arm/0000755000175000017500000000000014340334543017713 5ustar vimervimerjamulus-3.9.1+dfsg/libs/opus/silk/fixed/arm/warped_autocorrelation_FIX_arm.h0000644000175000017500000001026114340334543026205 0ustar vimervimer/*********************************************************************** Copyright (c) 2017 Google Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SILK_WARPED_AUTOCORRELATION_FIX_ARM_H # define SILK_WARPED_AUTOCORRELATION_FIX_ARM_H # include "celt/arm/armcpu.h" # if defined(FIXED_POINT) # if defined(OPUS_ARM_MAY_HAVE_NEON_INTR) void silk_warped_autocorrelation_FIX_neon( opus_int32 *corr, /* O Result [order + 1] */ opus_int *scale, /* O Scaling of the correlation vector */ const opus_int16 *input, /* I Input data to correlate */ const opus_int warping_Q16, /* I Warping coefficient */ const opus_int length, /* I Length of input */ const opus_int order /* I Correlation order (even) */ ); # if !defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_PRESUME_NEON) # define OVERRIDE_silk_warped_autocorrelation_FIX (1) # define silk_warped_autocorrelation_FIX(corr, scale, input, warping_Q16, length, order, arch) \ ((void)(arch), PRESUME_NEON(silk_warped_autocorrelation_FIX)(corr, scale, input, warping_Q16, length, order)) # endif # endif # if !defined(OVERRIDE_silk_warped_autocorrelation_FIX) /*Is run-time CPU detection enabled on this platform?*/ # if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR)) extern void (*const SILK_WARPED_AUTOCORRELATION_FIX_IMPL[OPUS_ARCHMASK+1])(opus_int32*, opus_int*, const opus_int16*, const opus_int, const opus_int, const opus_int); # define OVERRIDE_silk_warped_autocorrelation_FIX (1) # define silk_warped_autocorrelation_FIX(corr, scale, input, warping_Q16, length, order, arch) \ ((*SILK_WARPED_AUTOCORRELATION_FIX_IMPL[(arch)&OPUS_ARCHMASK])(corr, scale, input, warping_Q16, length, order)) # elif defined(OPUS_ARM_PRESUME_NEON_INTR) # define OVERRIDE_silk_warped_autocorrelation_FIX (1) # define silk_warped_autocorrelation_FIX(corr, scale, input, warping_Q16, length, order, arch) \ ((void)(arch), silk_warped_autocorrelation_FIX_neon(corr, scale, input, warping_Q16, length, order)) # endif # endif # endif /* end FIXED_POINT */ #endif /* end SILK_WARPED_AUTOCORRELATION_FIX_ARM_H */ jamulus-3.9.1+dfsg/libs/opus/silk/fixed/arm/warped_autocorrelation_FIX_neon_intr.c0000644000175000017500000003156414340334543027425 0ustar vimervimer/*********************************************************************** Copyright (c) 2017 Google Inc., Jean-Marc Valin Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #ifdef OPUS_CHECK_ASM # include #endif #include "stack_alloc.h" #include "main_FIX.h" static OPUS_INLINE void calc_corr( const opus_int32 *const input_QS, opus_int64 *const corr_QC, const opus_int offset, const int32x4_t state_QS_s32x4 ) { int64x2_t corr_QC_s64x2[ 2 ], t_s64x2[ 2 ]; const int32x4_t input_QS_s32x4 = vld1q_s32( input_QS + offset ); corr_QC_s64x2[ 0 ] = vld1q_s64( corr_QC + offset + 0 ); corr_QC_s64x2[ 1 ] = vld1q_s64( corr_QC + offset + 2 ); t_s64x2[ 0 ] = vmull_s32( vget_low_s32( state_QS_s32x4 ), vget_low_s32( input_QS_s32x4 ) ); t_s64x2[ 1 ] = vmull_s32( vget_high_s32( state_QS_s32x4 ), vget_high_s32( input_QS_s32x4 ) ); corr_QC_s64x2[ 0 ] = vsraq_n_s64( corr_QC_s64x2[ 0 ], t_s64x2[ 0 ], 2 * QS - QC ); corr_QC_s64x2[ 1 ] = vsraq_n_s64( corr_QC_s64x2[ 1 ], t_s64x2[ 1 ], 2 * QS - QC ); vst1q_s64( corr_QC + offset + 0, corr_QC_s64x2[ 0 ] ); vst1q_s64( corr_QC + offset + 2, corr_QC_s64x2[ 1 ] ); } static OPUS_INLINE int32x4_t calc_state( const int32x4_t state_QS0_s32x4, const int32x4_t state_QS0_1_s32x4, const int32x4_t state_QS1_1_s32x4, const int32x4_t warping_Q16_s32x4 ) { int32x4_t t_s32x4 = vsubq_s32( state_QS0_s32x4, state_QS0_1_s32x4 ); t_s32x4 = vqdmulhq_s32( t_s32x4, warping_Q16_s32x4 ); return vaddq_s32( state_QS1_1_s32x4, t_s32x4 ); } void silk_warped_autocorrelation_FIX_neon( opus_int32 *corr, /* O Result [order + 1] */ opus_int *scale, /* O Scaling of the correlation vector */ const opus_int16 *input, /* I Input data to correlate */ const opus_int warping_Q16, /* I Warping coefficient */ const opus_int length, /* I Length of input */ const opus_int order /* I Correlation order (even) */ ) { if( ( MAX_SHAPE_LPC_ORDER > 24 ) || ( order < 6 ) ) { silk_warped_autocorrelation_FIX_c( corr, scale, input, warping_Q16, length, order ); } else { opus_int n, i, lsh; opus_int64 corr_QC[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; /* In reverse order */ opus_int64 corr_QC_orderT; int64x2_t lsh_s64x2; const opus_int orderT = ( order + 3 ) & ~3; opus_int64 *corr_QCT; opus_int32 *input_QS; VARDECL( opus_int32, input_QST ); VARDECL( opus_int32, state ); SAVE_STACK; /* Order must be even */ silk_assert( ( order & 1 ) == 0 ); silk_assert( 2 * QS - QC >= 0 ); ALLOC( input_QST, length + 2 * MAX_SHAPE_LPC_ORDER, opus_int32 ); input_QS = input_QST; /* input_QS has zero paddings in the beginning and end. */ vst1q_s32( input_QS, vdupq_n_s32( 0 ) ); input_QS += 4; vst1q_s32( input_QS, vdupq_n_s32( 0 ) ); input_QS += 4; vst1q_s32( input_QS, vdupq_n_s32( 0 ) ); input_QS += 4; vst1q_s32( input_QS, vdupq_n_s32( 0 ) ); input_QS += 4; vst1q_s32( input_QS, vdupq_n_s32( 0 ) ); input_QS += 4; vst1q_s32( input_QS, vdupq_n_s32( 0 ) ); input_QS += 4; /* Loop over samples */ for( n = 0; n < length - 7; n += 8, input_QS += 8 ) { const int16x8_t t0_s16x4 = vld1q_s16( input + n ); vst1q_s32( input_QS + 0, vshll_n_s16( vget_low_s16( t0_s16x4 ), QS ) ); vst1q_s32( input_QS + 4, vshll_n_s16( vget_high_s16( t0_s16x4 ), QS ) ); } for( ; n < length; n++, input_QS++ ) { input_QS[ 0 ] = silk_LSHIFT32( (opus_int32)input[ n ], QS ); } vst1q_s32( input_QS, vdupq_n_s32( 0 ) ); input_QS += 4; vst1q_s32( input_QS, vdupq_n_s32( 0 ) ); input_QS += 4; vst1q_s32( input_QS, vdupq_n_s32( 0 ) ); input_QS += 4; vst1q_s32( input_QS, vdupq_n_s32( 0 ) ); input_QS += 4; vst1q_s32( input_QS, vdupq_n_s32( 0 ) ); input_QS += 4; vst1q_s32( input_QS, vdupq_n_s32( 0 ) ); input_QS = input_QST + MAX_SHAPE_LPC_ORDER - orderT; /* The following loop runs ( length + order ) times, with ( order ) extra epilogues. */ /* The zero paddings in input_QS guarantee corr_QC's correctness even with the extra epilogues. */ /* The values of state_QS will be polluted by the extra epilogues, however they are temporary values. */ /* Keep the C code here to help understand the intrinsics optimization. */ /* { opus_int32 state_QS[ 2 ][ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; opus_int32 *state_QST[ 3 ]; state_QST[ 0 ] = state_QS[ 0 ]; state_QST[ 1 ] = state_QS[ 1 ]; for( n = 0; n < length + order; n++, input_QS++ ) { state_QST[ 0 ][ orderT ] = input_QS[ orderT ]; for( i = 0; i < orderT; i++ ) { corr_QC[ i ] += silk_RSHIFT64( silk_SMULL( state_QST[ 0 ][ i ], input_QS[ i ] ), 2 * QS - QC ); state_QST[ 1 ][ i ] = silk_SMLAWB( state_QST[ 1 ][ i + 1 ], state_QST[ 0 ][ i ] - state_QST[ 0 ][ i + 1 ], warping_Q16 ); } state_QST[ 2 ] = state_QST[ 0 ]; state_QST[ 0 ] = state_QST[ 1 ]; state_QST[ 1 ] = state_QST[ 2 ]; } } */ { const int32x4_t warping_Q16_s32x4 = vdupq_n_s32( warping_Q16 << 15 ); const opus_int32 *in = input_QS + orderT; opus_int o = orderT; int32x4_t state_QS_s32x4[ 3 ][ 2 ]; ALLOC( state, length + orderT, opus_int32 ); state_QS_s32x4[ 2 ][ 1 ] = vdupq_n_s32( 0 ); /* Calculate 8 taps of all inputs in each loop. */ do { state_QS_s32x4[ 0 ][ 0 ] = state_QS_s32x4[ 0 ][ 1 ] = state_QS_s32x4[ 1 ][ 0 ] = state_QS_s32x4[ 1 ][ 1 ] = vdupq_n_s32( 0 ); n = 0; do { calc_corr( input_QS + n, corr_QC, o - 8, state_QS_s32x4[ 0 ][ 0 ] ); calc_corr( input_QS + n, corr_QC, o - 4, state_QS_s32x4[ 0 ][ 1 ] ); state_QS_s32x4[ 2 ][ 1 ] = vld1q_s32( in + n ); vst1q_lane_s32( state + n, state_QS_s32x4[ 0 ][ 0 ], 0 ); state_QS_s32x4[ 2 ][ 0 ] = vextq_s32( state_QS_s32x4[ 0 ][ 0 ], state_QS_s32x4[ 0 ][ 1 ], 1 ); state_QS_s32x4[ 2 ][ 1 ] = vextq_s32( state_QS_s32x4[ 0 ][ 1 ], state_QS_s32x4[ 2 ][ 1 ], 1 ); state_QS_s32x4[ 0 ][ 0 ] = calc_state( state_QS_s32x4[ 0 ][ 0 ], state_QS_s32x4[ 2 ][ 0 ], state_QS_s32x4[ 1 ][ 0 ], warping_Q16_s32x4 ); state_QS_s32x4[ 0 ][ 1 ] = calc_state( state_QS_s32x4[ 0 ][ 1 ], state_QS_s32x4[ 2 ][ 1 ], state_QS_s32x4[ 1 ][ 1 ], warping_Q16_s32x4 ); state_QS_s32x4[ 1 ][ 0 ] = state_QS_s32x4[ 2 ][ 0 ]; state_QS_s32x4[ 1 ][ 1 ] = state_QS_s32x4[ 2 ][ 1 ]; } while( ++n < ( length + order ) ); in = state; o -= 8; } while( o > 4 ); if( o ) { /* Calculate the last 4 taps of all inputs. */ opus_int32 *stateT = state; silk_assert( o == 4 ); state_QS_s32x4[ 0 ][ 0 ] = state_QS_s32x4[ 1 ][ 0 ] = vdupq_n_s32( 0 ); n = length + order; do { calc_corr( input_QS, corr_QC, 0, state_QS_s32x4[ 0 ][ 0 ] ); state_QS_s32x4[ 2 ][ 0 ] = vld1q_s32( stateT ); vst1q_lane_s32( stateT, state_QS_s32x4[ 0 ][ 0 ], 0 ); state_QS_s32x4[ 2 ][ 0 ] = vextq_s32( state_QS_s32x4[ 0 ][ 0 ], state_QS_s32x4[ 2 ][ 0 ], 1 ); state_QS_s32x4[ 0 ][ 0 ] = calc_state( state_QS_s32x4[ 0 ][ 0 ], state_QS_s32x4[ 2 ][ 0 ], state_QS_s32x4[ 1 ][ 0 ], warping_Q16_s32x4 ); state_QS_s32x4[ 1 ][ 0 ] = state_QS_s32x4[ 2 ][ 0 ]; input_QS++; stateT++; } while( --n ); } } { const opus_int16 *inputT = input; int32x4_t t_s32x4; int64x1_t t_s64x1; int64x2_t t_s64x2 = vdupq_n_s64( 0 ); for( n = 0; n <= length - 8; n += 8 ) { int16x8_t input_s16x8 = vld1q_s16( inputT ); t_s32x4 = vmull_s16( vget_low_s16( input_s16x8 ), vget_low_s16( input_s16x8 ) ); t_s32x4 = vmlal_s16( t_s32x4, vget_high_s16( input_s16x8 ), vget_high_s16( input_s16x8 ) ); t_s64x2 = vaddw_s32( t_s64x2, vget_low_s32( t_s32x4 ) ); t_s64x2 = vaddw_s32( t_s64x2, vget_high_s32( t_s32x4 ) ); inputT += 8; } t_s64x1 = vadd_s64( vget_low_s64( t_s64x2 ), vget_high_s64( t_s64x2 ) ); corr_QC_orderT = vget_lane_s64( t_s64x1, 0 ); for( ; n < length; n++ ) { corr_QC_orderT += silk_SMULL( input[ n ], input[ n ] ); } corr_QC_orderT = silk_LSHIFT64( corr_QC_orderT, QC ); corr_QC[ orderT ] = corr_QC_orderT; } corr_QCT = corr_QC + orderT - order; lsh = silk_CLZ64( corr_QC_orderT ) - 35; lsh = silk_LIMIT( lsh, -12 - QC, 30 - QC ); *scale = -( QC + lsh ); silk_assert( *scale >= -30 && *scale <= 12 ); lsh_s64x2 = vdupq_n_s64( lsh ); for( i = 0; i <= order - 3; i += 4 ) { int32x4_t corr_s32x4; int64x2_t corr_QC0_s64x2, corr_QC1_s64x2; corr_QC0_s64x2 = vld1q_s64( corr_QCT + i ); corr_QC1_s64x2 = vld1q_s64( corr_QCT + i + 2 ); corr_QC0_s64x2 = vshlq_s64( corr_QC0_s64x2, lsh_s64x2 ); corr_QC1_s64x2 = vshlq_s64( corr_QC1_s64x2, lsh_s64x2 ); corr_s32x4 = vcombine_s32( vmovn_s64( corr_QC1_s64x2 ), vmovn_s64( corr_QC0_s64x2 ) ); corr_s32x4 = vrev64q_s32( corr_s32x4 ); vst1q_s32( corr + order - i - 3, corr_s32x4 ); } if( lsh >= 0 ) { for( ; i < order + 1; i++ ) { corr[ order - i ] = (opus_int32)silk_CHECK_FIT32( silk_LSHIFT64( corr_QCT[ i ], lsh ) ); } } else { for( ; i < order + 1; i++ ) { corr[ order - i ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( corr_QCT[ i ], -lsh ) ); } } silk_assert( corr_QCT[ order ] >= 0 ); /* If breaking, decrease QC*/ RESTORE_STACK; } #ifdef OPUS_CHECK_ASM { opus_int32 corr_c[ MAX_SHAPE_LPC_ORDER + 1 ]; opus_int scale_c; silk_warped_autocorrelation_FIX_c( corr_c, &scale_c, input, warping_Q16, length, order ); silk_assert( !memcmp( corr_c, corr, sizeof( corr_c[ 0 ] ) * ( order + 1 ) ) ); silk_assert( scale_c == *scale ); } #endif } jamulus-3.9.1+dfsg/libs/opus/silk/fixed/main_FIX.h0000644000175000017500000004541714340334543020752 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SILK_MAIN_FIX_H #define SILK_MAIN_FIX_H #include "SigProc_FIX.h" #include "structs_FIX.h" #include "control.h" #include "main.h" #include "PLC.h" #include "debug.h" #include "entenc.h" #if ((defined(OPUS_ARM_ASM) && defined(FIXED_POINT)) \ || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)) #include "fixed/arm/warped_autocorrelation_FIX_arm.h" #endif #ifndef FORCE_CPP_BUILD #ifdef __cplusplus extern "C" { #endif #endif #define silk_encoder_state_Fxx silk_encoder_state_FIX #define silk_encode_do_VAD_Fxx silk_encode_do_VAD_FIX #define silk_encode_frame_Fxx silk_encode_frame_FIX #define QC 10 #define QS 13 /*********************/ /* Encoder Functions */ /*********************/ /* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */ void silk_HP_variable_cutoff( silk_encoder_state_Fxx state_Fxx[] /* I/O Encoder states */ ); /* Encoder main function */ void silk_encode_do_VAD_FIX( silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ opus_int activity /* I Decision of Opus voice activity detector */ ); /* Encoder main function */ opus_int silk_encode_frame_FIX( silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ opus_int32 *pnBytesOut, /* O Pointer to number of payload bytes; */ ec_enc *psRangeEnc, /* I/O compressor data structure */ opus_int condCoding, /* I The type of conditional coding to use */ opus_int maxBits, /* I If > 0: maximum number of output bits */ opus_int useCBR /* I Flag to force constant-bitrate operation */ ); /* Initializes the Silk encoder state */ opus_int silk_init_encoder( silk_encoder_state_Fxx *psEnc, /* I/O Pointer to Silk FIX encoder state */ int arch /* I Run-time architecture */ ); /* Control the Silk encoder */ opus_int silk_control_encoder( silk_encoder_state_Fxx *psEnc, /* I/O Pointer to Silk encoder state */ silk_EncControlStruct *encControl, /* I Control structure */ const opus_int allow_bw_switch, /* I Flag to allow switching audio bandwidth */ const opus_int channelNb, /* I Channel number */ const opus_int force_fs_kHz ); /**************************/ /* Noise shaping analysis */ /**************************/ /* Compute noise shaping coefficients and initial gain values */ void silk_noise_shape_analysis_FIX( silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */ silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */ const opus_int16 *pitch_res, /* I LPC residual from pitch analysis */ const opus_int16 *x, /* I Input signal [ frame_length + la_shape ] */ int arch /* I Run-time architecture */ ); /* Autocorrelations for a warped frequency axis */ void silk_warped_autocorrelation_FIX_c( opus_int32 *corr, /* O Result [order + 1] */ opus_int *scale, /* O Scaling of the correlation vector */ const opus_int16 *input, /* I Input data to correlate */ const opus_int warping_Q16, /* I Warping coefficient */ const opus_int length, /* I Length of input */ const opus_int order /* I Correlation order (even) */ ); #if !defined(OVERRIDE_silk_warped_autocorrelation_FIX) #define silk_warped_autocorrelation_FIX(corr, scale, input, warping_Q16, length, order, arch) \ ((void)(arch), silk_warped_autocorrelation_FIX_c(corr, scale, input, warping_Q16, length, order)) #endif /* Calculation of LTP state scaling */ void silk_LTP_scale_ctrl_FIX( silk_encoder_state_FIX *psEnc, /* I/O encoder state */ silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ opus_int condCoding /* I The type of conditional coding to use */ ); /**********************************************/ /* Prediction Analysis */ /**********************************************/ /* Find pitch lags */ void silk_find_pitch_lags_FIX( silk_encoder_state_FIX *psEnc, /* I/O encoder state */ silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ opus_int16 res[], /* O residual */ const opus_int16 x[], /* I Speech signal */ int arch /* I Run-time architecture */ ); /* Find LPC and LTP coefficients */ void silk_find_pred_coefs_FIX( silk_encoder_state_FIX *psEnc, /* I/O encoder state */ silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ const opus_int16 res_pitch[], /* I Residual from pitch analysis */ const opus_int16 x[], /* I Speech signal */ opus_int condCoding /* I The type of conditional coding to use */ ); /* LPC analysis */ void silk_find_LPC_FIX( silk_encoder_state *psEncC, /* I/O Encoder state */ opus_int16 NLSF_Q15[], /* O NLSFs */ const opus_int16 x[], /* I Input signal */ const opus_int32 minInvGain_Q30 /* I Inverse of max prediction gain */ ); /* LTP analysis */ void silk_find_LTP_FIX( opus_int32 XXLTP_Q17[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Correlation matrix */ opus_int32 xXLTP_Q17[ MAX_NB_SUBFR * LTP_ORDER ], /* O Correlation vector */ const opus_int16 r_lpc[], /* I Residual signal after LPC */ const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */ const opus_int subfr_length, /* I Subframe length */ const opus_int nb_subfr, /* I Number of subframes */ int arch /* I Run-time architecture */ ); void silk_LTP_analysis_filter_FIX( opus_int16 *LTP_res, /* O LTP residual signal of length MAX_NB_SUBFR * ( pre_length + subfr_length ) */ const opus_int16 *x, /* I Pointer to input signal with at least max( pitchL ) preceding samples */ const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],/* I LTP_ORDER LTP coefficients for each MAX_NB_SUBFR subframe */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag, one for each subframe */ const opus_int32 invGains_Q16[ MAX_NB_SUBFR ], /* I Inverse quantization gains, one for each subframe */ const opus_int subfr_length, /* I Length of each subframe */ const opus_int nb_subfr, /* I Number of subframes */ const opus_int pre_length /* I Length of the preceding samples starting at &x[0] for each subframe */ ); /* Calculates residual energies of input subframes where all subframes have LPC_order */ /* of preceding samples */ void silk_residual_energy_FIX( opus_int32 nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */ opus_int nrgsQ[ MAX_NB_SUBFR ], /* O Q value per subframe */ const opus_int16 x[], /* I Input signal */ opus_int16 a_Q12[ 2 ][ MAX_LPC_ORDER ], /* I AR coefs for each frame half */ const opus_int32 gains[ MAX_NB_SUBFR ], /* I Quantization gains */ const opus_int subfr_length, /* I Subframe length */ const opus_int nb_subfr, /* I Number of subframes */ const opus_int LPC_order, /* I LPC order */ int arch /* I Run-time architecture */ ); /* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */ opus_int32 silk_residual_energy16_covar_FIX( const opus_int16 *c, /* I Prediction vector */ const opus_int32 *wXX, /* I Correlation matrix */ const opus_int32 *wXx, /* I Correlation vector */ opus_int32 wxx, /* I Signal energy */ opus_int D, /* I Dimension */ opus_int cQ /* I Q value for c vector 0 - 15 */ ); /* Processing of gains */ void silk_process_gains_FIX( silk_encoder_state_FIX *psEnc, /* I/O Encoder state */ silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control */ opus_int condCoding /* I The type of conditional coding to use */ ); /******************/ /* Linear Algebra */ /******************/ /* Calculates correlation matrix X'*X */ void silk_corrMatrix_FIX( const opus_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */ const opus_int L, /* I Length of vectors */ const opus_int order, /* I Max lag for correlation */ opus_int32 *XX, /* O Pointer to X'*X correlation matrix [ order x order ] */ opus_int32 *nrg, /* O Energy of x vector */ opus_int *rshifts, /* O Right shifts of correlations */ int arch /* I Run-time architecture */ ); /* Calculates correlation vector X'*t */ void silk_corrVector_FIX( const opus_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */ const opus_int16 *t, /* I Target vector [L] */ const opus_int L, /* I Length of vectors */ const opus_int order, /* I Max lag for correlation */ opus_int32 *Xt, /* O Pointer to X'*t correlation vector [order] */ const opus_int rshifts, /* I Right shifts of correlations */ int arch /* I Run-time architecture */ ); #ifndef FORCE_CPP_BUILD #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* FORCE_CPP_BUILD */ #endif /* SILK_MAIN_FIX_H */ jamulus-3.9.1+dfsg/libs/opus/silk/tests/0000755000175000017500000000000014340334543017177 5ustar vimervimerjamulus-3.9.1+dfsg/libs/opus/silk/tests/test_unit_LPC_inv_pred_gain.c0000644000175000017500000001125714340334543024751 0ustar vimervimer/*********************************************************************** Copyright (c) 2017 Google Inc., Jean-Marc Valin Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "celt/stack_alloc.h" #include "cpu_support.h" #include "SigProc_FIX.h" /* Computes the impulse response of the filter so we can catch filters that are definitely unstable. Some unstable filters may be classified as stable, but not the other way around. */ int check_stability(opus_int16 *A_Q12, int order) { int i; int j; int sum_a, sum_abs_a; sum_a = sum_abs_a = 0; for( j = 0; j < order; j++ ) { sum_a += A_Q12[ j ]; sum_abs_a += silk_abs( A_Q12[ j ] ); } /* Check DC stability. */ if( sum_a >= 4096 ) { return 0; } /* If the sum of absolute values is less than 1, the filter has to be stable. */ if( sum_abs_a < 4096 ) { return 1; } double y[SILK_MAX_ORDER_LPC] = {0}; y[0] = 1; for( i = 0; i < 10000; i++ ) { double sum = 0; for( j = 0; j < order; j++ ) { sum += y[ j ]*A_Q12[ j ]; } for( j = order - 1; j > 0; j-- ) { y[ j ] = y[ j - 1 ]; } y[ 0 ] = sum*(1./4096); /* If impulse response reaches +/- 10000, the filter is definitely unstable. */ if( !(y[ 0 ] < 10000 && y[ 0 ] > -10000) ) { return 0; } /* Test every 8 sample for low amplitude. */ if( ( i & 0x7 ) == 0 ) { double amp = 0; for( j = 0; j < order; j++ ) { amp += fabs(y[j]); } if( amp < 0.00001 ) { return 1; } } } return 1; } int main(void) { const int arch = opus_select_arch(); /* Set to 10000 so all branches in C function are triggered */ const int loop_num = 10000; int count = 0; ALLOC_STACK; /* FIXME: Make the seed random (with option to set it explicitly) so we get wider coverage. */ srand(0); printf("Testing silk_LPC_inverse_pred_gain() optimization ...\n"); for( count = 0; count < loop_num; count++ ) { unsigned int i; opus_int order; unsigned int shift; opus_int16 A_Q12[ SILK_MAX_ORDER_LPC ]; opus_int32 gain; for( order = 2; order <= SILK_MAX_ORDER_LPC; order += 2 ) { /* order must be even. */ for( shift = 0; shift < 16; shift++ ) { /* Different dynamic range. */ for( i = 0; i < SILK_MAX_ORDER_LPC; i++ ) { A_Q12[i] = ((opus_int16)rand()) >> shift; } gain = silk_LPC_inverse_pred_gain(A_Q12, order, arch); /* Look for filters that silk_LPC_inverse_pred_gain() thinks are stable but definitely aren't. */ if( gain != 0 && !check_stability(A_Q12, order) ) { fprintf(stderr, "**Loop %4d failed!**\n", count); return 1; } } } if( !(count % 500) ) { printf("Loop %4d passed\n", count); } } printf("silk_LPC_inverse_pred_gain() optimization passed\n"); return 0; } jamulus-3.9.1+dfsg/libs/opus/silk/NSQ.h0000644000175000017500000001030014340334543016641 0ustar vimervimer/*********************************************************************** Copyright (c) 2014 Vidyo. Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SILK_NSQ_H #define SILK_NSQ_H #include "SigProc_FIX.h" #undef silk_short_prediction_create_arch_coef static OPUS_INLINE opus_int32 silk_noise_shape_quantizer_short_prediction_c(const opus_int32 *buf32, const opus_int16 *coef16, opus_int order) { opus_int32 out; silk_assert( order == 10 || order == 16 ); /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ out = silk_RSHIFT( order, 1 ); out = silk_SMLAWB( out, buf32[ 0 ], coef16[ 0 ] ); out = silk_SMLAWB( out, buf32[ -1 ], coef16[ 1 ] ); out = silk_SMLAWB( out, buf32[ -2 ], coef16[ 2 ] ); out = silk_SMLAWB( out, buf32[ -3 ], coef16[ 3 ] ); out = silk_SMLAWB( out, buf32[ -4 ], coef16[ 4 ] ); out = silk_SMLAWB( out, buf32[ -5 ], coef16[ 5 ] ); out = silk_SMLAWB( out, buf32[ -6 ], coef16[ 6 ] ); out = silk_SMLAWB( out, buf32[ -7 ], coef16[ 7 ] ); out = silk_SMLAWB( out, buf32[ -8 ], coef16[ 8 ] ); out = silk_SMLAWB( out, buf32[ -9 ], coef16[ 9 ] ); if( order == 16 ) { out = silk_SMLAWB( out, buf32[ -10 ], coef16[ 10 ] ); out = silk_SMLAWB( out, buf32[ -11 ], coef16[ 11 ] ); out = silk_SMLAWB( out, buf32[ -12 ], coef16[ 12 ] ); out = silk_SMLAWB( out, buf32[ -13 ], coef16[ 13 ] ); out = silk_SMLAWB( out, buf32[ -14 ], coef16[ 14 ] ); out = silk_SMLAWB( out, buf32[ -15 ], coef16[ 15 ] ); } return out; } #define silk_noise_shape_quantizer_short_prediction(in, coef, coefRev, order, arch) ((void)arch,silk_noise_shape_quantizer_short_prediction_c(in, coef, order)) static OPUS_INLINE opus_int32 silk_NSQ_noise_shape_feedback_loop_c(const opus_int32 *data0, opus_int32 *data1, const opus_int16 *coef, opus_int order) { opus_int32 out; opus_int32 tmp1, tmp2; opus_int j; tmp2 = data0[0]; tmp1 = data1[0]; data1[0] = tmp2; out = silk_RSHIFT(order, 1); out = silk_SMLAWB(out, tmp2, coef[0]); for (j = 2; j < order; j += 2) { tmp2 = data1[j - 1]; data1[j - 1] = tmp1; out = silk_SMLAWB(out, tmp1, coef[j - 1]); tmp1 = data1[j + 0]; data1[j + 0] = tmp2; out = silk_SMLAWB(out, tmp2, coef[j]); } data1[order - 1] = tmp1; out = silk_SMLAWB(out, tmp1, coef[order - 1]); /* Q11 -> Q12 */ out = silk_LSHIFT32( out, 1 ); return out; } #define silk_NSQ_noise_shape_feedback_loop(data0, data1, coef, order, arch) ((void)arch,silk_NSQ_noise_shape_feedback_loop_c(data0, data1, coef, order)) #if defined(OPUS_ARM_MAY_HAVE_NEON_INTR) #include "arm/NSQ_neon.h" #endif #endif /* SILK_NSQ_H */ jamulus-3.9.1+dfsg/libs/opus/silk/LP_variable_cutoff.c0000644000175000017500000001463014340334543021733 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* Elliptic/Cauer filters designed with 0.1 dB passband ripple, 80 dB minimum stopband attenuation, and [0.95 : 0.15 : 0.35] normalized cut off frequencies. */ #include "main.h" /* Helper function, interpolates the filter taps */ static OPUS_INLINE void silk_LP_interpolate_filter_taps( opus_int32 B_Q28[ TRANSITION_NB ], opus_int32 A_Q28[ TRANSITION_NA ], const opus_int ind, const opus_int32 fac_Q16 ) { opus_int nb, na; if( ind < TRANSITION_INT_NUM - 1 ) { if( fac_Q16 > 0 ) { if( fac_Q16 < 32768 ) { /* fac_Q16 is in range of a 16-bit int */ /* Piece-wise linear interpolation of B and A */ for( nb = 0; nb < TRANSITION_NB; nb++ ) { B_Q28[ nb ] = silk_SMLAWB( silk_Transition_LP_B_Q28[ ind ][ nb ], silk_Transition_LP_B_Q28[ ind + 1 ][ nb ] - silk_Transition_LP_B_Q28[ ind ][ nb ], fac_Q16 ); } for( na = 0; na < TRANSITION_NA; na++ ) { A_Q28[ na ] = silk_SMLAWB( silk_Transition_LP_A_Q28[ ind ][ na ], silk_Transition_LP_A_Q28[ ind + 1 ][ na ] - silk_Transition_LP_A_Q28[ ind ][ na ], fac_Q16 ); } } else { /* ( fac_Q16 - ( 1 << 16 ) ) is in range of a 16-bit int */ silk_assert( fac_Q16 - ( 1 << 16 ) == silk_SAT16( fac_Q16 - ( 1 << 16 ) ) ); /* Piece-wise linear interpolation of B and A */ for( nb = 0; nb < TRANSITION_NB; nb++ ) { B_Q28[ nb ] = silk_SMLAWB( silk_Transition_LP_B_Q28[ ind + 1 ][ nb ], silk_Transition_LP_B_Q28[ ind + 1 ][ nb ] - silk_Transition_LP_B_Q28[ ind ][ nb ], fac_Q16 - ( (opus_int32)1 << 16 ) ); } for( na = 0; na < TRANSITION_NA; na++ ) { A_Q28[ na ] = silk_SMLAWB( silk_Transition_LP_A_Q28[ ind + 1 ][ na ], silk_Transition_LP_A_Q28[ ind + 1 ][ na ] - silk_Transition_LP_A_Q28[ ind ][ na ], fac_Q16 - ( (opus_int32)1 << 16 ) ); } } } else { silk_memcpy( B_Q28, silk_Transition_LP_B_Q28[ ind ], TRANSITION_NB * sizeof( opus_int32 ) ); silk_memcpy( A_Q28, silk_Transition_LP_A_Q28[ ind ], TRANSITION_NA * sizeof( opus_int32 ) ); } } else { silk_memcpy( B_Q28, silk_Transition_LP_B_Q28[ TRANSITION_INT_NUM - 1 ], TRANSITION_NB * sizeof( opus_int32 ) ); silk_memcpy( A_Q28, silk_Transition_LP_A_Q28[ TRANSITION_INT_NUM - 1 ], TRANSITION_NA * sizeof( opus_int32 ) ); } } /* Low-pass filter with variable cutoff frequency based on */ /* piece-wise linear interpolation between elliptic filters */ /* Start by setting psEncC->mode <> 0; */ /* Deactivate by setting psEncC->mode = 0; */ void silk_LP_variable_cutoff( silk_LP_state *psLP, /* I/O LP filter state */ opus_int16 *frame, /* I/O Low-pass filtered output signal */ const opus_int frame_length /* I Frame length */ ) { opus_int32 B_Q28[ TRANSITION_NB ], A_Q28[ TRANSITION_NA ], fac_Q16 = 0; opus_int ind = 0; silk_assert( psLP->transition_frame_no >= 0 && psLP->transition_frame_no <= TRANSITION_FRAMES ); /* Run filter if needed */ if( psLP->mode != 0 ) { /* Calculate index and interpolation factor for interpolation */ #if( TRANSITION_INT_STEPS == 64 ) fac_Q16 = silk_LSHIFT( TRANSITION_FRAMES - psLP->transition_frame_no, 16 - 6 ); #else fac_Q16 = silk_DIV32_16( silk_LSHIFT( TRANSITION_FRAMES - psLP->transition_frame_no, 16 ), TRANSITION_FRAMES ); #endif ind = silk_RSHIFT( fac_Q16, 16 ); fac_Q16 -= silk_LSHIFT( ind, 16 ); silk_assert( ind >= 0 ); silk_assert( ind < TRANSITION_INT_NUM ); /* Interpolate filter coefficients */ silk_LP_interpolate_filter_taps( B_Q28, A_Q28, ind, fac_Q16 ); /* Update transition frame number for next frame */ psLP->transition_frame_no = silk_LIMIT( psLP->transition_frame_no + psLP->mode, 0, TRANSITION_FRAMES ); /* ARMA low-pass filtering */ silk_assert( TRANSITION_NB == 3 && TRANSITION_NA == 2 ); silk_biquad_alt_stride1( frame, B_Q28, A_Q28, psLP->In_LP_State, frame, frame_length); } } jamulus-3.9.1+dfsg/libs/opus/silk/CNG.c0000644000175000017500000002257314340334543016621 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" #include "stack_alloc.h" /* Generates excitation for CNG LPC synthesis */ static OPUS_INLINE void silk_CNG_exc( opus_int32 exc_Q14[], /* O CNG excitation signal Q10 */ opus_int32 exc_buf_Q14[], /* I Random samples buffer Q10 */ opus_int length, /* I Length */ opus_int32 *rand_seed /* I/O Seed to random index generator */ ) { opus_int32 seed; opus_int i, idx, exc_mask; exc_mask = CNG_BUF_MASK_MAX; while( exc_mask > length ) { exc_mask = silk_RSHIFT( exc_mask, 1 ); } seed = *rand_seed; for( i = 0; i < length; i++ ) { seed = silk_RAND( seed ); idx = (opus_int)( silk_RSHIFT( seed, 24 ) & exc_mask ); silk_assert( idx >= 0 ); silk_assert( idx <= CNG_BUF_MASK_MAX ); exc_Q14[ i ] = exc_buf_Q14[ idx ]; } *rand_seed = seed; } void silk_CNG_Reset( silk_decoder_state *psDec /* I/O Decoder state */ ) { opus_int i, NLSF_step_Q15, NLSF_acc_Q15; NLSF_step_Q15 = silk_DIV32_16( silk_int16_MAX, psDec->LPC_order + 1 ); NLSF_acc_Q15 = 0; for( i = 0; i < psDec->LPC_order; i++ ) { NLSF_acc_Q15 += NLSF_step_Q15; psDec->sCNG.CNG_smth_NLSF_Q15[ i ] = NLSF_acc_Q15; } psDec->sCNG.CNG_smth_Gain_Q16 = 0; psDec->sCNG.rand_seed = 3176576; } /* Updates CNG estimate, and applies the CNG when packet was lost */ void silk_CNG( silk_decoder_state *psDec, /* I/O Decoder state */ silk_decoder_control *psDecCtrl, /* I/O Decoder control */ opus_int16 frame[], /* I/O Signal */ opus_int length /* I Length of residual */ ) { opus_int i, subfr; opus_int32 LPC_pred_Q10, max_Gain_Q16, gain_Q16, gain_Q10; opus_int16 A_Q12[ MAX_LPC_ORDER ]; silk_CNG_struct *psCNG = &psDec->sCNG; SAVE_STACK; if( psDec->fs_kHz != psCNG->fs_kHz ) { /* Reset state */ silk_CNG_Reset( psDec ); psCNG->fs_kHz = psDec->fs_kHz; } if( psDec->lossCnt == 0 && psDec->prevSignalType == TYPE_NO_VOICE_ACTIVITY ) { /* Update CNG parameters */ /* Smoothing of LSF's */ for( i = 0; i < psDec->LPC_order; i++ ) { psCNG->CNG_smth_NLSF_Q15[ i ] += silk_SMULWB( (opus_int32)psDec->prevNLSF_Q15[ i ] - (opus_int32)psCNG->CNG_smth_NLSF_Q15[ i ], CNG_NLSF_SMTH_Q16 ); } /* Find the subframe with the highest gain */ max_Gain_Q16 = 0; subfr = 0; for( i = 0; i < psDec->nb_subfr; i++ ) { if( psDecCtrl->Gains_Q16[ i ] > max_Gain_Q16 ) { max_Gain_Q16 = psDecCtrl->Gains_Q16[ i ]; subfr = i; } } /* Update CNG excitation buffer with excitation from this subframe */ silk_memmove( &psCNG->CNG_exc_buf_Q14[ psDec->subfr_length ], psCNG->CNG_exc_buf_Q14, ( psDec->nb_subfr - 1 ) * psDec->subfr_length * sizeof( opus_int32 ) ); silk_memcpy( psCNG->CNG_exc_buf_Q14, &psDec->exc_Q14[ subfr * psDec->subfr_length ], psDec->subfr_length * sizeof( opus_int32 ) ); /* Smooth gains */ for( i = 0; i < psDec->nb_subfr; i++ ) { psCNG->CNG_smth_Gain_Q16 += silk_SMULWB( psDecCtrl->Gains_Q16[ i ] - psCNG->CNG_smth_Gain_Q16, CNG_GAIN_SMTH_Q16 ); } } /* Add CNG when packet is lost or during DTX */ if( psDec->lossCnt ) { VARDECL( opus_int32, CNG_sig_Q14 ); ALLOC( CNG_sig_Q14, length + MAX_LPC_ORDER, opus_int32 ); /* Generate CNG excitation */ gain_Q16 = silk_SMULWW( psDec->sPLC.randScale_Q14, psDec->sPLC.prevGain_Q16[1] ); if( gain_Q16 >= (1 << 21) || psCNG->CNG_smth_Gain_Q16 > (1 << 23) ) { gain_Q16 = silk_SMULTT( gain_Q16, gain_Q16 ); gain_Q16 = silk_SUB_LSHIFT32(silk_SMULTT( psCNG->CNG_smth_Gain_Q16, psCNG->CNG_smth_Gain_Q16 ), gain_Q16, 5 ); gain_Q16 = silk_LSHIFT32( silk_SQRT_APPROX( gain_Q16 ), 16 ); } else { gain_Q16 = silk_SMULWW( gain_Q16, gain_Q16 ); gain_Q16 = silk_SUB_LSHIFT32(silk_SMULWW( psCNG->CNG_smth_Gain_Q16, psCNG->CNG_smth_Gain_Q16 ), gain_Q16, 5 ); gain_Q16 = silk_LSHIFT32( silk_SQRT_APPROX( gain_Q16 ), 8 ); } gain_Q10 = silk_RSHIFT( gain_Q16, 6 ); silk_CNG_exc( CNG_sig_Q14 + MAX_LPC_ORDER, psCNG->CNG_exc_buf_Q14, length, &psCNG->rand_seed ); /* Convert CNG NLSF to filter representation */ silk_NLSF2A( A_Q12, psCNG->CNG_smth_NLSF_Q15, psDec->LPC_order, psDec->arch ); /* Generate CNG signal, by synthesis filtering */ silk_memcpy( CNG_sig_Q14, psCNG->CNG_synth_state, MAX_LPC_ORDER * sizeof( opus_int32 ) ); celt_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 ); for( i = 0; i < length; i++ ) { /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ LPC_pred_Q10 = silk_RSHIFT( psDec->LPC_order, 1 ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 1 ], A_Q12[ 0 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 2 ], A_Q12[ 1 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 3 ], A_Q12[ 2 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 4 ], A_Q12[ 3 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 5 ], A_Q12[ 4 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 6 ], A_Q12[ 5 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 7 ], A_Q12[ 6 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 8 ], A_Q12[ 7 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 9 ], A_Q12[ 8 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 10 ], A_Q12[ 9 ] ); if( psDec->LPC_order == 16 ) { LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 11 ], A_Q12[ 10 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 12 ], A_Q12[ 11 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 13 ], A_Q12[ 12 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 14 ], A_Q12[ 13 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 15 ], A_Q12[ 14 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 16 ], A_Q12[ 15 ] ); } /* Update states */ CNG_sig_Q14[ MAX_LPC_ORDER + i ] = silk_ADD_SAT32( CNG_sig_Q14[ MAX_LPC_ORDER + i ], silk_LSHIFT_SAT32( LPC_pred_Q10, 4 ) ); /* Scale with Gain and add to input signal */ frame[ i ] = (opus_int16)silk_ADD_SAT16( frame[ i ], silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( CNG_sig_Q14[ MAX_LPC_ORDER + i ], gain_Q10 ), 8 ) ) ); } silk_memcpy( psCNG->CNG_synth_state, &CNG_sig_Q14[ length ], MAX_LPC_ORDER * sizeof( opus_int32 ) ); } else { silk_memset( psCNG->CNG_synth_state, 0, psDec->LPC_order * sizeof( opus_int32 ) ); } RESTORE_STACK; } jamulus-3.9.1+dfsg/libs/opus/silk/stereo_encode_pred.c0000644000175000017500000000550514340334543022036 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" /* Entropy code the mid/side quantization indices */ void silk_stereo_encode_pred( ec_enc *psRangeEnc, /* I/O Compressor data structure */ opus_int8 ix[ 2 ][ 3 ] /* I Quantization indices */ ) { opus_int n; /* Entropy coding */ n = 5 * ix[ 0 ][ 2 ] + ix[ 1 ][ 2 ]; celt_assert( n < 25 ); ec_enc_icdf( psRangeEnc, n, silk_stereo_pred_joint_iCDF, 8 ); for( n = 0; n < 2; n++ ) { celt_assert( ix[ n ][ 0 ] < 3 ); celt_assert( ix[ n ][ 1 ] < STEREO_QUANT_SUB_STEPS ); ec_enc_icdf( psRangeEnc, ix[ n ][ 0 ], silk_uniform3_iCDF, 8 ); ec_enc_icdf( psRangeEnc, ix[ n ][ 1 ], silk_uniform5_iCDF, 8 ); } } /* Entropy code the mid-only flag */ void silk_stereo_encode_mid_only( ec_enc *psRangeEnc, /* I/O Compressor data structure */ opus_int8 mid_only_flag ) { /* Encode flag that only mid channel is coded */ ec_enc_icdf( psRangeEnc, mid_only_flag, silk_stereo_only_code_mid_iCDF, 8 ); } jamulus-3.9.1+dfsg/libs/opus/silk/code_signs.c0000644000175000017500000001266214340334543020325 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" /*#define silk_enc_map(a) ((a) > 0 ? 1 : 0)*/ /*#define silk_dec_map(a) ((a) > 0 ? 1 : -1)*/ /* shifting avoids if-statement */ #define silk_enc_map(a) ( silk_RSHIFT( (a), 15 ) + 1 ) #define silk_dec_map(a) ( silk_LSHIFT( (a), 1 ) - 1 ) /* Encodes signs of excitation */ void silk_encode_signs( ec_enc *psRangeEnc, /* I/O Compressor data structure */ const opus_int8 pulses[], /* I pulse signal */ opus_int length, /* I length of input */ const opus_int signalType, /* I Signal type */ const opus_int quantOffsetType, /* I Quantization offset type */ const opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ] /* I Sum of absolute pulses per block */ ) { opus_int i, j, p; opus_uint8 icdf[ 2 ]; const opus_int8 *q_ptr; const opus_uint8 *icdf_ptr; icdf[ 1 ] = 0; q_ptr = pulses; i = silk_SMULBB( 7, silk_ADD_LSHIFT( quantOffsetType, signalType, 1 ) ); icdf_ptr = &silk_sign_iCDF[ i ]; length = silk_RSHIFT( length + SHELL_CODEC_FRAME_LENGTH/2, LOG2_SHELL_CODEC_FRAME_LENGTH ); for( i = 0; i < length; i++ ) { p = sum_pulses[ i ]; if( p > 0 ) { icdf[ 0 ] = icdf_ptr[ silk_min( p & 0x1F, 6 ) ]; for( j = 0; j < SHELL_CODEC_FRAME_LENGTH; j++ ) { if( q_ptr[ j ] != 0 ) { ec_enc_icdf( psRangeEnc, silk_enc_map( q_ptr[ j ]), icdf, 8 ); } } } q_ptr += SHELL_CODEC_FRAME_LENGTH; } } /* Decodes signs of excitation */ void silk_decode_signs( ec_dec *psRangeDec, /* I/O Compressor data structure */ opus_int16 pulses[], /* I/O pulse signal */ opus_int length, /* I length of input */ const opus_int signalType, /* I Signal type */ const opus_int quantOffsetType, /* I Quantization offset type */ const opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ] /* I Sum of absolute pulses per block */ ) { opus_int i, j, p; opus_uint8 icdf[ 2 ]; opus_int16 *q_ptr; const opus_uint8 *icdf_ptr; icdf[ 1 ] = 0; q_ptr = pulses; i = silk_SMULBB( 7, silk_ADD_LSHIFT( quantOffsetType, signalType, 1 ) ); icdf_ptr = &silk_sign_iCDF[ i ]; length = silk_RSHIFT( length + SHELL_CODEC_FRAME_LENGTH/2, LOG2_SHELL_CODEC_FRAME_LENGTH ); for( i = 0; i < length; i++ ) { p = sum_pulses[ i ]; if( p > 0 ) { icdf[ 0 ] = icdf_ptr[ silk_min( p & 0x1F, 6 ) ]; for( j = 0; j < SHELL_CODEC_FRAME_LENGTH; j++ ) { if( q_ptr[ j ] > 0 ) { /* attach sign */ #if 0 /* conditional implementation */ if( ec_dec_icdf( psRangeDec, icdf, 8 ) == 0 ) { q_ptr[ j ] = -q_ptr[ j ]; } #else /* implementation with shift, subtraction, multiplication */ q_ptr[ j ] *= silk_dec_map( ec_dec_icdf( psRangeDec, icdf, 8 ) ); #endif } } } q_ptr += SHELL_CODEC_FRAME_LENGTH; } } jamulus-3.9.1+dfsg/libs/opus/silk/PLC.c0000644000175000017500000004774514340334543016640 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" #include "stack_alloc.h" #include "PLC.h" #define NB_ATT 2 static const opus_int16 HARM_ATT_Q15[NB_ATT] = { 32440, 31130 }; /* 0.99, 0.95 */ static const opus_int16 PLC_RAND_ATTENUATE_V_Q15[NB_ATT] = { 31130, 26214 }; /* 0.95, 0.8 */ static const opus_int16 PLC_RAND_ATTENUATE_UV_Q15[NB_ATT] = { 32440, 29491 }; /* 0.99, 0.9 */ static OPUS_INLINE void silk_PLC_update( silk_decoder_state *psDec, /* I/O Decoder state */ silk_decoder_control *psDecCtrl /* I/O Decoder control */ ); static OPUS_INLINE void silk_PLC_conceal( silk_decoder_state *psDec, /* I/O Decoder state */ silk_decoder_control *psDecCtrl, /* I/O Decoder control */ opus_int16 frame[], /* O LPC residual signal */ int arch /* I Run-time architecture */ ); void silk_PLC_Reset( silk_decoder_state *psDec /* I/O Decoder state */ ) { psDec->sPLC.pitchL_Q8 = silk_LSHIFT( psDec->frame_length, 8 - 1 ); psDec->sPLC.prevGain_Q16[ 0 ] = SILK_FIX_CONST( 1, 16 ); psDec->sPLC.prevGain_Q16[ 1 ] = SILK_FIX_CONST( 1, 16 ); psDec->sPLC.subfr_length = 20; psDec->sPLC.nb_subfr = 2; } void silk_PLC( silk_decoder_state *psDec, /* I/O Decoder state */ silk_decoder_control *psDecCtrl, /* I/O Decoder control */ opus_int16 frame[], /* I/O signal */ opus_int lost, /* I Loss flag */ int arch /* I Run-time architecture */ ) { /* PLC control function */ if( psDec->fs_kHz != psDec->sPLC.fs_kHz ) { silk_PLC_Reset( psDec ); psDec->sPLC.fs_kHz = psDec->fs_kHz; } if( lost ) { /****************************/ /* Generate Signal */ /****************************/ silk_PLC_conceal( psDec, psDecCtrl, frame, arch ); psDec->lossCnt++; } else { /****************************/ /* Update state */ /****************************/ silk_PLC_update( psDec, psDecCtrl ); } } /**************************************************/ /* Update state of PLC */ /**************************************************/ static OPUS_INLINE void silk_PLC_update( silk_decoder_state *psDec, /* I/O Decoder state */ silk_decoder_control *psDecCtrl /* I/O Decoder control */ ) { opus_int32 LTP_Gain_Q14, temp_LTP_Gain_Q14; opus_int i, j; silk_PLC_struct *psPLC; psPLC = &psDec->sPLC; /* Update parameters used in case of packet loss */ psDec->prevSignalType = psDec->indices.signalType; LTP_Gain_Q14 = 0; if( psDec->indices.signalType == TYPE_VOICED ) { /* Find the parameters for the last subframe which contains a pitch pulse */ for( j = 0; j * psDec->subfr_length < psDecCtrl->pitchL[ psDec->nb_subfr - 1 ]; j++ ) { if( j == psDec->nb_subfr ) { break; } temp_LTP_Gain_Q14 = 0; for( i = 0; i < LTP_ORDER; i++ ) { temp_LTP_Gain_Q14 += psDecCtrl->LTPCoef_Q14[ ( psDec->nb_subfr - 1 - j ) * LTP_ORDER + i ]; } if( temp_LTP_Gain_Q14 > LTP_Gain_Q14 ) { LTP_Gain_Q14 = temp_LTP_Gain_Q14; silk_memcpy( psPLC->LTPCoef_Q14, &psDecCtrl->LTPCoef_Q14[ silk_SMULBB( psDec->nb_subfr - 1 - j, LTP_ORDER ) ], LTP_ORDER * sizeof( opus_int16 ) ); psPLC->pitchL_Q8 = silk_LSHIFT( psDecCtrl->pitchL[ psDec->nb_subfr - 1 - j ], 8 ); } } silk_memset( psPLC->LTPCoef_Q14, 0, LTP_ORDER * sizeof( opus_int16 ) ); psPLC->LTPCoef_Q14[ LTP_ORDER / 2 ] = LTP_Gain_Q14; /* Limit LT coefs */ if( LTP_Gain_Q14 < V_PITCH_GAIN_START_MIN_Q14 ) { opus_int scale_Q10; opus_int32 tmp; tmp = silk_LSHIFT( V_PITCH_GAIN_START_MIN_Q14, 10 ); scale_Q10 = silk_DIV32( tmp, silk_max( LTP_Gain_Q14, 1 ) ); for( i = 0; i < LTP_ORDER; i++ ) { psPLC->LTPCoef_Q14[ i ] = silk_RSHIFT( silk_SMULBB( psPLC->LTPCoef_Q14[ i ], scale_Q10 ), 10 ); } } else if( LTP_Gain_Q14 > V_PITCH_GAIN_START_MAX_Q14 ) { opus_int scale_Q14; opus_int32 tmp; tmp = silk_LSHIFT( V_PITCH_GAIN_START_MAX_Q14, 14 ); scale_Q14 = silk_DIV32( tmp, silk_max( LTP_Gain_Q14, 1 ) ); for( i = 0; i < LTP_ORDER; i++ ) { psPLC->LTPCoef_Q14[ i ] = silk_RSHIFT( silk_SMULBB( psPLC->LTPCoef_Q14[ i ], scale_Q14 ), 14 ); } } } else { psPLC->pitchL_Q8 = silk_LSHIFT( silk_SMULBB( psDec->fs_kHz, 18 ), 8 ); silk_memset( psPLC->LTPCoef_Q14, 0, LTP_ORDER * sizeof( opus_int16 )); } /* Save LPC coefficients */ silk_memcpy( psPLC->prevLPC_Q12, psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order * sizeof( opus_int16 ) ); psPLC->prevLTP_scale_Q14 = psDecCtrl->LTP_scale_Q14; /* Save last two gains */ silk_memcpy( psPLC->prevGain_Q16, &psDecCtrl->Gains_Q16[ psDec->nb_subfr - 2 ], 2 * sizeof( opus_int32 ) ); psPLC->subfr_length = psDec->subfr_length; psPLC->nb_subfr = psDec->nb_subfr; } static OPUS_INLINE void silk_PLC_energy(opus_int32 *energy1, opus_int *shift1, opus_int32 *energy2, opus_int *shift2, const opus_int32 *exc_Q14, const opus_int32 *prevGain_Q10, int subfr_length, int nb_subfr) { int i, k; VARDECL( opus_int16, exc_buf ); opus_int16 *exc_buf_ptr; SAVE_STACK; ALLOC( exc_buf, 2*subfr_length, opus_int16 ); /* Find random noise component */ /* Scale previous excitation signal */ exc_buf_ptr = exc_buf; for( k = 0; k < 2; k++ ) { for( i = 0; i < subfr_length; i++ ) { exc_buf_ptr[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT( silk_SMULWW( exc_Q14[ i + ( k + nb_subfr - 2 ) * subfr_length ], prevGain_Q10[ k ] ), 8 ) ); } exc_buf_ptr += subfr_length; } /* Find the subframe with lowest energy of the last two and use that as random noise generator */ silk_sum_sqr_shift( energy1, shift1, exc_buf, subfr_length ); silk_sum_sqr_shift( energy2, shift2, &exc_buf[ subfr_length ], subfr_length ); RESTORE_STACK; } static OPUS_INLINE void silk_PLC_conceal( silk_decoder_state *psDec, /* I/O Decoder state */ silk_decoder_control *psDecCtrl, /* I/O Decoder control */ opus_int16 frame[], /* O LPC residual signal */ int arch /* I Run-time architecture */ ) { opus_int i, j, k; opus_int lag, idx, sLTP_buf_idx, shift1, shift2; opus_int32 rand_seed, harm_Gain_Q15, rand_Gain_Q15, inv_gain_Q30; opus_int32 energy1, energy2, *rand_ptr, *pred_lag_ptr; opus_int32 LPC_pred_Q10, LTP_pred_Q12; opus_int16 rand_scale_Q14; opus_int16 *B_Q14; opus_int32 *sLPC_Q14_ptr; opus_int16 A_Q12[ MAX_LPC_ORDER ]; #ifdef SMALL_FOOTPRINT opus_int16 *sLTP; #else VARDECL( opus_int16, sLTP ); #endif VARDECL( opus_int32, sLTP_Q14 ); silk_PLC_struct *psPLC = &psDec->sPLC; opus_int32 prevGain_Q10[2]; SAVE_STACK; ALLOC( sLTP_Q14, psDec->ltp_mem_length + psDec->frame_length, opus_int32 ); #ifdef SMALL_FOOTPRINT /* Ugly hack that breaks aliasing rules to save stack: put sLTP at the very end of sLTP_Q14. */ sLTP = ((opus_int16*)&sLTP_Q14[psDec->ltp_mem_length + psDec->frame_length])-psDec->ltp_mem_length; #else ALLOC( sLTP, psDec->ltp_mem_length, opus_int16 ); #endif prevGain_Q10[0] = silk_RSHIFT( psPLC->prevGain_Q16[ 0 ], 6); prevGain_Q10[1] = silk_RSHIFT( psPLC->prevGain_Q16[ 1 ], 6); if( psDec->first_frame_after_reset ) { silk_memset( psPLC->prevLPC_Q12, 0, sizeof( psPLC->prevLPC_Q12 ) ); } silk_PLC_energy(&energy1, &shift1, &energy2, &shift2, psDec->exc_Q14, prevGain_Q10, psDec->subfr_length, psDec->nb_subfr); if( silk_RSHIFT( energy1, shift2 ) < silk_RSHIFT( energy2, shift1 ) ) { /* First sub-frame has lowest energy */ rand_ptr = &psDec->exc_Q14[ silk_max_int( 0, ( psPLC->nb_subfr - 1 ) * psPLC->subfr_length - RAND_BUF_SIZE ) ]; } else { /* Second sub-frame has lowest energy */ rand_ptr = &psDec->exc_Q14[ silk_max_int( 0, psPLC->nb_subfr * psPLC->subfr_length - RAND_BUF_SIZE ) ]; } /* Set up Gain to random noise component */ B_Q14 = psPLC->LTPCoef_Q14; rand_scale_Q14 = psPLC->randScale_Q14; /* Set up attenuation gains */ harm_Gain_Q15 = HARM_ATT_Q15[ silk_min_int( NB_ATT - 1, psDec->lossCnt ) ]; if( psDec->prevSignalType == TYPE_VOICED ) { rand_Gain_Q15 = PLC_RAND_ATTENUATE_V_Q15[ silk_min_int( NB_ATT - 1, psDec->lossCnt ) ]; } else { rand_Gain_Q15 = PLC_RAND_ATTENUATE_UV_Q15[ silk_min_int( NB_ATT - 1, psDec->lossCnt ) ]; } /* LPC concealment. Apply BWE to previous LPC */ silk_bwexpander( psPLC->prevLPC_Q12, psDec->LPC_order, SILK_FIX_CONST( BWE_COEF, 16 ) ); /* Preload LPC coefficients to array on stack. Gives small performance gain */ silk_memcpy( A_Q12, psPLC->prevLPC_Q12, psDec->LPC_order * sizeof( opus_int16 ) ); /* First Lost frame */ if( psDec->lossCnt == 0 ) { rand_scale_Q14 = 1 << 14; /* Reduce random noise Gain for voiced frames */ if( psDec->prevSignalType == TYPE_VOICED ) { for( i = 0; i < LTP_ORDER; i++ ) { rand_scale_Q14 -= B_Q14[ i ]; } rand_scale_Q14 = silk_max_16( 3277, rand_scale_Q14 ); /* 0.2 */ rand_scale_Q14 = (opus_int16)silk_RSHIFT( silk_SMULBB( rand_scale_Q14, psPLC->prevLTP_scale_Q14 ), 14 ); } else { /* Reduce random noise for unvoiced frames with high LPC gain */ opus_int32 invGain_Q30, down_scale_Q30; invGain_Q30 = silk_LPC_inverse_pred_gain( psPLC->prevLPC_Q12, psDec->LPC_order, arch ); down_scale_Q30 = silk_min_32( silk_RSHIFT( (opus_int32)1 << 30, LOG2_INV_LPC_GAIN_HIGH_THRES ), invGain_Q30 ); down_scale_Q30 = silk_max_32( silk_RSHIFT( (opus_int32)1 << 30, LOG2_INV_LPC_GAIN_LOW_THRES ), down_scale_Q30 ); down_scale_Q30 = silk_LSHIFT( down_scale_Q30, LOG2_INV_LPC_GAIN_HIGH_THRES ); rand_Gain_Q15 = silk_RSHIFT( silk_SMULWB( down_scale_Q30, rand_Gain_Q15 ), 14 ); } } rand_seed = psPLC->rand_seed; lag = silk_RSHIFT_ROUND( psPLC->pitchL_Q8, 8 ); sLTP_buf_idx = psDec->ltp_mem_length; /* Rewhiten LTP state */ idx = psDec->ltp_mem_length - lag - psDec->LPC_order - LTP_ORDER / 2; celt_assert( idx > 0 ); silk_LPC_analysis_filter( &sLTP[ idx ], &psDec->outBuf[ idx ], A_Q12, psDec->ltp_mem_length - idx, psDec->LPC_order, arch ); /* Scale LTP state */ inv_gain_Q30 = silk_INVERSE32_varQ( psPLC->prevGain_Q16[ 1 ], 46 ); inv_gain_Q30 = silk_min( inv_gain_Q30, silk_int32_MAX >> 1 ); for( i = idx + psDec->LPC_order; i < psDec->ltp_mem_length; i++ ) { sLTP_Q14[ i ] = silk_SMULWB( inv_gain_Q30, sLTP[ i ] ); } /***************************/ /* LTP synthesis filtering */ /***************************/ for( k = 0; k < psDec->nb_subfr; k++ ) { /* Set up pointer */ pred_lag_ptr = &sLTP_Q14[ sLTP_buf_idx - lag + LTP_ORDER / 2 ]; for( i = 0; i < psDec->subfr_length; i++ ) { /* Unrolled loop */ /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ LTP_pred_Q12 = 2; LTP_pred_Q12 = silk_SMLAWB( LTP_pred_Q12, pred_lag_ptr[ 0 ], B_Q14[ 0 ] ); LTP_pred_Q12 = silk_SMLAWB( LTP_pred_Q12, pred_lag_ptr[ -1 ], B_Q14[ 1 ] ); LTP_pred_Q12 = silk_SMLAWB( LTP_pred_Q12, pred_lag_ptr[ -2 ], B_Q14[ 2 ] ); LTP_pred_Q12 = silk_SMLAWB( LTP_pred_Q12, pred_lag_ptr[ -3 ], B_Q14[ 3 ] ); LTP_pred_Q12 = silk_SMLAWB( LTP_pred_Q12, pred_lag_ptr[ -4 ], B_Q14[ 4 ] ); pred_lag_ptr++; /* Generate LPC excitation */ rand_seed = silk_RAND( rand_seed ); idx = silk_RSHIFT( rand_seed, 25 ) & RAND_BUF_MASK; sLTP_Q14[ sLTP_buf_idx ] = silk_LSHIFT32( silk_SMLAWB( LTP_pred_Q12, rand_ptr[ idx ], rand_scale_Q14 ), 2 ); sLTP_buf_idx++; } /* Gradually reduce LTP gain */ for( j = 0; j < LTP_ORDER; j++ ) { B_Q14[ j ] = silk_RSHIFT( silk_SMULBB( harm_Gain_Q15, B_Q14[ j ] ), 15 ); } if ( psDec->indices.signalType != TYPE_NO_VOICE_ACTIVITY ) { /* Gradually reduce excitation gain */ rand_scale_Q14 = silk_RSHIFT( silk_SMULBB( rand_scale_Q14, rand_Gain_Q15 ), 15 ); } /* Slowly increase pitch lag */ psPLC->pitchL_Q8 = silk_SMLAWB( psPLC->pitchL_Q8, psPLC->pitchL_Q8, PITCH_DRIFT_FAC_Q16 ); psPLC->pitchL_Q8 = silk_min_32( psPLC->pitchL_Q8, silk_LSHIFT( silk_SMULBB( MAX_PITCH_LAG_MS, psDec->fs_kHz ), 8 ) ); lag = silk_RSHIFT_ROUND( psPLC->pitchL_Q8, 8 ); } /***************************/ /* LPC synthesis filtering */ /***************************/ sLPC_Q14_ptr = &sLTP_Q14[ psDec->ltp_mem_length - MAX_LPC_ORDER ]; /* Copy LPC state */ silk_memcpy( sLPC_Q14_ptr, psDec->sLPC_Q14_buf, MAX_LPC_ORDER * sizeof( opus_int32 ) ); celt_assert( psDec->LPC_order >= 10 ); /* check that unrolling works */ for( i = 0; i < psDec->frame_length; i++ ) { /* partly unrolled */ /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ LPC_pred_Q10 = silk_RSHIFT( psDec->LPC_order, 1 ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 1 ], A_Q12[ 0 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 2 ], A_Q12[ 1 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 3 ], A_Q12[ 2 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 4 ], A_Q12[ 3 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 5 ], A_Q12[ 4 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 6 ], A_Q12[ 5 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 7 ], A_Q12[ 6 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 8 ], A_Q12[ 7 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 9 ], A_Q12[ 8 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 10 ], A_Q12[ 9 ] ); for( j = 10; j < psDec->LPC_order; j++ ) { LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - j - 1 ], A_Q12[ j ] ); } /* Add prediction to LPC excitation */ sLPC_Q14_ptr[ MAX_LPC_ORDER + i ] = silk_ADD_SAT32( sLPC_Q14_ptr[ MAX_LPC_ORDER + i ], silk_LSHIFT_SAT32( LPC_pred_Q10, 4 )); /* Scale with Gain */ frame[ i ] = (opus_int16)silk_SAT16( silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14_ptr[ MAX_LPC_ORDER + i ], prevGain_Q10[ 1 ] ), 8 ) ) ); } /* Save LPC state */ silk_memcpy( psDec->sLPC_Q14_buf, &sLPC_Q14_ptr[ psDec->frame_length ], MAX_LPC_ORDER * sizeof( opus_int32 ) ); /**************************************/ /* Update states */ /**************************************/ psPLC->rand_seed = rand_seed; psPLC->randScale_Q14 = rand_scale_Q14; for( i = 0; i < MAX_NB_SUBFR; i++ ) { psDecCtrl->pitchL[ i ] = lag; } RESTORE_STACK; } /* Glues concealed frames with new good received frames */ void silk_PLC_glue_frames( silk_decoder_state *psDec, /* I/O decoder state */ opus_int16 frame[], /* I/O signal */ opus_int length /* I length of signal */ ) { opus_int i, energy_shift; opus_int32 energy; silk_PLC_struct *psPLC; psPLC = &psDec->sPLC; if( psDec->lossCnt ) { /* Calculate energy in concealed residual */ silk_sum_sqr_shift( &psPLC->conc_energy, &psPLC->conc_energy_shift, frame, length ); psPLC->last_frame_lost = 1; } else { if( psDec->sPLC.last_frame_lost ) { /* Calculate residual in decoded signal if last frame was lost */ silk_sum_sqr_shift( &energy, &energy_shift, frame, length ); /* Normalize energies */ if( energy_shift > psPLC->conc_energy_shift ) { psPLC->conc_energy = silk_RSHIFT( psPLC->conc_energy, energy_shift - psPLC->conc_energy_shift ); } else if( energy_shift < psPLC->conc_energy_shift ) { energy = silk_RSHIFT( energy, psPLC->conc_energy_shift - energy_shift ); } /* Fade in the energy difference */ if( energy > psPLC->conc_energy ) { opus_int32 frac_Q24, LZ; opus_int32 gain_Q16, slope_Q16; LZ = silk_CLZ32( psPLC->conc_energy ); LZ = LZ - 1; psPLC->conc_energy = silk_LSHIFT( psPLC->conc_energy, LZ ); energy = silk_RSHIFT( energy, silk_max_32( 24 - LZ, 0 ) ); frac_Q24 = silk_DIV32( psPLC->conc_energy, silk_max( energy, 1 ) ); gain_Q16 = silk_LSHIFT( silk_SQRT_APPROX( frac_Q24 ), 4 ); slope_Q16 = silk_DIV32_16( ( (opus_int32)1 << 16 ) - gain_Q16, length ); /* Make slope 4x steeper to avoid missing onsets after DTX */ slope_Q16 = silk_LSHIFT( slope_Q16, 2 ); for( i = 0; i < length; i++ ) { frame[ i ] = silk_SMULWB( gain_Q16, frame[ i ] ); gain_Q16 += slope_Q16; if( gain_Q16 > (opus_int32)1 << 16 ) { break; } } } } psPLC->last_frame_lost = 0; } } jamulus-3.9.1+dfsg/libs/opus/silk/bwexpander_32.c0000644000175000017500000000467214340334543020655 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FIX.h" /* Chirp (bandwidth expand) LP AR filter */ void silk_bwexpander_32( opus_int32 *ar, /* I/O AR filter to be expanded (without leading 1) */ const opus_int d, /* I Length of ar */ opus_int32 chirp_Q16 /* I Chirp factor in Q16 */ ) { opus_int i; opus_int32 chirp_minus_one_Q16 = chirp_Q16 - 65536; for( i = 0; i < d - 1; i++ ) { ar[ i ] = silk_SMULWW( chirp_Q16, ar[ i ] ); chirp_Q16 += silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, chirp_minus_one_Q16 ), 16 ); } ar[ d - 1 ] = silk_SMULWW( chirp_Q16, ar[ d - 1 ] ); } jamulus-3.9.1+dfsg/libs/opus/silk/log2lin.c0000644000175000017500000000511414340334543017550 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FIX.h" /* Approximation of 2^() (very close inverse of silk_lin2log()) */ /* Convert input to a linear scale */ opus_int32 silk_log2lin( const opus_int32 inLog_Q7 /* I input on log scale */ ) { opus_int32 out, frac_Q7; if( inLog_Q7 < 0 ) { return 0; } else if ( inLog_Q7 >= 3967 ) { return silk_int32_MAX; } out = silk_LSHIFT( 1, silk_RSHIFT( inLog_Q7, 7 ) ); frac_Q7 = inLog_Q7 & 0x7F; if( inLog_Q7 < 2048 ) { /* Piece-wise parabolic approximation */ out = silk_ADD_RSHIFT32( out, silk_MUL( out, silk_SMLAWB( frac_Q7, silk_SMULBB( frac_Q7, 128 - frac_Q7 ), -174 ) ), 7 ); } else { /* Piece-wise parabolic approximation */ out = silk_MLA( out, silk_RSHIFT( out, 7 ), silk_SMLAWB( frac_Q7, silk_SMULBB( frac_Q7, 128 - frac_Q7 ), -174 ) ); } return out; } jamulus-3.9.1+dfsg/libs/opus/silk/macros.h0000644000175000017500000001442414340334543017477 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SILK_MACROS_H #define SILK_MACROS_H #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "opus_types.h" #include "opus_defines.h" #include "arch.h" /* This is an OPUS_INLINE header file for general platform. */ /* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */ #if OPUS_FAST_INT64 #define silk_SMULWB(a32, b32) ((opus_int32)(((a32) * (opus_int64)((opus_int16)(b32))) >> 16)) #else #define silk_SMULWB(a32, b32) ((((a32) >> 16) * (opus_int32)((opus_int16)(b32))) + ((((a32) & 0x0000FFFF) * (opus_int32)((opus_int16)(b32))) >> 16)) #endif /* a32 + (b32 * (opus_int32)((opus_int16)(c32))) >> 16 output have to be 32bit int */ #if OPUS_FAST_INT64 #define silk_SMLAWB(a32, b32, c32) ((opus_int32)((a32) + (((b32) * (opus_int64)((opus_int16)(c32))) >> 16))) #else #define silk_SMLAWB(a32, b32, c32) ((a32) + ((((b32) >> 16) * (opus_int32)((opus_int16)(c32))) + ((((b32) & 0x0000FFFF) * (opus_int32)((opus_int16)(c32))) >> 16))) #endif /* (a32 * (b32 >> 16)) >> 16 */ #if OPUS_FAST_INT64 #define silk_SMULWT(a32, b32) ((opus_int32)(((a32) * (opus_int64)((b32) >> 16)) >> 16)) #else #define silk_SMULWT(a32, b32) (((a32) >> 16) * ((b32) >> 16) + ((((a32) & 0x0000FFFF) * ((b32) >> 16)) >> 16)) #endif /* a32 + (b32 * (c32 >> 16)) >> 16 */ #if OPUS_FAST_INT64 #define silk_SMLAWT(a32, b32, c32) ((opus_int32)((a32) + (((b32) * ((opus_int64)(c32) >> 16)) >> 16))) #else #define silk_SMLAWT(a32, b32, c32) ((a32) + (((b32) >> 16) * ((c32) >> 16)) + ((((b32) & 0x0000FFFF) * ((c32) >> 16)) >> 16)) #endif /* (opus_int32)((opus_int16)(a3))) * (opus_int32)((opus_int16)(b32)) output have to be 32bit int */ #define silk_SMULBB(a32, b32) ((opus_int32)((opus_int16)(a32)) * (opus_int32)((opus_int16)(b32))) /* a32 + (opus_int32)((opus_int16)(b32)) * (opus_int32)((opus_int16)(c32)) output have to be 32bit int */ #define silk_SMLABB(a32, b32, c32) ((a32) + ((opus_int32)((opus_int16)(b32))) * (opus_int32)((opus_int16)(c32))) /* (opus_int32)((opus_int16)(a32)) * (b32 >> 16) */ #define silk_SMULBT(a32, b32) ((opus_int32)((opus_int16)(a32)) * ((b32) >> 16)) /* a32 + (opus_int32)((opus_int16)(b32)) * (c32 >> 16) */ #define silk_SMLABT(a32, b32, c32) ((a32) + ((opus_int32)((opus_int16)(b32))) * ((c32) >> 16)) /* a64 + (b32 * c32) */ #define silk_SMLAL(a64, b32, c32) (silk_ADD64((a64), ((opus_int64)(b32) * (opus_int64)(c32)))) /* (a32 * b32) >> 16 */ #if OPUS_FAST_INT64 #define silk_SMULWW(a32, b32) ((opus_int32)(((opus_int64)(a32) * (b32)) >> 16)) #else #define silk_SMULWW(a32, b32) silk_MLA(silk_SMULWB((a32), (b32)), (a32), silk_RSHIFT_ROUND((b32), 16)) #endif /* a32 + ((b32 * c32) >> 16) */ #if OPUS_FAST_INT64 #define silk_SMLAWW(a32, b32, c32) ((opus_int32)((a32) + (((opus_int64)(b32) * (c32)) >> 16))) #else #define silk_SMLAWW(a32, b32, c32) silk_MLA(silk_SMLAWB((a32), (b32), (c32)), (b32), silk_RSHIFT_ROUND((c32), 16)) #endif /* add/subtract with output saturated */ #define silk_ADD_SAT32(a, b) ((((opus_uint32)(a) + (opus_uint32)(b)) & 0x80000000) == 0 ? \ ((((a) & (b)) & 0x80000000) != 0 ? silk_int32_MIN : (a)+(b)) : \ ((((a) | (b)) & 0x80000000) == 0 ? silk_int32_MAX : (a)+(b)) ) #define silk_SUB_SAT32(a, b) ((((opus_uint32)(a)-(opus_uint32)(b)) & 0x80000000) == 0 ? \ (( (a) & ((b)^0x80000000) & 0x80000000) ? silk_int32_MIN : (a)-(b)) : \ ((((a)^0x80000000) & (b) & 0x80000000) ? silk_int32_MAX : (a)-(b)) ) #if defined(MIPSr1_ASM) #include "mips/macros_mipsr1.h" #endif #include "ecintrin.h" #ifndef OVERRIDE_silk_CLZ16 static OPUS_INLINE opus_int32 silk_CLZ16(opus_int16 in16) { return 32 - EC_ILOG(in16<<16|0x8000); } #endif #ifndef OVERRIDE_silk_CLZ32 static OPUS_INLINE opus_int32 silk_CLZ32(opus_int32 in32) { return in32 ? 32 - EC_ILOG(in32) : 32; } #endif /* Row based */ #define matrix_ptr(Matrix_base_adr, row, column, N) \ (*((Matrix_base_adr) + ((row)*(N)+(column)))) #define matrix_adr(Matrix_base_adr, row, column, N) \ ((Matrix_base_adr) + ((row)*(N)+(column))) /* Column based */ #ifndef matrix_c_ptr # define matrix_c_ptr(Matrix_base_adr, row, column, M) \ (*((Matrix_base_adr) + ((row)+(M)*(column)))) #endif #ifdef OPUS_ARM_INLINE_ASM #include "arm/macros_armv4.h" #endif #ifdef OPUS_ARM_INLINE_EDSP #include "arm/macros_armv5e.h" #endif #ifdef OPUS_ARM_PRESUME_AARCH64_NEON_INTR #include "arm/macros_arm64.h" #endif #endif /* SILK_MACROS_H */ jamulus-3.9.1+dfsg/libs/opus/silk/shell_coder.c0000644000175000017500000001704614340334543020474 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" /* shell coder; pulse-subframe length is hardcoded */ static OPUS_INLINE void combine_pulses( opus_int *out, /* O combined pulses vector [len] */ const opus_int *in, /* I input vector [2 * len] */ const opus_int len /* I number of OUTPUT samples */ ) { opus_int k; for( k = 0; k < len; k++ ) { out[ k ] = in[ 2 * k ] + in[ 2 * k + 1 ]; } } static OPUS_INLINE void encode_split( ec_enc *psRangeEnc, /* I/O compressor data structure */ const opus_int p_child1, /* I pulse amplitude of first child subframe */ const opus_int p, /* I pulse amplitude of current subframe */ const opus_uint8 *shell_table /* I table of shell cdfs */ ) { if( p > 0 ) { ec_enc_icdf( psRangeEnc, p_child1, &shell_table[ silk_shell_code_table_offsets[ p ] ], 8 ); } } static OPUS_INLINE void decode_split( opus_int16 *p_child1, /* O pulse amplitude of first child subframe */ opus_int16 *p_child2, /* O pulse amplitude of second child subframe */ ec_dec *psRangeDec, /* I/O Compressor data structure */ const opus_int p, /* I pulse amplitude of current subframe */ const opus_uint8 *shell_table /* I table of shell cdfs */ ) { if( p > 0 ) { p_child1[ 0 ] = ec_dec_icdf( psRangeDec, &shell_table[ silk_shell_code_table_offsets[ p ] ], 8 ); p_child2[ 0 ] = p - p_child1[ 0 ]; } else { p_child1[ 0 ] = 0; p_child2[ 0 ] = 0; } } /* Shell encoder, operates on one shell code frame of 16 pulses */ void silk_shell_encoder( ec_enc *psRangeEnc, /* I/O compressor data structure */ const opus_int *pulses0 /* I data: nonnegative pulse amplitudes */ ) { opus_int pulses1[ 8 ], pulses2[ 4 ], pulses3[ 2 ], pulses4[ 1 ]; /* this function operates on one shell code frame of 16 pulses */ silk_assert( SHELL_CODEC_FRAME_LENGTH == 16 ); /* tree representation per pulse-subframe */ combine_pulses( pulses1, pulses0, 8 ); combine_pulses( pulses2, pulses1, 4 ); combine_pulses( pulses3, pulses2, 2 ); combine_pulses( pulses4, pulses3, 1 ); encode_split( psRangeEnc, pulses3[ 0 ], pulses4[ 0 ], silk_shell_code_table3 ); encode_split( psRangeEnc, pulses2[ 0 ], pulses3[ 0 ], silk_shell_code_table2 ); encode_split( psRangeEnc, pulses1[ 0 ], pulses2[ 0 ], silk_shell_code_table1 ); encode_split( psRangeEnc, pulses0[ 0 ], pulses1[ 0 ], silk_shell_code_table0 ); encode_split( psRangeEnc, pulses0[ 2 ], pulses1[ 1 ], silk_shell_code_table0 ); encode_split( psRangeEnc, pulses1[ 2 ], pulses2[ 1 ], silk_shell_code_table1 ); encode_split( psRangeEnc, pulses0[ 4 ], pulses1[ 2 ], silk_shell_code_table0 ); encode_split( psRangeEnc, pulses0[ 6 ], pulses1[ 3 ], silk_shell_code_table0 ); encode_split( psRangeEnc, pulses2[ 2 ], pulses3[ 1 ], silk_shell_code_table2 ); encode_split( psRangeEnc, pulses1[ 4 ], pulses2[ 2 ], silk_shell_code_table1 ); encode_split( psRangeEnc, pulses0[ 8 ], pulses1[ 4 ], silk_shell_code_table0 ); encode_split( psRangeEnc, pulses0[ 10 ], pulses1[ 5 ], silk_shell_code_table0 ); encode_split( psRangeEnc, pulses1[ 6 ], pulses2[ 3 ], silk_shell_code_table1 ); encode_split( psRangeEnc, pulses0[ 12 ], pulses1[ 6 ], silk_shell_code_table0 ); encode_split( psRangeEnc, pulses0[ 14 ], pulses1[ 7 ], silk_shell_code_table0 ); } /* Shell decoder, operates on one shell code frame of 16 pulses */ void silk_shell_decoder( opus_int16 *pulses0, /* O data: nonnegative pulse amplitudes */ ec_dec *psRangeDec, /* I/O Compressor data structure */ const opus_int pulses4 /* I number of pulses per pulse-subframe */ ) { opus_int16 pulses3[ 2 ], pulses2[ 4 ], pulses1[ 8 ]; /* this function operates on one shell code frame of 16 pulses */ silk_assert( SHELL_CODEC_FRAME_LENGTH == 16 ); decode_split( &pulses3[ 0 ], &pulses3[ 1 ], psRangeDec, pulses4, silk_shell_code_table3 ); decode_split( &pulses2[ 0 ], &pulses2[ 1 ], psRangeDec, pulses3[ 0 ], silk_shell_code_table2 ); decode_split( &pulses1[ 0 ], &pulses1[ 1 ], psRangeDec, pulses2[ 0 ], silk_shell_code_table1 ); decode_split( &pulses0[ 0 ], &pulses0[ 1 ], psRangeDec, pulses1[ 0 ], silk_shell_code_table0 ); decode_split( &pulses0[ 2 ], &pulses0[ 3 ], psRangeDec, pulses1[ 1 ], silk_shell_code_table0 ); decode_split( &pulses1[ 2 ], &pulses1[ 3 ], psRangeDec, pulses2[ 1 ], silk_shell_code_table1 ); decode_split( &pulses0[ 4 ], &pulses0[ 5 ], psRangeDec, pulses1[ 2 ], silk_shell_code_table0 ); decode_split( &pulses0[ 6 ], &pulses0[ 7 ], psRangeDec, pulses1[ 3 ], silk_shell_code_table0 ); decode_split( &pulses2[ 2 ], &pulses2[ 3 ], psRangeDec, pulses3[ 1 ], silk_shell_code_table2 ); decode_split( &pulses1[ 4 ], &pulses1[ 5 ], psRangeDec, pulses2[ 2 ], silk_shell_code_table1 ); decode_split( &pulses0[ 8 ], &pulses0[ 9 ], psRangeDec, pulses1[ 4 ], silk_shell_code_table0 ); decode_split( &pulses0[ 10 ], &pulses0[ 11 ], psRangeDec, pulses1[ 5 ], silk_shell_code_table0 ); decode_split( &pulses1[ 6 ], &pulses1[ 7 ], psRangeDec, pulses2[ 3 ], silk_shell_code_table1 ); decode_split( &pulses0[ 12 ], &pulses0[ 13 ], psRangeDec, pulses1[ 6 ], silk_shell_code_table0 ); decode_split( &pulses0[ 14 ], &pulses0[ 15 ], psRangeDec, pulses1[ 7 ], silk_shell_code_table0 ); } jamulus-3.9.1+dfsg/libs/opus/silk/decode_pitch.c0000644000175000017500000000720514340334543020617 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif /*********************************************************** * Pitch analyser function ********************************************************** */ #include "SigProc_FIX.h" #include "pitch_est_defines.h" void silk_decode_pitch( opus_int16 lagIndex, /* I */ opus_int8 contourIndex, /* O */ opus_int pitch_lags[], /* O 4 pitch values */ const opus_int Fs_kHz, /* I sampling frequency (kHz) */ const opus_int nb_subfr /* I number of sub frames */ ) { opus_int lag, k, min_lag, max_lag, cbk_size; const opus_int8 *Lag_CB_ptr; if( Fs_kHz == 8 ) { if( nb_subfr == PE_MAX_NB_SUBFR ) { Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ]; cbk_size = PE_NB_CBKS_STAGE2_EXT; } else { celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1 ); Lag_CB_ptr = &silk_CB_lags_stage2_10_ms[ 0 ][ 0 ]; cbk_size = PE_NB_CBKS_STAGE2_10MS; } } else { if( nb_subfr == PE_MAX_NB_SUBFR ) { Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ]; cbk_size = PE_NB_CBKS_STAGE3_MAX; } else { celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1 ); Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; cbk_size = PE_NB_CBKS_STAGE3_10MS; } } min_lag = silk_SMULBB( PE_MIN_LAG_MS, Fs_kHz ); max_lag = silk_SMULBB( PE_MAX_LAG_MS, Fs_kHz ); lag = min_lag + lagIndex; for( k = 0; k < nb_subfr; k++ ) { pitch_lags[ k ] = lag + matrix_ptr( Lag_CB_ptr, k, contourIndex, cbk_size ); pitch_lags[ k ] = silk_LIMIT( pitch_lags[ k ], min_lag, max_lag ); } } jamulus-3.9.1+dfsg/libs/opus/silk/resampler_down2.c0000644000175000017500000000662314340334543021313 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FIX.h" #include "resampler_rom.h" /* Downsample by a factor 2 */ void silk_resampler_down2( opus_int32 *S, /* I/O State vector [ 2 ] */ opus_int16 *out, /* O Output signal [ floor(len/2) ] */ const opus_int16 *in, /* I Input signal [ len ] */ opus_int32 inLen /* I Number of input samples */ ) { opus_int32 k, len2 = silk_RSHIFT32( inLen, 1 ); opus_int32 in32, out32, Y, X; celt_assert( silk_resampler_down2_0 > 0 ); celt_assert( silk_resampler_down2_1 < 0 ); /* Internal variables and state are in Q10 format */ for( k = 0; k < len2; k++ ) { /* Convert to Q10 */ in32 = silk_LSHIFT( (opus_int32)in[ 2 * k ], 10 ); /* All-pass section for even input sample */ Y = silk_SUB32( in32, S[ 0 ] ); X = silk_SMLAWB( Y, Y, silk_resampler_down2_1 ); out32 = silk_ADD32( S[ 0 ], X ); S[ 0 ] = silk_ADD32( in32, X ); /* Convert to Q10 */ in32 = silk_LSHIFT( (opus_int32)in[ 2 * k + 1 ], 10 ); /* All-pass section for odd input sample, and add to output of previous section */ Y = silk_SUB32( in32, S[ 1 ] ); X = silk_SMULWB( Y, silk_resampler_down2_0 ); out32 = silk_ADD32( out32, S[ 1 ] ); out32 = silk_ADD32( out32, X ); S[ 1 ] = silk_ADD32( in32, X ); /* Add, convert back to int16 and store to output */ out[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( out32, 11 ) ); } } jamulus-3.9.1+dfsg/libs/opus/silk/LPC_fit.c0000644000175000017500000000756514340334543017476 0ustar vimervimer/*********************************************************************** Copyright (c) 2013, Koen Vos. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FIX.h" /* Convert int32 coefficients to int16 coefs and make sure there's no wrap-around */ void silk_LPC_fit( opus_int16 *a_QOUT, /* O Output signal */ opus_int32 *a_QIN, /* I/O Input signal */ const opus_int QOUT, /* I Input Q domain */ const opus_int QIN, /* I Input Q domain */ const opus_int d /* I Filter order */ ) { opus_int i, k, idx = 0; opus_int32 maxabs, absval, chirp_Q16; /* Limit the maximum absolute value of the prediction coefficients, so that they'll fit in int16 */ for( i = 0; i < 10; i++ ) { /* Find maximum absolute value and its index */ maxabs = 0; for( k = 0; k < d; k++ ) { absval = silk_abs( a_QIN[k] ); if( absval > maxabs ) { maxabs = absval; idx = k; } } maxabs = silk_RSHIFT_ROUND( maxabs, QIN - QOUT ); if( maxabs > silk_int16_MAX ) { /* Reduce magnitude of prediction coefficients */ maxabs = silk_min( maxabs, 163838 ); /* ( silk_int32_MAX >> 14 ) + silk_int16_MAX = 163838 */ chirp_Q16 = SILK_FIX_CONST( 0.999, 16 ) - silk_DIV32( silk_LSHIFT( maxabs - silk_int16_MAX, 14 ), silk_RSHIFT32( silk_MUL( maxabs, idx + 1), 2 ) ); silk_bwexpander_32( a_QIN, d, chirp_Q16 ); } else { break; } } if( i == 10 ) { /* Reached the last iteration, clip the coefficients */ for( k = 0; k < d; k++ ) { a_QOUT[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( a_QIN[ k ], QIN - QOUT ) ); a_QIN[ k ] = silk_LSHIFT( (opus_int32)a_QOUT[ k ], QIN - QOUT ); } } else { for( k = 0; k < d; k++ ) { a_QOUT[ k ] = (opus_int16)silk_RSHIFT_ROUND( a_QIN[ k ], QIN - QOUT ); } } } jamulus-3.9.1+dfsg/libs/opus/silk/ana_filt_bank_1.c0000644000175000017500000000727214340334543021201 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FIX.h" /* Coefficients for 2-band filter bank based on first-order allpass filters */ static opus_int16 A_fb1_20 = 5394 << 1; static opus_int16 A_fb1_21 = -24290; /* (opus_int16)(20623 << 1) */ /* Split signal into two decimated bands using first-order allpass filters */ void silk_ana_filt_bank_1( const opus_int16 *in, /* I Input signal [N] */ opus_int32 *S, /* I/O State vector [2] */ opus_int16 *outL, /* O Low band [N/2] */ opus_int16 *outH, /* O High band [N/2] */ const opus_int32 N /* I Number of input samples */ ) { opus_int k, N2 = silk_RSHIFT( N, 1 ); opus_int32 in32, X, Y, out_1, out_2; /* Internal variables and state are in Q10 format */ for( k = 0; k < N2; k++ ) { /* Convert to Q10 */ in32 = silk_LSHIFT( (opus_int32)in[ 2 * k ], 10 ); /* All-pass section for even input sample */ Y = silk_SUB32( in32, S[ 0 ] ); X = silk_SMLAWB( Y, Y, A_fb1_21 ); out_1 = silk_ADD32( S[ 0 ], X ); S[ 0 ] = silk_ADD32( in32, X ); /* Convert to Q10 */ in32 = silk_LSHIFT( (opus_int32)in[ 2 * k + 1 ], 10 ); /* All-pass section for odd input sample, and add to output of previous section */ Y = silk_SUB32( in32, S[ 1 ] ); X = silk_SMULWB( Y, A_fb1_20 ); out_2 = silk_ADD32( S[ 1 ], X ); S[ 1 ] = silk_ADD32( in32, X ); /* Add/subtract, convert back to int16 and store to output */ outL[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_ADD32( out_2, out_1 ), 11 ) ); outH[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SUB32( out_2, out_1 ), 11 ) ); } } jamulus-3.9.1+dfsg/libs/opus/silk/HP_variable_cutoff.c0000644000175000017500000000762514340334543021735 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef FIXED_POINT #include "main_FIX.h" #else #include "main_FLP.h" #endif #include "tuning_parameters.h" /* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */ void silk_HP_variable_cutoff( silk_encoder_state_Fxx state_Fxx[] /* I/O Encoder states */ ) { opus_int quality_Q15; opus_int32 pitch_freq_Hz_Q16, pitch_freq_log_Q7, delta_freq_Q7; silk_encoder_state *psEncC1 = &state_Fxx[ 0 ].sCmn; /* Adaptive cutoff frequency: estimate low end of pitch frequency range */ if( psEncC1->prevSignalType == TYPE_VOICED ) { /* difference, in log domain */ pitch_freq_Hz_Q16 = silk_DIV32_16( silk_LSHIFT( silk_MUL( psEncC1->fs_kHz, 1000 ), 16 ), psEncC1->prevLag ); pitch_freq_log_Q7 = silk_lin2log( pitch_freq_Hz_Q16 ) - ( 16 << 7 ); /* adjustment based on quality */ quality_Q15 = psEncC1->input_quality_bands_Q15[ 0 ]; pitch_freq_log_Q7 = silk_SMLAWB( pitch_freq_log_Q7, silk_SMULWB( silk_LSHIFT( -quality_Q15, 2 ), quality_Q15 ), pitch_freq_log_Q7 - ( silk_lin2log( SILK_FIX_CONST( VARIABLE_HP_MIN_CUTOFF_HZ, 16 ) ) - ( 16 << 7 ) ) ); /* delta_freq = pitch_freq_log - psEnc->variable_HP_smth1; */ delta_freq_Q7 = pitch_freq_log_Q7 - silk_RSHIFT( psEncC1->variable_HP_smth1_Q15, 8 ); if( delta_freq_Q7 < 0 ) { /* less smoothing for decreasing pitch frequency, to track something close to the minimum */ delta_freq_Q7 = silk_MUL( delta_freq_Q7, 3 ); } /* limit delta, to reduce impact of outliers in pitch estimation */ delta_freq_Q7 = silk_LIMIT_32( delta_freq_Q7, -SILK_FIX_CONST( VARIABLE_HP_MAX_DELTA_FREQ, 7 ), SILK_FIX_CONST( VARIABLE_HP_MAX_DELTA_FREQ, 7 ) ); /* update smoother */ psEncC1->variable_HP_smth1_Q15 = silk_SMLAWB( psEncC1->variable_HP_smth1_Q15, silk_SMULBB( psEncC1->speech_activity_Q8, delta_freq_Q7 ), SILK_FIX_CONST( VARIABLE_HP_SMTH_COEF1, 16 ) ); /* limit frequency range */ psEncC1->variable_HP_smth1_Q15 = silk_LIMIT_32( psEncC1->variable_HP_smth1_Q15, silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 ), silk_LSHIFT( silk_lin2log( VARIABLE_HP_MAX_CUTOFF_HZ ), 8 ) ); } } jamulus-3.9.1+dfsg/libs/opus/silk/MacroCount.h0000644000175000017500000005043414340334543020266 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SIGPROCFIX_API_MACROCOUNT_H #define SIGPROCFIX_API_MACROCOUNT_H #include #ifdef silk_MACRO_COUNT #define varDefine opus_int64 ops_count = 0; extern opus_int64 ops_count; static OPUS_INLINE opus_int64 silk_SaveCount(){ return(ops_count); } static OPUS_INLINE opus_int64 silk_SaveResetCount(){ opus_int64 ret; ret = ops_count; ops_count = 0; return(ret); } static OPUS_INLINE silk_PrintCount(){ printf("ops_count = %d \n ", (opus_int32)ops_count); } #undef silk_MUL static OPUS_INLINE opus_int32 silk_MUL(opus_int32 a32, opus_int32 b32){ opus_int32 ret; ops_count += 4; ret = a32 * b32; return ret; } #undef silk_MUL_uint static OPUS_INLINE opus_uint32 silk_MUL_uint(opus_uint32 a32, opus_uint32 b32){ opus_uint32 ret; ops_count += 4; ret = a32 * b32; return ret; } #undef silk_MLA static OPUS_INLINE opus_int32 silk_MLA(opus_int32 a32, opus_int32 b32, opus_int32 c32){ opus_int32 ret; ops_count += 4; ret = a32 + b32 * c32; return ret; } #undef silk_MLA_uint static OPUS_INLINE opus_int32 silk_MLA_uint(opus_uint32 a32, opus_uint32 b32, opus_uint32 c32){ opus_uint32 ret; ops_count += 4; ret = a32 + b32 * c32; return ret; } #undef silk_SMULWB static OPUS_INLINE opus_int32 silk_SMULWB(opus_int32 a32, opus_int32 b32){ opus_int32 ret; ops_count += 5; ret = (a32 >> 16) * (opus_int32)((opus_int16)b32) + (((a32 & 0x0000FFFF) * (opus_int32)((opus_int16)b32)) >> 16); return ret; } #undef silk_SMLAWB static OPUS_INLINE opus_int32 silk_SMLAWB(opus_int32 a32, opus_int32 b32, opus_int32 c32){ opus_int32 ret; ops_count += 5; ret = ((a32) + ((((b32) >> 16) * (opus_int32)((opus_int16)(c32))) + ((((b32) & 0x0000FFFF) * (opus_int32)((opus_int16)(c32))) >> 16))); return ret; } #undef silk_SMULWT static OPUS_INLINE opus_int32 silk_SMULWT(opus_int32 a32, opus_int32 b32){ opus_int32 ret; ops_count += 4; ret = (a32 >> 16) * (b32 >> 16) + (((a32 & 0x0000FFFF) * (b32 >> 16)) >> 16); return ret; } #undef silk_SMLAWT static OPUS_INLINE opus_int32 silk_SMLAWT(opus_int32 a32, opus_int32 b32, opus_int32 c32){ opus_int32 ret; ops_count += 4; ret = a32 + ((b32 >> 16) * (c32 >> 16)) + (((b32 & 0x0000FFFF) * ((c32 >> 16)) >> 16)); return ret; } #undef silk_SMULBB static OPUS_INLINE opus_int32 silk_SMULBB(opus_int32 a32, opus_int32 b32){ opus_int32 ret; ops_count += 1; ret = (opus_int32)((opus_int16)a32) * (opus_int32)((opus_int16)b32); return ret; } #undef silk_SMLABB static OPUS_INLINE opus_int32 silk_SMLABB(opus_int32 a32, opus_int32 b32, opus_int32 c32){ opus_int32 ret; ops_count += 1; ret = a32 + (opus_int32)((opus_int16)b32) * (opus_int32)((opus_int16)c32); return ret; } #undef silk_SMULBT static OPUS_INLINE opus_int32 silk_SMULBT(opus_int32 a32, opus_int32 b32 ){ opus_int32 ret; ops_count += 4; ret = ((opus_int32)((opus_int16)a32)) * (b32 >> 16); return ret; } #undef silk_SMLABT static OPUS_INLINE opus_int32 silk_SMLABT(opus_int32 a32, opus_int32 b32, opus_int32 c32){ opus_int32 ret; ops_count += 1; ret = a32 + ((opus_int32)((opus_int16)b32)) * (c32 >> 16); return ret; } #undef silk_SMULTT static OPUS_INLINE opus_int32 silk_SMULTT(opus_int32 a32, opus_int32 b32){ opus_int32 ret; ops_count += 1; ret = (a32 >> 16) * (b32 >> 16); return ret; } #undef silk_SMLATT static OPUS_INLINE opus_int32 silk_SMLATT(opus_int32 a32, opus_int32 b32, opus_int32 c32){ opus_int32 ret; ops_count += 1; ret = a32 + (b32 >> 16) * (c32 >> 16); return ret; } /* multiply-accumulate macros that allow overflow in the addition (ie, no asserts in debug mode)*/ #undef silk_MLA_ovflw #define silk_MLA_ovflw silk_MLA #undef silk_SMLABB_ovflw #define silk_SMLABB_ovflw silk_SMLABB #undef silk_SMLABT_ovflw #define silk_SMLABT_ovflw silk_SMLABT #undef silk_SMLATT_ovflw #define silk_SMLATT_ovflw silk_SMLATT #undef silk_SMLAWB_ovflw #define silk_SMLAWB_ovflw silk_SMLAWB #undef silk_SMLAWT_ovflw #define silk_SMLAWT_ovflw silk_SMLAWT #undef silk_SMULL static OPUS_INLINE opus_int64 silk_SMULL(opus_int32 a32, opus_int32 b32){ opus_int64 ret; ops_count += 8; ret = ((opus_int64)(a32) * /*(opus_int64)*/(b32)); return ret; } #undef silk_SMLAL static OPUS_INLINE opus_int64 silk_SMLAL(opus_int64 a64, opus_int32 b32, opus_int32 c32){ opus_int64 ret; ops_count += 8; ret = a64 + ((opus_int64)(b32) * /*(opus_int64)*/(c32)); return ret; } #undef silk_SMLALBB static OPUS_INLINE opus_int64 silk_SMLALBB(opus_int64 a64, opus_int16 b16, opus_int16 c16){ opus_int64 ret; ops_count += 4; ret = a64 + ((opus_int64)(b16) * /*(opus_int64)*/(c16)); return ret; } #undef SigProcFIX_CLZ16 static OPUS_INLINE opus_int32 SigProcFIX_CLZ16(opus_int16 in16) { opus_int32 out32 = 0; ops_count += 10; if( in16 == 0 ) { return 16; } /* test nibbles */ if( in16 & 0xFF00 ) { if( in16 & 0xF000 ) { in16 >>= 12; } else { out32 += 4; in16 >>= 8; } } else { if( in16 & 0xFFF0 ) { out32 += 8; in16 >>= 4; } else { out32 += 12; } } /* test bits and return */ if( in16 & 0xC ) { if( in16 & 0x8 ) return out32 + 0; else return out32 + 1; } else { if( in16 & 0xE ) return out32 + 2; else return out32 + 3; } } #undef SigProcFIX_CLZ32 static OPUS_INLINE opus_int32 SigProcFIX_CLZ32(opus_int32 in32) { /* test highest 16 bits and convert to opus_int16 */ ops_count += 2; if( in32 & 0xFFFF0000 ) { return SigProcFIX_CLZ16((opus_int16)(in32 >> 16)); } else { return SigProcFIX_CLZ16((opus_int16)in32) + 16; } } #undef silk_DIV32 static OPUS_INLINE opus_int32 silk_DIV32(opus_int32 a32, opus_int32 b32){ ops_count += 64; return a32 / b32; } #undef silk_DIV32_16 static OPUS_INLINE opus_int32 silk_DIV32_16(opus_int32 a32, opus_int32 b32){ ops_count += 32; return a32 / b32; } #undef silk_SAT8 static OPUS_INLINE opus_int8 silk_SAT8(opus_int64 a){ opus_int8 tmp; ops_count += 1; tmp = (opus_int8)((a) > silk_int8_MAX ? silk_int8_MAX : \ ((a) < silk_int8_MIN ? silk_int8_MIN : (a))); return(tmp); } #undef silk_SAT16 static OPUS_INLINE opus_int16 silk_SAT16(opus_int64 a){ opus_int16 tmp; ops_count += 1; tmp = (opus_int16)((a) > silk_int16_MAX ? silk_int16_MAX : \ ((a) < silk_int16_MIN ? silk_int16_MIN : (a))); return(tmp); } #undef silk_SAT32 static OPUS_INLINE opus_int32 silk_SAT32(opus_int64 a){ opus_int32 tmp; ops_count += 1; tmp = (opus_int32)((a) > silk_int32_MAX ? silk_int32_MAX : \ ((a) < silk_int32_MIN ? silk_int32_MIN : (a))); return(tmp); } #undef silk_POS_SAT32 static OPUS_INLINE opus_int32 silk_POS_SAT32(opus_int64 a){ opus_int32 tmp; ops_count += 1; tmp = (opus_int32)((a) > silk_int32_MAX ? silk_int32_MAX : (a)); return(tmp); } #undef silk_ADD_POS_SAT8 static OPUS_INLINE opus_int8 silk_ADD_POS_SAT8(opus_int64 a, opus_int64 b){ opus_int8 tmp; ops_count += 1; tmp = (opus_int8)((((a)+(b)) & 0x80) ? silk_int8_MAX : ((a)+(b))); return(tmp); } #undef silk_ADD_POS_SAT16 static OPUS_INLINE opus_int16 silk_ADD_POS_SAT16(opus_int64 a, opus_int64 b){ opus_int16 tmp; ops_count += 1; tmp = (opus_int16)((((a)+(b)) & 0x8000) ? silk_int16_MAX : ((a)+(b))); return(tmp); } #undef silk_ADD_POS_SAT32 static OPUS_INLINE opus_int32 silk_ADD_POS_SAT32(opus_int64 a, opus_int64 b){ opus_int32 tmp; ops_count += 1; tmp = (opus_int32)((((a)+(b)) & 0x80000000) ? silk_int32_MAX : ((a)+(b))); return(tmp); } #undef silk_LSHIFT8 static OPUS_INLINE opus_int8 silk_LSHIFT8(opus_int8 a, opus_int32 shift){ opus_int8 ret; ops_count += 1; ret = a << shift; return ret; } #undef silk_LSHIFT16 static OPUS_INLINE opus_int16 silk_LSHIFT16(opus_int16 a, opus_int32 shift){ opus_int16 ret; ops_count += 1; ret = a << shift; return ret; } #undef silk_LSHIFT32 static OPUS_INLINE opus_int32 silk_LSHIFT32(opus_int32 a, opus_int32 shift){ opus_int32 ret; ops_count += 1; ret = a << shift; return ret; } #undef silk_LSHIFT64 static OPUS_INLINE opus_int64 silk_LSHIFT64(opus_int64 a, opus_int shift){ ops_count += 1; return a << shift; } #undef silk_LSHIFT_ovflw static OPUS_INLINE opus_int32 silk_LSHIFT_ovflw(opus_int32 a, opus_int32 shift){ ops_count += 1; return a << shift; } #undef silk_LSHIFT_uint static OPUS_INLINE opus_uint32 silk_LSHIFT_uint(opus_uint32 a, opus_int32 shift){ opus_uint32 ret; ops_count += 1; ret = a << shift; return ret; } #undef silk_RSHIFT8 static OPUS_INLINE opus_int8 silk_RSHIFT8(opus_int8 a, opus_int32 shift){ ops_count += 1; return a >> shift; } #undef silk_RSHIFT16 static OPUS_INLINE opus_int16 silk_RSHIFT16(opus_int16 a, opus_int32 shift){ ops_count += 1; return a >> shift; } #undef silk_RSHIFT32 static OPUS_INLINE opus_int32 silk_RSHIFT32(opus_int32 a, opus_int32 shift){ ops_count += 1; return a >> shift; } #undef silk_RSHIFT64 static OPUS_INLINE opus_int64 silk_RSHIFT64(opus_int64 a, opus_int64 shift){ ops_count += 1; return a >> shift; } #undef silk_RSHIFT_uint static OPUS_INLINE opus_uint32 silk_RSHIFT_uint(opus_uint32 a, opus_int32 shift){ ops_count += 1; return a >> shift; } #undef silk_ADD_LSHIFT static OPUS_INLINE opus_int32 silk_ADD_LSHIFT(opus_int32 a, opus_int32 b, opus_int32 shift){ opus_int32 ret; ops_count += 1; ret = a + (b << shift); return ret; /* shift >= 0*/ } #undef silk_ADD_LSHIFT32 static OPUS_INLINE opus_int32 silk_ADD_LSHIFT32(opus_int32 a, opus_int32 b, opus_int32 shift){ opus_int32 ret; ops_count += 1; ret = a + (b << shift); return ret; /* shift >= 0*/ } #undef silk_ADD_LSHIFT_uint static OPUS_INLINE opus_uint32 silk_ADD_LSHIFT_uint(opus_uint32 a, opus_uint32 b, opus_int32 shift){ opus_uint32 ret; ops_count += 1; ret = a + (b << shift); return ret; /* shift >= 0*/ } #undef silk_ADD_RSHIFT static OPUS_INLINE opus_int32 silk_ADD_RSHIFT(opus_int32 a, opus_int32 b, opus_int32 shift){ opus_int32 ret; ops_count += 1; ret = a + (b >> shift); return ret; /* shift > 0*/ } #undef silk_ADD_RSHIFT32 static OPUS_INLINE opus_int32 silk_ADD_RSHIFT32(opus_int32 a, opus_int32 b, opus_int32 shift){ opus_int32 ret; ops_count += 1; ret = a + (b >> shift); return ret; /* shift > 0*/ } #undef silk_ADD_RSHIFT_uint static OPUS_INLINE opus_uint32 silk_ADD_RSHIFT_uint(opus_uint32 a, opus_uint32 b, opus_int32 shift){ opus_uint32 ret; ops_count += 1; ret = a + (b >> shift); return ret; /* shift > 0*/ } #undef silk_SUB_LSHIFT32 static OPUS_INLINE opus_int32 silk_SUB_LSHIFT32(opus_int32 a, opus_int32 b, opus_int32 shift){ opus_int32 ret; ops_count += 1; ret = a - (b << shift); return ret; /* shift >= 0*/ } #undef silk_SUB_RSHIFT32 static OPUS_INLINE opus_int32 silk_SUB_RSHIFT32(opus_int32 a, opus_int32 b, opus_int32 shift){ opus_int32 ret; ops_count += 1; ret = a - (b >> shift); return ret; /* shift > 0*/ } #undef silk_RSHIFT_ROUND static OPUS_INLINE opus_int32 silk_RSHIFT_ROUND(opus_int32 a, opus_int32 shift){ opus_int32 ret; ops_count += 3; ret = shift == 1 ? (a >> 1) + (a & 1) : ((a >> (shift - 1)) + 1) >> 1; return ret; } #undef silk_RSHIFT_ROUND64 static OPUS_INLINE opus_int64 silk_RSHIFT_ROUND64(opus_int64 a, opus_int32 shift){ opus_int64 ret; ops_count += 6; ret = shift == 1 ? (a >> 1) + (a & 1) : ((a >> (shift - 1)) + 1) >> 1; return ret; } #undef silk_abs_int64 static OPUS_INLINE opus_int64 silk_abs_int64(opus_int64 a){ ops_count += 1; return (((a) > 0) ? (a) : -(a)); /* Be careful, silk_abs returns wrong when input equals to silk_intXX_MIN*/ } #undef silk_abs_int32 static OPUS_INLINE opus_int32 silk_abs_int32(opus_int32 a){ ops_count += 1; return silk_abs(a); } #undef silk_min static silk_min(a, b){ ops_count += 1; return (((a) < (b)) ? (a) : (b)); } #undef silk_max static silk_max(a, b){ ops_count += 1; return (((a) > (b)) ? (a) : (b)); } #undef silk_sign static silk_sign(a){ ops_count += 1; return ((a) > 0 ? 1 : ( (a) < 0 ? -1 : 0 )); } #undef silk_ADD16 static OPUS_INLINE opus_int16 silk_ADD16(opus_int16 a, opus_int16 b){ opus_int16 ret; ops_count += 1; ret = a + b; return ret; } #undef silk_ADD32 static OPUS_INLINE opus_int32 silk_ADD32(opus_int32 a, opus_int32 b){ opus_int32 ret; ops_count += 1; ret = a + b; return ret; } #undef silk_ADD64 static OPUS_INLINE opus_int64 silk_ADD64(opus_int64 a, opus_int64 b){ opus_int64 ret; ops_count += 2; ret = a + b; return ret; } #undef silk_SUB16 static OPUS_INLINE opus_int16 silk_SUB16(opus_int16 a, opus_int16 b){ opus_int16 ret; ops_count += 1; ret = a - b; return ret; } #undef silk_SUB32 static OPUS_INLINE opus_int32 silk_SUB32(opus_int32 a, opus_int32 b){ opus_int32 ret; ops_count += 1; ret = a - b; return ret; } #undef silk_SUB64 static OPUS_INLINE opus_int64 silk_SUB64(opus_int64 a, opus_int64 b){ opus_int64 ret; ops_count += 2; ret = a - b; return ret; } #undef silk_ADD_SAT16 static OPUS_INLINE opus_int16 silk_ADD_SAT16( opus_int16 a16, opus_int16 b16 ) { opus_int16 res; /* Nb will be counted in AKP_add32 and silk_SAT16*/ res = (opus_int16)silk_SAT16( silk_ADD32( (opus_int32)(a16), (b16) ) ); return res; } #undef silk_ADD_SAT32 static OPUS_INLINE opus_int32 silk_ADD_SAT32(opus_int32 a32, opus_int32 b32){ opus_int32 res; ops_count += 1; res = ((((a32) + (b32)) & 0x80000000) == 0 ? \ ((((a32) & (b32)) & 0x80000000) != 0 ? silk_int32_MIN : (a32)+(b32)) : \ ((((a32) | (b32)) & 0x80000000) == 0 ? silk_int32_MAX : (a32)+(b32)) ); return res; } #undef silk_ADD_SAT64 static OPUS_INLINE opus_int64 silk_ADD_SAT64( opus_int64 a64, opus_int64 b64 ) { opus_int64 res; ops_count += 1; res = ((((a64) + (b64)) & 0x8000000000000000LL) == 0 ? \ ((((a64) & (b64)) & 0x8000000000000000LL) != 0 ? silk_int64_MIN : (a64)+(b64)) : \ ((((a64) | (b64)) & 0x8000000000000000LL) == 0 ? silk_int64_MAX : (a64)+(b64)) ); return res; } #undef silk_SUB_SAT16 static OPUS_INLINE opus_int16 silk_SUB_SAT16( opus_int16 a16, opus_int16 b16 ) { opus_int16 res; silk_assert(0); /* Nb will be counted in sub-macros*/ res = (opus_int16)silk_SAT16( silk_SUB32( (opus_int32)(a16), (b16) ) ); return res; } #undef silk_SUB_SAT32 static OPUS_INLINE opus_int32 silk_SUB_SAT32( opus_int32 a32, opus_int32 b32 ) { opus_int32 res; ops_count += 1; res = ((((a32)-(b32)) & 0x80000000) == 0 ? \ (( (a32) & ((b32)^0x80000000) & 0x80000000) ? silk_int32_MIN : (a32)-(b32)) : \ ((((a32)^0x80000000) & (b32) & 0x80000000) ? silk_int32_MAX : (a32)-(b32)) ); return res; } #undef silk_SUB_SAT64 static OPUS_INLINE opus_int64 silk_SUB_SAT64( opus_int64 a64, opus_int64 b64 ) { opus_int64 res; ops_count += 1; res = ((((a64)-(b64)) & 0x8000000000000000LL) == 0 ? \ (( (a64) & ((b64)^0x8000000000000000LL) & 0x8000000000000000LL) ? silk_int64_MIN : (a64)-(b64)) : \ ((((a64)^0x8000000000000000LL) & (b64) & 0x8000000000000000LL) ? silk_int64_MAX : (a64)-(b64)) ); return res; } #undef silk_SMULWW static OPUS_INLINE opus_int32 silk_SMULWW(opus_int32 a32, opus_int32 b32){ opus_int32 ret; /* Nb will be counted in sub-macros*/ ret = silk_MLA(silk_SMULWB((a32), (b32)), (a32), silk_RSHIFT_ROUND((b32), 16)); return ret; } #undef silk_SMLAWW static OPUS_INLINE opus_int32 silk_SMLAWW(opus_int32 a32, opus_int32 b32, opus_int32 c32){ opus_int32 ret; /* Nb will be counted in sub-macros*/ ret = silk_MLA(silk_SMLAWB((a32), (b32), (c32)), (b32), silk_RSHIFT_ROUND((c32), 16)); return ret; } #undef silk_min_int static OPUS_INLINE opus_int silk_min_int(opus_int a, opus_int b) { ops_count += 1; return (((a) < (b)) ? (a) : (b)); } #undef silk_min_16 static OPUS_INLINE opus_int16 silk_min_16(opus_int16 a, opus_int16 b) { ops_count += 1; return (((a) < (b)) ? (a) : (b)); } #undef silk_min_32 static OPUS_INLINE opus_int32 silk_min_32(opus_int32 a, opus_int32 b) { ops_count += 1; return (((a) < (b)) ? (a) : (b)); } #undef silk_min_64 static OPUS_INLINE opus_int64 silk_min_64(opus_int64 a, opus_int64 b) { ops_count += 1; return (((a) < (b)) ? (a) : (b)); } /* silk_min() versions with typecast in the function call */ #undef silk_max_int static OPUS_INLINE opus_int silk_max_int(opus_int a, opus_int b) { ops_count += 1; return (((a) > (b)) ? (a) : (b)); } #undef silk_max_16 static OPUS_INLINE opus_int16 silk_max_16(opus_int16 a, opus_int16 b) { ops_count += 1; return (((a) > (b)) ? (a) : (b)); } #undef silk_max_32 static OPUS_INLINE opus_int32 silk_max_32(opus_int32 a, opus_int32 b) { ops_count += 1; return (((a) > (b)) ? (a) : (b)); } #undef silk_max_64 static OPUS_INLINE opus_int64 silk_max_64(opus_int64 a, opus_int64 b) { ops_count += 1; return (((a) > (b)) ? (a) : (b)); } #undef silk_LIMIT_int static OPUS_INLINE opus_int silk_LIMIT_int(opus_int a, opus_int limit1, opus_int limit2) { opus_int ret; ops_count += 6; ret = ((limit1) > (limit2) ? ((a) > (limit1) ? (limit1) : ((a) < (limit2) ? (limit2) : (a))) \ : ((a) > (limit2) ? (limit2) : ((a) < (limit1) ? (limit1) : (a)))); return(ret); } #undef silk_LIMIT_16 static OPUS_INLINE opus_int16 silk_LIMIT_16(opus_int16 a, opus_int16 limit1, opus_int16 limit2) { opus_int16 ret; ops_count += 6; ret = ((limit1) > (limit2) ? ((a) > (limit1) ? (limit1) : ((a) < (limit2) ? (limit2) : (a))) \ : ((a) > (limit2) ? (limit2) : ((a) < (limit1) ? (limit1) : (a)))); return(ret); } #undef silk_LIMIT_32 static OPUS_INLINE opus_int32 silk_LIMIT_32(opus_int32 a, opus_int32 limit1, opus_int32 limit2) { opus_int32 ret; ops_count += 6; ret = ((limit1) > (limit2) ? ((a) > (limit1) ? (limit1) : ((a) < (limit2) ? (limit2) : (a))) \ : ((a) > (limit2) ? (limit2) : ((a) < (limit1) ? (limit1) : (a)))); return(ret); } #else #define varDefine #define silk_SaveCount() #endif #endif jamulus-3.9.1+dfsg/libs/opus/silk/MacroDebug.h0000644000175000017500000010137014340334543020220 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Copyright (C) 2012 Xiph.Org Foundation Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef MACRO_DEBUG_H #define MACRO_DEBUG_H /* Redefine macro functions with extensive assertion in DEBUG mode. As functions can't be undefined, this file can't work with SigProcFIX_MacroCount.h */ #if ( defined (FIXED_DEBUG) || ( 0 && defined (_DEBUG) ) ) && !defined (silk_MACRO_COUNT) #undef silk_ADD16 #define silk_ADD16(a,b) silk_ADD16_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_int16 silk_ADD16_(opus_int16 a, opus_int16 b, char *file, int line){ opus_int16 ret; ret = a + b; if ( ret != silk_ADD_SAT16( a, b ) ) { fprintf (stderr, "silk_ADD16(%d, %d) in %s: line %d\n", a, b, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return ret; } #undef silk_ADD32 #define silk_ADD32(a,b) silk_ADD32_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_ADD32_(opus_int32 a, opus_int32 b, char *file, int line){ opus_int32 ret; ret = a + b; if ( ret != silk_ADD_SAT32( a, b ) ) { fprintf (stderr, "silk_ADD32(%d, %d) in %s: line %d\n", a, b, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return ret; } #undef silk_ADD64 #define silk_ADD64(a,b) silk_ADD64_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_int64 silk_ADD64_(opus_int64 a, opus_int64 b, char *file, int line){ opus_int64 ret; ret = a + b; if ( ret != silk_ADD_SAT64( a, b ) ) { fprintf (stderr, "silk_ADD64(%lld, %lld) in %s: line %d\n", (long long)a, (long long)b, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return ret; } #undef silk_SUB16 #define silk_SUB16(a,b) silk_SUB16_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_int16 silk_SUB16_(opus_int16 a, opus_int16 b, char *file, int line){ opus_int16 ret; ret = a - b; if ( ret != silk_SUB_SAT16( a, b ) ) { fprintf (stderr, "silk_SUB16(%d, %d) in %s: line %d\n", a, b, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return ret; } #undef silk_SUB32 #define silk_SUB32(a,b) silk_SUB32_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_SUB32_(opus_int32 a, opus_int32 b, char *file, int line){ opus_int32 ret; ret = a - b; if ( ret != silk_SUB_SAT32( a, b ) ) { fprintf (stderr, "silk_SUB32(%d, %d) in %s: line %d\n", a, b, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return ret; } #undef silk_SUB64 #define silk_SUB64(a,b) silk_SUB64_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_int64 silk_SUB64_(opus_int64 a, opus_int64 b, char *file, int line){ opus_int64 ret; ret = a - b; if ( ret != silk_SUB_SAT64( a, b ) ) { fprintf (stderr, "silk_SUB64(%lld, %lld) in %s: line %d\n", (long long)a, (long long)b, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return ret; } #undef silk_ADD_SAT16 #define silk_ADD_SAT16(a,b) silk_ADD_SAT16_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_int16 silk_ADD_SAT16_( opus_int16 a16, opus_int16 b16, char *file, int line) { opus_int16 res; res = (opus_int16)silk_SAT16( silk_ADD32( (opus_int32)(a16), (b16) ) ); if ( res != silk_SAT16( (opus_int32)a16 + (opus_int32)b16 ) ) { fprintf (stderr, "silk_ADD_SAT16(%d, %d) in %s: line %d\n", a16, b16, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return res; } #undef silk_ADD_SAT32 #define silk_ADD_SAT32(a,b) silk_ADD_SAT32_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_ADD_SAT32_(opus_int32 a32, opus_int32 b32, char *file, int line){ opus_int32 res; res = ((((opus_uint32)(a32) + (opus_uint32)(b32)) & 0x80000000) == 0 ? \ ((((a32) & (b32)) & 0x80000000) != 0 ? silk_int32_MIN : (a32)+(b32)) : \ ((((a32) | (b32)) & 0x80000000) == 0 ? silk_int32_MAX : (a32)+(b32)) ); if ( res != silk_SAT32( (opus_int64)a32 + (opus_int64)b32 ) ) { fprintf (stderr, "silk_ADD_SAT32(%d, %d) in %s: line %d\n", a32, b32, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return res; } #undef silk_ADD_SAT64 #define silk_ADD_SAT64(a,b) silk_ADD_SAT64_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_int64 silk_ADD_SAT64_( opus_int64 a64, opus_int64 b64, char *file, int line) { opus_int64 res; int fail = 0; res = ((((a64) + (b64)) & 0x8000000000000000LL) == 0 ? \ ((((a64) & (b64)) & 0x8000000000000000LL) != 0 ? silk_int64_MIN : (a64)+(b64)) : \ ((((a64) | (b64)) & 0x8000000000000000LL) == 0 ? silk_int64_MAX : (a64)+(b64)) ); if( res != a64 + b64 ) { /* Check that we saturated to the correct extreme value */ if ( !(( res == silk_int64_MAX && ( ( a64 >> 1 ) + ( b64 >> 1 ) > ( silk_int64_MAX >> 3 ) ) ) || ( res == silk_int64_MIN && ( ( a64 >> 1 ) + ( b64 >> 1 ) < ( silk_int64_MIN >> 3 ) ) ) ) ) { fail = 1; } } else { /* Saturation not necessary */ fail = res != a64 + b64; } if ( fail ) { fprintf (stderr, "silk_ADD_SAT64(%lld, %lld) in %s: line %d\n", (long long)a64, (long long)b64, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return res; } #undef silk_SUB_SAT16 #define silk_SUB_SAT16(a,b) silk_SUB_SAT16_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_int16 silk_SUB_SAT16_( opus_int16 a16, opus_int16 b16, char *file, int line ) { opus_int16 res; res = (opus_int16)silk_SAT16( silk_SUB32( (opus_int32)(a16), (b16) ) ); if ( res != silk_SAT16( (opus_int32)a16 - (opus_int32)b16 ) ) { fprintf (stderr, "silk_SUB_SAT16(%d, %d) in %s: line %d\n", a16, b16, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return res; } #undef silk_SUB_SAT32 #define silk_SUB_SAT32(a,b) silk_SUB_SAT32_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_SUB_SAT32_( opus_int32 a32, opus_int32 b32, char *file, int line ) { opus_int32 res; res = ((((opus_uint32)(a32)-(opus_uint32)(b32)) & 0x80000000) == 0 ? \ (( (a32) & ((b32)^0x80000000) & 0x80000000) ? silk_int32_MIN : (a32)-(b32)) : \ ((((a32)^0x80000000) & (b32) & 0x80000000) ? silk_int32_MAX : (a32)-(b32)) ); if ( res != silk_SAT32( (opus_int64)a32 - (opus_int64)b32 ) ) { fprintf (stderr, "silk_SUB_SAT32(%d, %d) in %s: line %d\n", a32, b32, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return res; } #undef silk_SUB_SAT64 #define silk_SUB_SAT64(a,b) silk_SUB_SAT64_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_int64 silk_SUB_SAT64_( opus_int64 a64, opus_int64 b64, char *file, int line ) { opus_int64 res; int fail = 0; res = ((((a64)-(b64)) & 0x8000000000000000LL) == 0 ? \ (( (a64) & ((b64)^0x8000000000000000LL) & 0x8000000000000000LL) ? silk_int64_MIN : (a64)-(b64)) : \ ((((a64)^0x8000000000000000LL) & (b64) & 0x8000000000000000LL) ? silk_int64_MAX : (a64)-(b64)) ); if( res != a64 - b64 ) { /* Check that we saturated to the correct extreme value */ if( !(( res == silk_int64_MAX && ( ( a64 >> 1 ) + ( b64 >> 1 ) > ( silk_int64_MAX >> 3 ) ) ) || ( res == silk_int64_MIN && ( ( a64 >> 1 ) + ( b64 >> 1 ) < ( silk_int64_MIN >> 3 ) ) ) )) { fail = 1; } } else { /* Saturation not necessary */ fail = res != a64 - b64; } if ( fail ) { fprintf (stderr, "silk_SUB_SAT64(%lld, %lld) in %s: line %d\n", (long long)a64, (long long)b64, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return res; } #undef silk_MUL #define silk_MUL(a,b) silk_MUL_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_MUL_(opus_int32 a32, opus_int32 b32, char *file, int line){ opus_int32 ret; opus_int64 ret64; ret = a32 * b32; ret64 = (opus_int64)a32 * (opus_int64)b32; if ( (opus_int64)ret != ret64 ) { fprintf (stderr, "silk_MUL(%d, %d) in %s: line %d\n", a32, b32, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return ret; } #undef silk_MUL_uint #define silk_MUL_uint(a,b) silk_MUL_uint_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_uint32 silk_MUL_uint_(opus_uint32 a32, opus_uint32 b32, char *file, int line){ opus_uint32 ret; ret = a32 * b32; if ( (opus_uint64)ret != (opus_uint64)a32 * (opus_uint64)b32 ) { fprintf (stderr, "silk_MUL_uint(%u, %u) in %s: line %d\n", a32, b32, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return ret; } #undef silk_MLA #define silk_MLA(a,b,c) silk_MLA_((a), (b), (c), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_MLA_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){ opus_int32 ret; ret = a32 + b32 * c32; if ( (opus_int64)ret != (opus_int64)a32 + (opus_int64)b32 * (opus_int64)c32 ) { fprintf (stderr, "silk_MLA(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return ret; } #undef silk_MLA_uint #define silk_MLA_uint(a,b,c) silk_MLA_uint_((a), (b), (c), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_MLA_uint_(opus_uint32 a32, opus_uint32 b32, opus_uint32 c32, char *file, int line){ opus_uint32 ret; ret = a32 + b32 * c32; if ( (opus_int64)ret != (opus_int64)a32 + (opus_int64)b32 * (opus_int64)c32 ) { fprintf (stderr, "silk_MLA_uint(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return ret; } #undef silk_SMULWB #define silk_SMULWB(a,b) silk_SMULWB_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_SMULWB_(opus_int32 a32, opus_int32 b32, char *file, int line){ opus_int32 ret; ret = (a32 >> 16) * (opus_int32)((opus_int16)b32) + (((a32 & 0x0000FFFF) * (opus_int32)((opus_int16)b32)) >> 16); if ( (opus_int64)ret != ((opus_int64)a32 * (opus_int16)b32) >> 16 ) { fprintf (stderr, "silk_SMULWB(%d, %d) in %s: line %d\n", a32, b32, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return ret; } #undef silk_SMLAWB #define silk_SMLAWB(a,b,c) silk_SMLAWB_((a), (b), (c), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_SMLAWB_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){ opus_int32 ret; ret = silk_ADD32( a32, silk_SMULWB( b32, c32 ) ); if ( silk_ADD32( a32, silk_SMULWB( b32, c32 ) ) != silk_ADD_SAT32( a32, silk_SMULWB( b32, c32 ) ) ) { fprintf (stderr, "silk_SMLAWB(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return ret; } #undef silk_SMULWT #define silk_SMULWT(a,b) silk_SMULWT_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_SMULWT_(opus_int32 a32, opus_int32 b32, char *file, int line){ opus_int32 ret; ret = (a32 >> 16) * (b32 >> 16) + (((a32 & 0x0000FFFF) * (b32 >> 16)) >> 16); if ( (opus_int64)ret != ((opus_int64)a32 * (b32 >> 16)) >> 16 ) { fprintf (stderr, "silk_SMULWT(%d, %d) in %s: line %d\n", a32, b32, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return ret; } #undef silk_SMLAWT #define silk_SMLAWT(a,b,c) silk_SMLAWT_((a), (b), (c), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_SMLAWT_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){ opus_int32 ret; ret = a32 + ((b32 >> 16) * (c32 >> 16)) + (((b32 & 0x0000FFFF) * ((c32 >> 16)) >> 16)); if ( (opus_int64)ret != (opus_int64)a32 + (((opus_int64)b32 * (c32 >> 16)) >> 16) ) { fprintf (stderr, "silk_SMLAWT(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return ret; } #undef silk_SMULL #define silk_SMULL(a,b) silk_SMULL_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_int64 silk_SMULL_(opus_int64 a64, opus_int64 b64, char *file, int line){ opus_int64 ret64; int fail = 0; ret64 = a64 * b64; if( b64 != 0 ) { fail = a64 != (ret64 / b64); } else if( a64 != 0 ) { fail = b64 != (ret64 / a64); } if ( fail ) { fprintf (stderr, "silk_SMULL(%lld, %lld) in %s: line %d\n", (long long)a64, (long long)b64, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return ret64; } /* no checking needed for silk_SMULBB */ #undef silk_SMLABB #define silk_SMLABB(a,b,c) silk_SMLABB_((a), (b), (c), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_SMLABB_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){ opus_int32 ret; ret = a32 + (opus_int32)((opus_int16)b32) * (opus_int32)((opus_int16)c32); if ( (opus_int64)ret != (opus_int64)a32 + (opus_int64)b32 * (opus_int16)c32 ) { fprintf (stderr, "silk_SMLABB(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return ret; } /* no checking needed for silk_SMULBT */ #undef silk_SMLABT #define silk_SMLABT(a,b,c) silk_SMLABT_((a), (b), (c), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_SMLABT_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){ opus_int32 ret; ret = a32 + ((opus_int32)((opus_int16)b32)) * (c32 >> 16); if ( (opus_int64)ret != (opus_int64)a32 + (opus_int64)b32 * (c32 >> 16) ) { fprintf (stderr, "silk_SMLABT(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return ret; } /* no checking needed for silk_SMULTT */ #undef silk_SMLATT #define silk_SMLATT(a,b,c) silk_SMLATT_((a), (b), (c), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_SMLATT_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){ opus_int32 ret; ret = a32 + (b32 >> 16) * (c32 >> 16); if ( (opus_int64)ret != (opus_int64)a32 + (b32 >> 16) * (c32 >> 16) ) { fprintf (stderr, "silk_SMLATT(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return ret; } #undef silk_SMULWW #define silk_SMULWW(a,b) silk_SMULWW_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_SMULWW_(opus_int32 a32, opus_int32 b32, char *file, int line){ opus_int32 ret, tmp1, tmp2; opus_int64 ret64; int fail = 0; ret = silk_SMULWB( a32, b32 ); tmp1 = silk_RSHIFT_ROUND( b32, 16 ); tmp2 = silk_MUL( a32, tmp1 ); fail |= (opus_int64)tmp2 != (opus_int64) a32 * (opus_int64) tmp1; tmp1 = ret; ret = silk_ADD32( tmp1, tmp2 ); fail |= silk_ADD32( tmp1, tmp2 ) != silk_ADD_SAT32( tmp1, tmp2 ); ret64 = silk_RSHIFT64( silk_SMULL( a32, b32 ), 16 ); fail |= (opus_int64)ret != ret64; if ( fail ) { fprintf (stderr, "silk_SMULWT(%d, %d) in %s: line %d\n", a32, b32, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return ret; } #undef silk_SMLAWW #define silk_SMLAWW(a,b,c) silk_SMLAWW_((a), (b), (c), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_SMLAWW_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){ opus_int32 ret, tmp; tmp = silk_SMULWW( b32, c32 ); ret = silk_ADD32( a32, tmp ); if ( ret != silk_ADD_SAT32( a32, tmp ) ) { fprintf (stderr, "silk_SMLAWW(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return ret; } /* Multiply-accumulate macros that allow overflow in the addition (ie, no asserts in debug mode) */ #undef silk_MLA_ovflw #define silk_MLA_ovflw(a32, b32, c32) ((a32) + ((b32) * (c32))) #undef silk_SMLABB_ovflw #define silk_SMLABB_ovflw(a32, b32, c32) ((a32) + ((opus_int32)((opus_int16)(b32))) * (opus_int32)((opus_int16)(c32))) /* no checking needed for silk_SMULL no checking needed for silk_SMLAL no checking needed for silk_SMLALBB no checking needed for SigProcFIX_CLZ16 no checking needed for SigProcFIX_CLZ32*/ #undef silk_DIV32 #define silk_DIV32(a,b) silk_DIV32_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_DIV32_(opus_int32 a32, opus_int32 b32, char *file, int line){ if ( b32 == 0 ) { fprintf (stderr, "silk_DIV32(%d, %d) in %s: line %d\n", a32, b32, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return a32 / b32; } #undef silk_DIV32_16 #define silk_DIV32_16(a,b) silk_DIV32_16_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_DIV32_16_(opus_int32 a32, opus_int32 b32, char *file, int line){ int fail = 0; fail |= b32 == 0; fail |= b32 > silk_int16_MAX; fail |= b32 < silk_int16_MIN; if ( fail ) { fprintf (stderr, "silk_DIV32_16(%d, %d) in %s: line %d\n", a32, b32, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return a32 / b32; } /* no checking needed for silk_SAT8 no checking needed for silk_SAT16 no checking needed for silk_SAT32 no checking needed for silk_POS_SAT32 no checking needed for silk_ADD_POS_SAT8 no checking needed for silk_ADD_POS_SAT16 no checking needed for silk_ADD_POS_SAT32 */ #undef silk_LSHIFT8 #define silk_LSHIFT8(a,b) silk_LSHIFT8_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_int8 silk_LSHIFT8_(opus_int8 a, opus_int32 shift, char *file, int line){ opus_int8 ret; int fail = 0; ret = a << shift; fail |= shift < 0; fail |= shift >= 8; fail |= (opus_int64)ret != ((opus_int64)a) << shift; if ( fail ) { fprintf (stderr, "silk_LSHIFT8(%d, %d) in %s: line %d\n", a, shift, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return ret; } #undef silk_LSHIFT16 #define silk_LSHIFT16(a,b) silk_LSHIFT16_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_int16 silk_LSHIFT16_(opus_int16 a, opus_int32 shift, char *file, int line){ opus_int16 ret; int fail = 0; ret = a << shift; fail |= shift < 0; fail |= shift >= 16; fail |= (opus_int64)ret != ((opus_int64)a) << shift; if ( fail ) { fprintf (stderr, "silk_LSHIFT16(%d, %d) in %s: line %d\n", a, shift, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return ret; } #undef silk_LSHIFT32 #define silk_LSHIFT32(a,b) silk_LSHIFT32_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_LSHIFT32_(opus_int32 a, opus_int32 shift, char *file, int line){ opus_int32 ret; int fail = 0; ret = a << shift; fail |= shift < 0; fail |= shift >= 32; fail |= (opus_int64)ret != ((opus_int64)a) << shift; if ( fail ) { fprintf (stderr, "silk_LSHIFT32(%d, %d) in %s: line %d\n", a, shift, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return ret; } #undef silk_LSHIFT64 #define silk_LSHIFT64(a,b) silk_LSHIFT64_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_int64 silk_LSHIFT64_(opus_int64 a, opus_int shift, char *file, int line){ opus_int64 ret; int fail = 0; ret = a << shift; fail |= shift < 0; fail |= shift >= 64; fail |= (ret>>shift) != ((opus_int64)a); if ( fail ) { fprintf (stderr, "silk_LSHIFT64(%lld, %d) in %s: line %d\n", (long long)a, shift, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return ret; } #undef silk_LSHIFT_ovflw #define silk_LSHIFT_ovflw(a,b) silk_LSHIFT_ovflw_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_LSHIFT_ovflw_(opus_int32 a, opus_int32 shift, char *file, int line){ if ( (shift < 0) || (shift >= 32) ) /* no check for overflow */ { fprintf (stderr, "silk_LSHIFT_ovflw(%d, %d) in %s: line %d\n", a, shift, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return a << shift; } #undef silk_LSHIFT_uint #define silk_LSHIFT_uint(a,b) silk_LSHIFT_uint_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_uint32 silk_LSHIFT_uint_(opus_uint32 a, opus_int32 shift, char *file, int line){ opus_uint32 ret; ret = a << shift; if ( (shift < 0) || ((opus_int64)ret != ((opus_int64)a) << shift)) { fprintf (stderr, "silk_LSHIFT_uint(%u, %d) in %s: line %d\n", a, shift, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return ret; } #undef silk_RSHIFT8 #define silk_RSHITF8(a,b) silk_RSHIFT8_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_int8 silk_RSHIFT8_(opus_int8 a, opus_int32 shift, char *file, int line){ if ( (shift < 0) || (shift>=8) ) { fprintf (stderr, "silk_RSHITF8(%d, %d) in %s: line %d\n", a, shift, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return a >> shift; } #undef silk_RSHIFT16 #define silk_RSHITF16(a,b) silk_RSHIFT16_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_int16 silk_RSHIFT16_(opus_int16 a, opus_int32 shift, char *file, int line){ if ( (shift < 0) || (shift>=16) ) { fprintf (stderr, "silk_RSHITF16(%d, %d) in %s: line %d\n", a, shift, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return a >> shift; } #undef silk_RSHIFT32 #define silk_RSHIFT32(a,b) silk_RSHIFT32_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_RSHIFT32_(opus_int32 a, opus_int32 shift, char *file, int line){ if ( (shift < 0) || (shift>=32) ) { fprintf (stderr, "silk_RSHITF32(%d, %d) in %s: line %d\n", a, shift, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return a >> shift; } #undef silk_RSHIFT64 #define silk_RSHIFT64(a,b) silk_RSHIFT64_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_int64 silk_RSHIFT64_(opus_int64 a, opus_int64 shift, char *file, int line){ if ( (shift < 0) || (shift>=64) ) { fprintf (stderr, "silk_RSHITF64(%lld, %lld) in %s: line %d\n", (long long)a, (long long)shift, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return a >> shift; } #undef silk_RSHIFT_uint #define silk_RSHIFT_uint(a,b) silk_RSHIFT_uint_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_uint32 silk_RSHIFT_uint_(opus_uint32 a, opus_int32 shift, char *file, int line){ if ( (shift < 0) || (shift>32) ) { fprintf (stderr, "silk_RSHIFT_uint(%u, %d) in %s: line %d\n", a, shift, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return a >> shift; } #undef silk_ADD_LSHIFT #define silk_ADD_LSHIFT(a,b,c) silk_ADD_LSHIFT_((a), (b), (c), __FILE__, __LINE__) static OPUS_INLINE int silk_ADD_LSHIFT_(int a, int b, int shift, char *file, int line){ opus_int16 ret; ret = a + (b << shift); if ( (shift < 0) || (shift>15) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) << shift)) ) { fprintf (stderr, "silk_ADD_LSHIFT(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return ret; /* shift >= 0 */ } #undef silk_ADD_LSHIFT32 #define silk_ADD_LSHIFT32(a,b,c) silk_ADD_LSHIFT32_((a), (b), (c), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_ADD_LSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){ opus_int32 ret; ret = a + (b << shift); if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) << shift)) ) { fprintf (stderr, "silk_ADD_LSHIFT32(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return ret; /* shift >= 0 */ } #undef silk_ADD_LSHIFT_uint #define silk_ADD_LSHIFT_uint(a,b,c) silk_ADD_LSHIFT_uint_((a), (b), (c), __FILE__, __LINE__) static OPUS_INLINE opus_uint32 silk_ADD_LSHIFT_uint_(opus_uint32 a, opus_uint32 b, opus_int32 shift, char *file, int line){ opus_uint32 ret; ret = a + (b << shift); if ( (shift < 0) || (shift>32) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) << shift)) ) { fprintf (stderr, "silk_ADD_LSHIFT_uint(%u, %u, %d) in %s: line %d\n", a, b, shift, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return ret; /* shift >= 0 */ } #undef silk_ADD_RSHIFT #define silk_ADD_RSHIFT(a,b,c) silk_ADD_RSHIFT_((a), (b), (c), __FILE__, __LINE__) static OPUS_INLINE int silk_ADD_RSHIFT_(int a, int b, int shift, char *file, int line){ opus_int16 ret; ret = a + (b >> shift); if ( (shift < 0) || (shift>15) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) >> shift)) ) { fprintf (stderr, "silk_ADD_RSHIFT(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return ret; /* shift > 0 */ } #undef silk_ADD_RSHIFT32 #define silk_ADD_RSHIFT32(a,b,c) silk_ADD_RSHIFT32_((a), (b), (c), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_ADD_RSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){ opus_int32 ret; ret = a + (b >> shift); if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) >> shift)) ) { fprintf (stderr, "silk_ADD_RSHIFT32(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return ret; /* shift > 0 */ } #undef silk_ADD_RSHIFT_uint #define silk_ADD_RSHIFT_uint(a,b,c) silk_ADD_RSHIFT_uint_((a), (b), (c), __FILE__, __LINE__) static OPUS_INLINE opus_uint32 silk_ADD_RSHIFT_uint_(opus_uint32 a, opus_uint32 b, opus_int32 shift, char *file, int line){ opus_uint32 ret; ret = a + (b >> shift); if ( (shift < 0) || (shift>32) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) >> shift)) ) { fprintf (stderr, "silk_ADD_RSHIFT_uint(%u, %u, %d) in %s: line %d\n", a, b, shift, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return ret; /* shift > 0 */ } #undef silk_SUB_LSHIFT32 #define silk_SUB_LSHIFT32(a,b,c) silk_SUB_LSHIFT32_((a), (b), (c), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_SUB_LSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){ opus_int32 ret; ret = a - (b << shift); if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a - (((opus_int64)b) << shift)) ) { fprintf (stderr, "silk_SUB_LSHIFT32(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return ret; /* shift >= 0 */ } #undef silk_SUB_RSHIFT32 #define silk_SUB_RSHIFT32(a,b,c) silk_SUB_RSHIFT32_((a), (b), (c), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_SUB_RSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){ opus_int32 ret; ret = a - (b >> shift); if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a - (((opus_int64)b) >> shift)) ) { fprintf (stderr, "silk_SUB_RSHIFT32(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return ret; /* shift > 0 */ } #undef silk_RSHIFT_ROUND #define silk_RSHIFT_ROUND(a,b) silk_RSHIFT_ROUND_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_RSHIFT_ROUND_(opus_int32 a, opus_int32 shift, char *file, int line){ opus_int32 ret; ret = shift == 1 ? (a >> 1) + (a & 1) : ((a >> (shift - 1)) + 1) >> 1; /* the marco definition can't handle a shift of zero */ if ( (shift <= 0) || (shift>31) || ((opus_int64)ret != ((opus_int64)a + ((opus_int64)1 << (shift - 1))) >> shift) ) { fprintf (stderr, "silk_RSHIFT_ROUND(%d, %d) in %s: line %d\n", a, shift, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return ret; } #undef silk_RSHIFT_ROUND64 #define silk_RSHIFT_ROUND64(a,b) silk_RSHIFT_ROUND64_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_int64 silk_RSHIFT_ROUND64_(opus_int64 a, opus_int32 shift, char *file, int line){ opus_int64 ret; /* the marco definition can't handle a shift of zero */ if ( (shift <= 0) || (shift>=64) ) { fprintf (stderr, "silk_RSHIFT_ROUND64(%lld, %d) in %s: line %d\n", (long long)a, shift, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } ret = shift == 1 ? (a >> 1) + (a & 1) : ((a >> (shift - 1)) + 1) >> 1; return ret; } /* silk_abs is used on floats also, so doesn't work... */ /*#undef silk_abs static OPUS_INLINE opus_int32 silk_abs(opus_int32 a){ silk_assert(a != 0x80000000); return (((a) > 0) ? (a) : -(a)); // Be careful, silk_abs returns wrong when input equals to silk_intXX_MIN }*/ #undef silk_abs_int64 #define silk_abs_int64(a) silk_abs_int64_((a), __FILE__, __LINE__) static OPUS_INLINE opus_int64 silk_abs_int64_(opus_int64 a, char *file, int line){ if ( a == silk_int64_MIN ) { fprintf (stderr, "silk_abs_int64(%lld) in %s: line %d\n", (long long)a, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return (((a) > 0) ? (a) : -(a)); /* Be careful, silk_abs returns wrong when input equals to silk_intXX_MIN */ } #undef silk_abs_int32 #define silk_abs_int32(a) silk_abs_int32_((a), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_abs_int32_(opus_int32 a, char *file, int line){ if ( a == silk_int32_MIN ) { fprintf (stderr, "silk_abs_int32(%d) in %s: line %d\n", a, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return silk_abs(a); } #undef silk_CHECK_FIT8 #define silk_CHECK_FIT8(a) silk_CHECK_FIT8_((a), __FILE__, __LINE__) static OPUS_INLINE opus_int8 silk_CHECK_FIT8_( opus_int64 a, char *file, int line ){ opus_int8 ret; ret = (opus_int8)a; if ( (opus_int64)ret != a ) { fprintf (stderr, "silk_CHECK_FIT8(%lld) in %s: line %d\n", (long long)a, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return( ret ); } #undef silk_CHECK_FIT16 #define silk_CHECK_FIT16(a) silk_CHECK_FIT16_((a), __FILE__, __LINE__) static OPUS_INLINE opus_int16 silk_CHECK_FIT16_( opus_int64 a, char *file, int line ){ opus_int16 ret; ret = (opus_int16)a; if ( (opus_int64)ret != a ) { fprintf (stderr, "silk_CHECK_FIT16(%lld) in %s: line %d\n", (long long)a, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return( ret ); } #undef silk_CHECK_FIT32 #define silk_CHECK_FIT32(a) silk_CHECK_FIT32_((a), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_CHECK_FIT32_( opus_int64 a, char *file, int line ){ opus_int32 ret; ret = (opus_int32)a; if ( (opus_int64)ret != a ) { fprintf (stderr, "silk_CHECK_FIT32(%lld) in %s: line %d\n", (long long)a, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif } return( ret ); } /* no checking for silk_NSHIFT_MUL_32_32 no checking for silk_NSHIFT_MUL_16_16 no checking needed for silk_min no checking needed for silk_max no checking needed for silk_sign */ #endif #endif /* MACRO_DEBUG_H */ jamulus-3.9.1+dfsg/libs/opus/silk/NLSF_decode.c0000644000175000017500000001123614340334543020251 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" /* Predictive dequantizer for NLSF residuals */ static OPUS_INLINE void silk_NLSF_residual_dequant( /* O Returns RD value in Q30 */ opus_int16 x_Q10[], /* O Output [ order ] */ const opus_int8 indices[], /* I Quantization indices [ order ] */ const opus_uint8 pred_coef_Q8[], /* I Backward predictor coefs [ order ] */ const opus_int quant_step_size_Q16, /* I Quantization step size */ const opus_int16 order /* I Number of input values */ ) { opus_int i, out_Q10, pred_Q10; out_Q10 = 0; for( i = order-1; i >= 0; i-- ) { pred_Q10 = silk_RSHIFT( silk_SMULBB( out_Q10, (opus_int16)pred_coef_Q8[ i ] ), 8 ); out_Q10 = silk_LSHIFT( indices[ i ], 10 ); if( out_Q10 > 0 ) { out_Q10 = silk_SUB16( out_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) ); } else if( out_Q10 < 0 ) { out_Q10 = silk_ADD16( out_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) ); } out_Q10 = silk_SMLAWB( pred_Q10, (opus_int32)out_Q10, quant_step_size_Q16 ); x_Q10[ i ] = out_Q10; } } /***********************/ /* NLSF vector decoder */ /***********************/ void silk_NLSF_decode( opus_int16 *pNLSF_Q15, /* O Quantized NLSF vector [ LPC_ORDER ] */ opus_int8 *NLSFIndices, /* I Codebook path vector [ LPC_ORDER + 1 ] */ const silk_NLSF_CB_struct *psNLSF_CB /* I Codebook object */ ) { opus_int i; opus_uint8 pred_Q8[ MAX_LPC_ORDER ]; opus_int16 ec_ix[ MAX_LPC_ORDER ]; opus_int16 res_Q10[ MAX_LPC_ORDER ]; opus_int32 NLSF_Q15_tmp; const opus_uint8 *pCB_element; const opus_int16 *pCB_Wght_Q9; /* Unpack entropy table indices and predictor for current CB1 index */ silk_NLSF_unpack( ec_ix, pred_Q8, psNLSF_CB, NLSFIndices[ 0 ] ); /* Predictive residual dequantizer */ silk_NLSF_residual_dequant( res_Q10, &NLSFIndices[ 1 ], pred_Q8, psNLSF_CB->quantStepSize_Q16, psNLSF_CB->order ); /* Apply inverse square-rooted weights to first stage and add to output */ pCB_element = &psNLSF_CB->CB1_NLSF_Q8[ NLSFIndices[ 0 ] * psNLSF_CB->order ]; pCB_Wght_Q9 = &psNLSF_CB->CB1_Wght_Q9[ NLSFIndices[ 0 ] * psNLSF_CB->order ]; for( i = 0; i < psNLSF_CB->order; i++ ) { NLSF_Q15_tmp = silk_ADD_LSHIFT32( silk_DIV32_16( silk_LSHIFT( (opus_int32)res_Q10[ i ], 14 ), pCB_Wght_Q9[ i ] ), (opus_int16)pCB_element[ i ], 7 ); pNLSF_Q15[ i ] = (opus_int16)silk_LIMIT( NLSF_Q15_tmp, 0, 32767 ); } /* NLSF stabilization */ silk_NLSF_stabilize( pNLSF_Q15, psNLSF_CB->deltaMin_Q15, psNLSF_CB->order ); } jamulus-3.9.1+dfsg/libs/opus/silk/tables_gain.c0000644000175000017500000000472714340334543020463 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "tables.h" #ifdef __cplusplus extern "C" { #endif const opus_uint8 silk_gain_iCDF[ 3 ][ N_LEVELS_QGAIN / 8 ] = { { 224, 112, 44, 15, 3, 2, 1, 0 }, { 254, 237, 192, 132, 70, 23, 4, 0 }, { 255, 252, 226, 155, 61, 11, 2, 0 } }; const opus_uint8 silk_delta_gain_iCDF[ MAX_DELTA_GAIN_QUANT - MIN_DELTA_GAIN_QUANT + 1 ] = { 250, 245, 234, 203, 71, 50, 42, 38, 35, 33, 31, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; #ifdef __cplusplus } #endif jamulus-3.9.1+dfsg/libs/opus/silk/NLSF_stabilize.c0000644000175000017500000001431314340334543021013 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* NLSF stabilizer: */ /* */ /* - Moves NLSFs further apart if they are too close */ /* - Moves NLSFs away from borders if they are too close */ /* - High effort to achieve a modification with minimum */ /* Euclidean distance to input vector */ /* - Output are sorted NLSF coefficients */ /* */ #include "SigProc_FIX.h" /* Constant Definitions */ #define MAX_LOOPS 20 /* NLSF stabilizer, for a single input data vector */ void silk_NLSF_stabilize( opus_int16 *NLSF_Q15, /* I/O Unstable/stabilized normalized LSF vector in Q15 [L] */ const opus_int16 *NDeltaMin_Q15, /* I Min distance vector, NDeltaMin_Q15[L] must be >= 1 [L+1] */ const opus_int L /* I Number of NLSF parameters in the input vector */ ) { opus_int i, I=0, k, loops; opus_int16 center_freq_Q15; opus_int32 diff_Q15, min_diff_Q15, min_center_Q15, max_center_Q15; /* This is necessary to ensure an output within range of a opus_int16 */ silk_assert( NDeltaMin_Q15[L] >= 1 ); for( loops = 0; loops < MAX_LOOPS; loops++ ) { /**************************/ /* Find smallest distance */ /**************************/ /* First element */ min_diff_Q15 = NLSF_Q15[0] - NDeltaMin_Q15[0]; I = 0; /* Middle elements */ for( i = 1; i <= L-1; i++ ) { diff_Q15 = NLSF_Q15[i] - ( NLSF_Q15[i-1] + NDeltaMin_Q15[i] ); if( diff_Q15 < min_diff_Q15 ) { min_diff_Q15 = diff_Q15; I = i; } } /* Last element */ diff_Q15 = ( 1 << 15 ) - ( NLSF_Q15[L-1] + NDeltaMin_Q15[L] ); if( diff_Q15 < min_diff_Q15 ) { min_diff_Q15 = diff_Q15; I = L; } /***************************************************/ /* Now check if the smallest distance non-negative */ /***************************************************/ if( min_diff_Q15 >= 0 ) { return; } if( I == 0 ) { /* Move away from lower limit */ NLSF_Q15[0] = NDeltaMin_Q15[0]; } else if( I == L) { /* Move away from higher limit */ NLSF_Q15[L-1] = ( 1 << 15 ) - NDeltaMin_Q15[L]; } else { /* Find the lower extreme for the location of the current center frequency */ min_center_Q15 = 0; for( k = 0; k < I; k++ ) { min_center_Q15 += NDeltaMin_Q15[k]; } min_center_Q15 += silk_RSHIFT( NDeltaMin_Q15[I], 1 ); /* Find the upper extreme for the location of the current center frequency */ max_center_Q15 = 1 << 15; for( k = L; k > I; k-- ) { max_center_Q15 -= NDeltaMin_Q15[k]; } max_center_Q15 -= silk_RSHIFT( NDeltaMin_Q15[I], 1 ); /* Move apart, sorted by value, keeping the same center frequency */ center_freq_Q15 = (opus_int16)silk_LIMIT_32( silk_RSHIFT_ROUND( (opus_int32)NLSF_Q15[I-1] + (opus_int32)NLSF_Q15[I], 1 ), min_center_Q15, max_center_Q15 ); NLSF_Q15[I-1] = center_freq_Q15 - silk_RSHIFT( NDeltaMin_Q15[I], 1 ); NLSF_Q15[I] = NLSF_Q15[I-1] + NDeltaMin_Q15[I]; } } /* Safe and simple fall back method, which is less ideal than the above */ if( loops == MAX_LOOPS ) { /* Insertion sort (fast for already almost sorted arrays): */ /* Best case: O(n) for an already sorted array */ /* Worst case: O(n^2) for an inversely sorted array */ silk_insertion_sort_increasing_all_values_int16( &NLSF_Q15[0], L ); /* First NLSF should be no less than NDeltaMin[0] */ NLSF_Q15[0] = silk_max_int( NLSF_Q15[0], NDeltaMin_Q15[0] ); /* Keep delta_min distance between the NLSFs */ for( i = 1; i < L; i++ ) NLSF_Q15[i] = silk_max_int( NLSF_Q15[i], silk_ADD_SAT16( NLSF_Q15[i-1], NDeltaMin_Q15[i] ) ); /* Last NLSF should be no higher than 1 - NDeltaMin[L] */ NLSF_Q15[L-1] = silk_min_int( NLSF_Q15[L-1], (1<<15) - NDeltaMin_Q15[L] ); /* Keep NDeltaMin distance between the NLSFs */ for( i = L-2; i >= 0; i-- ) NLSF_Q15[i] = silk_min_int( NLSF_Q15[i], NLSF_Q15[i+1] - NDeltaMin_Q15[i+1] ); } } jamulus-3.9.1+dfsg/libs/opus/silk/table_LSF_cos.c0000644000175000017500000001013714340334543020642 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "tables.h" /* Cosine approximation table for LSF conversion */ /* Q12 values (even) */ const opus_int16 silk_LSFCosTab_FIX_Q12[ LSF_COS_TAB_SZ_FIX + 1 ] = { 8192, 8190, 8182, 8170, 8152, 8130, 8104, 8072, 8034, 7994, 7946, 7896, 7840, 7778, 7714, 7644, 7568, 7490, 7406, 7318, 7226, 7128, 7026, 6922, 6812, 6698, 6580, 6458, 6332, 6204, 6070, 5934, 5792, 5648, 5502, 5352, 5198, 5040, 4880, 4718, 4552, 4382, 4212, 4038, 3862, 3684, 3502, 3320, 3136, 2948, 2760, 2570, 2378, 2186, 1990, 1794, 1598, 1400, 1202, 1002, 802, 602, 402, 202, 0, -202, -402, -602, -802, -1002, -1202, -1400, -1598, -1794, -1990, -2186, -2378, -2570, -2760, -2948, -3136, -3320, -3502, -3684, -3862, -4038, -4212, -4382, -4552, -4718, -4880, -5040, -5198, -5352, -5502, -5648, -5792, -5934, -6070, -6204, -6332, -6458, -6580, -6698, -6812, -6922, -7026, -7128, -7226, -7318, -7406, -7490, -7568, -7644, -7714, -7778, -7840, -7896, -7946, -7994, -8034, -8072, -8104, -8130, -8152, -8170, -8182, -8190, -8192 }; jamulus-3.9.1+dfsg/libs/opus/silk/sort.c0000644000175000017500000001417114340334543017174 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* Insertion sort (fast for already almost sorted arrays): */ /* Best case: O(n) for an already sorted array */ /* Worst case: O(n^2) for an inversely sorted array */ /* */ /* Shell short: https://en.wikipedia.org/wiki/Shell_sort */ #include "SigProc_FIX.h" void silk_insertion_sort_increasing( opus_int32 *a, /* I/O Unsorted / Sorted vector */ opus_int *idx, /* O Index vector for the sorted elements */ const opus_int L, /* I Vector length */ const opus_int K /* I Number of correctly sorted positions */ ) { opus_int32 value; opus_int i, j; /* Safety checks */ celt_assert( K > 0 ); celt_assert( L > 0 ); celt_assert( L >= K ); /* Write start indices in index vector */ for( i = 0; i < K; i++ ) { idx[ i ] = i; } /* Sort vector elements by value, increasing order */ for( i = 1; i < K; i++ ) { value = a[ i ]; for( j = i - 1; ( j >= 0 ) && ( value < a[ j ] ); j-- ) { a[ j + 1 ] = a[ j ]; /* Shift value */ idx[ j + 1 ] = idx[ j ]; /* Shift index */ } a[ j + 1 ] = value; /* Write value */ idx[ j + 1 ] = i; /* Write index */ } /* If less than L values are asked for, check the remaining values, */ /* but only spend CPU to ensure that the K first values are correct */ for( i = K; i < L; i++ ) { value = a[ i ]; if( value < a[ K - 1 ] ) { for( j = K - 2; ( j >= 0 ) && ( value < a[ j ] ); j-- ) { a[ j + 1 ] = a[ j ]; /* Shift value */ idx[ j + 1 ] = idx[ j ]; /* Shift index */ } a[ j + 1 ] = value; /* Write value */ idx[ j + 1 ] = i; /* Write index */ } } } #ifdef FIXED_POINT /* This function is only used by the fixed-point build */ void silk_insertion_sort_decreasing_int16( opus_int16 *a, /* I/O Unsorted / Sorted vector */ opus_int *idx, /* O Index vector for the sorted elements */ const opus_int L, /* I Vector length */ const opus_int K /* I Number of correctly sorted positions */ ) { opus_int i, j; opus_int value; /* Safety checks */ celt_assert( K > 0 ); celt_assert( L > 0 ); celt_assert( L >= K ); /* Write start indices in index vector */ for( i = 0; i < K; i++ ) { idx[ i ] = i; } /* Sort vector elements by value, decreasing order */ for( i = 1; i < K; i++ ) { value = a[ i ]; for( j = i - 1; ( j >= 0 ) && ( value > a[ j ] ); j-- ) { a[ j + 1 ] = a[ j ]; /* Shift value */ idx[ j + 1 ] = idx[ j ]; /* Shift index */ } a[ j + 1 ] = value; /* Write value */ idx[ j + 1 ] = i; /* Write index */ } /* If less than L values are asked for, check the remaining values, */ /* but only spend CPU to ensure that the K first values are correct */ for( i = K; i < L; i++ ) { value = a[ i ]; if( value > a[ K - 1 ] ) { for( j = K - 2; ( j >= 0 ) && ( value > a[ j ] ); j-- ) { a[ j + 1 ] = a[ j ]; /* Shift value */ idx[ j + 1 ] = idx[ j ]; /* Shift index */ } a[ j + 1 ] = value; /* Write value */ idx[ j + 1 ] = i; /* Write index */ } } } #endif void silk_insertion_sort_increasing_all_values_int16( opus_int16 *a, /* I/O Unsorted / Sorted vector */ const opus_int L /* I Vector length */ ) { opus_int value; opus_int i, j; /* Safety checks */ celt_assert( L > 0 ); /* Sort vector elements by value, increasing order */ for( i = 1; i < L; i++ ) { value = a[ i ]; for( j = i - 1; ( j >= 0 ) && ( value < a[ j ] ); j-- ) { a[ j + 1 ] = a[ j ]; /* Shift value */ } a[ j + 1 ] = value; /* Write value */ } } jamulus-3.9.1+dfsg/libs/opus/silk/tables_NLSF_CB_WB.c0000644000175000017500000003424314340334543021237 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "tables.h" static const opus_uint8 silk_NLSF_CB1_WB_Q8[ 512 ] = { 7, 23, 38, 54, 69, 85, 100, 116, 131, 147, 162, 178, 193, 208, 223, 239, 13, 25, 41, 55, 69, 83, 98, 112, 127, 142, 157, 171, 187, 203, 220, 236, 15, 21, 34, 51, 61, 78, 92, 106, 126, 136, 152, 167, 185, 205, 225, 240, 10, 21, 36, 50, 63, 79, 95, 110, 126, 141, 157, 173, 189, 205, 221, 237, 17, 20, 37, 51, 59, 78, 89, 107, 123, 134, 150, 164, 184, 205, 224, 240, 10, 15, 32, 51, 67, 81, 96, 112, 129, 142, 158, 173, 189, 204, 220, 236, 8, 21, 37, 51, 65, 79, 98, 113, 126, 138, 155, 168, 179, 192, 209, 218, 12, 15, 34, 55, 63, 78, 87, 108, 118, 131, 148, 167, 185, 203, 219, 236, 16, 19, 32, 36, 56, 79, 91, 108, 118, 136, 154, 171, 186, 204, 220, 237, 11, 28, 43, 58, 74, 89, 105, 120, 135, 150, 165, 180, 196, 211, 226, 241, 6, 16, 33, 46, 60, 75, 92, 107, 123, 137, 156, 169, 185, 199, 214, 225, 11, 19, 30, 44, 57, 74, 89, 105, 121, 135, 152, 169, 186, 202, 218, 234, 12, 19, 29, 46, 57, 71, 88, 100, 120, 132, 148, 165, 182, 199, 216, 233, 17, 23, 35, 46, 56, 77, 92, 106, 123, 134, 152, 167, 185, 204, 222, 237, 14, 17, 45, 53, 63, 75, 89, 107, 115, 132, 151, 171, 188, 206, 221, 240, 9, 16, 29, 40, 56, 71, 88, 103, 119, 137, 154, 171, 189, 205, 222, 237, 16, 19, 36, 48, 57, 76, 87, 105, 118, 132, 150, 167, 185, 202, 218, 236, 12, 17, 29, 54, 71, 81, 94, 104, 126, 136, 149, 164, 182, 201, 221, 237, 15, 28, 47, 62, 79, 97, 115, 129, 142, 155, 168, 180, 194, 208, 223, 238, 8, 14, 30, 45, 62, 78, 94, 111, 127, 143, 159, 175, 192, 207, 223, 239, 17, 30, 49, 62, 79, 92, 107, 119, 132, 145, 160, 174, 190, 204, 220, 235, 14, 19, 36, 45, 61, 76, 91, 108, 121, 138, 154, 172, 189, 205, 222, 238, 12, 18, 31, 45, 60, 76, 91, 107, 123, 138, 154, 171, 187, 204, 221, 236, 13, 17, 31, 43, 53, 70, 83, 103, 114, 131, 149, 167, 185, 203, 220, 237, 17, 22, 35, 42, 58, 78, 93, 110, 125, 139, 155, 170, 188, 206, 224, 240, 8, 15, 34, 50, 67, 83, 99, 115, 131, 146, 162, 178, 193, 209, 224, 239, 13, 16, 41, 66, 73, 86, 95, 111, 128, 137, 150, 163, 183, 206, 225, 241, 17, 25, 37, 52, 63, 75, 92, 102, 119, 132, 144, 160, 175, 191, 212, 231, 19, 31, 49, 65, 83, 100, 117, 133, 147, 161, 174, 187, 200, 213, 227, 242, 18, 31, 52, 68, 88, 103, 117, 126, 138, 149, 163, 177, 192, 207, 223, 239, 16, 29, 47, 61, 76, 90, 106, 119, 133, 147, 161, 176, 193, 209, 224, 240, 15, 21, 35, 50, 61, 73, 86, 97, 110, 119, 129, 141, 175, 198, 218, 237 }; static const opus_int16 silk_NLSF_CB1_WB_Wght_Q9[ 512 ] = { 3657, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2963, 2963, 2925, 2846, 3216, 3085, 2972, 3056, 3056, 3010, 3010, 3010, 2963, 2963, 3010, 2972, 2888, 2846, 2846, 2726, 3920, 4014, 2981, 3207, 3207, 2934, 3056, 2846, 3122, 3244, 2925, 2846, 2620, 2553, 2780, 2925, 3516, 3197, 3010, 3103, 3019, 2888, 2925, 2925, 2925, 2925, 2888, 2888, 2888, 2888, 2888, 2753, 5054, 5054, 2934, 3573, 3385, 3056, 3085, 2793, 3160, 3160, 2972, 2846, 2513, 2540, 2753, 2888, 4428, 4149, 2700, 2753, 2972, 3010, 2925, 2846, 2981, 3019, 2925, 2925, 2925, 2925, 2888, 2726, 3620, 3019, 2972, 3056, 3056, 2873, 2806, 3056, 3216, 3047, 2981, 3291, 3291, 2981, 3310, 2991, 5227, 5014, 2540, 3338, 3526, 3385, 3197, 3094, 3376, 2981, 2700, 2647, 2687, 2793, 2846, 2673, 5081, 5174, 4615, 4428, 2460, 2897, 3047, 3207, 3169, 2687, 2740, 2888, 2846, 2793, 2846, 2700, 3122, 2888, 2963, 2925, 2925, 2925, 2925, 2963, 2963, 2963, 2963, 2925, 2925, 2963, 2963, 2963, 4202, 3207, 2981, 3103, 3010, 2888, 2888, 2925, 2972, 2873, 2916, 3019, 2972, 3010, 3197, 2873, 3760, 3760, 3244, 3103, 2981, 2888, 2925, 2888, 2972, 2934, 2793, 2793, 2846, 2888, 2888, 2660, 3854, 4014, 3207, 3122, 3244, 2934, 3047, 2963, 2963, 3085, 2846, 2793, 2793, 2793, 2793, 2580, 3845, 4080, 3357, 3516, 3094, 2740, 3010, 2934, 3122, 3085, 2846, 2846, 2647, 2647, 2846, 2806, 5147, 4894, 3225, 3845, 3441, 3169, 2897, 3413, 3451, 2700, 2580, 2673, 2740, 2846, 2806, 2753, 4109, 3789, 3291, 3160, 2925, 2888, 2888, 2925, 2793, 2740, 2793, 2740, 2793, 2846, 2888, 2806, 5081, 5054, 3047, 3545, 3244, 3056, 3085, 2944, 3103, 2897, 2740, 2740, 2740, 2846, 2793, 2620, 4309, 4309, 2860, 2527, 3207, 3376, 3376, 3075, 3075, 3376, 3056, 2846, 2647, 2580, 2726, 2753, 3056, 2916, 2806, 2888, 2740, 2687, 2897, 3103, 3150, 3150, 3216, 3169, 3056, 3010, 2963, 2846, 4375, 3882, 2925, 2888, 2846, 2888, 2846, 2846, 2888, 2888, 2888, 2846, 2888, 2925, 2888, 2846, 2981, 2916, 2916, 2981, 2981, 3056, 3122, 3216, 3150, 3056, 3010, 2972, 2972, 2972, 2925, 2740, 4229, 4149, 3310, 3347, 2925, 2963, 2888, 2981, 2981, 2846, 2793, 2740, 2846, 2846, 2846, 2793, 4080, 4014, 3103, 3010, 2925, 2925, 2925, 2888, 2925, 2925, 2846, 2846, 2846, 2793, 2888, 2780, 4615, 4575, 3169, 3441, 3207, 2981, 2897, 3038, 3122, 2740, 2687, 2687, 2687, 2740, 2793, 2700, 4149, 4269, 3789, 3657, 2726, 2780, 2888, 2888, 3010, 2972, 2925, 2846, 2687, 2687, 2793, 2888, 4215, 3554, 2753, 2846, 2846, 2888, 2888, 2888, 2925, 2925, 2888, 2925, 2925, 2925, 2963, 2888, 5174, 4921, 2261, 3432, 3789, 3479, 3347, 2846, 3310, 3479, 3150, 2897, 2460, 2487, 2753, 2925, 3451, 3685, 3122, 3197, 3357, 3047, 3207, 3207, 2981, 3216, 3085, 2925, 2925, 2687, 2540, 2434, 2981, 3010, 2793, 2793, 2740, 2793, 2846, 2972, 3056, 3103, 3150, 3150, 3150, 3103, 3010, 3010, 2944, 2873, 2687, 2726, 2780, 3010, 3432, 3545, 3357, 3244, 3056, 3010, 2963, 2925, 2888, 2846, 3019, 2944, 2897, 3010, 3010, 2972, 3019, 3103, 3056, 3056, 3010, 2888, 2846, 2925, 2925, 2888, 3920, 3967, 3010, 3197, 3357, 3216, 3291, 3291, 3479, 3704, 3441, 2726, 2181, 2460, 2580, 2607 }; static const opus_uint8 silk_NLSF_CB1_iCDF_WB[ 64 ] = { 225, 204, 201, 184, 183, 175, 158, 154, 153, 135, 119, 115, 113, 110, 109, 99, 98, 95, 79, 68, 52, 50, 48, 45, 43, 32, 31, 27, 18, 10, 3, 0, 255, 251, 235, 230, 212, 201, 196, 182, 167, 166, 163, 151, 138, 124, 110, 104, 90, 78, 76, 70, 69, 57, 45, 34, 24, 21, 11, 6, 5, 4, 3, 0 }; static const opus_uint8 silk_NLSF_CB2_SELECT_WB[ 256 ] = { 0, 0, 0, 0, 0, 0, 0, 1, 100, 102, 102, 68, 68, 36, 34, 96, 164, 107, 158, 185, 180, 185, 139, 102, 64, 66, 36, 34, 34, 0, 1, 32, 208, 139, 141, 191, 152, 185, 155, 104, 96, 171, 104, 166, 102, 102, 102, 132, 1, 0, 0, 0, 0, 16, 16, 0, 80, 109, 78, 107, 185, 139, 103, 101, 208, 212, 141, 139, 173, 153, 123, 103, 36, 0, 0, 0, 0, 0, 0, 1, 48, 0, 0, 0, 0, 0, 0, 32, 68, 135, 123, 119, 119, 103, 69, 98, 68, 103, 120, 118, 118, 102, 71, 98, 134, 136, 157, 184, 182, 153, 139, 134, 208, 168, 248, 75, 189, 143, 121, 107, 32, 49, 34, 34, 34, 0, 17, 2, 210, 235, 139, 123, 185, 137, 105, 134, 98, 135, 104, 182, 100, 183, 171, 134, 100, 70, 68, 70, 66, 66, 34, 131, 64, 166, 102, 68, 36, 2, 1, 0, 134, 166, 102, 68, 34, 34, 66, 132, 212, 246, 158, 139, 107, 107, 87, 102, 100, 219, 125, 122, 137, 118, 103, 132, 114, 135, 137, 105, 171, 106, 50, 34, 164, 214, 141, 143, 185, 151, 121, 103, 192, 34, 0, 0, 0, 0, 0, 1, 208, 109, 74, 187, 134, 249, 159, 137, 102, 110, 154, 118, 87, 101, 119, 101, 0, 2, 0, 36, 36, 66, 68, 35, 96, 164, 102, 100, 36, 0, 2, 33, 167, 138, 174, 102, 100, 84, 2, 2, 100, 107, 120, 119, 36, 197, 24, 0 }; static const opus_uint8 silk_NLSF_CB2_iCDF_WB[ 72 ] = { 255, 254, 253, 244, 12, 3, 2, 1, 0, 255, 254, 252, 224, 38, 3, 2, 1, 0, 255, 254, 251, 209, 57, 4, 2, 1, 0, 255, 254, 244, 195, 69, 4, 2, 1, 0, 255, 251, 232, 184, 84, 7, 2, 1, 0, 255, 254, 240, 186, 86, 14, 2, 1, 0, 255, 254, 239, 178, 91, 30, 5, 1, 0, 255, 248, 227, 177, 100, 19, 2, 1, 0 }; static const opus_uint8 silk_NLSF_CB2_BITS_WB_Q5[ 72 ] = { 255, 255, 255, 156, 4, 154, 255, 255, 255, 255, 255, 227, 102, 15, 92, 255, 255, 255, 255, 255, 213, 83, 24, 72, 236, 255, 255, 255, 255, 150, 76, 33, 63, 214, 255, 255, 255, 190, 121, 77, 43, 55, 185, 255, 255, 255, 245, 137, 71, 43, 59, 139, 255, 255, 255, 255, 131, 66, 50, 66, 107, 194, 255, 255, 166, 116, 76, 55, 53, 125, 255, 255 }; static const opus_uint8 silk_NLSF_PRED_WB_Q8[ 30 ] = { 175, 148, 160, 176, 178, 173, 174, 164, 177, 174, 196, 182, 198, 192, 182, 68, 62, 66, 60, 72, 117, 85, 90, 118, 136, 151, 142, 160, 142, 155 }; static const opus_int16 silk_NLSF_DELTA_MIN_WB_Q15[ 17 ] = { 100, 3, 40, 3, 3, 3, 5, 14, 14, 10, 11, 3, 8, 9, 7, 3, 347 }; const silk_NLSF_CB_struct silk_NLSF_CB_WB = { 32, 16, SILK_FIX_CONST( 0.15, 16 ), SILK_FIX_CONST( 1.0 / 0.15, 6 ), silk_NLSF_CB1_WB_Q8, silk_NLSF_CB1_WB_Wght_Q9, silk_NLSF_CB1_iCDF_WB, silk_NLSF_PRED_WB_Q8, silk_NLSF_CB2_SELECT_WB, silk_NLSF_CB2_iCDF_WB, silk_NLSF_CB2_BITS_WB_Q5, silk_NLSF_DELTA_MIN_WB_Q15, }; jamulus-3.9.1+dfsg/libs/opus/silk/A2NLSF.c0000644000175000017500000002500714340334543017132 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ /* Conversion between prediction filter coefficients and NLSFs */ /* Requires the order to be an even number */ /* A piecewise linear approximation maps LSF <-> cos(LSF) */ /* Therefore the result is not accurate NLSFs, but the two */ /* functions are accurate inverses of each other */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FIX.h" #include "tables.h" /* Number of binary divisions, when not in low complexity mode */ #define BIN_DIV_STEPS_A2NLSF_FIX 3 /* must be no higher than 16 - log2( LSF_COS_TAB_SZ_FIX ) */ #define MAX_ITERATIONS_A2NLSF_FIX 16 /* Helper function for A2NLSF(..) */ /* Transforms polynomials from cos(n*f) to cos(f)^n */ static OPUS_INLINE void silk_A2NLSF_trans_poly( opus_int32 *p, /* I/O Polynomial */ const opus_int dd /* I Polynomial order (= filter order / 2 ) */ ) { opus_int k, n; for( k = 2; k <= dd; k++ ) { for( n = dd; n > k; n-- ) { p[ n - 2 ] -= p[ n ]; } p[ k - 2 ] -= silk_LSHIFT( p[ k ], 1 ); } } /* Helper function for A2NLSF(..) */ /* Polynomial evaluation */ static OPUS_INLINE opus_int32 silk_A2NLSF_eval_poly( /* return the polynomial evaluation, in Q16 */ opus_int32 *p, /* I Polynomial, Q16 */ const opus_int32 x, /* I Evaluation point, Q12 */ const opus_int dd /* I Order */ ) { opus_int n; opus_int32 x_Q16, y32; y32 = p[ dd ]; /* Q16 */ x_Q16 = silk_LSHIFT( x, 4 ); if ( opus_likely( 8 == dd ) ) { y32 = silk_SMLAWW( p[ 7 ], y32, x_Q16 ); y32 = silk_SMLAWW( p[ 6 ], y32, x_Q16 ); y32 = silk_SMLAWW( p[ 5 ], y32, x_Q16 ); y32 = silk_SMLAWW( p[ 4 ], y32, x_Q16 ); y32 = silk_SMLAWW( p[ 3 ], y32, x_Q16 ); y32 = silk_SMLAWW( p[ 2 ], y32, x_Q16 ); y32 = silk_SMLAWW( p[ 1 ], y32, x_Q16 ); y32 = silk_SMLAWW( p[ 0 ], y32, x_Q16 ); } else { for( n = dd - 1; n >= 0; n-- ) { y32 = silk_SMLAWW( p[ n ], y32, x_Q16 ); /* Q16 */ } } return y32; } static OPUS_INLINE void silk_A2NLSF_init( const opus_int32 *a_Q16, opus_int32 *P, opus_int32 *Q, const opus_int dd ) { opus_int k; /* Convert filter coefs to even and odd polynomials */ P[dd] = silk_LSHIFT( 1, 16 ); Q[dd] = silk_LSHIFT( 1, 16 ); for( k = 0; k < dd; k++ ) { P[ k ] = -a_Q16[ dd - k - 1 ] - a_Q16[ dd + k ]; /* Q16 */ Q[ k ] = -a_Q16[ dd - k - 1 ] + a_Q16[ dd + k ]; /* Q16 */ } /* Divide out zeros as we have that for even filter orders, */ /* z = 1 is always a root in Q, and */ /* z = -1 is always a root in P */ for( k = dd; k > 0; k-- ) { P[ k - 1 ] -= P[ k ]; Q[ k - 1 ] += Q[ k ]; } /* Transform polynomials from cos(n*f) to cos(f)^n */ silk_A2NLSF_trans_poly( P, dd ); silk_A2NLSF_trans_poly( Q, dd ); } /* Compute Normalized Line Spectral Frequencies (NLSFs) from whitening filter coefficients */ /* If not all roots are found, the a_Q16 coefficients are bandwidth expanded until convergence. */ void silk_A2NLSF( opus_int16 *NLSF, /* O Normalized Line Spectral Frequencies in Q15 (0..2^15-1) [d] */ opus_int32 *a_Q16, /* I/O Monic whitening filter coefficients in Q16 [d] */ const opus_int d /* I Filter order (must be even) */ ) { opus_int i, k, m, dd, root_ix, ffrac; opus_int32 xlo, xhi, xmid; opus_int32 ylo, yhi, ymid, thr; opus_int32 nom, den; opus_int32 P[ SILK_MAX_ORDER_LPC / 2 + 1 ]; opus_int32 Q[ SILK_MAX_ORDER_LPC / 2 + 1 ]; opus_int32 *PQ[ 2 ]; opus_int32 *p; /* Store pointers to array */ PQ[ 0 ] = P; PQ[ 1 ] = Q; dd = silk_RSHIFT( d, 1 ); silk_A2NLSF_init( a_Q16, P, Q, dd ); /* Find roots, alternating between P and Q */ p = P; /* Pointer to polynomial */ xlo = silk_LSFCosTab_FIX_Q12[ 0 ]; /* Q12*/ ylo = silk_A2NLSF_eval_poly( p, xlo, dd ); if( ylo < 0 ) { /* Set the first NLSF to zero and move on to the next */ NLSF[ 0 ] = 0; p = Q; /* Pointer to polynomial */ ylo = silk_A2NLSF_eval_poly( p, xlo, dd ); root_ix = 1; /* Index of current root */ } else { root_ix = 0; /* Index of current root */ } k = 1; /* Loop counter */ i = 0; /* Counter for bandwidth expansions applied */ thr = 0; while( 1 ) { /* Evaluate polynomial */ xhi = silk_LSFCosTab_FIX_Q12[ k ]; /* Q12 */ yhi = silk_A2NLSF_eval_poly( p, xhi, dd ); /* Detect zero crossing */ if( ( ylo <= 0 && yhi >= thr ) || ( ylo >= 0 && yhi <= -thr ) ) { if( yhi == 0 ) { /* If the root lies exactly at the end of the current */ /* interval, look for the next root in the next interval */ thr = 1; } else { thr = 0; } /* Binary division */ ffrac = -256; for( m = 0; m < BIN_DIV_STEPS_A2NLSF_FIX; m++ ) { /* Evaluate polynomial */ xmid = silk_RSHIFT_ROUND( xlo + xhi, 1 ); ymid = silk_A2NLSF_eval_poly( p, xmid, dd ); /* Detect zero crossing */ if( ( ylo <= 0 && ymid >= 0 ) || ( ylo >= 0 && ymid <= 0 ) ) { /* Reduce frequency */ xhi = xmid; yhi = ymid; } else { /* Increase frequency */ xlo = xmid; ylo = ymid; ffrac = silk_ADD_RSHIFT( ffrac, 128, m ); } } /* Interpolate */ if( silk_abs( ylo ) < 65536 ) { /* Avoid dividing by zero */ den = ylo - yhi; nom = silk_LSHIFT( ylo, 8 - BIN_DIV_STEPS_A2NLSF_FIX ) + silk_RSHIFT( den, 1 ); if( den != 0 ) { ffrac += silk_DIV32( nom, den ); } } else { /* No risk of dividing by zero because abs(ylo - yhi) >= abs(ylo) >= 65536 */ ffrac += silk_DIV32( ylo, silk_RSHIFT( ylo - yhi, 8 - BIN_DIV_STEPS_A2NLSF_FIX ) ); } NLSF[ root_ix ] = (opus_int16)silk_min_32( silk_LSHIFT( (opus_int32)k, 8 ) + ffrac, silk_int16_MAX ); silk_assert( NLSF[ root_ix ] >= 0 ); root_ix++; /* Next root */ if( root_ix >= d ) { /* Found all roots */ break; } /* Alternate pointer to polynomial */ p = PQ[ root_ix & 1 ]; /* Evaluate polynomial */ xlo = silk_LSFCosTab_FIX_Q12[ k - 1 ]; /* Q12*/ ylo = silk_LSHIFT( 1 - ( root_ix & 2 ), 12 ); } else { /* Increment loop counter */ k++; xlo = xhi; ylo = yhi; thr = 0; if( k > LSF_COS_TAB_SZ_FIX ) { i++; if( i > MAX_ITERATIONS_A2NLSF_FIX ) { /* Set NLSFs to white spectrum and exit */ NLSF[ 0 ] = (opus_int16)silk_DIV32_16( 1 << 15, d + 1 ); for( k = 1; k < d; k++ ) { NLSF[ k ] = (opus_int16)silk_ADD16( NLSF[ k-1 ], NLSF[ 0 ] ); } return; } /* Error: Apply progressively more bandwidth expansion and run again */ silk_bwexpander_32( a_Q16, d, 65536 - silk_LSHIFT( 1, i ) ); silk_A2NLSF_init( a_Q16, P, Q, dd ); p = P; /* Pointer to polynomial */ xlo = silk_LSFCosTab_FIX_Q12[ 0 ]; /* Q12*/ ylo = silk_A2NLSF_eval_poly( p, xlo, dd ); if( ylo < 0 ) { /* Set the first NLSF to zero and move on to the next */ NLSF[ 0 ] = 0; p = Q; /* Pointer to polynomial */ ylo = silk_A2NLSF_eval_poly( p, xlo, dd ); root_ix = 1; /* Index of current root */ } else { root_ix = 0; /* Index of current root */ } k = 1; /* Reset loop counter */ } } } } jamulus-3.9.1+dfsg/libs/opus/silk/resampler_rom.c0000644000175000017500000001121314340334543021046 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* Filter coefficients for IIR/FIR polyphase resampling * * Total size: 179 Words (358 Bytes) */ #include "resampler_private.h" /* Matlab code for the notch filter coefficients: */ /* B = [1, 0.147, 1]; A = [1, 0.107, 0.89]; G = 0.93; freqz(G * B, A, 2^14, 16e3); axis([0, 8000, -10, 1]) */ /* fprintf('\t%6d, %6d, %6d, %6d\n', round(B(2)*2^16), round(-A(2)*2^16), round((1-A(3))*2^16), round(G*2^15)) */ /* const opus_int16 silk_resampler_up2_hq_notch[ 4 ] = { 9634, -7012, 7209, 30474 }; */ /* Tables with IIR and FIR coefficients for fractional downsamplers (123 Words) */ silk_DWORD_ALIGN const opus_int16 silk_Resampler_3_4_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ] = { -20694, -13867, -49, 64, 17, -157, 353, -496, 163, 11047, 22205, -39, 6, 91, -170, 186, 23, -896, 6336, 19928, -19, -36, 102, -89, -24, 328, -951, 2568, 15909, }; silk_DWORD_ALIGN const opus_int16 silk_Resampler_2_3_COEFS[ 2 + 2 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ] = { -14457, -14019, 64, 128, -122, 36, 310, -768, 584, 9267, 17733, 12, 128, 18, -142, 288, -117, -865, 4123, 14459, }; silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_2_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR1 / 2 ] = { 616, -14323, -10, 39, 58, -46, -84, 120, 184, -315, -541, 1284, 5380, 9024, }; silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_3_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = { 16102, -15162, -13, 0, 20, 26, 5, -31, -43, -4, 65, 90, 7, -157, -248, -44, 593, 1583, 2612, 3271, }; silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_4_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = { 22500, -15099, 3, -14, -20, -15, 2, 25, 37, 25, -16, -71, -107, -79, 50, 292, 623, 982, 1288, 1464, }; silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_6_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = { 27540, -15257, 17, 12, 8, 1, -10, -22, -30, -32, -22, 3, 44, 100, 168, 243, 317, 381, 429, 455, }; silk_DWORD_ALIGN const opus_int16 silk_Resampler_2_3_COEFS_LQ[ 2 + 2 * 2 ] = { -2797, -6507, 4697, 10739, 1567, 8276, }; /* Table with interplation fractions of 1/24, 3/24, 5/24, ... , 23/24 : 23/24 (46 Words) */ silk_DWORD_ALIGN const opus_int16 silk_resampler_frac_FIR_12[ 12 ][ RESAMPLER_ORDER_FIR_12 / 2 ] = { { 189, -600, 617, 30567 }, { 117, -159, -1070, 29704 }, { 52, 221, -2392, 28276 }, { -4, 529, -3350, 26341 }, { -48, 758, -3956, 23973 }, { -80, 905, -4235, 21254 }, { -99, 972, -4222, 18278 }, { -107, 967, -3957, 15143 }, { -103, 896, -3487, 11950 }, { -91, 773, -2865, 8798 }, { -71, 611, -2143, 5784 }, { -46, 425, -1375, 2996 }, }; jamulus-3.9.1+dfsg/libs/opus/silk/encode_indices.c0000644000175000017500000002221714340334543021140 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" /* Encode side-information parameters to payload */ void silk_encode_indices( silk_encoder_state *psEncC, /* I/O Encoder state */ ec_enc *psRangeEnc, /* I/O Compressor data structure */ opus_int FrameIndex, /* I Frame number */ opus_int encode_LBRR, /* I Flag indicating LBRR data is being encoded */ opus_int condCoding /* I The type of conditional coding to use */ ) { opus_int i, k, typeOffset; opus_int encode_absolute_lagIndex, delta_lagIndex; opus_int16 ec_ix[ MAX_LPC_ORDER ]; opus_uint8 pred_Q8[ MAX_LPC_ORDER ]; const SideInfoIndices *psIndices; if( encode_LBRR ) { psIndices = &psEncC->indices_LBRR[ FrameIndex ]; } else { psIndices = &psEncC->indices; } /*******************************************/ /* Encode signal type and quantizer offset */ /*******************************************/ typeOffset = 2 * psIndices->signalType + psIndices->quantOffsetType; celt_assert( typeOffset >= 0 && typeOffset < 6 ); celt_assert( encode_LBRR == 0 || typeOffset >= 2 ); if( encode_LBRR || typeOffset >= 2 ) { ec_enc_icdf( psRangeEnc, typeOffset - 2, silk_type_offset_VAD_iCDF, 8 ); } else { ec_enc_icdf( psRangeEnc, typeOffset, silk_type_offset_no_VAD_iCDF, 8 ); } /****************/ /* Encode gains */ /****************/ /* first subframe */ if( condCoding == CODE_CONDITIONALLY ) { /* conditional coding */ silk_assert( psIndices->GainsIndices[ 0 ] >= 0 && psIndices->GainsIndices[ 0 ] < MAX_DELTA_GAIN_QUANT - MIN_DELTA_GAIN_QUANT + 1 ); ec_enc_icdf( psRangeEnc, psIndices->GainsIndices[ 0 ], silk_delta_gain_iCDF, 8 ); } else { /* independent coding, in two stages: MSB bits followed by 3 LSBs */ silk_assert( psIndices->GainsIndices[ 0 ] >= 0 && psIndices->GainsIndices[ 0 ] < N_LEVELS_QGAIN ); ec_enc_icdf( psRangeEnc, silk_RSHIFT( psIndices->GainsIndices[ 0 ], 3 ), silk_gain_iCDF[ psIndices->signalType ], 8 ); ec_enc_icdf( psRangeEnc, psIndices->GainsIndices[ 0 ] & 7, silk_uniform8_iCDF, 8 ); } /* remaining subframes */ for( i = 1; i < psEncC->nb_subfr; i++ ) { silk_assert( psIndices->GainsIndices[ i ] >= 0 && psIndices->GainsIndices[ i ] < MAX_DELTA_GAIN_QUANT - MIN_DELTA_GAIN_QUANT + 1 ); ec_enc_icdf( psRangeEnc, psIndices->GainsIndices[ i ], silk_delta_gain_iCDF, 8 ); } /****************/ /* Encode NLSFs */ /****************/ ec_enc_icdf( psRangeEnc, psIndices->NLSFIndices[ 0 ], &psEncC->psNLSF_CB->CB1_iCDF[ ( psIndices->signalType >> 1 ) * psEncC->psNLSF_CB->nVectors ], 8 ); silk_NLSF_unpack( ec_ix, pred_Q8, psEncC->psNLSF_CB, psIndices->NLSFIndices[ 0 ] ); celt_assert( psEncC->psNLSF_CB->order == psEncC->predictLPCOrder ); for( i = 0; i < psEncC->psNLSF_CB->order; i++ ) { if( psIndices->NLSFIndices[ i+1 ] >= NLSF_QUANT_MAX_AMPLITUDE ) { ec_enc_icdf( psRangeEnc, 2 * NLSF_QUANT_MAX_AMPLITUDE, &psEncC->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 ); ec_enc_icdf( psRangeEnc, psIndices->NLSFIndices[ i+1 ] - NLSF_QUANT_MAX_AMPLITUDE, silk_NLSF_EXT_iCDF, 8 ); } else if( psIndices->NLSFIndices[ i+1 ] <= -NLSF_QUANT_MAX_AMPLITUDE ) { ec_enc_icdf( psRangeEnc, 0, &psEncC->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 ); ec_enc_icdf( psRangeEnc, -psIndices->NLSFIndices[ i+1 ] - NLSF_QUANT_MAX_AMPLITUDE, silk_NLSF_EXT_iCDF, 8 ); } else { ec_enc_icdf( psRangeEnc, psIndices->NLSFIndices[ i+1 ] + NLSF_QUANT_MAX_AMPLITUDE, &psEncC->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 ); } } /* Encode NLSF interpolation factor */ if( psEncC->nb_subfr == MAX_NB_SUBFR ) { silk_assert( psIndices->NLSFInterpCoef_Q2 >= 0 && psIndices->NLSFInterpCoef_Q2 < 5 ); ec_enc_icdf( psRangeEnc, psIndices->NLSFInterpCoef_Q2, silk_NLSF_interpolation_factor_iCDF, 8 ); } if( psIndices->signalType == TYPE_VOICED ) { /*********************/ /* Encode pitch lags */ /*********************/ /* lag index */ encode_absolute_lagIndex = 1; if( condCoding == CODE_CONDITIONALLY && psEncC->ec_prevSignalType == TYPE_VOICED ) { /* Delta Encoding */ delta_lagIndex = psIndices->lagIndex - psEncC->ec_prevLagIndex; if( delta_lagIndex < -8 || delta_lagIndex > 11 ) { delta_lagIndex = 0; } else { delta_lagIndex = delta_lagIndex + 9; encode_absolute_lagIndex = 0; /* Only use delta */ } silk_assert( delta_lagIndex >= 0 && delta_lagIndex < 21 ); ec_enc_icdf( psRangeEnc, delta_lagIndex, silk_pitch_delta_iCDF, 8 ); } if( encode_absolute_lagIndex ) { /* Absolute encoding */ opus_int32 pitch_high_bits, pitch_low_bits; pitch_high_bits = silk_DIV32_16( psIndices->lagIndex, silk_RSHIFT( psEncC->fs_kHz, 1 ) ); pitch_low_bits = psIndices->lagIndex - silk_SMULBB( pitch_high_bits, silk_RSHIFT( psEncC->fs_kHz, 1 ) ); silk_assert( pitch_low_bits < psEncC->fs_kHz / 2 ); silk_assert( pitch_high_bits < 32 ); ec_enc_icdf( psRangeEnc, pitch_high_bits, silk_pitch_lag_iCDF, 8 ); ec_enc_icdf( psRangeEnc, pitch_low_bits, psEncC->pitch_lag_low_bits_iCDF, 8 ); } psEncC->ec_prevLagIndex = psIndices->lagIndex; /* Contour index */ silk_assert( psIndices->contourIndex >= 0 ); silk_assert( ( psIndices->contourIndex < 34 && psEncC->fs_kHz > 8 && psEncC->nb_subfr == 4 ) || ( psIndices->contourIndex < 11 && psEncC->fs_kHz == 8 && psEncC->nb_subfr == 4 ) || ( psIndices->contourIndex < 12 && psEncC->fs_kHz > 8 && psEncC->nb_subfr == 2 ) || ( psIndices->contourIndex < 3 && psEncC->fs_kHz == 8 && psEncC->nb_subfr == 2 ) ); ec_enc_icdf( psRangeEnc, psIndices->contourIndex, psEncC->pitch_contour_iCDF, 8 ); /********************/ /* Encode LTP gains */ /********************/ /* PERIndex value */ silk_assert( psIndices->PERIndex >= 0 && psIndices->PERIndex < 3 ); ec_enc_icdf( psRangeEnc, psIndices->PERIndex, silk_LTP_per_index_iCDF, 8 ); /* Codebook Indices */ for( k = 0; k < psEncC->nb_subfr; k++ ) { silk_assert( psIndices->LTPIndex[ k ] >= 0 && psIndices->LTPIndex[ k ] < ( 8 << psIndices->PERIndex ) ); ec_enc_icdf( psRangeEnc, psIndices->LTPIndex[ k ], silk_LTP_gain_iCDF_ptrs[ psIndices->PERIndex ], 8 ); } /**********************/ /* Encode LTP scaling */ /**********************/ if( condCoding == CODE_INDEPENDENTLY ) { silk_assert( psIndices->LTP_scaleIndex >= 0 && psIndices->LTP_scaleIndex < 3 ); ec_enc_icdf( psRangeEnc, psIndices->LTP_scaleIndex, silk_LTPscale_iCDF, 8 ); } silk_assert( !condCoding || psIndices->LTP_scaleIndex == 0 ); } psEncC->ec_prevSignalType = psIndices->signalType; /***************/ /* Encode seed */ /***************/ silk_assert( psIndices->Seed >= 0 && psIndices->Seed < 4 ); ec_enc_icdf( psRangeEnc, psIndices->Seed, silk_uniform4_iCDF, 8 ); } jamulus-3.9.1+dfsg/libs/opus/silk/NLSF2A.c0000644000175000017500000001433214340334543017131 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* conversion between prediction filter coefficients and LSFs */ /* order should be even */ /* a piecewise linear approximation maps LSF <-> cos(LSF) */ /* therefore the result is not accurate LSFs, but the two */ /* functions are accurate inverses of each other */ #include "SigProc_FIX.h" #include "tables.h" #define QA 16 /* helper function for NLSF2A(..) */ static OPUS_INLINE void silk_NLSF2A_find_poly( opus_int32 *out, /* O intermediate polynomial, QA [dd+1] */ const opus_int32 *cLSF, /* I vector of interleaved 2*cos(LSFs), QA [d] */ opus_int dd /* I polynomial order (= 1/2 * filter order) */ ) { opus_int k, n; opus_int32 ftmp; out[0] = silk_LSHIFT( 1, QA ); out[1] = -cLSF[0]; for( k = 1; k < dd; k++ ) { ftmp = cLSF[2*k]; /* QA*/ out[k+1] = silk_LSHIFT( out[k-1], 1 ) - (opus_int32)silk_RSHIFT_ROUND64( silk_SMULL( ftmp, out[k] ), QA ); for( n = k; n > 1; n-- ) { out[n] += out[n-2] - (opus_int32)silk_RSHIFT_ROUND64( silk_SMULL( ftmp, out[n-1] ), QA ); } out[1] -= ftmp; } } /* compute whitening filter coefficients from normalized line spectral frequencies */ void silk_NLSF2A( opus_int16 *a_Q12, /* O monic whitening filter coefficients in Q12, [ d ] */ const opus_int16 *NLSF, /* I normalized line spectral frequencies in Q15, [ d ] */ const opus_int d, /* I filter order (should be even) */ int arch /* I Run-time architecture */ ) { /* This ordering was found to maximize quality. It improves numerical accuracy of silk_NLSF2A_find_poly() compared to "standard" ordering. */ static const unsigned char ordering16[16] = { 0, 15, 8, 7, 4, 11, 12, 3, 2, 13, 10, 5, 6, 9, 14, 1 }; static const unsigned char ordering10[10] = { 0, 9, 6, 3, 4, 5, 8, 1, 2, 7 }; const unsigned char *ordering; opus_int k, i, dd; opus_int32 cos_LSF_QA[ SILK_MAX_ORDER_LPC ]; opus_int32 P[ SILK_MAX_ORDER_LPC / 2 + 1 ], Q[ SILK_MAX_ORDER_LPC / 2 + 1 ]; opus_int32 Ptmp, Qtmp, f_int, f_frac, cos_val, delta; opus_int32 a32_QA1[ SILK_MAX_ORDER_LPC ]; silk_assert( LSF_COS_TAB_SZ_FIX == 128 ); celt_assert( d==10 || d==16 ); /* convert LSFs to 2*cos(LSF), using piecewise linear curve from table */ ordering = d == 16 ? ordering16 : ordering10; for( k = 0; k < d; k++ ) { silk_assert( NLSF[k] >= 0 ); /* f_int on a scale 0-127 (rounded down) */ f_int = silk_RSHIFT( NLSF[k], 15 - 7 ); /* f_frac, range: 0..255 */ f_frac = NLSF[k] - silk_LSHIFT( f_int, 15 - 7 ); silk_assert(f_int >= 0); silk_assert(f_int < LSF_COS_TAB_SZ_FIX ); /* Read start and end value from table */ cos_val = silk_LSFCosTab_FIX_Q12[ f_int ]; /* Q12 */ delta = silk_LSFCosTab_FIX_Q12[ f_int + 1 ] - cos_val; /* Q12, with a range of 0..200 */ /* Linear interpolation */ cos_LSF_QA[ordering[k]] = silk_RSHIFT_ROUND( silk_LSHIFT( cos_val, 8 ) + silk_MUL( delta, f_frac ), 20 - QA ); /* QA */ } dd = silk_RSHIFT( d, 1 ); /* generate even and odd polynomials using convolution */ silk_NLSF2A_find_poly( P, &cos_LSF_QA[ 0 ], dd ); silk_NLSF2A_find_poly( Q, &cos_LSF_QA[ 1 ], dd ); /* convert even and odd polynomials to opus_int32 Q12 filter coefs */ for( k = 0; k < dd; k++ ) { Ptmp = P[ k+1 ] + P[ k ]; Qtmp = Q[ k+1 ] - Q[ k ]; /* the Ptmp and Qtmp values at this stage need to fit in int32 */ a32_QA1[ k ] = -Qtmp - Ptmp; /* QA+1 */ a32_QA1[ d-k-1 ] = Qtmp - Ptmp; /* QA+1 */ } /* Convert int32 coefficients to Q12 int16 coefs */ silk_LPC_fit( a_Q12, a32_QA1, 12, QA + 1, d ); for( i = 0; silk_LPC_inverse_pred_gain( a_Q12, d, arch ) == 0 && i < MAX_LPC_STABILIZE_ITERATIONS; i++ ) { /* Prediction coefficients are (too close to) unstable; apply bandwidth expansion */ /* on the unscaled coefficients, convert to Q12 and measure again */ silk_bwexpander_32( a32_QA1, d, 65536 - silk_LSHIFT( 2, i ) ); for( k = 0; k < d; k++ ) { a_Q12[ k ] = (opus_int16)silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ); /* QA+1 -> Q12 */ } } } jamulus-3.9.1+dfsg/libs/opus/silk/LPC_inv_pred_gain.c0000644000175000017500000001402114340334543021501 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FIX.h" #include "define.h" #define QA 24 #define A_LIMIT SILK_FIX_CONST( 0.99975, QA ) #define MUL32_FRAC_Q(a32, b32, Q) ((opus_int32)(silk_RSHIFT_ROUND64(silk_SMULL(a32, b32), Q))) /* Compute inverse of LPC prediction gain, and */ /* test if LPC coefficients are stable (all poles within unit circle) */ static opus_int32 LPC_inverse_pred_gain_QA_c( /* O Returns inverse prediction gain in energy domain, Q30 */ opus_int32 A_QA[ SILK_MAX_ORDER_LPC ], /* I Prediction coefficients */ const opus_int order /* I Prediction order */ ) { opus_int k, n, mult2Q; opus_int32 invGain_Q30, rc_Q31, rc_mult1_Q30, rc_mult2, tmp1, tmp2; invGain_Q30 = SILK_FIX_CONST( 1, 30 ); for( k = order - 1; k > 0; k-- ) { /* Check for stability */ if( ( A_QA[ k ] > A_LIMIT ) || ( A_QA[ k ] < -A_LIMIT ) ) { return 0; } /* Set RC equal to negated AR coef */ rc_Q31 = -silk_LSHIFT( A_QA[ k ], 31 - QA ); /* rc_mult1_Q30 range: [ 1 : 2^30 ] */ rc_mult1_Q30 = silk_SUB32( SILK_FIX_CONST( 1, 30 ), silk_SMMUL( rc_Q31, rc_Q31 ) ); silk_assert( rc_mult1_Q30 > ( 1 << 15 ) ); /* reduce A_LIMIT if fails */ silk_assert( rc_mult1_Q30 <= ( 1 << 30 ) ); /* Update inverse gain */ /* invGain_Q30 range: [ 0 : 2^30 ] */ invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 ); silk_assert( invGain_Q30 >= 0 ); silk_assert( invGain_Q30 <= ( 1 << 30 ) ); if( invGain_Q30 < SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN, 30 ) ) { return 0; } /* rc_mult2 range: [ 2^30 : silk_int32_MAX ] */ mult2Q = 32 - silk_CLZ32( silk_abs( rc_mult1_Q30 ) ); rc_mult2 = silk_INVERSE32_varQ( rc_mult1_Q30, mult2Q + 30 ); /* Update AR coefficient */ for( n = 0; n < (k + 1) >> 1; n++ ) { opus_int64 tmp64; tmp1 = A_QA[ n ]; tmp2 = A_QA[ k - n - 1 ]; tmp64 = silk_RSHIFT_ROUND64( silk_SMULL( silk_SUB_SAT32(tmp1, MUL32_FRAC_Q( tmp2, rc_Q31, 31 ) ), rc_mult2 ), mult2Q); if( tmp64 > silk_int32_MAX || tmp64 < silk_int32_MIN ) { return 0; } A_QA[ n ] = ( opus_int32 )tmp64; tmp64 = silk_RSHIFT_ROUND64( silk_SMULL( silk_SUB_SAT32(tmp2, MUL32_FRAC_Q( tmp1, rc_Q31, 31 ) ), rc_mult2), mult2Q); if( tmp64 > silk_int32_MAX || tmp64 < silk_int32_MIN ) { return 0; } A_QA[ k - n - 1 ] = ( opus_int32 )tmp64; } } /* Check for stability */ if( ( A_QA[ k ] > A_LIMIT ) || ( A_QA[ k ] < -A_LIMIT ) ) { return 0; } /* Set RC equal to negated AR coef */ rc_Q31 = -silk_LSHIFT( A_QA[ 0 ], 31 - QA ); /* Range: [ 1 : 2^30 ] */ rc_mult1_Q30 = silk_SUB32( SILK_FIX_CONST( 1, 30 ), silk_SMMUL( rc_Q31, rc_Q31 ) ); /* Update inverse gain */ /* Range: [ 0 : 2^30 ] */ invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 ); silk_assert( invGain_Q30 >= 0 ); silk_assert( invGain_Q30 <= ( 1 << 30 ) ); if( invGain_Q30 < SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN, 30 ) ) { return 0; } return invGain_Q30; } /* For input in Q12 domain */ opus_int32 silk_LPC_inverse_pred_gain_c( /* O Returns inverse prediction gain in energy domain, Q30 */ const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */ const opus_int order /* I Prediction order */ ) { opus_int k; opus_int32 Atmp_QA[ SILK_MAX_ORDER_LPC ]; opus_int32 DC_resp = 0; /* Increase Q domain of the AR coefficients */ for( k = 0; k < order; k++ ) { DC_resp += (opus_int32)A_Q12[ k ]; Atmp_QA[ k ] = silk_LSHIFT32( (opus_int32)A_Q12[ k ], QA - 12 ); } /* If the DC is unstable, we don't even need to do the full calculations */ if( DC_resp >= 4096 ) { return 0; } return LPC_inverse_pred_gain_QA_c( Atmp_QA, order ); } jamulus-3.9.1+dfsg/libs/opus/silk/init_decoder.c0000644000175000017500000000447614340334543020644 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" /************************/ /* Init Decoder State */ /************************/ opus_int silk_init_decoder( silk_decoder_state *psDec /* I/O Decoder state pointer */ ) { /* Clear the entire encoder state, except anything copied */ silk_memset( psDec, 0, sizeof( silk_decoder_state ) ); /* Used to deactivate LSF interpolation */ psDec->first_frame_after_reset = 1; psDec->prev_gain_Q16 = 65536; psDec->arch = opus_select_arch(); /* Reset CNG state */ silk_CNG_Reset( psDec ); /* Reset PLC state */ silk_PLC_Reset( psDec ); return(0); } jamulus-3.9.1+dfsg/libs/opus/silk/encode_pulses.c0000644000175000017500000002120714340334543021033 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" #include "stack_alloc.h" /*********************************************/ /* Encode quantization indices of excitation */ /*********************************************/ static OPUS_INLINE opus_int combine_and_check( /* return ok */ opus_int *pulses_comb, /* O */ const opus_int *pulses_in, /* I */ opus_int max_pulses, /* I max value for sum of pulses */ opus_int len /* I number of output values */ ) { opus_int k, sum; for( k = 0; k < len; k++ ) { sum = pulses_in[ 2 * k ] + pulses_in[ 2 * k + 1 ]; if( sum > max_pulses ) { return 1; } pulses_comb[ k ] = sum; } return 0; } /* Encode quantization indices of excitation */ void silk_encode_pulses( ec_enc *psRangeEnc, /* I/O compressor data structure */ const opus_int signalType, /* I Signal type */ const opus_int quantOffsetType, /* I quantOffsetType */ opus_int8 pulses[], /* I quantization indices */ const opus_int frame_length /* I Frame length */ ) { opus_int i, k, j, iter, bit, nLS, scale_down, RateLevelIndex = 0; opus_int32 abs_q, minSumBits_Q5, sumBits_Q5; VARDECL( opus_int, abs_pulses ); VARDECL( opus_int, sum_pulses ); VARDECL( opus_int, nRshifts ); opus_int pulses_comb[ 8 ]; opus_int *abs_pulses_ptr; const opus_int8 *pulses_ptr; const opus_uint8 *cdf_ptr; const opus_uint8 *nBits_ptr; SAVE_STACK; silk_memset( pulses_comb, 0, 8 * sizeof( opus_int ) ); /* Fixing Valgrind reported problem*/ /****************************/ /* Prepare for shell coding */ /****************************/ /* Calculate number of shell blocks */ silk_assert( 1 << LOG2_SHELL_CODEC_FRAME_LENGTH == SHELL_CODEC_FRAME_LENGTH ); iter = silk_RSHIFT( frame_length, LOG2_SHELL_CODEC_FRAME_LENGTH ); if( iter * SHELL_CODEC_FRAME_LENGTH < frame_length ) { celt_assert( frame_length == 12 * 10 ); /* Make sure only happens for 10 ms @ 12 kHz */ iter++; silk_memset( &pulses[ frame_length ], 0, SHELL_CODEC_FRAME_LENGTH * sizeof(opus_int8)); } /* Take the absolute value of the pulses */ ALLOC( abs_pulses, iter * SHELL_CODEC_FRAME_LENGTH, opus_int ); silk_assert( !( SHELL_CODEC_FRAME_LENGTH & 3 ) ); for( i = 0; i < iter * SHELL_CODEC_FRAME_LENGTH; i+=4 ) { abs_pulses[i+0] = ( opus_int )silk_abs( pulses[ i + 0 ] ); abs_pulses[i+1] = ( opus_int )silk_abs( pulses[ i + 1 ] ); abs_pulses[i+2] = ( opus_int )silk_abs( pulses[ i + 2 ] ); abs_pulses[i+3] = ( opus_int )silk_abs( pulses[ i + 3 ] ); } /* Calc sum pulses per shell code frame */ ALLOC( sum_pulses, iter, opus_int ); ALLOC( nRshifts, iter, opus_int ); abs_pulses_ptr = abs_pulses; for( i = 0; i < iter; i++ ) { nRshifts[ i ] = 0; while( 1 ) { /* 1+1 -> 2 */ scale_down = combine_and_check( pulses_comb, abs_pulses_ptr, silk_max_pulses_table[ 0 ], 8 ); /* 2+2 -> 4 */ scale_down += combine_and_check( pulses_comb, pulses_comb, silk_max_pulses_table[ 1 ], 4 ); /* 4+4 -> 8 */ scale_down += combine_and_check( pulses_comb, pulses_comb, silk_max_pulses_table[ 2 ], 2 ); /* 8+8 -> 16 */ scale_down += combine_and_check( &sum_pulses[ i ], pulses_comb, silk_max_pulses_table[ 3 ], 1 ); if( scale_down ) { /* We need to downscale the quantization signal */ nRshifts[ i ]++; for( k = 0; k < SHELL_CODEC_FRAME_LENGTH; k++ ) { abs_pulses_ptr[ k ] = silk_RSHIFT( abs_pulses_ptr[ k ], 1 ); } } else { /* Jump out of while(1) loop and go to next shell coding frame */ break; } } abs_pulses_ptr += SHELL_CODEC_FRAME_LENGTH; } /**************/ /* Rate level */ /**************/ /* find rate level that leads to fewest bits for coding of pulses per block info */ minSumBits_Q5 = silk_int32_MAX; for( k = 0; k < N_RATE_LEVELS - 1; k++ ) { nBits_ptr = silk_pulses_per_block_BITS_Q5[ k ]; sumBits_Q5 = silk_rate_levels_BITS_Q5[ signalType >> 1 ][ k ]; for( i = 0; i < iter; i++ ) { if( nRshifts[ i ] > 0 ) { sumBits_Q5 += nBits_ptr[ SILK_MAX_PULSES + 1 ]; } else { sumBits_Q5 += nBits_ptr[ sum_pulses[ i ] ]; } } if( sumBits_Q5 < minSumBits_Q5 ) { minSumBits_Q5 = sumBits_Q5; RateLevelIndex = k; } } ec_enc_icdf( psRangeEnc, RateLevelIndex, silk_rate_levels_iCDF[ signalType >> 1 ], 8 ); /***************************************************/ /* Sum-Weighted-Pulses Encoding */ /***************************************************/ cdf_ptr = silk_pulses_per_block_iCDF[ RateLevelIndex ]; for( i = 0; i < iter; i++ ) { if( nRshifts[ i ] == 0 ) { ec_enc_icdf( psRangeEnc, sum_pulses[ i ], cdf_ptr, 8 ); } else { ec_enc_icdf( psRangeEnc, SILK_MAX_PULSES + 1, cdf_ptr, 8 ); for( k = 0; k < nRshifts[ i ] - 1; k++ ) { ec_enc_icdf( psRangeEnc, SILK_MAX_PULSES + 1, silk_pulses_per_block_iCDF[ N_RATE_LEVELS - 1 ], 8 ); } ec_enc_icdf( psRangeEnc, sum_pulses[ i ], silk_pulses_per_block_iCDF[ N_RATE_LEVELS - 1 ], 8 ); } } /******************/ /* Shell Encoding */ /******************/ for( i = 0; i < iter; i++ ) { if( sum_pulses[ i ] > 0 ) { silk_shell_encoder( psRangeEnc, &abs_pulses[ i * SHELL_CODEC_FRAME_LENGTH ] ); } } /****************/ /* LSB Encoding */ /****************/ for( i = 0; i < iter; i++ ) { if( nRshifts[ i ] > 0 ) { pulses_ptr = &pulses[ i * SHELL_CODEC_FRAME_LENGTH ]; nLS = nRshifts[ i ] - 1; for( k = 0; k < SHELL_CODEC_FRAME_LENGTH; k++ ) { abs_q = (opus_int8)silk_abs( pulses_ptr[ k ] ); for( j = nLS; j > 0; j-- ) { bit = silk_RSHIFT( abs_q, j ) & 1; ec_enc_icdf( psRangeEnc, bit, silk_lsb_iCDF, 8 ); } bit = abs_q & 1; ec_enc_icdf( psRangeEnc, bit, silk_lsb_iCDF, 8 ); } } } /****************/ /* Encode signs */ /****************/ silk_encode_signs( psRangeEnc, pulses, frame_length, signalType, quantOffsetType, sum_pulses ); RESTORE_STACK; } jamulus-3.9.1+dfsg/libs/opus/silk/PLC.h0000644000175000017500000000627514340334543016636 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SILK_PLC_H #define SILK_PLC_H #include "main.h" #define BWE_COEF 0.99 #define V_PITCH_GAIN_START_MIN_Q14 11469 /* 0.7 in Q14 */ #define V_PITCH_GAIN_START_MAX_Q14 15565 /* 0.95 in Q14 */ #define MAX_PITCH_LAG_MS 18 #define RAND_BUF_SIZE 128 #define RAND_BUF_MASK ( RAND_BUF_SIZE - 1 ) #define LOG2_INV_LPC_GAIN_HIGH_THRES 3 /* 2^3 = 8 dB LPC gain */ #define LOG2_INV_LPC_GAIN_LOW_THRES 8 /* 2^8 = 24 dB LPC gain */ #define PITCH_DRIFT_FAC_Q16 655 /* 0.01 in Q16 */ void silk_PLC_Reset( silk_decoder_state *psDec /* I/O Decoder state */ ); void silk_PLC( silk_decoder_state *psDec, /* I/O Decoder state */ silk_decoder_control *psDecCtrl, /* I/O Decoder control */ opus_int16 frame[], /* I/O signal */ opus_int lost, /* I Loss flag */ int arch /* I Run-time architecture */ ); void silk_PLC_glue_frames( silk_decoder_state *psDec, /* I/O decoder state */ opus_int16 frame[], /* I/O signal */ opus_int length /* I length of signal */ ); #endif jamulus-3.9.1+dfsg/libs/opus/silk/NLSF_encode.c0000644000175000017500000001376114340334543020270 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" #include "stack_alloc.h" /***********************/ /* NLSF vector encoder */ /***********************/ opus_int32 silk_NLSF_encode( /* O Returns RD value in Q25 */ opus_int8 *NLSFIndices, /* I Codebook path vector [ LPC_ORDER + 1 ] */ opus_int16 *pNLSF_Q15, /* I/O (Un)quantized NLSF vector [ LPC_ORDER ] */ const silk_NLSF_CB_struct *psNLSF_CB, /* I Codebook object */ const opus_int16 *pW_Q2, /* I NLSF weight vector [ LPC_ORDER ] */ const opus_int NLSF_mu_Q20, /* I Rate weight for the RD optimization */ const opus_int nSurvivors, /* I Max survivors after first stage */ const opus_int signalType /* I Signal type: 0/1/2 */ ) { opus_int i, s, ind1, bestIndex, prob_Q8, bits_q7; opus_int32 W_tmp_Q9, ret; VARDECL( opus_int32, err_Q24 ); VARDECL( opus_int32, RD_Q25 ); VARDECL( opus_int, tempIndices1 ); VARDECL( opus_int8, tempIndices2 ); opus_int16 res_Q10[ MAX_LPC_ORDER ]; opus_int16 NLSF_tmp_Q15[ MAX_LPC_ORDER ]; opus_int16 W_adj_Q5[ MAX_LPC_ORDER ]; opus_uint8 pred_Q8[ MAX_LPC_ORDER ]; opus_int16 ec_ix[ MAX_LPC_ORDER ]; const opus_uint8 *pCB_element, *iCDF_ptr; const opus_int16 *pCB_Wght_Q9; SAVE_STACK; celt_assert( signalType >= 0 && signalType <= 2 ); silk_assert( NLSF_mu_Q20 <= 32767 && NLSF_mu_Q20 >= 0 ); /* NLSF stabilization */ silk_NLSF_stabilize( pNLSF_Q15, psNLSF_CB->deltaMin_Q15, psNLSF_CB->order ); /* First stage: VQ */ ALLOC( err_Q24, psNLSF_CB->nVectors, opus_int32 ); silk_NLSF_VQ( err_Q24, pNLSF_Q15, psNLSF_CB->CB1_NLSF_Q8, psNLSF_CB->CB1_Wght_Q9, psNLSF_CB->nVectors, psNLSF_CB->order ); /* Sort the quantization errors */ ALLOC( tempIndices1, nSurvivors, opus_int ); silk_insertion_sort_increasing( err_Q24, tempIndices1, psNLSF_CB->nVectors, nSurvivors ); ALLOC( RD_Q25, nSurvivors, opus_int32 ); ALLOC( tempIndices2, nSurvivors * MAX_LPC_ORDER, opus_int8 ); /* Loop over survivors */ for( s = 0; s < nSurvivors; s++ ) { ind1 = tempIndices1[ s ]; /* Residual after first stage */ pCB_element = &psNLSF_CB->CB1_NLSF_Q8[ ind1 * psNLSF_CB->order ]; pCB_Wght_Q9 = &psNLSF_CB->CB1_Wght_Q9[ ind1 * psNLSF_CB->order ]; for( i = 0; i < psNLSF_CB->order; i++ ) { NLSF_tmp_Q15[ i ] = silk_LSHIFT16( (opus_int16)pCB_element[ i ], 7 ); W_tmp_Q9 = pCB_Wght_Q9[ i ]; res_Q10[ i ] = (opus_int16)silk_RSHIFT( silk_SMULBB( pNLSF_Q15[ i ] - NLSF_tmp_Q15[ i ], W_tmp_Q9 ), 14 ); W_adj_Q5[ i ] = silk_DIV32_varQ( (opus_int32)pW_Q2[ i ], silk_SMULBB( W_tmp_Q9, W_tmp_Q9 ), 21 ); } /* Unpack entropy table indices and predictor for current CB1 index */ silk_NLSF_unpack( ec_ix, pred_Q8, psNLSF_CB, ind1 ); /* Trellis quantizer */ RD_Q25[ s ] = silk_NLSF_del_dec_quant( &tempIndices2[ s * MAX_LPC_ORDER ], res_Q10, W_adj_Q5, pred_Q8, ec_ix, psNLSF_CB->ec_Rates_Q5, psNLSF_CB->quantStepSize_Q16, psNLSF_CB->invQuantStepSize_Q6, NLSF_mu_Q20, psNLSF_CB->order ); /* Add rate for first stage */ iCDF_ptr = &psNLSF_CB->CB1_iCDF[ ( signalType >> 1 ) * psNLSF_CB->nVectors ]; if( ind1 == 0 ) { prob_Q8 = 256 - iCDF_ptr[ ind1 ]; } else { prob_Q8 = iCDF_ptr[ ind1 - 1 ] - iCDF_ptr[ ind1 ]; } bits_q7 = ( 8 << 7 ) - silk_lin2log( prob_Q8 ); RD_Q25[ s ] = silk_SMLABB( RD_Q25[ s ], bits_q7, silk_RSHIFT( NLSF_mu_Q20, 2 ) ); } /* Find the lowest rate-distortion error */ silk_insertion_sort_increasing( RD_Q25, &bestIndex, nSurvivors, 1 ); NLSFIndices[ 0 ] = (opus_int8)tempIndices1[ bestIndex ]; silk_memcpy( &NLSFIndices[ 1 ], &tempIndices2[ bestIndex * MAX_LPC_ORDER ], psNLSF_CB->order * sizeof( opus_int8 ) ); /* Decode */ silk_NLSF_decode( pNLSF_Q15, NLSFIndices, psNLSF_CB ); ret = RD_Q25[ 0 ]; RESTORE_STACK; return ret; } jamulus-3.9.1+dfsg/libs/opus/silk/control.h0000644000175000017500000001402514340334543017670 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SILK_CONTROL_H #define SILK_CONTROL_H #include "typedef.h" #ifdef __cplusplus extern "C" { #endif /* Decoder API flags */ #define FLAG_DECODE_NORMAL 0 #define FLAG_PACKET_LOST 1 #define FLAG_DECODE_LBRR 2 /***********************************************/ /* Structure for controlling encoder operation */ /***********************************************/ typedef struct { /* I: Number of channels; 1/2 */ opus_int32 nChannelsAPI; /* I: Number of channels; 1/2 */ opus_int32 nChannelsInternal; /* I: Input signal sampling rate in Hertz; 8000/12000/16000/24000/32000/44100/48000 */ opus_int32 API_sampleRate; /* I: Maximum internal sampling rate in Hertz; 8000/12000/16000 */ opus_int32 maxInternalSampleRate; /* I: Minimum internal sampling rate in Hertz; 8000/12000/16000 */ opus_int32 minInternalSampleRate; /* I: Soft request for internal sampling rate in Hertz; 8000/12000/16000 */ opus_int32 desiredInternalSampleRate; /* I: Number of samples per packet in milliseconds; 10/20/40/60 */ opus_int payloadSize_ms; /* I: Bitrate during active speech in bits/second; internally limited */ opus_int32 bitRate; /* I: Uplink packet loss in percent (0-100) */ opus_int packetLossPercentage; /* I: Complexity mode; 0 is lowest, 10 is highest complexity */ opus_int complexity; /* I: Flag to enable in-band Forward Error Correction (FEC); 0/1 */ opus_int useInBandFEC; /* I: Flag to actually code in-band Forward Error Correction (FEC) in the current packet; 0/1 */ opus_int LBRR_coded; /* I: Flag to enable discontinuous transmission (DTX); 0/1 */ opus_int useDTX; /* I: Flag to use constant bitrate */ opus_int useCBR; /* I: Maximum number of bits allowed for the frame */ opus_int maxBits; /* I: Causes a smooth downmix to mono */ opus_int toMono; /* I: Opus encoder is allowing us to switch bandwidth */ opus_int opusCanSwitch; /* I: Make frames as independent as possible (but still use LPC) */ opus_int reducedDependency; /* O: Internal sampling rate used, in Hertz; 8000/12000/16000 */ opus_int32 internalSampleRate; /* O: Flag that bandwidth switching is allowed (because low voice activity) */ opus_int allowBandwidthSwitch; /* O: Flag that SILK runs in WB mode without variable LP filter (use for switching between WB/SWB/FB) */ opus_int inWBmodeWithoutVariableLP; /* O: Stereo width */ opus_int stereoWidth_Q14; /* O: Tells the Opus encoder we're ready to switch */ opus_int switchReady; /* O: SILK Signal type */ opus_int signalType; /* O: SILK offset (dithering) */ opus_int offset; } silk_EncControlStruct; /**************************************************************************/ /* Structure for controlling decoder operation and reading decoder status */ /**************************************************************************/ typedef struct { /* I: Number of channels; 1/2 */ opus_int32 nChannelsAPI; /* I: Number of channels; 1/2 */ opus_int32 nChannelsInternal; /* I: Output signal sampling rate in Hertz; 8000/12000/16000/24000/32000/44100/48000 */ opus_int32 API_sampleRate; /* I: Internal sampling rate used, in Hertz; 8000/12000/16000 */ opus_int32 internalSampleRate; /* I: Number of samples per packet in milliseconds; 10/20/40/60 */ opus_int payloadSize_ms; /* O: Pitch lag of previous frame (0 if unvoiced), measured in samples at 48 kHz */ opus_int prevPitchLag; } silk_DecControlStruct; #ifdef __cplusplus } #endif #endif jamulus-3.9.1+dfsg/libs/opus/silk/stereo_decode_pred.c0000644000175000017500000000653114340334543022024 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" /* Decode mid/side predictors */ void silk_stereo_decode_pred( ec_dec *psRangeDec, /* I/O Compressor data structure */ opus_int32 pred_Q13[] /* O Predictors */ ) { opus_int n, ix[ 2 ][ 3 ]; opus_int32 low_Q13, step_Q13; /* Entropy decoding */ n = ec_dec_icdf( psRangeDec, silk_stereo_pred_joint_iCDF, 8 ); ix[ 0 ][ 2 ] = silk_DIV32_16( n, 5 ); ix[ 1 ][ 2 ] = n - 5 * ix[ 0 ][ 2 ]; for( n = 0; n < 2; n++ ) { ix[ n ][ 0 ] = ec_dec_icdf( psRangeDec, silk_uniform3_iCDF, 8 ); ix[ n ][ 1 ] = ec_dec_icdf( psRangeDec, silk_uniform5_iCDF, 8 ); } /* Dequantize */ for( n = 0; n < 2; n++ ) { ix[ n ][ 0 ] += 3 * ix[ n ][ 2 ]; low_Q13 = silk_stereo_pred_quant_Q13[ ix[ n ][ 0 ] ]; step_Q13 = silk_SMULWB( silk_stereo_pred_quant_Q13[ ix[ n ][ 0 ] + 1 ] - low_Q13, SILK_FIX_CONST( 0.5 / STEREO_QUANT_SUB_STEPS, 16 ) ); pred_Q13[ n ] = silk_SMLABB( low_Q13, step_Q13, 2 * ix[ n ][ 1 ] + 1 ); } /* Subtract second from first predictor (helps when actually applying these) */ pred_Q13[ 0 ] -= pred_Q13[ 1 ]; } /* Decode mid-only flag */ void silk_stereo_decode_mid_only( ec_dec *psRangeDec, /* I/O Compressor data structure */ opus_int *decode_only_mid /* O Flag that only mid channel has been coded */ ) { /* Decode flag that only mid channel is coded */ *decode_only_mid = ec_dec_icdf( psRangeDec, silk_stereo_only_code_mid_iCDF, 8 ); } jamulus-3.9.1+dfsg/libs/opus/silk/inner_prod_aligned.c0000644000175000017500000000462314340334543022030 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FIX.h" opus_int32 silk_inner_prod_aligned_scale( const opus_int16 *const inVec1, /* I input vector 1 */ const opus_int16 *const inVec2, /* I input vector 2 */ const opus_int scale, /* I number of bits to shift */ const opus_int len /* I vector lengths */ ) { opus_int i; opus_int32 sum = 0; for( i = 0; i < len; i++ ) { sum = silk_ADD_RSHIFT32( sum, silk_SMULBB( inVec1[ i ], inVec2[ i ] ), scale ); } return sum; } jamulus-3.9.1+dfsg/libs/opus/silk/resampler.c0000644000175000017500000002331314340334543020175 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* * Matrix of resampling methods used: * Fs_out (kHz) * 8 12 16 24 48 * * 8 C UF U UF UF * 12 AF C UF U UF * Fs_in (kHz) 16 D AF C UF UF * 24 AF D AF C U * 48 AF AF AF D C * * C -> Copy (no resampling) * D -> Allpass-based 2x downsampling * U -> Allpass-based 2x upsampling * UF -> Allpass-based 2x upsampling followed by FIR interpolation * AF -> AR2 filter followed by FIR interpolation */ #include "resampler_private.h" /* Tables with delay compensation values to equalize total delay for different modes */ static const opus_int8 delay_matrix_enc[ 5 ][ 3 ] = { /* in \ out 8 12 16 */ /* 8 */ { 6, 0, 3 }, /* 12 */ { 0, 7, 3 }, /* 16 */ { 0, 1, 10 }, /* 24 */ { 0, 2, 6 }, /* 48 */ { 18, 10, 12 } }; static const opus_int8 delay_matrix_dec[ 3 ][ 5 ] = { /* in \ out 8 12 16 24 48 */ /* 8 */ { 4, 0, 2, 0, 0 }, /* 12 */ { 0, 9, 4, 7, 4 }, /* 16 */ { 0, 3, 12, 7, 7 } }; /* Simple way to make [8000, 12000, 16000, 24000, 48000] to [0, 1, 2, 3, 4] */ #define rateID(R) ( ( ( ((R)>>12) - ((R)>16000) ) >> ((R)>24000) ) - 1 ) #define USE_silk_resampler_copy (0) #define USE_silk_resampler_private_up2_HQ_wrapper (1) #define USE_silk_resampler_private_IIR_FIR (2) #define USE_silk_resampler_private_down_FIR (3) /* Initialize/reset the resampler state for a given pair of input/output sampling rates */ opus_int silk_resampler_init( silk_resampler_state_struct *S, /* I/O Resampler state */ opus_int32 Fs_Hz_in, /* I Input sampling rate (Hz) */ opus_int32 Fs_Hz_out, /* I Output sampling rate (Hz) */ opus_int forEnc /* I If 1: encoder; if 0: decoder */ ) { opus_int up2x; /* Clear state */ silk_memset( S, 0, sizeof( silk_resampler_state_struct ) ); /* Input checking */ if( forEnc ) { if( ( Fs_Hz_in != 8000 && Fs_Hz_in != 12000 && Fs_Hz_in != 16000 && Fs_Hz_in != 24000 && Fs_Hz_in != 48000 ) || ( Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000 ) ) { celt_assert( 0 ); return -1; } S->inputDelay = delay_matrix_enc[ rateID( Fs_Hz_in ) ][ rateID( Fs_Hz_out ) ]; } else { if( ( Fs_Hz_in != 8000 && Fs_Hz_in != 12000 && Fs_Hz_in != 16000 ) || ( Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000 && Fs_Hz_out != 24000 && Fs_Hz_out != 48000 ) ) { celt_assert( 0 ); return -1; } S->inputDelay = delay_matrix_dec[ rateID( Fs_Hz_in ) ][ rateID( Fs_Hz_out ) ]; } S->Fs_in_kHz = silk_DIV32_16( Fs_Hz_in, 1000 ); S->Fs_out_kHz = silk_DIV32_16( Fs_Hz_out, 1000 ); /* Number of samples processed per batch */ S->batchSize = S->Fs_in_kHz * RESAMPLER_MAX_BATCH_SIZE_MS; /* Find resampler with the right sampling ratio */ up2x = 0; if( Fs_Hz_out > Fs_Hz_in ) { /* Upsample */ if( Fs_Hz_out == silk_MUL( Fs_Hz_in, 2 ) ) { /* Fs_out : Fs_in = 2 : 1 */ /* Special case: directly use 2x upsampler */ S->resampler_function = USE_silk_resampler_private_up2_HQ_wrapper; } else { /* Default resampler */ S->resampler_function = USE_silk_resampler_private_IIR_FIR; up2x = 1; } } else if ( Fs_Hz_out < Fs_Hz_in ) { /* Downsample */ S->resampler_function = USE_silk_resampler_private_down_FIR; if( silk_MUL( Fs_Hz_out, 4 ) == silk_MUL( Fs_Hz_in, 3 ) ) { /* Fs_out : Fs_in = 3 : 4 */ S->FIR_Fracs = 3; S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR0; S->Coefs = silk_Resampler_3_4_COEFS; } else if( silk_MUL( Fs_Hz_out, 3 ) == silk_MUL( Fs_Hz_in, 2 ) ) { /* Fs_out : Fs_in = 2 : 3 */ S->FIR_Fracs = 2; S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR0; S->Coefs = silk_Resampler_2_3_COEFS; } else if( silk_MUL( Fs_Hz_out, 2 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 2 */ S->FIR_Fracs = 1; S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR1; S->Coefs = silk_Resampler_1_2_COEFS; } else if( silk_MUL( Fs_Hz_out, 3 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 3 */ S->FIR_Fracs = 1; S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR2; S->Coefs = silk_Resampler_1_3_COEFS; } else if( silk_MUL( Fs_Hz_out, 4 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 4 */ S->FIR_Fracs = 1; S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR2; S->Coefs = silk_Resampler_1_4_COEFS; } else if( silk_MUL( Fs_Hz_out, 6 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 6 */ S->FIR_Fracs = 1; S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR2; S->Coefs = silk_Resampler_1_6_COEFS; } else { /* None available */ celt_assert( 0 ); return -1; } } else { /* Input and output sampling rates are equal: copy */ S->resampler_function = USE_silk_resampler_copy; } /* Ratio of input/output samples */ S->invRatio_Q16 = silk_LSHIFT32( silk_DIV32( silk_LSHIFT32( Fs_Hz_in, 14 + up2x ), Fs_Hz_out ), 2 ); /* Make sure the ratio is rounded up */ while( silk_SMULWW( S->invRatio_Q16, Fs_Hz_out ) < silk_LSHIFT32( Fs_Hz_in, up2x ) ) { S->invRatio_Q16++; } return 0; } /* Resampler: convert from one sampling rate to another */ /* Input and output sampling rate are at most 48000 Hz */ opus_int silk_resampler( silk_resampler_state_struct *S, /* I/O Resampler state */ opus_int16 out[], /* O Output signal */ const opus_int16 in[], /* I Input signal */ opus_int32 inLen /* I Number of input samples */ ) { opus_int nSamples; /* Need at least 1 ms of input data */ celt_assert( inLen >= S->Fs_in_kHz ); /* Delay can't exceed the 1 ms of buffering */ celt_assert( S->inputDelay <= S->Fs_in_kHz ); nSamples = S->Fs_in_kHz - S->inputDelay; /* Copy to delay buffer */ silk_memcpy( &S->delayBuf[ S->inputDelay ], in, nSamples * sizeof( opus_int16 ) ); switch( S->resampler_function ) { case USE_silk_resampler_private_up2_HQ_wrapper: silk_resampler_private_up2_HQ_wrapper( S, out, S->delayBuf, S->Fs_in_kHz ); silk_resampler_private_up2_HQ_wrapper( S, &out[ S->Fs_out_kHz ], &in[ nSamples ], inLen - S->Fs_in_kHz ); break; case USE_silk_resampler_private_IIR_FIR: silk_resampler_private_IIR_FIR( S, out, S->delayBuf, S->Fs_in_kHz ); silk_resampler_private_IIR_FIR( S, &out[ S->Fs_out_kHz ], &in[ nSamples ], inLen - S->Fs_in_kHz ); break; case USE_silk_resampler_private_down_FIR: silk_resampler_private_down_FIR( S, out, S->delayBuf, S->Fs_in_kHz ); silk_resampler_private_down_FIR( S, &out[ S->Fs_out_kHz ], &in[ nSamples ], inLen - S->Fs_in_kHz ); break; default: silk_memcpy( out, S->delayBuf, S->Fs_in_kHz * sizeof( opus_int16 ) ); silk_memcpy( &out[ S->Fs_out_kHz ], &in[ nSamples ], ( inLen - S->Fs_in_kHz ) * sizeof( opus_int16 ) ); } /* Copy to delay buffer */ silk_memcpy( S->delayBuf, &in[ inLen - S->inputDelay ], S->inputDelay * sizeof( opus_int16 ) ); return 0; } jamulus-3.9.1+dfsg/libs/opus/silk/stereo_quant_pred.c0000644000175000017500000000651414340334543021732 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" /* Quantize mid/side predictors */ void silk_stereo_quant_pred( opus_int32 pred_Q13[], /* I/O Predictors (out: quantized) */ opus_int8 ix[ 2 ][ 3 ] /* O Quantization indices */ ) { opus_int i, j, n; opus_int32 low_Q13, step_Q13, lvl_Q13, err_min_Q13, err_Q13, quant_pred_Q13 = 0; /* Quantize */ for( n = 0; n < 2; n++ ) { /* Brute-force search over quantization levels */ err_min_Q13 = silk_int32_MAX; for( i = 0; i < STEREO_QUANT_TAB_SIZE - 1; i++ ) { low_Q13 = silk_stereo_pred_quant_Q13[ i ]; step_Q13 = silk_SMULWB( silk_stereo_pred_quant_Q13[ i + 1 ] - low_Q13, SILK_FIX_CONST( 0.5 / STEREO_QUANT_SUB_STEPS, 16 ) ); for( j = 0; j < STEREO_QUANT_SUB_STEPS; j++ ) { lvl_Q13 = silk_SMLABB( low_Q13, step_Q13, 2 * j + 1 ); err_Q13 = silk_abs( pred_Q13[ n ] - lvl_Q13 ); if( err_Q13 < err_min_Q13 ) { err_min_Q13 = err_Q13; quant_pred_Q13 = lvl_Q13; ix[ n ][ 0 ] = i; ix[ n ][ 1 ] = j; } else { /* Error increasing, so we're past the optimum */ goto done; } } } done: ix[ n ][ 2 ] = silk_DIV32_16( ix[ n ][ 0 ], 3 ); ix[ n ][ 0 ] -= ix[ n ][ 2 ] * 3; pred_Q13[ n ] = quant_pred_Q13; } /* Subtract second from first predictor (helps when actually applying these) */ pred_Q13[ 0 ] -= pred_Q13[ 1 ]; } jamulus-3.9.1+dfsg/libs/opus/silk/main.h0000644000175000017500000007765014340334543017151 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SILK_MAIN_H #define SILK_MAIN_H #include "SigProc_FIX.h" #include "define.h" #include "structs.h" #include "tables.h" #include "PLC.h" #include "control.h" #include "debug.h" #include "entenc.h" #include "entdec.h" #if defined(OPUS_X86_MAY_HAVE_SSE4_1) #include "x86/main_sse.h" #endif #if (defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)) #include "arm/NSQ_del_dec_arm.h" #endif /* Convert Left/Right stereo signal to adaptive Mid/Side representation */ void silk_stereo_LR_to_MS( stereo_enc_state *state, /* I/O State */ opus_int16 x1[], /* I/O Left input signal, becomes mid signal */ opus_int16 x2[], /* I/O Right input signal, becomes side signal */ opus_int8 ix[ 2 ][ 3 ], /* O Quantization indices */ opus_int8 *mid_only_flag, /* O Flag: only mid signal coded */ opus_int32 mid_side_rates_bps[], /* O Bitrates for mid and side signals */ opus_int32 total_rate_bps, /* I Total bitrate */ opus_int prev_speech_act_Q8, /* I Speech activity level in previous frame */ opus_int toMono, /* I Last frame before a stereo->mono transition */ opus_int fs_kHz, /* I Sample rate (kHz) */ opus_int frame_length /* I Number of samples */ ); /* Convert adaptive Mid/Side representation to Left/Right stereo signal */ void silk_stereo_MS_to_LR( stereo_dec_state *state, /* I/O State */ opus_int16 x1[], /* I/O Left input signal, becomes mid signal */ opus_int16 x2[], /* I/O Right input signal, becomes side signal */ const opus_int32 pred_Q13[], /* I Predictors */ opus_int fs_kHz, /* I Samples rate (kHz) */ opus_int frame_length /* I Number of samples */ ); /* Find least-squares prediction gain for one signal based on another and quantize it */ opus_int32 silk_stereo_find_predictor( /* O Returns predictor in Q13 */ opus_int32 *ratio_Q14, /* O Ratio of residual and mid energies */ const opus_int16 x[], /* I Basis signal */ const opus_int16 y[], /* I Target signal */ opus_int32 mid_res_amp_Q0[], /* I/O Smoothed mid, residual norms */ opus_int length, /* I Number of samples */ opus_int smooth_coef_Q16 /* I Smoothing coefficient */ ); /* Quantize mid/side predictors */ void silk_stereo_quant_pred( opus_int32 pred_Q13[], /* I/O Predictors (out: quantized) */ opus_int8 ix[ 2 ][ 3 ] /* O Quantization indices */ ); /* Entropy code the mid/side quantization indices */ void silk_stereo_encode_pred( ec_enc *psRangeEnc, /* I/O Compressor data structure */ opus_int8 ix[ 2 ][ 3 ] /* I Quantization indices */ ); /* Entropy code the mid-only flag */ void silk_stereo_encode_mid_only( ec_enc *psRangeEnc, /* I/O Compressor data structure */ opus_int8 mid_only_flag ); /* Decode mid/side predictors */ void silk_stereo_decode_pred( ec_dec *psRangeDec, /* I/O Compressor data structure */ opus_int32 pred_Q13[] /* O Predictors */ ); /* Decode mid-only flag */ void silk_stereo_decode_mid_only( ec_dec *psRangeDec, /* I/O Compressor data structure */ opus_int *decode_only_mid /* O Flag that only mid channel has been coded */ ); /* Encodes signs of excitation */ void silk_encode_signs( ec_enc *psRangeEnc, /* I/O Compressor data structure */ const opus_int8 pulses[], /* I pulse signal */ opus_int length, /* I length of input */ const opus_int signalType, /* I Signal type */ const opus_int quantOffsetType, /* I Quantization offset type */ const opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ] /* I Sum of absolute pulses per block */ ); /* Decodes signs of excitation */ void silk_decode_signs( ec_dec *psRangeDec, /* I/O Compressor data structure */ opus_int16 pulses[], /* I/O pulse signal */ opus_int length, /* I length of input */ const opus_int signalType, /* I Signal type */ const opus_int quantOffsetType, /* I Quantization offset type */ const opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ] /* I Sum of absolute pulses per block */ ); /* Check encoder control struct */ opus_int check_control_input( silk_EncControlStruct *encControl /* I Control structure */ ); /* Control internal sampling rate */ opus_int silk_control_audio_bandwidth( silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */ silk_EncControlStruct *encControl /* I Control structure */ ); /* Control SNR of residual quantizer */ opus_int silk_control_SNR( silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */ opus_int32 TargetRate_bps /* I Target max bitrate (bps) */ ); /***************/ /* Shell coder */ /***************/ /* Encode quantization indices of excitation */ void silk_encode_pulses( ec_enc *psRangeEnc, /* I/O compressor data structure */ const opus_int signalType, /* I Signal type */ const opus_int quantOffsetType, /* I quantOffsetType */ opus_int8 pulses[], /* I quantization indices */ const opus_int frame_length /* I Frame length */ ); /* Shell encoder, operates on one shell code frame of 16 pulses */ void silk_shell_encoder( ec_enc *psRangeEnc, /* I/O compressor data structure */ const opus_int *pulses0 /* I data: nonnegative pulse amplitudes */ ); /* Shell decoder, operates on one shell code frame of 16 pulses */ void silk_shell_decoder( opus_int16 *pulses0, /* O data: nonnegative pulse amplitudes */ ec_dec *psRangeDec, /* I/O Compressor data structure */ const opus_int pulses4 /* I number of pulses per pulse-subframe */ ); /* Gain scalar quantization with hysteresis, uniform on log scale */ void silk_gains_quant( opus_int8 ind[ MAX_NB_SUBFR ], /* O gain indices */ opus_int32 gain_Q16[ MAX_NB_SUBFR ], /* I/O gains (quantized out) */ opus_int8 *prev_ind, /* I/O last index in previous frame */ const opus_int conditional, /* I first gain is delta coded if 1 */ const opus_int nb_subfr /* I number of subframes */ ); /* Gains scalar dequantization, uniform on log scale */ void silk_gains_dequant( opus_int32 gain_Q16[ MAX_NB_SUBFR ], /* O quantized gains */ const opus_int8 ind[ MAX_NB_SUBFR ], /* I gain indices */ opus_int8 *prev_ind, /* I/O last index in previous frame */ const opus_int conditional, /* I first gain is delta coded if 1 */ const opus_int nb_subfr /* I number of subframes */ ); /* Compute unique identifier of gain indices vector */ opus_int32 silk_gains_ID( /* O returns unique identifier of gains */ const opus_int8 ind[ MAX_NB_SUBFR ], /* I gain indices */ const opus_int nb_subfr /* I number of subframes */ ); /* Interpolate two vectors */ void silk_interpolate( opus_int16 xi[ MAX_LPC_ORDER ], /* O interpolated vector */ const opus_int16 x0[ MAX_LPC_ORDER ], /* I first vector */ const opus_int16 x1[ MAX_LPC_ORDER ], /* I second vector */ const opus_int ifact_Q2, /* I interp. factor, weight on 2nd vector */ const opus_int d /* I number of parameters */ ); /* LTP tap quantizer */ void silk_quant_LTP_gains( opus_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ], /* O Quantized LTP gains */ opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook Index */ opus_int8 *periodicity_index, /* O Periodicity Index */ opus_int32 *sum_gain_dB_Q7, /* I/O Cumulative max prediction gain */ opus_int *pred_gain_dB_Q7, /* O LTP prediction gain */ const opus_int32 XX_Q17[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ], /* I Correlation matrix in Q18 */ const opus_int32 xX_Q17[ MAX_NB_SUBFR*LTP_ORDER ], /* I Correlation vector in Q18 */ const opus_int subfr_len, /* I Number of samples per subframe */ const opus_int nb_subfr, /* I Number of subframes */ int arch /* I Run-time architecture */ ); /* Entropy constrained matrix-weighted VQ, for a single input data vector */ void silk_VQ_WMat_EC_c( opus_int8 *ind, /* O index of best codebook vector */ opus_int32 *res_nrg_Q15, /* O best residual energy */ opus_int32 *rate_dist_Q8, /* O best total bitrate */ opus_int *gain_Q7, /* O sum of absolute LTP coefficients */ const opus_int32 *XX_Q17, /* I correlation matrix */ const opus_int32 *xX_Q17, /* I correlation vector */ const opus_int8 *cb_Q7, /* I codebook */ const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */ const opus_uint8 *cl_Q5, /* I code length for each codebook vector */ const opus_int subfr_len, /* I number of samples per subframe */ const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */ const opus_int L /* I number of vectors in codebook */ ); #if !defined(OVERRIDE_silk_VQ_WMat_EC) #define silk_VQ_WMat_EC(ind, res_nrg_Q15, rate_dist_Q8, gain_Q7, XX_Q17, xX_Q17, cb_Q7, cb_gain_Q7, cl_Q5, subfr_len, max_gain_Q7, L, arch) \ ((void)(arch),silk_VQ_WMat_EC_c(ind, res_nrg_Q15, rate_dist_Q8, gain_Q7, XX_Q17, xX_Q17, cb_Q7, cb_gain_Q7, cl_Q5, subfr_len, max_gain_Q7, L)) #endif /************************************/ /* Noise shaping quantization (NSQ) */ /************************************/ void silk_NSQ_c( const silk_encoder_state *psEncC, /* I Encoder State */ silk_nsq_state *NSQ, /* I/O NSQ state */ SideInfoIndices *psIndices, /* I/O Quantization Indices */ const opus_int16 x16[], /* I Input */ opus_int8 pulses[], /* O Quantized pulse signal */ const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ const opus_int LTP_scale_Q14 /* I LTP state scaling */ ); #if !defined(OVERRIDE_silk_NSQ) #define silk_NSQ(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, \ HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \ ((void)(arch),silk_NSQ_c(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, \ HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14)) #endif /* Noise shaping using delayed decision */ void silk_NSQ_del_dec_c( const silk_encoder_state *psEncC, /* I Encoder State */ silk_nsq_state *NSQ, /* I/O NSQ state */ SideInfoIndices *psIndices, /* I/O Quantization Indices */ const opus_int16 x16[], /* I Input */ opus_int8 pulses[], /* O Quantized pulse signal */ const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ const opus_int LTP_scale_Q14 /* I LTP state scaling */ ); #if !defined(OVERRIDE_silk_NSQ_del_dec) #define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, \ HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \ ((void)(arch),silk_NSQ_del_dec_c(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, \ HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14)) #endif /************/ /* Silk VAD */ /************/ /* Initialize the Silk VAD */ opus_int silk_VAD_Init( /* O Return value, 0 if success */ silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */ ); /* Get speech activity level in Q8 */ opus_int silk_VAD_GetSA_Q8_c( /* O Return value, 0 if success */ silk_encoder_state *psEncC, /* I/O Encoder state */ const opus_int16 pIn[] /* I PCM input */ ); #if !defined(OVERRIDE_silk_VAD_GetSA_Q8) #define silk_VAD_GetSA_Q8(psEnC, pIn, arch) ((void)(arch),silk_VAD_GetSA_Q8_c(psEnC, pIn)) #endif /* Low-pass filter with variable cutoff frequency based on */ /* piece-wise linear interpolation between elliptic filters */ /* Start by setting transition_frame_no = 1; */ void silk_LP_variable_cutoff( silk_LP_state *psLP, /* I/O LP filter state */ opus_int16 *frame, /* I/O Low-pass filtered output signal */ const opus_int frame_length /* I Frame length */ ); /******************/ /* NLSF Quantizer */ /******************/ /* Limit, stabilize, convert and quantize NLSFs */ void silk_process_NLSFs( silk_encoder_state *psEncC, /* I/O Encoder state */ opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ], /* O Prediction coefficients */ opus_int16 pNLSF_Q15[ MAX_LPC_ORDER ], /* I/O Normalized LSFs (quant out) (0 - (2^15-1)) */ const opus_int16 prev_NLSFq_Q15[ MAX_LPC_ORDER ] /* I Previous Normalized LSFs (0 - (2^15-1)) */ ); opus_int32 silk_NLSF_encode( /* O Returns RD value in Q25 */ opus_int8 *NLSFIndices, /* I Codebook path vector [ LPC_ORDER + 1 ] */ opus_int16 *pNLSF_Q15, /* I/O Quantized NLSF vector [ LPC_ORDER ] */ const silk_NLSF_CB_struct *psNLSF_CB, /* I Codebook object */ const opus_int16 *pW_QW, /* I NLSF weight vector [ LPC_ORDER ] */ const opus_int NLSF_mu_Q20, /* I Rate weight for the RD optimization */ const opus_int nSurvivors, /* I Max survivors after first stage */ const opus_int signalType /* I Signal type: 0/1/2 */ ); /* Compute quantization errors for an LPC_order element input vector for a VQ codebook */ void silk_NLSF_VQ( opus_int32 err_Q26[], /* O Quantization errors [K] */ const opus_int16 in_Q15[], /* I Input vectors to be quantized [LPC_order] */ const opus_uint8 pCB_Q8[], /* I Codebook vectors [K*LPC_order] */ const opus_int16 pWght_Q9[], /* I Codebook weights [K*LPC_order] */ const opus_int K, /* I Number of codebook vectors */ const opus_int LPC_order /* I Number of LPCs */ ); /* Delayed-decision quantizer for NLSF residuals */ opus_int32 silk_NLSF_del_dec_quant( /* O Returns RD value in Q25 */ opus_int8 indices[], /* O Quantization indices [ order ] */ const opus_int16 x_Q10[], /* I Input [ order ] */ const opus_int16 w_Q5[], /* I Weights [ order ] */ const opus_uint8 pred_coef_Q8[], /* I Backward predictor coefs [ order ] */ const opus_int16 ec_ix[], /* I Indices to entropy coding tables [ order ] */ const opus_uint8 ec_rates_Q5[], /* I Rates [] */ const opus_int quant_step_size_Q16, /* I Quantization step size */ const opus_int16 inv_quant_step_size_Q6, /* I Inverse quantization step size */ const opus_int32 mu_Q20, /* I R/D tradeoff */ const opus_int16 order /* I Number of input values */ ); /* Unpack predictor values and indices for entropy coding tables */ void silk_NLSF_unpack( opus_int16 ec_ix[], /* O Indices to entropy tables [ LPC_ORDER ] */ opus_uint8 pred_Q8[], /* O LSF predictor [ LPC_ORDER ] */ const silk_NLSF_CB_struct *psNLSF_CB, /* I Codebook object */ const opus_int CB1_index /* I Index of vector in first LSF codebook */ ); /***********************/ /* NLSF vector decoder */ /***********************/ void silk_NLSF_decode( opus_int16 *pNLSF_Q15, /* O Quantized NLSF vector [ LPC_ORDER ] */ opus_int8 *NLSFIndices, /* I Codebook path vector [ LPC_ORDER + 1 ] */ const silk_NLSF_CB_struct *psNLSF_CB /* I Codebook object */ ); /****************************************************/ /* Decoder Functions */ /****************************************************/ opus_int silk_init_decoder( silk_decoder_state *psDec /* I/O Decoder state pointer */ ); /* Set decoder sampling rate */ opus_int silk_decoder_set_fs( silk_decoder_state *psDec, /* I/O Decoder state pointer */ opus_int fs_kHz, /* I Sampling frequency (kHz) */ opus_int32 fs_API_Hz /* I API Sampling frequency (Hz) */ ); /****************/ /* Decode frame */ /****************/ opus_int silk_decode_frame( silk_decoder_state *psDec, /* I/O Pointer to Silk decoder state */ ec_dec *psRangeDec, /* I/O Compressor data structure */ opus_int16 pOut[], /* O Pointer to output speech frame */ opus_int32 *pN, /* O Pointer to size of output frame */ opus_int lostFlag, /* I 0: no loss, 1 loss, 2 decode fec */ opus_int condCoding, /* I The type of conditional coding to use */ int arch /* I Run-time architecture */ ); /* Decode indices from bitstream */ void silk_decode_indices( silk_decoder_state *psDec, /* I/O State */ ec_dec *psRangeDec, /* I/O Compressor data structure */ opus_int FrameIndex, /* I Frame number */ opus_int decode_LBRR, /* I Flag indicating LBRR data is being decoded */ opus_int condCoding /* I The type of conditional coding to use */ ); /* Decode parameters from payload */ void silk_decode_parameters( silk_decoder_state *psDec, /* I/O State */ silk_decoder_control *psDecCtrl, /* I/O Decoder control */ opus_int condCoding /* I The type of conditional coding to use */ ); /* Core decoder. Performs inverse NSQ operation LTP + LPC */ void silk_decode_core( silk_decoder_state *psDec, /* I/O Decoder state */ silk_decoder_control *psDecCtrl, /* I Decoder control */ opus_int16 xq[], /* O Decoded speech */ const opus_int16 pulses[ MAX_FRAME_LENGTH ], /* I Pulse signal */ int arch /* I Run-time architecture */ ); /* Decode quantization indices of excitation (Shell coding) */ void silk_decode_pulses( ec_dec *psRangeDec, /* I/O Compressor data structure */ opus_int16 pulses[], /* O Excitation signal */ const opus_int signalType, /* I Sigtype */ const opus_int quantOffsetType, /* I quantOffsetType */ const opus_int frame_length /* I Frame length */ ); /******************/ /* CNG */ /******************/ /* Reset CNG */ void silk_CNG_Reset( silk_decoder_state *psDec /* I/O Decoder state */ ); /* Updates CNG estimate, and applies the CNG when packet was lost */ void silk_CNG( silk_decoder_state *psDec, /* I/O Decoder state */ silk_decoder_control *psDecCtrl, /* I/O Decoder control */ opus_int16 frame[], /* I/O Signal */ opus_int length /* I Length of residual */ ); /* Encoding of various parameters */ void silk_encode_indices( silk_encoder_state *psEncC, /* I/O Encoder state */ ec_enc *psRangeEnc, /* I/O Compressor data structure */ opus_int FrameIndex, /* I Frame number */ opus_int encode_LBRR, /* I Flag indicating LBRR data is being encoded */ opus_int condCoding /* I The type of conditional coding to use */ ); #endif jamulus-3.9.1+dfsg/libs/opus/silk/debug.h0000644000175000017500000003124014340334543017274 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SILK_DEBUG_H #define SILK_DEBUG_H #include "typedef.h" #include /* file writing */ #include /* strcpy, strcmp */ #ifdef __cplusplus extern "C" { #endif unsigned long GetHighResolutionTime(void); /* O time in usec*/ /* Set to 1 to enable DEBUG_STORE_DATA() macros for dumping * intermediate signals from the codec. */ #define SILK_DEBUG 0 /* Flag for using timers */ #define SILK_TIC_TOC 0 #if SILK_TIC_TOC #if (defined(_WIN32) || defined(_WINCE)) #include /* timer */ #else /* Linux or Mac*/ #include #endif /*********************************/ /* timer functions for profiling */ /*********************************/ /* example: */ /* */ /* TIC(LPC) */ /* do_LPC(in_vec, order, acoef); // do LPC analysis */ /* TOC(LPC) */ /* */ /* and call the following just before exiting (from main) */ /* */ /* silk_TimerSave("silk_TimingData.txt"); */ /* */ /* results are now in silk_TimingData.txt */ void silk_TimerSave(char *file_name); /* max number of timers (in different locations) */ #define silk_NUM_TIMERS_MAX 50 /* max length of name tags in TIC(..), TOC(..) */ #define silk_NUM_TIMERS_MAX_TAG_LEN 30 extern int silk_Timer_nTimers; extern int silk_Timer_depth_ctr; extern char silk_Timer_tags[silk_NUM_TIMERS_MAX][silk_NUM_TIMERS_MAX_TAG_LEN]; #ifdef _WIN32 extern LARGE_INTEGER silk_Timer_start[silk_NUM_TIMERS_MAX]; #else extern unsigned long silk_Timer_start[silk_NUM_TIMERS_MAX]; #endif extern unsigned int silk_Timer_cnt[silk_NUM_TIMERS_MAX]; extern opus_int64 silk_Timer_sum[silk_NUM_TIMERS_MAX]; extern opus_int64 silk_Timer_max[silk_NUM_TIMERS_MAX]; extern opus_int64 silk_Timer_min[silk_NUM_TIMERS_MAX]; extern opus_int64 silk_Timer_depth[silk_NUM_TIMERS_MAX]; /* WARNING: TIC()/TOC can measure only up to 0.1 seconds at a time */ #ifdef _WIN32 #define TIC(TAG_NAME) { \ static int init = 0; \ static int ID = -1; \ if( init == 0 ) \ { \ int k; \ init = 1; \ for( k = 0; k < silk_Timer_nTimers; k++ ) { \ if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \ ID = k; \ break; \ } \ } \ if (ID == -1) { \ ID = silk_Timer_nTimers; \ silk_Timer_nTimers++; \ silk_Timer_depth[ID] = silk_Timer_depth_ctr; \ strcpy(silk_Timer_tags[ID], #TAG_NAME); \ silk_Timer_cnt[ID] = 0; \ silk_Timer_sum[ID] = 0; \ silk_Timer_min[ID] = 0xFFFFFFFF; \ silk_Timer_max[ID] = 0; \ } \ } \ silk_Timer_depth_ctr++; \ QueryPerformanceCounter(&silk_Timer_start[ID]); \ } #else #define TIC(TAG_NAME) { \ static int init = 0; \ static int ID = -1; \ if( init == 0 ) \ { \ int k; \ init = 1; \ for( k = 0; k < silk_Timer_nTimers; k++ ) { \ if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \ ID = k; \ break; \ } \ } \ if (ID == -1) { \ ID = silk_Timer_nTimers; \ silk_Timer_nTimers++; \ silk_Timer_depth[ID] = silk_Timer_depth_ctr; \ strcpy(silk_Timer_tags[ID], #TAG_NAME); \ silk_Timer_cnt[ID] = 0; \ silk_Timer_sum[ID] = 0; \ silk_Timer_min[ID] = 0xFFFFFFFF; \ silk_Timer_max[ID] = 0; \ } \ } \ silk_Timer_depth_ctr++; \ silk_Timer_start[ID] = GetHighResolutionTime(); \ } #endif #ifdef _WIN32 #define TOC(TAG_NAME) { \ LARGE_INTEGER lpPerformanceCount; \ static int init = 0; \ static int ID = 0; \ if( init == 0 ) \ { \ int k; \ init = 1; \ for( k = 0; k < silk_Timer_nTimers; k++ ) { \ if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \ ID = k; \ break; \ } \ } \ } \ QueryPerformanceCounter(&lpPerformanceCount); \ lpPerformanceCount.QuadPart -= silk_Timer_start[ID].QuadPart; \ if((lpPerformanceCount.QuadPart < 100000000) && \ (lpPerformanceCount.QuadPart >= 0)) { \ silk_Timer_cnt[ID]++; \ silk_Timer_sum[ID] += lpPerformanceCount.QuadPart; \ if( lpPerformanceCount.QuadPart > silk_Timer_max[ID] ) \ silk_Timer_max[ID] = lpPerformanceCount.QuadPart; \ if( lpPerformanceCount.QuadPart < silk_Timer_min[ID] ) \ silk_Timer_min[ID] = lpPerformanceCount.QuadPart; \ } \ silk_Timer_depth_ctr--; \ } #else #define TOC(TAG_NAME) { \ unsigned long endTime; \ static int init = 0; \ static int ID = 0; \ if( init == 0 ) \ { \ int k; \ init = 1; \ for( k = 0; k < silk_Timer_nTimers; k++ ) { \ if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \ ID = k; \ break; \ } \ } \ } \ endTime = GetHighResolutionTime(); \ endTime -= silk_Timer_start[ID]; \ if((endTime < 100000000) && \ (endTime >= 0)) { \ silk_Timer_cnt[ID]++; \ silk_Timer_sum[ID] += endTime; \ if( endTime > silk_Timer_max[ID] ) \ silk_Timer_max[ID] = endTime; \ if( endTime < silk_Timer_min[ID] ) \ silk_Timer_min[ID] = endTime; \ } \ silk_Timer_depth_ctr--; \ } #endif #else /* SILK_TIC_TOC */ /* define macros as empty strings */ #define TIC(TAG_NAME) #define TOC(TAG_NAME) #define silk_TimerSave(FILE_NAME) #endif /* SILK_TIC_TOC */ #if SILK_DEBUG /************************************/ /* write data to file for debugging */ /************************************/ /* Example: DEBUG_STORE_DATA(testfile.pcm, &RIN[0], 160*sizeof(opus_int16)); */ #define silk_NUM_STORES_MAX 100 extern FILE *silk_debug_store_fp[ silk_NUM_STORES_MAX ]; extern int silk_debug_store_count; /* Faster way of storing the data */ #define DEBUG_STORE_DATA( FILE_NAME, DATA_PTR, N_BYTES ) { \ static opus_int init = 0, cnt = 0; \ static FILE **fp; \ if (init == 0) { \ init = 1; \ cnt = silk_debug_store_count++; \ silk_debug_store_fp[ cnt ] = fopen(#FILE_NAME, "wb"); \ } \ fwrite((DATA_PTR), (N_BYTES), 1, silk_debug_store_fp[ cnt ]); \ } /* Call this at the end of main() */ #define SILK_DEBUG_STORE_CLOSE_FILES { \ opus_int i; \ for( i = 0; i < silk_debug_store_count; i++ ) { \ fclose( silk_debug_store_fp[ i ] ); \ } \ } #else /* SILK_DEBUG */ /* define macros as empty strings */ #define DEBUG_STORE_DATA(FILE_NAME, DATA_PTR, N_BYTES) #define SILK_DEBUG_STORE_CLOSE_FILES #endif /* SILK_DEBUG */ #ifdef __cplusplus } #endif #endif /* SILK_DEBUG_H */ jamulus-3.9.1+dfsg/libs/opus/silk/mips/0000755000175000017500000000000014340334543017005 5ustar vimervimerjamulus-3.9.1+dfsg/libs/opus/silk/mips/macros_mipsr1.h0000644000175000017500000000543614340334543021745 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef __SILK_MACROS_MIPSR1_H__ #define __SILK_MACROS_MIPSR1_H__ #define mips_clz(x) __builtin_clz(x) #undef silk_SMULWB static inline int silk_SMULWB(int a, int b) { long long ac; int c; ac = __builtin_mips_mult(a, (opus_int32)(opus_int16)b); c = __builtin_mips_extr_w(ac, 16); return c; } #undef silk_SMLAWB #define silk_SMLAWB(a32, b32, c32) ((a32) + silk_SMULWB(b32, c32)) #undef silk_SMULWW static inline int silk_SMULWW(int a, int b) { long long ac; int c; ac = __builtin_mips_mult(a, b); c = __builtin_mips_extr_w(ac, 16); return c; } #undef silk_SMLAWW static inline int silk_SMLAWW(int a, int b, int c) { long long ac; int res; ac = __builtin_mips_mult(b, c); res = __builtin_mips_extr_w(ac, 16); res += a; return res; } #define OVERRIDE_silk_CLZ16 static inline opus_int32 silk_CLZ16(opus_int16 in16) { int re32; opus_int32 in32 = (opus_int32 )in16; re32 = mips_clz(in32); re32-=16; return re32; } #define OVERRIDE_silk_CLZ32 static inline opus_int32 silk_CLZ32(opus_int32 in32) { int re32; re32 = mips_clz(in32); return re32; } #endif /* __SILK_MACROS_MIPSR1_H__ */ jamulus-3.9.1+dfsg/libs/opus/silk/mips/sigproc_fix_mipsr1.h0000644000175000017500000000424414340334543022771 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SILK_SIGPROC_FIX_MIPSR1_H #define SILK_SIGPROC_FIX_MIPSR1_H #undef silk_SAT16 static inline short int silk_SAT16(int a) { int c; c = __builtin_mips_shll_s_w(a, 16); c = c>>16; return c; } #undef silk_LSHIFT_SAT32 static inline int silk_LSHIFT_SAT32(int a, int shift) { int r; r = __builtin_mips_shll_s_w(a, shift); return r; } #undef silk_RSHIFT_ROUND static inline int silk_RSHIFT_ROUND(int a, int shift) { int r; r = __builtin_mips_shra_r_w(a, shift); return r; } #endif /* SILK_SIGPROC_FIX_MIPSR1_H */ jamulus-3.9.1+dfsg/libs/opus/silk/mips/NSQ_del_dec_mipsr1.h0000644000175000017500000005070414340334543022557 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef __NSQ_DEL_DEC_MIPSR1_H__ #define __NSQ_DEL_DEC_MIPSR1_H__ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" #include "stack_alloc.h" #define OVERRIDE_silk_noise_shape_quantizer_del_dec static inline void silk_noise_shape_quantizer_del_dec( silk_nsq_state *NSQ, /* I/O NSQ state */ NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ opus_int signalType, /* I Signal type */ const opus_int32 x_Q10[], /* I */ opus_int8 pulses[], /* O */ opus_int16 xq[], /* O */ opus_int32 sLTP_Q15[], /* I/O LTP filter state */ opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */ const opus_int16 a_Q12[], /* I Short term prediction coefs */ const opus_int16 b_Q14[], /* I Long term prediction coefs */ const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */ opus_int lag, /* I Pitch lag */ opus_int32 HarmShapeFIRPacked_Q14, /* I */ opus_int Tilt_Q14, /* I Spectral tilt */ opus_int32 LF_shp_Q14, /* I */ opus_int32 Gain_Q16, /* I */ opus_int Lambda_Q10, /* I */ opus_int offset_Q10, /* I */ opus_int length, /* I Input length */ opus_int subfr, /* I Subframe number */ opus_int shapingLPCOrder, /* I Shaping LPC filter order */ opus_int predictLPCOrder, /* I Prediction filter order */ opus_int warping_Q16, /* I */ opus_int nStatesDelayedDecision, /* I Number of states in decision tree */ opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */ opus_int decisionDelay, /* I */ int arch /* I */ ) { opus_int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx; opus_int32 Winner_rand_state; opus_int32 LTP_pred_Q14, LPC_pred_Q14, n_AR_Q14, n_LTP_Q14; opus_int32 n_LF_Q14, r_Q10, rr_Q10, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10; opus_int32 q1_Q0, q1_Q10, q2_Q10, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10; opus_int32 tmp1, tmp2, sLF_AR_shp_Q14; opus_int32 *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14; NSQ_sample_struct psSampleState[ MAX_DEL_DEC_STATES ][ 2 ]; NSQ_del_dec_struct *psDD; NSQ_sample_struct *psSS; opus_int16 b_Q14_0, b_Q14_1, b_Q14_2, b_Q14_3, b_Q14_4; opus_int16 a_Q12_0, a_Q12_1, a_Q12_2, a_Q12_3, a_Q12_4, a_Q12_5, a_Q12_6; opus_int16 a_Q12_7, a_Q12_8, a_Q12_9, a_Q12_10, a_Q12_11, a_Q12_12, a_Q12_13; opus_int16 a_Q12_14, a_Q12_15; opus_int32 cur, prev, next; /*Unused.*/ (void)arch; //Initialize b_Q14 variables b_Q14_0 = b_Q14[ 0 ]; b_Q14_1 = b_Q14[ 1 ]; b_Q14_2 = b_Q14[ 2 ]; b_Q14_3 = b_Q14[ 3 ]; b_Q14_4 = b_Q14[ 4 ]; //Initialize a_Q12 variables a_Q12_0 = a_Q12[0]; a_Q12_1 = a_Q12[1]; a_Q12_2 = a_Q12[2]; a_Q12_3 = a_Q12[3]; a_Q12_4 = a_Q12[4]; a_Q12_5 = a_Q12[5]; a_Q12_6 = a_Q12[6]; a_Q12_7 = a_Q12[7]; a_Q12_8 = a_Q12[8]; a_Q12_9 = a_Q12[9]; a_Q12_10 = a_Q12[10]; a_Q12_11 = a_Q12[11]; a_Q12_12 = a_Q12[12]; a_Q12_13 = a_Q12[13]; a_Q12_14 = a_Q12[14]; a_Q12_15 = a_Q12[15]; long long temp64; silk_assert( nStatesDelayedDecision > 0 ); shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ]; pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ]; Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 ); for( i = 0; i < length; i++ ) { /* Perform common calculations used in all states */ /* Long-term prediction */ if( signalType == TYPE_VOICED ) { /* Unrolled loop */ /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ temp64 = __builtin_mips_mult(pred_lag_ptr[ 0 ], b_Q14_0 ); temp64 = __builtin_mips_madd( temp64, pred_lag_ptr[ -1 ], b_Q14_1 ); temp64 = __builtin_mips_madd( temp64, pred_lag_ptr[ -2 ], b_Q14_2 ); temp64 = __builtin_mips_madd( temp64, pred_lag_ptr[ -3 ], b_Q14_3 ); temp64 = __builtin_mips_madd( temp64, pred_lag_ptr[ -4 ], b_Q14_4 ); temp64 += 32768; LTP_pred_Q14 = __builtin_mips_extr_w(temp64, 16); LTP_pred_Q14 = silk_LSHIFT( LTP_pred_Q14, 1 ); /* Q13 -> Q14 */ pred_lag_ptr++; } else { LTP_pred_Q14 = 0; } /* Long-term shaping */ if( lag > 0 ) { /* Symmetric, packed FIR coefficients */ n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 ); n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 ); n_LTP_Q14 = silk_SUB_LSHIFT32( LTP_pred_Q14, n_LTP_Q14, 2 ); /* Q12 -> Q14 */ shp_lag_ptr++; } else { n_LTP_Q14 = 0; } for( k = 0; k < nStatesDelayedDecision; k++ ) { /* Delayed decision state */ psDD = &psDelDec[ k ]; /* Sample state */ psSS = psSampleState[ k ]; /* Generate dither */ psDD->Seed = silk_RAND( psDD->Seed ); /* Pointer used in short term prediction and shaping */ psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ]; /* Short-term prediction */ silk_assert( predictLPCOrder == 10 || predictLPCOrder == 16 ); temp64 = __builtin_mips_mult(psLPC_Q14[ 0 ], a_Q12_0 ); temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -1 ], a_Q12_1 ); temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -2 ], a_Q12_2 ); temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -3 ], a_Q12_3 ); temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -4 ], a_Q12_4 ); temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -5 ], a_Q12_5 ); temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -6 ], a_Q12_6 ); temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -7 ], a_Q12_7 ); temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -8 ], a_Q12_8 ); temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -9 ], a_Q12_9 ); if( predictLPCOrder == 16 ) { temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -10 ], a_Q12_10 ); temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -11 ], a_Q12_11 ); temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -12 ], a_Q12_12 ); temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -13 ], a_Q12_13 ); temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -14 ], a_Q12_14 ); temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -15 ], a_Q12_15 ); } temp64 += 32768; LPC_pred_Q14 = __builtin_mips_extr_w(temp64, 16); LPC_pred_Q14 = silk_LSHIFT( LPC_pred_Q14, 4 ); /* Q10 -> Q14 */ /* Noise shape feedback */ silk_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */ /* Output of lowpass section */ tmp2 = silk_SMLAWB( psLPC_Q14[ 0 ], psDD->sAR2_Q14[ 0 ], warping_Q16 ); /* Output of allpass section */ tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ 0 ], psDD->sAR2_Q14[ 1 ] - tmp2, warping_Q16 ); psDD->sAR2_Q14[ 0 ] = tmp2; temp64 = __builtin_mips_mult(tmp2, AR_shp_Q13[ 0 ] ); prev = psDD->sAR2_Q14[ 1 ]; /* Loop over allpass sections */ for( j = 2; j < shapingLPCOrder; j += 2 ) { cur = psDD->sAR2_Q14[ j ]; next = psDD->sAR2_Q14[ j+1 ]; /* Output of allpass section */ tmp2 = silk_SMLAWB( prev, cur - tmp1, warping_Q16 ); psDD->sAR2_Q14[ j - 1 ] = tmp1; temp64 = __builtin_mips_madd( temp64, tmp1, AR_shp_Q13[ j - 1 ] ); temp64 = __builtin_mips_madd( temp64, tmp2, AR_shp_Q13[ j ] ); /* Output of allpass section */ tmp1 = silk_SMLAWB( cur, next - tmp2, warping_Q16 ); psDD->sAR2_Q14[ j + 0 ] = tmp2; prev = next; } psDD->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1; temp64 = __builtin_mips_madd( temp64, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] ); temp64 += 32768; n_AR_Q14 = __builtin_mips_extr_w(temp64, 16); n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 1 ); /* Q11 -> Q12 */ n_AR_Q14 = silk_SMLAWB( n_AR_Q14, psDD->LF_AR_Q14, Tilt_Q14 ); /* Q12 */ n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 2 ); /* Q12 -> Q14 */ n_LF_Q14 = silk_SMULWB( psDD->Shape_Q14[ *smpl_buf_idx ], LF_shp_Q14 ); /* Q12 */ n_LF_Q14 = silk_SMLAWT( n_LF_Q14, psDD->LF_AR_Q14, LF_shp_Q14 ); /* Q12 */ n_LF_Q14 = silk_LSHIFT( n_LF_Q14, 2 ); /* Q12 -> Q14 */ /* Input minus prediction plus noise feedback */ /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP */ tmp1 = silk_ADD32( n_AR_Q14, n_LF_Q14 ); /* Q14 */ tmp2 = silk_ADD32( n_LTP_Q14, LPC_pred_Q14 ); /* Q13 */ tmp1 = silk_SUB32( tmp2, tmp1 ); /* Q13 */ tmp1 = silk_RSHIFT_ROUND( tmp1, 4 ); /* Q10 */ r_Q10 = silk_SUB32( x_Q10[ i ], tmp1 ); /* residual error Q10 */ /* Flip sign depending on dither */ if ( psDD->Seed < 0 ) { r_Q10 = -r_Q10; } r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 ); /* Find two quantization level candidates and measure their rate-distortion */ q1_Q10 = silk_SUB32( r_Q10, offset_Q10 ); q1_Q0 = silk_RSHIFT( q1_Q10, 10 ); if( q1_Q0 > 0 ) { q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); q2_Q10 = silk_ADD32( q1_Q10, 1024 ); rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 ); rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 ); } else if( q1_Q0 == 0 ) { q1_Q10 = offset_Q10; q2_Q10 = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 ); rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 ); rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 ); } else if( q1_Q0 == -1 ) { q2_Q10 = offset_Q10; q1_Q10 = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 ); rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 ); rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 ); } else { /* q1_Q0 < -1 */ q1_Q10 = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); q2_Q10 = silk_ADD32( q1_Q10, 1024 ); rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 ); rd2_Q10 = silk_SMULBB( -q2_Q10, Lambda_Q10 ); } rr_Q10 = silk_SUB32( r_Q10, q1_Q10 ); rd1_Q10 = silk_RSHIFT( silk_SMLABB( rd1_Q10, rr_Q10, rr_Q10 ), 10 ); rr_Q10 = silk_SUB32( r_Q10, q2_Q10 ); rd2_Q10 = silk_RSHIFT( silk_SMLABB( rd2_Q10, rr_Q10, rr_Q10 ), 10 ); if( rd1_Q10 < rd2_Q10 ) { psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 ); psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 ); psSS[ 0 ].Q_Q10 = q1_Q10; psSS[ 1 ].Q_Q10 = q2_Q10; } else { psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 ); psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 ); psSS[ 0 ].Q_Q10 = q2_Q10; psSS[ 1 ].Q_Q10 = q1_Q10; } /* Update states for best quantization */ /* Quantized excitation */ exc_Q14 = silk_LSHIFT32( psSS[ 0 ].Q_Q10, 4 ); if ( psDD->Seed < 0 ) { exc_Q14 = -exc_Q14; } /* Add predictions */ LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 ); xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 ); /* Update states */ sLF_AR_shp_Q14 = silk_SUB32( xq_Q14, n_AR_Q14 ); psSS[ 0 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 ); psSS[ 0 ].LF_AR_Q14 = sLF_AR_shp_Q14; psSS[ 0 ].LPC_exc_Q14 = LPC_exc_Q14; psSS[ 0 ].xq_Q14 = xq_Q14; /* Update states for second best quantization */ /* Quantized excitation */ exc_Q14 = silk_LSHIFT32( psSS[ 1 ].Q_Q10, 4 ); if ( psDD->Seed < 0 ) { exc_Q14 = -exc_Q14; } /* Add predictions */ LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 ); xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 ); /* Update states */ sLF_AR_shp_Q14 = silk_SUB32( xq_Q14, n_AR_Q14 ); psSS[ 1 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 ); psSS[ 1 ].LF_AR_Q14 = sLF_AR_shp_Q14; psSS[ 1 ].LPC_exc_Q14 = LPC_exc_Q14; psSS[ 1 ].xq_Q14 = xq_Q14; } *smpl_buf_idx = ( *smpl_buf_idx - 1 ) % DECISION_DELAY; if( *smpl_buf_idx < 0 ) *smpl_buf_idx += DECISION_DELAY; last_smple_idx = ( *smpl_buf_idx + decisionDelay ) % DECISION_DELAY; /* Find winner */ RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10; Winner_ind = 0; for( k = 1; k < nStatesDelayedDecision; k++ ) { if( psSampleState[ k ][ 0 ].RD_Q10 < RDmin_Q10 ) { RDmin_Q10 = psSampleState[ k ][ 0 ].RD_Q10; Winner_ind = k; } } /* Increase RD values of expired states */ Winner_rand_state = psDelDec[ Winner_ind ].RandState[ last_smple_idx ]; for( k = 0; k < nStatesDelayedDecision; k++ ) { if( psDelDec[ k ].RandState[ last_smple_idx ] != Winner_rand_state ) { psSampleState[ k ][ 0 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 0 ].RD_Q10, silk_int32_MAX >> 4 ); psSampleState[ k ][ 1 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 1 ].RD_Q10, silk_int32_MAX >> 4 ); silk_assert( psSampleState[ k ][ 0 ].RD_Q10 >= 0 ); } } /* Find worst in first set and best in second set */ RDmax_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10; RDmin_Q10 = psSampleState[ 0 ][ 1 ].RD_Q10; RDmax_ind = 0; RDmin_ind = 0; for( k = 1; k < nStatesDelayedDecision; k++ ) { /* find worst in first set */ if( psSampleState[ k ][ 0 ].RD_Q10 > RDmax_Q10 ) { RDmax_Q10 = psSampleState[ k ][ 0 ].RD_Q10; RDmax_ind = k; } /* find best in second set */ if( psSampleState[ k ][ 1 ].RD_Q10 < RDmin_Q10 ) { RDmin_Q10 = psSampleState[ k ][ 1 ].RD_Q10; RDmin_ind = k; } } /* Replace a state if best from second set outperforms worst in first set */ if( RDmin_Q10 < RDmax_Q10 ) { silk_memcpy( ( (opus_int32 *)&psDelDec[ RDmax_ind ] ) + i, ( (opus_int32 *)&psDelDec[ RDmin_ind ] ) + i, sizeof( NSQ_del_dec_struct ) - i * sizeof( opus_int32) ); silk_memcpy( &psSampleState[ RDmax_ind ][ 0 ], &psSampleState[ RDmin_ind ][ 1 ], sizeof( NSQ_sample_struct ) ); } /* Write samples from winner to output and long-term filter states */ psDD = &psDelDec[ Winner_ind ]; if( subfr > 0 || i >= decisionDelay ) { pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 ); xq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], delayedGain_Q10[ last_smple_idx ] ), 8 ) ); NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDD->Shape_Q14[ last_smple_idx ]; sLTP_Q15[ NSQ->sLTP_buf_idx - decisionDelay ] = psDD->Pred_Q15[ last_smple_idx ]; } NSQ->sLTP_shp_buf_idx++; NSQ->sLTP_buf_idx++; /* Update states */ for( k = 0; k < nStatesDelayedDecision; k++ ) { psDD = &psDelDec[ k ]; psSS = &psSampleState[ k ][ 0 ]; psDD->LF_AR_Q14 = psSS->LF_AR_Q14; psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ] = psSS->xq_Q14; psDD->Xq_Q14[ *smpl_buf_idx ] = psSS->xq_Q14; psDD->Q_Q10[ *smpl_buf_idx ] = psSS->Q_Q10; psDD->Pred_Q15[ *smpl_buf_idx ] = silk_LSHIFT32( psSS->LPC_exc_Q14, 1 ); psDD->Shape_Q14[ *smpl_buf_idx ] = psSS->sLTP_shp_Q14; psDD->Seed = silk_ADD32_ovflw( psDD->Seed, silk_RSHIFT_ROUND( psSS->Q_Q10, 10 ) ); psDD->RandState[ *smpl_buf_idx ] = psDD->Seed; psDD->RD_Q10 = psSS->RD_Q10; } delayedGain_Q10[ *smpl_buf_idx ] = Gain_Q10; } /* Update LPC states */ for( k = 0; k < nStatesDelayedDecision; k++ ) { psDD = &psDelDec[ k ]; silk_memcpy( psDD->sLPC_Q14, &psDD->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); } } #endif /* __NSQ_DEL_DEC_MIPSR1_H__ */ jamulus-3.9.1+dfsg/libs/opus/silk/stereo_MS_to_LR.c0000644000175000017500000001140714340334543021203 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" /* Convert adaptive Mid/Side representation to Left/Right stereo signal */ void silk_stereo_MS_to_LR( stereo_dec_state *state, /* I/O State */ opus_int16 x1[], /* I/O Left input signal, becomes mid signal */ opus_int16 x2[], /* I/O Right input signal, becomes side signal */ const opus_int32 pred_Q13[], /* I Predictors */ opus_int fs_kHz, /* I Samples rate (kHz) */ opus_int frame_length /* I Number of samples */ ) { opus_int n, denom_Q16, delta0_Q13, delta1_Q13; opus_int32 sum, diff, pred0_Q13, pred1_Q13; /* Buffering */ silk_memcpy( x1, state->sMid, 2 * sizeof( opus_int16 ) ); silk_memcpy( x2, state->sSide, 2 * sizeof( opus_int16 ) ); silk_memcpy( state->sMid, &x1[ frame_length ], 2 * sizeof( opus_int16 ) ); silk_memcpy( state->sSide, &x2[ frame_length ], 2 * sizeof( opus_int16 ) ); /* Interpolate predictors and add prediction to side channel */ pred0_Q13 = state->pred_prev_Q13[ 0 ]; pred1_Q13 = state->pred_prev_Q13[ 1 ]; denom_Q16 = silk_DIV32_16( (opus_int32)1 << 16, STEREO_INTERP_LEN_MS * fs_kHz ); delta0_Q13 = silk_RSHIFT_ROUND( silk_SMULBB( pred_Q13[ 0 ] - state->pred_prev_Q13[ 0 ], denom_Q16 ), 16 ); delta1_Q13 = silk_RSHIFT_ROUND( silk_SMULBB( pred_Q13[ 1 ] - state->pred_prev_Q13[ 1 ], denom_Q16 ), 16 ); for( n = 0; n < STEREO_INTERP_LEN_MS * fs_kHz; n++ ) { pred0_Q13 += delta0_Q13; pred1_Q13 += delta1_Q13; sum = silk_LSHIFT( silk_ADD_LSHIFT( x1[ n ] + x1[ n + 2 ], x1[ n + 1 ], 1 ), 9 ); /* Q11 */ sum = silk_SMLAWB( silk_LSHIFT( (opus_int32)x2[ n + 1 ], 8 ), sum, pred0_Q13 ); /* Q8 */ sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)x1[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */ x2[ n + 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) ); } pred0_Q13 = pred_Q13[ 0 ]; pred1_Q13 = pred_Q13[ 1 ]; for( n = STEREO_INTERP_LEN_MS * fs_kHz; n < frame_length; n++ ) { sum = silk_LSHIFT( silk_ADD_LSHIFT( x1[ n ] + x1[ n + 2 ], x1[ n + 1 ], 1 ), 9 ); /* Q11 */ sum = silk_SMLAWB( silk_LSHIFT( (opus_int32)x2[ n + 1 ], 8 ), sum, pred0_Q13 ); /* Q8 */ sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)x1[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */ x2[ n + 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) ); } state->pred_prev_Q13[ 0 ] = pred_Q13[ 0 ]; state->pred_prev_Q13[ 1 ] = pred_Q13[ 1 ]; /* Convert to left/right signals */ for( n = 0; n < frame_length; n++ ) { sum = x1[ n + 1 ] + (opus_int32)x2[ n + 1 ]; diff = x1[ n + 1 ] - (opus_int32)x2[ n + 1 ]; x1[ n + 1 ] = (opus_int16)silk_SAT16( sum ); x2[ n + 1 ] = (opus_int16)silk_SAT16( diff ); } } jamulus-3.9.1+dfsg/libs/opus/silk/NLSF_VQ.c0000644000175000017500000000760714340334543017363 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" /* Compute quantization errors for an LPC_order element input vector for a VQ codebook */ void silk_NLSF_VQ( opus_int32 err_Q24[], /* O Quantization errors [K] */ const opus_int16 in_Q15[], /* I Input vectors to be quantized [LPC_order] */ const opus_uint8 pCB_Q8[], /* I Codebook vectors [K*LPC_order] */ const opus_int16 pWght_Q9[], /* I Codebook weights [K*LPC_order] */ const opus_int K, /* I Number of codebook vectors */ const opus_int LPC_order /* I Number of LPCs */ ) { opus_int i, m; opus_int32 diff_Q15, diffw_Q24, sum_error_Q24, pred_Q24; const opus_int16 *w_Q9_ptr; const opus_uint8 *cb_Q8_ptr; celt_assert( ( LPC_order & 1 ) == 0 ); /* Loop over codebook */ cb_Q8_ptr = pCB_Q8; w_Q9_ptr = pWght_Q9; for( i = 0; i < K; i++ ) { sum_error_Q24 = 0; pred_Q24 = 0; for( m = LPC_order-2; m >= 0; m -= 2 ) { /* Compute weighted absolute predictive quantization error for index m + 1 */ diff_Q15 = silk_SUB_LSHIFT32( in_Q15[ m + 1 ], (opus_int32)cb_Q8_ptr[ m + 1 ], 7 ); /* range: [ -32767 : 32767 ]*/ diffw_Q24 = silk_SMULBB( diff_Q15, w_Q9_ptr[ m + 1 ] ); sum_error_Q24 = silk_ADD32( sum_error_Q24, silk_abs( silk_SUB_RSHIFT32( diffw_Q24, pred_Q24, 1 ) ) ); pred_Q24 = diffw_Q24; /* Compute weighted absolute predictive quantization error for index m */ diff_Q15 = silk_SUB_LSHIFT32( in_Q15[ m ], (opus_int32)cb_Q8_ptr[ m ], 7 ); /* range: [ -32767 : 32767 ]*/ diffw_Q24 = silk_SMULBB( diff_Q15, w_Q9_ptr[ m ] ); sum_error_Q24 = silk_ADD32( sum_error_Q24, silk_abs( silk_SUB_RSHIFT32( diffw_Q24, pred_Q24, 1 ) ) ); pred_Q24 = diffw_Q24; silk_assert( sum_error_Q24 >= 0 ); } err_Q24[ i ] = sum_error_Q24; cb_Q8_ptr += LPC_order; w_Q9_ptr += LPC_order; } } jamulus-3.9.1+dfsg/libs/opus/silk/typedef.h0000644000175000017500000000655014340334543017654 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SILK_TYPEDEF_H #define SILK_TYPEDEF_H #include "opus_types.h" #include "opus_defines.h" #ifndef FIXED_POINT # include # define silk_float float # define silk_float_MAX FLT_MAX #endif #define silk_int64_MAX ((opus_int64)0x7FFFFFFFFFFFFFFFLL) /* 2^63 - 1 */ #define silk_int64_MIN ((opus_int64)0x8000000000000000LL) /* -2^63 */ #define silk_int32_MAX 0x7FFFFFFF /* 2^31 - 1 = 2147483647 */ #define silk_int32_MIN ((opus_int32)0x80000000) /* -2^31 = -2147483648 */ #define silk_int16_MAX 0x7FFF /* 2^15 - 1 = 32767 */ #define silk_int16_MIN ((opus_int16)0x8000) /* -2^15 = -32768 */ #define silk_int8_MAX 0x7F /* 2^7 - 1 = 127 */ #define silk_int8_MIN ((opus_int8)0x80) /* -2^7 = -128 */ #define silk_uint8_MAX 0xFF /* 2^8 - 1 = 255 */ #define silk_TRUE 1 #define silk_FALSE 0 /* assertions */ #if (defined _WIN32 && !defined _WINCE && !defined(__GNUC__) && !defined(NO_ASSERTS)) # ifndef silk_assert # include /* ASSERTE() */ # define silk_assert(COND) _ASSERTE(COND) # endif #else # ifdef ENABLE_ASSERTIONS # include # include #define silk_fatal(str) _silk_fatal(str, __FILE__, __LINE__); #ifdef __GNUC__ __attribute__((noreturn)) #endif static OPUS_INLINE void _silk_fatal(const char *str, const char *file, int line) { fprintf (stderr, "Fatal (internal) error in %s, line %d: %s\n", file, line, str); abort(); } # define silk_assert(COND) {if (!(COND)) {silk_fatal("assertion failed: " #COND);}} # else # define silk_assert(COND) # endif #endif #endif /* SILK_TYPEDEF_H */ jamulus-3.9.1+dfsg/libs/opus/silk/init_encoder.c0000644000175000017500000000547514340334543020656 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef FIXED_POINT #include "main_FIX.h" #else #include "main_FLP.h" #endif #include "tuning_parameters.h" #include "cpu_support.h" /*********************************/ /* Initialize Silk Encoder state */ /*********************************/ opus_int silk_init_encoder( silk_encoder_state_Fxx *psEnc, /* I/O Pointer to Silk FIX encoder state */ int arch /* I Run-time architecture */ ) { opus_int ret = 0; /* Clear the entire encoder state */ silk_memset( psEnc, 0, sizeof( silk_encoder_state_Fxx ) ); psEnc->sCmn.arch = arch; psEnc->sCmn.variable_HP_smth1_Q15 = silk_LSHIFT( silk_lin2log( SILK_FIX_CONST( VARIABLE_HP_MIN_CUTOFF_HZ, 16 ) ) - ( 16 << 7 ), 8 ); psEnc->sCmn.variable_HP_smth2_Q15 = psEnc->sCmn.variable_HP_smth1_Q15; /* Used to deactivate LSF interpolation, pitch prediction */ psEnc->sCmn.first_frame_after_reset = 1; /* Initialize Silk VAD */ ret += silk_VAD_Init( &psEnc->sCmn.sVAD ); return ret; } jamulus-3.9.1+dfsg/libs/opus/silk/NSQ.c0000644000175000017500000005440314340334543016650 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" #include "stack_alloc.h" #include "NSQ.h" static OPUS_INLINE void silk_nsq_scale_states( const silk_encoder_state *psEncC, /* I Encoder State */ silk_nsq_state *NSQ, /* I/O NSQ state */ const opus_int16 x16[], /* I input */ opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */ const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */ opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ opus_int subfr, /* I subframe number */ const opus_int LTP_scale_Q14, /* I */ const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ const opus_int signal_type /* I Signal type */ ); #if !defined(OPUS_X86_MAY_HAVE_SSE4_1) static OPUS_INLINE void silk_noise_shape_quantizer( silk_nsq_state *NSQ, /* I/O NSQ state */ opus_int signalType, /* I Signal type */ const opus_int32 x_sc_Q10[], /* I */ opus_int8 pulses[], /* O */ opus_int16 xq[], /* O */ opus_int32 sLTP_Q15[], /* I/O LTP state */ const opus_int16 a_Q12[], /* I Short term prediction coefs */ const opus_int16 b_Q14[], /* I Long term prediction coefs */ const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */ opus_int lag, /* I Pitch lag */ opus_int32 HarmShapeFIRPacked_Q14, /* I */ opus_int Tilt_Q14, /* I Spectral tilt */ opus_int32 LF_shp_Q14, /* I */ opus_int32 Gain_Q16, /* I */ opus_int Lambda_Q10, /* I */ opus_int offset_Q10, /* I */ opus_int length, /* I Input length */ opus_int shapingLPCOrder, /* I Noise shaping AR filter order */ opus_int predictLPCOrder, /* I Prediction filter order */ int arch /* I Architecture */ ); #endif void silk_NSQ_c ( const silk_encoder_state *psEncC, /* I Encoder State */ silk_nsq_state *NSQ, /* I/O NSQ state */ SideInfoIndices *psIndices, /* I/O Quantization Indices */ const opus_int16 x16[], /* I Input */ opus_int8 pulses[], /* O Quantized pulse signal */ const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ const opus_int LTP_scale_Q14 /* I LTP state scaling */ ) { opus_int k, lag, start_idx, LSF_interpolation_flag; const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13; opus_int16 *pxq; VARDECL( opus_int32, sLTP_Q15 ); VARDECL( opus_int16, sLTP ); opus_int32 HarmShapeFIRPacked_Q14; opus_int offset_Q10; VARDECL( opus_int32, x_sc_Q10 ); SAVE_STACK; NSQ->rand_seed = psIndices->Seed; /* Set unvoiced lag to the previous one, overwrite later for voiced */ lag = NSQ->lagPrev; silk_assert( NSQ->prev_gain_Q16 != 0 ); offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ]; if( psIndices->NLSFInterpCoef_Q2 == 4 ) { LSF_interpolation_flag = 0; } else { LSF_interpolation_flag = 1; } ALLOC( sLTP_Q15, psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 ); ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 ); ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 ); /* Set up pointers to start of sub frame */ NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length; NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; pxq = &NSQ->xq[ psEncC->ltp_mem_length ]; for( k = 0; k < psEncC->nb_subfr; k++ ) { A_Q12 = &PredCoef_Q12[ (( k >> 1 ) | ( 1 - LSF_interpolation_flag )) * MAX_LPC_ORDER ]; B_Q14 = <PCoef_Q14[ k * LTP_ORDER ]; AR_shp_Q13 = &AR_Q13[ k * MAX_SHAPE_LPC_ORDER ]; /* Noise shape parameters */ silk_assert( HarmShapeGain_Q14[ k ] >= 0 ); HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 ); HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 ); NSQ->rewhite_flag = 0; if( psIndices->signalType == TYPE_VOICED ) { /* Voiced */ lag = pitchL[ k ]; /* Re-whitening */ if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) { /* Rewhiten with new A coefs */ start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2; celt_assert( start_idx > 0 ); silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ], A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch ); NSQ->rewhite_flag = 1; NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; } } silk_nsq_scale_states( psEncC, NSQ, x16, x_sc_Q10, sLTP, sLTP_Q15, k, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType ); silk_noise_shape_quantizer( NSQ, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, psEncC->shapingLPCOrder, psEncC->predictLPCOrder, psEncC->arch ); x16 += psEncC->subfr_length; pulses += psEncC->subfr_length; pxq += psEncC->subfr_length; } /* Update lagPrev for next frame */ NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ]; /* Save quantized speech and noise shaping signals */ silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) ); silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) ); RESTORE_STACK; } /***********************************/ /* silk_noise_shape_quantizer */ /***********************************/ #if !defined(OPUS_X86_MAY_HAVE_SSE4_1) static OPUS_INLINE #endif void silk_noise_shape_quantizer( silk_nsq_state *NSQ, /* I/O NSQ state */ opus_int signalType, /* I Signal type */ const opus_int32 x_sc_Q10[], /* I */ opus_int8 pulses[], /* O */ opus_int16 xq[], /* O */ opus_int32 sLTP_Q15[], /* I/O LTP state */ const opus_int16 a_Q12[], /* I Short term prediction coefs */ const opus_int16 b_Q14[], /* I Long term prediction coefs */ const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */ opus_int lag, /* I Pitch lag */ opus_int32 HarmShapeFIRPacked_Q14, /* I */ opus_int Tilt_Q14, /* I Spectral tilt */ opus_int32 LF_shp_Q14, /* I */ opus_int32 Gain_Q16, /* I */ opus_int Lambda_Q10, /* I */ opus_int offset_Q10, /* I */ opus_int length, /* I Input length */ opus_int shapingLPCOrder, /* I Noise shaping AR filter order */ opus_int predictLPCOrder, /* I Prediction filter order */ int arch /* I Architecture */ ) { opus_int i; opus_int32 LTP_pred_Q13, LPC_pred_Q10, n_AR_Q12, n_LTP_Q13; opus_int32 n_LF_Q12, r_Q10, rr_Q10, q1_Q0, q1_Q10, q2_Q10, rd1_Q20, rd2_Q20; opus_int32 exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10; opus_int32 tmp1, tmp2, sLF_AR_shp_Q14; opus_int32 *psLPC_Q14, *shp_lag_ptr, *pred_lag_ptr; #ifdef silk_short_prediction_create_arch_coef opus_int32 a_Q12_arch[MAX_LPC_ORDER]; #endif shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ]; pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ]; Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 ); /* Set up short term AR state */ psLPC_Q14 = &NSQ->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 ]; #ifdef silk_short_prediction_create_arch_coef silk_short_prediction_create_arch_coef(a_Q12_arch, a_Q12, predictLPCOrder); #endif for( i = 0; i < length; i++ ) { /* Generate dither */ NSQ->rand_seed = silk_RAND( NSQ->rand_seed ); /* Short-term prediction */ LPC_pred_Q10 = silk_noise_shape_quantizer_short_prediction(psLPC_Q14, a_Q12, a_Q12_arch, predictLPCOrder, arch); /* Long-term prediction */ if( signalType == TYPE_VOICED ) { /* Unrolled loop */ /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ LTP_pred_Q13 = 2; LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ 0 ], b_Q14[ 0 ] ); LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -1 ], b_Q14[ 1 ] ); LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -2 ], b_Q14[ 2 ] ); LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -3 ], b_Q14[ 3 ] ); LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -4 ], b_Q14[ 4 ] ); pred_lag_ptr++; } else { LTP_pred_Q13 = 0; } /* Noise shape feedback */ celt_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */ n_AR_Q12 = silk_NSQ_noise_shape_feedback_loop(&NSQ->sDiff_shp_Q14, NSQ->sAR2_Q14, AR_shp_Q13, shapingLPCOrder, arch); n_AR_Q12 = silk_SMLAWB( n_AR_Q12, NSQ->sLF_AR_shp_Q14, Tilt_Q14 ); n_LF_Q12 = silk_SMULWB( NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - 1 ], LF_shp_Q14 ); n_LF_Q12 = silk_SMLAWT( n_LF_Q12, NSQ->sLF_AR_shp_Q14, LF_shp_Q14 ); celt_assert( lag > 0 || signalType != TYPE_VOICED ); /* Combine prediction and noise shaping signals */ tmp1 = silk_SUB32( silk_LSHIFT32( LPC_pred_Q10, 2 ), n_AR_Q12 ); /* Q12 */ tmp1 = silk_SUB32( tmp1, n_LF_Q12 ); /* Q12 */ if( lag > 0 ) { /* Symmetric, packed FIR coefficients */ n_LTP_Q13 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 ); n_LTP_Q13 = silk_SMLAWT( n_LTP_Q13, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 ); n_LTP_Q13 = silk_LSHIFT( n_LTP_Q13, 1 ); shp_lag_ptr++; tmp2 = silk_SUB32( LTP_pred_Q13, n_LTP_Q13 ); /* Q13 */ tmp1 = silk_ADD_LSHIFT32( tmp2, tmp1, 1 ); /* Q13 */ tmp1 = silk_RSHIFT_ROUND( tmp1, 3 ); /* Q10 */ } else { tmp1 = silk_RSHIFT_ROUND( tmp1, 2 ); /* Q10 */ } r_Q10 = silk_SUB32( x_sc_Q10[ i ], tmp1 ); /* residual error Q10 */ /* Flip sign depending on dither */ if( NSQ->rand_seed < 0 ) { r_Q10 = -r_Q10; } r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 ); /* Find two quantization level candidates and measure their rate-distortion */ q1_Q10 = silk_SUB32( r_Q10, offset_Q10 ); q1_Q0 = silk_RSHIFT( q1_Q10, 10 ); if (Lambda_Q10 > 2048) { /* For aggressive RDO, the bias becomes more than one pulse. */ int rdo_offset = Lambda_Q10/2 - 512; if (q1_Q10 > rdo_offset) { q1_Q0 = silk_RSHIFT( q1_Q10 - rdo_offset, 10 ); } else if (q1_Q10 < -rdo_offset) { q1_Q0 = silk_RSHIFT( q1_Q10 + rdo_offset, 10 ); } else if (q1_Q10 < 0) { q1_Q0 = -1; } else { q1_Q0 = 0; } } if( q1_Q0 > 0 ) { q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); q2_Q10 = silk_ADD32( q1_Q10, 1024 ); rd1_Q20 = silk_SMULBB( q1_Q10, Lambda_Q10 ); rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 ); } else if( q1_Q0 == 0 ) { q1_Q10 = offset_Q10; q2_Q10 = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 ); rd1_Q20 = silk_SMULBB( q1_Q10, Lambda_Q10 ); rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 ); } else if( q1_Q0 == -1 ) { q2_Q10 = offset_Q10; q1_Q10 = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 ); rd1_Q20 = silk_SMULBB( -q1_Q10, Lambda_Q10 ); rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 ); } else { /* Q1_Q0 < -1 */ q1_Q10 = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); q2_Q10 = silk_ADD32( q1_Q10, 1024 ); rd1_Q20 = silk_SMULBB( -q1_Q10, Lambda_Q10 ); rd2_Q20 = silk_SMULBB( -q2_Q10, Lambda_Q10 ); } rr_Q10 = silk_SUB32( r_Q10, q1_Q10 ); rd1_Q20 = silk_SMLABB( rd1_Q20, rr_Q10, rr_Q10 ); rr_Q10 = silk_SUB32( r_Q10, q2_Q10 ); rd2_Q20 = silk_SMLABB( rd2_Q20, rr_Q10, rr_Q10 ); if( rd2_Q20 < rd1_Q20 ) { q1_Q10 = q2_Q10; } pulses[ i ] = (opus_int8)silk_RSHIFT_ROUND( q1_Q10, 10 ); /* Excitation */ exc_Q14 = silk_LSHIFT( q1_Q10, 4 ); if ( NSQ->rand_seed < 0 ) { exc_Q14 = -exc_Q14; } /* Add predictions */ LPC_exc_Q14 = silk_ADD_LSHIFT32( exc_Q14, LTP_pred_Q13, 1 ); xq_Q14 = silk_ADD_LSHIFT32( LPC_exc_Q14, LPC_pred_Q10, 4 ); /* Scale XQ back to normal level before saving */ xq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( xq_Q14, Gain_Q10 ), 8 ) ); /* Update states */ psLPC_Q14++; *psLPC_Q14 = xq_Q14; NSQ->sDiff_shp_Q14 = silk_SUB_LSHIFT32( xq_Q14, x_sc_Q10[ i ], 4 ); sLF_AR_shp_Q14 = silk_SUB_LSHIFT32( NSQ->sDiff_shp_Q14, n_AR_Q12, 2 ); NSQ->sLF_AR_shp_Q14 = sLF_AR_shp_Q14; NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx ] = silk_SUB_LSHIFT32( sLF_AR_shp_Q14, n_LF_Q12, 2 ); sLTP_Q15[ NSQ->sLTP_buf_idx ] = silk_LSHIFT( LPC_exc_Q14, 1 ); NSQ->sLTP_shp_buf_idx++; NSQ->sLTP_buf_idx++; /* Make dither dependent on quantized signal */ NSQ->rand_seed = silk_ADD32_ovflw( NSQ->rand_seed, pulses[ i ] ); } /* Update LPC synth buffer */ silk_memcpy( NSQ->sLPC_Q14, &NSQ->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); } static OPUS_INLINE void silk_nsq_scale_states( const silk_encoder_state *psEncC, /* I Encoder State */ silk_nsq_state *NSQ, /* I/O NSQ state */ const opus_int16 x16[], /* I input */ opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */ const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */ opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ opus_int subfr, /* I subframe number */ const opus_int LTP_scale_Q14, /* I */ const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ const opus_int signal_type /* I Signal type */ ) { opus_int i, lag; opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q26; lag = pitchL[ subfr ]; inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 ); silk_assert( inv_gain_Q31 != 0 ); /* Scale input */ inv_gain_Q26 = silk_RSHIFT_ROUND( inv_gain_Q31, 5 ); for( i = 0; i < psEncC->subfr_length; i++ ) { x_sc_Q10[ i ] = silk_SMULWW( x16[ i ], inv_gain_Q26 ); } /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */ if( NSQ->rewhite_flag ) { if( subfr == 0 ) { /* Do LTP downscaling */ inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 ); } for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) { silk_assert( i < MAX_FRAME_LENGTH ); sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] ); } } /* Adjust for changing gain */ if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) { gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 ); /* Scale long-term shaping state */ for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx; i++ ) { NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] ); } /* Scale long-term prediction state */ if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) { for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) { sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] ); } } NSQ->sLF_AR_shp_Q14 = silk_SMULWW( gain_adj_Q16, NSQ->sLF_AR_shp_Q14 ); NSQ->sDiff_shp_Q14 = silk_SMULWW( gain_adj_Q16, NSQ->sDiff_shp_Q14 ); /* Scale short-term prediction and shaping states */ for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) { NSQ->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLPC_Q14[ i ] ); } for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) { NSQ->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sAR2_Q14[ i ] ); } /* Save inverse gain */ NSQ->prev_gain_Q16 = Gains_Q16[ subfr ]; } } jamulus-3.9.1+dfsg/libs/opus/silk/x86/0000755000175000017500000000000014340334543016462 5ustar vimervimerjamulus-3.9.1+dfsg/libs/opus/silk/x86/NSQ_del_dec_sse4_1.c0000644000175000017500000013266314340334543022117 0ustar vimervimer/* Copyright (c) 2014, Cisco Systems, INC Written by XiangMingZhu WeiZhou MinPeng YanWang Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "main.h" #include "celt/x86/x86cpu.h" #include "stack_alloc.h" typedef struct { opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ]; opus_int32 RandState[ DECISION_DELAY ]; opus_int32 Q_Q10[ DECISION_DELAY ]; opus_int32 Xq_Q14[ DECISION_DELAY ]; opus_int32 Pred_Q15[ DECISION_DELAY ]; opus_int32 Shape_Q14[ DECISION_DELAY ]; opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ]; opus_int32 LF_AR_Q14; opus_int32 Seed; opus_int32 SeedInit; opus_int32 RD_Q10; } NSQ_del_dec_struct; typedef struct { opus_int32 Q_Q10; opus_int32 RD_Q10; opus_int32 xq_Q14; opus_int32 LF_AR_Q14; opus_int32 sLTP_shp_Q14; opus_int32 LPC_exc_Q14; } NSQ_sample_struct; typedef NSQ_sample_struct NSQ_sample_pair[ 2 ]; static OPUS_INLINE void silk_nsq_del_dec_scale_states_sse4_1( const silk_encoder_state *psEncC, /* I Encoder State */ silk_nsq_state *NSQ, /* I/O NSQ state */ NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ const opus_int32 x_Q3[], /* I Input in Q3 */ opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */ const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */ opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ opus_int subfr, /* I Subframe number */ opus_int nStatesDelayedDecision, /* I Number of del dec states */ const opus_int LTP_scale_Q14, /* I LTP state scaling */ const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ const opus_int signal_type, /* I Signal type */ const opus_int decisionDelay /* I Decision delay */ ); /******************************************/ /* Noise shape quantizer for one subframe */ /******************************************/ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_sse4_1( silk_nsq_state *NSQ, /* I/O NSQ state */ NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ opus_int signalType, /* I Signal type */ const opus_int32 x_Q10[], /* I */ opus_int8 pulses[], /* O */ opus_int16 xq[], /* O */ opus_int32 sLTP_Q15[], /* I/O LTP filter state */ opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */ const opus_int16 a_Q12[], /* I Short term prediction coefs */ const opus_int16 b_Q14[], /* I Long term prediction coefs */ const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */ opus_int lag, /* I Pitch lag */ opus_int32 HarmShapeFIRPacked_Q14, /* I */ opus_int Tilt_Q14, /* I Spectral tilt */ opus_int32 LF_shp_Q14, /* I */ opus_int32 Gain_Q16, /* I */ opus_int Lambda_Q10, /* I */ opus_int offset_Q10, /* I */ opus_int length, /* I Input length */ opus_int subfr, /* I Subframe number */ opus_int shapingLPCOrder, /* I Shaping LPC filter order */ opus_int predictLPCOrder, /* I Prediction filter order */ opus_int warping_Q16, /* I */ opus_int nStatesDelayedDecision, /* I Number of states in decision tree */ opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */ opus_int decisionDelay /* I */ ); void silk_NSQ_del_dec_sse4_1( const silk_encoder_state *psEncC, /* I Encoder State */ silk_nsq_state *NSQ, /* I/O NSQ state */ SideInfoIndices *psIndices, /* I/O Quantization Indices */ const opus_int32 x_Q3[], /* I Prefiltered input signal */ opus_int8 pulses[], /* O Quantized pulse signal */ const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ const opus_int LTP_scale_Q14 /* I LTP state scaling */ ) { opus_int i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr; opus_int last_smple_idx, smpl_buf_idx, decisionDelay; const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13; opus_int16 *pxq; VARDECL( opus_int32, sLTP_Q15 ); VARDECL( opus_int16, sLTP ); opus_int32 HarmShapeFIRPacked_Q14; opus_int offset_Q10; opus_int32 RDmin_Q10, Gain_Q10; VARDECL( opus_int32, x_sc_Q10 ); VARDECL( opus_int32, delayedGain_Q10 ); VARDECL( NSQ_del_dec_struct, psDelDec ); NSQ_del_dec_struct *psDD; SAVE_STACK; /* Set unvoiced lag to the previous one, overwrite later for voiced */ lag = NSQ->lagPrev; silk_assert( NSQ->prev_gain_Q16 != 0 ); /* Initialize delayed decision states */ ALLOC( psDelDec, psEncC->nStatesDelayedDecision, NSQ_del_dec_struct ); silk_memset( psDelDec, 0, psEncC->nStatesDelayedDecision * sizeof( NSQ_del_dec_struct ) ); for( k = 0; k < psEncC->nStatesDelayedDecision; k++ ) { psDD = &psDelDec[ k ]; psDD->Seed = ( k + psIndices->Seed ) & 3; psDD->SeedInit = psDD->Seed; psDD->RD_Q10 = 0; psDD->LF_AR_Q14 = NSQ->sLF_AR_shp_Q14; psDD->Shape_Q14[ 0 ] = NSQ->sLTP_shp_Q14[ psEncC->ltp_mem_length - 1 ]; silk_memcpy( psDD->sLPC_Q14, NSQ->sLPC_Q14, NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); silk_memcpy( psDD->sAR2_Q14, NSQ->sAR2_Q14, sizeof( NSQ->sAR2_Q14 ) ); } offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ]; smpl_buf_idx = 0; /* index of oldest samples */ decisionDelay = silk_min_int( DECISION_DELAY, psEncC->subfr_length ); /* For voiced frames limit the decision delay to lower than the pitch lag */ if( psIndices->signalType == TYPE_VOICED ) { for( k = 0; k < psEncC->nb_subfr; k++ ) { decisionDelay = silk_min_int( decisionDelay, pitchL[ k ] - LTP_ORDER / 2 - 1 ); } } else { if( lag > 0 ) { decisionDelay = silk_min_int( decisionDelay, lag - LTP_ORDER / 2 - 1 ); } } if( psIndices->NLSFInterpCoef_Q2 == 4 ) { LSF_interpolation_flag = 0; } else { LSF_interpolation_flag = 1; } ALLOC( sLTP_Q15, psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 ); ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 ); ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 ); ALLOC( delayedGain_Q10, DECISION_DELAY, opus_int32 ); /* Set up pointers to start of sub frame */ pxq = &NSQ->xq[ psEncC->ltp_mem_length ]; NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length; NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; subfr = 0; for( k = 0; k < psEncC->nb_subfr; k++ ) { A_Q12 = &PredCoef_Q12[ ( ( k >> 1 ) | ( 1 - LSF_interpolation_flag ) ) * MAX_LPC_ORDER ]; B_Q14 = <PCoef_Q14[ k * LTP_ORDER ]; AR_shp_Q13 = &AR2_Q13[ k * MAX_SHAPE_LPC_ORDER ]; /* Noise shape parameters */ silk_assert( HarmShapeGain_Q14[ k ] >= 0 ); HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 ); HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 ); NSQ->rewhite_flag = 0; if( psIndices->signalType == TYPE_VOICED ) { /* Voiced */ lag = pitchL[ k ]; /* Re-whitening */ if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) { if( k == 2 ) { /* RESET DELAYED DECISIONS */ /* Find winner */ RDmin_Q10 = psDelDec[ 0 ].RD_Q10; Winner_ind = 0; for( i = 1; i < psEncC->nStatesDelayedDecision; i++ ) { if( psDelDec[ i ].RD_Q10 < RDmin_Q10 ) { RDmin_Q10 = psDelDec[ i ].RD_Q10; Winner_ind = i; } } for( i = 0; i < psEncC->nStatesDelayedDecision; i++ ) { if( i != Winner_ind ) { psDelDec[ i ].RD_Q10 += ( silk_int32_MAX >> 4 ); silk_assert( psDelDec[ i ].RD_Q10 >= 0 ); } } /* Copy final part of signals from winner state to output and long-term filter states */ psDD = &psDelDec[ Winner_ind ]; last_smple_idx = smpl_buf_idx + decisionDelay; for( i = 0; i < decisionDelay; i++ ) { last_smple_idx = ( last_smple_idx - 1 ) % DECISION_DELAY; if( last_smple_idx < 0 ) last_smple_idx += DECISION_DELAY; pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 ); pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gains_Q16[ 1 ] ), 14 ) ); NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ]; } subfr = 0; } /* Rewhiten with new A coefs */ start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2; celt_assert( start_idx > 0 ); silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ], A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch ); NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; NSQ->rewhite_flag = 1; } } silk_nsq_del_dec_scale_states_sse4_1( psEncC, NSQ, psDelDec, x_Q3, x_sc_Q10, sLTP, sLTP_Q15, k, psEncC->nStatesDelayedDecision, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType, decisionDelay ); silk_noise_shape_quantizer_del_dec_sse4_1( NSQ, psDelDec, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, delayedGain_Q10, A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder, psEncC->predictLPCOrder, psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay ); x_Q3 += psEncC->subfr_length; pulses += psEncC->subfr_length; pxq += psEncC->subfr_length; } /* Find winner */ RDmin_Q10 = psDelDec[ 0 ].RD_Q10; Winner_ind = 0; for( k = 1; k < psEncC->nStatesDelayedDecision; k++ ) { if( psDelDec[ k ].RD_Q10 < RDmin_Q10 ) { RDmin_Q10 = psDelDec[ k ].RD_Q10; Winner_ind = k; } } /* Copy final part of signals from winner state to output and long-term filter states */ psDD = &psDelDec[ Winner_ind ]; psIndices->Seed = psDD->SeedInit; last_smple_idx = smpl_buf_idx + decisionDelay; Gain_Q10 = silk_RSHIFT32( Gains_Q16[ psEncC->nb_subfr - 1 ], 6 ); for( i = 0; i < decisionDelay; i++ ) { last_smple_idx = ( last_smple_idx - 1 ) % DECISION_DELAY; if( last_smple_idx < 0 ) last_smple_idx += DECISION_DELAY; pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 ); pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gain_Q10 ), 8 ) ); NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ]; } silk_memcpy( NSQ->sLPC_Q14, &psDD->sLPC_Q14[ psEncC->subfr_length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); silk_memcpy( NSQ->sAR2_Q14, psDD->sAR2_Q14, sizeof( psDD->sAR2_Q14 ) ); /* Update states */ NSQ->sLF_AR_shp_Q14 = psDD->LF_AR_Q14; NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ]; /* Save quantized speech signal */ silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) ); silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) ); RESTORE_STACK; } /******************************************/ /* Noise shape quantizer for one subframe */ /******************************************/ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_sse4_1( silk_nsq_state *NSQ, /* I/O NSQ state */ NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ opus_int signalType, /* I Signal type */ const opus_int32 x_Q10[], /* I */ opus_int8 pulses[], /* O */ opus_int16 xq[], /* O */ opus_int32 sLTP_Q15[], /* I/O LTP filter state */ opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */ const opus_int16 a_Q12[], /* I Short term prediction coefs */ const opus_int16 b_Q14[], /* I Long term prediction coefs */ const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */ opus_int lag, /* I Pitch lag */ opus_int32 HarmShapeFIRPacked_Q14, /* I */ opus_int Tilt_Q14, /* I Spectral tilt */ opus_int32 LF_shp_Q14, /* I */ opus_int32 Gain_Q16, /* I */ opus_int Lambda_Q10, /* I */ opus_int offset_Q10, /* I */ opus_int length, /* I Input length */ opus_int subfr, /* I Subframe number */ opus_int shapingLPCOrder, /* I Shaping LPC filter order */ opus_int predictLPCOrder, /* I Prediction filter order */ opus_int warping_Q16, /* I */ opus_int nStatesDelayedDecision, /* I Number of states in decision tree */ opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */ opus_int decisionDelay /* I */ ) { opus_int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx; opus_int32 Winner_rand_state; opus_int32 LTP_pred_Q14, LPC_pred_Q14, n_AR_Q14, n_LTP_Q14; opus_int32 n_LF_Q14, r_Q10, rr_Q10, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10; opus_int32 q1_Q0, q1_Q10, q2_Q10, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10; opus_int32 tmp1, tmp2, sLF_AR_shp_Q14; opus_int32 *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14; VARDECL( NSQ_sample_pair, psSampleState ); NSQ_del_dec_struct *psDD; NSQ_sample_struct *psSS; __m128i a_Q12_0123, a_Q12_4567, a_Q12_89AB, a_Q12_CDEF; __m128i b_Q12_0123, b_sr_Q12_0123; SAVE_STACK; celt_assert( nStatesDelayedDecision > 0 ); ALLOC( psSampleState, nStatesDelayedDecision, NSQ_sample_pair ); shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ]; pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ]; Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 ); a_Q12_0123 = OP_CVTEPI16_EPI32_M64( a_Q12 ); a_Q12_4567 = OP_CVTEPI16_EPI32_M64( a_Q12 + 4 ); if( opus_likely( predictLPCOrder == 16 ) ) { a_Q12_89AB = OP_CVTEPI16_EPI32_M64( a_Q12 + 8 ); a_Q12_CDEF = OP_CVTEPI16_EPI32_M64( a_Q12 + 12 ); } if( signalType == TYPE_VOICED ){ b_Q12_0123 = OP_CVTEPI16_EPI32_M64( b_Q14 ); b_sr_Q12_0123 = _mm_shuffle_epi32( b_Q12_0123, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* equal shift right 4 bytes */ } for( i = 0; i < length; i++ ) { /* Perform common calculations used in all states */ /* Long-term prediction */ if( signalType == TYPE_VOICED ) { /* Unrolled loop */ /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ LTP_pred_Q14 = 2; { __m128i tmpa, tmpb, pred_lag_ptr_tmp; pred_lag_ptr_tmp = _mm_loadu_si128( (__m128i *)(&pred_lag_ptr[ -3 ] ) ); pred_lag_ptr_tmp = _mm_shuffle_epi32( pred_lag_ptr_tmp, 0x1B ); tmpa = _mm_mul_epi32( pred_lag_ptr_tmp, b_Q12_0123 ); tmpa = _mm_srli_si128( tmpa, 2 ); pred_lag_ptr_tmp = _mm_shuffle_epi32( pred_lag_ptr_tmp, _MM_SHUFFLE( 0, 3, 2, 1 ) );/* equal shift right 4 bytes */ pred_lag_ptr_tmp = _mm_mul_epi32( pred_lag_ptr_tmp, b_sr_Q12_0123 ); pred_lag_ptr_tmp = _mm_srli_si128( pred_lag_ptr_tmp, 2 ); pred_lag_ptr_tmp = _mm_add_epi32( pred_lag_ptr_tmp, tmpa ); tmpb = _mm_shuffle_epi32( pred_lag_ptr_tmp, _MM_SHUFFLE( 0, 0, 3, 2 ) );/* equal shift right 8 bytes */ pred_lag_ptr_tmp = _mm_add_epi32( pred_lag_ptr_tmp, tmpb ); LTP_pred_Q14 += _mm_cvtsi128_si32( pred_lag_ptr_tmp ); LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] ); LTP_pred_Q14 = silk_LSHIFT( LTP_pred_Q14, 1 ); /* Q13 -> Q14 */ pred_lag_ptr++; } } else { LTP_pred_Q14 = 0; } /* Long-term shaping */ if( lag > 0 ) { /* Symmetric, packed FIR coefficients */ n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 ); n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 ); n_LTP_Q14 = silk_SUB_LSHIFT32( LTP_pred_Q14, n_LTP_Q14, 2 ); /* Q12 -> Q14 */ shp_lag_ptr++; } else { n_LTP_Q14 = 0; } { __m128i tmpa, tmpb, psLPC_Q14_tmp, a_Q12_tmp; for( k = 0; k < nStatesDelayedDecision; k++ ) { /* Delayed decision state */ psDD = &psDelDec[ k ]; /* Sample state */ psSS = psSampleState[ k ]; /* Generate dither */ psDD->Seed = silk_RAND( psDD->Seed ); /* Pointer used in short term prediction and shaping */ psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ]; /* Short-term prediction */ silk_assert( predictLPCOrder == 10 || predictLPCOrder == 16 ); /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ LPC_pred_Q14 = silk_RSHIFT( predictLPCOrder, 1 ); tmpb = _mm_setzero_si128(); /* step 1 */ psLPC_Q14_tmp = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[ -3 ] ) ); /* -3, -2 , -1, 0 */ psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, 0x1B ); /* 0, -1, -2, -3 */ tmpa = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_0123 ); /* 0, -1, -2, -3 * 0123 -> 0*0, 2*-2 */ tmpa = _mm_srli_epi64( tmpa, 16 ); tmpb = _mm_add_epi32( tmpb, tmpa ); psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* equal shift right 4 bytes */ a_Q12_tmp = _mm_shuffle_epi32( a_Q12_0123, _MM_SHUFFLE(0, 3, 2, 1 ) ); /* equal shift right 4 bytes */ psLPC_Q14_tmp = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_tmp ); /* 1*-1, 3*-3 */ psLPC_Q14_tmp = _mm_srli_epi64( psLPC_Q14_tmp, 16 ); tmpb = _mm_add_epi32( tmpb, psLPC_Q14_tmp ); /* step 2 */ psLPC_Q14_tmp = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[ -7 ] ) ); psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, 0x1B ); tmpa = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_4567 ); tmpa = _mm_srli_epi64( tmpa, 16 ); tmpb = _mm_add_epi32( tmpb, tmpa ); psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* equal shift right 4 bytes */ a_Q12_tmp = _mm_shuffle_epi32( a_Q12_4567, _MM_SHUFFLE(0, 3, 2, 1 ) ); /* equal shift right 4 bytes */ psLPC_Q14_tmp = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_tmp ); psLPC_Q14_tmp = _mm_srli_epi64( psLPC_Q14_tmp, 16 ); tmpb = _mm_add_epi32( tmpb, psLPC_Q14_tmp ); if ( opus_likely( predictLPCOrder == 16 ) ) { /* step 3 */ psLPC_Q14_tmp = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[ -11 ] ) ); psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, 0x1B ); tmpa = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_89AB ); tmpa = _mm_srli_epi64( tmpa, 16 ); tmpb = _mm_add_epi32( tmpb, tmpa ); psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* equal shift right 4 bytes */ a_Q12_tmp = _mm_shuffle_epi32( a_Q12_89AB, _MM_SHUFFLE(0, 3, 2, 1 ) );/* equal shift right 4 bytes */ psLPC_Q14_tmp = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_tmp ); psLPC_Q14_tmp = _mm_srli_epi64( psLPC_Q14_tmp, 16 ); tmpb = _mm_add_epi32( tmpb, psLPC_Q14_tmp ); /* setp 4 */ psLPC_Q14_tmp = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[ -15 ] ) ); psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, 0x1B ); tmpa = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_CDEF ); tmpa = _mm_srli_epi64( tmpa, 16 ); tmpb = _mm_add_epi32( tmpb, tmpa ); psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* equal shift right 4 bytes */ a_Q12_tmp = _mm_shuffle_epi32( a_Q12_CDEF, _MM_SHUFFLE(0, 3, 2, 1 ) ); /* equal shift right 4 bytes */ psLPC_Q14_tmp = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_tmp ); psLPC_Q14_tmp = _mm_srli_epi64( psLPC_Q14_tmp, 16 ); tmpb = _mm_add_epi32( tmpb, psLPC_Q14_tmp ); /* add at last */ /* equal shift right 8 bytes*/ tmpa = _mm_shuffle_epi32( tmpb, _MM_SHUFFLE( 0, 0, 3, 2 ) ); tmpb = _mm_add_epi32( tmpb, tmpa ); LPC_pred_Q14 += _mm_cvtsi128_si32( tmpb ); } else { /* add at last */ tmpa = _mm_shuffle_epi32( tmpb, _MM_SHUFFLE( 0, 0, 3, 2 ) ); /* equal shift right 8 bytes*/ tmpb = _mm_add_epi32( tmpb, tmpa ); LPC_pred_Q14 += _mm_cvtsi128_si32( tmpb ); LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -8 ], a_Q12[ 8 ] ); LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -9 ], a_Q12[ 9 ] ); } LPC_pred_Q14 = silk_LSHIFT( LPC_pred_Q14, 4 ); /* Q10 -> Q14 */ /* Noise shape feedback */ silk_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */ /* Output of lowpass section */ tmp2 = silk_SMLAWB( psLPC_Q14[ 0 ], psDD->sAR2_Q14[ 0 ], warping_Q16 ); /* Output of allpass section */ tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ 0 ], psDD->sAR2_Q14[ 1 ] - tmp2, warping_Q16 ); psDD->sAR2_Q14[ 0 ] = tmp2; n_AR_Q14 = silk_RSHIFT( shapingLPCOrder, 1 ); n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ 0 ] ); /* Loop over allpass sections */ for( j = 2; j < shapingLPCOrder; j += 2 ) { /* Output of allpass section */ tmp2 = silk_SMLAWB( psDD->sAR2_Q14[ j - 1 ], psDD->sAR2_Q14[ j + 0 ] - tmp1, warping_Q16 ); psDD->sAR2_Q14[ j - 1 ] = tmp1; n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ j - 1 ] ); /* Output of allpass section */ tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ j + 0 ], psDD->sAR2_Q14[ j + 1 ] - tmp2, warping_Q16 ); psDD->sAR2_Q14[ j + 0 ] = tmp2; n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ j ] ); } psDD->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1; n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] ); n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 1 ); /* Q11 -> Q12 */ n_AR_Q14 = silk_SMLAWB( n_AR_Q14, psDD->LF_AR_Q14, Tilt_Q14 ); /* Q12 */ n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 2 ); /* Q12 -> Q14 */ n_LF_Q14 = silk_SMULWB( psDD->Shape_Q14[ *smpl_buf_idx ], LF_shp_Q14 ); /* Q12 */ n_LF_Q14 = silk_SMLAWT( n_LF_Q14, psDD->LF_AR_Q14, LF_shp_Q14 ); /* Q12 */ n_LF_Q14 = silk_LSHIFT( n_LF_Q14, 2 ); /* Q12 -> Q14 */ /* Input minus prediction plus noise feedback */ /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP */ tmp1 = silk_ADD32( n_AR_Q14, n_LF_Q14 ); /* Q14 */ tmp2 = silk_ADD32( n_LTP_Q14, LPC_pred_Q14 ); /* Q13 */ tmp1 = silk_SUB32( tmp2, tmp1 ); /* Q13 */ tmp1 = silk_RSHIFT_ROUND( tmp1, 4 ); /* Q10 */ r_Q10 = silk_SUB32( x_Q10[ i ], tmp1 ); /* residual error Q10 */ /* Flip sign depending on dither */ if ( psDD->Seed < 0 ) { r_Q10 = -r_Q10; } r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 ); /* Find two quantization level candidates and measure their rate-distortion */ q1_Q10 = silk_SUB32( r_Q10, offset_Q10 ); q1_Q0 = silk_RSHIFT( q1_Q10, 10 ); if( q1_Q0 > 0 ) { q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); q2_Q10 = silk_ADD32( q1_Q10, 1024 ); rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 ); rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 ); } else if( q1_Q0 == 0 ) { q1_Q10 = offset_Q10; q2_Q10 = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 ); rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 ); rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 ); } else if( q1_Q0 == -1 ) { q2_Q10 = offset_Q10; q1_Q10 = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 ); rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 ); rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 ); } else { /* q1_Q0 < -1 */ q1_Q10 = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); q2_Q10 = silk_ADD32( q1_Q10, 1024 ); rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 ); rd2_Q10 = silk_SMULBB( -q2_Q10, Lambda_Q10 ); } rr_Q10 = silk_SUB32( r_Q10, q1_Q10 ); rd1_Q10 = silk_RSHIFT( silk_SMLABB( rd1_Q10, rr_Q10, rr_Q10 ), 10 ); rr_Q10 = silk_SUB32( r_Q10, q2_Q10 ); rd2_Q10 = silk_RSHIFT( silk_SMLABB( rd2_Q10, rr_Q10, rr_Q10 ), 10 ); if( rd1_Q10 < rd2_Q10 ) { psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 ); psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 ); psSS[ 0 ].Q_Q10 = q1_Q10; psSS[ 1 ].Q_Q10 = q2_Q10; } else { psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 ); psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 ); psSS[ 0 ].Q_Q10 = q2_Q10; psSS[ 1 ].Q_Q10 = q1_Q10; } /* Update states for best quantization */ /* Quantized excitation */ exc_Q14 = silk_LSHIFT32( psSS[ 0 ].Q_Q10, 4 ); if ( psDD->Seed < 0 ) { exc_Q14 = -exc_Q14; } /* Add predictions */ LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 ); xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 ); /* Update states */ sLF_AR_shp_Q14 = silk_SUB32( xq_Q14, n_AR_Q14 ); psSS[ 0 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 ); psSS[ 0 ].LF_AR_Q14 = sLF_AR_shp_Q14; psSS[ 0 ].LPC_exc_Q14 = LPC_exc_Q14; psSS[ 0 ].xq_Q14 = xq_Q14; /* Update states for second best quantization */ /* Quantized excitation */ exc_Q14 = silk_LSHIFT32( psSS[ 1 ].Q_Q10, 4 ); if ( psDD->Seed < 0 ) { exc_Q14 = -exc_Q14; } /* Add predictions */ LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 ); xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 ); /* Update states */ sLF_AR_shp_Q14 = silk_SUB32( xq_Q14, n_AR_Q14 ); psSS[ 1 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 ); psSS[ 1 ].LF_AR_Q14 = sLF_AR_shp_Q14; psSS[ 1 ].LPC_exc_Q14 = LPC_exc_Q14; psSS[ 1 ].xq_Q14 = xq_Q14; } } *smpl_buf_idx = ( *smpl_buf_idx - 1 ) % DECISION_DELAY; if( *smpl_buf_idx < 0 ) *smpl_buf_idx += DECISION_DELAY; last_smple_idx = ( *smpl_buf_idx + decisionDelay ) % DECISION_DELAY; /* Find winner */ RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10; Winner_ind = 0; for( k = 1; k < nStatesDelayedDecision; k++ ) { if( psSampleState[ k ][ 0 ].RD_Q10 < RDmin_Q10 ) { RDmin_Q10 = psSampleState[ k ][ 0 ].RD_Q10; Winner_ind = k; } } /* Increase RD values of expired states */ Winner_rand_state = psDelDec[ Winner_ind ].RandState[ last_smple_idx ]; for( k = 0; k < nStatesDelayedDecision; k++ ) { if( psDelDec[ k ].RandState[ last_smple_idx ] != Winner_rand_state ) { psSampleState[ k ][ 0 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 0 ].RD_Q10, silk_int32_MAX >> 4 ); psSampleState[ k ][ 1 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 1 ].RD_Q10, silk_int32_MAX >> 4 ); silk_assert( psSampleState[ k ][ 0 ].RD_Q10 >= 0 ); } } /* Find worst in first set and best in second set */ RDmax_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10; RDmin_Q10 = psSampleState[ 0 ][ 1 ].RD_Q10; RDmax_ind = 0; RDmin_ind = 0; for( k = 1; k < nStatesDelayedDecision; k++ ) { /* find worst in first set */ if( psSampleState[ k ][ 0 ].RD_Q10 > RDmax_Q10 ) { RDmax_Q10 = psSampleState[ k ][ 0 ].RD_Q10; RDmax_ind = k; } /* find best in second set */ if( psSampleState[ k ][ 1 ].RD_Q10 < RDmin_Q10 ) { RDmin_Q10 = psSampleState[ k ][ 1 ].RD_Q10; RDmin_ind = k; } } /* Replace a state if best from second set outperforms worst in first set */ if( RDmin_Q10 < RDmax_Q10 ) { silk_memcpy( ( (opus_int32 *)&psDelDec[ RDmax_ind ] ) + i, ( (opus_int32 *)&psDelDec[ RDmin_ind ] ) + i, sizeof( NSQ_del_dec_struct ) - i * sizeof( opus_int32) ); silk_memcpy( &psSampleState[ RDmax_ind ][ 0 ], &psSampleState[ RDmin_ind ][ 1 ], sizeof( NSQ_sample_struct ) ); } /* Write samples from winner to output and long-term filter states */ psDD = &psDelDec[ Winner_ind ]; if( subfr > 0 || i >= decisionDelay ) { pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 ); xq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], delayedGain_Q10[ last_smple_idx ] ), 8 ) ); NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDD->Shape_Q14[ last_smple_idx ]; sLTP_Q15[ NSQ->sLTP_buf_idx - decisionDelay ] = psDD->Pred_Q15[ last_smple_idx ]; } NSQ->sLTP_shp_buf_idx++; NSQ->sLTP_buf_idx++; /* Update states */ for( k = 0; k < nStatesDelayedDecision; k++ ) { psDD = &psDelDec[ k ]; psSS = &psSampleState[ k ][ 0 ]; psDD->LF_AR_Q14 = psSS->LF_AR_Q14; psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ] = psSS->xq_Q14; psDD->Xq_Q14[ *smpl_buf_idx ] = psSS->xq_Q14; psDD->Q_Q10[ *smpl_buf_idx ] = psSS->Q_Q10; psDD->Pred_Q15[ *smpl_buf_idx ] = silk_LSHIFT32( psSS->LPC_exc_Q14, 1 ); psDD->Shape_Q14[ *smpl_buf_idx ] = psSS->sLTP_shp_Q14; psDD->Seed = silk_ADD32_ovflw( psDD->Seed, silk_RSHIFT_ROUND( psSS->Q_Q10, 10 ) ); psDD->RandState[ *smpl_buf_idx ] = psDD->Seed; psDD->RD_Q10 = psSS->RD_Q10; } delayedGain_Q10[ *smpl_buf_idx ] = Gain_Q10; } /* Update LPC states */ for( k = 0; k < nStatesDelayedDecision; k++ ) { psDD = &psDelDec[ k ]; silk_memcpy( psDD->sLPC_Q14, &psDD->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); } RESTORE_STACK; } static OPUS_INLINE void silk_nsq_del_dec_scale_states_sse4_1( const silk_encoder_state *psEncC, /* I Encoder State */ silk_nsq_state *NSQ, /* I/O NSQ state */ NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ const opus_int32 x_Q3[], /* I Input in Q3 */ opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */ const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */ opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ opus_int subfr, /* I Subframe number */ opus_int nStatesDelayedDecision, /* I Number of del dec states */ const opus_int LTP_scale_Q14, /* I LTP state scaling */ const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ const opus_int signal_type, /* I Signal type */ const opus_int decisionDelay /* I Decision delay */ ) { opus_int i, k, lag; opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q23; NSQ_del_dec_struct *psDD; __m128i xmm_inv_gain_Q23, xmm_x_Q3_x2x0, xmm_x_Q3_x3x1; lag = pitchL[ subfr ]; inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 ); silk_assert( inv_gain_Q31 != 0 ); /* Calculate gain adjustment factor */ if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) { gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 ); } else { gain_adj_Q16 = (opus_int32)1 << 16; } /* Scale input */ inv_gain_Q23 = silk_RSHIFT_ROUND( inv_gain_Q31, 8 ); /* prepare inv_gain_Q23 in packed 4 32-bits */ xmm_inv_gain_Q23 = _mm_set1_epi32(inv_gain_Q23); for( i = 0; i < psEncC->subfr_length - 3; i += 4 ) { xmm_x_Q3_x2x0 = _mm_loadu_si128( (__m128i *)(&(x_Q3[ i ] ) ) ); /* equal shift right 4 bytes*/ xmm_x_Q3_x3x1 = _mm_shuffle_epi32( xmm_x_Q3_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) ); xmm_x_Q3_x2x0 = _mm_mul_epi32( xmm_x_Q3_x2x0, xmm_inv_gain_Q23 ); xmm_x_Q3_x3x1 = _mm_mul_epi32( xmm_x_Q3_x3x1, xmm_inv_gain_Q23 ); xmm_x_Q3_x2x0 = _mm_srli_epi64( xmm_x_Q3_x2x0, 16 ); xmm_x_Q3_x3x1 = _mm_slli_epi64( xmm_x_Q3_x3x1, 16 ); xmm_x_Q3_x2x0 = _mm_blend_epi16( xmm_x_Q3_x2x0, xmm_x_Q3_x3x1, 0xCC ); _mm_storeu_si128( (__m128i *)(&(x_sc_Q10[ i ])), xmm_x_Q3_x2x0 ); } for( ; i < psEncC->subfr_length; i++ ) { x_sc_Q10[ i ] = silk_SMULWW( x_Q3[ i ], inv_gain_Q23 ); } /* Save inverse gain */ NSQ->prev_gain_Q16 = Gains_Q16[ subfr ]; /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */ if( NSQ->rewhite_flag ) { if( subfr == 0 ) { /* Do LTP downscaling */ inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 ); } for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) { silk_assert( i < MAX_FRAME_LENGTH ); sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] ); } } /* Adjust for changing gain */ if( gain_adj_Q16 != (opus_int32)1 << 16 ) { /* Scale long-term shaping state */ { __m128i xmm_gain_adj_Q16, xmm_sLTP_shp_Q14_x2x0, xmm_sLTP_shp_Q14_x3x1; /* prepare gain_adj_Q16 in packed 4 32-bits */ xmm_gain_adj_Q16 = _mm_set1_epi32( gain_adj_Q16 ); for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx - 3; i += 4 ) { xmm_sLTP_shp_Q14_x2x0 = _mm_loadu_si128( (__m128i *)(&(NSQ->sLTP_shp_Q14[ i ] ) ) ); /* equal shift right 4 bytes*/ xmm_sLTP_shp_Q14_x3x1 = _mm_shuffle_epi32( xmm_sLTP_shp_Q14_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) ); xmm_sLTP_shp_Q14_x2x0 = _mm_mul_epi32( xmm_sLTP_shp_Q14_x2x0, xmm_gain_adj_Q16 ); xmm_sLTP_shp_Q14_x3x1 = _mm_mul_epi32( xmm_sLTP_shp_Q14_x3x1, xmm_gain_adj_Q16 ); xmm_sLTP_shp_Q14_x2x0 = _mm_srli_epi64( xmm_sLTP_shp_Q14_x2x0, 16 ); xmm_sLTP_shp_Q14_x3x1 = _mm_slli_epi64( xmm_sLTP_shp_Q14_x3x1, 16 ); xmm_sLTP_shp_Q14_x2x0 = _mm_blend_epi16( xmm_sLTP_shp_Q14_x2x0, xmm_sLTP_shp_Q14_x3x1, 0xCC ); _mm_storeu_si128( (__m128i *)(&(NSQ->sLTP_shp_Q14[ i ] ) ), xmm_sLTP_shp_Q14_x2x0 ); } for( ; i < NSQ->sLTP_shp_buf_idx; i++ ) { NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] ); } /* Scale long-term prediction state */ if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) { for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx - decisionDelay; i++ ) { sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] ); } } for( k = 0; k < nStatesDelayedDecision; k++ ) { psDD = &psDelDec[ k ]; /* Scale scalar states */ psDD->LF_AR_Q14 = silk_SMULWW( gain_adj_Q16, psDD->LF_AR_Q14 ); /* Scale short-term prediction and shaping states */ for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) { psDD->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sLPC_Q14[ i ] ); } for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) { psDD->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sAR2_Q14[ i ] ); } for( i = 0; i < DECISION_DELAY; i++ ) { psDD->Pred_Q15[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Pred_Q15[ i ] ); psDD->Shape_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Shape_Q14[ i ] ); } } } } } jamulus-3.9.1+dfsg/libs/opus/silk/x86/main_sse.h0000644000175000017500000004140714340334543020437 0ustar vimervimer/* Copyright (c) 2014, Cisco Systems, INC Written by XiangMingZhu WeiZhou MinPeng YanWang Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef MAIN_SSE_H #define MAIN_SSE_H #ifdef HAVE_CONFIG_H #include "config.h" #endif # if defined(OPUS_X86_MAY_HAVE_SSE4_1) #if 0 /* FIXME: SSE disabled until silk_VQ_WMat_EC_sse4_1() gets updated. */ # define OVERRIDE_silk_VQ_WMat_EC void silk_VQ_WMat_EC_sse4_1( opus_int8 *ind, /* O index of best codebook vector */ opus_int32 *rate_dist_Q14, /* O best weighted quant error + mu * rate */ opus_int *gain_Q7, /* O sum of absolute LTP coefficients */ const opus_int16 *in_Q14, /* I input vector to be quantized */ const opus_int32 *W_Q18, /* I weighting matrix */ const opus_int8 *cb_Q7, /* I codebook */ const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */ const opus_uint8 *cl_Q5, /* I code length for each codebook vector */ const opus_int mu_Q9, /* I tradeoff betw. weighted error and rate */ const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */ opus_int L /* I number of vectors in codebook */ ); #if defined OPUS_X86_PRESUME_SSE4_1 #define silk_VQ_WMat_EC(ind, rate_dist_Q14, gain_Q7, in_Q14, W_Q18, cb_Q7, cb_gain_Q7, cl_Q5, \ mu_Q9, max_gain_Q7, L, arch) \ ((void)(arch),silk_VQ_WMat_EC_sse4_1(ind, rate_dist_Q14, gain_Q7, in_Q14, W_Q18, cb_Q7, cb_gain_Q7, cl_Q5, \ mu_Q9, max_gain_Q7, L)) #else extern void (*const SILK_VQ_WMAT_EC_IMPL[OPUS_ARCHMASK + 1])( opus_int8 *ind, /* O index of best codebook vector */ opus_int32 *rate_dist_Q14, /* O best weighted quant error + mu * rate */ opus_int *gain_Q7, /* O sum of absolute LTP coefficients */ const opus_int16 *in_Q14, /* I input vector to be quantized */ const opus_int32 *W_Q18, /* I weighting matrix */ const opus_int8 *cb_Q7, /* I codebook */ const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */ const opus_uint8 *cl_Q5, /* I code length for each codebook vector */ const opus_int mu_Q9, /* I tradeoff betw. weighted error and rate */ const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */ opus_int L /* I number of vectors in codebook */ ); # define silk_VQ_WMat_EC(ind, rate_dist_Q14, gain_Q7, in_Q14, W_Q18, cb_Q7, cb_gain_Q7, cl_Q5, \ mu_Q9, max_gain_Q7, L, arch) \ ((*SILK_VQ_WMAT_EC_IMPL[(arch) & OPUS_ARCHMASK])(ind, rate_dist_Q14, gain_Q7, in_Q14, W_Q18, cb_Q7, cb_gain_Q7, cl_Q5, \ mu_Q9, max_gain_Q7, L)) #endif #endif #if 0 /* FIXME: SSE disabled until the NSQ code gets updated. */ # define OVERRIDE_silk_NSQ void silk_NSQ_sse4_1( const silk_encoder_state *psEncC, /* I Encoder State */ silk_nsq_state *NSQ, /* I/O NSQ state */ SideInfoIndices *psIndices, /* I/O Quantization Indices */ const opus_int32 x_Q3[], /* I Prefiltered input signal */ opus_int8 pulses[], /* O Quantized pulse signal */ const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ const opus_int LTP_scale_Q14 /* I LTP state scaling */ ); #if defined OPUS_X86_PRESUME_SSE4_1 #define silk_NSQ(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \ HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \ ((void)(arch),silk_NSQ_sse4_1(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \ HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14)) #else extern void (*const SILK_NSQ_IMPL[OPUS_ARCHMASK + 1])( const silk_encoder_state *psEncC, /* I Encoder State */ silk_nsq_state *NSQ, /* I/O NSQ state */ SideInfoIndices *psIndices, /* I/O Quantization Indices */ const opus_int32 x_Q3[], /* I Prefiltered input signal */ opus_int8 pulses[], /* O Quantized pulse signal */ const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ const opus_int LTP_scale_Q14 /* I LTP state scaling */ ); # define silk_NSQ(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \ HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \ ((*SILK_NSQ_IMPL[(arch) & OPUS_ARCHMASK])(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \ HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14)) #endif # define OVERRIDE_silk_NSQ_del_dec void silk_NSQ_del_dec_sse4_1( const silk_encoder_state *psEncC, /* I Encoder State */ silk_nsq_state *NSQ, /* I/O NSQ state */ SideInfoIndices *psIndices, /* I/O Quantization Indices */ const opus_int32 x_Q3[], /* I Prefiltered input signal */ opus_int8 pulses[], /* O Quantized pulse signal */ const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ const opus_int LTP_scale_Q14 /* I LTP state scaling */ ); #if defined OPUS_X86_PRESUME_SSE4_1 #define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \ HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \ ((void)(arch),silk_NSQ_del_dec_sse4_1(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \ HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14)) #else extern void (*const SILK_NSQ_DEL_DEC_IMPL[OPUS_ARCHMASK + 1])( const silk_encoder_state *psEncC, /* I Encoder State */ silk_nsq_state *NSQ, /* I/O NSQ state */ SideInfoIndices *psIndices, /* I/O Quantization Indices */ const opus_int32 x_Q3[], /* I Prefiltered input signal */ opus_int8 pulses[], /* O Quantized pulse signal */ const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ const opus_int LTP_scale_Q14 /* I LTP state scaling */ ); # define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \ HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \ ((*SILK_NSQ_DEL_DEC_IMPL[(arch) & OPUS_ARCHMASK])(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \ HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14)) #endif #endif void silk_noise_shape_quantizer( silk_nsq_state *NSQ, /* I/O NSQ state */ opus_int signalType, /* I Signal type */ const opus_int32 x_sc_Q10[], /* I */ opus_int8 pulses[], /* O */ opus_int16 xq[], /* O */ opus_int32 sLTP_Q15[], /* I/O LTP state */ const opus_int16 a_Q12[], /* I Short term prediction coefs */ const opus_int16 b_Q14[], /* I Long term prediction coefs */ const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */ opus_int lag, /* I Pitch lag */ opus_int32 HarmShapeFIRPacked_Q14, /* I */ opus_int Tilt_Q14, /* I Spectral tilt */ opus_int32 LF_shp_Q14, /* I */ opus_int32 Gain_Q16, /* I */ opus_int Lambda_Q10, /* I */ opus_int offset_Q10, /* I */ opus_int length, /* I Input length */ opus_int shapingLPCOrder, /* I Noise shaping AR filter order */ opus_int predictLPCOrder, /* I Prediction filter order */ int arch /* I Architecture */ ); /**************************/ /* Noise level estimation */ /**************************/ void silk_VAD_GetNoiseLevels( const opus_int32 pX[ VAD_N_BANDS ], /* I subband energies */ silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */ ); # define OVERRIDE_silk_VAD_GetSA_Q8 opus_int silk_VAD_GetSA_Q8_sse4_1( silk_encoder_state *psEnC, const opus_int16 pIn[] ); #if defined(OPUS_X86_PRESUME_SSE4_1) #define silk_VAD_GetSA_Q8(psEnC, pIn, arch) ((void)(arch),silk_VAD_GetSA_Q8_sse4_1(psEnC, pIn)) #else # define silk_VAD_GetSA_Q8(psEnC, pIn, arch) \ ((*SILK_VAD_GETSA_Q8_IMPL[(arch) & OPUS_ARCHMASK])(psEnC, pIn)) extern opus_int (*const SILK_VAD_GETSA_Q8_IMPL[OPUS_ARCHMASK + 1])( silk_encoder_state *psEnC, const opus_int16 pIn[]); #endif # endif #endif jamulus-3.9.1+dfsg/libs/opus/silk/x86/SigProc_FIX_sse.h0000644000175000017500000001175614340334543021573 0ustar vimervimer/* Copyright (c) 2014, Cisco Systems, INC Written by XiangMingZhu WeiZhou MinPeng YanWang Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef SIGPROC_FIX_SSE_H #define SIGPROC_FIX_SSE_H #ifdef HAVE_CONFIG_H #include "config.h" #endif #if defined(OPUS_X86_MAY_HAVE_SSE4_1) void silk_burg_modified_sse4_1( opus_int32 *res_nrg, /* O Residual energy */ opus_int *res_nrg_Q, /* O Residual energy Q value */ opus_int32 A_Q16[], /* O Prediction coefficients (length order) */ const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */ const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */ const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */ const opus_int nb_subfr, /* I Number of subframes stacked in x */ const opus_int D, /* I Order */ int arch /* I Run-time architecture */ ); #if defined(OPUS_X86_PRESUME_SSE4_1) #define silk_burg_modified(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch) \ ((void)(arch), silk_burg_modified_sse4_1(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch)) #else extern void (*const SILK_BURG_MODIFIED_IMPL[OPUS_ARCHMASK + 1])( opus_int32 *res_nrg, /* O Residual energy */ opus_int *res_nrg_Q, /* O Residual energy Q value */ opus_int32 A_Q16[], /* O Prediction coefficients (length order) */ const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */ const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */ const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */ const opus_int nb_subfr, /* I Number of subframes stacked in x */ const opus_int D, /* I Order */ int arch /* I Run-time architecture */); # define silk_burg_modified(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch) \ ((*SILK_BURG_MODIFIED_IMPL[(arch) & OPUS_ARCHMASK])(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch)) #endif opus_int64 silk_inner_prod16_aligned_64_sse4_1( const opus_int16 *inVec1, const opus_int16 *inVec2, const opus_int len ); #if defined(OPUS_X86_PRESUME_SSE4_1) #define silk_inner_prod16_aligned_64(inVec1, inVec2, len, arch) \ ((void)(arch),silk_inner_prod16_aligned_64_sse4_1(inVec1, inVec2, len)) #else extern opus_int64 (*const SILK_INNER_PROD16_ALIGNED_64_IMPL[OPUS_ARCHMASK + 1])( const opus_int16 *inVec1, const opus_int16 *inVec2, const opus_int len); # define silk_inner_prod16_aligned_64(inVec1, inVec2, len, arch) \ ((*SILK_INNER_PROD16_ALIGNED_64_IMPL[(arch) & OPUS_ARCHMASK])(inVec1, inVec2, len)) #endif #endif #endif jamulus-3.9.1+dfsg/libs/opus/silk/x86/NSQ_sse4_1.c0000644000175000017500000010215514340334543020451 0ustar vimervimer/* Copyright (c) 2014, Cisco Systems, INC Written by XiangMingZhu WeiZhou MinPeng YanWang Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "main.h" #include "celt/x86/x86cpu.h" #include "stack_alloc.h" static OPUS_INLINE void silk_nsq_scale_states_sse4_1( const silk_encoder_state *psEncC, /* I Encoder State */ silk_nsq_state *NSQ, /* I/O NSQ state */ const opus_int32 x_Q3[], /* I input in Q3 */ opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */ const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */ opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ opus_int subfr, /* I subframe number */ const opus_int LTP_scale_Q14, /* I */ const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ const opus_int signal_type /* I Signal type */ ); static OPUS_INLINE void silk_noise_shape_quantizer_10_16_sse4_1( silk_nsq_state *NSQ, /* I/O NSQ state */ opus_int signalType, /* I Signal type */ const opus_int32 x_sc_Q10[], /* I */ opus_int8 pulses[], /* O */ opus_int16 xq[], /* O */ opus_int32 sLTP_Q15[], /* I/O LTP state */ const opus_int16 a_Q12[], /* I Short term prediction coefs */ const opus_int16 b_Q14[], /* I Long term prediction coefs */ const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */ opus_int lag, /* I Pitch lag */ opus_int32 HarmShapeFIRPacked_Q14, /* I */ opus_int Tilt_Q14, /* I Spectral tilt */ opus_int32 LF_shp_Q14, /* I */ opus_int32 Gain_Q16, /* I */ opus_int offset_Q10, /* I */ opus_int length, /* I Input length */ opus_int32 table[][4] /* I */ ); void silk_NSQ_sse4_1( const silk_encoder_state *psEncC, /* I Encoder State */ silk_nsq_state *NSQ, /* I/O NSQ state */ SideInfoIndices *psIndices, /* I/O Quantization Indices */ const opus_int32 x_Q3[], /* I Prefiltered input signal */ opus_int8 pulses[], /* O Quantized pulse signal */ const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ const opus_int LTP_scale_Q14 /* I LTP state scaling */ ) { opus_int k, lag, start_idx, LSF_interpolation_flag; const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13; opus_int16 *pxq; VARDECL( opus_int32, sLTP_Q15 ); VARDECL( opus_int16, sLTP ); opus_int32 HarmShapeFIRPacked_Q14; opus_int offset_Q10; VARDECL( opus_int32, x_sc_Q10 ); opus_int32 table[ 64 ][ 4 ]; opus_int32 tmp1; opus_int32 q1_Q10, q2_Q10, rd1_Q20, rd2_Q20; SAVE_STACK; NSQ->rand_seed = psIndices->Seed; /* Set unvoiced lag to the previous one, overwrite later for voiced */ lag = NSQ->lagPrev; silk_assert( NSQ->prev_gain_Q16 != 0 ); offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ]; /* 0 */ q1_Q10 = offset_Q10; q2_Q10 = offset_Q10 + ( 1024 - QUANT_LEVEL_ADJUST_Q10 ); rd1_Q20 = q1_Q10 * Lambda_Q10; rd2_Q20 = q2_Q10 * Lambda_Q10; table[ 32 ][ 0 ] = q1_Q10; table[ 32 ][ 1 ] = q2_Q10; table[ 32 ][ 2 ] = 2 * (q1_Q10 - q2_Q10); table[ 32 ][ 3 ] = (rd1_Q20 - rd2_Q20) + (q1_Q10 * q1_Q10 - q2_Q10 * q2_Q10); /* -1 */ q1_Q10 = offset_Q10 - ( 1024 - QUANT_LEVEL_ADJUST_Q10 ); q2_Q10 = offset_Q10; rd1_Q20 = - q1_Q10 * Lambda_Q10; rd2_Q20 = q2_Q10 * Lambda_Q10; table[ 31 ][ 0 ] = q1_Q10; table[ 31 ][ 1 ] = q2_Q10; table[ 31 ][ 2 ] = 2 * (q1_Q10 - q2_Q10); table[ 31 ][ 3 ] = (rd1_Q20 - rd2_Q20) + (q1_Q10 * q1_Q10 - q2_Q10 * q2_Q10); /* > 0 */ for (k = 1; k <= 31; k++) { tmp1 = offset_Q10 + silk_LSHIFT( k, 10 ); q1_Q10 = tmp1 - QUANT_LEVEL_ADJUST_Q10; q2_Q10 = tmp1 - QUANT_LEVEL_ADJUST_Q10 + 1024; rd1_Q20 = q1_Q10 * Lambda_Q10; rd2_Q20 = q2_Q10 * Lambda_Q10; table[ 32 + k ][ 0 ] = q1_Q10; table[ 32 + k ][ 1 ] = q2_Q10; table[ 32 + k ][ 2 ] = 2 * (q1_Q10 - q2_Q10); table[ 32 + k ][ 3 ] = (rd1_Q20 - rd2_Q20) + (q1_Q10 * q1_Q10 - q2_Q10 * q2_Q10); } /* < -1 */ for (k = -32; k <= -2; k++) { tmp1 = offset_Q10 + silk_LSHIFT( k, 10 ); q1_Q10 = tmp1 + QUANT_LEVEL_ADJUST_Q10; q2_Q10 = tmp1 + QUANT_LEVEL_ADJUST_Q10 + 1024; rd1_Q20 = - q1_Q10 * Lambda_Q10; rd2_Q20 = - q2_Q10 * Lambda_Q10; table[ 32 + k ][ 0 ] = q1_Q10; table[ 32 + k ][ 1 ] = q2_Q10; table[ 32 + k ][ 2 ] = 2 * (q1_Q10 - q2_Q10); table[ 32 + k ][ 3 ] = (rd1_Q20 - rd2_Q20) + (q1_Q10 * q1_Q10 - q2_Q10 * q2_Q10); } if( psIndices->NLSFInterpCoef_Q2 == 4 ) { LSF_interpolation_flag = 0; } else { LSF_interpolation_flag = 1; } ALLOC( sLTP_Q15, psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 ); ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 ); ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 ); /* Set up pointers to start of sub frame */ NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length; NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; pxq = &NSQ->xq[ psEncC->ltp_mem_length ]; for( k = 0; k < psEncC->nb_subfr; k++ ) { A_Q12 = &PredCoef_Q12[ (( k >> 1 ) | ( 1 - LSF_interpolation_flag )) * MAX_LPC_ORDER ]; B_Q14 = <PCoef_Q14[ k * LTP_ORDER ]; AR_shp_Q13 = &AR2_Q13[ k * MAX_SHAPE_LPC_ORDER ]; /* Noise shape parameters */ silk_assert( HarmShapeGain_Q14[ k ] >= 0 ); HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 ); HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 ); NSQ->rewhite_flag = 0; if( psIndices->signalType == TYPE_VOICED ) { /* Voiced */ lag = pitchL[ k ]; /* Re-whitening */ if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) { /* Rewhiten with new A coefs */ start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2; celt_assert( start_idx > 0 ); silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ], A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch ); NSQ->rewhite_flag = 1; NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; } } silk_nsq_scale_states_sse4_1( psEncC, NSQ, x_Q3, x_sc_Q10, sLTP, sLTP_Q15, k, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType ); if ( opus_likely( ( 10 == psEncC->shapingLPCOrder ) && ( 16 == psEncC->predictLPCOrder) ) ) { silk_noise_shape_quantizer_10_16_sse4_1( NSQ, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], offset_Q10, psEncC->subfr_length, &(table[32]) ); } else { silk_noise_shape_quantizer( NSQ, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, psEncC->shapingLPCOrder, psEncC->predictLPCOrder, psEncC->arch ); } x_Q3 += psEncC->subfr_length; pulses += psEncC->subfr_length; pxq += psEncC->subfr_length; } /* Update lagPrev for next frame */ NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ]; /* Save quantized speech and noise shaping signals */ silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) ); silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) ); RESTORE_STACK; } /***********************************/ /* silk_noise_shape_quantizer_10_16 */ /***********************************/ static OPUS_INLINE void silk_noise_shape_quantizer_10_16_sse4_1( silk_nsq_state *NSQ, /* I/O NSQ state */ opus_int signalType, /* I Signal type */ const opus_int32 x_sc_Q10[], /* I */ opus_int8 pulses[], /* O */ opus_int16 xq[], /* O */ opus_int32 sLTP_Q15[], /* I/O LTP state */ const opus_int16 a_Q12[], /* I Short term prediction coefs */ const opus_int16 b_Q14[], /* I Long term prediction coefs */ const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */ opus_int lag, /* I Pitch lag */ opus_int32 HarmShapeFIRPacked_Q14, /* I */ opus_int Tilt_Q14, /* I Spectral tilt */ opus_int32 LF_shp_Q14, /* I */ opus_int32 Gain_Q16, /* I */ opus_int offset_Q10, /* I */ opus_int length, /* I Input length */ opus_int32 table[][4] /* I */ ) { opus_int i; opus_int32 LTP_pred_Q13, LPC_pred_Q10, n_AR_Q12, n_LTP_Q13; opus_int32 n_LF_Q12, r_Q10, q1_Q0, q1_Q10, q2_Q10; opus_int32 exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10; opus_int32 tmp1, tmp2, sLF_AR_shp_Q14; opus_int32 *psLPC_Q14, *shp_lag_ptr, *pred_lag_ptr; __m128i xmm_tempa, xmm_tempb; __m128i xmm_one; __m128i psLPC_Q14_hi_01234567, psLPC_Q14_hi_89ABCDEF; __m128i psLPC_Q14_lo_01234567, psLPC_Q14_lo_89ABCDEF; __m128i a_Q12_01234567, a_Q12_89ABCDEF; __m128i sAR2_Q14_hi_76543210, sAR2_Q14_lo_76543210; __m128i AR_shp_Q13_76543210; shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ]; pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ]; Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 ); /* Set up short term AR state */ psLPC_Q14 = &NSQ->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 ]; sLF_AR_shp_Q14 = NSQ->sLF_AR_shp_Q14; xq_Q14 = psLPC_Q14[ 0 ]; LTP_pred_Q13 = 0; /* load a_Q12 */ xmm_one = _mm_set_epi8( 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14 ); /* load a_Q12[0] - a_Q12[7] */ a_Q12_01234567 = _mm_loadu_si128( (__m128i *)(&a_Q12[ 0 ] ) ); /* load a_Q12[ 8 ] - a_Q12[ 15 ] */ a_Q12_89ABCDEF = _mm_loadu_si128( (__m128i *)(&a_Q12[ 8 ] ) ); a_Q12_01234567 = _mm_shuffle_epi8( a_Q12_01234567, xmm_one ); a_Q12_89ABCDEF = _mm_shuffle_epi8( a_Q12_89ABCDEF, xmm_one ); /* load AR_shp_Q13 */ AR_shp_Q13_76543210 = _mm_loadu_si128( (__m128i *)(&AR_shp_Q13[0] ) ); /* load psLPC_Q14 */ xmm_one = _mm_set_epi8(15, 14, 11, 10, 7, 6, 3, 2, 13, 12, 9, 8, 5, 4, 1, 0 ); xmm_tempa = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[-16]) ); xmm_tempb = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[-12]) ); xmm_tempa = _mm_shuffle_epi8( xmm_tempa, xmm_one ); xmm_tempb = _mm_shuffle_epi8( xmm_tempb, xmm_one ); psLPC_Q14_hi_89ABCDEF = _mm_unpackhi_epi64( xmm_tempa, xmm_tempb ); psLPC_Q14_lo_89ABCDEF = _mm_unpacklo_epi64( xmm_tempa, xmm_tempb ); xmm_tempa = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[ -8 ]) ); xmm_tempb = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[ -4 ]) ); xmm_tempa = _mm_shuffle_epi8( xmm_tempa, xmm_one ); xmm_tempb = _mm_shuffle_epi8( xmm_tempb, xmm_one ); psLPC_Q14_hi_01234567 = _mm_unpackhi_epi64( xmm_tempa, xmm_tempb ); psLPC_Q14_lo_01234567 = _mm_unpacklo_epi64( xmm_tempa, xmm_tempb ); /* load sAR2_Q14 */ xmm_tempa = _mm_loadu_si128( (__m128i *)(&(NSQ->sAR2_Q14[ 0 ]) ) ); xmm_tempb = _mm_loadu_si128( (__m128i *)(&(NSQ->sAR2_Q14[ 4 ]) ) ); xmm_tempa = _mm_shuffle_epi8( xmm_tempa, xmm_one ); xmm_tempb = _mm_shuffle_epi8( xmm_tempb, xmm_one ); sAR2_Q14_hi_76543210 = _mm_unpackhi_epi64( xmm_tempa, xmm_tempb ); sAR2_Q14_lo_76543210 = _mm_unpacklo_epi64( xmm_tempa, xmm_tempb ); /* prepare 1 in 8 * 16bit */ xmm_one = _mm_set1_epi16(1); for( i = 0; i < length; i++ ) { /* Short-term prediction */ __m128i xmm_hi_07, xmm_hi_8F, xmm_lo_07, xmm_lo_8F; /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ LPC_pred_Q10 = 8; /* silk_RSHIFT( predictLPCOrder, 1 ); */ /* shift psLPC_Q14 */ psLPC_Q14_hi_89ABCDEF = _mm_alignr_epi8( psLPC_Q14_hi_01234567, psLPC_Q14_hi_89ABCDEF, 2 ); psLPC_Q14_lo_89ABCDEF = _mm_alignr_epi8( psLPC_Q14_lo_01234567, psLPC_Q14_lo_89ABCDEF, 2 ); psLPC_Q14_hi_01234567 = _mm_srli_si128( psLPC_Q14_hi_01234567, 2 ); psLPC_Q14_lo_01234567 = _mm_srli_si128( psLPC_Q14_lo_01234567, 2 ); psLPC_Q14_hi_01234567 = _mm_insert_epi16( psLPC_Q14_hi_01234567, (xq_Q14 >> 16), 7 ); psLPC_Q14_lo_01234567 = _mm_insert_epi16( psLPC_Q14_lo_01234567, (xq_Q14), 7 ); /* high part, use pmaddwd, results in 4 32-bit */ xmm_hi_07 = _mm_madd_epi16( psLPC_Q14_hi_01234567, a_Q12_01234567 ); xmm_hi_8F = _mm_madd_epi16( psLPC_Q14_hi_89ABCDEF, a_Q12_89ABCDEF ); /* low part, use pmulhw, results in 8 16-bit, note we need simulate unsigned * signed, _mm_srai_epi16(psLPC_Q14_lo_01234567, 15) */ xmm_tempa = _mm_cmpgt_epi16( _mm_setzero_si128(), psLPC_Q14_lo_01234567 ); xmm_tempb = _mm_cmpgt_epi16( _mm_setzero_si128(), psLPC_Q14_lo_89ABCDEF ); xmm_tempa = _mm_and_si128( xmm_tempa, a_Q12_01234567 ); xmm_tempb = _mm_and_si128( xmm_tempb, a_Q12_89ABCDEF ); xmm_lo_07 = _mm_mulhi_epi16( psLPC_Q14_lo_01234567, a_Q12_01234567 ); xmm_lo_8F = _mm_mulhi_epi16( psLPC_Q14_lo_89ABCDEF, a_Q12_89ABCDEF ); xmm_lo_07 = _mm_add_epi16( xmm_lo_07, xmm_tempa ); xmm_lo_8F = _mm_add_epi16( xmm_lo_8F, xmm_tempb ); xmm_lo_07 = _mm_madd_epi16( xmm_lo_07, xmm_one ); xmm_lo_8F = _mm_madd_epi16( xmm_lo_8F, xmm_one ); /* accumulate */ xmm_hi_07 = _mm_add_epi32( xmm_hi_07, xmm_hi_8F ); xmm_lo_07 = _mm_add_epi32( xmm_lo_07, xmm_lo_8F ); xmm_hi_07 = _mm_add_epi32( xmm_hi_07, xmm_lo_07 ); xmm_hi_07 = _mm_add_epi32( xmm_hi_07, _mm_unpackhi_epi64(xmm_hi_07, xmm_hi_07 ) ); xmm_hi_07 = _mm_add_epi32( xmm_hi_07, _mm_shufflelo_epi16(xmm_hi_07, 0x0E ) ); LPC_pred_Q10 += _mm_cvtsi128_si32( xmm_hi_07 ); /* Long-term prediction */ if ( opus_likely( signalType == TYPE_VOICED ) ) { /* Unrolled loop */ /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ LTP_pred_Q13 = 2; { __m128i b_Q14_3210, b_Q14_0123, pred_lag_ptr_0123; b_Q14_3210 = OP_CVTEPI16_EPI32_M64( b_Q14 ); b_Q14_0123 = _mm_shuffle_epi32( b_Q14_3210, 0x1B ); /* loaded: [0] [-1] [-2] [-3] */ pred_lag_ptr_0123 = _mm_loadu_si128( (__m128i *)(&pred_lag_ptr[ -3 ] ) ); /* shuffle to [-3] [-2] [-1] [0] and to new xmm */ xmm_tempa = _mm_shuffle_epi32( pred_lag_ptr_0123, 0x1B ); /*64-bit multiply, a[2] * b[-2], a[0] * b[0] */ xmm_tempa = _mm_mul_epi32( xmm_tempa, b_Q14_3210 ); /* right shift 2 bytes (16 bits), zero extended */ xmm_tempa = _mm_srli_si128( xmm_tempa, 2 ); /* a[1] * b[-1], a[3] * b[-3] */ pred_lag_ptr_0123 = _mm_mul_epi32( pred_lag_ptr_0123, b_Q14_0123 ); pred_lag_ptr_0123 = _mm_srli_si128( pred_lag_ptr_0123, 2 ); pred_lag_ptr_0123 = _mm_add_epi32( pred_lag_ptr_0123, xmm_tempa ); /* equal shift right 8 bytes*/ xmm_tempa = _mm_shuffle_epi32( pred_lag_ptr_0123, _MM_SHUFFLE( 0, 0, 3, 2 ) ); xmm_tempa = _mm_add_epi32( xmm_tempa, pred_lag_ptr_0123 ); LTP_pred_Q13 += _mm_cvtsi128_si32( xmm_tempa ); LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -4 ], b_Q14[ 4 ] ); pred_lag_ptr++; } } /* Noise shape feedback */ NSQ->sAR2_Q14[ 9 ] = NSQ->sAR2_Q14[ 8 ]; NSQ->sAR2_Q14[ 8 ] = _mm_cvtsi128_si32( _mm_srli_si128(_mm_unpackhi_epi16( sAR2_Q14_lo_76543210, sAR2_Q14_hi_76543210 ), 12 ) ); sAR2_Q14_hi_76543210 = _mm_slli_si128( sAR2_Q14_hi_76543210, 2 ); sAR2_Q14_lo_76543210 = _mm_slli_si128( sAR2_Q14_lo_76543210, 2 ); sAR2_Q14_hi_76543210 = _mm_insert_epi16( sAR2_Q14_hi_76543210, (xq_Q14 >> 16), 0 ); sAR2_Q14_lo_76543210 = _mm_insert_epi16( sAR2_Q14_lo_76543210, (xq_Q14), 0 ); /* high part, use pmaddwd, results in 4 32-bit */ xmm_hi_07 = _mm_madd_epi16( sAR2_Q14_hi_76543210, AR_shp_Q13_76543210 ); /* low part, use pmulhw, results in 8 16-bit, note we need simulate unsigned * signed,_mm_srai_epi16(sAR2_Q14_lo_76543210, 15) */ xmm_tempa = _mm_cmpgt_epi16( _mm_setzero_si128(), sAR2_Q14_lo_76543210 ); xmm_tempa = _mm_and_si128( xmm_tempa, AR_shp_Q13_76543210 ); xmm_lo_07 = _mm_mulhi_epi16( sAR2_Q14_lo_76543210, AR_shp_Q13_76543210 ); xmm_lo_07 = _mm_add_epi16( xmm_lo_07, xmm_tempa ); xmm_lo_07 = _mm_madd_epi16( xmm_lo_07, xmm_one ); /* accumulate */ xmm_hi_07 = _mm_add_epi32( xmm_hi_07, xmm_lo_07 ); xmm_hi_07 = _mm_add_epi32( xmm_hi_07, _mm_unpackhi_epi64(xmm_hi_07, xmm_hi_07 ) ); xmm_hi_07 = _mm_add_epi32( xmm_hi_07, _mm_shufflelo_epi16(xmm_hi_07, 0x0E ) ); n_AR_Q12 = 5 + _mm_cvtsi128_si32( xmm_hi_07 ); n_AR_Q12 = silk_SMLAWB( n_AR_Q12, NSQ->sAR2_Q14[ 8 ], AR_shp_Q13[ 8 ] ); n_AR_Q12 = silk_SMLAWB( n_AR_Q12, NSQ->sAR2_Q14[ 9 ], AR_shp_Q13[ 9 ] ); n_AR_Q12 = silk_LSHIFT32( n_AR_Q12, 1 ); /* Q11 -> Q12 */ n_AR_Q12 = silk_SMLAWB( n_AR_Q12, sLF_AR_shp_Q14, Tilt_Q14 ); n_LF_Q12 = silk_SMULWB( NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - 1 ], LF_shp_Q14 ); n_LF_Q12 = silk_SMLAWT( n_LF_Q12, sLF_AR_shp_Q14, LF_shp_Q14 ); silk_assert( lag > 0 || signalType != TYPE_VOICED ); /* Combine prediction and noise shaping signals */ tmp1 = silk_SUB32( silk_LSHIFT32( LPC_pred_Q10, 2 ), n_AR_Q12 ); /* Q12 */ tmp1 = silk_SUB32( tmp1, n_LF_Q12 ); /* Q12 */ if( lag > 0 ) { /* Symmetric, packed FIR coefficients */ n_LTP_Q13 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 ); n_LTP_Q13 = silk_SMLAWT( n_LTP_Q13, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 ); n_LTP_Q13 = silk_LSHIFT( n_LTP_Q13, 1 ); shp_lag_ptr++; tmp2 = silk_SUB32( LTP_pred_Q13, n_LTP_Q13 ); /* Q13 */ tmp1 = silk_ADD_LSHIFT32( tmp2, tmp1, 1 ); /* Q13 */ tmp1 = silk_RSHIFT_ROUND( tmp1, 3 ); /* Q10 */ } else { tmp1 = silk_RSHIFT_ROUND( tmp1, 2 ); /* Q10 */ } r_Q10 = silk_SUB32( x_sc_Q10[ i ], tmp1 ); /* residual error Q10 */ /* Generate dither */ NSQ->rand_seed = silk_RAND( NSQ->rand_seed ); /* Flip sign depending on dither */ tmp2 = -r_Q10; if ( NSQ->rand_seed < 0 ) r_Q10 = tmp2; r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 ); /* Find two quantization level candidates and measure their rate-distortion */ q1_Q10 = silk_SUB32( r_Q10, offset_Q10 ); q1_Q0 = silk_RSHIFT( q1_Q10, 10 ); q1_Q10 = table[q1_Q0][0]; q2_Q10 = table[q1_Q0][1]; if (r_Q10 * table[q1_Q0][2] - table[q1_Q0][3] < 0) { q1_Q10 = q2_Q10; } pulses[ i ] = (opus_int8)silk_RSHIFT_ROUND( q1_Q10, 10 ); /* Excitation */ exc_Q14 = silk_LSHIFT( q1_Q10, 4 ); tmp2 = -exc_Q14; if ( NSQ->rand_seed < 0 ) exc_Q14 = tmp2; /* Add predictions */ LPC_exc_Q14 = silk_ADD_LSHIFT32( exc_Q14, LTP_pred_Q13, 1 ); xq_Q14 = silk_ADD_LSHIFT32( LPC_exc_Q14, LPC_pred_Q10, 4 ); /* Update states */ psLPC_Q14++; *psLPC_Q14 = xq_Q14; sLF_AR_shp_Q14 = silk_SUB_LSHIFT32( xq_Q14, n_AR_Q12, 2 ); NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx ] = silk_SUB_LSHIFT32( sLF_AR_shp_Q14, n_LF_Q12, 2 ); sLTP_Q15[ NSQ->sLTP_buf_idx ] = silk_LSHIFT( LPC_exc_Q14, 1 ); NSQ->sLTP_shp_buf_idx++; NSQ->sLTP_buf_idx++; /* Make dither dependent on quantized signal */ NSQ->rand_seed = silk_ADD32_ovflw( NSQ->rand_seed, pulses[ i ] ); } NSQ->sLF_AR_shp_Q14 = sLF_AR_shp_Q14; /* Scale XQ back to normal level before saving */ psLPC_Q14 = &NSQ->sLPC_Q14[ NSQ_LPC_BUF_LENGTH ]; /* write back sAR2_Q14 */ xmm_tempa = _mm_unpackhi_epi16( sAR2_Q14_lo_76543210, sAR2_Q14_hi_76543210 ); xmm_tempb = _mm_unpacklo_epi16( sAR2_Q14_lo_76543210, sAR2_Q14_hi_76543210 ); _mm_storeu_si128( (__m128i *)(&NSQ->sAR2_Q14[ 4 ]), xmm_tempa ); _mm_storeu_si128( (__m128i *)(&NSQ->sAR2_Q14[ 0 ]), xmm_tempb ); /* xq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( psLPC_Q14[ i ], Gain_Q10 ), 8 ) ); */ { __m128i xmm_Gain_Q10; __m128i xmm_xq_Q14_3210, xmm_xq_Q14_x3x1, xmm_xq_Q14_7654, xmm_xq_Q14_x7x5; /* prepare (1 << 7) in packed 4 32-bits */ xmm_tempa = _mm_set1_epi32( (1 << 7) ); /* prepare Gain_Q10 in packed 4 32-bits */ xmm_Gain_Q10 = _mm_set1_epi32( Gain_Q10 ); /* process xq */ for (i = 0; i < length - 7; i += 8) { xmm_xq_Q14_3210 = _mm_loadu_si128( (__m128i *)(&(psLPC_Q14[ i + 0 ] ) ) ); xmm_xq_Q14_7654 = _mm_loadu_si128( (__m128i *)(&(psLPC_Q14[ i + 4 ] ) ) ); /* equal shift right 4 bytes*/ xmm_xq_Q14_x3x1 = _mm_shuffle_epi32( xmm_xq_Q14_3210, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* equal shift right 4 bytes*/ xmm_xq_Q14_x7x5 = _mm_shuffle_epi32( xmm_xq_Q14_7654, _MM_SHUFFLE( 0, 3, 2, 1 ) ); xmm_xq_Q14_3210 = _mm_mul_epi32( xmm_xq_Q14_3210, xmm_Gain_Q10 ); xmm_xq_Q14_x3x1 = _mm_mul_epi32( xmm_xq_Q14_x3x1, xmm_Gain_Q10 ); xmm_xq_Q14_7654 = _mm_mul_epi32( xmm_xq_Q14_7654, xmm_Gain_Q10 ); xmm_xq_Q14_x7x5 = _mm_mul_epi32( xmm_xq_Q14_x7x5, xmm_Gain_Q10 ); xmm_xq_Q14_3210 = _mm_srli_epi64( xmm_xq_Q14_3210, 16 ); xmm_xq_Q14_x3x1 = _mm_slli_epi64( xmm_xq_Q14_x3x1, 16 ); xmm_xq_Q14_7654 = _mm_srli_epi64( xmm_xq_Q14_7654, 16 ); xmm_xq_Q14_x7x5 = _mm_slli_epi64( xmm_xq_Q14_x7x5, 16 ); xmm_xq_Q14_3210 = _mm_blend_epi16( xmm_xq_Q14_3210, xmm_xq_Q14_x3x1, 0xCC ); xmm_xq_Q14_7654 = _mm_blend_epi16( xmm_xq_Q14_7654, xmm_xq_Q14_x7x5, 0xCC ); /* silk_RSHIFT_ROUND(xq, 8) */ xmm_xq_Q14_3210 = _mm_add_epi32( xmm_xq_Q14_3210, xmm_tempa ); xmm_xq_Q14_7654 = _mm_add_epi32( xmm_xq_Q14_7654, xmm_tempa ); xmm_xq_Q14_3210 = _mm_srai_epi32( xmm_xq_Q14_3210, 8 ); xmm_xq_Q14_7654 = _mm_srai_epi32( xmm_xq_Q14_7654, 8 ); /* silk_SAT16 */ xmm_xq_Q14_3210 = _mm_packs_epi32( xmm_xq_Q14_3210, xmm_xq_Q14_7654 ); /* save to xq */ _mm_storeu_si128( (__m128i *)(&xq[ i ] ), xmm_xq_Q14_3210 ); } } for ( ; i < length; i++) { xq[i] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( psLPC_Q14[ i ], Gain_Q10 ), 8 ) ); } /* Update LPC synth buffer */ silk_memcpy( NSQ->sLPC_Q14, &NSQ->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); } static OPUS_INLINE void silk_nsq_scale_states_sse4_1( const silk_encoder_state *psEncC, /* I Encoder State */ silk_nsq_state *NSQ, /* I/O NSQ state */ const opus_int32 x_Q3[], /* I input in Q3 */ opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */ const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */ opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ opus_int subfr, /* I subframe number */ const opus_int LTP_scale_Q14, /* I */ const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ const opus_int signal_type /* I Signal type */ ) { opus_int i, lag; opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q23; __m128i xmm_inv_gain_Q23, xmm_x_Q3_x2x0, xmm_x_Q3_x3x1; lag = pitchL[ subfr ]; inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 ); silk_assert( inv_gain_Q31 != 0 ); /* Calculate gain adjustment factor */ if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) { gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 ); } else { gain_adj_Q16 = (opus_int32)1 << 16; } /* Scale input */ inv_gain_Q23 = silk_RSHIFT_ROUND( inv_gain_Q31, 8 ); /* prepare inv_gain_Q23 in packed 4 32-bits */ xmm_inv_gain_Q23 = _mm_set1_epi32(inv_gain_Q23); for( i = 0; i < psEncC->subfr_length - 3; i += 4 ) { xmm_x_Q3_x2x0 = _mm_loadu_si128( (__m128i *)(&(x_Q3[ i ] ) ) ); /* equal shift right 4 bytes*/ xmm_x_Q3_x3x1 = _mm_shuffle_epi32( xmm_x_Q3_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) ); xmm_x_Q3_x2x0 = _mm_mul_epi32( xmm_x_Q3_x2x0, xmm_inv_gain_Q23 ); xmm_x_Q3_x3x1 = _mm_mul_epi32( xmm_x_Q3_x3x1, xmm_inv_gain_Q23 ); xmm_x_Q3_x2x0 = _mm_srli_epi64( xmm_x_Q3_x2x0, 16 ); xmm_x_Q3_x3x1 = _mm_slli_epi64( xmm_x_Q3_x3x1, 16 ); xmm_x_Q3_x2x0 = _mm_blend_epi16( xmm_x_Q3_x2x0, xmm_x_Q3_x3x1, 0xCC ); _mm_storeu_si128( (__m128i *)(&(x_sc_Q10[ i ] ) ), xmm_x_Q3_x2x0 ); } for( ; i < psEncC->subfr_length; i++ ) { x_sc_Q10[ i ] = silk_SMULWW( x_Q3[ i ], inv_gain_Q23 ); } /* Save inverse gain */ NSQ->prev_gain_Q16 = Gains_Q16[ subfr ]; /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */ if( NSQ->rewhite_flag ) { if( subfr == 0 ) { /* Do LTP downscaling */ inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 ); } for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) { silk_assert( i < MAX_FRAME_LENGTH ); sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] ); } } /* Adjust for changing gain */ if( gain_adj_Q16 != (opus_int32)1 << 16 ) { /* Scale long-term shaping state */ __m128i xmm_gain_adj_Q16, xmm_sLTP_shp_Q14_x2x0, xmm_sLTP_shp_Q14_x3x1; /* prepare gain_adj_Q16 in packed 4 32-bits */ xmm_gain_adj_Q16 = _mm_set1_epi32(gain_adj_Q16); for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx - 3; i += 4 ) { xmm_sLTP_shp_Q14_x2x0 = _mm_loadu_si128( (__m128i *)(&(NSQ->sLTP_shp_Q14[ i ] ) ) ); /* equal shift right 4 bytes*/ xmm_sLTP_shp_Q14_x3x1 = _mm_shuffle_epi32( xmm_sLTP_shp_Q14_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) ); xmm_sLTP_shp_Q14_x2x0 = _mm_mul_epi32( xmm_sLTP_shp_Q14_x2x0, xmm_gain_adj_Q16 ); xmm_sLTP_shp_Q14_x3x1 = _mm_mul_epi32( xmm_sLTP_shp_Q14_x3x1, xmm_gain_adj_Q16 ); xmm_sLTP_shp_Q14_x2x0 = _mm_srli_epi64( xmm_sLTP_shp_Q14_x2x0, 16 ); xmm_sLTP_shp_Q14_x3x1 = _mm_slli_epi64( xmm_sLTP_shp_Q14_x3x1, 16 ); xmm_sLTP_shp_Q14_x2x0 = _mm_blend_epi16( xmm_sLTP_shp_Q14_x2x0, xmm_sLTP_shp_Q14_x3x1, 0xCC ); _mm_storeu_si128( (__m128i *)(&(NSQ->sLTP_shp_Q14[ i ] ) ), xmm_sLTP_shp_Q14_x2x0 ); } for( ; i < NSQ->sLTP_shp_buf_idx; i++ ) { NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] ); } /* Scale long-term prediction state */ if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) { for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) { sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] ); } } NSQ->sLF_AR_shp_Q14 = silk_SMULWW( gain_adj_Q16, NSQ->sLF_AR_shp_Q14 ); /* Scale short-term prediction and shaping states */ for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) { NSQ->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLPC_Q14[ i ] ); } for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) { NSQ->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sAR2_Q14[ i ] ); } } } jamulus-3.9.1+dfsg/libs/opus/silk/x86/VAD_sse4_1.c0000644000175000017500000002666714340334543020437 0ustar vimervimer/* Copyright (c) 2014, Cisco Systems, INC Written by XiangMingZhu WeiZhou MinPeng YanWang Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "main.h" #include "stack_alloc.h" /* Weighting factors for tilt measure */ static const opus_int32 tiltWeights[ VAD_N_BANDS ] = { 30000, 6000, -12000, -12000 }; /***************************************/ /* Get the speech activity level in Q8 */ /***************************************/ opus_int silk_VAD_GetSA_Q8_sse4_1( /* O Return value, 0 if success */ silk_encoder_state *psEncC, /* I/O Encoder state */ const opus_int16 pIn[] /* I PCM input */ ) { opus_int SA_Q15, pSNR_dB_Q7, input_tilt; opus_int decimated_framelength1, decimated_framelength2; opus_int decimated_framelength; opus_int dec_subframe_length, dec_subframe_offset, SNR_Q7, i, b, s; opus_int32 sumSquared, smooth_coef_Q16; opus_int16 HPstateTmp; VARDECL( opus_int16, X ); opus_int32 Xnrg[ VAD_N_BANDS ]; opus_int32 NrgToNoiseRatio_Q8[ VAD_N_BANDS ]; opus_int32 speech_nrg, x_tmp; opus_int X_offset[ VAD_N_BANDS ]; opus_int ret = 0; silk_VAD_state *psSilk_VAD = &psEncC->sVAD; SAVE_STACK; /* Safety checks */ silk_assert( VAD_N_BANDS == 4 ); celt_assert( MAX_FRAME_LENGTH >= psEncC->frame_length ); celt_assert( psEncC->frame_length <= 512 ); celt_assert( psEncC->frame_length == 8 * silk_RSHIFT( psEncC->frame_length, 3 ) ); /***********************/ /* Filter and Decimate */ /***********************/ decimated_framelength1 = silk_RSHIFT( psEncC->frame_length, 1 ); decimated_framelength2 = silk_RSHIFT( psEncC->frame_length, 2 ); decimated_framelength = silk_RSHIFT( psEncC->frame_length, 3 ); /* Decimate into 4 bands: 0 L 3L L 3L 5L - -- - -- -- 8 8 2 4 4 [0-1 kHz| temp. |1-2 kHz| 2-4 kHz | 4-8 kHz | They're arranged to allow the minimal ( frame_length / 4 ) extra scratch space during the downsampling process */ X_offset[ 0 ] = 0; X_offset[ 1 ] = decimated_framelength + decimated_framelength2; X_offset[ 2 ] = X_offset[ 1 ] + decimated_framelength; X_offset[ 3 ] = X_offset[ 2 ] + decimated_framelength2; ALLOC( X, X_offset[ 3 ] + decimated_framelength1, opus_int16 ); /* 0-8 kHz to 0-4 kHz and 4-8 kHz */ silk_ana_filt_bank_1( pIn, &psSilk_VAD->AnaState[ 0 ], X, &X[ X_offset[ 3 ] ], psEncC->frame_length ); /* 0-4 kHz to 0-2 kHz and 2-4 kHz */ silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState1[ 0 ], X, &X[ X_offset[ 2 ] ], decimated_framelength1 ); /* 0-2 kHz to 0-1 kHz and 1-2 kHz */ silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState2[ 0 ], X, &X[ X_offset[ 1 ] ], decimated_framelength2 ); /*********************************************/ /* HP filter on lowest band (differentiator) */ /*********************************************/ X[ decimated_framelength - 1 ] = silk_RSHIFT( X[ decimated_framelength - 1 ], 1 ); HPstateTmp = X[ decimated_framelength - 1 ]; for( i = decimated_framelength - 1; i > 0; i-- ) { X[ i - 1 ] = silk_RSHIFT( X[ i - 1 ], 1 ); X[ i ] -= X[ i - 1 ]; } X[ 0 ] -= psSilk_VAD->HPstate; psSilk_VAD->HPstate = HPstateTmp; /*************************************/ /* Calculate the energy in each band */ /*************************************/ for( b = 0; b < VAD_N_BANDS; b++ ) { /* Find the decimated framelength in the non-uniformly divided bands */ decimated_framelength = silk_RSHIFT( psEncC->frame_length, silk_min_int( VAD_N_BANDS - b, VAD_N_BANDS - 1 ) ); /* Split length into subframe lengths */ dec_subframe_length = silk_RSHIFT( decimated_framelength, VAD_INTERNAL_SUBFRAMES_LOG2 ); dec_subframe_offset = 0; /* Compute energy per sub-frame */ /* initialize with summed energy of last subframe */ Xnrg[ b ] = psSilk_VAD->XnrgSubfr[ b ]; for( s = 0; s < VAD_INTERNAL_SUBFRAMES; s++ ) { __m128i xmm_X, xmm_acc; sumSquared = 0; xmm_acc = _mm_setzero_si128(); for( i = 0; i < dec_subframe_length - 7; i += 8 ) { xmm_X = _mm_loadu_si128( (__m128i *)&(X[ X_offset[ b ] + i + dec_subframe_offset ] ) ); xmm_X = _mm_srai_epi16( xmm_X, 3 ); xmm_X = _mm_madd_epi16( xmm_X, xmm_X ); xmm_acc = _mm_add_epi32( xmm_acc, xmm_X ); } xmm_acc = _mm_add_epi32( xmm_acc, _mm_unpackhi_epi64( xmm_acc, xmm_acc ) ); xmm_acc = _mm_add_epi32( xmm_acc, _mm_shufflelo_epi16( xmm_acc, 0x0E ) ); sumSquared += _mm_cvtsi128_si32( xmm_acc ); for( ; i < dec_subframe_length; i++ ) { /* The energy will be less than dec_subframe_length * ( silk_int16_MIN / 8 ) ^ 2. */ /* Therefore we can accumulate with no risk of overflow (unless dec_subframe_length > 128) */ x_tmp = silk_RSHIFT( X[ X_offset[ b ] + i + dec_subframe_offset ], 3 ); sumSquared = silk_SMLABB( sumSquared, x_tmp, x_tmp ); /* Safety check */ silk_assert( sumSquared >= 0 ); } /* Add/saturate summed energy of current subframe */ if( s < VAD_INTERNAL_SUBFRAMES - 1 ) { Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], sumSquared ); } else { /* Look-ahead subframe */ Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], silk_RSHIFT( sumSquared, 1 ) ); } dec_subframe_offset += dec_subframe_length; } psSilk_VAD->XnrgSubfr[ b ] = sumSquared; } /********************/ /* Noise estimation */ /********************/ silk_VAD_GetNoiseLevels( &Xnrg[ 0 ], psSilk_VAD ); /***********************************************/ /* Signal-plus-noise to noise ratio estimation */ /***********************************************/ sumSquared = 0; input_tilt = 0; for( b = 0; b < VAD_N_BANDS; b++ ) { speech_nrg = Xnrg[ b ] - psSilk_VAD->NL[ b ]; if( speech_nrg > 0 ) { /* Divide, with sufficient resolution */ if( ( Xnrg[ b ] & 0xFF800000 ) == 0 ) { NrgToNoiseRatio_Q8[ b ] = silk_DIV32( silk_LSHIFT( Xnrg[ b ], 8 ), psSilk_VAD->NL[ b ] + 1 ); } else { NrgToNoiseRatio_Q8[ b ] = silk_DIV32( Xnrg[ b ], silk_RSHIFT( psSilk_VAD->NL[ b ], 8 ) + 1 ); } /* Convert to log domain */ SNR_Q7 = silk_lin2log( NrgToNoiseRatio_Q8[ b ] ) - 8 * 128; /* Sum-of-squares */ sumSquared = silk_SMLABB( sumSquared, SNR_Q7, SNR_Q7 ); /* Q14 */ /* Tilt measure */ if( speech_nrg < ( (opus_int32)1 << 20 ) ) { /* Scale down SNR value for small subband speech energies */ SNR_Q7 = silk_SMULWB( silk_LSHIFT( silk_SQRT_APPROX( speech_nrg ), 6 ), SNR_Q7 ); } input_tilt = silk_SMLAWB( input_tilt, tiltWeights[ b ], SNR_Q7 ); } else { NrgToNoiseRatio_Q8[ b ] = 256; } } /* Mean-of-squares */ sumSquared = silk_DIV32_16( sumSquared, VAD_N_BANDS ); /* Q14 */ /* Root-mean-square approximation, scale to dBs, and write to output pointer */ pSNR_dB_Q7 = (opus_int16)( 3 * silk_SQRT_APPROX( sumSquared ) ); /* Q7 */ /*********************************/ /* Speech Probability Estimation */ /*********************************/ SA_Q15 = silk_sigm_Q15( silk_SMULWB( VAD_SNR_FACTOR_Q16, pSNR_dB_Q7 ) - VAD_NEGATIVE_OFFSET_Q5 ); /**************************/ /* Frequency Tilt Measure */ /**************************/ psEncC->input_tilt_Q15 = silk_LSHIFT( silk_sigm_Q15( input_tilt ) - 16384, 1 ); /**************************************************/ /* Scale the sigmoid output based on power levels */ /**************************************************/ speech_nrg = 0; for( b = 0; b < VAD_N_BANDS; b++ ) { /* Accumulate signal-without-noise energies, higher frequency bands have more weight */ speech_nrg += ( b + 1 ) * silk_RSHIFT( Xnrg[ b ] - psSilk_VAD->NL[ b ], 4 ); } /* Power scaling */ if( speech_nrg <= 0 ) { SA_Q15 = silk_RSHIFT( SA_Q15, 1 ); } else if( speech_nrg < 32768 ) { if( psEncC->frame_length == 10 * psEncC->fs_kHz ) { speech_nrg = silk_LSHIFT_SAT32( speech_nrg, 16 ); } else { speech_nrg = silk_LSHIFT_SAT32( speech_nrg, 15 ); } /* square-root */ speech_nrg = silk_SQRT_APPROX( speech_nrg ); SA_Q15 = silk_SMULWB( 32768 + speech_nrg, SA_Q15 ); } /* Copy the resulting speech activity in Q8 */ psEncC->speech_activity_Q8 = silk_min_int( silk_RSHIFT( SA_Q15, 7 ), silk_uint8_MAX ); /***********************************/ /* Energy Level and SNR estimation */ /***********************************/ /* Smoothing coefficient */ smooth_coef_Q16 = silk_SMULWB( VAD_SNR_SMOOTH_COEF_Q18, silk_SMULWB( (opus_int32)SA_Q15, SA_Q15 ) ); if( psEncC->frame_length == 10 * psEncC->fs_kHz ) { smooth_coef_Q16 >>= 1; } for( b = 0; b < VAD_N_BANDS; b++ ) { /* compute smoothed energy-to-noise ratio per band */ psSilk_VAD->NrgRatioSmth_Q8[ b ] = silk_SMLAWB( psSilk_VAD->NrgRatioSmth_Q8[ b ], NrgToNoiseRatio_Q8[ b ] - psSilk_VAD->NrgRatioSmth_Q8[ b ], smooth_coef_Q16 ); /* signal to noise ratio in dB per band */ SNR_Q7 = 3 * ( silk_lin2log( psSilk_VAD->NrgRatioSmth_Q8[b] ) - 8 * 128 ); /* quality = sigmoid( 0.25 * ( SNR_dB - 16 ) ); */ psEncC->input_quality_bands_Q15[ b ] = silk_sigm_Q15( silk_RSHIFT( SNR_Q7 - 16 * 128, 4 ) ); } RESTORE_STACK; return( ret ); } jamulus-3.9.1+dfsg/libs/opus/silk/x86/VQ_WMat_EC_sse4_1.c0000644000175000017500000001470014340334543021633 0ustar vimervimer/* Copyright (c) 2014, Cisco Systems, INC Written by XiangMingZhu WeiZhou MinPeng YanWang Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "main.h" #include "celt/x86/x86cpu.h" /* Entropy constrained matrix-weighted VQ, hard-coded to 5-element vectors, for a single input data vector */ void silk_VQ_WMat_EC_sse4_1( opus_int8 *ind, /* O index of best codebook vector */ opus_int32 *rate_dist_Q14, /* O best weighted quant error + mu * rate */ opus_int *gain_Q7, /* O sum of absolute LTP coefficients */ const opus_int16 *in_Q14, /* I input vector to be quantized */ const opus_int32 *W_Q18, /* I weighting matrix */ const opus_int8 *cb_Q7, /* I codebook */ const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */ const opus_uint8 *cl_Q5, /* I code length for each codebook vector */ const opus_int mu_Q9, /* I tradeoff betw. weighted error and rate */ const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */ opus_int L /* I number of vectors in codebook */ ) { opus_int k, gain_tmp_Q7; const opus_int8 *cb_row_Q7; opus_int16 diff_Q14[ 5 ]; opus_int32 sum1_Q14, sum2_Q16; __m128i C_tmp1, C_tmp2, C_tmp3, C_tmp4, C_tmp5; /* Loop over codebook */ *rate_dist_Q14 = silk_int32_MAX; cb_row_Q7 = cb_Q7; for( k = 0; k < L; k++ ) { gain_tmp_Q7 = cb_gain_Q7[k]; diff_Q14[ 0 ] = in_Q14[ 0 ] - silk_LSHIFT( cb_row_Q7[ 0 ], 7 ); C_tmp1 = OP_CVTEPI16_EPI32_M64( &in_Q14[ 1 ] ); C_tmp2 = OP_CVTEPI8_EPI32_M32( &cb_row_Q7[ 1 ] ); C_tmp2 = _mm_slli_epi32( C_tmp2, 7 ); C_tmp1 = _mm_sub_epi32( C_tmp1, C_tmp2 ); diff_Q14[ 1 ] = _mm_extract_epi16( C_tmp1, 0 ); diff_Q14[ 2 ] = _mm_extract_epi16( C_tmp1, 2 ); diff_Q14[ 3 ] = _mm_extract_epi16( C_tmp1, 4 ); diff_Q14[ 4 ] = _mm_extract_epi16( C_tmp1, 6 ); /* Weighted rate */ sum1_Q14 = silk_SMULBB( mu_Q9, cl_Q5[ k ] ); /* Penalty for too large gain */ sum1_Q14 = silk_ADD_LSHIFT32( sum1_Q14, silk_max( silk_SUB32( gain_tmp_Q7, max_gain_Q7 ), 0 ), 10 ); silk_assert( sum1_Q14 >= 0 ); /* first row of W_Q18 */ C_tmp3 = _mm_loadu_si128( (__m128i *)(&W_Q18[ 1 ] ) ); C_tmp4 = _mm_mul_epi32( C_tmp3, C_tmp1 ); C_tmp4 = _mm_srli_si128( C_tmp4, 2 ); C_tmp1 = _mm_shuffle_epi32( C_tmp1, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* shift right 4 bytes */ C_tmp3 = _mm_shuffle_epi32( C_tmp3, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* shift right 4 bytes */ C_tmp5 = _mm_mul_epi32( C_tmp3, C_tmp1 ); C_tmp5 = _mm_srli_si128( C_tmp5, 2 ); C_tmp5 = _mm_add_epi32( C_tmp4, C_tmp5 ); C_tmp5 = _mm_slli_epi32( C_tmp5, 1 ); C_tmp5 = _mm_add_epi32( C_tmp5, _mm_shuffle_epi32( C_tmp5, _MM_SHUFFLE( 0, 0, 0, 2 ) ) ); sum2_Q16 = _mm_cvtsi128_si32( C_tmp5 ); sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 0 ], diff_Q14[ 0 ] ); sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 0 ] ); /* second row of W_Q18 */ sum2_Q16 = silk_SMULWB( W_Q18[ 7 ], diff_Q14[ 2 ] ); sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 8 ], diff_Q14[ 3 ] ); sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 9 ], diff_Q14[ 4 ] ); sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 ); sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 6 ], diff_Q14[ 1 ] ); sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 1 ] ); /* third row of W_Q18 */ sum2_Q16 = silk_SMULWB( W_Q18[ 13 ], diff_Q14[ 3 ] ); sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 14 ], diff_Q14[ 4 ] ); sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 ); sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 12 ], diff_Q14[ 2 ] ); sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 2 ] ); /* fourth row of W_Q18 */ sum2_Q16 = silk_SMULWB( W_Q18[ 19 ], diff_Q14[ 4 ] ); sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 ); sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 18 ], diff_Q14[ 3 ] ); sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 3 ] ); /* last row of W_Q18 */ sum2_Q16 = silk_SMULWB( W_Q18[ 24 ], diff_Q14[ 4 ] ); sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 4 ] ); silk_assert( sum1_Q14 >= 0 ); /* find best */ if( sum1_Q14 < *rate_dist_Q14 ) { *rate_dist_Q14 = sum1_Q14; *ind = (opus_int8)k; *gain_Q7 = gain_tmp_Q7; } /* Go to next cbk vector */ cb_row_Q7 += LTP_ORDER; } } jamulus-3.9.1+dfsg/libs/opus/silk/x86/x86_silk_map.c0000644000175000017500000002275414340334543021144 0ustar vimervimer/* Copyright (c) 2014, Cisco Systems, INC Written by XiangMingZhu WeiZhou MinPeng YanWang Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if defined(HAVE_CONFIG_H) #include "config.h" #endif #include "celt/x86/x86cpu.h" #include "structs.h" #include "SigProc_FIX.h" #include "pitch.h" #include "main.h" #if !defined(OPUS_X86_PRESUME_SSE4_1) #if defined(FIXED_POINT) #include "fixed/main_FIX.h" opus_int64 (*const SILK_INNER_PROD16_ALIGNED_64_IMPL[ OPUS_ARCHMASK + 1 ] )( const opus_int16 *inVec1, const opus_int16 *inVec2, const opus_int len ) = { silk_inner_prod16_aligned_64_c, /* non-sse */ silk_inner_prod16_aligned_64_c, silk_inner_prod16_aligned_64_c, MAY_HAVE_SSE4_1( silk_inner_prod16_aligned_64 ), /* sse4.1 */ MAY_HAVE_SSE4_1( silk_inner_prod16_aligned_64 ) /* avx */ }; #endif opus_int (*const SILK_VAD_GETSA_Q8_IMPL[ OPUS_ARCHMASK + 1 ] )( silk_encoder_state *psEncC, const opus_int16 pIn[] ) = { silk_VAD_GetSA_Q8_c, /* non-sse */ silk_VAD_GetSA_Q8_c, silk_VAD_GetSA_Q8_c, MAY_HAVE_SSE4_1( silk_VAD_GetSA_Q8 ), /* sse4.1 */ MAY_HAVE_SSE4_1( silk_VAD_GetSA_Q8 ) /* avx */ }; #if 0 /* FIXME: SSE disabled until the NSQ code gets updated. */ void (*const SILK_NSQ_IMPL[ OPUS_ARCHMASK + 1 ] )( const silk_encoder_state *psEncC, /* I Encoder State */ silk_nsq_state *NSQ, /* I/O NSQ state */ SideInfoIndices *psIndices, /* I/O Quantization Indices */ const opus_int32 x_Q3[], /* I Prefiltered input signal */ opus_int8 pulses[], /* O Quantized pulse signal */ const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ const opus_int LTP_scale_Q14 /* I LTP state scaling */ ) = { silk_NSQ_c, /* non-sse */ silk_NSQ_c, silk_NSQ_c, MAY_HAVE_SSE4_1( silk_NSQ ), /* sse4.1 */ MAY_HAVE_SSE4_1( silk_NSQ ) /* avx */ }; #endif #if 0 /* FIXME: SSE disabled until silk_VQ_WMat_EC_sse4_1() gets updated. */ void (*const SILK_VQ_WMAT_EC_IMPL[ OPUS_ARCHMASK + 1 ] )( opus_int8 *ind, /* O index of best codebook vector */ opus_int32 *rate_dist_Q14, /* O best weighted quant error + mu * rate */ opus_int *gain_Q7, /* O sum of absolute LTP coefficients */ const opus_int16 *in_Q14, /* I input vector to be quantized */ const opus_int32 *W_Q18, /* I weighting matrix */ const opus_int8 *cb_Q7, /* I codebook */ const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */ const opus_uint8 *cl_Q5, /* I code length for each codebook vector */ const opus_int mu_Q9, /* I tradeoff betw. weighted error and rate */ const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */ opus_int L /* I number of vectors in codebook */ ) = { silk_VQ_WMat_EC_c, /* non-sse */ silk_VQ_WMat_EC_c, silk_VQ_WMat_EC_c, MAY_HAVE_SSE4_1( silk_VQ_WMat_EC ), /* sse4.1 */ MAY_HAVE_SSE4_1( silk_VQ_WMat_EC ) /* avx */ }; #endif #if 0 /* FIXME: SSE disabled until the NSQ code gets updated. */ void (*const SILK_NSQ_DEL_DEC_IMPL[ OPUS_ARCHMASK + 1 ] )( const silk_encoder_state *psEncC, /* I Encoder State */ silk_nsq_state *NSQ, /* I/O NSQ state */ SideInfoIndices *psIndices, /* I/O Quantization Indices */ const opus_int32 x_Q3[], /* I Prefiltered input signal */ opus_int8 pulses[], /* O Quantized pulse signal */ const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ const opus_int LTP_scale_Q14 /* I LTP state scaling */ ) = { silk_NSQ_del_dec_c, /* non-sse */ silk_NSQ_del_dec_c, silk_NSQ_del_dec_c, MAY_HAVE_SSE4_1( silk_NSQ_del_dec ), /* sse4.1 */ MAY_HAVE_SSE4_1( silk_NSQ_del_dec ) /* avx */ }; #endif #if defined(FIXED_POINT) void (*const SILK_BURG_MODIFIED_IMPL[ OPUS_ARCHMASK + 1 ] )( opus_int32 *res_nrg, /* O Residual energy */ opus_int *res_nrg_Q, /* O Residual energy Q value */ opus_int32 A_Q16[], /* O Prediction coefficients (length order) */ const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */ const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */ const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */ const opus_int nb_subfr, /* I Number of subframes stacked in x */ const opus_int D, /* I Order */ int arch /* I Run-time architecture */ ) = { silk_burg_modified_c, /* non-sse */ silk_burg_modified_c, silk_burg_modified_c, MAY_HAVE_SSE4_1( silk_burg_modified ), /* sse4.1 */ MAY_HAVE_SSE4_1( silk_burg_modified ) /* avx */ }; #endif #endif jamulus-3.9.1+dfsg/libs/opus/silk/structs.h0000644000175000017500000005125314340334543017723 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SILK_STRUCTS_H #define SILK_STRUCTS_H #include "typedef.h" #include "SigProc_FIX.h" #include "define.h" #include "entenc.h" #include "entdec.h" #ifdef __cplusplus extern "C" { #endif /************************************/ /* Noise shaping quantization state */ /************************************/ typedef struct { opus_int16 xq[ 2 * MAX_FRAME_LENGTH ]; /* Buffer for quantized output signal */ opus_int32 sLTP_shp_Q14[ 2 * MAX_FRAME_LENGTH ]; opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ]; opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ]; opus_int32 sLF_AR_shp_Q14; opus_int32 sDiff_shp_Q14; opus_int lagPrev; opus_int sLTP_buf_idx; opus_int sLTP_shp_buf_idx; opus_int32 rand_seed; opus_int32 prev_gain_Q16; opus_int rewhite_flag; } silk_nsq_state; /********************************/ /* VAD state */ /********************************/ typedef struct { opus_int32 AnaState[ 2 ]; /* Analysis filterbank state: 0-8 kHz */ opus_int32 AnaState1[ 2 ]; /* Analysis filterbank state: 0-4 kHz */ opus_int32 AnaState2[ 2 ]; /* Analysis filterbank state: 0-2 kHz */ opus_int32 XnrgSubfr[ VAD_N_BANDS ]; /* Subframe energies */ opus_int32 NrgRatioSmth_Q8[ VAD_N_BANDS ]; /* Smoothed energy level in each band */ opus_int16 HPstate; /* State of differentiator in the lowest band */ opus_int32 NL[ VAD_N_BANDS ]; /* Noise energy level in each band */ opus_int32 inv_NL[ VAD_N_BANDS ]; /* Inverse noise energy level in each band */ opus_int32 NoiseLevelBias[ VAD_N_BANDS ]; /* Noise level estimator bias/offset */ opus_int32 counter; /* Frame counter used in the initial phase */ } silk_VAD_state; /* Variable cut-off low-pass filter state */ typedef struct { opus_int32 In_LP_State[ 2 ]; /* Low pass filter state */ opus_int32 transition_frame_no; /* Counter which is mapped to a cut-off frequency */ opus_int mode; /* Operating mode, <0: switch down, >0: switch up; 0: do nothing */ opus_int32 saved_fs_kHz; /* If non-zero, holds the last sampling rate before a bandwidth switching reset. */ } silk_LP_state; /* Structure containing NLSF codebook */ typedef struct { const opus_int16 nVectors; const opus_int16 order; const opus_int16 quantStepSize_Q16; const opus_int16 invQuantStepSize_Q6; const opus_uint8 *CB1_NLSF_Q8; const opus_int16 *CB1_Wght_Q9; const opus_uint8 *CB1_iCDF; const opus_uint8 *pred_Q8; const opus_uint8 *ec_sel; const opus_uint8 *ec_iCDF; const opus_uint8 *ec_Rates_Q5; const opus_int16 *deltaMin_Q15; } silk_NLSF_CB_struct; typedef struct { opus_int16 pred_prev_Q13[ 2 ]; opus_int16 sMid[ 2 ]; opus_int16 sSide[ 2 ]; opus_int32 mid_side_amp_Q0[ 4 ]; opus_int16 smth_width_Q14; opus_int16 width_prev_Q14; opus_int16 silent_side_len; opus_int8 predIx[ MAX_FRAMES_PER_PACKET ][ 2 ][ 3 ]; opus_int8 mid_only_flags[ MAX_FRAMES_PER_PACKET ]; } stereo_enc_state; typedef struct { opus_int16 pred_prev_Q13[ 2 ]; opus_int16 sMid[ 2 ]; opus_int16 sSide[ 2 ]; } stereo_dec_state; typedef struct { opus_int8 GainsIndices[ MAX_NB_SUBFR ]; opus_int8 LTPIndex[ MAX_NB_SUBFR ]; opus_int8 NLSFIndices[ MAX_LPC_ORDER + 1 ]; opus_int16 lagIndex; opus_int8 contourIndex; opus_int8 signalType; opus_int8 quantOffsetType; opus_int8 NLSFInterpCoef_Q2; opus_int8 PERIndex; opus_int8 LTP_scaleIndex; opus_int8 Seed; } SideInfoIndices; /********************************/ /* Encoder state */ /********************************/ typedef struct { opus_int32 In_HP_State[ 2 ]; /* High pass filter state */ opus_int32 variable_HP_smth1_Q15; /* State of first smoother */ opus_int32 variable_HP_smth2_Q15; /* State of second smoother */ silk_LP_state sLP; /* Low pass filter state */ silk_VAD_state sVAD; /* Voice activity detector state */ silk_nsq_state sNSQ; /* Noise Shape Quantizer State */ opus_int16 prev_NLSFq_Q15[ MAX_LPC_ORDER ]; /* Previously quantized NLSF vector */ opus_int speech_activity_Q8; /* Speech activity */ opus_int allow_bandwidth_switch; /* Flag indicating that switching of internal bandwidth is allowed */ opus_int8 LBRRprevLastGainIndex; opus_int8 prevSignalType; opus_int prevLag; opus_int pitch_LPC_win_length; opus_int max_pitch_lag; /* Highest possible pitch lag (samples) */ opus_int32 API_fs_Hz; /* API sampling frequency (Hz) */ opus_int32 prev_API_fs_Hz; /* Previous API sampling frequency (Hz) */ opus_int maxInternal_fs_Hz; /* Maximum internal sampling frequency (Hz) */ opus_int minInternal_fs_Hz; /* Minimum internal sampling frequency (Hz) */ opus_int desiredInternal_fs_Hz; /* Soft request for internal sampling frequency (Hz) */ opus_int fs_kHz; /* Internal sampling frequency (kHz) */ opus_int nb_subfr; /* Number of 5 ms subframes in a frame */ opus_int frame_length; /* Frame length (samples) */ opus_int subfr_length; /* Subframe length (samples) */ opus_int ltp_mem_length; /* Length of LTP memory */ opus_int la_pitch; /* Look-ahead for pitch analysis (samples) */ opus_int la_shape; /* Look-ahead for noise shape analysis (samples) */ opus_int shapeWinLength; /* Window length for noise shape analysis (samples) */ opus_int32 TargetRate_bps; /* Target bitrate (bps) */ opus_int PacketSize_ms; /* Number of milliseconds to put in each packet */ opus_int PacketLoss_perc; /* Packet loss rate measured by farend */ opus_int32 frameCounter; opus_int Complexity; /* Complexity setting */ opus_int nStatesDelayedDecision; /* Number of states in delayed decision quantization */ opus_int useInterpolatedNLSFs; /* Flag for using NLSF interpolation */ opus_int shapingLPCOrder; /* Filter order for noise shaping filters */ opus_int predictLPCOrder; /* Filter order for prediction filters */ opus_int pitchEstimationComplexity; /* Complexity level for pitch estimator */ opus_int pitchEstimationLPCOrder; /* Whitening filter order for pitch estimator */ opus_int32 pitchEstimationThreshold_Q16; /* Threshold for pitch estimator */ opus_int32 sum_log_gain_Q7; /* Cumulative max prediction gain */ opus_int NLSF_MSVQ_Survivors; /* Number of survivors in NLSF MSVQ */ opus_int first_frame_after_reset; /* Flag for deactivating NLSF interpolation, pitch prediction */ opus_int controlled_since_last_payload; /* Flag for ensuring codec_control only runs once per packet */ opus_int warping_Q16; /* Warping parameter for warped noise shaping */ opus_int useCBR; /* Flag to enable constant bitrate */ opus_int prefillFlag; /* Flag to indicate that only buffers are prefilled, no coding */ const opus_uint8 *pitch_lag_low_bits_iCDF; /* Pointer to iCDF table for low bits of pitch lag index */ const opus_uint8 *pitch_contour_iCDF; /* Pointer to iCDF table for pitch contour index */ const silk_NLSF_CB_struct *psNLSF_CB; /* Pointer to NLSF codebook */ opus_int input_quality_bands_Q15[ VAD_N_BANDS ]; opus_int input_tilt_Q15; opus_int SNR_dB_Q7; /* Quality setting */ opus_int8 VAD_flags[ MAX_FRAMES_PER_PACKET ]; opus_int8 LBRR_flag; opus_int LBRR_flags[ MAX_FRAMES_PER_PACKET ]; SideInfoIndices indices; opus_int8 pulses[ MAX_FRAME_LENGTH ]; int arch; /* Input/output buffering */ opus_int16 inputBuf[ MAX_FRAME_LENGTH + 2 ]; /* Buffer containing input signal */ opus_int inputBufIx; opus_int nFramesPerPacket; opus_int nFramesEncoded; /* Number of frames analyzed in current packet */ opus_int nChannelsAPI; opus_int nChannelsInternal; opus_int channelNb; /* Parameters For LTP scaling Control */ opus_int frames_since_onset; /* Specifically for entropy coding */ opus_int ec_prevSignalType; opus_int16 ec_prevLagIndex; silk_resampler_state_struct resampler_state; /* DTX */ opus_int useDTX; /* Flag to enable DTX */ opus_int inDTX; /* Flag to signal DTX period */ opus_int noSpeechCounter; /* Counts concecutive nonactive frames, used by DTX */ /* Inband Low Bitrate Redundancy (LBRR) data */ opus_int useInBandFEC; /* Saves the API setting for query */ opus_int LBRR_enabled; /* Depends on useInBandFRC, bitrate and packet loss rate */ opus_int LBRR_GainIncreases; /* Gains increment for coding LBRR frames */ SideInfoIndices indices_LBRR[ MAX_FRAMES_PER_PACKET ]; opus_int8 pulses_LBRR[ MAX_FRAMES_PER_PACKET ][ MAX_FRAME_LENGTH ]; } silk_encoder_state; /* Struct for Packet Loss Concealment */ typedef struct { opus_int32 pitchL_Q8; /* Pitch lag to use for voiced concealment */ opus_int16 LTPCoef_Q14[ LTP_ORDER ]; /* LTP coefficients to use for voiced concealment */ opus_int16 prevLPC_Q12[ MAX_LPC_ORDER ]; opus_int last_frame_lost; /* Was previous frame lost */ opus_int32 rand_seed; /* Seed for unvoiced signal generation */ opus_int16 randScale_Q14; /* Scaling of unvoiced random signal */ opus_int32 conc_energy; opus_int conc_energy_shift; opus_int16 prevLTP_scale_Q14; opus_int32 prevGain_Q16[ 2 ]; opus_int fs_kHz; opus_int nb_subfr; opus_int subfr_length; } silk_PLC_struct; /* Struct for CNG */ typedef struct { opus_int32 CNG_exc_buf_Q14[ MAX_FRAME_LENGTH ]; opus_int16 CNG_smth_NLSF_Q15[ MAX_LPC_ORDER ]; opus_int32 CNG_synth_state[ MAX_LPC_ORDER ]; opus_int32 CNG_smth_Gain_Q16; opus_int32 rand_seed; opus_int fs_kHz; } silk_CNG_struct; /********************************/ /* Decoder state */ /********************************/ typedef struct { opus_int32 prev_gain_Q16; opus_int32 exc_Q14[ MAX_FRAME_LENGTH ]; opus_int32 sLPC_Q14_buf[ MAX_LPC_ORDER ]; opus_int16 outBuf[ MAX_FRAME_LENGTH + 2 * MAX_SUB_FRAME_LENGTH ]; /* Buffer for output signal */ opus_int lagPrev; /* Previous Lag */ opus_int8 LastGainIndex; /* Previous gain index */ opus_int fs_kHz; /* Sampling frequency in kHz */ opus_int32 fs_API_hz; /* API sample frequency (Hz) */ opus_int nb_subfr; /* Number of 5 ms subframes in a frame */ opus_int frame_length; /* Frame length (samples) */ opus_int subfr_length; /* Subframe length (samples) */ opus_int ltp_mem_length; /* Length of LTP memory */ opus_int LPC_order; /* LPC order */ opus_int16 prevNLSF_Q15[ MAX_LPC_ORDER ]; /* Used to interpolate LSFs */ opus_int first_frame_after_reset; /* Flag for deactivating NLSF interpolation */ const opus_uint8 *pitch_lag_low_bits_iCDF; /* Pointer to iCDF table for low bits of pitch lag index */ const opus_uint8 *pitch_contour_iCDF; /* Pointer to iCDF table for pitch contour index */ /* For buffering payload in case of more frames per packet */ opus_int nFramesDecoded; opus_int nFramesPerPacket; /* Specifically for entropy coding */ opus_int ec_prevSignalType; opus_int16 ec_prevLagIndex; opus_int VAD_flags[ MAX_FRAMES_PER_PACKET ]; opus_int LBRR_flag; opus_int LBRR_flags[ MAX_FRAMES_PER_PACKET ]; silk_resampler_state_struct resampler_state; const silk_NLSF_CB_struct *psNLSF_CB; /* Pointer to NLSF codebook */ /* Quantization indices */ SideInfoIndices indices; /* CNG state */ silk_CNG_struct sCNG; /* Stuff used for PLC */ opus_int lossCnt; opus_int prevSignalType; int arch; silk_PLC_struct sPLC; } silk_decoder_state; /************************/ /* Decoder control */ /************************/ typedef struct { /* Prediction and coding parameters */ opus_int pitchL[ MAX_NB_SUBFR ]; opus_int32 Gains_Q16[ MAX_NB_SUBFR ]; /* Holds interpolated and final coefficients, 4-byte aligned */ silk_DWORD_ALIGN opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ]; opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ]; opus_int LTP_scale_Q14; } silk_decoder_control; #ifdef __cplusplus } #endif #endif jamulus-3.9.1+dfsg/libs/opus/silk/bwexpander.c0000644000175000017500000000531014340334543020337 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FIX.h" /* Chirp (bandwidth expand) LP AR filter */ void silk_bwexpander( opus_int16 *ar, /* I/O AR filter to be expanded (without leading 1) */ const opus_int d, /* I Length of ar */ opus_int32 chirp_Q16 /* I Chirp factor (typically in the range 0 to 1) */ ) { opus_int i; opus_int32 chirp_minus_one_Q16 = chirp_Q16 - 65536; /* NB: Dont use silk_SMULWB, instead of silk_RSHIFT_ROUND( silk_MUL(), 16 ), below. */ /* Bias in silk_SMULWB can lead to unstable filters */ for( i = 0; i < d - 1; i++ ) { ar[ i ] = (opus_int16)silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, ar[ i ] ), 16 ); chirp_Q16 += silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, chirp_minus_one_Q16 ), 16 ); } ar[ d - 1 ] = (opus_int16)silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, ar[ d - 1 ] ), 16 ); } jamulus-3.9.1+dfsg/libs/opus/silk/decode_core.c0000644000175000017500000002717514340334543020450 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" #include "stack_alloc.h" /**********************************************************/ /* Core decoder. Performs inverse NSQ operation LTP + LPC */ /**********************************************************/ void silk_decode_core( silk_decoder_state *psDec, /* I/O Decoder state */ silk_decoder_control *psDecCtrl, /* I Decoder control */ opus_int16 xq[], /* O Decoded speech */ const opus_int16 pulses[ MAX_FRAME_LENGTH ], /* I Pulse signal */ int arch /* I Run-time architecture */ ) { opus_int i, k, lag = 0, start_idx, sLTP_buf_idx, NLSF_interpolation_flag, signalType; opus_int16 *A_Q12, *B_Q14, *pxq, A_Q12_tmp[ MAX_LPC_ORDER ]; VARDECL( opus_int16, sLTP ); VARDECL( opus_int32, sLTP_Q15 ); opus_int32 LTP_pred_Q13, LPC_pred_Q10, Gain_Q10, inv_gain_Q31, gain_adj_Q16, rand_seed, offset_Q10; opus_int32 *pred_lag_ptr, *pexc_Q14, *pres_Q14; VARDECL( opus_int32, res_Q14 ); VARDECL( opus_int32, sLPC_Q14 ); SAVE_STACK; silk_assert( psDec->prev_gain_Q16 != 0 ); ALLOC( sLTP, psDec->ltp_mem_length, opus_int16 ); ALLOC( sLTP_Q15, psDec->ltp_mem_length + psDec->frame_length, opus_int32 ); ALLOC( res_Q14, psDec->subfr_length, opus_int32 ); ALLOC( sLPC_Q14, psDec->subfr_length + MAX_LPC_ORDER, opus_int32 ); offset_Q10 = silk_Quantization_Offsets_Q10[ psDec->indices.signalType >> 1 ][ psDec->indices.quantOffsetType ]; if( psDec->indices.NLSFInterpCoef_Q2 < 1 << 2 ) { NLSF_interpolation_flag = 1; } else { NLSF_interpolation_flag = 0; } /* Decode excitation */ rand_seed = psDec->indices.Seed; for( i = 0; i < psDec->frame_length; i++ ) { rand_seed = silk_RAND( rand_seed ); psDec->exc_Q14[ i ] = silk_LSHIFT( (opus_int32)pulses[ i ], 14 ); if( psDec->exc_Q14[ i ] > 0 ) { psDec->exc_Q14[ i ] -= QUANT_LEVEL_ADJUST_Q10 << 4; } else if( psDec->exc_Q14[ i ] < 0 ) { psDec->exc_Q14[ i ] += QUANT_LEVEL_ADJUST_Q10 << 4; } psDec->exc_Q14[ i ] += offset_Q10 << 4; if( rand_seed < 0 ) { psDec->exc_Q14[ i ] = -psDec->exc_Q14[ i ]; } rand_seed = silk_ADD32_ovflw( rand_seed, pulses[ i ] ); } /* Copy LPC state */ silk_memcpy( sLPC_Q14, psDec->sLPC_Q14_buf, MAX_LPC_ORDER * sizeof( opus_int32 ) ); pexc_Q14 = psDec->exc_Q14; pxq = xq; sLTP_buf_idx = psDec->ltp_mem_length; /* Loop over subframes */ for( k = 0; k < psDec->nb_subfr; k++ ) { pres_Q14 = res_Q14; A_Q12 = psDecCtrl->PredCoef_Q12[ k >> 1 ]; /* Preload LPC coefficients to array on stack. Gives small performance gain */ silk_memcpy( A_Q12_tmp, A_Q12, psDec->LPC_order * sizeof( opus_int16 ) ); B_Q14 = &psDecCtrl->LTPCoef_Q14[ k * LTP_ORDER ]; signalType = psDec->indices.signalType; Gain_Q10 = silk_RSHIFT( psDecCtrl->Gains_Q16[ k ], 6 ); inv_gain_Q31 = silk_INVERSE32_varQ( psDecCtrl->Gains_Q16[ k ], 47 ); /* Calculate gain adjustment factor */ if( psDecCtrl->Gains_Q16[ k ] != psDec->prev_gain_Q16 ) { gain_adj_Q16 = silk_DIV32_varQ( psDec->prev_gain_Q16, psDecCtrl->Gains_Q16[ k ], 16 ); /* Scale short term state */ for( i = 0; i < MAX_LPC_ORDER; i++ ) { sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, sLPC_Q14[ i ] ); } } else { gain_adj_Q16 = (opus_int32)1 << 16; } /* Save inv_gain */ silk_assert( inv_gain_Q31 != 0 ); psDec->prev_gain_Q16 = psDecCtrl->Gains_Q16[ k ]; /* Avoid abrupt transition from voiced PLC to unvoiced normal decoding */ if( psDec->lossCnt && psDec->prevSignalType == TYPE_VOICED && psDec->indices.signalType != TYPE_VOICED && k < MAX_NB_SUBFR/2 ) { silk_memset( B_Q14, 0, LTP_ORDER * sizeof( opus_int16 ) ); B_Q14[ LTP_ORDER/2 ] = SILK_FIX_CONST( 0.25, 14 ); signalType = TYPE_VOICED; psDecCtrl->pitchL[ k ] = psDec->lagPrev; } if( signalType == TYPE_VOICED ) { /* Voiced */ lag = psDecCtrl->pitchL[ k ]; /* Re-whitening */ if( k == 0 || ( k == 2 && NLSF_interpolation_flag ) ) { /* Rewhiten with new A coefs */ start_idx = psDec->ltp_mem_length - lag - psDec->LPC_order - LTP_ORDER / 2; celt_assert( start_idx > 0 ); if( k == 2 ) { silk_memcpy( &psDec->outBuf[ psDec->ltp_mem_length ], xq, 2 * psDec->subfr_length * sizeof( opus_int16 ) ); } silk_LPC_analysis_filter( &sLTP[ start_idx ], &psDec->outBuf[ start_idx + k * psDec->subfr_length ], A_Q12, psDec->ltp_mem_length - start_idx, psDec->LPC_order, arch ); /* After rewhitening the LTP state is unscaled */ if( k == 0 ) { /* Do LTP downscaling to reduce inter-packet dependency */ inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, psDecCtrl->LTP_scale_Q14 ), 2 ); } for( i = 0; i < lag + LTP_ORDER/2; i++ ) { sLTP_Q15[ sLTP_buf_idx - i - 1 ] = silk_SMULWB( inv_gain_Q31, sLTP[ psDec->ltp_mem_length - i - 1 ] ); } } else { /* Update LTP state when Gain changes */ if( gain_adj_Q16 != (opus_int32)1 << 16 ) { for( i = 0; i < lag + LTP_ORDER/2; i++ ) { sLTP_Q15[ sLTP_buf_idx - i - 1 ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ sLTP_buf_idx - i - 1 ] ); } } } } /* Long-term prediction */ if( signalType == TYPE_VOICED ) { /* Set up pointer */ pred_lag_ptr = &sLTP_Q15[ sLTP_buf_idx - lag + LTP_ORDER / 2 ]; for( i = 0; i < psDec->subfr_length; i++ ) { /* Unrolled loop */ /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ LTP_pred_Q13 = 2; LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ 0 ], B_Q14[ 0 ] ); LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -1 ], B_Q14[ 1 ] ); LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -2 ], B_Q14[ 2 ] ); LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -3 ], B_Q14[ 3 ] ); LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -4 ], B_Q14[ 4 ] ); pred_lag_ptr++; /* Generate LPC excitation */ pres_Q14[ i ] = silk_ADD_LSHIFT32( pexc_Q14[ i ], LTP_pred_Q13, 1 ); /* Update states */ sLTP_Q15[ sLTP_buf_idx ] = silk_LSHIFT( pres_Q14[ i ], 1 ); sLTP_buf_idx++; } } else { pres_Q14 = pexc_Q14; } for( i = 0; i < psDec->subfr_length; i++ ) { /* Short-term prediction */ celt_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 ); /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ LPC_pred_Q10 = silk_RSHIFT( psDec->LPC_order, 1 ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 1 ], A_Q12_tmp[ 0 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 2 ], A_Q12_tmp[ 1 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 3 ], A_Q12_tmp[ 2 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 4 ], A_Q12_tmp[ 3 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 5 ], A_Q12_tmp[ 4 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 6 ], A_Q12_tmp[ 5 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 7 ], A_Q12_tmp[ 6 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 8 ], A_Q12_tmp[ 7 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 9 ], A_Q12_tmp[ 8 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 10 ], A_Q12_tmp[ 9 ] ); if( psDec->LPC_order == 16 ) { LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 11 ], A_Q12_tmp[ 10 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 12 ], A_Q12_tmp[ 11 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 13 ], A_Q12_tmp[ 12 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 14 ], A_Q12_tmp[ 13 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 15 ], A_Q12_tmp[ 14 ] ); LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 16 ], A_Q12_tmp[ 15 ] ); } /* Add prediction to LPC excitation */ sLPC_Q14[ MAX_LPC_ORDER + i ] = silk_ADD_SAT32( pres_Q14[ i ], silk_LSHIFT_SAT32( LPC_pred_Q10, 4 ) ); /* Scale with gain */ pxq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14[ MAX_LPC_ORDER + i ], Gain_Q10 ), 8 ) ); } /* Update LPC filter state */ silk_memcpy( sLPC_Q14, &sLPC_Q14[ psDec->subfr_length ], MAX_LPC_ORDER * sizeof( opus_int32 ) ); pexc_Q14 += psDec->subfr_length; pxq += psDec->subfr_length; } /* Save LPC state */ silk_memcpy( psDec->sLPC_Q14_buf, sLPC_Q14, MAX_LPC_ORDER * sizeof( opus_int32 ) ); RESTORE_STACK; } jamulus-3.9.1+dfsg/libs/opus/silk/pitch_est_tables.c0000644000175000017500000000700514340334543021517 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "typedef.h" #include "pitch_est_defines.h" const opus_int8 silk_CB_lags_stage2_10_ms[ PE_MAX_NB_SUBFR >> 1][ PE_NB_CBKS_STAGE2_10MS ] = { {0, 1, 0}, {0, 0, 1} }; const opus_int8 silk_CB_lags_stage3_10_ms[ PE_MAX_NB_SUBFR >> 1 ][ PE_NB_CBKS_STAGE3_10MS ] = { { 0, 0, 1,-1, 1,-1, 2,-2, 2,-2, 3,-3}, { 0, 1, 0, 1,-1, 2,-1, 2,-2, 3,-2, 3} }; const opus_int8 silk_Lag_range_stage3_10_ms[ PE_MAX_NB_SUBFR >> 1 ][ 2 ] = { {-3, 7}, {-2, 7} }; const opus_int8 silk_CB_lags_stage2[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE2_EXT ] = { {0, 2,-1,-1,-1, 0, 0, 1, 1, 0, 1}, {0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0}, {0,-1, 2, 1, 0, 1, 1, 0, 0,-1,-1} }; const opus_int8 silk_CB_lags_stage3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ] = { {0, 0, 1,-1, 0, 1,-1, 0,-1, 1,-2, 2,-2,-2, 2,-3, 2, 3,-3,-4, 3,-4, 4, 4,-5, 5,-6,-5, 6,-7, 6, 5, 8,-9}, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0,-1, 1, 0, 0, 1,-1, 0, 1,-1,-1, 1,-1, 2, 1,-1, 2,-2,-2, 2,-2, 2, 2, 3,-3}, {0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1,-1, 1, 0, 0, 2, 1,-1, 2,-1,-1, 2,-1, 2, 2,-1, 3,-2,-2,-2, 3}, {0, 1, 0, 0, 1, 0, 1,-1, 2,-1, 2,-1, 2, 3,-2, 3,-2,-2, 4, 4,-3, 5,-3,-4, 6,-4, 6, 5,-5, 8,-6,-5,-7, 9} }; const opus_int8 silk_Lag_range_stage3[ SILK_PE_MAX_COMPLEX + 1 ] [ PE_MAX_NB_SUBFR ][ 2 ] = { /* Lags to search for low number of stage3 cbks */ { {-5,8}, {-1,6}, {-1,6}, {-4,10} }, /* Lags to search for middle number of stage3 cbks */ { {-6,10}, {-2,6}, {-1,6}, {-5,10} }, /* Lags to search for max number of stage3 cbks */ { {-9,12}, {-3,7}, {-2,7}, {-7,13} } }; const opus_int8 silk_nb_cbk_searchs_stage3[ SILK_PE_MAX_COMPLEX + 1 ] = { PE_NB_CBKS_STAGE3_MIN, PE_NB_CBKS_STAGE3_MID, PE_NB_CBKS_STAGE3_MAX }; jamulus-3.9.1+dfsg/libs/opus/silk/arm/0000755000175000017500000000000014340334543016614 5ustar vimervimerjamulus-3.9.1+dfsg/libs/opus/silk/arm/NSQ_del_dec_arm.h0000644000175000017500000001255614340334543021735 0ustar vimervimer/*********************************************************************** Copyright (c) 2017 Google Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SILK_NSQ_DEL_DEC_ARM_H #define SILK_NSQ_DEL_DEC_ARM_H #include "celt/arm/armcpu.h" #if defined(OPUS_ARM_MAY_HAVE_NEON_INTR) void silk_NSQ_del_dec_neon( const silk_encoder_state *psEncC, silk_nsq_state *NSQ, SideInfoIndices *psIndices, const opus_int16 x16[], opus_int8 pulses[], const opus_int16 PredCoef_Q12[2 * MAX_LPC_ORDER], const opus_int16 LTPCoef_Q14[LTP_ORDER * MAX_NB_SUBFR], const opus_int16 AR_Q13[MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER], const opus_int HarmShapeGain_Q14[MAX_NB_SUBFR], const opus_int Tilt_Q14[MAX_NB_SUBFR], const opus_int32 LF_shp_Q14[MAX_NB_SUBFR], const opus_int32 Gains_Q16[MAX_NB_SUBFR], const opus_int pitchL[MAX_NB_SUBFR], const opus_int Lambda_Q10, const opus_int LTP_scale_Q14); #if !defined(OPUS_HAVE_RTCD) #define OVERRIDE_silk_NSQ_del_dec (1) #define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, \ LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, Tilt_Q14, \ LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, \ LTP_scale_Q14, arch) \ ((void)(arch), \ PRESUME_NEON(silk_NSQ_del_dec)( \ psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, \ AR_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, \ Lambda_Q10, LTP_scale_Q14)) #endif #endif #if !defined(OVERRIDE_silk_NSQ_del_dec) /*Is run-time CPU detection enabled on this platform?*/ #if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && \ !defined(OPUS_ARM_PRESUME_NEON_INTR)) extern void (*const SILK_NSQ_DEL_DEC_IMPL[OPUS_ARCHMASK + 1])( const silk_encoder_state *psEncC, silk_nsq_state *NSQ, SideInfoIndices *psIndices, const opus_int16 x16[], opus_int8 pulses[], const opus_int16 PredCoef_Q12[2 * MAX_LPC_ORDER], const opus_int16 LTPCoef_Q14[LTP_ORDER * MAX_NB_SUBFR], const opus_int16 AR_Q13[MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER], const opus_int HarmShapeGain_Q14[MAX_NB_SUBFR], const opus_int Tilt_Q14[MAX_NB_SUBFR], const opus_int32 LF_shp_Q14[MAX_NB_SUBFR], const opus_int32 Gains_Q16[MAX_NB_SUBFR], const opus_int pitchL[MAX_NB_SUBFR], const opus_int Lambda_Q10, const opus_int LTP_scale_Q14); #define OVERRIDE_silk_NSQ_del_dec (1) #define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, \ LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, Tilt_Q14, \ LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, \ LTP_scale_Q14, arch) \ ((*SILK_NSQ_DEL_DEC_IMPL[(arch)&OPUS_ARCHMASK])( \ psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, \ AR_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, \ Lambda_Q10, LTP_scale_Q14)) #elif defined(OPUS_ARM_PRESUME_NEON_INTR) #define OVERRIDE_silk_NSQ_del_dec (1) #define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, \ LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, Tilt_Q14, \ LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, \ LTP_scale_Q14, arch) \ ((void)(arch), \ silk_NSQ_del_dec_neon(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, \ LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, Tilt_Q14, \ LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, \ LTP_scale_Q14)) #endif #endif #endif /* end SILK_NSQ_DEL_DEC_ARM_H */ jamulus-3.9.1+dfsg/libs/opus/silk/arm/macros_arm64.h0000644000175000017500000000352614340334543021270 0ustar vimervimer/*********************************************************************** Copyright (C) 2015 Vidyo Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SILK_MACROS_ARM64_H #define SILK_MACROS_ARM64_H #include #undef silk_ADD_SAT32 #define silk_ADD_SAT32(a, b) (vqadds_s32((a), (b))) #undef silk_SUB_SAT32 #define silk_SUB_SAT32(a, b) (vqsubs_s32((a), (b))) #endif /* SILK_MACROS_ARM64_H */ jamulus-3.9.1+dfsg/libs/opus/silk/arm/SigProc_FIX_armv4.h0000644000175000017500000000402014340334543022146 0ustar vimervimer/*********************************************************************** Copyright (C) 2013 Xiph.Org Foundation and contributors Copyright (c) 2013 Parrot Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SILK_SIGPROC_FIX_ARMv4_H #define SILK_SIGPROC_FIX_ARMv4_H #undef silk_MLA static OPUS_INLINE opus_int32 silk_MLA_armv4(opus_int32 a, opus_int32 b, opus_int32 c) { opus_int32 res; __asm__( "#silk_MLA\n\t" "mla %0, %1, %2, %3\n\t" : "=&r"(res) : "r"(b), "r"(c), "r"(a) ); return res; } #define silk_MLA(a, b, c) (silk_MLA_armv4(a, b, c)) #endif jamulus-3.9.1+dfsg/libs/opus/silk/arm/biquad_alt_neon_intr.c0000644000175000017500000003007614340334543023146 0ustar vimervimer/*********************************************************************** Copyright (c) 2017 Google Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #ifdef OPUS_CHECK_ASM # include # include "stack_alloc.h" #endif #include "SigProc_FIX.h" static inline void silk_biquad_alt_stride2_kernel( const int32x4_t A_L_s32x4, const int32x4_t A_U_s32x4, const int32x4_t B_Q28_s32x4, const int32x2_t t_s32x2, const int32x4_t in_s32x4, int32x4_t *S_s32x4, int32x2_t *out32_Q14_s32x2 ) { int32x4_t t_s32x4, out32_Q14_s32x4; *out32_Q14_s32x2 = vadd_s32( vget_low_s32( *S_s32x4 ), t_s32x2 ); /* silk_SMLAWB( S{0,1}, B_Q28[ 0 ], in{0,1} ) */ *S_s32x4 = vcombine_s32( vget_high_s32( *S_s32x4 ), vdup_n_s32( 0 ) ); /* S{0,1} = S{2,3}; S{2,3} = 0; */ *out32_Q14_s32x2 = vshl_n_s32( *out32_Q14_s32x2, 2 ); /* out32_Q14_{0,1} = silk_LSHIFT( silk_SMLAWB( S{0,1}, B_Q28[ 0 ], in{0,1} ), 2 ); */ out32_Q14_s32x4 = vcombine_s32( *out32_Q14_s32x2, *out32_Q14_s32x2 ); /* out32_Q14_{0,1,0,1} */ t_s32x4 = vqdmulhq_s32( out32_Q14_s32x4, A_L_s32x4 ); /* silk_SMULWB( out32_Q14_{0,1,0,1}, A{0,0,1,1}_L_Q28 ) */ *S_s32x4 = vrsraq_n_s32( *S_s32x4, t_s32x4, 14 ); /* S{0,1} = S{2,3} + silk_RSHIFT_ROUND(); S{2,3} = silk_RSHIFT_ROUND(); */ t_s32x4 = vqdmulhq_s32( out32_Q14_s32x4, A_U_s32x4 ); /* silk_SMULWB( out32_Q14_{0,1,0,1}, A{0,0,1,1}_U_Q28 ) */ *S_s32x4 = vaddq_s32( *S_s32x4, t_s32x4 ); /* S0 = silk_SMLAWB( S{0,1,2,3}, out32_Q14_{0,1,0,1}, A{0,0,1,1}_U_Q28 ); */ t_s32x4 = vqdmulhq_s32( in_s32x4, B_Q28_s32x4 ); /* silk_SMULWB( B_Q28[ {1,1,2,2} ], in{0,1,0,1} ) */ *S_s32x4 = vaddq_s32( *S_s32x4, t_s32x4 ); /* S0 = silk_SMLAWB( S0, B_Q28[ {1,1,2,2} ], in{0,1,0,1} ); */ } void silk_biquad_alt_stride2_neon( const opus_int16 *in, /* I input signal */ const opus_int32 *B_Q28, /* I MA coefficients [3] */ const opus_int32 *A_Q28, /* I AR coefficients [2] */ opus_int32 *S, /* I/O State vector [4] */ opus_int16 *out, /* O output signal */ const opus_int32 len /* I signal length (must be even) */ ) { /* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */ opus_int k = 0; const int32x2_t offset_s32x2 = vdup_n_s32( (1<<14) - 1 ); const int32x4_t offset_s32x4 = vcombine_s32( offset_s32x2, offset_s32x2 ); int16x4_t in_s16x4 = vdup_n_s16( 0 ); int16x4_t out_s16x4; int32x2_t A_Q28_s32x2, A_L_s32x2, A_U_s32x2, B_Q28_s32x2, t_s32x2; int32x4_t A_L_s32x4, A_U_s32x4, B_Q28_s32x4, S_s32x4, out32_Q14_s32x4; int32x2x2_t t0_s32x2x2, t1_s32x2x2, t2_s32x2x2, S_s32x2x2; #ifdef OPUS_CHECK_ASM opus_int32 S_c[ 4 ]; VARDECL( opus_int16, out_c ); SAVE_STACK; ALLOC( out_c, 2 * len, opus_int16 ); silk_memcpy( &S_c, S, sizeof( S_c ) ); silk_biquad_alt_stride2_c( in, B_Q28, A_Q28, S_c, out_c, len ); #endif /* Negate A_Q28 values and split in two parts */ A_Q28_s32x2 = vld1_s32( A_Q28 ); A_Q28_s32x2 = vneg_s32( A_Q28_s32x2 ); A_L_s32x2 = vshl_n_s32( A_Q28_s32x2, 18 ); /* ( -A_Q28[] & 0x00003FFF ) << 18 */ A_L_s32x2 = vreinterpret_s32_u32( vshr_n_u32( vreinterpret_u32_s32( A_L_s32x2 ), 3 ) ); /* ( -A_Q28[] & 0x00003FFF ) << 15 */ A_U_s32x2 = vshr_n_s32( A_Q28_s32x2, 14 ); /* silk_RSHIFT( -A_Q28[], 14 ) */ A_U_s32x2 = vshl_n_s32( A_U_s32x2, 16 ); /* silk_RSHIFT( -A_Q28[], 14 ) << 16 (Clip two leading bits to conform to C function.) */ A_U_s32x2 = vshr_n_s32( A_U_s32x2, 1 ); /* silk_RSHIFT( -A_Q28[], 14 ) << 15 */ B_Q28_s32x2 = vld1_s32( B_Q28 ); t_s32x2 = vld1_s32( B_Q28 + 1 ); t0_s32x2x2 = vzip_s32( A_L_s32x2, A_L_s32x2 ); t1_s32x2x2 = vzip_s32( A_U_s32x2, A_U_s32x2 ); t2_s32x2x2 = vzip_s32( t_s32x2, t_s32x2 ); A_L_s32x4 = vcombine_s32( t0_s32x2x2.val[ 0 ], t0_s32x2x2.val[ 1 ] ); /* A{0,0,1,1}_L_Q28 */ A_U_s32x4 = vcombine_s32( t1_s32x2x2.val[ 0 ], t1_s32x2x2.val[ 1 ] ); /* A{0,0,1,1}_U_Q28 */ B_Q28_s32x4 = vcombine_s32( t2_s32x2x2.val[ 0 ], t2_s32x2x2.val[ 1 ] ); /* B_Q28[ {1,1,2,2} ] */ S_s32x4 = vld1q_s32( S ); /* S0 = S[ 0 ]; S3 = S[ 3 ]; */ S_s32x2x2 = vtrn_s32( vget_low_s32( S_s32x4 ), vget_high_s32( S_s32x4 ) ); /* S2 = S[ 1 ]; S1 = S[ 2 ]; */ S_s32x4 = vcombine_s32( S_s32x2x2.val[ 0 ], S_s32x2x2.val[ 1 ] ); for( ; k < len - 1; k += 2 ) { int32x4_t in_s32x4[ 2 ], t_s32x4; int32x2_t out32_Q14_s32x2[ 2 ]; /* S[ 2 * i + 0 ], S[ 2 * i + 1 ], S[ 2 * i + 2 ], S[ 2 * i + 3 ]: Q12 */ in_s16x4 = vld1_s16( &in[ 2 * k ] ); /* in{0,1,2,3} = in[ 2 * k + {0,1,2,3} ]; */ in_s32x4[ 0 ] = vshll_n_s16( in_s16x4, 15 ); /* in{0,1,2,3} << 15 */ t_s32x4 = vqdmulhq_lane_s32( in_s32x4[ 0 ], B_Q28_s32x2, 0 ); /* silk_SMULWB( B_Q28[ 0 ], in{0,1,2,3} ) */ in_s32x4[ 1 ] = vcombine_s32( vget_high_s32( in_s32x4[ 0 ] ), vget_high_s32( in_s32x4[ 0 ] ) ); /* in{2,3,2,3} << 15 */ in_s32x4[ 0 ] = vcombine_s32( vget_low_s32 ( in_s32x4[ 0 ] ), vget_low_s32 ( in_s32x4[ 0 ] ) ); /* in{0,1,0,1} << 15 */ silk_biquad_alt_stride2_kernel( A_L_s32x4, A_U_s32x4, B_Q28_s32x4, vget_low_s32 ( t_s32x4 ), in_s32x4[ 0 ], &S_s32x4, &out32_Q14_s32x2[ 0 ] ); silk_biquad_alt_stride2_kernel( A_L_s32x4, A_U_s32x4, B_Q28_s32x4, vget_high_s32( t_s32x4 ), in_s32x4[ 1 ], &S_s32x4, &out32_Q14_s32x2[ 1 ] ); /* Scale back to Q0 and saturate */ out32_Q14_s32x4 = vcombine_s32( out32_Q14_s32x2[ 0 ], out32_Q14_s32x2[ 1 ] ); /* out32_Q14_{0,1,2,3} */ out32_Q14_s32x4 = vaddq_s32( out32_Q14_s32x4, offset_s32x4 ); /* out32_Q14_{0,1,2,3} + (1<<14) - 1 */ out_s16x4 = vqshrn_n_s32( out32_Q14_s32x4, 14 ); /* (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14_{0,1,2,3} + (1<<14) - 1, 14 ) ) */ vst1_s16( &out[ 2 * k ], out_s16x4 ); /* out[ 2 * k + {0,1,2,3} ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14_{0,1,2,3} + (1<<14) - 1, 14 ) ); */ } /* Process leftover. */ if( k < len ) { int32x4_t in_s32x4; int32x2_t out32_Q14_s32x2; /* S[ 2 * i + 0 ], S[ 2 * i + 1 ]: Q12 */ in_s16x4 = vld1_lane_s16( &in[ 2 * k + 0 ], in_s16x4, 0 ); /* in{0,1} = in[ 2 * k + {0,1} ]; */ in_s16x4 = vld1_lane_s16( &in[ 2 * k + 1 ], in_s16x4, 1 ); /* in{0,1} = in[ 2 * k + {0,1} ]; */ in_s32x4 = vshll_n_s16( in_s16x4, 15 ); /* in{0,1} << 15 */ t_s32x2 = vqdmulh_lane_s32( vget_low_s32( in_s32x4 ), B_Q28_s32x2, 0 ); /* silk_SMULWB( B_Q28[ 0 ], in{0,1} ) */ in_s32x4 = vcombine_s32( vget_low_s32( in_s32x4 ), vget_low_s32( in_s32x4 ) ); /* in{0,1,0,1} << 15 */ silk_biquad_alt_stride2_kernel( A_L_s32x4, A_U_s32x4, B_Q28_s32x4, t_s32x2, in_s32x4, &S_s32x4, &out32_Q14_s32x2 ); /* Scale back to Q0 and saturate */ out32_Q14_s32x2 = vadd_s32( out32_Q14_s32x2, offset_s32x2 ); /* out32_Q14_{0,1} + (1<<14) - 1 */ out32_Q14_s32x4 = vcombine_s32( out32_Q14_s32x2, out32_Q14_s32x2 ); /* out32_Q14_{0,1,0,1} + (1<<14) - 1 */ out_s16x4 = vqshrn_n_s32( out32_Q14_s32x4, 14 ); /* (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14_{0,1,0,1} + (1<<14) - 1, 14 ) ) */ vst1_lane_s16( &out[ 2 * k + 0 ], out_s16x4, 0 ); /* out[ 2 * k + 0 ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14_0 + (1<<14) - 1, 14 ) ); */ vst1_lane_s16( &out[ 2 * k + 1 ], out_s16x4, 1 ); /* out[ 2 * k + 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14_1 + (1<<14) - 1, 14 ) ); */ } vst1q_lane_s32( &S[ 0 ], S_s32x4, 0 ); /* S[ 0 ] = S0; */ vst1q_lane_s32( &S[ 1 ], S_s32x4, 2 ); /* S[ 1 ] = S2; */ vst1q_lane_s32( &S[ 2 ], S_s32x4, 1 ); /* S[ 2 ] = S1; */ vst1q_lane_s32( &S[ 3 ], S_s32x4, 3 ); /* S[ 3 ] = S3; */ #ifdef OPUS_CHECK_ASM silk_assert( !memcmp( S_c, S, sizeof( S_c ) ) ); silk_assert( !memcmp( out_c, out, 2 * len * sizeof( opus_int16 ) ) ); RESTORE_STACK; #endif } jamulus-3.9.1+dfsg/libs/opus/silk/arm/SigProc_FIX_armv5e.h0000644000175000017500000000452614340334543022327 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Copyright (c) 2013 Parrot Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SILK_SIGPROC_FIX_ARMv5E_H #define SILK_SIGPROC_FIX_ARMv5E_H #undef silk_SMULTT static OPUS_INLINE opus_int32 silk_SMULTT_armv5e(opus_int32 a, opus_int32 b) { opus_int32 res; __asm__( "#silk_SMULTT\n\t" "smultt %0, %1, %2\n\t" : "=r"(res) : "%r"(a), "r"(b) ); return res; } #define silk_SMULTT(a, b) (silk_SMULTT_armv5e(a, b)) #undef silk_SMLATT static OPUS_INLINE opus_int32 silk_SMLATT_armv5e(opus_int32 a, opus_int32 b, opus_int32 c) { opus_int32 res; __asm__( "#silk_SMLATT\n\t" "smlatt %0, %1, %2, %3\n\t" : "=r"(res) : "%r"(b), "r"(c), "r"(a) ); return res; } #define silk_SMLATT(a, b, c) (silk_SMLATT_armv5e(a, b, c)) #endif jamulus-3.9.1+dfsg/libs/opus/silk/arm/LPC_inv_pred_gain_neon_intr.c0000644000175000017500000003063214340334543024341 0ustar vimervimer/*********************************************************************** Copyright (c) 2017 Google Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "SigProc_FIX.h" #include "define.h" #define QA 24 #define A_LIMIT SILK_FIX_CONST( 0.99975, QA ) #define MUL32_FRAC_Q(a32, b32, Q) ((opus_int32)(silk_RSHIFT_ROUND64(silk_SMULL(a32, b32), Q))) /* The difficulty is how to judge a 64-bit signed integer tmp64 is 32-bit overflowed, * since NEON has no 64-bit min, max or comparison instructions. * A failed idea is to compare the results of vmovn(tmp64) and vqmovn(tmp64) whether they are equal or not. * However, this idea fails when the tmp64 is something like 0xFFFFFFF980000000. * Here we know that mult2Q >= 1, so the highest bit (bit 63, sign bit) of tmp64 must equal to bit 62. * tmp64 was shifted left by 1 and we got tmp64'. If high_half(tmp64') != 0 and high_half(tmp64') != -1, * then we know that bit 31 to bit 63 of tmp64 can not all be the sign bit, and therefore tmp64 is 32-bit overflowed. * That is, we judge if tmp64' > 0x00000000FFFFFFFF, or tmp64' <= 0xFFFFFFFF00000000. * We use narrowing shift right 31 bits to tmp32' to save data bandwidth and instructions. * That is, we judge if tmp32' > 0x00000000, or tmp32' <= 0xFFFFFFFF. */ /* Compute inverse of LPC prediction gain, and */ /* test if LPC coefficients are stable (all poles within unit circle) */ static OPUS_INLINE opus_int32 LPC_inverse_pred_gain_QA_neon( /* O Returns inverse prediction gain in energy domain, Q30 */ opus_int32 A_QA[ SILK_MAX_ORDER_LPC ], /* I Prediction coefficients */ const opus_int order /* I Prediction order */ ) { opus_int k, n, mult2Q; opus_int32 invGain_Q30, rc_Q31, rc_mult1_Q30, rc_mult2, tmp1, tmp2; opus_int32 max, min; int32x4_t max_s32x4, min_s32x4; int32x2_t max_s32x2, min_s32x2; max_s32x4 = vdupq_n_s32( silk_int32_MIN ); min_s32x4 = vdupq_n_s32( silk_int32_MAX ); invGain_Q30 = SILK_FIX_CONST( 1, 30 ); for( k = order - 1; k > 0; k-- ) { int32x2_t rc_Q31_s32x2, rc_mult2_s32x2; int64x2_t mult2Q_s64x2; /* Check for stability */ if( ( A_QA[ k ] > A_LIMIT ) || ( A_QA[ k ] < -A_LIMIT ) ) { return 0; } /* Set RC equal to negated AR coef */ rc_Q31 = -silk_LSHIFT( A_QA[ k ], 31 - QA ); /* rc_mult1_Q30 range: [ 1 : 2^30 ] */ rc_mult1_Q30 = silk_SUB32( SILK_FIX_CONST( 1, 30 ), silk_SMMUL( rc_Q31, rc_Q31 ) ); silk_assert( rc_mult1_Q30 > ( 1 << 15 ) ); /* reduce A_LIMIT if fails */ silk_assert( rc_mult1_Q30 <= ( 1 << 30 ) ); /* Update inverse gain */ /* invGain_Q30 range: [ 0 : 2^30 ] */ invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 ); silk_assert( invGain_Q30 >= 0 ); silk_assert( invGain_Q30 <= ( 1 << 30 ) ); if( invGain_Q30 < SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN, 30 ) ) { return 0; } /* rc_mult2 range: [ 2^30 : silk_int32_MAX ] */ mult2Q = 32 - silk_CLZ32( silk_abs( rc_mult1_Q30 ) ); rc_mult2 = silk_INVERSE32_varQ( rc_mult1_Q30, mult2Q + 30 ); /* Update AR coefficient */ rc_Q31_s32x2 = vdup_n_s32( rc_Q31 ); mult2Q_s64x2 = vdupq_n_s64( -mult2Q ); rc_mult2_s32x2 = vdup_n_s32( rc_mult2 ); for( n = 0; n < ( ( k + 1 ) >> 1 ) - 3; n += 4 ) { /* We always calculate extra elements of A_QA buffer when ( k % 4 ) != 0, to take the advantage of SIMD parallelization. */ int32x4_t tmp1_s32x4, tmp2_s32x4, t0_s32x4, t1_s32x4, s0_s32x4, s1_s32x4, t_QA0_s32x4, t_QA1_s32x4; int64x2_t t0_s64x2, t1_s64x2, t2_s64x2, t3_s64x2; tmp1_s32x4 = vld1q_s32( A_QA + n ); tmp2_s32x4 = vld1q_s32( A_QA + k - n - 4 ); tmp2_s32x4 = vrev64q_s32( tmp2_s32x4 ); tmp2_s32x4 = vcombine_s32( vget_high_s32( tmp2_s32x4 ), vget_low_s32( tmp2_s32x4 ) ); t0_s32x4 = vqrdmulhq_lane_s32( tmp2_s32x4, rc_Q31_s32x2, 0 ); t1_s32x4 = vqrdmulhq_lane_s32( tmp1_s32x4, rc_Q31_s32x2, 0 ); t_QA0_s32x4 = vqsubq_s32( tmp1_s32x4, t0_s32x4 ); t_QA1_s32x4 = vqsubq_s32( tmp2_s32x4, t1_s32x4 ); t0_s64x2 = vmull_s32( vget_low_s32 ( t_QA0_s32x4 ), rc_mult2_s32x2 ); t1_s64x2 = vmull_s32( vget_high_s32( t_QA0_s32x4 ), rc_mult2_s32x2 ); t2_s64x2 = vmull_s32( vget_low_s32 ( t_QA1_s32x4 ), rc_mult2_s32x2 ); t3_s64x2 = vmull_s32( vget_high_s32( t_QA1_s32x4 ), rc_mult2_s32x2 ); t0_s64x2 = vrshlq_s64( t0_s64x2, mult2Q_s64x2 ); t1_s64x2 = vrshlq_s64( t1_s64x2, mult2Q_s64x2 ); t2_s64x2 = vrshlq_s64( t2_s64x2, mult2Q_s64x2 ); t3_s64x2 = vrshlq_s64( t3_s64x2, mult2Q_s64x2 ); t0_s32x4 = vcombine_s32( vmovn_s64( t0_s64x2 ), vmovn_s64( t1_s64x2 ) ); t1_s32x4 = vcombine_s32( vmovn_s64( t2_s64x2 ), vmovn_s64( t3_s64x2 ) ); s0_s32x4 = vcombine_s32( vshrn_n_s64( t0_s64x2, 31 ), vshrn_n_s64( t1_s64x2, 31 ) ); s1_s32x4 = vcombine_s32( vshrn_n_s64( t2_s64x2, 31 ), vshrn_n_s64( t3_s64x2, 31 ) ); max_s32x4 = vmaxq_s32( max_s32x4, s0_s32x4 ); min_s32x4 = vminq_s32( min_s32x4, s0_s32x4 ); max_s32x4 = vmaxq_s32( max_s32x4, s1_s32x4 ); min_s32x4 = vminq_s32( min_s32x4, s1_s32x4 ); t1_s32x4 = vrev64q_s32( t1_s32x4 ); t1_s32x4 = vcombine_s32( vget_high_s32( t1_s32x4 ), vget_low_s32( t1_s32x4 ) ); vst1q_s32( A_QA + n, t0_s32x4 ); vst1q_s32( A_QA + k - n - 4, t1_s32x4 ); } for( ; n < (k + 1) >> 1; n++ ) { opus_int64 tmp64; tmp1 = A_QA[ n ]; tmp2 = A_QA[ k - n - 1 ]; tmp64 = silk_RSHIFT_ROUND64( silk_SMULL( silk_SUB_SAT32(tmp1, MUL32_FRAC_Q( tmp2, rc_Q31, 31 ) ), rc_mult2 ), mult2Q); if( tmp64 > silk_int32_MAX || tmp64 < silk_int32_MIN ) { return 0; } A_QA[ n ] = ( opus_int32 )tmp64; tmp64 = silk_RSHIFT_ROUND64( silk_SMULL( silk_SUB_SAT32(tmp2, MUL32_FRAC_Q( tmp1, rc_Q31, 31 ) ), rc_mult2), mult2Q); if( tmp64 > silk_int32_MAX || tmp64 < silk_int32_MIN ) { return 0; } A_QA[ k - n - 1 ] = ( opus_int32 )tmp64; } } /* Check for stability */ if( ( A_QA[ k ] > A_LIMIT ) || ( A_QA[ k ] < -A_LIMIT ) ) { return 0; } max_s32x2 = vmax_s32( vget_low_s32( max_s32x4 ), vget_high_s32( max_s32x4 ) ); min_s32x2 = vmin_s32( vget_low_s32( min_s32x4 ), vget_high_s32( min_s32x4 ) ); max_s32x2 = vmax_s32( max_s32x2, vreinterpret_s32_s64( vshr_n_s64( vreinterpret_s64_s32( max_s32x2 ), 32 ) ) ); min_s32x2 = vmin_s32( min_s32x2, vreinterpret_s32_s64( vshr_n_s64( vreinterpret_s64_s32( min_s32x2 ), 32 ) ) ); max = vget_lane_s32( max_s32x2, 0 ); min = vget_lane_s32( min_s32x2, 0 ); if( ( max > 0 ) || ( min < -1 ) ) { return 0; } /* Set RC equal to negated AR coef */ rc_Q31 = -silk_LSHIFT( A_QA[ 0 ], 31 - QA ); /* Range: [ 1 : 2^30 ] */ rc_mult1_Q30 = silk_SUB32( SILK_FIX_CONST( 1, 30 ), silk_SMMUL( rc_Q31, rc_Q31 ) ); /* Update inverse gain */ /* Range: [ 0 : 2^30 ] */ invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 ); silk_assert( invGain_Q30 >= 0 ); silk_assert( invGain_Q30 <= ( 1 << 30 ) ); if( invGain_Q30 < SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN, 30 ) ) { return 0; } return invGain_Q30; } /* For input in Q12 domain */ opus_int32 silk_LPC_inverse_pred_gain_neon( /* O Returns inverse prediction gain in energy domain, Q30 */ const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */ const opus_int order /* I Prediction order */ ) { #ifdef OPUS_CHECK_ASM const opus_int32 invGain_Q30_c = silk_LPC_inverse_pred_gain_c( A_Q12, order ); #endif opus_int32 invGain_Q30; if( ( SILK_MAX_ORDER_LPC != 24 ) || ( order & 1 )) { invGain_Q30 = silk_LPC_inverse_pred_gain_c( A_Q12, order ); } else { opus_int32 Atmp_QA[ SILK_MAX_ORDER_LPC ]; opus_int32 DC_resp; int16x8_t t0_s16x8, t1_s16x8, t2_s16x8; int32x4_t t0_s32x4; const opus_int leftover = order & 7; /* Increase Q domain of the AR coefficients */ t0_s16x8 = vld1q_s16( A_Q12 + 0 ); t1_s16x8 = vld1q_s16( A_Q12 + 8 ); t2_s16x8 = vld1q_s16( A_Q12 + 16 ); t0_s32x4 = vpaddlq_s16( t0_s16x8 ); switch( order - leftover ) { case 24: t0_s32x4 = vpadalq_s16( t0_s32x4, t2_s16x8 ); /* FALLTHROUGH */ case 16: t0_s32x4 = vpadalq_s16( t0_s32x4, t1_s16x8 ); vst1q_s32( Atmp_QA + 16, vshll_n_s16( vget_low_s16 ( t2_s16x8 ), QA - 12 ) ); vst1q_s32( Atmp_QA + 20, vshll_n_s16( vget_high_s16( t2_s16x8 ), QA - 12 ) ); /* FALLTHROUGH */ case 8: { const int32x2_t t_s32x2 = vpadd_s32( vget_low_s32( t0_s32x4 ), vget_high_s32( t0_s32x4 ) ); const int64x1_t t_s64x1 = vpaddl_s32( t_s32x2 ); DC_resp = vget_lane_s32( vreinterpret_s32_s64( t_s64x1 ), 0 ); vst1q_s32( Atmp_QA + 8, vshll_n_s16( vget_low_s16 ( t1_s16x8 ), QA - 12 ) ); vst1q_s32( Atmp_QA + 12, vshll_n_s16( vget_high_s16( t1_s16x8 ), QA - 12 ) ); } break; default: DC_resp = 0; break; } A_Q12 += order - leftover; switch( leftover ) { case 6: DC_resp += (opus_int32)A_Q12[ 5 ]; DC_resp += (opus_int32)A_Q12[ 4 ]; /* FALLTHROUGH */ case 4: DC_resp += (opus_int32)A_Q12[ 3 ]; DC_resp += (opus_int32)A_Q12[ 2 ]; /* FALLTHROUGH */ case 2: DC_resp += (opus_int32)A_Q12[ 1 ]; DC_resp += (opus_int32)A_Q12[ 0 ]; /* FALLTHROUGH */ default: break; } /* If the DC is unstable, we don't even need to do the full calculations */ if( DC_resp >= 4096 ) { invGain_Q30 = 0; } else { vst1q_s32( Atmp_QA + 0, vshll_n_s16( vget_low_s16 ( t0_s16x8 ), QA - 12 ) ); vst1q_s32( Atmp_QA + 4, vshll_n_s16( vget_high_s16( t0_s16x8 ), QA - 12 ) ); invGain_Q30 = LPC_inverse_pred_gain_QA_neon( Atmp_QA, order ); } } #ifdef OPUS_CHECK_ASM silk_assert( invGain_Q30_c == invGain_Q30 ); #endif return invGain_Q30; } jamulus-3.9.1+dfsg/libs/opus/silk/arm/macros_armv5e.h0000644000175000017500000001416714340334543021541 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Copyright (c) 2013 Parrot Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SILK_MACROS_ARMv5E_H #define SILK_MACROS_ARMv5E_H /* This macro only avoids the undefined behaviour from a left shift of a negative value. It should only be used in macros that can't include SigProc_FIX.h. In other cases, use silk_LSHIFT32(). */ #define SAFE_SHL(a,b) ((opus_int32)((opus_uint32)(a) << (b))) /* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */ #undef silk_SMULWB static OPUS_INLINE opus_int32 silk_SMULWB_armv5e(opus_int32 a, opus_int16 b) { int res; __asm__( "#silk_SMULWB\n\t" "smulwb %0, %1, %2\n\t" : "=r"(res) : "r"(a), "r"(b) ); return res; } #define silk_SMULWB(a, b) (silk_SMULWB_armv5e(a, b)) /* a32 + (b32 * (opus_int32)((opus_int16)(c32))) >> 16 output have to be 32bit int */ #undef silk_SMLAWB static OPUS_INLINE opus_int32 silk_SMLAWB_armv5e(opus_int32 a, opus_int32 b, opus_int16 c) { int res; __asm__( "#silk_SMLAWB\n\t" "smlawb %0, %1, %2, %3\n\t" : "=r"(res) : "r"(b), "r"(c), "r"(a) ); return res; } #define silk_SMLAWB(a, b, c) (silk_SMLAWB_armv5e(a, b, c)) /* (a32 * (b32 >> 16)) >> 16 */ #undef silk_SMULWT static OPUS_INLINE opus_int32 silk_SMULWT_armv5e(opus_int32 a, opus_int32 b) { int res; __asm__( "#silk_SMULWT\n\t" "smulwt %0, %1, %2\n\t" : "=r"(res) : "r"(a), "r"(b) ); return res; } #define silk_SMULWT(a, b) (silk_SMULWT_armv5e(a, b)) /* a32 + (b32 * (c32 >> 16)) >> 16 */ #undef silk_SMLAWT static OPUS_INLINE opus_int32 silk_SMLAWT_armv5e(opus_int32 a, opus_int32 b, opus_int32 c) { int res; __asm__( "#silk_SMLAWT\n\t" "smlawt %0, %1, %2, %3\n\t" : "=r"(res) : "r"(b), "r"(c), "r"(a) ); return res; } #define silk_SMLAWT(a, b, c) (silk_SMLAWT_armv5e(a, b, c)) /* (opus_int32)((opus_int16)(a3))) * (opus_int32)((opus_int16)(b32)) output have to be 32bit int */ #undef silk_SMULBB static OPUS_INLINE opus_int32 silk_SMULBB_armv5e(opus_int32 a, opus_int32 b) { int res; __asm__( "#silk_SMULBB\n\t" "smulbb %0, %1, %2\n\t" : "=r"(res) : "%r"(a), "r"(b) ); return res; } #define silk_SMULBB(a, b) (silk_SMULBB_armv5e(a, b)) /* a32 + (opus_int32)((opus_int16)(b32)) * (opus_int32)((opus_int16)(c32)) output have to be 32bit int */ #undef silk_SMLABB static OPUS_INLINE opus_int32 silk_SMLABB_armv5e(opus_int32 a, opus_int32 b, opus_int32 c) { int res; __asm__( "#silk_SMLABB\n\t" "smlabb %0, %1, %2, %3\n\t" : "=r"(res) : "%r"(b), "r"(c), "r"(a) ); return res; } #define silk_SMLABB(a, b, c) (silk_SMLABB_armv5e(a, b, c)) /* (opus_int32)((opus_int16)(a32)) * (b32 >> 16) */ #undef silk_SMULBT static OPUS_INLINE opus_int32 silk_SMULBT_armv5e(opus_int32 a, opus_int32 b) { int res; __asm__( "#silk_SMULBT\n\t" "smulbt %0, %1, %2\n\t" : "=r"(res) : "r"(a), "r"(b) ); return res; } #define silk_SMULBT(a, b) (silk_SMULBT_armv5e(a, b)) /* a32 + (opus_int32)((opus_int16)(b32)) * (c32 >> 16) */ #undef silk_SMLABT static OPUS_INLINE opus_int32 silk_SMLABT_armv5e(opus_int32 a, opus_int32 b, opus_int32 c) { int res; __asm__( "#silk_SMLABT\n\t" "smlabt %0, %1, %2, %3\n\t" : "=r"(res) : "r"(b), "r"(c), "r"(a) ); return res; } #define silk_SMLABT(a, b, c) (silk_SMLABT_armv5e(a, b, c)) /* add/subtract with output saturated */ #undef silk_ADD_SAT32 static OPUS_INLINE opus_int32 silk_ADD_SAT32_armv5e(opus_int32 a, opus_int32 b) { int res; __asm__( "#silk_ADD_SAT32\n\t" "qadd %0, %1, %2\n\t" : "=r"(res) : "%r"(a), "r"(b) ); return res; } #define silk_ADD_SAT32(a, b) (silk_ADD_SAT32_armv5e(a, b)) #undef silk_SUB_SAT32 static OPUS_INLINE opus_int32 silk_SUB_SAT32_armv5e(opus_int32 a, opus_int32 b) { int res; __asm__( "#silk_SUB_SAT32\n\t" "qsub %0, %1, %2\n\t" : "=r"(res) : "r"(a), "r"(b) ); return res; } #define silk_SUB_SAT32(a, b) (silk_SUB_SAT32_armv5e(a, b)) #undef silk_CLZ16 static OPUS_INLINE opus_int32 silk_CLZ16_armv5(opus_int16 in16) { int res; __asm__( "#silk_CLZ16\n\t" "clz %0, %1;\n" : "=r"(res) : "r"(SAFE_SHL(in16,16)|0x8000) ); return res; } #define silk_CLZ16(in16) (silk_CLZ16_armv5(in16)) #undef silk_CLZ32 static OPUS_INLINE opus_int32 silk_CLZ32_armv5(opus_int32 in32) { int res; __asm__( "#silk_CLZ32\n\t" "clz %0, %1\n\t" : "=r"(res) : "r"(in32) ); return res; } #define silk_CLZ32(in32) (silk_CLZ32_armv5(in32)) #undef SAFE_SHL #endif /* SILK_MACROS_ARMv5E_H */ jamulus-3.9.1+dfsg/libs/opus/silk/arm/NSQ_neon.c0000644000175000017500000001130014340334543020433 0ustar vimervimer/*********************************************************************** Copyright (C) 2014 Vidyo Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "main.h" #include "stack_alloc.h" #include "NSQ.h" #include "celt/cpu_support.h" #include "celt/arm/armcpu.h" opus_int32 silk_noise_shape_quantizer_short_prediction_neon(const opus_int32 *buf32, const opus_int32 *coef32, opus_int order) { int32x4_t coef0 = vld1q_s32(coef32); int32x4_t coef1 = vld1q_s32(coef32 + 4); int32x4_t coef2 = vld1q_s32(coef32 + 8); int32x4_t coef3 = vld1q_s32(coef32 + 12); int32x4_t a0 = vld1q_s32(buf32 - 15); int32x4_t a1 = vld1q_s32(buf32 - 11); int32x4_t a2 = vld1q_s32(buf32 - 7); int32x4_t a3 = vld1q_s32(buf32 - 3); int32x4_t b0 = vqdmulhq_s32(coef0, a0); int32x4_t b1 = vqdmulhq_s32(coef1, a1); int32x4_t b2 = vqdmulhq_s32(coef2, a2); int32x4_t b3 = vqdmulhq_s32(coef3, a3); int32x4_t c0 = vaddq_s32(b0, b1); int32x4_t c1 = vaddq_s32(b2, b3); int32x4_t d = vaddq_s32(c0, c1); int64x2_t e = vpaddlq_s32(d); int64x1_t f = vadd_s64(vget_low_s64(e), vget_high_s64(e)); opus_int32 out = vget_lane_s32(vreinterpret_s32_s64(f), 0); out += silk_RSHIFT( order, 1 ); return out; } opus_int32 silk_NSQ_noise_shape_feedback_loop_neon(const opus_int32 *data0, opus_int32 *data1, const opus_int16 *coef, opus_int order) { opus_int32 out; if (order == 8) { int32x4_t a00 = vdupq_n_s32(data0[0]); int32x4_t a01 = vld1q_s32(data1); /* data1[0] ... [3] */ int32x4_t a0 = vextq_s32 (a00, a01, 3); /* data0[0] data1[0] ...[2] */ int32x4_t a1 = vld1q_s32(data1 + 3); /* data1[3] ... [6] */ /*TODO: Convert these once in advance instead of once per sample, like silk_noise_shape_quantizer_short_prediction_neon() does.*/ int16x8_t coef16 = vld1q_s16(coef); int32x4_t coef0 = vmovl_s16(vget_low_s16(coef16)); int32x4_t coef1 = vmovl_s16(vget_high_s16(coef16)); /*This is not bit-exact with the C version, since we do not drop the lower 16 bits of each multiply, but wait until the end to truncate precision. This is an encoder-specific calculation (and unlike silk_noise_shape_quantizer_short_prediction_neon(), is not meant to simulate what the decoder will do). We still could use vqdmulhq_s32() like silk_noise_shape_quantizer_short_prediction_neon() and save half the multiplies, but the speed difference is not large, since we then need two extra adds.*/ int64x2_t b0 = vmull_s32(vget_low_s32(a0), vget_low_s32(coef0)); int64x2_t b1 = vmlal_s32(b0, vget_high_s32(a0), vget_high_s32(coef0)); int64x2_t b2 = vmlal_s32(b1, vget_low_s32(a1), vget_low_s32(coef1)); int64x2_t b3 = vmlal_s32(b2, vget_high_s32(a1), vget_high_s32(coef1)); int64x1_t c = vadd_s64(vget_low_s64(b3), vget_high_s64(b3)); int64x1_t cS = vrshr_n_s64(c, 15); int32x2_t d = vreinterpret_s32_s64(cS); out = vget_lane_s32(d, 0); vst1q_s32(data1, a0); vst1q_s32(data1 + 4, a1); return out; } return silk_NSQ_noise_shape_feedback_loop_c(data0, data1, coef, order); } jamulus-3.9.1+dfsg/libs/opus/silk/arm/LPC_inv_pred_gain_arm.h0000644000175000017500000000625314340334543023134 0ustar vimervimer/*********************************************************************** Copyright (c) 2017 Google Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SILK_LPC_INV_PRED_GAIN_ARM_H # define SILK_LPC_INV_PRED_GAIN_ARM_H # include "celt/arm/armcpu.h" # if defined(OPUS_ARM_MAY_HAVE_NEON_INTR) opus_int32 silk_LPC_inverse_pred_gain_neon( /* O Returns inverse prediction gain in energy domain, Q30 */ const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */ const opus_int order /* I Prediction order */ ); # if !defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_PRESUME_NEON) # define OVERRIDE_silk_LPC_inverse_pred_gain (1) # define silk_LPC_inverse_pred_gain(A_Q12, order, arch) ((void)(arch), PRESUME_NEON(silk_LPC_inverse_pred_gain)(A_Q12, order)) # endif # endif # if !defined(OVERRIDE_silk_LPC_inverse_pred_gain) /*Is run-time CPU detection enabled on this platform?*/ # if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR)) extern opus_int32 (*const SILK_LPC_INVERSE_PRED_GAIN_IMPL[OPUS_ARCHMASK+1])(const opus_int16 *A_Q12, const opus_int order); # define OVERRIDE_silk_LPC_inverse_pred_gain (1) # define silk_LPC_inverse_pred_gain(A_Q12, order, arch) ((*SILK_LPC_INVERSE_PRED_GAIN_IMPL[(arch)&OPUS_ARCHMASK])(A_Q12, order)) # elif defined(OPUS_ARM_PRESUME_NEON_INTR) # define OVERRIDE_silk_LPC_inverse_pred_gain (1) # define silk_LPC_inverse_pred_gain(A_Q12, order, arch) ((void)(arch), silk_LPC_inverse_pred_gain_neon(A_Q12, order)) # endif # endif #endif /* end SILK_LPC_INV_PRED_GAIN_ARM_H */ jamulus-3.9.1+dfsg/libs/opus/silk/arm/biquad_alt_arm.h0000644000175000017500000001051614340334543021734 0ustar vimervimer/*********************************************************************** Copyright (c) 2017 Google Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SILK_BIQUAD_ALT_ARM_H # define SILK_BIQUAD_ALT_ARM_H # include "celt/arm/armcpu.h" # if defined(OPUS_ARM_MAY_HAVE_NEON_INTR) void silk_biquad_alt_stride2_neon( const opus_int16 *in, /* I input signal */ const opus_int32 *B_Q28, /* I MA coefficients [3] */ const opus_int32 *A_Q28, /* I AR coefficients [2] */ opus_int32 *S, /* I/O State vector [4] */ opus_int16 *out, /* O output signal */ const opus_int32 len /* I signal length (must be even) */ ); # if !defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_PRESUME_NEON) # define OVERRIDE_silk_biquad_alt_stride2 (1) # define silk_biquad_alt_stride2(in, B_Q28, A_Q28, S, out, len, arch) ((void)(arch), PRESUME_NEON(silk_biquad_alt_stride2)(in, B_Q28, A_Q28, S, out, len)) # endif # endif # if !defined(OVERRIDE_silk_biquad_alt_stride2) /*Is run-time CPU detection enabled on this platform?*/ # if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR)) extern void (*const SILK_BIQUAD_ALT_STRIDE2_IMPL[OPUS_ARCHMASK+1])( const opus_int16 *in, /* I input signal */ const opus_int32 *B_Q28, /* I MA coefficients [3] */ const opus_int32 *A_Q28, /* I AR coefficients [2] */ opus_int32 *S, /* I/O State vector [4] */ opus_int16 *out, /* O output signal */ const opus_int32 len /* I signal length (must be even) */ ); # define OVERRIDE_silk_biquad_alt_stride2 (1) # define silk_biquad_alt_stride2(in, B_Q28, A_Q28, S, out, len, arch) ((*SILK_BIQUAD_ALT_STRIDE2_IMPL[(arch)&OPUS_ARCHMASK])(in, B_Q28, A_Q28, S, out, len)) # elif defined(OPUS_ARM_PRESUME_NEON_INTR) # define OVERRIDE_silk_biquad_alt_stride2 (1) # define silk_biquad_alt_stride2(in, B_Q28, A_Q28, S, out, len, arch) ((void)(arch), silk_biquad_alt_stride2_neon(in, B_Q28, A_Q28, S, out, len)) # endif # endif #endif /* end SILK_BIQUAD_ALT_ARM_H */ jamulus-3.9.1+dfsg/libs/opus/silk/arm/NSQ_neon.h0000644000175000017500000001157714340334543020460 0ustar vimervimer/*********************************************************************** Copyright (C) 2014 Vidyo Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SILK_NSQ_NEON_H #define SILK_NSQ_NEON_H #include "cpu_support.h" #include "SigProc_FIX.h" #undef silk_short_prediction_create_arch_coef /* For vectorized calc, reverse a_Q12 coefs, convert to 32-bit, and shift for vqdmulhq_s32. */ static OPUS_INLINE void silk_short_prediction_create_arch_coef_neon(opus_int32 *out, const opus_int16 *in, opus_int order) { out[15] = silk_LSHIFT32(in[0], 15); out[14] = silk_LSHIFT32(in[1], 15); out[13] = silk_LSHIFT32(in[2], 15); out[12] = silk_LSHIFT32(in[3], 15); out[11] = silk_LSHIFT32(in[4], 15); out[10] = silk_LSHIFT32(in[5], 15); out[9] = silk_LSHIFT32(in[6], 15); out[8] = silk_LSHIFT32(in[7], 15); out[7] = silk_LSHIFT32(in[8], 15); out[6] = silk_LSHIFT32(in[9], 15); if (order == 16) { out[5] = silk_LSHIFT32(in[10], 15); out[4] = silk_LSHIFT32(in[11], 15); out[3] = silk_LSHIFT32(in[12], 15); out[2] = silk_LSHIFT32(in[13], 15); out[1] = silk_LSHIFT32(in[14], 15); out[0] = silk_LSHIFT32(in[15], 15); } else { out[5] = 0; out[4] = 0; out[3] = 0; out[2] = 0; out[1] = 0; out[0] = 0; } } #if defined(OPUS_ARM_PRESUME_NEON_INTR) #define silk_short_prediction_create_arch_coef(out, in, order) \ (silk_short_prediction_create_arch_coef_neon(out, in, order)) #elif defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_MAY_HAVE_NEON_INTR) #define silk_short_prediction_create_arch_coef(out, in, order) \ do { if (arch == OPUS_ARCH_ARM_NEON) { silk_short_prediction_create_arch_coef_neon(out, in, order); } } while (0) #endif opus_int32 silk_noise_shape_quantizer_short_prediction_neon(const opus_int32 *buf32, const opus_int32 *coef32, opus_int order); opus_int32 silk_NSQ_noise_shape_feedback_loop_neon(const opus_int32 *data0, opus_int32 *data1, const opus_int16 *coef, opus_int order); #if defined(OPUS_ARM_PRESUME_NEON_INTR) #undef silk_noise_shape_quantizer_short_prediction #define silk_noise_shape_quantizer_short_prediction(in, coef, coefRev, order, arch) \ ((void)arch,silk_noise_shape_quantizer_short_prediction_neon(in, coefRev, order)) #undef silk_NSQ_noise_shape_feedback_loop #define silk_NSQ_noise_shape_feedback_loop(data0, data1, coef, order, arch) ((void)arch,silk_NSQ_noise_shape_feedback_loop_neon(data0, data1, coef, order)) #elif defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_MAY_HAVE_NEON_INTR) /* silk_noise_shape_quantizer_short_prediction implementations take different parameters based on arch (coef vs. coefRev) so can't use the usual IMPL table implementation */ #undef silk_noise_shape_quantizer_short_prediction #define silk_noise_shape_quantizer_short_prediction(in, coef, coefRev, order, arch) \ (arch == OPUS_ARCH_ARM_NEON ? \ silk_noise_shape_quantizer_short_prediction_neon(in, coefRev, order) : \ silk_noise_shape_quantizer_short_prediction_c(in, coef, order)) extern opus_int32 (*const SILK_NSQ_NOISE_SHAPE_FEEDBACK_LOOP_IMPL[OPUS_ARCHMASK+1])( const opus_int32 *data0, opus_int32 *data1, const opus_int16 *coef, opus_int order); #undef silk_NSQ_noise_shape_feedback_loop #define silk_NSQ_noise_shape_feedback_loop(data0, data1, coef, order, arch) \ (SILK_NSQ_NOISE_SHAPE_FEEDBACK_LOOP_IMPL[(arch)&OPUS_ARCHMASK](data0, data1, \ coef, order)) #endif #endif /* SILK_NSQ_NEON_H */ jamulus-3.9.1+dfsg/libs/opus/silk/arm/macros_armv4.h0000644000175000017500000000737314340334543021374 0ustar vimervimer/*********************************************************************** Copyright (C) 2013 Xiph.Org Foundation and contributors. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifndef SILK_MACROS_ARMv4_H #define SILK_MACROS_ARMv4_H /* This macro only avoids the undefined behaviour from a left shift of a negative value. It should only be used in macros that can't include SigProc_FIX.h. In other cases, use silk_LSHIFT32(). */ #define SAFE_SHL(a,b) ((opus_int32)((opus_uint32)(a) << (b))) /* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */ #undef silk_SMULWB static OPUS_INLINE opus_int32 silk_SMULWB_armv4(opus_int32 a, opus_int16 b) { unsigned rd_lo; int rd_hi; __asm__( "#silk_SMULWB\n\t" "smull %0, %1, %2, %3\n\t" : "=&r"(rd_lo), "=&r"(rd_hi) : "%r"(a), "r"(SAFE_SHL(b,16)) ); return rd_hi; } #define silk_SMULWB(a, b) (silk_SMULWB_armv4(a, b)) /* a32 + (b32 * (opus_int32)((opus_int16)(c32))) >> 16 output have to be 32bit int */ #undef silk_SMLAWB #define silk_SMLAWB(a, b, c) ((a) + silk_SMULWB(b, c)) /* (a32 * (b32 >> 16)) >> 16 */ #undef silk_SMULWT static OPUS_INLINE opus_int32 silk_SMULWT_armv4(opus_int32 a, opus_int32 b) { unsigned rd_lo; int rd_hi; __asm__( "#silk_SMULWT\n\t" "smull %0, %1, %2, %3\n\t" : "=&r"(rd_lo), "=&r"(rd_hi) : "%r"(a), "r"(b&~0xFFFF) ); return rd_hi; } #define silk_SMULWT(a, b) (silk_SMULWT_armv4(a, b)) /* a32 + (b32 * (c32 >> 16)) >> 16 */ #undef silk_SMLAWT #define silk_SMLAWT(a, b, c) ((a) + silk_SMULWT(b, c)) /* (a32 * b32) >> 16 */ #undef silk_SMULWW static OPUS_INLINE opus_int32 silk_SMULWW_armv4(opus_int32 a, opus_int32 b) { unsigned rd_lo; int rd_hi; __asm__( "#silk_SMULWW\n\t" "smull %0, %1, %2, %3\n\t" : "=&r"(rd_lo), "=&r"(rd_hi) : "%r"(a), "r"(b) ); return SAFE_SHL(rd_hi,16)+(rd_lo>>16); } #define silk_SMULWW(a, b) (silk_SMULWW_armv4(a, b)) #undef silk_SMLAWW static OPUS_INLINE opus_int32 silk_SMLAWW_armv4(opus_int32 a, opus_int32 b, opus_int32 c) { unsigned rd_lo; int rd_hi; __asm__( "#silk_SMLAWW\n\t" "smull %0, %1, %2, %3\n\t" : "=&r"(rd_lo), "=&r"(rd_hi) : "%r"(b), "r"(c) ); return a+SAFE_SHL(rd_hi,16)+(rd_lo>>16); } #define silk_SMLAWW(a, b, c) (silk_SMLAWW_armv4(a, b, c)) #undef SAFE_SHL #endif /* SILK_MACROS_ARMv4_H */ jamulus-3.9.1+dfsg/libs/opus/silk/arm/arm_silk_map.c0000644000175000017500000001674214340334543021430 0ustar vimervimer/*********************************************************************** Copyright (C) 2014 Vidyo Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "main_FIX.h" #include "NSQ.h" #include "SigProc_FIX.h" #if defined(OPUS_HAVE_RTCD) # if (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && \ !defined(OPUS_ARM_PRESUME_NEON_INTR)) void (*const SILK_BIQUAD_ALT_STRIDE2_IMPL[OPUS_ARCHMASK + 1])( const opus_int16 *in, /* I input signal */ const opus_int32 *B_Q28, /* I MA coefficients [3] */ const opus_int32 *A_Q28, /* I AR coefficients [2] */ opus_int32 *S, /* I/O State vector [4] */ opus_int16 *out, /* O output signal */ const opus_int32 len /* I signal length (must be even) */ ) = { silk_biquad_alt_stride2_c, /* ARMv4 */ silk_biquad_alt_stride2_c, /* EDSP */ silk_biquad_alt_stride2_c, /* Media */ silk_biquad_alt_stride2_neon, /* Neon */ }; opus_int32 (*const SILK_LPC_INVERSE_PRED_GAIN_IMPL[OPUS_ARCHMASK + 1])( /* O Returns inverse prediction gain in energy domain, Q30 */ const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */ const opus_int order /* I Prediction order */ ) = { silk_LPC_inverse_pred_gain_c, /* ARMv4 */ silk_LPC_inverse_pred_gain_c, /* EDSP */ silk_LPC_inverse_pred_gain_c, /* Media */ silk_LPC_inverse_pred_gain_neon, /* Neon */ }; void (*const SILK_NSQ_DEL_DEC_IMPL[OPUS_ARCHMASK + 1])( const silk_encoder_state *psEncC, /* I Encoder State */ silk_nsq_state *NSQ, /* I/O NSQ state */ SideInfoIndices *psIndices, /* I/O Quantization Indices */ const opus_int16 x16[], /* I Input */ opus_int8 pulses[], /* O Quantized pulse signal */ const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ const opus_int LTP_scale_Q14 /* I LTP state scaling */ ) = { silk_NSQ_del_dec_c, /* ARMv4 */ silk_NSQ_del_dec_c, /* EDSP */ silk_NSQ_del_dec_c, /* Media */ silk_NSQ_del_dec_neon, /* Neon */ }; /*There is no table for silk_noise_shape_quantizer_short_prediction because the NEON version takes different parameters than the C version. Instead RTCD is done via if statements at the call sites. See NSQ_neon.h for details.*/ opus_int32 (*const SILK_NSQ_NOISE_SHAPE_FEEDBACK_LOOP_IMPL[OPUS_ARCHMASK+1])( const opus_int32 *data0, opus_int32 *data1, const opus_int16 *coef, opus_int order) = { silk_NSQ_noise_shape_feedback_loop_c, /* ARMv4 */ silk_NSQ_noise_shape_feedback_loop_c, /* EDSP */ silk_NSQ_noise_shape_feedback_loop_c, /* Media */ silk_NSQ_noise_shape_feedback_loop_neon, /* NEON */ }; # endif # if defined(FIXED_POINT) && \ defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR) void (*const SILK_WARPED_AUTOCORRELATION_FIX_IMPL[OPUS_ARCHMASK + 1])( opus_int32 *corr, /* O Result [order + 1] */ opus_int *scale, /* O Scaling of the correlation vector */ const opus_int16 *input, /* I Input data to correlate */ const opus_int warping_Q16, /* I Warping coefficient */ const opus_int length, /* I Length of input */ const opus_int order /* I Correlation order (even) */ ) = { silk_warped_autocorrelation_FIX_c, /* ARMv4 */ silk_warped_autocorrelation_FIX_c, /* EDSP */ silk_warped_autocorrelation_FIX_c, /* Media */ silk_warped_autocorrelation_FIX_neon, /* Neon */ }; # endif #endif /* OPUS_HAVE_RTCD */ jamulus-3.9.1+dfsg/libs/opus/silk/arm/NSQ_del_dec_neon_intr.c0000644000175000017500000017672414340334543023154 0ustar vimervimer/*********************************************************************** Copyright (c) 2017 Google Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #ifdef OPUS_CHECK_ASM # include #endif #include "main.h" #include "stack_alloc.h" /* NEON intrinsics optimization now can only parallelize up to 4 delay decision states. */ /* If there are more states, C function is called, and this optimization must be expanded. */ #define NEON_MAX_DEL_DEC_STATES 4 typedef struct { opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ][ NEON_MAX_DEL_DEC_STATES ]; opus_int32 RandState[ DECISION_DELAY ][ NEON_MAX_DEL_DEC_STATES ]; opus_int32 Q_Q10[ DECISION_DELAY ][ NEON_MAX_DEL_DEC_STATES ]; opus_int32 Xq_Q14[ DECISION_DELAY ][ NEON_MAX_DEL_DEC_STATES ]; opus_int32 Pred_Q15[ DECISION_DELAY ][ NEON_MAX_DEL_DEC_STATES ]; opus_int32 Shape_Q14[ DECISION_DELAY ][ NEON_MAX_DEL_DEC_STATES ]; opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ][ NEON_MAX_DEL_DEC_STATES ]; opus_int32 LF_AR_Q14[ NEON_MAX_DEL_DEC_STATES ]; opus_int32 Diff_Q14[ NEON_MAX_DEL_DEC_STATES ]; opus_int32 Seed[ NEON_MAX_DEL_DEC_STATES ]; opus_int32 SeedInit[ NEON_MAX_DEL_DEC_STATES ]; opus_int32 RD_Q10[ NEON_MAX_DEL_DEC_STATES ]; } NSQ_del_decs_struct; typedef struct { opus_int32 Q_Q10[ NEON_MAX_DEL_DEC_STATES ]; opus_int32 RD_Q10[ NEON_MAX_DEL_DEC_STATES ]; opus_int32 xq_Q14[ NEON_MAX_DEL_DEC_STATES ]; opus_int32 LF_AR_Q14[ NEON_MAX_DEL_DEC_STATES ]; opus_int32 Diff_Q14[ NEON_MAX_DEL_DEC_STATES ]; opus_int32 sLTP_shp_Q14[ NEON_MAX_DEL_DEC_STATES ]; opus_int32 LPC_exc_Q14[ NEON_MAX_DEL_DEC_STATES ]; } NSQ_samples_struct; static OPUS_INLINE void silk_nsq_del_dec_scale_states_neon( const silk_encoder_state *psEncC, /* I Encoder State */ silk_nsq_state *NSQ, /* I/O NSQ state */ NSQ_del_decs_struct psDelDec[], /* I/O Delayed decision states */ const opus_int16 x16[], /* I Input */ opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */ const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */ opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ opus_int subfr, /* I Subframe number */ const opus_int LTP_scale_Q14, /* I LTP state scaling */ const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ const opus_int signal_type, /* I Signal type */ const opus_int decisionDelay /* I Decision delay */ ); /******************************************/ /* Noise shape quantizer for one subframe */ /******************************************/ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_neon( silk_nsq_state *NSQ, /* I/O NSQ state */ NSQ_del_decs_struct psDelDec[], /* I/O Delayed decision states */ opus_int signalType, /* I Signal type */ const opus_int32 x_Q10[], /* I */ opus_int8 pulses[], /* O */ opus_int16 xq[], /* O */ opus_int32 sLTP_Q15[], /* I/O LTP filter state */ opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */ const opus_int16 a_Q12[], /* I Short term prediction coefs */ const opus_int16 b_Q14[], /* I Long term prediction coefs */ const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */ opus_int lag, /* I Pitch lag */ opus_int32 HarmShapeFIRPacked_Q14, /* I */ opus_int Tilt_Q14, /* I Spectral tilt */ opus_int32 LF_shp_Q14, /* I */ opus_int32 Gain_Q16, /* I */ opus_int Lambda_Q10, /* I */ opus_int offset_Q10, /* I */ opus_int length, /* I Input length */ opus_int subfr, /* I Subframe number */ opus_int shapingLPCOrder, /* I Shaping LPC filter order */ opus_int predictLPCOrder, /* I Prediction filter order */ opus_int warping_Q16, /* I */ opus_int nStatesDelayedDecision, /* I Number of states in decision tree */ opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */ opus_int decisionDelay /* I */ ); static OPUS_INLINE void copy_winner_state_kernel( const NSQ_del_decs_struct *psDelDec, const opus_int offset, const opus_int last_smple_idx, const opus_int Winner_ind, const int32x2_t gain_lo_s32x2, const int32x2_t gain_hi_s32x2, const int32x4_t shift_s32x4, int32x4_t t0_s32x4, int32x4_t t1_s32x4, opus_int8 *const pulses, opus_int16 *pxq, silk_nsq_state *NSQ ) { int16x8_t t_s16x8; int32x4_t o0_s32x4, o1_s32x4; t0_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 0 ][ Winner_ind ], t0_s32x4, 0 ); t0_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 1 ][ Winner_ind ], t0_s32x4, 1 ); t0_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 2 ][ Winner_ind ], t0_s32x4, 2 ); t0_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 3 ][ Winner_ind ], t0_s32x4, 3 ); t1_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 4 ][ Winner_ind ], t1_s32x4, 0 ); t1_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 5 ][ Winner_ind ], t1_s32x4, 1 ); t1_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 6 ][ Winner_ind ], t1_s32x4, 2 ); t1_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 7 ][ Winner_ind ], t1_s32x4, 3 ); t_s16x8 = vcombine_s16( vrshrn_n_s32( t0_s32x4, 10 ), vrshrn_n_s32( t1_s32x4, 10 ) ); vst1_s8( &pulses[ offset ], vmovn_s16( t_s16x8 ) ); t0_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 0 ][ Winner_ind ], t0_s32x4, 0 ); t0_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 1 ][ Winner_ind ], t0_s32x4, 1 ); t0_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 2 ][ Winner_ind ], t0_s32x4, 2 ); t0_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 3 ][ Winner_ind ], t0_s32x4, 3 ); t1_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 4 ][ Winner_ind ], t1_s32x4, 0 ); t1_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 5 ][ Winner_ind ], t1_s32x4, 1 ); t1_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 6 ][ Winner_ind ], t1_s32x4, 2 ); t1_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 7 ][ Winner_ind ], t1_s32x4, 3 ); o0_s32x4 = vqdmulhq_lane_s32( t0_s32x4, gain_lo_s32x2, 0 ); o1_s32x4 = vqdmulhq_lane_s32( t1_s32x4, gain_lo_s32x2, 0 ); o0_s32x4 = vmlaq_lane_s32( o0_s32x4, t0_s32x4, gain_hi_s32x2, 0 ); o1_s32x4 = vmlaq_lane_s32( o1_s32x4, t1_s32x4, gain_hi_s32x2, 0 ); o0_s32x4 = vrshlq_s32( o0_s32x4, shift_s32x4 ); o1_s32x4 = vrshlq_s32( o1_s32x4, shift_s32x4 ); vst1_s16( &pxq[ offset + 0 ], vqmovn_s32( o0_s32x4 ) ); vst1_s16( &pxq[ offset + 4 ], vqmovn_s32( o1_s32x4 ) ); t0_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 0 ][ Winner_ind ], t0_s32x4, 0 ); t0_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 1 ][ Winner_ind ], t0_s32x4, 1 ); t0_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 2 ][ Winner_ind ], t0_s32x4, 2 ); t0_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 3 ][ Winner_ind ], t0_s32x4, 3 ); t1_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 4 ][ Winner_ind ], t1_s32x4, 0 ); t1_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 5 ][ Winner_ind ], t1_s32x4, 1 ); t1_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 6 ][ Winner_ind ], t1_s32x4, 2 ); t1_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 7 ][ Winner_ind ], t1_s32x4, 3 ); vst1q_s32( &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx + offset + 0 ], t0_s32x4 ); vst1q_s32( &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx + offset + 4 ], t1_s32x4 ); } static OPUS_INLINE void copy_winner_state( const NSQ_del_decs_struct *psDelDec, const opus_int decisionDelay, const opus_int smpl_buf_idx, const opus_int Winner_ind, const opus_int32 gain, const opus_int32 shift, opus_int8 *const pulses, opus_int16 *pxq, silk_nsq_state *NSQ ) { opus_int i, last_smple_idx; const int32x2_t gain_lo_s32x2 = vdup_n_s32( silk_LSHIFT32( gain & 0x0000FFFF, 15 ) ); const int32x2_t gain_hi_s32x2 = vdup_n_s32( gain >> 16 ); const int32x4_t shift_s32x4 = vdupq_n_s32( -shift ); int32x4_t t0_s32x4, t1_s32x4; t0_s32x4 = t1_s32x4 = vdupq_n_s32( 0 ); /* initialization */ last_smple_idx = smpl_buf_idx + decisionDelay - 1 + DECISION_DELAY; if( last_smple_idx >= DECISION_DELAY ) last_smple_idx -= DECISION_DELAY; if( last_smple_idx >= DECISION_DELAY ) last_smple_idx -= DECISION_DELAY; for( i = 0; ( i < ( decisionDelay - 7 ) ) && ( last_smple_idx >= 7 ); i += 8, last_smple_idx -= 8 ) { copy_winner_state_kernel( psDelDec, i - decisionDelay, last_smple_idx, Winner_ind, gain_lo_s32x2, gain_hi_s32x2, shift_s32x4, t0_s32x4, t1_s32x4, pulses, pxq, NSQ ); } for( ; ( i < decisionDelay ) && ( last_smple_idx >= 0 ); i++, last_smple_idx-- ) { pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDelDec->Q_Q10[ last_smple_idx ][ Winner_ind ], 10 ); pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( psDelDec->Xq_Q14[ last_smple_idx ][ Winner_ind ], gain ), shift ) ); NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDelDec->Shape_Q14[ last_smple_idx ][ Winner_ind ]; } last_smple_idx += DECISION_DELAY; for( ; i < ( decisionDelay - 7 ); i++, last_smple_idx-- ) { copy_winner_state_kernel( psDelDec, i - decisionDelay, last_smple_idx, Winner_ind, gain_lo_s32x2, gain_hi_s32x2, shift_s32x4, t0_s32x4, t1_s32x4, pulses, pxq, NSQ ); } for( ; i < decisionDelay; i++, last_smple_idx-- ) { pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDelDec->Q_Q10[ last_smple_idx ][ Winner_ind ], 10 ); pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( psDelDec->Xq_Q14[ last_smple_idx ][ Winner_ind ], gain ), shift ) ); NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDelDec->Shape_Q14[ last_smple_idx ][ Winner_ind ]; } } void silk_NSQ_del_dec_neon( const silk_encoder_state *psEncC, /* I Encoder State */ silk_nsq_state *NSQ, /* I/O NSQ state */ SideInfoIndices *psIndices, /* I/O Quantization Indices */ const opus_int16 x16[], /* I Input */ opus_int8 pulses[], /* O Quantized pulse signal */ const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ const opus_int LTP_scale_Q14 /* I LTP state scaling */ ) { #ifdef OPUS_CHECK_ASM silk_nsq_state NSQ_c; SideInfoIndices psIndices_c; opus_int8 pulses_c[ MAX_FRAME_LENGTH ]; const opus_int8 *const pulses_a = pulses; ( void )pulses_a; silk_memcpy( &NSQ_c, NSQ, sizeof( NSQ_c ) ); silk_memcpy( &psIndices_c, psIndices, sizeof( psIndices_c ) ); silk_memcpy( pulses_c, pulses, sizeof( pulses_c ) ); silk_NSQ_del_dec_c( psEncC, &NSQ_c, &psIndices_c, x16, pulses_c, PredCoef_Q12, LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14 ); #endif /* The optimization parallelizes the different delay decision states. */ if(( psEncC->nStatesDelayedDecision > NEON_MAX_DEL_DEC_STATES ) || ( psEncC->nStatesDelayedDecision <= 2 )) { /* NEON intrinsics optimization now can only parallelize up to 4 delay decision states. */ /* If there are more states, C function is called, and this optimization must be expanded. */ /* When the number of delay decision states is less than 3, there are penalties using this */ /* optimization, and C function is called. */ /* When the number of delay decision states is 2, it's better to specialize another */ /* structure NSQ_del_dec2_struct and optimize with shorter NEON registers. (Low priority) */ silk_NSQ_del_dec_c( psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14 ); } else { opus_int i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr; opus_int smpl_buf_idx, decisionDelay; const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13; opus_int16 *pxq; VARDECL( opus_int32, sLTP_Q15 ); VARDECL( opus_int16, sLTP ); opus_int32 HarmShapeFIRPacked_Q14; opus_int offset_Q10; opus_int32 RDmin_Q10, Gain_Q10; VARDECL( opus_int32, x_sc_Q10 ); VARDECL( opus_int32, delayedGain_Q10 ); VARDECL( NSQ_del_decs_struct, psDelDec ); int32x4_t t_s32x4; SAVE_STACK; /* Set unvoiced lag to the previous one, overwrite later for voiced */ lag = NSQ->lagPrev; silk_assert( NSQ->prev_gain_Q16 != 0 ); /* Initialize delayed decision states */ ALLOC( psDelDec, 1, NSQ_del_decs_struct ); /* Only RandState and RD_Q10 need to be initialized to 0. */ silk_memset( psDelDec->RandState, 0, sizeof( psDelDec->RandState ) ); vst1q_s32( psDelDec->RD_Q10, vdupq_n_s32( 0 ) ); for( k = 0; k < psEncC->nStatesDelayedDecision; k++ ) { psDelDec->SeedInit[ k ] = psDelDec->Seed[ k ] = ( k + psIndices->Seed ) & 3; } vst1q_s32( psDelDec->LF_AR_Q14, vld1q_dup_s32( &NSQ->sLF_AR_shp_Q14 ) ); vst1q_s32( psDelDec->Diff_Q14, vld1q_dup_s32( &NSQ->sDiff_shp_Q14 ) ); vst1q_s32( psDelDec->Shape_Q14[ 0 ], vld1q_dup_s32( &NSQ->sLTP_shp_Q14[ psEncC->ltp_mem_length - 1 ] ) ); for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) { vst1q_s32( psDelDec->sLPC_Q14[ i ], vld1q_dup_s32( &NSQ->sLPC_Q14[ i ] ) ); } for( i = 0; i < (opus_int)( sizeof( NSQ->sAR2_Q14 ) / sizeof( NSQ->sAR2_Q14[ 0 ] ) ); i++ ) { vst1q_s32( psDelDec->sAR2_Q14[ i ], vld1q_dup_s32( &NSQ->sAR2_Q14[ i ] ) ); } offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ]; smpl_buf_idx = 0; /* index of oldest samples */ decisionDelay = silk_min_int( DECISION_DELAY, psEncC->subfr_length ); /* For voiced frames limit the decision delay to lower than the pitch lag */ if( psIndices->signalType == TYPE_VOICED ) { opus_int pitch_min = pitchL[ 0 ]; for( k = 1; k < psEncC->nb_subfr; k++ ) { pitch_min = silk_min_int( pitch_min, pitchL[ k ] ); } decisionDelay = silk_min_int( decisionDelay, pitch_min - LTP_ORDER / 2 - 1 ); } else { if( lag > 0 ) { decisionDelay = silk_min_int( decisionDelay, lag - LTP_ORDER / 2 - 1 ); } } if( psIndices->NLSFInterpCoef_Q2 == 4 ) { LSF_interpolation_flag = 0; } else { LSF_interpolation_flag = 1; } ALLOC( sLTP_Q15, psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 ); ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 ); ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 ); ALLOC( delayedGain_Q10, DECISION_DELAY, opus_int32 ); /* Set up pointers to start of sub frame */ pxq = &NSQ->xq[ psEncC->ltp_mem_length ]; NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length; NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; subfr = 0; for( k = 0; k < psEncC->nb_subfr; k++ ) { A_Q12 = &PredCoef_Q12[ ( ( k >> 1 ) | ( 1 - LSF_interpolation_flag ) ) * MAX_LPC_ORDER ]; B_Q14 = <PCoef_Q14[ k * LTP_ORDER ]; AR_shp_Q13 = &AR_Q13[ k * MAX_SHAPE_LPC_ORDER ]; /* Noise shape parameters */ silk_assert( HarmShapeGain_Q14[ k ] >= 0 ); HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 ); HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 ); NSQ->rewhite_flag = 0; if( psIndices->signalType == TYPE_VOICED ) { /* Voiced */ lag = pitchL[ k ]; /* Re-whitening */ if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) { if( k == 2 ) { /* RESET DELAYED DECISIONS */ /* Find winner */ int32x4_t RD_Q10_s32x4; RDmin_Q10 = psDelDec->RD_Q10[ 0 ]; Winner_ind = 0; for( i = 1; i < psEncC->nStatesDelayedDecision; i++ ) { if( psDelDec->RD_Q10[ i ] < RDmin_Q10 ) { RDmin_Q10 = psDelDec->RD_Q10[ i ]; Winner_ind = i; } } psDelDec->RD_Q10[ Winner_ind ] -= ( silk_int32_MAX >> 4 ); RD_Q10_s32x4 = vld1q_s32( psDelDec->RD_Q10 ); RD_Q10_s32x4 = vaddq_s32( RD_Q10_s32x4, vdupq_n_s32( silk_int32_MAX >> 4 ) ); vst1q_s32( psDelDec->RD_Q10, RD_Q10_s32x4 ); /* Copy final part of signals from winner state to output and long-term filter states */ copy_winner_state( psDelDec, decisionDelay, smpl_buf_idx, Winner_ind, Gains_Q16[ 1 ], 14, pulses, pxq, NSQ ); subfr = 0; } /* Rewhiten with new A coefs */ start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2; silk_assert( start_idx > 0 ); silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ], A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch ); NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; NSQ->rewhite_flag = 1; } } silk_nsq_del_dec_scale_states_neon( psEncC, NSQ, psDelDec, x16, x_sc_Q10, sLTP, sLTP_Q15, k, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType, decisionDelay ); silk_noise_shape_quantizer_del_dec_neon( NSQ, psDelDec, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, delayedGain_Q10, A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder, psEncC->predictLPCOrder, psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay ); x16 += psEncC->subfr_length; pulses += psEncC->subfr_length; pxq += psEncC->subfr_length; } /* Find winner */ RDmin_Q10 = psDelDec->RD_Q10[ 0 ]; Winner_ind = 0; for( k = 1; k < psEncC->nStatesDelayedDecision; k++ ) { if( psDelDec->RD_Q10[ k ] < RDmin_Q10 ) { RDmin_Q10 = psDelDec->RD_Q10[ k ]; Winner_ind = k; } } /* Copy final part of signals from winner state to output and long-term filter states */ psIndices->Seed = psDelDec->SeedInit[ Winner_ind ]; Gain_Q10 = silk_RSHIFT32( Gains_Q16[ psEncC->nb_subfr - 1 ], 6 ); copy_winner_state( psDelDec, decisionDelay, smpl_buf_idx, Winner_ind, Gain_Q10, 8, pulses, pxq, NSQ ); t_s32x4 = vdupq_n_s32( 0 ); /* initialization */ for( i = 0; i < ( NSQ_LPC_BUF_LENGTH - 3 ); i += 4 ) { t_s32x4 = vld1q_lane_s32( &psDelDec->sLPC_Q14[ i + 0 ][ Winner_ind ], t_s32x4, 0 ); t_s32x4 = vld1q_lane_s32( &psDelDec->sLPC_Q14[ i + 1 ][ Winner_ind ], t_s32x4, 1 ); t_s32x4 = vld1q_lane_s32( &psDelDec->sLPC_Q14[ i + 2 ][ Winner_ind ], t_s32x4, 2 ); t_s32x4 = vld1q_lane_s32( &psDelDec->sLPC_Q14[ i + 3 ][ Winner_ind ], t_s32x4, 3 ); vst1q_s32( &NSQ->sLPC_Q14[ i ], t_s32x4 ); } for( ; i < NSQ_LPC_BUF_LENGTH; i++ ) { NSQ->sLPC_Q14[ i ] = psDelDec->sLPC_Q14[ i ][ Winner_ind ]; } for( i = 0; i < (opus_int)( sizeof( NSQ->sAR2_Q14 ) / sizeof( NSQ->sAR2_Q14[ 0 ] ) - 3 ); i += 4 ) { t_s32x4 = vld1q_lane_s32( &psDelDec->sAR2_Q14[ i + 0 ][ Winner_ind ], t_s32x4, 0 ); t_s32x4 = vld1q_lane_s32( &psDelDec->sAR2_Q14[ i + 1 ][ Winner_ind ], t_s32x4, 1 ); t_s32x4 = vld1q_lane_s32( &psDelDec->sAR2_Q14[ i + 2 ][ Winner_ind ], t_s32x4, 2 ); t_s32x4 = vld1q_lane_s32( &psDelDec->sAR2_Q14[ i + 3 ][ Winner_ind ], t_s32x4, 3 ); vst1q_s32( &NSQ->sAR2_Q14[ i ], t_s32x4 ); } for( ; i < (opus_int)( sizeof( NSQ->sAR2_Q14 ) / sizeof( NSQ->sAR2_Q14[ 0 ] ) ); i++ ) { NSQ->sAR2_Q14[ i ] = psDelDec->sAR2_Q14[ i ][ Winner_ind ]; } /* Update states */ NSQ->sLF_AR_shp_Q14 = psDelDec->LF_AR_Q14[ Winner_ind ]; NSQ->sDiff_shp_Q14 = psDelDec->Diff_Q14[ Winner_ind ]; NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ]; /* Save quantized speech signal */ silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) ); silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) ); RESTORE_STACK; } #ifdef OPUS_CHECK_ASM silk_assert( !memcmp( &NSQ_c, NSQ, sizeof( NSQ_c ) ) ); silk_assert( !memcmp( &psIndices_c, psIndices, sizeof( psIndices_c ) ) ); silk_assert( !memcmp( pulses_c, pulses_a, sizeof( pulses_c ) ) ); #endif } /******************************************/ /* Noise shape quantizer for one subframe */ /******************************************/ /* Note: Function silk_short_prediction_create_arch_coef_neon() defined in NSQ_neon.h is actually a hacking C function. */ /* Therefore here we append "_local" to the NEON function name to avoid confusion. */ static OPUS_INLINE void silk_short_prediction_create_arch_coef_neon_local(opus_int32 *out, const opus_int16 *in, opus_int order) { int16x8_t t_s16x8; int32x4_t t0_s32x4, t1_s32x4, t2_s32x4, t3_s32x4; silk_assert( order == 10 || order == 16 ); t_s16x8 = vld1q_s16( in + 0 ); /* 7 6 5 4 3 2 1 0 */ t_s16x8 = vrev64q_s16( t_s16x8 ); /* 4 5 6 7 0 1 2 3 */ t2_s32x4 = vshll_n_s16( vget_high_s16( t_s16x8 ), 15 ); /* 4 5 6 7 */ t3_s32x4 = vshll_n_s16( vget_low_s16( t_s16x8 ), 15 ); /* 0 1 2 3 */ if( order == 16 ) { t_s16x8 = vld1q_s16( in + 8 ); /* F E D C B A 9 8 */ t_s16x8 = vrev64q_s16( t_s16x8 ); /* C D E F 8 9 A B */ t0_s32x4 = vshll_n_s16( vget_high_s16( t_s16x8 ), 15 ); /* C D E F */ t1_s32x4 = vshll_n_s16( vget_low_s16( t_s16x8 ), 15 ); /* 8 9 A B */ } else { int16x4_t t_s16x4; t0_s32x4 = vdupq_n_s32( 0 ); /* zero zero zero zero */ t_s16x4 = vld1_s16( in + 6 ); /* 9 8 7 6 */ t_s16x4 = vrev64_s16( t_s16x4 ); /* 6 7 8 9 */ t1_s32x4 = vshll_n_s16( t_s16x4, 15 ); t1_s32x4 = vcombine_s32( vget_low_s32(t0_s32x4), vget_low_s32( t1_s32x4 ) ); /* 8 9 zero zero */ } vst1q_s32( out + 0, t0_s32x4 ); vst1q_s32( out + 4, t1_s32x4 ); vst1q_s32( out + 8, t2_s32x4 ); vst1q_s32( out + 12, t3_s32x4 ); } static OPUS_INLINE int32x4_t silk_SMLAWB_lane0_neon( const int32x4_t out_s32x4, const int32x4_t in_s32x4, const int32x2_t coef_s32x2 ) { return vaddq_s32( out_s32x4, vqdmulhq_lane_s32( in_s32x4, coef_s32x2, 0 ) ); } static OPUS_INLINE int32x4_t silk_SMLAWB_lane1_neon( const int32x4_t out_s32x4, const int32x4_t in_s32x4, const int32x2_t coef_s32x2 ) { return vaddq_s32( out_s32x4, vqdmulhq_lane_s32( in_s32x4, coef_s32x2, 1 ) ); } /* Note: This function has different return value than silk_noise_shape_quantizer_short_prediction_neon(). */ /* Therefore here we append "_local" to the function name to avoid confusion. */ static OPUS_INLINE int32x4_t silk_noise_shape_quantizer_short_prediction_neon_local(const opus_int32 *buf32, const opus_int32 *a_Q12_arch, opus_int order) { const int32x4_t a_Q12_arch0_s32x4 = vld1q_s32( a_Q12_arch + 0 ); const int32x4_t a_Q12_arch1_s32x4 = vld1q_s32( a_Q12_arch + 4 ); const int32x4_t a_Q12_arch2_s32x4 = vld1q_s32( a_Q12_arch + 8 ); const int32x4_t a_Q12_arch3_s32x4 = vld1q_s32( a_Q12_arch + 12 ); int32x4_t LPC_pred_Q14_s32x4; silk_assert( order == 10 || order == 16 ); /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ LPC_pred_Q14_s32x4 = vdupq_n_s32( silk_RSHIFT( order, 1 ) ); LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 0 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32( a_Q12_arch0_s32x4 ) ); LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 1 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32( a_Q12_arch0_s32x4 ) ); LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 2 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch0_s32x4 ) ); LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 3 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch0_s32x4 ) ); LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 4 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32( a_Q12_arch1_s32x4 ) ); LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 5 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32( a_Q12_arch1_s32x4 ) ); LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 6 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch1_s32x4 ) ); LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 7 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch1_s32x4 ) ); LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 8 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32( a_Q12_arch2_s32x4 ) ); LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 9 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32( a_Q12_arch2_s32x4 ) ); LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 10 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch2_s32x4 ) ); LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 11 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch2_s32x4 ) ); LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 12 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32( a_Q12_arch3_s32x4 ) ); LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 13 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32( a_Q12_arch3_s32x4 ) ); LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 14 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch3_s32x4 ) ); LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 15 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch3_s32x4 ) ); return LPC_pred_Q14_s32x4; } static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_neon( silk_nsq_state *NSQ, /* I/O NSQ state */ NSQ_del_decs_struct psDelDec[], /* I/O Delayed decision states */ opus_int signalType, /* I Signal type */ const opus_int32 x_Q10[], /* I */ opus_int8 pulses[], /* O */ opus_int16 xq[], /* O */ opus_int32 sLTP_Q15[], /* I/O LTP filter state */ opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */ const opus_int16 a_Q12[], /* I Short term prediction coefs */ const opus_int16 b_Q14[], /* I Long term prediction coefs */ const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */ opus_int lag, /* I Pitch lag */ opus_int32 HarmShapeFIRPacked_Q14, /* I */ opus_int Tilt_Q14, /* I Spectral tilt */ opus_int32 LF_shp_Q14, /* I */ opus_int32 Gain_Q16, /* I */ opus_int Lambda_Q10, /* I */ opus_int offset_Q10, /* I */ opus_int length, /* I Input length */ opus_int subfr, /* I Subframe number */ opus_int shapingLPCOrder, /* I Shaping LPC filter order */ opus_int predictLPCOrder, /* I Prediction filter order */ opus_int warping_Q16, /* I */ opus_int nStatesDelayedDecision, /* I Number of states in decision tree */ opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */ opus_int decisionDelay /* I */ ) { opus_int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx; opus_int32 Winner_rand_state; opus_int32 LTP_pred_Q14, n_LTP_Q14; opus_int32 RDmin_Q10, RDmax_Q10; opus_int32 Gain_Q10; opus_int32 *pred_lag_ptr, *shp_lag_ptr; opus_int32 a_Q12_arch[MAX_LPC_ORDER]; const int32x2_t warping_Q16_s32x2 = vdup_n_s32( silk_LSHIFT32( warping_Q16, 16 ) >> 1 ); const opus_int32 LF_shp_Q29 = silk_LSHIFT32( LF_shp_Q14, 16 ) >> 1; opus_int32 AR_shp_Q28[ MAX_SHAPE_LPC_ORDER ]; const uint32x4_t rand_multiplier_u32x4 = vdupq_n_u32( RAND_MULTIPLIER ); const uint32x4_t rand_increment_u32x4 = vdupq_n_u32( RAND_INCREMENT ); VARDECL( NSQ_samples_struct, psSampleState ); SAVE_STACK; silk_assert( nStatesDelayedDecision > 0 ); silk_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */ ALLOC( psSampleState, 2, NSQ_samples_struct ); shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ]; pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ]; Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 ); for( i = 0; i < ( MAX_SHAPE_LPC_ORDER - 7 ); i += 8 ) { const int16x8_t t_s16x8 = vld1q_s16( AR_shp_Q13 + i ); vst1q_s32( AR_shp_Q28 + i + 0, vshll_n_s16( vget_low_s16( t_s16x8 ), 15 ) ); vst1q_s32( AR_shp_Q28 + i + 4, vshll_n_s16( vget_high_s16( t_s16x8 ), 15 ) ); } for( ; i < MAX_SHAPE_LPC_ORDER; i++ ) { AR_shp_Q28[i] = silk_LSHIFT32( AR_shp_Q13[i], 15 ); } silk_short_prediction_create_arch_coef_neon_local( a_Q12_arch, a_Q12, predictLPCOrder ); for( i = 0; i < length; i++ ) { int32x4_t Seed_s32x4, LPC_pred_Q14_s32x4; int32x4_t sign_s32x4, tmp1_s32x4, tmp2_s32x4; int32x4_t n_AR_Q14_s32x4, n_LF_Q14_s32x4; int32x2_t AR_shp_Q28_s32x2; int16x4_t r_Q10_s16x4, rr_Q10_s16x4; /* Perform common calculations used in all states */ /* Long-term prediction */ if( signalType == TYPE_VOICED ) { /* Unrolled loop */ /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ LTP_pred_Q14 = 2; LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ 0 ], b_Q14[ 0 ] ); LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], b_Q14[ 1 ] ); LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], b_Q14[ 2 ] ); LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], b_Q14[ 3 ] ); LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] ); LTP_pred_Q14 = silk_LSHIFT( LTP_pred_Q14, 1 ); /* Q13 -> Q14 */ pred_lag_ptr++; } else { LTP_pred_Q14 = 0; } /* Long-term shaping */ if( lag > 0 ) { /* Symmetric, packed FIR coefficients */ n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 ); n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 ); n_LTP_Q14 = silk_SUB_LSHIFT32( LTP_pred_Q14, n_LTP_Q14, 2 ); /* Q12 -> Q14 */ shp_lag_ptr++; } else { n_LTP_Q14 = 0; } /* Generate dither */ Seed_s32x4 = vld1q_s32( psDelDec->Seed ); Seed_s32x4 = vreinterpretq_s32_u32( vmlaq_u32( rand_increment_u32x4, vreinterpretq_u32_s32( Seed_s32x4 ), rand_multiplier_u32x4 ) ); vst1q_s32( psDelDec->Seed, Seed_s32x4 ); /* Short-term prediction */ LPC_pred_Q14_s32x4 = silk_noise_shape_quantizer_short_prediction_neon_local(psDelDec->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 16 + i ], a_Q12_arch, predictLPCOrder); LPC_pred_Q14_s32x4 = vshlq_n_s32( LPC_pred_Q14_s32x4, 4 ); /* Q10 -> Q14 */ /* Noise shape feedback */ /* Output of lowpass section */ tmp2_s32x4 = silk_SMLAWB_lane0_neon( vld1q_s32( psDelDec->Diff_Q14 ), vld1q_s32( psDelDec->sAR2_Q14[ 0 ] ), warping_Q16_s32x2 ); /* Output of allpass section */ tmp1_s32x4 = vsubq_s32( vld1q_s32( psDelDec->sAR2_Q14[ 1 ] ), tmp2_s32x4 ); tmp1_s32x4 = silk_SMLAWB_lane0_neon( vld1q_s32( psDelDec->sAR2_Q14[ 0 ] ), tmp1_s32x4, warping_Q16_s32x2 ); vst1q_s32( psDelDec->sAR2_Q14[ 0 ], tmp2_s32x4 ); AR_shp_Q28_s32x2 = vld1_s32( AR_shp_Q28 ); n_AR_Q14_s32x4 = vaddq_s32( vdupq_n_s32( silk_RSHIFT( shapingLPCOrder, 1 ) ), vqdmulhq_lane_s32( tmp2_s32x4, AR_shp_Q28_s32x2, 0 ) ); /* Loop over allpass sections */ for( j = 2; j < shapingLPCOrder; j += 2 ) { /* Output of allpass section */ tmp2_s32x4 = vsubq_s32( vld1q_s32( psDelDec->sAR2_Q14[ j + 0 ] ), tmp1_s32x4 ); tmp2_s32x4 = silk_SMLAWB_lane0_neon( vld1q_s32( psDelDec->sAR2_Q14[ j - 1 ] ), tmp2_s32x4, warping_Q16_s32x2 ); vst1q_s32( psDelDec->sAR2_Q14[ j - 1 ], tmp1_s32x4 ); n_AR_Q14_s32x4 = vaddq_s32( n_AR_Q14_s32x4, vqdmulhq_lane_s32( tmp1_s32x4, AR_shp_Q28_s32x2, 1 ) ); /* Output of allpass section */ tmp1_s32x4 = vsubq_s32( vld1q_s32( psDelDec->sAR2_Q14[ j + 1 ] ), tmp2_s32x4 ); tmp1_s32x4 = silk_SMLAWB_lane0_neon( vld1q_s32( psDelDec->sAR2_Q14[ j + 0 ] ), tmp1_s32x4, warping_Q16_s32x2 ); vst1q_s32( psDelDec->sAR2_Q14[ j + 0 ], tmp2_s32x4 ); AR_shp_Q28_s32x2 = vld1_s32( &AR_shp_Q28[ j ] ); n_AR_Q14_s32x4 = vaddq_s32( n_AR_Q14_s32x4, vqdmulhq_lane_s32( tmp2_s32x4, AR_shp_Q28_s32x2, 0 ) ); } vst1q_s32( psDelDec->sAR2_Q14[ shapingLPCOrder - 1 ], tmp1_s32x4 ); n_AR_Q14_s32x4 = vaddq_s32( n_AR_Q14_s32x4, vqdmulhq_lane_s32( tmp1_s32x4, AR_shp_Q28_s32x2, 1 ) ); n_AR_Q14_s32x4 = vshlq_n_s32( n_AR_Q14_s32x4, 1 ); /* Q11 -> Q12 */ n_AR_Q14_s32x4 = vaddq_s32( n_AR_Q14_s32x4, vqdmulhq_n_s32( vld1q_s32( psDelDec->LF_AR_Q14 ), silk_LSHIFT32( Tilt_Q14, 16 ) >> 1 ) ); /* Q12 */ n_AR_Q14_s32x4 = vshlq_n_s32( n_AR_Q14_s32x4, 2 ); /* Q12 -> Q14 */ n_LF_Q14_s32x4 = vqdmulhq_n_s32( vld1q_s32( psDelDec->Shape_Q14[ *smpl_buf_idx ] ), LF_shp_Q29 ); /* Q12 */ n_LF_Q14_s32x4 = vaddq_s32( n_LF_Q14_s32x4, vqdmulhq_n_s32( vld1q_s32( psDelDec->LF_AR_Q14 ), silk_LSHIFT32( LF_shp_Q14 >> 16 , 15 ) ) ); /* Q12 */ n_LF_Q14_s32x4 = vshlq_n_s32( n_LF_Q14_s32x4, 2 ); /* Q12 -> Q14 */ /* Input minus prediction plus noise feedback */ /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP */ tmp1_s32x4 = vaddq_s32( n_AR_Q14_s32x4, n_LF_Q14_s32x4 ); /* Q14 */ tmp2_s32x4 = vaddq_s32( vdupq_n_s32( n_LTP_Q14 ), LPC_pred_Q14_s32x4 ); /* Q13 */ tmp1_s32x4 = vsubq_s32( tmp2_s32x4, tmp1_s32x4 ); /* Q13 */ tmp1_s32x4 = vrshrq_n_s32( tmp1_s32x4, 4 ); /* Q10 */ tmp1_s32x4 = vsubq_s32( vdupq_n_s32( x_Q10[ i ] ), tmp1_s32x4 ); /* residual error Q10 */ /* Flip sign depending on dither */ sign_s32x4 = vreinterpretq_s32_u32( vcltq_s32( Seed_s32x4, vdupq_n_s32( 0 ) ) ); tmp1_s32x4 = veorq_s32( tmp1_s32x4, sign_s32x4 ); tmp1_s32x4 = vsubq_s32( tmp1_s32x4, sign_s32x4 ); tmp1_s32x4 = vmaxq_s32( tmp1_s32x4, vdupq_n_s32( -( 31 << 10 ) ) ); tmp1_s32x4 = vminq_s32( tmp1_s32x4, vdupq_n_s32( 30 << 10 ) ); r_Q10_s16x4 = vmovn_s32( tmp1_s32x4 ); /* Find two quantization level candidates and measure their rate-distortion */ { int16x4_t q1_Q10_s16x4 = vsub_s16( r_Q10_s16x4, vdup_n_s16( offset_Q10 ) ); int16x4_t q1_Q0_s16x4 = vshr_n_s16( q1_Q10_s16x4, 10 ); int16x4_t q2_Q10_s16x4; int32x4_t rd1_Q10_s32x4, rd2_Q10_s32x4; uint32x4_t t_u32x4; if( Lambda_Q10 > 2048 ) { /* For aggressive RDO, the bias becomes more than one pulse. */ const int rdo_offset = Lambda_Q10/2 - 512; const uint16x4_t greaterThanRdo = vcgt_s16( q1_Q10_s16x4, vdup_n_s16( rdo_offset ) ); const uint16x4_t lessThanMinusRdo = vclt_s16( q1_Q10_s16x4, vdup_n_s16( -rdo_offset ) ); /* If Lambda_Q10 > 32767, then q1_Q0, q1_Q10 and q2_Q10 must change to 32-bit. */ silk_assert( Lambda_Q10 <= 32767 ); q1_Q0_s16x4 = vreinterpret_s16_u16( vclt_s16( q1_Q10_s16x4, vdup_n_s16( 0 ) ) ); q1_Q0_s16x4 = vbsl_s16( greaterThanRdo, vsub_s16( q1_Q10_s16x4, vdup_n_s16( rdo_offset ) ), q1_Q0_s16x4 ); q1_Q0_s16x4 = vbsl_s16( lessThanMinusRdo, vadd_s16( q1_Q10_s16x4, vdup_n_s16( rdo_offset ) ), q1_Q0_s16x4 ); q1_Q0_s16x4 = vshr_n_s16( q1_Q0_s16x4, 10 ); } { const uint16x4_t equal0_u16x4 = vceq_s16( q1_Q0_s16x4, vdup_n_s16( 0 ) ); const uint16x4_t equalMinus1_u16x4 = vceq_s16( q1_Q0_s16x4, vdup_n_s16( -1 ) ); const uint16x4_t lessThanMinus1_u16x4 = vclt_s16( q1_Q0_s16x4, vdup_n_s16( -1 ) ); int16x4_t tmp1_s16x4, tmp2_s16x4; q1_Q10_s16x4 = vshl_n_s16( q1_Q0_s16x4, 10 ); tmp1_s16x4 = vadd_s16( q1_Q10_s16x4, vdup_n_s16( offset_Q10 - QUANT_LEVEL_ADJUST_Q10 ) ); q1_Q10_s16x4 = vadd_s16( q1_Q10_s16x4, vdup_n_s16( offset_Q10 + QUANT_LEVEL_ADJUST_Q10 ) ); q1_Q10_s16x4 = vbsl_s16( lessThanMinus1_u16x4, q1_Q10_s16x4, tmp1_s16x4 ); q1_Q10_s16x4 = vbsl_s16( equal0_u16x4, vdup_n_s16( offset_Q10 ), q1_Q10_s16x4 ); q1_Q10_s16x4 = vbsl_s16( equalMinus1_u16x4, vdup_n_s16( offset_Q10 - ( 1024 - QUANT_LEVEL_ADJUST_Q10 ) ), q1_Q10_s16x4 ); q2_Q10_s16x4 = vadd_s16( q1_Q10_s16x4, vdup_n_s16( 1024 ) ); q2_Q10_s16x4 = vbsl_s16( equal0_u16x4, vdup_n_s16( offset_Q10 + 1024 - QUANT_LEVEL_ADJUST_Q10 ), q2_Q10_s16x4 ); q2_Q10_s16x4 = vbsl_s16( equalMinus1_u16x4, vdup_n_s16( offset_Q10 ), q2_Q10_s16x4 ); tmp1_s16x4 = q1_Q10_s16x4; tmp2_s16x4 = q2_Q10_s16x4; tmp1_s16x4 = vbsl_s16( vorr_u16( equalMinus1_u16x4, lessThanMinus1_u16x4 ), vneg_s16( tmp1_s16x4 ), tmp1_s16x4 ); tmp2_s16x4 = vbsl_s16( lessThanMinus1_u16x4, vneg_s16( tmp2_s16x4 ), tmp2_s16x4 ); rd1_Q10_s32x4 = vmull_s16( tmp1_s16x4, vdup_n_s16( Lambda_Q10 ) ); rd2_Q10_s32x4 = vmull_s16( tmp2_s16x4, vdup_n_s16( Lambda_Q10 ) ); } rr_Q10_s16x4 = vsub_s16( r_Q10_s16x4, q1_Q10_s16x4 ); rd1_Q10_s32x4 = vmlal_s16( rd1_Q10_s32x4, rr_Q10_s16x4, rr_Q10_s16x4 ); rd1_Q10_s32x4 = vshrq_n_s32( rd1_Q10_s32x4, 10 ); rr_Q10_s16x4 = vsub_s16( r_Q10_s16x4, q2_Q10_s16x4 ); rd2_Q10_s32x4 = vmlal_s16( rd2_Q10_s32x4, rr_Q10_s16x4, rr_Q10_s16x4 ); rd2_Q10_s32x4 = vshrq_n_s32( rd2_Q10_s32x4, 10 ); tmp2_s32x4 = vld1q_s32( psDelDec->RD_Q10 ); tmp1_s32x4 = vaddq_s32( tmp2_s32x4, vminq_s32( rd1_Q10_s32x4, rd2_Q10_s32x4 ) ); tmp2_s32x4 = vaddq_s32( tmp2_s32x4, vmaxq_s32( rd1_Q10_s32x4, rd2_Q10_s32x4 ) ); vst1q_s32( psSampleState[ 0 ].RD_Q10, tmp1_s32x4 ); vst1q_s32( psSampleState[ 1 ].RD_Q10, tmp2_s32x4 ); t_u32x4 = vcltq_s32( rd1_Q10_s32x4, rd2_Q10_s32x4 ); tmp1_s32x4 = vbslq_s32( t_u32x4, vmovl_s16( q1_Q10_s16x4 ), vmovl_s16( q2_Q10_s16x4 ) ); tmp2_s32x4 = vbslq_s32( t_u32x4, vmovl_s16( q2_Q10_s16x4 ), vmovl_s16( q1_Q10_s16x4 ) ); vst1q_s32( psSampleState[ 0 ].Q_Q10, tmp1_s32x4 ); vst1q_s32( psSampleState[ 1 ].Q_Q10, tmp2_s32x4 ); } { /* Update states for best quantization */ int32x4_t exc_Q14_s32x4, LPC_exc_Q14_s32x4, xq_Q14_s32x4, sLF_AR_shp_Q14_s32x4; /* Quantized excitation */ exc_Q14_s32x4 = vshlq_n_s32( tmp1_s32x4, 4 ); exc_Q14_s32x4 = veorq_s32( exc_Q14_s32x4, sign_s32x4 ); exc_Q14_s32x4 = vsubq_s32( exc_Q14_s32x4, sign_s32x4 ); /* Add predictions */ LPC_exc_Q14_s32x4 = vaddq_s32( exc_Q14_s32x4, vdupq_n_s32( LTP_pred_Q14 ) ); xq_Q14_s32x4 = vaddq_s32( LPC_exc_Q14_s32x4, LPC_pred_Q14_s32x4 ); /* Update states */ tmp1_s32x4 = vsubq_s32( xq_Q14_s32x4, vshlq_n_s32( vdupq_n_s32( x_Q10[ i ] ), 4 ) ); vst1q_s32( psSampleState[ 0 ].Diff_Q14, tmp1_s32x4 ); sLF_AR_shp_Q14_s32x4 = vsubq_s32( tmp1_s32x4, n_AR_Q14_s32x4 ); vst1q_s32( psSampleState[ 0 ].sLTP_shp_Q14, vsubq_s32( sLF_AR_shp_Q14_s32x4, n_LF_Q14_s32x4 ) ); vst1q_s32( psSampleState[ 0 ].LF_AR_Q14, sLF_AR_shp_Q14_s32x4 ); vst1q_s32( psSampleState[ 0 ].LPC_exc_Q14, LPC_exc_Q14_s32x4 ); vst1q_s32( psSampleState[ 0 ].xq_Q14, xq_Q14_s32x4 ); /* Quantized excitation */ exc_Q14_s32x4 = vshlq_n_s32( tmp2_s32x4, 4 ); exc_Q14_s32x4 = veorq_s32( exc_Q14_s32x4, sign_s32x4 ); exc_Q14_s32x4 = vsubq_s32( exc_Q14_s32x4, sign_s32x4 ); /* Add predictions */ LPC_exc_Q14_s32x4 = vaddq_s32( exc_Q14_s32x4, vdupq_n_s32( LTP_pred_Q14 ) ); xq_Q14_s32x4 = vaddq_s32( LPC_exc_Q14_s32x4, LPC_pred_Q14_s32x4 ); /* Update states */ tmp1_s32x4 = vsubq_s32( xq_Q14_s32x4, vshlq_n_s32( vdupq_n_s32( x_Q10[ i ] ), 4 ) ); vst1q_s32( psSampleState[ 1 ].Diff_Q14, tmp1_s32x4 ); sLF_AR_shp_Q14_s32x4 = vsubq_s32( tmp1_s32x4, n_AR_Q14_s32x4 ); vst1q_s32( psSampleState[ 1 ].sLTP_shp_Q14, vsubq_s32( sLF_AR_shp_Q14_s32x4, n_LF_Q14_s32x4 ) ); vst1q_s32( psSampleState[ 1 ].LF_AR_Q14, sLF_AR_shp_Q14_s32x4 ); vst1q_s32( psSampleState[ 1 ].LPC_exc_Q14, LPC_exc_Q14_s32x4 ); vst1q_s32( psSampleState[ 1 ].xq_Q14, xq_Q14_s32x4 ); } *smpl_buf_idx = *smpl_buf_idx ? ( *smpl_buf_idx - 1 ) : ( DECISION_DELAY - 1); last_smple_idx = *smpl_buf_idx + decisionDelay + DECISION_DELAY; if( last_smple_idx >= DECISION_DELAY ) last_smple_idx -= DECISION_DELAY; if( last_smple_idx >= DECISION_DELAY ) last_smple_idx -= DECISION_DELAY; /* Find winner */ RDmin_Q10 = psSampleState[ 0 ].RD_Q10[ 0 ]; Winner_ind = 0; for( k = 1; k < nStatesDelayedDecision; k++ ) { if( psSampleState[ 0 ].RD_Q10[ k ] < RDmin_Q10 ) { RDmin_Q10 = psSampleState[ 0 ].RD_Q10[ k ]; Winner_ind = k; } } /* Increase RD values of expired states */ { uint32x4_t t_u32x4; Winner_rand_state = psDelDec->RandState[ last_smple_idx ][ Winner_ind ]; t_u32x4 = vceqq_s32( vld1q_s32( psDelDec->RandState[ last_smple_idx ] ), vdupq_n_s32( Winner_rand_state ) ); t_u32x4 = vmvnq_u32( t_u32x4 ); t_u32x4 = vshrq_n_u32( t_u32x4, 5 ); tmp1_s32x4 = vld1q_s32( psSampleState[ 0 ].RD_Q10 ); tmp2_s32x4 = vld1q_s32( psSampleState[ 1 ].RD_Q10 ); tmp1_s32x4 = vaddq_s32( tmp1_s32x4, vreinterpretq_s32_u32( t_u32x4 ) ); tmp2_s32x4 = vaddq_s32( tmp2_s32x4, vreinterpretq_s32_u32( t_u32x4 ) ); vst1q_s32( psSampleState[ 0 ].RD_Q10, tmp1_s32x4 ); vst1q_s32( psSampleState[ 1 ].RD_Q10, tmp2_s32x4 ); /* Find worst in first set and best in second set */ RDmax_Q10 = psSampleState[ 0 ].RD_Q10[ 0 ]; RDmin_Q10 = psSampleState[ 1 ].RD_Q10[ 0 ]; RDmax_ind = 0; RDmin_ind = 0; for( k = 1; k < nStatesDelayedDecision; k++ ) { /* find worst in first set */ if( psSampleState[ 0 ].RD_Q10[ k ] > RDmax_Q10 ) { RDmax_Q10 = psSampleState[ 0 ].RD_Q10[ k ]; RDmax_ind = k; } /* find best in second set */ if( psSampleState[ 1 ].RD_Q10[ k ] < RDmin_Q10 ) { RDmin_Q10 = psSampleState[ 1 ].RD_Q10[ k ]; RDmin_ind = k; } } } /* Replace a state if best from second set outperforms worst in first set */ if( RDmin_Q10 < RDmax_Q10 ) { opus_int32 (*ptr)[NEON_MAX_DEL_DEC_STATES] = psDelDec->RandState; const int numOthers = (int)( ( sizeof( NSQ_del_decs_struct ) - sizeof( ( (NSQ_del_decs_struct *)0 )->sLPC_Q14 ) ) / ( NEON_MAX_DEL_DEC_STATES * sizeof( opus_int32 ) ) ); /* Only ( predictLPCOrder - 1 ) of sLPC_Q14 buffer need to be updated, though the first several */ /* useless sLPC_Q14[] will be different comparing with C when predictLPCOrder < NSQ_LPC_BUF_LENGTH. */ /* Here just update constant ( NSQ_LPC_BUF_LENGTH - 1 ) for simplicity. */ for( j = i + 1; j < i + NSQ_LPC_BUF_LENGTH; j++ ) { psDelDec->sLPC_Q14[ j ][ RDmax_ind ] = psDelDec->sLPC_Q14[ j ][ RDmin_ind ]; } for( j = 0; j < numOthers; j++ ) { ptr[ j ][ RDmax_ind ] = ptr[ j ][ RDmin_ind ]; } psSampleState[ 0 ].Q_Q10[ RDmax_ind ] = psSampleState[ 1 ].Q_Q10[ RDmin_ind ]; psSampleState[ 0 ].RD_Q10[ RDmax_ind ] = psSampleState[ 1 ].RD_Q10[ RDmin_ind ]; psSampleState[ 0 ].xq_Q14[ RDmax_ind ] = psSampleState[ 1 ].xq_Q14[ RDmin_ind ]; psSampleState[ 0 ].LF_AR_Q14[ RDmax_ind ] = psSampleState[ 1 ].LF_AR_Q14[ RDmin_ind ]; psSampleState[ 0 ].Diff_Q14[ RDmax_ind ] = psSampleState[ 1 ].Diff_Q14[ RDmin_ind ]; psSampleState[ 0 ].sLTP_shp_Q14[ RDmax_ind ] = psSampleState[ 1 ].sLTP_shp_Q14[ RDmin_ind ]; psSampleState[ 0 ].LPC_exc_Q14[ RDmax_ind ] = psSampleState[ 1 ].LPC_exc_Q14[ RDmin_ind ]; } /* Write samples from winner to output and long-term filter states */ if( subfr > 0 || i >= decisionDelay ) { pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDelDec->Q_Q10[ last_smple_idx ][ Winner_ind ], 10 ); xq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( psDelDec->Xq_Q14[ last_smple_idx ][ Winner_ind ], delayedGain_Q10[ last_smple_idx ] ), 8 ) ); NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDelDec->Shape_Q14[ last_smple_idx ][ Winner_ind ]; sLTP_Q15[ NSQ->sLTP_buf_idx - decisionDelay ] = psDelDec->Pred_Q15[ last_smple_idx ][ Winner_ind ]; } NSQ->sLTP_shp_buf_idx++; NSQ->sLTP_buf_idx++; /* Update states */ vst1q_s32( psDelDec->LF_AR_Q14, vld1q_s32( psSampleState[ 0 ].LF_AR_Q14 ) ); vst1q_s32( psDelDec->Diff_Q14, vld1q_s32( psSampleState[ 0 ].Diff_Q14 ) ); vst1q_s32( psDelDec->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ], vld1q_s32( psSampleState[ 0 ].xq_Q14 ) ); vst1q_s32( psDelDec->Xq_Q14[ *smpl_buf_idx ], vld1q_s32( psSampleState[ 0 ].xq_Q14 ) ); tmp1_s32x4 = vld1q_s32( psSampleState[ 0 ].Q_Q10 ); vst1q_s32( psDelDec->Q_Q10[ *smpl_buf_idx ], tmp1_s32x4 ); vst1q_s32( psDelDec->Pred_Q15[ *smpl_buf_idx ], vshlq_n_s32( vld1q_s32( psSampleState[ 0 ].LPC_exc_Q14 ), 1 ) ); vst1q_s32( psDelDec->Shape_Q14[ *smpl_buf_idx ], vld1q_s32( psSampleState[ 0 ].sLTP_shp_Q14 ) ); tmp1_s32x4 = vrshrq_n_s32( tmp1_s32x4, 10 ); tmp1_s32x4 = vaddq_s32( vld1q_s32( psDelDec->Seed ), tmp1_s32x4 ); vst1q_s32( psDelDec->Seed, tmp1_s32x4 ); vst1q_s32( psDelDec->RandState[ *smpl_buf_idx ], tmp1_s32x4 ); vst1q_s32( psDelDec->RD_Q10, vld1q_s32( psSampleState[ 0 ].RD_Q10 ) ); delayedGain_Q10[ *smpl_buf_idx ] = Gain_Q10; } /* Update LPC states */ silk_memcpy( psDelDec->sLPC_Q14[ 0 ], psDelDec->sLPC_Q14[ length ], NEON_MAX_DEL_DEC_STATES * NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); RESTORE_STACK; } static OPUS_INLINE void silk_SMULWB_8_neon( const opus_int16 *a, const int32x2_t b, opus_int32 *o ) { const int16x8_t a_s16x8 = vld1q_s16( a ); int32x4_t o0_s32x4, o1_s32x4; o0_s32x4 = vshll_n_s16( vget_low_s16( a_s16x8 ), 15 ); o1_s32x4 = vshll_n_s16( vget_high_s16( a_s16x8 ), 15 ); o0_s32x4 = vqdmulhq_lane_s32( o0_s32x4, b, 0 ); o1_s32x4 = vqdmulhq_lane_s32( o1_s32x4, b, 0 ); vst1q_s32( o, o0_s32x4 ); vst1q_s32( o + 4, o1_s32x4 ); } /* Only works when ( b >= -65536 ) && ( b < 65536 ). */ static OPUS_INLINE void silk_SMULWW_small_b_4_neon( opus_int32 *a, const int32x2_t b_s32x2) { int32x4_t o_s32x4; o_s32x4 = vld1q_s32( a ); o_s32x4 = vqdmulhq_lane_s32( o_s32x4, b_s32x2, 0 ); vst1q_s32( a, o_s32x4 ); } /* Only works when ( b >= -65536 ) && ( b < 65536 ). */ static OPUS_INLINE void silk_SMULWW_small_b_8_neon( opus_int32 *a, const int32x2_t b_s32x2 ) { int32x4_t o0_s32x4, o1_s32x4; o0_s32x4 = vld1q_s32( a ); o1_s32x4 = vld1q_s32( a + 4 ); o0_s32x4 = vqdmulhq_lane_s32( o0_s32x4, b_s32x2, 0 ); o1_s32x4 = vqdmulhq_lane_s32( o1_s32x4, b_s32x2, 0 ); vst1q_s32( a, o0_s32x4 ); vst1q_s32( a + 4, o1_s32x4 ); } static OPUS_INLINE void silk_SMULWW_4_neon( opus_int32 *a, const int32x2_t b_s32x2) { int32x4_t a_s32x4, o_s32x4; a_s32x4 = vld1q_s32( a ); o_s32x4 = vqdmulhq_lane_s32( a_s32x4, b_s32x2, 0 ); o_s32x4 = vmlaq_lane_s32( o_s32x4, a_s32x4, b_s32x2, 1 ); vst1q_s32( a, o_s32x4 ); } static OPUS_INLINE void silk_SMULWW_8_neon( opus_int32 *a, const int32x2_t b_s32x2 ) { int32x4_t a0_s32x4, a1_s32x4, o0_s32x4, o1_s32x4; a0_s32x4 = vld1q_s32( a ); a1_s32x4 = vld1q_s32( a + 4 ); o0_s32x4 = vqdmulhq_lane_s32( a0_s32x4, b_s32x2, 0 ); o1_s32x4 = vqdmulhq_lane_s32( a1_s32x4, b_s32x2, 0 ); o0_s32x4 = vmlaq_lane_s32( o0_s32x4, a0_s32x4, b_s32x2, 1 ); o1_s32x4 = vmlaq_lane_s32( o1_s32x4, a1_s32x4, b_s32x2, 1 ); vst1q_s32( a, o0_s32x4 ); vst1q_s32( a + 4, o1_s32x4 ); } static OPUS_INLINE void silk_SMULWW_loop_neon( const opus_int16 *a, const opus_int32 b, opus_int32 *o, const opus_int loop_num ) { opus_int i; int32x2_t b_s32x2; b_s32x2 = vdup_n_s32( b ); for( i = 0; i < loop_num - 7; i += 8 ) { silk_SMULWB_8_neon( a + i, b_s32x2, o + i ); } for( ; i < loop_num; i++ ) { o[ i ] = silk_SMULWW( a[ i ], b ); } } static OPUS_INLINE void silk_nsq_del_dec_scale_states_neon( const silk_encoder_state *psEncC, /* I Encoder State */ silk_nsq_state *NSQ, /* I/O NSQ state */ NSQ_del_decs_struct psDelDec[], /* I/O Delayed decision states */ const opus_int16 x16[], /* I Input */ opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */ const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */ opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ opus_int subfr, /* I Subframe number */ const opus_int LTP_scale_Q14, /* I LTP state scaling */ const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ const opus_int signal_type, /* I Signal type */ const opus_int decisionDelay /* I Decision delay */ ) { opus_int i, lag; opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q26; lag = pitchL[ subfr ]; inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 ); silk_assert( inv_gain_Q31 != 0 ); /* Scale input */ inv_gain_Q26 = silk_RSHIFT_ROUND( inv_gain_Q31, 5 ); silk_SMULWW_loop_neon( x16, inv_gain_Q26, x_sc_Q10, psEncC->subfr_length ); /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */ if( NSQ->rewhite_flag ) { if( subfr == 0 ) { /* Do LTP downscaling */ inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 ); } silk_SMULWW_loop_neon( sLTP + NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2, inv_gain_Q31, sLTP_Q15 + NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2, lag + LTP_ORDER / 2 ); } /* Adjust for changing gain */ if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) { int32x2_t gain_adj_Q16_s32x2; gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 ); /* Scale long-term shaping state */ if( ( gain_adj_Q16 >= -65536 ) && ( gain_adj_Q16 < 65536 ) ) { gain_adj_Q16_s32x2 = vdup_n_s32( silk_LSHIFT32( gain_adj_Q16, 15 ) ); for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx - 7; i += 8 ) { silk_SMULWW_small_b_8_neon( NSQ->sLTP_shp_Q14 + i, gain_adj_Q16_s32x2 ); } for( ; i < NSQ->sLTP_shp_buf_idx; i++ ) { NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] ); } /* Scale long-term prediction state */ if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) { for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx - decisionDelay - 7; i += 8 ) { silk_SMULWW_small_b_8_neon( sLTP_Q15 + i, gain_adj_Q16_s32x2 ); } for( ; i < NSQ->sLTP_buf_idx - decisionDelay; i++ ) { sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] ); } } /* Scale scalar states */ silk_SMULWW_small_b_4_neon( psDelDec->LF_AR_Q14, gain_adj_Q16_s32x2 ); silk_SMULWW_small_b_4_neon( psDelDec->Diff_Q14, gain_adj_Q16_s32x2 ); /* Scale short-term prediction and shaping states */ for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) { silk_SMULWW_small_b_4_neon( psDelDec->sLPC_Q14[ i ], gain_adj_Q16_s32x2 ); } for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) { silk_SMULWW_small_b_4_neon( psDelDec->sAR2_Q14[ i ], gain_adj_Q16_s32x2 ); } for( i = 0; i < DECISION_DELAY; i++ ) { silk_SMULWW_small_b_4_neon( psDelDec->Pred_Q15[ i ], gain_adj_Q16_s32x2 ); silk_SMULWW_small_b_4_neon( psDelDec->Shape_Q14[ i ], gain_adj_Q16_s32x2 ); } } else { gain_adj_Q16_s32x2 = vdup_n_s32( silk_LSHIFT32( gain_adj_Q16 & 0x0000FFFF, 15 ) ); gain_adj_Q16_s32x2 = vset_lane_s32( gain_adj_Q16 >> 16, gain_adj_Q16_s32x2, 1 ); for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx - 7; i += 8 ) { silk_SMULWW_8_neon( NSQ->sLTP_shp_Q14 + i, gain_adj_Q16_s32x2 ); } for( ; i < NSQ->sLTP_shp_buf_idx; i++ ) { NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] ); } /* Scale long-term prediction state */ if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) { for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx - decisionDelay - 7; i += 8 ) { silk_SMULWW_8_neon( sLTP_Q15 + i, gain_adj_Q16_s32x2 ); } for( ; i < NSQ->sLTP_buf_idx - decisionDelay; i++ ) { sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] ); } } /* Scale scalar states */ silk_SMULWW_4_neon( psDelDec->LF_AR_Q14, gain_adj_Q16_s32x2 ); silk_SMULWW_4_neon( psDelDec->Diff_Q14, gain_adj_Q16_s32x2 ); /* Scale short-term prediction and shaping states */ for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) { silk_SMULWW_4_neon( psDelDec->sLPC_Q14[ i ], gain_adj_Q16_s32x2 ); } for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) { silk_SMULWW_4_neon( psDelDec->sAR2_Q14[ i ], gain_adj_Q16_s32x2 ); } for( i = 0; i < DECISION_DELAY; i++ ) { silk_SMULWW_4_neon( psDelDec->Pred_Q15[ i ], gain_adj_Q16_s32x2 ); silk_SMULWW_4_neon( psDelDec->Shape_Q14[ i ], gain_adj_Q16_s32x2 ); } } /* Save inverse gain */ NSQ->prev_gain_Q16 = Gains_Q16[ subfr ]; } } jamulus-3.9.1+dfsg/libs/opus/silk/interpolate.c0000644000175000017500000000505114340334543020530 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" /* Interpolate two vectors */ void silk_interpolate( opus_int16 xi[ MAX_LPC_ORDER ], /* O interpolated vector */ const opus_int16 x0[ MAX_LPC_ORDER ], /* I first vector */ const opus_int16 x1[ MAX_LPC_ORDER ], /* I second vector */ const opus_int ifact_Q2, /* I interp. factor, weight on 2nd vector */ const opus_int d /* I number of parameters */ ) { opus_int i; celt_assert( ifact_Q2 >= 0 ); celt_assert( ifact_Q2 <= 4 ); for( i = 0; i < d; i++ ) { xi[ i ] = (opus_int16)silk_ADD_RSHIFT( x0[ i ], silk_SMULBB( x1[ i ] - x0[ i ], ifact_Q2 ), 2 ); } } jamulus-3.9.1+dfsg/libs/opus/silk/resampler_private_down_FIR.c0000644000175000017500000002522114340334543023456 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FIX.h" #include "resampler_private.h" #include "stack_alloc.h" static OPUS_INLINE opus_int16 *silk_resampler_private_down_FIR_INTERPOL( opus_int16 *out, opus_int32 *buf, const opus_int16 *FIR_Coefs, opus_int FIR_Order, opus_int FIR_Fracs, opus_int32 max_index_Q16, opus_int32 index_increment_Q16 ) { opus_int32 index_Q16, res_Q6; opus_int32 *buf_ptr; opus_int32 interpol_ind; const opus_int16 *interpol_ptr; switch( FIR_Order ) { case RESAMPLER_DOWN_ORDER_FIR0: for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) { /* Integer part gives pointer to buffered input */ buf_ptr = buf + silk_RSHIFT( index_Q16, 16 ); /* Fractional part gives interpolation coefficients */ interpol_ind = silk_SMULWB( index_Q16 & 0xFFFF, FIR_Fracs ); /* Inner product */ interpol_ptr = &FIR_Coefs[ RESAMPLER_DOWN_ORDER_FIR0 / 2 * interpol_ind ]; res_Q6 = silk_SMULWB( buf_ptr[ 0 ], interpol_ptr[ 0 ] ); res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 1 ], interpol_ptr[ 1 ] ); res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 2 ], interpol_ptr[ 2 ] ); res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 3 ], interpol_ptr[ 3 ] ); res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 4 ], interpol_ptr[ 4 ] ); res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 5 ], interpol_ptr[ 5 ] ); res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 6 ], interpol_ptr[ 6 ] ); res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 7 ], interpol_ptr[ 7 ] ); res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 8 ], interpol_ptr[ 8 ] ); interpol_ptr = &FIR_Coefs[ RESAMPLER_DOWN_ORDER_FIR0 / 2 * ( FIR_Fracs - 1 - interpol_ind ) ]; res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 17 ], interpol_ptr[ 0 ] ); res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 16 ], interpol_ptr[ 1 ] ); res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 15 ], interpol_ptr[ 2 ] ); res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 14 ], interpol_ptr[ 3 ] ); res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 13 ], interpol_ptr[ 4 ] ); res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 12 ], interpol_ptr[ 5 ] ); res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 11 ], interpol_ptr[ 6 ] ); res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 10 ], interpol_ptr[ 7 ] ); res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 9 ], interpol_ptr[ 8 ] ); /* Scale down, saturate and store in output array */ *out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q6, 6 ) ); } break; case RESAMPLER_DOWN_ORDER_FIR1: for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) { /* Integer part gives pointer to buffered input */ buf_ptr = buf + silk_RSHIFT( index_Q16, 16 ); /* Inner product */ res_Q6 = silk_SMULWB( silk_ADD32( buf_ptr[ 0 ], buf_ptr[ 23 ] ), FIR_Coefs[ 0 ] ); res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 1 ], buf_ptr[ 22 ] ), FIR_Coefs[ 1 ] ); res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 2 ], buf_ptr[ 21 ] ), FIR_Coefs[ 2 ] ); res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 3 ], buf_ptr[ 20 ] ), FIR_Coefs[ 3 ] ); res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 4 ], buf_ptr[ 19 ] ), FIR_Coefs[ 4 ] ); res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 5 ], buf_ptr[ 18 ] ), FIR_Coefs[ 5 ] ); res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 6 ], buf_ptr[ 17 ] ), FIR_Coefs[ 6 ] ); res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 7 ], buf_ptr[ 16 ] ), FIR_Coefs[ 7 ] ); res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 8 ], buf_ptr[ 15 ] ), FIR_Coefs[ 8 ] ); res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 9 ], buf_ptr[ 14 ] ), FIR_Coefs[ 9 ] ); res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 10 ], buf_ptr[ 13 ] ), FIR_Coefs[ 10 ] ); res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 11 ], buf_ptr[ 12 ] ), FIR_Coefs[ 11 ] ); /* Scale down, saturate and store in output array */ *out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q6, 6 ) ); } break; case RESAMPLER_DOWN_ORDER_FIR2: for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) { /* Integer part gives pointer to buffered input */ buf_ptr = buf + silk_RSHIFT( index_Q16, 16 ); /* Inner product */ res_Q6 = silk_SMULWB( silk_ADD32( buf_ptr[ 0 ], buf_ptr[ 35 ] ), FIR_Coefs[ 0 ] ); res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 1 ], buf_ptr[ 34 ] ), FIR_Coefs[ 1 ] ); res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 2 ], buf_ptr[ 33 ] ), FIR_Coefs[ 2 ] ); res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 3 ], buf_ptr[ 32 ] ), FIR_Coefs[ 3 ] ); res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 4 ], buf_ptr[ 31 ] ), FIR_Coefs[ 4 ] ); res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 5 ], buf_ptr[ 30 ] ), FIR_Coefs[ 5 ] ); res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 6 ], buf_ptr[ 29 ] ), FIR_Coefs[ 6 ] ); res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 7 ], buf_ptr[ 28 ] ), FIR_Coefs[ 7 ] ); res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 8 ], buf_ptr[ 27 ] ), FIR_Coefs[ 8 ] ); res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 9 ], buf_ptr[ 26 ] ), FIR_Coefs[ 9 ] ); res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 10 ], buf_ptr[ 25 ] ), FIR_Coefs[ 10 ] ); res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 11 ], buf_ptr[ 24 ] ), FIR_Coefs[ 11 ] ); res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 12 ], buf_ptr[ 23 ] ), FIR_Coefs[ 12 ] ); res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 13 ], buf_ptr[ 22 ] ), FIR_Coefs[ 13 ] ); res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 14 ], buf_ptr[ 21 ] ), FIR_Coefs[ 14 ] ); res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 15 ], buf_ptr[ 20 ] ), FIR_Coefs[ 15 ] ); res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 16 ], buf_ptr[ 19 ] ), FIR_Coefs[ 16 ] ); res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 17 ], buf_ptr[ 18 ] ), FIR_Coefs[ 17 ] ); /* Scale down, saturate and store in output array */ *out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q6, 6 ) ); } break; default: celt_assert( 0 ); } return out; } /* Resample with a 2nd order AR filter followed by FIR interpolation */ void silk_resampler_private_down_FIR( void *SS, /* I/O Resampler state */ opus_int16 out[], /* O Output signal */ const opus_int16 in[], /* I Input signal */ opus_int32 inLen /* I Number of input samples */ ) { silk_resampler_state_struct *S = (silk_resampler_state_struct *)SS; opus_int32 nSamplesIn; opus_int32 max_index_Q16, index_increment_Q16; VARDECL( opus_int32, buf ); const opus_int16 *FIR_Coefs; SAVE_STACK; ALLOC( buf, S->batchSize + S->FIR_Order, opus_int32 ); /* Copy buffered samples to start of buffer */ silk_memcpy( buf, S->sFIR.i32, S->FIR_Order * sizeof( opus_int32 ) ); FIR_Coefs = &S->Coefs[ 2 ]; /* Iterate over blocks of frameSizeIn input samples */ index_increment_Q16 = S->invRatio_Q16; while( 1 ) { nSamplesIn = silk_min( inLen, S->batchSize ); /* Second-order AR filter (output in Q8) */ silk_resampler_private_AR2( S->sIIR, &buf[ S->FIR_Order ], in, S->Coefs, nSamplesIn ); max_index_Q16 = silk_LSHIFT32( nSamplesIn, 16 ); /* Interpolate filtered signal */ out = silk_resampler_private_down_FIR_INTERPOL( out, buf, FIR_Coefs, S->FIR_Order, S->FIR_Fracs, max_index_Q16, index_increment_Q16 ); in += nSamplesIn; inLen -= nSamplesIn; if( inLen > 1 ) { /* More iterations to do; copy last part of filtered signal to beginning of buffer */ silk_memcpy( buf, &buf[ nSamplesIn ], S->FIR_Order * sizeof( opus_int32 ) ); } else { break; } } /* Copy last part of filtered signal to the state for the next call */ silk_memcpy( S->sFIR.i32, &buf[ nSamplesIn ], S->FIR_Order * sizeof( opus_int32 ) ); RESTORE_STACK; } jamulus-3.9.1+dfsg/libs/opus/silk/check_control_input.c0000644000175000017500000001151314340334543022236 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" #include "control.h" #include "errors.h" /* Check encoder control struct */ opus_int check_control_input( silk_EncControlStruct *encControl /* I Control structure */ ) { celt_assert( encControl != NULL ); if( ( ( encControl->API_sampleRate != 8000 ) && ( encControl->API_sampleRate != 12000 ) && ( encControl->API_sampleRate != 16000 ) && ( encControl->API_sampleRate != 24000 ) && ( encControl->API_sampleRate != 32000 ) && ( encControl->API_sampleRate != 44100 ) && ( encControl->API_sampleRate != 48000 ) ) || ( ( encControl->desiredInternalSampleRate != 8000 ) && ( encControl->desiredInternalSampleRate != 12000 ) && ( encControl->desiredInternalSampleRate != 16000 ) ) || ( ( encControl->maxInternalSampleRate != 8000 ) && ( encControl->maxInternalSampleRate != 12000 ) && ( encControl->maxInternalSampleRate != 16000 ) ) || ( ( encControl->minInternalSampleRate != 8000 ) && ( encControl->minInternalSampleRate != 12000 ) && ( encControl->minInternalSampleRate != 16000 ) ) || ( encControl->minInternalSampleRate > encControl->desiredInternalSampleRate ) || ( encControl->maxInternalSampleRate < encControl->desiredInternalSampleRate ) || ( encControl->minInternalSampleRate > encControl->maxInternalSampleRate ) ) { celt_assert( 0 ); return SILK_ENC_FS_NOT_SUPPORTED; } if( encControl->payloadSize_ms != 10 && encControl->payloadSize_ms != 20 && encControl->payloadSize_ms != 40 && encControl->payloadSize_ms != 60 ) { celt_assert( 0 ); return SILK_ENC_PACKET_SIZE_NOT_SUPPORTED; } if( encControl->packetLossPercentage < 0 || encControl->packetLossPercentage > 100 ) { celt_assert( 0 ); return SILK_ENC_INVALID_LOSS_RATE; } if( encControl->useDTX < 0 || encControl->useDTX > 1 ) { celt_assert( 0 ); return SILK_ENC_INVALID_DTX_SETTING; } if( encControl->useCBR < 0 || encControl->useCBR > 1 ) { celt_assert( 0 ); return SILK_ENC_INVALID_CBR_SETTING; } if( encControl->useInBandFEC < 0 || encControl->useInBandFEC > 1 ) { celt_assert( 0 ); return SILK_ENC_INVALID_INBAND_FEC_SETTING; } if( encControl->nChannelsAPI < 1 || encControl->nChannelsAPI > ENCODER_NUM_CHANNELS ) { celt_assert( 0 ); return SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR; } if( encControl->nChannelsInternal < 1 || encControl->nChannelsInternal > ENCODER_NUM_CHANNELS ) { celt_assert( 0 ); return SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR; } if( encControl->nChannelsInternal > encControl->nChannelsAPI ) { celt_assert( 0 ); return SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR; } if( encControl->complexity < 0 || encControl->complexity > 10 ) { celt_assert( 0 ); return SILK_ENC_INVALID_COMPLEXITY_SETTING; } return SILK_NO_ERROR; } jamulus-3.9.1+dfsg/libs/opus/silk/process_NLSFs.c0000644000175000017500000001250714340334543020671 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" /* Limit, stabilize, convert and quantize NLSFs */ void silk_process_NLSFs( silk_encoder_state *psEncC, /* I/O Encoder state */ opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ], /* O Prediction coefficients */ opus_int16 pNLSF_Q15[ MAX_LPC_ORDER ], /* I/O Normalized LSFs (quant out) (0 - (2^15-1)) */ const opus_int16 prev_NLSFq_Q15[ MAX_LPC_ORDER ] /* I Previous Normalized LSFs (0 - (2^15-1)) */ ) { opus_int i, doInterpolate; opus_int NLSF_mu_Q20; opus_int16 i_sqr_Q15; opus_int16 pNLSF0_temp_Q15[ MAX_LPC_ORDER ]; opus_int16 pNLSFW_QW[ MAX_LPC_ORDER ]; opus_int16 pNLSFW0_temp_QW[ MAX_LPC_ORDER ]; silk_assert( psEncC->speech_activity_Q8 >= 0 ); silk_assert( psEncC->speech_activity_Q8 <= SILK_FIX_CONST( 1.0, 8 ) ); celt_assert( psEncC->useInterpolatedNLSFs == 1 || psEncC->indices.NLSFInterpCoef_Q2 == ( 1 << 2 ) ); /***********************/ /* Calculate mu values */ /***********************/ /* NLSF_mu = 0.003 - 0.0015 * psEnc->speech_activity; */ NLSF_mu_Q20 = silk_SMLAWB( SILK_FIX_CONST( 0.003, 20 ), SILK_FIX_CONST( -0.001, 28 ), psEncC->speech_activity_Q8 ); if( psEncC->nb_subfr == 2 ) { /* Multiply by 1.5 for 10 ms packets */ NLSF_mu_Q20 = silk_ADD_RSHIFT( NLSF_mu_Q20, NLSF_mu_Q20, 1 ); } celt_assert( NLSF_mu_Q20 > 0 ); silk_assert( NLSF_mu_Q20 <= SILK_FIX_CONST( 0.005, 20 ) ); /* Calculate NLSF weights */ silk_NLSF_VQ_weights_laroia( pNLSFW_QW, pNLSF_Q15, psEncC->predictLPCOrder ); /* Update NLSF weights for interpolated NLSFs */ doInterpolate = ( psEncC->useInterpolatedNLSFs == 1 ) && ( psEncC->indices.NLSFInterpCoef_Q2 < 4 ); if( doInterpolate ) { /* Calculate the interpolated NLSF vector for the first half */ silk_interpolate( pNLSF0_temp_Q15, prev_NLSFq_Q15, pNLSF_Q15, psEncC->indices.NLSFInterpCoef_Q2, psEncC->predictLPCOrder ); /* Calculate first half NLSF weights for the interpolated NLSFs */ silk_NLSF_VQ_weights_laroia( pNLSFW0_temp_QW, pNLSF0_temp_Q15, psEncC->predictLPCOrder ); /* Update NLSF weights with contribution from first half */ i_sqr_Q15 = silk_LSHIFT( silk_SMULBB( psEncC->indices.NLSFInterpCoef_Q2, psEncC->indices.NLSFInterpCoef_Q2 ), 11 ); for( i = 0; i < psEncC->predictLPCOrder; i++ ) { pNLSFW_QW[ i ] = silk_ADD16( silk_RSHIFT( pNLSFW_QW[ i ], 1 ), silk_RSHIFT( silk_SMULBB( pNLSFW0_temp_QW[ i ], i_sqr_Q15 ), 16) ); silk_assert( pNLSFW_QW[ i ] >= 1 ); } } silk_NLSF_encode( psEncC->indices.NLSFIndices, pNLSF_Q15, psEncC->psNLSF_CB, pNLSFW_QW, NLSF_mu_Q20, psEncC->NLSF_MSVQ_Survivors, psEncC->indices.signalType ); /* Convert quantized NLSFs back to LPC coefficients */ silk_NLSF2A( PredCoef_Q12[ 1 ], pNLSF_Q15, psEncC->predictLPCOrder, psEncC->arch ); if( doInterpolate ) { /* Calculate the interpolated, quantized LSF vector for the first half */ silk_interpolate( pNLSF0_temp_Q15, prev_NLSFq_Q15, pNLSF_Q15, psEncC->indices.NLSFInterpCoef_Q2, psEncC->predictLPCOrder ); /* Convert back to LPC coefficients */ silk_NLSF2A( PredCoef_Q12[ 0 ], pNLSF0_temp_Q15, psEncC->predictLPCOrder, psEncC->arch ); } else { /* Copy LPC coefficients for first half from second half */ celt_assert( psEncC->predictLPCOrder <= MAX_LPC_ORDER ); silk_memcpy( PredCoef_Q12[ 0 ], PredCoef_Q12[ 1 ], psEncC->predictLPCOrder * sizeof( opus_int16 ) ); } } jamulus-3.9.1+dfsg/libs/opus/silk/tables_pitch_lag.c0000644000175000017500000000577414340334543021502 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "tables.h" const opus_uint8 silk_pitch_lag_iCDF[ 2 * ( PITCH_EST_MAX_LAG_MS - PITCH_EST_MIN_LAG_MS ) ] = { 253, 250, 244, 233, 212, 182, 150, 131, 120, 110, 98, 85, 72, 60, 49, 40, 32, 25, 19, 15, 13, 11, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; const opus_uint8 silk_pitch_delta_iCDF[21] = { 210, 208, 206, 203, 199, 193, 183, 168, 142, 104, 74, 52, 37, 27, 20, 14, 10, 6, 4, 2, 0 }; const opus_uint8 silk_pitch_contour_iCDF[34] = { 223, 201, 183, 167, 152, 138, 124, 111, 98, 88, 79, 70, 62, 56, 50, 44, 39, 35, 31, 27, 24, 21, 18, 16, 14, 12, 10, 8, 6, 4, 3, 2, 1, 0 }; const opus_uint8 silk_pitch_contour_NB_iCDF[11] = { 188, 176, 155, 138, 119, 97, 67, 43, 26, 10, 0 }; const opus_uint8 silk_pitch_contour_10_ms_iCDF[12] = { 165, 119, 80, 61, 47, 35, 27, 20, 14, 9, 4, 0 }; const opus_uint8 silk_pitch_contour_10_ms_NB_iCDF[3] = { 113, 63, 0 }; jamulus-3.9.1+dfsg/libs/opus/silk/LPC_analysis_filter.c0000644000175000017500000001162714340334543022076 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FIX.h" #include "celt_lpc.h" /*******************************************/ /* LPC analysis filter */ /* NB! State is kept internally and the */ /* filter always starts with zero state */ /* first d output samples are set to zero */ /*******************************************/ /* OPT: Using celt_fir() for this function should be faster, but it may cause integer overflows in intermediate values (not final results), which the current implementation silences by casting to unsigned. Enabling this should be safe in pretty much all cases, even though it is not technically C89-compliant. */ #define USE_CELT_FIR 0 void silk_LPC_analysis_filter( opus_int16 *out, /* O Output signal */ const opus_int16 *in, /* I Input signal */ const opus_int16 *B, /* I MA prediction coefficients, Q12 [order] */ const opus_int32 len, /* I Signal length */ const opus_int32 d, /* I Filter order */ int arch /* I Run-time architecture */ ) { opus_int j; #if defined(FIXED_POINT) && USE_CELT_FIR opus_int16 num[SILK_MAX_ORDER_LPC]; #else int ix; opus_int32 out32_Q12, out32; const opus_int16 *in_ptr; #endif celt_assert( d >= 6 ); celt_assert( (d & 1) == 0 ); celt_assert( d <= len ); #if defined(FIXED_POINT) && USE_CELT_FIR celt_assert( d <= SILK_MAX_ORDER_LPC ); for ( j = 0; j < d; j++ ) { num[ j ] = -B[ j ]; } celt_fir( in + d, num, out + d, len - d, d, arch ); for ( j = 0; j < d; j++ ) { out[ j ] = 0; } #else (void)arch; for( ix = d; ix < len; ix++ ) { in_ptr = &in[ ix - 1 ]; out32_Q12 = silk_SMULBB( in_ptr[ 0 ], B[ 0 ] ); /* Allowing wrap around so that two wraps can cancel each other. The rare cases where the result wraps around can only be triggered by invalid streams*/ out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -1 ], B[ 1 ] ); out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -2 ], B[ 2 ] ); out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -3 ], B[ 3 ] ); out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -4 ], B[ 4 ] ); out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -5 ], B[ 5 ] ); for( j = 6; j < d; j += 2 ) { out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -j ], B[ j ] ); out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -j - 1 ], B[ j + 1 ] ); } /* Subtract prediction */ out32_Q12 = silk_SUB32_ovflw( silk_LSHIFT( (opus_int32)in_ptr[ 1 ], 12 ), out32_Q12 ); /* Scale to Q0 */ out32 = silk_RSHIFT_ROUND( out32_Q12, 12 ); /* Saturate output */ out[ ix ] = (opus_int16)silk_SAT16( out32 ); } /* Set first d output samples to zero */ silk_memset( out, 0, d * sizeof( opus_int16 ) ); #endif } jamulus-3.9.1+dfsg/libs/opus/silk/stereo_LR_to_MS.c0000644000175000017500000003027114340334543021203 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" #include "stack_alloc.h" /* Convert Left/Right stereo signal to adaptive Mid/Side representation */ void silk_stereo_LR_to_MS( stereo_enc_state *state, /* I/O State */ opus_int16 x1[], /* I/O Left input signal, becomes mid signal */ opus_int16 x2[], /* I/O Right input signal, becomes side signal */ opus_int8 ix[ 2 ][ 3 ], /* O Quantization indices */ opus_int8 *mid_only_flag, /* O Flag: only mid signal coded */ opus_int32 mid_side_rates_bps[], /* O Bitrates for mid and side signals */ opus_int32 total_rate_bps, /* I Total bitrate */ opus_int prev_speech_act_Q8, /* I Speech activity level in previous frame */ opus_int toMono, /* I Last frame before a stereo->mono transition */ opus_int fs_kHz, /* I Sample rate (kHz) */ opus_int frame_length /* I Number of samples */ ) { opus_int n, is10msFrame, denom_Q16, delta0_Q13, delta1_Q13; opus_int32 sum, diff, smooth_coef_Q16, pred_Q13[ 2 ], pred0_Q13, pred1_Q13; opus_int32 LP_ratio_Q14, HP_ratio_Q14, frac_Q16, frac_3_Q16, min_mid_rate_bps, width_Q14, w_Q24, deltaw_Q24; VARDECL( opus_int16, side ); VARDECL( opus_int16, LP_mid ); VARDECL( opus_int16, HP_mid ); VARDECL( opus_int16, LP_side ); VARDECL( opus_int16, HP_side ); opus_int16 *mid = &x1[ -2 ]; SAVE_STACK; ALLOC( side, frame_length + 2, opus_int16 ); /* Convert to basic mid/side signals */ for( n = 0; n < frame_length + 2; n++ ) { sum = x1[ n - 2 ] + (opus_int32)x2[ n - 2 ]; diff = x1[ n - 2 ] - (opus_int32)x2[ n - 2 ]; mid[ n ] = (opus_int16)silk_RSHIFT_ROUND( sum, 1 ); side[ n ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( diff, 1 ) ); } /* Buffering */ silk_memcpy( mid, state->sMid, 2 * sizeof( opus_int16 ) ); silk_memcpy( side, state->sSide, 2 * sizeof( opus_int16 ) ); silk_memcpy( state->sMid, &mid[ frame_length ], 2 * sizeof( opus_int16 ) ); silk_memcpy( state->sSide, &side[ frame_length ], 2 * sizeof( opus_int16 ) ); /* LP and HP filter mid signal */ ALLOC( LP_mid, frame_length, opus_int16 ); ALLOC( HP_mid, frame_length, opus_int16 ); for( n = 0; n < frame_length; n++ ) { sum = silk_RSHIFT_ROUND( silk_ADD_LSHIFT( mid[ n ] + (opus_int32)mid[ n + 2 ], mid[ n + 1 ], 1 ), 2 ); LP_mid[ n ] = sum; HP_mid[ n ] = mid[ n + 1 ] - sum; } /* LP and HP filter side signal */ ALLOC( LP_side, frame_length, opus_int16 ); ALLOC( HP_side, frame_length, opus_int16 ); for( n = 0; n < frame_length; n++ ) { sum = silk_RSHIFT_ROUND( silk_ADD_LSHIFT( side[ n ] + (opus_int32)side[ n + 2 ], side[ n + 1 ], 1 ), 2 ); LP_side[ n ] = sum; HP_side[ n ] = side[ n + 1 ] - sum; } /* Find energies and predictors */ is10msFrame = frame_length == 10 * fs_kHz; smooth_coef_Q16 = is10msFrame ? SILK_FIX_CONST( STEREO_RATIO_SMOOTH_COEF / 2, 16 ) : SILK_FIX_CONST( STEREO_RATIO_SMOOTH_COEF, 16 ); smooth_coef_Q16 = silk_SMULWB( silk_SMULBB( prev_speech_act_Q8, prev_speech_act_Q8 ), smooth_coef_Q16 ); pred_Q13[ 0 ] = silk_stereo_find_predictor( &LP_ratio_Q14, LP_mid, LP_side, &state->mid_side_amp_Q0[ 0 ], frame_length, smooth_coef_Q16 ); pred_Q13[ 1 ] = silk_stereo_find_predictor( &HP_ratio_Q14, HP_mid, HP_side, &state->mid_side_amp_Q0[ 2 ], frame_length, smooth_coef_Q16 ); /* Ratio of the norms of residual and mid signals */ frac_Q16 = silk_SMLABB( HP_ratio_Q14, LP_ratio_Q14, 3 ); frac_Q16 = silk_min( frac_Q16, SILK_FIX_CONST( 1, 16 ) ); /* Determine bitrate distribution between mid and side, and possibly reduce stereo width */ total_rate_bps -= is10msFrame ? 1200 : 600; /* Subtract approximate bitrate for coding stereo parameters */ if( total_rate_bps < 1 ) { total_rate_bps = 1; } min_mid_rate_bps = silk_SMLABB( 2000, fs_kHz, 600 ); silk_assert( min_mid_rate_bps < 32767 ); /* Default bitrate distribution: 8 parts for Mid and (5+3*frac) parts for Side. so: mid_rate = ( 8 / ( 13 + 3 * frac ) ) * total_ rate */ frac_3_Q16 = silk_MUL( 3, frac_Q16 ); mid_side_rates_bps[ 0 ] = silk_DIV32_varQ( total_rate_bps, SILK_FIX_CONST( 8 + 5, 16 ) + frac_3_Q16, 16+3 ); /* If Mid bitrate below minimum, reduce stereo width */ if( mid_side_rates_bps[ 0 ] < min_mid_rate_bps ) { mid_side_rates_bps[ 0 ] = min_mid_rate_bps; mid_side_rates_bps[ 1 ] = total_rate_bps - mid_side_rates_bps[ 0 ]; /* width = 4 * ( 2 * side_rate - min_rate ) / ( ( 1 + 3 * frac ) * min_rate ) */ width_Q14 = silk_DIV32_varQ( silk_LSHIFT( mid_side_rates_bps[ 1 ], 1 ) - min_mid_rate_bps, silk_SMULWB( SILK_FIX_CONST( 1, 16 ) + frac_3_Q16, min_mid_rate_bps ), 14+2 ); width_Q14 = silk_LIMIT( width_Q14, 0, SILK_FIX_CONST( 1, 14 ) ); } else { mid_side_rates_bps[ 1 ] = total_rate_bps - mid_side_rates_bps[ 0 ]; width_Q14 = SILK_FIX_CONST( 1, 14 ); } /* Smoother */ state->smth_width_Q14 = (opus_int16)silk_SMLAWB( state->smth_width_Q14, width_Q14 - state->smth_width_Q14, smooth_coef_Q16 ); /* At very low bitrates or for inputs that are nearly amplitude panned, switch to panned-mono coding */ *mid_only_flag = 0; if( toMono ) { /* Last frame before stereo->mono transition; collapse stereo width */ width_Q14 = 0; pred_Q13[ 0 ] = 0; pred_Q13[ 1 ] = 0; silk_stereo_quant_pred( pred_Q13, ix ); } else if( state->width_prev_Q14 == 0 && ( 8 * total_rate_bps < 13 * min_mid_rate_bps || silk_SMULWB( frac_Q16, state->smth_width_Q14 ) < SILK_FIX_CONST( 0.05, 14 ) ) ) { /* Code as panned-mono; previous frame already had zero width */ /* Scale down and quantize predictors */ pred_Q13[ 0 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 0 ] ), 14 ); pred_Q13[ 1 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 1 ] ), 14 ); silk_stereo_quant_pred( pred_Q13, ix ); /* Collapse stereo width */ width_Q14 = 0; pred_Q13[ 0 ] = 0; pred_Q13[ 1 ] = 0; mid_side_rates_bps[ 0 ] = total_rate_bps; mid_side_rates_bps[ 1 ] = 0; *mid_only_flag = 1; } else if( state->width_prev_Q14 != 0 && ( 8 * total_rate_bps < 11 * min_mid_rate_bps || silk_SMULWB( frac_Q16, state->smth_width_Q14 ) < SILK_FIX_CONST( 0.02, 14 ) ) ) { /* Transition to zero-width stereo */ /* Scale down and quantize predictors */ pred_Q13[ 0 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 0 ] ), 14 ); pred_Q13[ 1 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 1 ] ), 14 ); silk_stereo_quant_pred( pred_Q13, ix ); /* Collapse stereo width */ width_Q14 = 0; pred_Q13[ 0 ] = 0; pred_Q13[ 1 ] = 0; } else if( state->smth_width_Q14 > SILK_FIX_CONST( 0.95, 14 ) ) { /* Full-width stereo coding */ silk_stereo_quant_pred( pred_Q13, ix ); width_Q14 = SILK_FIX_CONST( 1, 14 ); } else { /* Reduced-width stereo coding; scale down and quantize predictors */ pred_Q13[ 0 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 0 ] ), 14 ); pred_Q13[ 1 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 1 ] ), 14 ); silk_stereo_quant_pred( pred_Q13, ix ); width_Q14 = state->smth_width_Q14; } /* Make sure to keep on encoding until the tapered output has been transmitted */ if( *mid_only_flag == 1 ) { state->silent_side_len += frame_length - STEREO_INTERP_LEN_MS * fs_kHz; if( state->silent_side_len < LA_SHAPE_MS * fs_kHz ) { *mid_only_flag = 0; } else { /* Limit to avoid wrapping around */ state->silent_side_len = 10000; } } else { state->silent_side_len = 0; } if( *mid_only_flag == 0 && mid_side_rates_bps[ 1 ] < 1 ) { mid_side_rates_bps[ 1 ] = 1; mid_side_rates_bps[ 0 ] = silk_max_int( 1, total_rate_bps - mid_side_rates_bps[ 1 ]); } /* Interpolate predictors and subtract prediction from side channel */ pred0_Q13 = -state->pred_prev_Q13[ 0 ]; pred1_Q13 = -state->pred_prev_Q13[ 1 ]; w_Q24 = silk_LSHIFT( state->width_prev_Q14, 10 ); denom_Q16 = silk_DIV32_16( (opus_int32)1 << 16, STEREO_INTERP_LEN_MS * fs_kHz ); delta0_Q13 = -silk_RSHIFT_ROUND( silk_SMULBB( pred_Q13[ 0 ] - state->pred_prev_Q13[ 0 ], denom_Q16 ), 16 ); delta1_Q13 = -silk_RSHIFT_ROUND( silk_SMULBB( pred_Q13[ 1 ] - state->pred_prev_Q13[ 1 ], denom_Q16 ), 16 ); deltaw_Q24 = silk_LSHIFT( silk_SMULWB( width_Q14 - state->width_prev_Q14, denom_Q16 ), 10 ); for( n = 0; n < STEREO_INTERP_LEN_MS * fs_kHz; n++ ) { pred0_Q13 += delta0_Q13; pred1_Q13 += delta1_Q13; w_Q24 += deltaw_Q24; sum = silk_LSHIFT( silk_ADD_LSHIFT( mid[ n ] + (opus_int32)mid[ n + 2 ], mid[ n + 1 ], 1 ), 9 ); /* Q11 */ sum = silk_SMLAWB( silk_SMULWB( w_Q24, side[ n + 1 ] ), sum, pred0_Q13 ); /* Q8 */ sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)mid[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */ x2[ n - 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) ); } pred0_Q13 = -pred_Q13[ 0 ]; pred1_Q13 = -pred_Q13[ 1 ]; w_Q24 = silk_LSHIFT( width_Q14, 10 ); for( n = STEREO_INTERP_LEN_MS * fs_kHz; n < frame_length; n++ ) { sum = silk_LSHIFT( silk_ADD_LSHIFT( mid[ n ] + (opus_int32)mid[ n + 2 ], mid[ n + 1 ], 1 ), 9 ); /* Q11 */ sum = silk_SMLAWB( silk_SMULWB( w_Q24, side[ n + 1 ] ), sum, pred0_Q13 ); /* Q8 */ sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)mid[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */ x2[ n - 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) ); } state->pred_prev_Q13[ 0 ] = (opus_int16)pred_Q13[ 0 ]; state->pred_prev_Q13[ 1 ] = (opus_int16)pred_Q13[ 1 ]; state->width_prev_Q14 = (opus_int16)width_Q14; RESTORE_STACK; } jamulus-3.9.1+dfsg/libs/opus/silk/NLSF_del_dec_quant.c0000644000175000017500000002717014340334543021621 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" /* Delayed-decision quantizer for NLSF residuals */ opus_int32 silk_NLSF_del_dec_quant( /* O Returns RD value in Q25 */ opus_int8 indices[], /* O Quantization indices [ order ] */ const opus_int16 x_Q10[], /* I Input [ order ] */ const opus_int16 w_Q5[], /* I Weights [ order ] */ const opus_uint8 pred_coef_Q8[], /* I Backward predictor coefs [ order ] */ const opus_int16 ec_ix[], /* I Indices to entropy coding tables [ order ] */ const opus_uint8 ec_rates_Q5[], /* I Rates [] */ const opus_int quant_step_size_Q16, /* I Quantization step size */ const opus_int16 inv_quant_step_size_Q6, /* I Inverse quantization step size */ const opus_int32 mu_Q20, /* I R/D tradeoff */ const opus_int16 order /* I Number of input values */ ) { opus_int i, j, nStates, ind_tmp, ind_min_max, ind_max_min, in_Q10, res_Q10; opus_int pred_Q10, diff_Q10, rate0_Q5, rate1_Q5; opus_int16 out0_Q10, out1_Q10; opus_int32 RD_tmp_Q25, min_Q25, min_max_Q25, max_min_Q25; opus_int ind_sort[ NLSF_QUANT_DEL_DEC_STATES ]; opus_int8 ind[ NLSF_QUANT_DEL_DEC_STATES ][ MAX_LPC_ORDER ]; opus_int16 prev_out_Q10[ 2 * NLSF_QUANT_DEL_DEC_STATES ]; opus_int32 RD_Q25[ 2 * NLSF_QUANT_DEL_DEC_STATES ]; opus_int32 RD_min_Q25[ NLSF_QUANT_DEL_DEC_STATES ]; opus_int32 RD_max_Q25[ NLSF_QUANT_DEL_DEC_STATES ]; const opus_uint8 *rates_Q5; opus_int out0_Q10_table[2 * NLSF_QUANT_MAX_AMPLITUDE_EXT]; opus_int out1_Q10_table[2 * NLSF_QUANT_MAX_AMPLITUDE_EXT]; for (i = -NLSF_QUANT_MAX_AMPLITUDE_EXT; i <= NLSF_QUANT_MAX_AMPLITUDE_EXT-1; i++) { out0_Q10 = silk_LSHIFT( i, 10 ); out1_Q10 = silk_ADD16( out0_Q10, 1024 ); if( i > 0 ) { out0_Q10 = silk_SUB16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) ); out1_Q10 = silk_SUB16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) ); } else if( i == 0 ) { out1_Q10 = silk_SUB16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) ); } else if( i == -1 ) { out0_Q10 = silk_ADD16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) ); } else { out0_Q10 = silk_ADD16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) ); out1_Q10 = silk_ADD16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) ); } out0_Q10_table[ i + NLSF_QUANT_MAX_AMPLITUDE_EXT ] = silk_RSHIFT( silk_SMULBB( out0_Q10, quant_step_size_Q16 ), 16 ); out1_Q10_table[ i + NLSF_QUANT_MAX_AMPLITUDE_EXT ] = silk_RSHIFT( silk_SMULBB( out1_Q10, quant_step_size_Q16 ), 16 ); } silk_assert( (NLSF_QUANT_DEL_DEC_STATES & (NLSF_QUANT_DEL_DEC_STATES-1)) == 0 ); /* must be power of two */ nStates = 1; RD_Q25[ 0 ] = 0; prev_out_Q10[ 0 ] = 0; for( i = order - 1; i >= 0; i-- ) { rates_Q5 = &ec_rates_Q5[ ec_ix[ i ] ]; in_Q10 = x_Q10[ i ]; for( j = 0; j < nStates; j++ ) { pred_Q10 = silk_RSHIFT( silk_SMULBB( (opus_int16)pred_coef_Q8[ i ], prev_out_Q10[ j ] ), 8 ); res_Q10 = silk_SUB16( in_Q10, pred_Q10 ); ind_tmp = silk_RSHIFT( silk_SMULBB( inv_quant_step_size_Q6, res_Q10 ), 16 ); ind_tmp = silk_LIMIT( ind_tmp, -NLSF_QUANT_MAX_AMPLITUDE_EXT, NLSF_QUANT_MAX_AMPLITUDE_EXT-1 ); ind[ j ][ i ] = (opus_int8)ind_tmp; /* compute outputs for ind_tmp and ind_tmp + 1 */ out0_Q10 = out0_Q10_table[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE_EXT ]; out1_Q10 = out1_Q10_table[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE_EXT ]; out0_Q10 = silk_ADD16( out0_Q10, pred_Q10 ); out1_Q10 = silk_ADD16( out1_Q10, pred_Q10 ); prev_out_Q10[ j ] = out0_Q10; prev_out_Q10[ j + nStates ] = out1_Q10; /* compute RD for ind_tmp and ind_tmp + 1 */ if( ind_tmp + 1 >= NLSF_QUANT_MAX_AMPLITUDE ) { if( ind_tmp + 1 == NLSF_QUANT_MAX_AMPLITUDE ) { rate0_Q5 = rates_Q5[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE ]; rate1_Q5 = 280; } else { rate0_Q5 = silk_SMLABB( 280 - 43 * NLSF_QUANT_MAX_AMPLITUDE, 43, ind_tmp ); rate1_Q5 = silk_ADD16( rate0_Q5, 43 ); } } else if( ind_tmp <= -NLSF_QUANT_MAX_AMPLITUDE ) { if( ind_tmp == -NLSF_QUANT_MAX_AMPLITUDE ) { rate0_Q5 = 280; rate1_Q5 = rates_Q5[ ind_tmp + 1 + NLSF_QUANT_MAX_AMPLITUDE ]; } else { rate0_Q5 = silk_SMLABB( 280 - 43 * NLSF_QUANT_MAX_AMPLITUDE, -43, ind_tmp ); rate1_Q5 = silk_SUB16( rate0_Q5, 43 ); } } else { rate0_Q5 = rates_Q5[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE ]; rate1_Q5 = rates_Q5[ ind_tmp + 1 + NLSF_QUANT_MAX_AMPLITUDE ]; } RD_tmp_Q25 = RD_Q25[ j ]; diff_Q10 = silk_SUB16( in_Q10, out0_Q10 ); RD_Q25[ j ] = silk_SMLABB( silk_MLA( RD_tmp_Q25, silk_SMULBB( diff_Q10, diff_Q10 ), w_Q5[ i ] ), mu_Q20, rate0_Q5 ); diff_Q10 = silk_SUB16( in_Q10, out1_Q10 ); RD_Q25[ j + nStates ] = silk_SMLABB( silk_MLA( RD_tmp_Q25, silk_SMULBB( diff_Q10, diff_Q10 ), w_Q5[ i ] ), mu_Q20, rate1_Q5 ); } if( nStates <= NLSF_QUANT_DEL_DEC_STATES/2 ) { /* double number of states and copy */ for( j = 0; j < nStates; j++ ) { ind[ j + nStates ][ i ] = ind[ j ][ i ] + 1; } nStates = silk_LSHIFT( nStates, 1 ); for( j = nStates; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) { ind[ j ][ i ] = ind[ j - nStates ][ i ]; } } else { /* sort lower and upper half of RD_Q25, pairwise */ for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) { if( RD_Q25[ j ] > RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ] ) { RD_max_Q25[ j ] = RD_Q25[ j ]; RD_min_Q25[ j ] = RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ]; RD_Q25[ j ] = RD_min_Q25[ j ]; RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ] = RD_max_Q25[ j ]; /* swap prev_out values */ out0_Q10 = prev_out_Q10[ j ]; prev_out_Q10[ j ] = prev_out_Q10[ j + NLSF_QUANT_DEL_DEC_STATES ]; prev_out_Q10[ j + NLSF_QUANT_DEL_DEC_STATES ] = out0_Q10; ind_sort[ j ] = j + NLSF_QUANT_DEL_DEC_STATES; } else { RD_min_Q25[ j ] = RD_Q25[ j ]; RD_max_Q25[ j ] = RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ]; ind_sort[ j ] = j; } } /* compare the highest RD values of the winning half with the lowest one in the losing half, and copy if necessary */ /* afterwards ind_sort[] will contain the indices of the NLSF_QUANT_DEL_DEC_STATES winning RD values */ while( 1 ) { min_max_Q25 = silk_int32_MAX; max_min_Q25 = 0; ind_min_max = 0; ind_max_min = 0; for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) { if( min_max_Q25 > RD_max_Q25[ j ] ) { min_max_Q25 = RD_max_Q25[ j ]; ind_min_max = j; } if( max_min_Q25 < RD_min_Q25[ j ] ) { max_min_Q25 = RD_min_Q25[ j ]; ind_max_min = j; } } if( min_max_Q25 >= max_min_Q25 ) { break; } /* copy ind_min_max to ind_max_min */ ind_sort[ ind_max_min ] = ind_sort[ ind_min_max ] ^ NLSF_QUANT_DEL_DEC_STATES; RD_Q25[ ind_max_min ] = RD_Q25[ ind_min_max + NLSF_QUANT_DEL_DEC_STATES ]; prev_out_Q10[ ind_max_min ] = prev_out_Q10[ ind_min_max + NLSF_QUANT_DEL_DEC_STATES ]; RD_min_Q25[ ind_max_min ] = 0; RD_max_Q25[ ind_min_max ] = silk_int32_MAX; silk_memcpy( ind[ ind_max_min ], ind[ ind_min_max ], MAX_LPC_ORDER * sizeof( opus_int8 ) ); } /* increment index if it comes from the upper half */ for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) { ind[ j ][ i ] += silk_RSHIFT( ind_sort[ j ], NLSF_QUANT_DEL_DEC_STATES_LOG2 ); } } } /* last sample: find winner, copy indices and return RD value */ ind_tmp = 0; min_Q25 = silk_int32_MAX; for( j = 0; j < 2 * NLSF_QUANT_DEL_DEC_STATES; j++ ) { if( min_Q25 > RD_Q25[ j ] ) { min_Q25 = RD_Q25[ j ]; ind_tmp = j; } } for( j = 0; j < order; j++ ) { indices[ j ] = ind[ ind_tmp & ( NLSF_QUANT_DEL_DEC_STATES - 1 ) ][ j ]; silk_assert( indices[ j ] >= -NLSF_QUANT_MAX_AMPLITUDE_EXT ); silk_assert( indices[ j ] <= NLSF_QUANT_MAX_AMPLITUDE_EXT ); } indices[ 0 ] += silk_RSHIFT( ind_tmp, NLSF_QUANT_DEL_DEC_STATES_LOG2 ); silk_assert( indices[ 0 ] <= NLSF_QUANT_MAX_AMPLITUDE_EXT ); silk_assert( min_Q25 >= 0 ); return min_Q25; } jamulus-3.9.1+dfsg/libs/opus/silk/decoder_set_fs.c0000644000175000017500000001155014340334543021153 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" /* Set decoder sampling rate */ opus_int silk_decoder_set_fs( silk_decoder_state *psDec, /* I/O Decoder state pointer */ opus_int fs_kHz, /* I Sampling frequency (kHz) */ opus_int32 fs_API_Hz /* I API Sampling frequency (Hz) */ ) { opus_int frame_length, ret = 0; celt_assert( fs_kHz == 8 || fs_kHz == 12 || fs_kHz == 16 ); celt_assert( psDec->nb_subfr == MAX_NB_SUBFR || psDec->nb_subfr == MAX_NB_SUBFR/2 ); /* New (sub)frame length */ psDec->subfr_length = silk_SMULBB( SUB_FRAME_LENGTH_MS, fs_kHz ); frame_length = silk_SMULBB( psDec->nb_subfr, psDec->subfr_length ); /* Initialize resampler when switching internal or external sampling frequency */ if( psDec->fs_kHz != fs_kHz || psDec->fs_API_hz != fs_API_Hz ) { /* Initialize the resampler for dec_API.c preparing resampling from fs_kHz to API_fs_Hz */ ret += silk_resampler_init( &psDec->resampler_state, silk_SMULBB( fs_kHz, 1000 ), fs_API_Hz, 0 ); psDec->fs_API_hz = fs_API_Hz; } if( psDec->fs_kHz != fs_kHz || frame_length != psDec->frame_length ) { if( fs_kHz == 8 ) { if( psDec->nb_subfr == MAX_NB_SUBFR ) { psDec->pitch_contour_iCDF = silk_pitch_contour_NB_iCDF; } else { psDec->pitch_contour_iCDF = silk_pitch_contour_10_ms_NB_iCDF; } } else { if( psDec->nb_subfr == MAX_NB_SUBFR ) { psDec->pitch_contour_iCDF = silk_pitch_contour_iCDF; } else { psDec->pitch_contour_iCDF = silk_pitch_contour_10_ms_iCDF; } } if( psDec->fs_kHz != fs_kHz ) { psDec->ltp_mem_length = silk_SMULBB( LTP_MEM_LENGTH_MS, fs_kHz ); if( fs_kHz == 8 || fs_kHz == 12 ) { psDec->LPC_order = MIN_LPC_ORDER; psDec->psNLSF_CB = &silk_NLSF_CB_NB_MB; } else { psDec->LPC_order = MAX_LPC_ORDER; psDec->psNLSF_CB = &silk_NLSF_CB_WB; } if( fs_kHz == 16 ) { psDec->pitch_lag_low_bits_iCDF = silk_uniform8_iCDF; } else if( fs_kHz == 12 ) { psDec->pitch_lag_low_bits_iCDF = silk_uniform6_iCDF; } else if( fs_kHz == 8 ) { psDec->pitch_lag_low_bits_iCDF = silk_uniform4_iCDF; } else { /* unsupported sampling rate */ celt_assert( 0 ); } psDec->first_frame_after_reset = 1; psDec->lagPrev = 100; psDec->LastGainIndex = 10; psDec->prevSignalType = TYPE_NO_VOICE_ACTIVITY; silk_memset( psDec->outBuf, 0, sizeof(psDec->outBuf)); silk_memset( psDec->sLPC_Q14_buf, 0, sizeof(psDec->sLPC_Q14_buf) ); } psDec->fs_kHz = fs_kHz; psDec->frame_length = frame_length; } /* Check that settings are valid */ celt_assert( psDec->frame_length > 0 && psDec->frame_length <= MAX_FRAME_LENGTH ); return ret; } jamulus-3.9.1+dfsg/libs/opus/silk/dec_API.c0000644000175000017500000004654714340334543017445 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "API.h" #include "main.h" #include "stack_alloc.h" #include "os_support.h" /************************/ /* Decoder Super Struct */ /************************/ typedef struct { silk_decoder_state channel_state[ DECODER_NUM_CHANNELS ]; stereo_dec_state sStereo; opus_int nChannelsAPI; opus_int nChannelsInternal; opus_int prev_decode_only_middle; } silk_decoder; /*********************/ /* Decoder functions */ /*********************/ opus_int silk_Get_Decoder_Size( /* O Returns error code */ opus_int *decSizeBytes /* O Number of bytes in SILK decoder state */ ) { opus_int ret = SILK_NO_ERROR; *decSizeBytes = sizeof( silk_decoder ); return ret; } /* Reset decoder state */ opus_int silk_InitDecoder( /* O Returns error code */ void *decState /* I/O State */ ) { opus_int n, ret = SILK_NO_ERROR; silk_decoder_state *channel_state = ((silk_decoder *)decState)->channel_state; for( n = 0; n < DECODER_NUM_CHANNELS; n++ ) { ret = silk_init_decoder( &channel_state[ n ] ); } silk_memset(&((silk_decoder *)decState)->sStereo, 0, sizeof(((silk_decoder *)decState)->sStereo)); /* Not strictly needed, but it's cleaner that way */ ((silk_decoder *)decState)->prev_decode_only_middle = 0; return ret; } /* Decode a frame */ opus_int silk_Decode( /* O Returns error code */ void* decState, /* I/O State */ silk_DecControlStruct* decControl, /* I/O Control Structure */ opus_int lostFlag, /* I 0: no loss, 1 loss, 2 decode fec */ opus_int newPacketFlag, /* I Indicates first decoder call for this packet */ ec_dec *psRangeDec, /* I/O Compressor data structure */ opus_int16 *samplesOut, /* O Decoded output speech vector */ opus_int32 *nSamplesOut, /* O Number of samples decoded */ int arch /* I Run-time architecture */ ) { opus_int i, n, decode_only_middle = 0, ret = SILK_NO_ERROR; opus_int32 nSamplesOutDec, LBRR_symbol; opus_int16 *samplesOut1_tmp[ 2 ]; VARDECL( opus_int16, samplesOut1_tmp_storage1 ); VARDECL( opus_int16, samplesOut1_tmp_storage2 ); VARDECL( opus_int16, samplesOut2_tmp ); opus_int32 MS_pred_Q13[ 2 ] = { 0 }; opus_int16 *resample_out_ptr; silk_decoder *psDec = ( silk_decoder * )decState; silk_decoder_state *channel_state = psDec->channel_state; opus_int has_side; opus_int stereo_to_mono; int delay_stack_alloc; SAVE_STACK; celt_assert( decControl->nChannelsInternal == 1 || decControl->nChannelsInternal == 2 ); /**********************************/ /* Test if first frame in payload */ /**********************************/ if( newPacketFlag ) { for( n = 0; n < decControl->nChannelsInternal; n++ ) { channel_state[ n ].nFramesDecoded = 0; /* Used to count frames in packet */ } } /* If Mono -> Stereo transition in bitstream: init state of second channel */ if( decControl->nChannelsInternal > psDec->nChannelsInternal ) { ret += silk_init_decoder( &channel_state[ 1 ] ); } stereo_to_mono = decControl->nChannelsInternal == 1 && psDec->nChannelsInternal == 2 && ( decControl->internalSampleRate == 1000*channel_state[ 0 ].fs_kHz ); if( channel_state[ 0 ].nFramesDecoded == 0 ) { for( n = 0; n < decControl->nChannelsInternal; n++ ) { opus_int fs_kHz_dec; if( decControl->payloadSize_ms == 0 ) { /* Assuming packet loss, use 10 ms */ channel_state[ n ].nFramesPerPacket = 1; channel_state[ n ].nb_subfr = 2; } else if( decControl->payloadSize_ms == 10 ) { channel_state[ n ].nFramesPerPacket = 1; channel_state[ n ].nb_subfr = 2; } else if( decControl->payloadSize_ms == 20 ) { channel_state[ n ].nFramesPerPacket = 1; channel_state[ n ].nb_subfr = 4; } else if( decControl->payloadSize_ms == 40 ) { channel_state[ n ].nFramesPerPacket = 2; channel_state[ n ].nb_subfr = 4; } else if( decControl->payloadSize_ms == 60 ) { channel_state[ n ].nFramesPerPacket = 3; channel_state[ n ].nb_subfr = 4; } else { celt_assert( 0 ); RESTORE_STACK; return SILK_DEC_INVALID_FRAME_SIZE; } fs_kHz_dec = ( decControl->internalSampleRate >> 10 ) + 1; if( fs_kHz_dec != 8 && fs_kHz_dec != 12 && fs_kHz_dec != 16 ) { celt_assert( 0 ); RESTORE_STACK; return SILK_DEC_INVALID_SAMPLING_FREQUENCY; } ret += silk_decoder_set_fs( &channel_state[ n ], fs_kHz_dec, decControl->API_sampleRate ); } } if( decControl->nChannelsAPI == 2 && decControl->nChannelsInternal == 2 && ( psDec->nChannelsAPI == 1 || psDec->nChannelsInternal == 1 ) ) { silk_memset( psDec->sStereo.pred_prev_Q13, 0, sizeof( psDec->sStereo.pred_prev_Q13 ) ); silk_memset( psDec->sStereo.sSide, 0, sizeof( psDec->sStereo.sSide ) ); silk_memcpy( &channel_state[ 1 ].resampler_state, &channel_state[ 0 ].resampler_state, sizeof( silk_resampler_state_struct ) ); } psDec->nChannelsAPI = decControl->nChannelsAPI; psDec->nChannelsInternal = decControl->nChannelsInternal; if( decControl->API_sampleRate > (opus_int32)MAX_API_FS_KHZ * 1000 || decControl->API_sampleRate < 8000 ) { ret = SILK_DEC_INVALID_SAMPLING_FREQUENCY; RESTORE_STACK; return( ret ); } if( lostFlag != FLAG_PACKET_LOST && channel_state[ 0 ].nFramesDecoded == 0 ) { /* First decoder call for this payload */ /* Decode VAD flags and LBRR flag */ for( n = 0; n < decControl->nChannelsInternal; n++ ) { for( i = 0; i < channel_state[ n ].nFramesPerPacket; i++ ) { channel_state[ n ].VAD_flags[ i ] = ec_dec_bit_logp(psRangeDec, 1); } channel_state[ n ].LBRR_flag = ec_dec_bit_logp(psRangeDec, 1); } /* Decode LBRR flags */ for( n = 0; n < decControl->nChannelsInternal; n++ ) { silk_memset( channel_state[ n ].LBRR_flags, 0, sizeof( channel_state[ n ].LBRR_flags ) ); if( channel_state[ n ].LBRR_flag ) { if( channel_state[ n ].nFramesPerPacket == 1 ) { channel_state[ n ].LBRR_flags[ 0 ] = 1; } else { LBRR_symbol = ec_dec_icdf( psRangeDec, silk_LBRR_flags_iCDF_ptr[ channel_state[ n ].nFramesPerPacket - 2 ], 8 ) + 1; for( i = 0; i < channel_state[ n ].nFramesPerPacket; i++ ) { channel_state[ n ].LBRR_flags[ i ] = silk_RSHIFT( LBRR_symbol, i ) & 1; } } } } if( lostFlag == FLAG_DECODE_NORMAL ) { /* Regular decoding: skip all LBRR data */ for( i = 0; i < channel_state[ 0 ].nFramesPerPacket; i++ ) { for( n = 0; n < decControl->nChannelsInternal; n++ ) { if( channel_state[ n ].LBRR_flags[ i ] ) { opus_int16 pulses[ MAX_FRAME_LENGTH ]; opus_int condCoding; if( decControl->nChannelsInternal == 2 && n == 0 ) { silk_stereo_decode_pred( psRangeDec, MS_pred_Q13 ); if( channel_state[ 1 ].LBRR_flags[ i ] == 0 ) { silk_stereo_decode_mid_only( psRangeDec, &decode_only_middle ); } } /* Use conditional coding if previous frame available */ if( i > 0 && channel_state[ n ].LBRR_flags[ i - 1 ] ) { condCoding = CODE_CONDITIONALLY; } else { condCoding = CODE_INDEPENDENTLY; } silk_decode_indices( &channel_state[ n ], psRangeDec, i, 1, condCoding ); silk_decode_pulses( psRangeDec, pulses, channel_state[ n ].indices.signalType, channel_state[ n ].indices.quantOffsetType, channel_state[ n ].frame_length ); } } } } } /* Get MS predictor index */ if( decControl->nChannelsInternal == 2 ) { if( lostFlag == FLAG_DECODE_NORMAL || ( lostFlag == FLAG_DECODE_LBRR && channel_state[ 0 ].LBRR_flags[ channel_state[ 0 ].nFramesDecoded ] == 1 ) ) { silk_stereo_decode_pred( psRangeDec, MS_pred_Q13 ); /* For LBRR data, decode mid-only flag only if side-channel's LBRR flag is false */ if( ( lostFlag == FLAG_DECODE_NORMAL && channel_state[ 1 ].VAD_flags[ channel_state[ 0 ].nFramesDecoded ] == 0 ) || ( lostFlag == FLAG_DECODE_LBRR && channel_state[ 1 ].LBRR_flags[ channel_state[ 0 ].nFramesDecoded ] == 0 ) ) { silk_stereo_decode_mid_only( psRangeDec, &decode_only_middle ); } else { decode_only_middle = 0; } } else { for( n = 0; n < 2; n++ ) { MS_pred_Q13[ n ] = psDec->sStereo.pred_prev_Q13[ n ]; } } } /* Reset side channel decoder prediction memory for first frame with side coding */ if( decControl->nChannelsInternal == 2 && decode_only_middle == 0 && psDec->prev_decode_only_middle == 1 ) { silk_memset( psDec->channel_state[ 1 ].outBuf, 0, sizeof(psDec->channel_state[ 1 ].outBuf) ); silk_memset( psDec->channel_state[ 1 ].sLPC_Q14_buf, 0, sizeof(psDec->channel_state[ 1 ].sLPC_Q14_buf) ); psDec->channel_state[ 1 ].lagPrev = 100; psDec->channel_state[ 1 ].LastGainIndex = 10; psDec->channel_state[ 1 ].prevSignalType = TYPE_NO_VOICE_ACTIVITY; psDec->channel_state[ 1 ].first_frame_after_reset = 1; } /* Check if the temp buffer fits into the output PCM buffer. If it fits, we can delay allocating the temp buffer until after the SILK peak stack usage. We need to use a < and not a <= because of the two extra samples. */ delay_stack_alloc = decControl->internalSampleRate*decControl->nChannelsInternal < decControl->API_sampleRate*decControl->nChannelsAPI; ALLOC( samplesOut1_tmp_storage1, delay_stack_alloc ? ALLOC_NONE : decControl->nChannelsInternal*(channel_state[ 0 ].frame_length + 2 ), opus_int16 ); if ( delay_stack_alloc ) { samplesOut1_tmp[ 0 ] = samplesOut; samplesOut1_tmp[ 1 ] = samplesOut + channel_state[ 0 ].frame_length + 2; } else { samplesOut1_tmp[ 0 ] = samplesOut1_tmp_storage1; samplesOut1_tmp[ 1 ] = samplesOut1_tmp_storage1 + channel_state[ 0 ].frame_length + 2; } if( lostFlag == FLAG_DECODE_NORMAL ) { has_side = !decode_only_middle; } else { has_side = !psDec->prev_decode_only_middle || (decControl->nChannelsInternal == 2 && lostFlag == FLAG_DECODE_LBRR && channel_state[1].LBRR_flags[ channel_state[1].nFramesDecoded ] == 1 ); } /* Call decoder for one frame */ for( n = 0; n < decControl->nChannelsInternal; n++ ) { if( n == 0 || has_side ) { opus_int FrameIndex; opus_int condCoding; FrameIndex = channel_state[ 0 ].nFramesDecoded - n; /* Use independent coding if no previous frame available */ if( FrameIndex <= 0 ) { condCoding = CODE_INDEPENDENTLY; } else if( lostFlag == FLAG_DECODE_LBRR ) { condCoding = channel_state[ n ].LBRR_flags[ FrameIndex - 1 ] ? CODE_CONDITIONALLY : CODE_INDEPENDENTLY; } else if( n > 0 && psDec->prev_decode_only_middle ) { /* If we skipped a side frame in this packet, we don't need LTP scaling; the LTP state is well-defined. */ condCoding = CODE_INDEPENDENTLY_NO_LTP_SCALING; } else { condCoding = CODE_CONDITIONALLY; } ret += silk_decode_frame( &channel_state[ n ], psRangeDec, &samplesOut1_tmp[ n ][ 2 ], &nSamplesOutDec, lostFlag, condCoding, arch); } else { silk_memset( &samplesOut1_tmp[ n ][ 2 ], 0, nSamplesOutDec * sizeof( opus_int16 ) ); } channel_state[ n ].nFramesDecoded++; } if( decControl->nChannelsAPI == 2 && decControl->nChannelsInternal == 2 ) { /* Convert Mid/Side to Left/Right */ silk_stereo_MS_to_LR( &psDec->sStereo, samplesOut1_tmp[ 0 ], samplesOut1_tmp[ 1 ], MS_pred_Q13, channel_state[ 0 ].fs_kHz, nSamplesOutDec ); } else { /* Buffering */ silk_memcpy( samplesOut1_tmp[ 0 ], psDec->sStereo.sMid, 2 * sizeof( opus_int16 ) ); silk_memcpy( psDec->sStereo.sMid, &samplesOut1_tmp[ 0 ][ nSamplesOutDec ], 2 * sizeof( opus_int16 ) ); } /* Number of output samples */ *nSamplesOut = silk_DIV32( nSamplesOutDec * decControl->API_sampleRate, silk_SMULBB( channel_state[ 0 ].fs_kHz, 1000 ) ); /* Set up pointers to temp buffers */ ALLOC( samplesOut2_tmp, decControl->nChannelsAPI == 2 ? *nSamplesOut : ALLOC_NONE, opus_int16 ); if( decControl->nChannelsAPI == 2 ) { resample_out_ptr = samplesOut2_tmp; } else { resample_out_ptr = samplesOut; } ALLOC( samplesOut1_tmp_storage2, delay_stack_alloc ? decControl->nChannelsInternal*(channel_state[ 0 ].frame_length + 2 ) : ALLOC_NONE, opus_int16 ); if ( delay_stack_alloc ) { OPUS_COPY(samplesOut1_tmp_storage2, samplesOut, decControl->nChannelsInternal*(channel_state[ 0 ].frame_length + 2)); samplesOut1_tmp[ 0 ] = samplesOut1_tmp_storage2; samplesOut1_tmp[ 1 ] = samplesOut1_tmp_storage2 + channel_state[ 0 ].frame_length + 2; } for( n = 0; n < silk_min( decControl->nChannelsAPI, decControl->nChannelsInternal ); n++ ) { /* Resample decoded signal to API_sampleRate */ ret += silk_resampler( &channel_state[ n ].resampler_state, resample_out_ptr, &samplesOut1_tmp[ n ][ 1 ], nSamplesOutDec ); /* Interleave if stereo output and stereo stream */ if( decControl->nChannelsAPI == 2 ) { for( i = 0; i < *nSamplesOut; i++ ) { samplesOut[ n + 2 * i ] = resample_out_ptr[ i ]; } } } /* Create two channel output from mono stream */ if( decControl->nChannelsAPI == 2 && decControl->nChannelsInternal == 1 ) { if ( stereo_to_mono ){ /* Resample right channel for newly collapsed stereo just in case we weren't doing collapsing when switching to mono */ ret += silk_resampler( &channel_state[ 1 ].resampler_state, resample_out_ptr, &samplesOut1_tmp[ 0 ][ 1 ], nSamplesOutDec ); for( i = 0; i < *nSamplesOut; i++ ) { samplesOut[ 1 + 2 * i ] = resample_out_ptr[ i ]; } } else { for( i = 0; i < *nSamplesOut; i++ ) { samplesOut[ 1 + 2 * i ] = samplesOut[ 0 + 2 * i ]; } } } /* Export pitch lag, measured at 48 kHz sampling rate */ if( channel_state[ 0 ].prevSignalType == TYPE_VOICED ) { int mult_tab[ 3 ] = { 6, 4, 3 }; decControl->prevPitchLag = channel_state[ 0 ].lagPrev * mult_tab[ ( channel_state[ 0 ].fs_kHz - 8 ) >> 2 ]; } else { decControl->prevPitchLag = 0; } if( lostFlag == FLAG_PACKET_LOST ) { /* On packet loss, remove the gain clamping to prevent having the energy "bounce back" if we lose packets when the energy is going down */ for ( i = 0; i < psDec->nChannelsInternal; i++ ) psDec->channel_state[ i ].LastGainIndex = 10; } else { psDec->prev_decode_only_middle = decode_only_middle; } RESTORE_STACK; return ret; } #if 0 /* Getting table of contents for a packet */ opus_int silk_get_TOC( const opus_uint8 *payload, /* I Payload data */ const opus_int nBytesIn, /* I Number of input bytes */ const opus_int nFramesPerPayload, /* I Number of SILK frames per payload */ silk_TOC_struct *Silk_TOC /* O Type of content */ ) { opus_int i, flags, ret = SILK_NO_ERROR; if( nBytesIn < 1 ) { return -1; } if( nFramesPerPayload < 0 || nFramesPerPayload > 3 ) { return -1; } silk_memset( Silk_TOC, 0, sizeof( *Silk_TOC ) ); /* For stereo, extract the flags for the mid channel */ flags = silk_RSHIFT( payload[ 0 ], 7 - nFramesPerPayload ) & ( silk_LSHIFT( 1, nFramesPerPayload + 1 ) - 1 ); Silk_TOC->inbandFECFlag = flags & 1; for( i = nFramesPerPayload - 1; i >= 0 ; i-- ) { flags = silk_RSHIFT( flags, 1 ); Silk_TOC->VADFlags[ i ] = flags & 1; Silk_TOC->VADFlag |= flags & 1; } return ret; } #endif jamulus-3.9.1+dfsg/libs/opus/silk/resampler_down2_3.c0000644000175000017500000001123514340334543021530 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SigProc_FIX.h" #include "resampler_private.h" #include "stack_alloc.h" #define ORDER_FIR 4 /* Downsample by a factor 2/3, low quality */ void silk_resampler_down2_3( opus_int32 *S, /* I/O State vector [ 6 ] */ opus_int16 *out, /* O Output signal [ floor(2*inLen/3) ] */ const opus_int16 *in, /* I Input signal [ inLen ] */ opus_int32 inLen /* I Number of input samples */ ) { opus_int32 nSamplesIn, counter, res_Q6; VARDECL( opus_int32, buf ); opus_int32 *buf_ptr; SAVE_STACK; ALLOC( buf, RESAMPLER_MAX_BATCH_SIZE_IN + ORDER_FIR, opus_int32 ); /* Copy buffered samples to start of buffer */ silk_memcpy( buf, S, ORDER_FIR * sizeof( opus_int32 ) ); /* Iterate over blocks of frameSizeIn input samples */ while( 1 ) { nSamplesIn = silk_min( inLen, RESAMPLER_MAX_BATCH_SIZE_IN ); /* Second-order AR filter (output in Q8) */ silk_resampler_private_AR2( &S[ ORDER_FIR ], &buf[ ORDER_FIR ], in, silk_Resampler_2_3_COEFS_LQ, nSamplesIn ); /* Interpolate filtered signal */ buf_ptr = buf; counter = nSamplesIn; while( counter > 2 ) { /* Inner product */ res_Q6 = silk_SMULWB( buf_ptr[ 0 ], silk_Resampler_2_3_COEFS_LQ[ 2 ] ); res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 1 ], silk_Resampler_2_3_COEFS_LQ[ 3 ] ); res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 2 ], silk_Resampler_2_3_COEFS_LQ[ 5 ] ); res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 3 ], silk_Resampler_2_3_COEFS_LQ[ 4 ] ); /* Scale down, saturate and store in output array */ *out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q6, 6 ) ); res_Q6 = silk_SMULWB( buf_ptr[ 1 ], silk_Resampler_2_3_COEFS_LQ[ 4 ] ); res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 2 ], silk_Resampler_2_3_COEFS_LQ[ 5 ] ); res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 3 ], silk_Resampler_2_3_COEFS_LQ[ 3 ] ); res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 4 ], silk_Resampler_2_3_COEFS_LQ[ 2 ] ); /* Scale down, saturate and store in output array */ *out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q6, 6 ) ); buf_ptr += 3; counter -= 3; } in += nSamplesIn; inLen -= nSamplesIn; if( inLen > 0 ) { /* More iterations to do; copy last part of filtered signal to beginning of buffer */ silk_memcpy( buf, &buf[ nSamplesIn ], ORDER_FIR * sizeof( opus_int32 ) ); } else { break; } } /* Copy last part of filtered signal to the state for the next call */ silk_memcpy( S, &buf[ nSamplesIn ], ORDER_FIR * sizeof( opus_int32 ) ); RESTORE_STACK; } jamulus-3.9.1+dfsg/libs/opus/silk/decode_indices.c0000644000175000017500000001611514340334543021126 0ustar vimervimer/*********************************************************************** Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Internet Society, IETF or IETF Trust, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main.h" /* Decode side-information parameters from payload */ void silk_decode_indices( silk_decoder_state *psDec, /* I/O State */ ec_dec *psRangeDec, /* I/O Compressor data structure */ opus_int FrameIndex, /* I Frame number */ opus_int decode_LBRR, /* I Flag indicating LBRR data is being decoded */ opus_int condCoding /* I The type of conditional coding to use */ ) { opus_int i, k, Ix; opus_int decode_absolute_lagIndex, delta_lagIndex; opus_int16 ec_ix[ MAX_LPC_ORDER ]; opus_uint8 pred_Q8[ MAX_LPC_ORDER ]; /*******************************************/ /* Decode signal type and quantizer offset */ /*******************************************/ if( decode_LBRR || psDec->VAD_flags[ FrameIndex ] ) { Ix = ec_dec_icdf( psRangeDec, silk_type_offset_VAD_iCDF, 8 ) + 2; } else { Ix = ec_dec_icdf( psRangeDec, silk_type_offset_no_VAD_iCDF, 8 ); } psDec->indices.signalType = (opus_int8)silk_RSHIFT( Ix, 1 ); psDec->indices.quantOffsetType = (opus_int8)( Ix & 1 ); /****************/ /* Decode gains */ /****************/ /* First subframe */ if( condCoding == CODE_CONDITIONALLY ) { /* Conditional coding */ psDec->indices.GainsIndices[ 0 ] = (opus_int8)ec_dec_icdf( psRangeDec, silk_delta_gain_iCDF, 8 ); } else { /* Independent coding, in two stages: MSB bits followed by 3 LSBs */ psDec->indices.GainsIndices[ 0 ] = (opus_int8)silk_LSHIFT( ec_dec_icdf( psRangeDec, silk_gain_iCDF[ psDec->indices.signalType ], 8 ), 3 ); psDec->indices.GainsIndices[ 0 ] += (opus_int8)ec_dec_icdf( psRangeDec, silk_uniform8_iCDF, 8 ); } /* Remaining subframes */ for( i = 1; i < psDec->nb_subfr; i++ ) { psDec->indices.GainsIndices[ i ] = (opus_int8)ec_dec_icdf( psRangeDec, silk_delta_gain_iCDF, 8 ); } /**********************/ /* Decode LSF Indices */ /**********************/ psDec->indices.NLSFIndices[ 0 ] = (opus_int8)ec_dec_icdf( psRangeDec, &psDec->psNLSF_CB->CB1_iCDF[ ( psDec->indices.signalType >> 1 ) * psDec->psNLSF_CB->nVectors ], 8 ); silk_NLSF_unpack( ec_ix, pred_Q8, psDec->psNLSF_CB, psDec->indices.NLSFIndices[ 0 ] ); celt_assert( psDec->psNLSF_CB->order == psDec->LPC_order ); for( i = 0; i < psDec->psNLSF_CB->order; i++ ) { Ix = ec_dec_icdf( psRangeDec, &psDec->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 ); if( Ix == 0 ) { Ix -= ec_dec_icdf( psRangeDec, silk_NLSF_EXT_iCDF, 8 ); } else if( Ix == 2 * NLSF_QUANT_MAX_AMPLITUDE ) { Ix += ec_dec_icdf( psRangeDec, silk_NLSF_EXT_iCDF, 8 ); } psDec->indices.NLSFIndices[ i+1 ] = (opus_int8)( Ix - NLSF_QUANT_MAX_AMPLITUDE ); } /* Decode LSF interpolation factor */ if( psDec->nb_subfr == MAX_NB_SUBFR ) { psDec->indices.NLSFInterpCoef_Q2 = (opus_int8)ec_dec_icdf( psRangeDec, silk_NLSF_interpolation_factor_iCDF, 8 ); } else { psDec->indices.NLSFInterpCoef_Q2 = 4; } if( psDec->indices.signalType == TYPE_VOICED ) { /*********************/ /* Decode pitch lags */ /*********************/ /* Get lag index */ decode_absolute_lagIndex = 1; if( condCoding == CODE_CONDITIONALLY && psDec->ec_prevSignalType == TYPE_VOICED ) { /* Decode Delta index */ delta_lagIndex = (opus_int16)ec_dec_icdf( psRangeDec, silk_pitch_delta_iCDF, 8 ); if( delta_lagIndex > 0 ) { delta_lagIndex = delta_lagIndex - 9; psDec->indices.lagIndex = (opus_int16)( psDec->ec_prevLagIndex + delta_lagIndex ); decode_absolute_lagIndex = 0; } } if( decode_absolute_lagIndex ) { /* Absolute decoding */ psDec->indices.lagIndex = (opus_int16)ec_dec_icdf( psRangeDec, silk_pitch_lag_iCDF, 8 ) * silk_RSHIFT( psDec->fs_kHz, 1 ); psDec->indices.lagIndex += (opus_int16)ec_dec_icdf( psRangeDec, psDec->pitch_lag_low_bits_iCDF, 8 ); } psDec->ec_prevLagIndex = psDec->indices.lagIndex; /* Get contour index */ psDec->indices.contourIndex = (opus_int8)ec_dec_icdf( psRangeDec, psDec->pitch_contour_iCDF, 8 ); /********************/ /* Decode LTP gains */ /********************/ /* Decode PERIndex value */ psDec->indices.PERIndex = (opus_int8)ec_dec_icdf( psRangeDec, silk_LTP_per_index_iCDF, 8 ); for( k = 0; k < psDec->nb_subfr; k++ ) { psDec->indices.LTPIndex[ k ] = (opus_int8)ec_dec_icdf( psRangeDec, silk_LTP_gain_iCDF_ptrs[ psDec->indices.PERIndex ], 8 ); } /**********************/ /* Decode LTP scaling */ /**********************/ if( condCoding == CODE_INDEPENDENTLY ) { psDec->indices.LTP_scaleIndex = (opus_int8)ec_dec_icdf( psRangeDec, silk_LTPscale_iCDF, 8 ); } else { psDec->indices.LTP_scaleIndex = 0; } } psDec->ec_prevSignalType = psDec->indices.signalType; /***************/ /* Decode seed */ /***************/ psDec->indices.Seed = (opus_int8)ec_dec_icdf( psRangeDec, silk_uniform4_iCDF, 8 ); } jamulus-3.9.1+dfsg/libs/opus/OpusConfig.cmake.in0000644000175000017500000000103014340334543020550 0ustar vimervimerset(OPUS_VERSION @PROJECT_VERSION@) set(OPUS_VERSION_STRING @PROJECT_VERSION@) set(OPUS_VERSION_MAJOR @PROJECT_VERSION_MAJOR@) set(OPUS_VERSION_MINOR @PROJECT_VERSION_MINOR@) set(OPUS_VERSION_PATCH @PROJECT_VERSION_PATCH@) @PACKAGE_INIT@ set_and_check(OPUS_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@") set_and_check(OPUS_INCLUDE_DIRS "@PACKAGE_INCLUDE_INSTALL_DIR@") include(${CMAKE_CURRENT_LIST_DIR}/OpusTargets.cmake) set(OPUS_LIBRARY Opus::opus) set(OPUS_LIBRARIES Opus::opus) check_required_components(Opus) set(OPUS_FOUND 1) jamulus-3.9.1+dfsg/libs/opus/Makefile.mips0000644000175000017500000001074114340334543017505 0ustar vimervimer#################### COMPILE OPTIONS ####################### # Uncomment this for fixed-point build FIXED_POINT=1 # It is strongly recommended to uncomment one of these # VAR_ARRAYS: Use C99 variable-length arrays for stack allocation # USE_ALLOCA: Use alloca() for stack allocation # If none is defined, then the fallback is a non-threadsafe global array CFLAGS := -DUSE_ALLOCA $(CFLAGS) #CFLAGS := -DVAR_ARRAYS $(CFLAGS) # These options affect performance # HAVE_LRINTF: Use C99 intrinsics to speed up float-to-int conversion CFLAGS := -DHAVE_LRINTF $(CFLAGS) ###################### END OF OPTIONS ###################### -include package_version include silk_sources.mk include celt_sources.mk include opus_sources.mk ifdef FIXED_POINT SILK_SOURCES += $(SILK_SOURCES_FIXED) else SILK_SOURCES += $(SILK_SOURCES_FLOAT) OPUS_SOURCES += $(OPUS_SOURCES_FLOAT) endif EXESUFFIX = LIBPREFIX = lib LIBSUFFIX = .a OBJSUFFIX = .o CC = $(TOOLCHAIN_PREFIX)cc$(TOOLCHAIN_SUFFIX) AR = $(TOOLCHAIN_PREFIX)ar RANLIB = $(TOOLCHAIN_PREFIX)ranlib CP = $(TOOLCHAIN_PREFIX)cp cppflags-from-defines = $(addprefix -D,$(1)) cppflags-from-includes = $(addprefix -I,$(1)) ldflags-from-ldlibdirs = $(addprefix -L,$(1)) ldlibs-from-libs = $(addprefix -l,$(1)) WARNINGS = -Wall -W -Wstrict-prototypes -Wextra -Wcast-align -Wnested-externs -Wshadow CFLAGS += -mips32r2 -mno-mips16 -std=gnu99 -O2 -g $(WARNINGS) -DENABLE_ASSERTIONS -DMIPSr1_ASM -DOPUS_BUILD -mdspr2 -march=74kc -mtune=74kc -mmt -mgp32 CINCLUDES = include silk celt ifdef FIXED_POINT CFLAGS += -DFIXED_POINT=1 -DDISABLE_FLOAT_API CINCLUDES += silk/fixed else CINCLUDES += silk/float endif LIBS = m LDLIBDIRS = ./ CFLAGS += $(call cppflags-from-defines,$(CDEFINES)) CFLAGS += $(call cppflags-from-includes,$(CINCLUDES)) LDFLAGS += $(call ldflags-from-ldlibdirs,$(LDLIBDIRS)) LDLIBS += $(call ldlibs-from-libs,$(LIBS)) COMPILE.c.cmdline = $(CC) -c $(CFLAGS) -o $@ $< LINK.o = $(CC) $(LDPREFLAGS) $(LDFLAGS) LINK.o.cmdline = $(LINK.o) $^ $(LDLIBS) -o $@$(EXESUFFIX) ARCHIVE.cmdline = $(AR) $(ARFLAGS) $@ $^ && $(RANLIB) $@ %$(OBJSUFFIX):%.c $(COMPILE.c.cmdline) %$(OBJSUFFIX):%.cpp $(COMPILE.cpp.cmdline) # Directives # Variable definitions LIB_NAME = opus TARGET = $(LIBPREFIX)$(LIB_NAME)$(LIBSUFFIX) SRCS_C = $(SILK_SOURCES) $(CELT_SOURCES) $(OPUS_SOURCES) OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(SRCS_C)) OPUSDEMO_SRCS_C = src/opus_demo.c OPUSDEMO_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(OPUSDEMO_SRCS_C)) TESTOPUSAPI_SRCS_C = tests/test_opus_api.c TESTOPUSAPI_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(TESTOPUSAPI_SRCS_C)) TESTOPUSDECODE_SRCS_C = tests/test_opus_decode.c TESTOPUSDECODE_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(TESTOPUSDECODE_SRCS_C)) TESTOPUSENCODE_SRCS_C = tests/test_opus_encode.c tests/opus_encode_regressions.c TESTOPUSENCODE_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(TESTOPUSENCODE_SRCS_C)) TESTOPUSPADDING_SRCS_C = tests/test_opus_padding.c TESTOPUSPADDING_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(TESTOPUSPADDING_SRCS_C)) OPUSCOMPARE_SRCS_C = src/opus_compare.c OPUSCOMPARE_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(OPUSCOMPARE_SRCS_C)) TESTS := test_opus_api test_opus_decode test_opus_encode test_opus_padding # Rules all: lib opus_demo opus_compare $(TESTS) lib: $(TARGET) check: all for test in $(TESTS); do ./$$test; done $(TARGET): $(OBJS) $(ARCHIVE.cmdline) opus_demo$(EXESUFFIX): $(OPUSDEMO_OBJS) $(TARGET) $(LINK.o.cmdline) test_opus_api$(EXESUFFIX): $(TESTOPUSAPI_OBJS) $(TARGET) $(LINK.o.cmdline) test_opus_decode$(EXESUFFIX): $(TESTOPUSDECODE_OBJS) $(TARGET) $(LINK.o.cmdline) test_opus_encode$(EXESUFFIX): $(TESTOPUSENCODE_OBJS) $(TARGET) $(LINK.o.cmdline) test_opus_padding$(EXESUFFIX): $(TESTOPUSPADDING_OBJS) $(TARGET) $(LINK.o.cmdline) opus_compare$(EXESUFFIX): $(OPUSCOMPARE_OBJS) $(LINK.o.cmdline) celt/celt.o: CFLAGS += -DPACKAGE_VERSION='$(PACKAGE_VERSION)' celt/celt.o: package_version package_version: force @if [ -x ./update_version ]; then \ ./update_version || true; \ elif [ ! -e ./package_version ]; then \ echo 'PACKAGE_VERSION="unknown"' > ./package_version; \ fi force: clean: rm -f opus_demo$(EXESUFFIX) opus_compare$(EXESUFFIX) $(TARGET) \ test_opus_api$(EXESUFFIX) test_opus_decode$(EXESUFFIX) \ test_opus_encode$(EXESUFFIX) test_opus_padding$(EXESUFFIX) \ $(OBJS) $(OPUSDEMO_OBJS) $(OPUSCOMPARE_OBJS) $(TESTOPUSAPI_OBJS) \ $(TESTOPUSDECODE_OBJS) $(TESTOPUSENCODE_OBJS) $(TESTOPUSPADDING_OBJS) .PHONY: all lib clean force check jamulus-3.9.1+dfsg/libs/opus/README0000644000175000017500000001333514340334543015760 0ustar vimervimer== Opus audio codec == Opus is a codec for interactive speech and audio transmission over the Internet. Opus can handle a wide range of interactive audio applications, including Voice over IP, videoconferencing, in-game chat, and even remote live music performances. It can scale from low bit-rate narrowband speech to very high quality stereo music. Opus, when coupled with an appropriate container format, is also suitable for non-realtime stored-file applications such as music distribution, game soundtracks, portable music players, jukeboxes, and other applications that have historically used high latency formats such as MP3, AAC, or Vorbis. Opus is specified by IETF RFC 6716: https://tools.ietf.org/html/rfc6716 The Opus format and this implementation of it are subject to the royalty- free patent and copyright licenses specified in the file COPYING. This package implements a shared library for encoding and decoding raw Opus bitstreams. Raw Opus bitstreams should be used over RTP according to https://tools.ietf.org/html/rfc7587 The package also includes a number of test tools used for testing the correct operation of the library. The bitstreams read/written by these tools should not be used for Opus file distribution: They include additional debugging data and cannot support seeking. Opus stored in files should use the Ogg encapsulation for Opus which is described at: https://tools.ietf.org/html/rfc7845 An opus-tools package is available which provides encoding and decoding of Ogg encapsulated Opus files and includes a number of useful features. Opus-tools can be found at: https://git.xiph.org/?p=opus-tools.git or on the main Opus website: https://opus-codec.org/ == Compiling libopus == To build from a distribution tarball, you only need to do the following: % ./configure % make To build from the git repository, the following steps are necessary: 0) Set up a development environment: On an Ubuntu or Debian family Linux distribution: % sudo apt-get install git autoconf automake libtool gcc make On a Fedora/Redhat based Linux: % sudo dnf install git autoconf automake libtool gcc make Or for older Redhat/Centos Linux releases: % sudo yum install git autoconf automake libtool gcc make On Apple macOS, install Xcode and brew.sh, then in the Terminal enter: % brew install autoconf automake libtool 1) Clone the repository: % git clone https://git.xiph.org/opus.git % cd opus 2) Compiling the source % ./autogen.sh % ./configure % make 3) Install the codec libraries (optional) % sudo make install Once you have compiled the codec, there will be a opus_demo executable in the top directory. Usage: opus_demo [-e] [options] opus_demo -d [options] mode: voip | audio | restricted-lowdelay options: -e : only runs the encoder (output the bit-stream) -d : only runs the decoder (reads the bit-stream as input) -cbr : enable constant bitrate; default: variable bitrate -cvbr : enable constrained variable bitrate; default: unconstrained -bandwidth : audio bandwidth (from narrowband to fullband); default: sampling rate -framesize <2.5|5|10|20|40|60> : frame size in ms; default: 20 -max_payload : maximum payload size in bytes, default: 1024 -complexity : complexity, 0 (lowest) ... 10 (highest); default: 10 -inbandfec : enable SILK inband FEC -forcemono : force mono encoding, even for stereo input -dtx : enable SILK DTX -loss : simulate packet loss, in percent (0-100); default: 0 input and output are little-endian signed 16-bit PCM files or opus bitstreams with simple opus_demo proprietary framing. == Testing == This package includes a collection of automated unit and system tests which SHOULD be run after compiling the package especially the first time it is run on a new platform. To run the integrated tests: % make check There is also collection of standard test vectors which are not included in this package for size reasons but can be obtained from: https://opus-codec.org/docs/opus_testvectors-rfc8251.tar.gz To run compare the code to these test vectors: % curl -OL https://opus-codec.org/docs/opus_testvectors-rfc8251.tar.gz % tar -zxf opus_testvectors-rfc8251.tar.gz % ./tests/run_vectors.sh ./ opus_newvectors 48000 == Portability notes == This implementation uses floating-point by default but can be compiled to use only fixed-point arithmetic by setting --enable-fixed-point (if using autoconf) or by defining the FIXED_POINT macro (if building manually). The fixed point implementation has somewhat lower audio quality and is slower on platforms with fast FPUs, it is normally only used in embedded environments. The implementation can be compiled with either a C89 or a C99 compiler. While it does not rely on any _undefined behavior_ as defined by C89 or C99, it relies on common _implementation-defined behavior_ for two's complement architectures: o Right shifts of negative values are consistent with two's complement arithmetic, so that a>>b is equivalent to floor(a/(2^b)), o For conversion to a signed integer of N bits, the value is reduced modulo 2^N to be within range of the type, o The result of integer division of a negative value is truncated towards zero, and o The compiler provides a 64-bit integer type (a C99 requirement which is supported by most C89 compilers). jamulus-3.9.1+dfsg/libs/opus/INSTALL0000644000175000017500000003661414340334543016136 0ustar vimervimerInstallation Instructions ************************* Copyright (C) 1994-1996, 1999-2002, 2004-2016 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without warranty of any kind. Basic Installation ================== Briefly, the shell command './configure && make && make install' should configure, build, and install this package. The following more-detailed instructions are generic; see the 'README' file for instructions specific to this package. Some packages provide this 'INSTALL' file but do not implement all of the features documented below. The lack of an optional feature in a given package is not necessarily a bug. More recommendations for GNU packages can be found in *note Makefile Conventions: (standards)Makefile Conventions. The 'configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a 'Makefile' in each directory of the package. It may also create one or more '.h' files containing system-dependent definitions. Finally, it creates a shell script 'config.status' that you can run in the future to recreate the current configuration, and a file 'config.log' containing compiler output (useful mainly for debugging 'configure'). It can also use an optional file (typically called 'config.cache' and enabled with '--cache-file=config.cache' or simply '-C') that saves the results of its tests to speed up reconfiguring. Caching is disabled by default to prevent problems with accidental use of stale cache files. If you need to do unusual things to compile the package, please try to figure out how 'configure' could check whether to do them, and mail diffs or instructions to the address given in the 'README' so they can be considered for the next release. If you are using the cache, and at some point 'config.cache' contains results you don't want to keep, you may remove or edit it. The file 'configure.ac' (or 'configure.in') is used to create 'configure' by a program called 'autoconf'. You need 'configure.ac' if you want to change it or regenerate 'configure' using a newer version of 'autoconf'. The simplest way to compile this package is: 1. 'cd' to the directory containing the package's source code and type './configure' to configure the package for your system. Running 'configure' might take a while. While running, it prints some messages telling which features it is checking for. 2. Type 'make' to compile the package. 3. Optionally, type 'make check' to run any self-tests that come with the package, generally using the just-built uninstalled binaries. 4. Type 'make install' to install the programs and any data files and documentation. When installing into a prefix owned by root, it is recommended that the package be configured and built as a regular user, and only the 'make install' phase executed with root privileges. 5. Optionally, type 'make installcheck' to repeat any self-tests, but this time using the binaries in their final installed location. This target does not install anything. Running this target as a regular user, particularly if the prior 'make install' required root privileges, verifies that the installation completed correctly. 6. You can remove the program binaries and object files from the source code directory by typing 'make clean'. To also remove the files that 'configure' created (so you can compile the package for a different kind of computer), type 'make distclean'. There is also a 'make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. 7. Often, you can also type 'make uninstall' to remove the installed files again. In practice, not all packages have tested that uninstallation works correctly, even though it is required by the GNU Coding Standards. 8. Some packages, particularly those that use Automake, provide 'make distcheck', which can by used by developers to test that all other targets like 'make install' and 'make uninstall' work correctly. This target is generally not run by end users. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the 'configure' script does not know about. Run './configure --help' for details on some of the pertinent environment variables. You can give 'configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c99 CFLAGS=-g LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you can use GNU 'make'. 'cd' to the directory where you want the object files and executables to go and run the 'configure' script. 'configure' automatically checks for the source code in the directory that 'configure' is in and in '..'. This is known as a "VPATH" build. With a non-GNU 'make', it is safer to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use 'make distclean' before reconfiguring for another architecture. On MacOS X 10.5 and later systems, you can create libraries and executables that work on multiple system types--known as "fat" or "universal" binaries--by specifying multiple '-arch' options to the compiler but only a single '-arch' option to the preprocessor. Like this: ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CPP="gcc -E" CXXCPP="g++ -E" This is not guaranteed to produce working output in all cases, you may have to build one architecture at a time and combine the results using the 'lipo' tool if you have problems. Installation Names ================== By default, 'make install' installs the package's commands under '/usr/local/bin', include files under '/usr/local/include', etc. You can specify an installation prefix other than '/usr/local' by giving 'configure' the option '--prefix=PREFIX', where PREFIX must be an absolute file name. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you pass the option '--exec-prefix=PREFIX' to 'configure', the package uses PREFIX as the prefix for installing programs and libraries. Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like '--bindir=DIR' to specify different values for particular kinds of files. Run 'configure --help' for a list of the directories you can set and what kinds of files go in them. In general, the default for these options is expressed in terms of '${prefix}', so that specifying just '--prefix' will affect all of the other directory specifications that were not explicitly provided. The most portable way to affect installation locations is to pass the correct locations to 'configure'; however, many packages provide one or both of the following shortcuts of passing variable assignments to the 'make install' command line to change installation locations without having to reconfigure or recompile. The first method involves providing an override variable for each affected directory. For example, 'make install prefix=/alternate/directory' will choose an alternate location for all directory configuration variables that were expressed in terms of '${prefix}'. Any directories that were specified during 'configure', but not in terms of '${prefix}', must each be overridden at install time for the entire installation to be relocated. The approach of makefile variable overrides for each directory variable is required by the GNU Coding Standards, and ideally causes no recompilation. However, some platforms have known limitations with the semantics of shared libraries that end up requiring recompilation when using this method, particularly noticeable in packages that use GNU Libtool. The second method involves providing the 'DESTDIR' variable. For example, 'make install DESTDIR=/alternate/directory' will prepend '/alternate/directory' before all installation names. The approach of 'DESTDIR' overrides is not required by the GNU Coding Standards, and does not work on platforms that have drive letters. On the other hand, it does better at avoiding recompilation issues, and works well even when some directory options were not specified in terms of '${prefix}' at 'configure' time. Optional Features ================= If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving 'configure' the option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'. Some packages pay attention to '--enable-FEATURE' options to 'configure', where FEATURE indicates an optional part of the package. They may also pay attention to '--with-PACKAGE' options, where PACKAGE is something like 'gnu-as' or 'x' (for the X Window System). The 'README' should mention any '--enable-' and '--with-' options that the package recognizes. For packages that use the X Window System, 'configure' can usually find the X include and library files automatically, but if it doesn't, you can use the 'configure' options '--x-includes=DIR' and '--x-libraries=DIR' to specify their locations. Some packages offer the ability to configure how verbose the execution of 'make' will be. For these packages, running './configure --enable-silent-rules' sets the default to minimal output, which can be overridden with 'make V=1'; while running './configure --disable-silent-rules' sets the default to verbose, which can be overridden with 'make V=0'. Particular systems ================== On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC is not installed, it is recommended to use the following options in order to use an ANSI C compiler: ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" and if that doesn't work, install pre-built binaries of GCC for HP-UX. HP-UX 'make' updates targets which have the same time stamps as their prerequisites, which makes it generally unusable when shipped generated files such as 'configure' are involved. Use GNU 'make' instead. On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot parse its '' header file. The option '-nodtk' can be used as a workaround. If GNU CC is not installed, it is therefore recommended to try ./configure CC="cc" and if that doesn't work, try ./configure CC="cc -nodtk" On Solaris, don't put '/usr/ucb' early in your 'PATH'. This directory contains several dysfunctional programs; working variants of these programs are available in '/usr/bin'. So, if you need '/usr/ucb' in your 'PATH', put it _after_ '/usr/bin'. On Haiku, software installed for all users goes in '/boot/common', not '/usr/local'. It is recommended to use the following options: ./configure --prefix=/boot/common Specifying the System Type ========================== There may be some features 'configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, 'configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the '--build=TYPE' option. TYPE can either be a short name for the system type, such as 'sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file 'config.sub' for the possible values of each field. If 'config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the option '--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with '--host=TYPE'. Sharing Defaults ================ If you want to set default values for 'configure' scripts to share, you can create a site shell script called 'config.site' that gives default values for variables like 'CC', 'cache_file', and 'prefix'. 'configure' looks for 'PREFIX/share/config.site' if it exists, then 'PREFIX/etc/config.site' if it exists. Or, you can set the 'CONFIG_SITE' environment variable to the location of the site script. A warning: not all 'configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to 'configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the 'configure' command line, using 'VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc causes the specified 'gcc' to be used as the C compiler (unless it is overridden in the site shell script). Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an Autoconf limitation. Until the limitation is lifted, you can use this workaround: CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash 'configure' Invocation ====================== 'configure' recognizes the following options to control how it operates. '--help' '-h' Print a summary of all of the options to 'configure', and exit. '--help=short' '--help=recursive' Print a summary of the options unique to this package's 'configure', and exit. The 'short' variant lists options used only in the top level, while the 'recursive' variant lists options also present in any nested packages. '--version' '-V' Print the version of Autoconf used to generate the 'configure' script, and exit. '--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally 'config.cache'. FILE defaults to '/dev/null' to disable caching. '--config-cache' '-C' Alias for '--cache-file=config.cache'. '--quiet' '--silent' '-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to '/dev/null' (any error messages will still be shown). '--srcdir=DIR' Look for the package's source code in directory DIR. Usually 'configure' can determine that directory automatically. '--prefix=DIR' Use DIR as the installation prefix. *note Installation Names:: for more details, including other options available for fine-tuning the installation locations. '--no-create' '-n' Run the configure checks, but stop before creating any output files. 'configure' also accepts some other, not widely useful, options. Run 'configure --help' for more details. jamulus-3.9.1+dfsg/libs/opus/src/0000755000175000017500000000000014340334543015662 5ustar vimervimerjamulus-3.9.1+dfsg/libs/opus/src/opus_demo.c0000644000175000017500000010444214340334543020025 0ustar vimervimer/* Copyright (c) 2007-2008 CSIRO Copyright (c) 2007-2009 Xiph.Org Foundation Written by Jean-Marc Valin */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "opus.h" #include "debug.h" #include "opus_types.h" #include "opus_private.h" #include "opus_multistream.h" #define MAX_PACKET 1500 void print_usage( char* argv[] ) { fprintf(stderr, "Usage: %s [-e] " " [options] \n", argv[0]); fprintf(stderr, " %s -d " "[options] \n\n", argv[0]); fprintf(stderr, "application: voip | audio | restricted-lowdelay\n" ); fprintf(stderr, "options:\n" ); fprintf(stderr, "-e : only runs the encoder (output the bit-stream)\n" ); fprintf(stderr, "-d : only runs the decoder (reads the bit-stream as input)\n" ); fprintf(stderr, "-cbr : enable constant bitrate; default: variable bitrate\n" ); fprintf(stderr, "-cvbr : enable constrained variable bitrate; default: unconstrained\n" ); fprintf(stderr, "-delayed-decision : use look-ahead for speech/music detection (experts only); default: disabled\n" ); fprintf(stderr, "-bandwidth : audio bandwidth (from narrowband to fullband); default: sampling rate\n" ); fprintf(stderr, "-framesize <2.5|5|10|20|40|60|80|100|120> : frame size in ms; default: 20 \n" ); fprintf(stderr, "-max_payload : maximum payload size in bytes, default: 1024\n" ); fprintf(stderr, "-complexity : complexity, 0 (lowest) ... 10 (highest); default: 10\n" ); fprintf(stderr, "-inbandfec : enable SILK inband FEC\n" ); fprintf(stderr, "-forcemono : force mono encoding, even for stereo input\n" ); fprintf(stderr, "-dtx : enable SILK DTX\n" ); fprintf(stderr, "-loss : simulate packet loss, in percent (0-100); default: 0\n" ); } static void int_to_char(opus_uint32 i, unsigned char ch[4]) { ch[0] = i>>24; ch[1] = (i>>16)&0xFF; ch[2] = (i>>8)&0xFF; ch[3] = i&0xFF; } static opus_uint32 char_to_int(unsigned char ch[4]) { return ((opus_uint32)ch[0]<<24) | ((opus_uint32)ch[1]<<16) | ((opus_uint32)ch[2]<< 8) | (opus_uint32)ch[3]; } #define check_encoder_option(decode_only, opt) do {if (decode_only) {fprintf(stderr, "option %s is only for encoding\n", opt); goto failure;}} while(0) static const int silk8_test[][4] = { {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*3, 1}, {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*2, 1}, {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960, 1}, {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 480, 1}, {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*3, 2}, {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*2, 2}, {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960, 2}, {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 480, 2} }; static const int silk12_test[][4] = { {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*3, 1}, {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*2, 1}, {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960, 1}, {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 480, 1}, {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*3, 2}, {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*2, 2}, {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960, 2}, {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 480, 2} }; static const int silk16_test[][4] = { {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*3, 1}, {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*2, 1}, {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960, 1}, {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 480, 1}, {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*3, 2}, {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*2, 2}, {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960, 2}, {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 480, 2} }; static const int hybrid24_test[][4] = { {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 1}, {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 1}, {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 2}, {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 2} }; static const int hybrid48_test[][4] = { {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 1}, {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 1}, {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 2}, {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 2} }; static const int celt_test[][4] = { {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 1}, {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 1}, {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960, 1}, {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960, 1}, {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 1}, {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 1}, {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 480, 1}, {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 480, 1}, {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 240, 1}, {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 240, 1}, {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 240, 1}, {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 240, 1}, {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 120, 1}, {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 120, 1}, {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 120, 1}, {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 120, 1}, {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 2}, {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 2}, {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960, 2}, {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960, 2}, {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 2}, {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 2}, {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 480, 2}, {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 480, 2}, {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 240, 2}, {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 240, 2}, {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 240, 2}, {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 240, 2}, {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 120, 2}, {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 120, 2}, {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 120, 2}, {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 120, 2}, }; static const int celt_hq_test[][4] = { {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 2}, {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 2}, {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 240, 2}, {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 120, 2}, }; #if 0 /* This is a hack that replaces the normal encoder/decoder with the multistream version */ #define OpusEncoder OpusMSEncoder #define OpusDecoder OpusMSDecoder #define opus_encode opus_multistream_encode #define opus_decode opus_multistream_decode #define opus_encoder_ctl opus_multistream_encoder_ctl #define opus_decoder_ctl opus_multistream_decoder_ctl #define opus_encoder_create ms_opus_encoder_create #define opus_decoder_create ms_opus_decoder_create #define opus_encoder_destroy opus_multistream_encoder_destroy #define opus_decoder_destroy opus_multistream_decoder_destroy static OpusEncoder *ms_opus_encoder_create(opus_int32 Fs, int channels, int application, int *error) { int streams, coupled_streams; unsigned char mapping[256]; return (OpusEncoder *)opus_multistream_surround_encoder_create(Fs, channels, 1, &streams, &coupled_streams, mapping, application, error); } static OpusDecoder *ms_opus_decoder_create(opus_int32 Fs, int channels, int *error) { int streams; int coupled_streams; unsigned char mapping[256]={0,1}; streams = 1; coupled_streams = channels==2; return (OpusDecoder *)opus_multistream_decoder_create(Fs, channels, streams, coupled_streams, mapping, error); } #endif int main(int argc, char *argv[]) { int err; char *inFile, *outFile; FILE *fin=NULL; FILE *fout=NULL; OpusEncoder *enc=NULL; OpusDecoder *dec=NULL; int args; int len[2]; int frame_size, channels; opus_int32 bitrate_bps=0; unsigned char *data[2] = {NULL, NULL}; unsigned char *fbytes=NULL; opus_int32 sampling_rate; int use_vbr; int max_payload_bytes; int complexity; int use_inbandfec; int use_dtx; int forcechannels; int cvbr = 0; int packet_loss_perc; opus_int32 count=0, count_act=0; int k; opus_int32 skip=0; int stop=0; short *in=NULL; short *out=NULL; int application=OPUS_APPLICATION_AUDIO; double bits=0.0, bits_max=0.0, bits_act=0.0, bits2=0.0, nrg; double tot_samples=0; opus_uint64 tot_in, tot_out; int bandwidth=OPUS_AUTO; const char *bandwidth_string; int lost = 0, lost_prev = 1; int toggle = 0; opus_uint32 enc_final_range[2]; opus_uint32 dec_final_range; int encode_only=0, decode_only=0; int max_frame_size = 48000*2; size_t num_read; int curr_read=0; int sweep_bps = 0; int random_framesize=0, newsize=0, delayed_celt=0; int sweep_max=0, sweep_min=0; int random_fec=0; const int (*mode_list)[4]=NULL; int nb_modes_in_list=0; int curr_mode=0; int curr_mode_count=0; int mode_switch_time = 48000; int nb_encoded=0; int remaining=0; int variable_duration=OPUS_FRAMESIZE_ARG; int delayed_decision=0; int ret = EXIT_FAILURE; if (argc < 5 ) { print_usage( argv ); goto failure; } tot_in=tot_out=0; fprintf(stderr, "%s\n", opus_get_version_string()); args = 1; if (strcmp(argv[args], "-e")==0) { encode_only = 1; args++; } else if (strcmp(argv[args], "-d")==0) { decode_only = 1; args++; } if (!decode_only && argc < 7 ) { print_usage( argv ); goto failure; } if (!decode_only) { if (strcmp(argv[args], "voip")==0) application = OPUS_APPLICATION_VOIP; else if (strcmp(argv[args], "restricted-lowdelay")==0) application = OPUS_APPLICATION_RESTRICTED_LOWDELAY; else if (strcmp(argv[args], "audio")!=0) { fprintf(stderr, "unknown application: %s\n", argv[args]); print_usage(argv); goto failure; } args++; } sampling_rate = (opus_int32)atol(argv[args]); args++; if (sampling_rate != 8000 && sampling_rate != 12000 && sampling_rate != 16000 && sampling_rate != 24000 && sampling_rate != 48000) { fprintf(stderr, "Supported sampling rates are 8000, 12000, " "16000, 24000 and 48000.\n"); goto failure; } frame_size = sampling_rate/50; channels = atoi(argv[args]); args++; if (channels < 1 || channels > 2) { fprintf(stderr, "Opus_demo supports only 1 or 2 channels.\n"); goto failure; } if (!decode_only) { bitrate_bps = (opus_int32)atol(argv[args]); args++; } /* defaults: */ use_vbr = 1; max_payload_bytes = MAX_PACKET; complexity = 10; use_inbandfec = 0; forcechannels = OPUS_AUTO; use_dtx = 0; packet_loss_perc = 0; while( args < argc - 2 ) { /* process command line options */ if( strcmp( argv[ args ], "-cbr" ) == 0 ) { check_encoder_option(decode_only, "-cbr"); use_vbr = 0; args++; } else if( strcmp( argv[ args ], "-bandwidth" ) == 0 ) { check_encoder_option(decode_only, "-bandwidth"); if (strcmp(argv[ args + 1 ], "NB")==0) bandwidth = OPUS_BANDWIDTH_NARROWBAND; else if (strcmp(argv[ args + 1 ], "MB")==0) bandwidth = OPUS_BANDWIDTH_MEDIUMBAND; else if (strcmp(argv[ args + 1 ], "WB")==0) bandwidth = OPUS_BANDWIDTH_WIDEBAND; else if (strcmp(argv[ args + 1 ], "SWB")==0) bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND; else if (strcmp(argv[ args + 1 ], "FB")==0) bandwidth = OPUS_BANDWIDTH_FULLBAND; else { fprintf(stderr, "Unknown bandwidth %s. " "Supported are NB, MB, WB, SWB, FB.\n", argv[ args + 1 ]); goto failure; } args += 2; } else if( strcmp( argv[ args ], "-framesize" ) == 0 ) { check_encoder_option(decode_only, "-framesize"); if (strcmp(argv[ args + 1 ], "2.5")==0) frame_size = sampling_rate/400; else if (strcmp(argv[ args + 1 ], "5")==0) frame_size = sampling_rate/200; else if (strcmp(argv[ args + 1 ], "10")==0) frame_size = sampling_rate/100; else if (strcmp(argv[ args + 1 ], "20")==0) frame_size = sampling_rate/50; else if (strcmp(argv[ args + 1 ], "40")==0) frame_size = sampling_rate/25; else if (strcmp(argv[ args + 1 ], "60")==0) frame_size = 3*sampling_rate/50; else if (strcmp(argv[ args + 1 ], "80")==0) frame_size = 4*sampling_rate/50; else if (strcmp(argv[ args + 1 ], "100")==0) frame_size = 5*sampling_rate/50; else if (strcmp(argv[ args + 1 ], "120")==0) frame_size = 6*sampling_rate/50; else { fprintf(stderr, "Unsupported frame size: %s ms. " "Supported are 2.5, 5, 10, 20, 40, 60, 80, 100, 120.\n", argv[ args + 1 ]); goto failure; } args += 2; } else if( strcmp( argv[ args ], "-max_payload" ) == 0 ) { check_encoder_option(decode_only, "-max_payload"); max_payload_bytes = atoi( argv[ args + 1 ] ); args += 2; } else if( strcmp( argv[ args ], "-complexity" ) == 0 ) { check_encoder_option(decode_only, "-complexity"); complexity = atoi( argv[ args + 1 ] ); args += 2; } else if( strcmp( argv[ args ], "-inbandfec" ) == 0 ) { use_inbandfec = 1; args++; } else if( strcmp( argv[ args ], "-forcemono" ) == 0 ) { check_encoder_option(decode_only, "-forcemono"); forcechannels = 1; args++; } else if( strcmp( argv[ args ], "-cvbr" ) == 0 ) { check_encoder_option(decode_only, "-cvbr"); cvbr = 1; args++; } else if( strcmp( argv[ args ], "-delayed-decision" ) == 0 ) { check_encoder_option(decode_only, "-delayed-decision"); delayed_decision = 1; args++; } else if( strcmp( argv[ args ], "-dtx") == 0 ) { check_encoder_option(decode_only, "-dtx"); use_dtx = 1; args++; } else if( strcmp( argv[ args ], "-loss" ) == 0 ) { packet_loss_perc = atoi( argv[ args + 1 ] ); args += 2; } else if( strcmp( argv[ args ], "-sweep" ) == 0 ) { check_encoder_option(decode_only, "-sweep"); sweep_bps = atoi( argv[ args + 1 ] ); args += 2; } else if( strcmp( argv[ args ], "-random_framesize" ) == 0 ) { check_encoder_option(decode_only, "-random_framesize"); random_framesize = 1; args++; } else if( strcmp( argv[ args ], "-sweep_max" ) == 0 ) { check_encoder_option(decode_only, "-sweep_max"); sweep_max = atoi( argv[ args + 1 ] ); args += 2; } else if( strcmp( argv[ args ], "-random_fec" ) == 0 ) { check_encoder_option(decode_only, "-random_fec"); random_fec = 1; args++; } else if( strcmp( argv[ args ], "-silk8k_test" ) == 0 ) { check_encoder_option(decode_only, "-silk8k_test"); mode_list = silk8_test; nb_modes_in_list = 8; args++; } else if( strcmp( argv[ args ], "-silk12k_test" ) == 0 ) { check_encoder_option(decode_only, "-silk12k_test"); mode_list = silk12_test; nb_modes_in_list = 8; args++; } else if( strcmp( argv[ args ], "-silk16k_test" ) == 0 ) { check_encoder_option(decode_only, "-silk16k_test"); mode_list = silk16_test; nb_modes_in_list = 8; args++; } else if( strcmp( argv[ args ], "-hybrid24k_test" ) == 0 ) { check_encoder_option(decode_only, "-hybrid24k_test"); mode_list = hybrid24_test; nb_modes_in_list = 4; args++; } else if( strcmp( argv[ args ], "-hybrid48k_test" ) == 0 ) { check_encoder_option(decode_only, "-hybrid48k_test"); mode_list = hybrid48_test; nb_modes_in_list = 4; args++; } else if( strcmp( argv[ args ], "-celt_test" ) == 0 ) { check_encoder_option(decode_only, "-celt_test"); mode_list = celt_test; nb_modes_in_list = 32; args++; } else if( strcmp( argv[ args ], "-celt_hq_test" ) == 0 ) { check_encoder_option(decode_only, "-celt_hq_test"); mode_list = celt_hq_test; nb_modes_in_list = 4; args++; } else { printf( "Error: unrecognized setting: %s\n\n", argv[ args ] ); print_usage( argv ); goto failure; } } if (sweep_max) sweep_min = bitrate_bps; if (max_payload_bytes < 0 || max_payload_bytes > MAX_PACKET) { fprintf (stderr, "max_payload_bytes must be between 0 and %d\n", MAX_PACKET); goto failure; } inFile = argv[argc-2]; fin = fopen(inFile, "rb"); if (!fin) { fprintf (stderr, "Could not open input file %s\n", argv[argc-2]); goto failure; } if (mode_list) { int size; fseek(fin, 0, SEEK_END); size = ftell(fin); fprintf(stderr, "File size is %d bytes\n", size); fseek(fin, 0, SEEK_SET); mode_switch_time = size/sizeof(short)/channels/nb_modes_in_list; fprintf(stderr, "Switching mode every %d samples\n", mode_switch_time); } outFile = argv[argc-1]; fout = fopen(outFile, "wb+"); if (!fout) { fprintf (stderr, "Could not open output file %s\n", argv[argc-1]); goto failure; } if (!decode_only) { enc = opus_encoder_create(sampling_rate, channels, application, &err); if (err != OPUS_OK) { fprintf(stderr, "Cannot create encoder: %s\n", opus_strerror(err)); goto failure; } opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps)); opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(bandwidth)); opus_encoder_ctl(enc, OPUS_SET_VBR(use_vbr)); opus_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(cvbr)); opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complexity)); opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(use_inbandfec)); opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(forcechannels)); opus_encoder_ctl(enc, OPUS_SET_DTX(use_dtx)); opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(packet_loss_perc)); opus_encoder_ctl(enc, OPUS_GET_LOOKAHEAD(&skip)); opus_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(16)); opus_encoder_ctl(enc, OPUS_SET_EXPERT_FRAME_DURATION(variable_duration)); } if (!encode_only) { dec = opus_decoder_create(sampling_rate, channels, &err); if (err != OPUS_OK) { fprintf(stderr, "Cannot create decoder: %s\n", opus_strerror(err)); goto failure; } } switch(bandwidth) { case OPUS_BANDWIDTH_NARROWBAND: bandwidth_string = "narrowband"; break; case OPUS_BANDWIDTH_MEDIUMBAND: bandwidth_string = "mediumband"; break; case OPUS_BANDWIDTH_WIDEBAND: bandwidth_string = "wideband"; break; case OPUS_BANDWIDTH_SUPERWIDEBAND: bandwidth_string = "superwideband"; break; case OPUS_BANDWIDTH_FULLBAND: bandwidth_string = "fullband"; break; case OPUS_AUTO: bandwidth_string = "auto bandwidth"; break; default: bandwidth_string = "unknown"; break; } if (decode_only) fprintf(stderr, "Decoding with %ld Hz output (%d channels)\n", (long)sampling_rate, channels); else fprintf(stderr, "Encoding %ld Hz input at %.3f kb/s " "in %s with %d-sample frames.\n", (long)sampling_rate, bitrate_bps*0.001, bandwidth_string, frame_size); in = (short*)malloc(max_frame_size*channels*sizeof(short)); out = (short*)malloc(max_frame_size*channels*sizeof(short)); /* We need to allocate for 16-bit PCM data, but we store it as unsigned char. */ fbytes = (unsigned char*)malloc(max_frame_size*channels*sizeof(short)); data[0] = (unsigned char*)calloc(max_payload_bytes,sizeof(unsigned char)); if ( use_inbandfec ) { data[1] = (unsigned char*)calloc(max_payload_bytes,sizeof(unsigned char)); } if(delayed_decision) { if (frame_size==sampling_rate/400) variable_duration = OPUS_FRAMESIZE_2_5_MS; else if (frame_size==sampling_rate/200) variable_duration = OPUS_FRAMESIZE_5_MS; else if (frame_size==sampling_rate/100) variable_duration = OPUS_FRAMESIZE_10_MS; else if (frame_size==sampling_rate/50) variable_duration = OPUS_FRAMESIZE_20_MS; else if (frame_size==sampling_rate/25) variable_duration = OPUS_FRAMESIZE_40_MS; else if (frame_size==3*sampling_rate/50) variable_duration = OPUS_FRAMESIZE_60_MS; else if (frame_size==4*sampling_rate/50) variable_duration = OPUS_FRAMESIZE_80_MS; else if (frame_size==5*sampling_rate/50) variable_duration = OPUS_FRAMESIZE_100_MS; else variable_duration = OPUS_FRAMESIZE_120_MS; opus_encoder_ctl(enc, OPUS_SET_EXPERT_FRAME_DURATION(variable_duration)); frame_size = 2*48000; } while (!stop) { if (delayed_celt) { frame_size = newsize; delayed_celt = 0; } else if (random_framesize && rand()%20==0) { newsize = rand()%6; switch(newsize) { case 0: newsize=sampling_rate/400; break; case 1: newsize=sampling_rate/200; break; case 2: newsize=sampling_rate/100; break; case 3: newsize=sampling_rate/50; break; case 4: newsize=sampling_rate/25; break; case 5: newsize=3*sampling_rate/50; break; } while (newsize < sampling_rate/25 && bitrate_bps-abs(sweep_bps) <= 3*12*sampling_rate/newsize) newsize*=2; if (newsize < sampling_rate/100 && frame_size >= sampling_rate/100) { opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY)); delayed_celt=1; } else { frame_size = newsize; } } if (random_fec && rand()%30==0) { opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(rand()%4==0)); } if (decode_only) { unsigned char ch[4]; num_read = fread(ch, 1, 4, fin); if (num_read!=4) break; len[toggle] = char_to_int(ch); if (len[toggle]>max_payload_bytes || len[toggle]<0) { fprintf(stderr, "Invalid payload length: %d\n",len[toggle]); break; } num_read = fread(ch, 1, 4, fin); if (num_read!=4) break; enc_final_range[toggle] = char_to_int(ch); num_read = fread(data[toggle], 1, len[toggle], fin); if (num_read!=(size_t)len[toggle]) { fprintf(stderr, "Ran out of input, " "expecting %d bytes got %d\n", len[toggle],(int)num_read); break; } } else { int i; if (mode_list!=NULL) { opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(mode_list[curr_mode][1])); opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(mode_list[curr_mode][0])); opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(mode_list[curr_mode][3])); frame_size = mode_list[curr_mode][2]; } num_read = fread(fbytes, sizeof(short)*channels, frame_size-remaining, fin); curr_read = (int)num_read; tot_in += curr_read; for(i=0;i sweep_max) sweep_bps = -sweep_bps; else if (bitrate_bps < sweep_min) sweep_bps = -sweep_bps; } /* safety */ if (bitrate_bps<1000) bitrate_bps = 1000; opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps)); } opus_encoder_ctl(enc, OPUS_GET_FINAL_RANGE(&enc_final_range[toggle])); if (len[toggle] < 0) { fprintf (stderr, "opus_encode() returned %d\n", len[toggle]); goto failure; } curr_mode_count += frame_size; if (curr_mode_count > mode_switch_time && curr_mode < nb_modes_in_list-1) { curr_mode++; curr_mode_count = 0; } } #if 0 /* This is for testing the padding code, do not enable by default */ if (len[toggle]<1275) { int new_len = len[toggle]+rand()%(max_payload_bytes-len[toggle]); if ((err = opus_packet_pad(data[toggle], len[toggle], new_len)) != OPUS_OK) { fprintf(stderr, "padding failed: %s\n", opus_strerror(err)); goto failure; } len[toggle] = new_len; } #endif if (encode_only) { unsigned char int_field[4]; int_to_char(len[toggle], int_field); if (fwrite(int_field, 1, 4, fout) != 4) { fprintf(stderr, "Error writing.\n"); goto failure; } int_to_char(enc_final_range[toggle], int_field); if (fwrite(int_field, 1, 4, fout) != 4) { fprintf(stderr, "Error writing.\n"); goto failure; } if (fwrite(data[toggle], 1, len[toggle], fout) != (unsigned)len[toggle]) { fprintf(stderr, "Error writing.\n"); goto failure; } tot_samples += nb_encoded; } else { opus_int32 output_samples; lost = len[toggle]==0 || (packet_loss_perc>0 && rand()%100 < packet_loss_perc); if (lost) opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&output_samples)); else output_samples = max_frame_size; if( count >= use_inbandfec ) { /* delay by one packet when using in-band FEC */ if( use_inbandfec ) { if( lost_prev ) { /* attempt to decode with in-band FEC from next packet */ opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&output_samples)); output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, output_samples, 1); } else { /* regular decode */ output_samples = max_frame_size; output_samples = opus_decode(dec, data[1-toggle], len[1-toggle], out, output_samples, 0); } } else { output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, output_samples, 0); } if (output_samples>0) { if (!decode_only && tot_out + output_samples > tot_in) { stop=1; output_samples = (opus_int32)(tot_in - tot_out); } if (output_samples>skip) { int i; for(i=0;i<(output_samples-skip)*channels;i++) { short s; s=out[i+(skip*channels)]; fbytes[2*i]=s&0xFF; fbytes[2*i+1]=(s>>8)&0xFF; } if (fwrite(fbytes, sizeof(short)*channels, output_samples-skip, fout) != (unsigned)(output_samples-skip)){ fprintf(stderr, "Error writing.\n"); goto failure; } tot_out += output_samples-skip; } if (output_samples= use_inbandfec ) { /* count bits */ bits += len[toggle]*8; bits_max = ( len[toggle]*8 > bits_max ) ? len[toggle]*8 : bits_max; bits2 += len[toggle]*len[toggle]*64; if (!decode_only) { nrg = 0.0; for ( k = 0; k < frame_size * channels; k++ ) { nrg += in[ k ] * (double)in[ k ]; } nrg /= frame_size * channels; if( nrg > 1e5 ) { bits_act += len[toggle]*8; count_act++; } } } count++; toggle = (toggle + use_inbandfec) & 1; } if(decode_only && count > 0) frame_size = (int)(tot_samples / count); count -= use_inbandfec; if (tot_samples >= 1 && count > 0 && frame_size) { /* Print out bitrate statistics */ double var; fprintf (stderr, "average bitrate: %7.3f kb/s\n", 1e-3*bits*sampling_rate/tot_samples); fprintf (stderr, "maximum bitrate: %7.3f kb/s\n", 1e-3*bits_max*sampling_rate/frame_size); if (!decode_only) fprintf (stderr, "active bitrate: %7.3f kb/s\n", 1e-3*bits_act*sampling_rate/(1e-15+frame_size*(double)count_act)); var = bits2/count - bits*bits/(count*(double)count); if (var < 0) var = 0; fprintf (stderr, "bitrate standard deviation: %7.3f kb/s\n", 1e-3*sqrt(var)*sampling_rate/frame_size); } else { fprintf(stderr, "bitrate statistics are undefined\n"); } silk_TimerSave("opus_timing.txt"); ret = EXIT_SUCCESS; failure: opus_encoder_destroy(enc); opus_decoder_destroy(dec); free(data[0]); free(data[1]); if (fin) fclose(fin); if (fout) fclose(fout); free(in); free(out); free(fbytes); return ret; } jamulus-3.9.1+dfsg/libs/opus/src/mlp.c0000644000175000017500000001014714340334543016621 0ustar vimervimer/* Copyright (c) 2008-2011 Octasic Inc. 2012-2017 Jean-Marc Valin */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "opus_types.h" #include "opus_defines.h" #include "arch.h" #include "tansig_table.h" #include "mlp.h" static OPUS_INLINE float tansig_approx(float x) { int i; float y, dy; float sign=1; /* Tests are reversed to catch NaNs */ if (!(x<8)) return 1; if (!(x>-8)) return -1; #ifndef FIXED_POINT /* Another check in case of -ffast-math */ if (celt_isnan(x)) return 0; #endif if (x<0) { x=-x; sign=-1; } i = (int)floor(.5f+25*x); x -= .04f*i; y = tansig_table[i]; dy = 1-y*y; y = y + x*dy*(1 - y*x); return sign*y; } static OPUS_INLINE float sigmoid_approx(float x) { return .5f + .5f*tansig_approx(.5f*x); } static void gemm_accum(float *out, const opus_int8 *weights, int rows, int cols, int col_stride, const float *x) { int i, j; for (i=0;inb_inputs; N = layer->nb_neurons; stride = N; for (i=0;ibias[i]; gemm_accum(output, layer->input_weights, N, M, stride, input); for (i=0;isigmoid) { for (i=0;inb_inputs; N = gru->nb_neurons; stride = 3*N; /* Compute update gate. */ for (i=0;ibias[i]; gemm_accum(z, gru->input_weights, N, M, stride, input); gemm_accum(z, gru->recurrent_weights, N, N, stride, state); for (i=0;ibias[N + i]; gemm_accum(r, &gru->input_weights[N], N, M, stride, input); gemm_accum(r, &gru->recurrent_weights[N], N, N, stride, state); for (i=0;ibias[2*N + i]; for (i=0;iinput_weights[2*N], N, M, stride, input); gemm_accum(h, &gru->recurrent_weights[2*N], N, N, stride, tmp); for (i=0;i= 2) && !defined(__OPTIMIZE__) && !defined(OPUS_WILL_BE_SLOW) # pragma message "You appear to be compiling without optimization, if so opus will be very slow." #endif #include #include "celt.h" #include "opus.h" #include "entdec.h" #include "modes.h" #include "API.h" #include "stack_alloc.h" #include "float_cast.h" #include "opus_private.h" #include "os_support.h" #include "structs.h" #include "define.h" #include "mathops.h" #include "cpu_support.h" struct OpusDecoder { int celt_dec_offset; int silk_dec_offset; int channels; opus_int32 Fs; /** Sampling rate (at the API level) */ silk_DecControlStruct DecControl; int decode_gain; int arch; /* Everything beyond this point gets cleared on a reset */ #define OPUS_DECODER_RESET_START stream_channels int stream_channels; int bandwidth; int mode; int prev_mode; int frame_size; int prev_redundancy; int last_packet_duration; #ifndef FIXED_POINT opus_val16 softclip_mem[2]; #endif opus_uint32 rangeFinal; }; #if defined(ENABLE_HARDENING) || defined(ENABLE_ASSERTIONS) static void validate_opus_decoder(OpusDecoder *st) { celt_assert(st->channels == 1 || st->channels == 2); celt_assert(st->Fs == 48000 || st->Fs == 24000 || st->Fs == 16000 || st->Fs == 12000 || st->Fs == 8000); celt_assert(st->DecControl.API_sampleRate == st->Fs); celt_assert(st->DecControl.internalSampleRate == 0 || st->DecControl.internalSampleRate == 16000 || st->DecControl.internalSampleRate == 12000 || st->DecControl.internalSampleRate == 8000); celt_assert(st->DecControl.nChannelsAPI == st->channels); celt_assert(st->DecControl.nChannelsInternal == 0 || st->DecControl.nChannelsInternal == 1 || st->DecControl.nChannelsInternal == 2); celt_assert(st->DecControl.payloadSize_ms == 0 || st->DecControl.payloadSize_ms == 10 || st->DecControl.payloadSize_ms == 20 || st->DecControl.payloadSize_ms == 40 || st->DecControl.payloadSize_ms == 60); #ifdef OPUS_ARCHMASK celt_assert(st->arch >= 0); celt_assert(st->arch <= OPUS_ARCHMASK); #endif celt_assert(st->stream_channels == 1 || st->stream_channels == 2); } #define VALIDATE_OPUS_DECODER(st) validate_opus_decoder(st) #else #define VALIDATE_OPUS_DECODER(st) #endif int opus_decoder_get_size(int channels) { int silkDecSizeBytes, celtDecSizeBytes; int ret; if (channels<1 || channels > 2) return 0; ret = silk_Get_Decoder_Size( &silkDecSizeBytes ); if(ret) return 0; silkDecSizeBytes = align(silkDecSizeBytes); celtDecSizeBytes = celt_decoder_get_size(channels); return align(sizeof(OpusDecoder))+silkDecSizeBytes+celtDecSizeBytes; } int opus_decoder_init(OpusDecoder *st, opus_int32 Fs, int channels) { void *silk_dec; CELTDecoder *celt_dec; int ret, silkDecSizeBytes; if ((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000) || (channels!=1&&channels!=2)) return OPUS_BAD_ARG; OPUS_CLEAR((char*)st, opus_decoder_get_size(channels)); /* Initialize SILK decoder */ ret = silk_Get_Decoder_Size(&silkDecSizeBytes); if (ret) return OPUS_INTERNAL_ERROR; silkDecSizeBytes = align(silkDecSizeBytes); st->silk_dec_offset = align(sizeof(OpusDecoder)); st->celt_dec_offset = st->silk_dec_offset+silkDecSizeBytes; silk_dec = (char*)st+st->silk_dec_offset; celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset); st->stream_channels = st->channels = channels; st->Fs = Fs; st->DecControl.API_sampleRate = st->Fs; st->DecControl.nChannelsAPI = st->channels; /* Reset decoder */ ret = silk_InitDecoder( silk_dec ); if(ret)return OPUS_INTERNAL_ERROR; /* Initialize CELT decoder */ ret = celt_decoder_init(celt_dec, Fs, channels); if(ret!=OPUS_OK)return OPUS_INTERNAL_ERROR; celt_decoder_ctl(celt_dec, CELT_SET_SIGNALLING(0)); st->prev_mode = 0; st->frame_size = Fs/400; st->arch = opus_select_arch(); return OPUS_OK; } OpusDecoder *opus_decoder_create(opus_int32 Fs, int channels, int *error) { int ret; OpusDecoder *st; if ((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000) || (channels!=1&&channels!=2)) { if (error) *error = OPUS_BAD_ARG; return NULL; } st = (OpusDecoder *)opus_alloc(opus_decoder_get_size(channels)); if (st == NULL) { if (error) *error = OPUS_ALLOC_FAIL; return NULL; } ret = opus_decoder_init(st, Fs, channels); if (error) *error = ret; if (ret != OPUS_OK) { opus_free(st); st = NULL; } return st; } static void smooth_fade(const opus_val16 *in1, const opus_val16 *in2, opus_val16 *out, int overlap, int channels, const opus_val16 *window, opus_int32 Fs) { int i, c; int inc = 48000/Fs; for (c=0;csilk_dec_offset; celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset); F20 = st->Fs/50; F10 = F20>>1; F5 = F10>>1; F2_5 = F5>>1; if (frame_size < F2_5) { RESTORE_STACK; return OPUS_BUFFER_TOO_SMALL; } /* Limit frame_size to avoid excessive stack allocations. */ frame_size = IMIN(frame_size, st->Fs/25*3); /* Payloads of 1 (2 including ToC) or 0 trigger the PLC/DTX */ if (len<=1) { data = NULL; /* In that case, don't conceal more than what the ToC says */ frame_size = IMIN(frame_size, st->frame_size); } if (data != NULL) { audiosize = st->frame_size; mode = st->mode; bandwidth = st->bandwidth; ec_dec_init(&dec,(unsigned char*)data,len); } else { audiosize = frame_size; mode = st->prev_mode; bandwidth = 0; if (mode == 0) { /* If we haven't got any packet yet, all we can do is return zeros */ for (i=0;ichannels;i++) pcm[i] = 0; RESTORE_STACK; return audiosize; } /* Avoids trying to run the PLC on sizes other than 2.5 (CELT), 5 (CELT), 10, or 20 (e.g. 12.5 or 30 ms). */ if (audiosize > F20) { do { int ret = opus_decode_frame(st, NULL, 0, pcm, IMIN(audiosize, F20), 0); if (ret<0) { RESTORE_STACK; return ret; } pcm += ret*st->channels; audiosize -= ret; } while (audiosize > 0); RESTORE_STACK; return frame_size; } else if (audiosize < F20) { if (audiosize > F10) audiosize = F10; else if (mode != MODE_SILK_ONLY && audiosize > F5 && audiosize < F10) audiosize = F5; } } /* In fixed-point, we can tell CELT to do the accumulation on top of the SILK PCM buffer. This saves some stack space. */ #ifdef FIXED_POINT celt_accum = (mode != MODE_CELT_ONLY) && (frame_size >= F10); #else celt_accum = 0; #endif pcm_transition_silk_size = ALLOC_NONE; pcm_transition_celt_size = ALLOC_NONE; if (data!=NULL && st->prev_mode > 0 && ( (mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY && !st->prev_redundancy) || (mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) ) ) { transition = 1; /* Decide where to allocate the stack memory for pcm_transition */ if (mode == MODE_CELT_ONLY) pcm_transition_celt_size = F5*st->channels; else pcm_transition_silk_size = F5*st->channels; } ALLOC(pcm_transition_celt, pcm_transition_celt_size, opus_val16); if (transition && mode == MODE_CELT_ONLY) { pcm_transition = pcm_transition_celt; opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0); } if (audiosize > frame_size) { /*fprintf(stderr, "PCM buffer too small: %d vs %d (mode = %d)\n", audiosize, frame_size, mode);*/ RESTORE_STACK; return OPUS_BAD_ARG; } else { frame_size = audiosize; } /* Don't allocate any memory when in CELT-only mode */ pcm_silk_size = (mode != MODE_CELT_ONLY && !celt_accum) ? IMAX(F10, frame_size)*st->channels : ALLOC_NONE; ALLOC(pcm_silk, pcm_silk_size, opus_int16); /* SILK processing */ if (mode != MODE_CELT_ONLY) { int lost_flag, decoded_samples; opus_int16 *pcm_ptr; #ifdef FIXED_POINT if (celt_accum) pcm_ptr = pcm; else #endif pcm_ptr = pcm_silk; if (st->prev_mode==MODE_CELT_ONLY) silk_InitDecoder( silk_dec ); /* The SILK PLC cannot produce frames of less than 10 ms */ st->DecControl.payloadSize_ms = IMAX(10, 1000 * audiosize / st->Fs); if (data != NULL) { st->DecControl.nChannelsInternal = st->stream_channels; if( mode == MODE_SILK_ONLY ) { if( bandwidth == OPUS_BANDWIDTH_NARROWBAND ) { st->DecControl.internalSampleRate = 8000; } else if( bandwidth == OPUS_BANDWIDTH_MEDIUMBAND ) { st->DecControl.internalSampleRate = 12000; } else if( bandwidth == OPUS_BANDWIDTH_WIDEBAND ) { st->DecControl.internalSampleRate = 16000; } else { st->DecControl.internalSampleRate = 16000; celt_assert( 0 ); } } else { /* Hybrid mode */ st->DecControl.internalSampleRate = 16000; } } lost_flag = data == NULL ? 1 : 2 * decode_fec; decoded_samples = 0; do { /* Call SILK decoder */ int first_frame = decoded_samples == 0; silk_ret = silk_Decode( silk_dec, &st->DecControl, lost_flag, first_frame, &dec, pcm_ptr, &silk_frame_size, st->arch ); if( silk_ret ) { if (lost_flag) { /* PLC failure should not be fatal */ silk_frame_size = frame_size; for (i=0;ichannels;i++) pcm_ptr[i] = 0; } else { RESTORE_STACK; return OPUS_INTERNAL_ERROR; } } pcm_ptr += silk_frame_size * st->channels; decoded_samples += silk_frame_size; } while( decoded_samples < frame_size ); } start_band = 0; if (!decode_fec && mode != MODE_CELT_ONLY && data != NULL && ec_tell(&dec)+17+20*(st->mode == MODE_HYBRID) <= 8*len) { /* Check if we have a redundant 0-8 kHz band */ if (mode == MODE_HYBRID) redundancy = ec_dec_bit_logp(&dec, 12); else redundancy = 1; if (redundancy) { celt_to_silk = ec_dec_bit_logp(&dec, 1); /* redundancy_bytes will be at least two, in the non-hybrid case due to the ec_tell() check above */ redundancy_bytes = mode==MODE_HYBRID ? (opus_int32)ec_dec_uint(&dec, 256)+2 : len-((ec_tell(&dec)+7)>>3); len -= redundancy_bytes; /* This is a sanity check. It should never happen for a valid packet, so the exact behaviour is not normative. */ if (len*8 < ec_tell(&dec)) { len = 0; redundancy_bytes = 0; redundancy = 0; } /* Shrink decoder because of raw bits */ dec.storage -= redundancy_bytes; } } if (mode != MODE_CELT_ONLY) start_band = 17; if (redundancy) { transition = 0; pcm_transition_silk_size=ALLOC_NONE; } ALLOC(pcm_transition_silk, pcm_transition_silk_size, opus_val16); if (transition && mode != MODE_CELT_ONLY) { pcm_transition = pcm_transition_silk; opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0); } if (bandwidth) { int endband=21; switch(bandwidth) { case OPUS_BANDWIDTH_NARROWBAND: endband = 13; break; case OPUS_BANDWIDTH_MEDIUMBAND: case OPUS_BANDWIDTH_WIDEBAND: endband = 17; break; case OPUS_BANDWIDTH_SUPERWIDEBAND: endband = 19; break; case OPUS_BANDWIDTH_FULLBAND: endband = 21; break; default: celt_assert(0); break; } MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_SET_END_BAND(endband))); } MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_SET_CHANNELS(st->stream_channels))); /* Only allocation memory for redundancy if/when needed */ redundant_audio_size = redundancy ? F5*st->channels : ALLOC_NONE; ALLOC(redundant_audio, redundant_audio_size, opus_val16); /* 5 ms redundant frame for CELT->SILK*/ if (redundancy && celt_to_silk) { MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0))); celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, redundant_audio, F5, NULL, 0); MUST_SUCCEED(celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng))); } /* MUST be after PLC */ MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(start_band))); if (mode != MODE_SILK_ONLY) { int celt_frame_size = IMIN(F20, frame_size); /* Make sure to discard any previous CELT state */ if (mode != st->prev_mode && st->prev_mode > 0 && !st->prev_redundancy) MUST_SUCCEED(celt_decoder_ctl(celt_dec, OPUS_RESET_STATE)); /* Decode CELT */ celt_ret = celt_decode_with_ec(celt_dec, decode_fec ? NULL : data, len, pcm, celt_frame_size, &dec, celt_accum); } else { unsigned char silence[2] = {0xFF, 0xFF}; if (!celt_accum) { for (i=0;ichannels;i++) pcm[i] = 0; } /* For hybrid -> SILK transitions, we let the CELT MDCT do a fade-out by decoding a silence frame */ if (st->prev_mode == MODE_HYBRID && !(redundancy && celt_to_silk && st->prev_redundancy) ) { MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0))); celt_decode_with_ec(celt_dec, silence, 2, pcm, F2_5, NULL, celt_accum); } } if (mode != MODE_CELT_ONLY && !celt_accum) { #ifdef FIXED_POINT for (i=0;ichannels;i++) pcm[i] = SAT16(ADD32(pcm[i], pcm_silk[i])); #else for (i=0;ichannels;i++) pcm[i] = pcm[i] + (opus_val16)((1.f/32768.f)*pcm_silk[i]); #endif } { const CELTMode *celt_mode; MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_GET_MODE(&celt_mode))); window = celt_mode->window; } /* 5 ms redundant frame for SILK->CELT */ if (redundancy && !celt_to_silk) { MUST_SUCCEED(celt_decoder_ctl(celt_dec, OPUS_RESET_STATE)); MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0))); celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, redundant_audio, F5, NULL, 0); MUST_SUCCEED(celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng))); smooth_fade(pcm+st->channels*(frame_size-F2_5), redundant_audio+st->channels*F2_5, pcm+st->channels*(frame_size-F2_5), F2_5, st->channels, window, st->Fs); } if (redundancy && celt_to_silk) { for (c=0;cchannels;c++) { for (i=0;ichannels*i+c] = redundant_audio[st->channels*i+c]; } smooth_fade(redundant_audio+st->channels*F2_5, pcm+st->channels*F2_5, pcm+st->channels*F2_5, F2_5, st->channels, window, st->Fs); } if (transition) { if (audiosize >= F5) { for (i=0;ichannels*F2_5;i++) pcm[i] = pcm_transition[i]; smooth_fade(pcm_transition+st->channels*F2_5, pcm+st->channels*F2_5, pcm+st->channels*F2_5, F2_5, st->channels, window, st->Fs); } else { /* Not enough time to do a clean transition, but we do it anyway This will not preserve amplitude perfectly and may introduce a bit of temporal aliasing, but it shouldn't be too bad and that's pretty much the best we can do. In any case, generating this transition it pretty silly in the first place */ smooth_fade(pcm_transition, pcm, pcm, F2_5, st->channels, window, st->Fs); } } if(st->decode_gain) { opus_val32 gain; gain = celt_exp2(MULT16_16_P15(QCONST16(6.48814081e-4f, 25), st->decode_gain)); for (i=0;ichannels;i++) { opus_val32 x; x = MULT16_32_P16(pcm[i],gain); pcm[i] = SATURATE(x, 32767); } } if (len <= 1) st->rangeFinal = 0; else st->rangeFinal = dec.rng ^ redundant_rng; st->prev_mode = mode; st->prev_redundancy = redundancy && !celt_to_silk; if (celt_ret>=0) { if (OPUS_CHECK_ARRAY(pcm, audiosize*st->channels)) OPUS_PRINT_INT(audiosize); } RESTORE_STACK; return celt_ret < 0 ? celt_ret : audiosize; } int opus_decode_native(OpusDecoder *st, const unsigned char *data, opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec, int self_delimited, opus_int32 *packet_offset, int soft_clip) { int i, nb_samples; int count, offset; unsigned char toc; int packet_frame_size, packet_bandwidth, packet_mode, packet_stream_channels; /* 48 x 2.5 ms = 120 ms */ opus_int16 size[48]; VALIDATE_OPUS_DECODER(st); if (decode_fec<0 || decode_fec>1) return OPUS_BAD_ARG; /* For FEC/PLC, frame_size has to be to have a multiple of 2.5 ms */ if ((decode_fec || len==0 || data==NULL) && frame_size%(st->Fs/400)!=0) return OPUS_BAD_ARG; if (len==0 || data==NULL) { int pcm_count=0; do { int ret; ret = opus_decode_frame(st, NULL, 0, pcm+pcm_count*st->channels, frame_size-pcm_count, 0); if (ret<0) return ret; pcm_count += ret; } while (pcm_count < frame_size); celt_assert(pcm_count == frame_size); if (OPUS_CHECK_ARRAY(pcm, pcm_count*st->channels)) OPUS_PRINT_INT(pcm_count); st->last_packet_duration = pcm_count; return pcm_count; } else if (len<0) return OPUS_BAD_ARG; packet_mode = opus_packet_get_mode(data); packet_bandwidth = opus_packet_get_bandwidth(data); packet_frame_size = opus_packet_get_samples_per_frame(data, st->Fs); packet_stream_channels = opus_packet_get_nb_channels(data); count = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL, size, &offset, packet_offset); if (count<0) return count; data += offset; if (decode_fec) { int duration_copy; int ret; /* If no FEC can be present, run the PLC (recursive call) */ if (frame_size < packet_frame_size || packet_mode == MODE_CELT_ONLY || st->mode == MODE_CELT_ONLY) return opus_decode_native(st, NULL, 0, pcm, frame_size, 0, 0, NULL, soft_clip); /* Otherwise, run the PLC on everything except the size for which we might have FEC */ duration_copy = st->last_packet_duration; if (frame_size-packet_frame_size!=0) { ret = opus_decode_native(st, NULL, 0, pcm, frame_size-packet_frame_size, 0, 0, NULL, soft_clip); if (ret<0) { st->last_packet_duration = duration_copy; return ret; } celt_assert(ret==frame_size-packet_frame_size); } /* Complete with FEC */ st->mode = packet_mode; st->bandwidth = packet_bandwidth; st->frame_size = packet_frame_size; st->stream_channels = packet_stream_channels; ret = opus_decode_frame(st, data, size[0], pcm+st->channels*(frame_size-packet_frame_size), packet_frame_size, 1); if (ret<0) return ret; else { if (OPUS_CHECK_ARRAY(pcm, frame_size*st->channels)) OPUS_PRINT_INT(frame_size); st->last_packet_duration = frame_size; return frame_size; } } if (count*packet_frame_size > frame_size) return OPUS_BUFFER_TOO_SMALL; /* Update the state as the last step to avoid updating it on an invalid packet */ st->mode = packet_mode; st->bandwidth = packet_bandwidth; st->frame_size = packet_frame_size; st->stream_channels = packet_stream_channels; nb_samples=0; for (i=0;ichannels, frame_size-nb_samples, 0); if (ret<0) return ret; celt_assert(ret==packet_frame_size); data += size[i]; nb_samples += ret; } st->last_packet_duration = nb_samples; if (OPUS_CHECK_ARRAY(pcm, nb_samples*st->channels)) OPUS_PRINT_INT(nb_samples); #ifndef FIXED_POINT if (soft_clip) opus_pcm_soft_clip(pcm, nb_samples, st->channels, st->softclip_mem); else st->softclip_mem[0]=st->softclip_mem[1]=0; #endif return nb_samples; } #ifdef FIXED_POINT int opus_decode(OpusDecoder *st, const unsigned char *data, opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec) { if(frame_size<=0) return OPUS_BAD_ARG; return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL, 0); } #ifndef DISABLE_FLOAT_API int opus_decode_float(OpusDecoder *st, const unsigned char *data, opus_int32 len, float *pcm, int frame_size, int decode_fec) { VARDECL(opus_int16, out); int ret, i; int nb_samples; ALLOC_STACK; if(frame_size<=0) { RESTORE_STACK; return OPUS_BAD_ARG; } if (data != NULL && len > 0 && !decode_fec) { nb_samples = opus_decoder_get_nb_samples(st, data, len); if (nb_samples>0) frame_size = IMIN(frame_size, nb_samples); else return OPUS_INVALID_PACKET; } celt_assert(st->channels == 1 || st->channels == 2); ALLOC(out, frame_size*st->channels, opus_int16); ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 0); if (ret > 0) { for (i=0;ichannels;i++) pcm[i] = (1.f/32768.f)*(out[i]); } RESTORE_STACK; return ret; } #endif #else int opus_decode(OpusDecoder *st, const unsigned char *data, opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec) { VARDECL(float, out); int ret, i; int nb_samples; ALLOC_STACK; if(frame_size<=0) { RESTORE_STACK; return OPUS_BAD_ARG; } if (data != NULL && len > 0 && !decode_fec) { nb_samples = opus_decoder_get_nb_samples(st, data, len); if (nb_samples>0) frame_size = IMIN(frame_size, nb_samples); else return OPUS_INVALID_PACKET; } celt_assert(st->channels == 1 || st->channels == 2); ALLOC(out, frame_size*st->channels, float); ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 1); if (ret > 0) { for (i=0;ichannels;i++) pcm[i] = FLOAT2INT16(out[i]); } RESTORE_STACK; return ret; } int opus_decode_float(OpusDecoder *st, const unsigned char *data, opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec) { if(frame_size<=0) return OPUS_BAD_ARG; return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL, 0); } #endif int opus_decoder_ctl(OpusDecoder *st, int request, ...) { int ret = OPUS_OK; va_list ap; void *silk_dec; CELTDecoder *celt_dec; silk_dec = (char*)st+st->silk_dec_offset; celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset); va_start(ap, request); switch (request) { case OPUS_GET_BANDWIDTH_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } *value = st->bandwidth; } break; case OPUS_GET_FINAL_RANGE_REQUEST: { opus_uint32 *value = va_arg(ap, opus_uint32*); if (!value) { goto bad_arg; } *value = st->rangeFinal; } break; case OPUS_RESET_STATE: { OPUS_CLEAR((char*)&st->OPUS_DECODER_RESET_START, sizeof(OpusDecoder)- ((char*)&st->OPUS_DECODER_RESET_START - (char*)st)); celt_decoder_ctl(celt_dec, OPUS_RESET_STATE); silk_InitDecoder( silk_dec ); st->stream_channels = st->channels; st->frame_size = st->Fs/400; } break; case OPUS_GET_SAMPLE_RATE_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } *value = st->Fs; } break; case OPUS_GET_PITCH_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } if (st->prev_mode == MODE_CELT_ONLY) ret = celt_decoder_ctl(celt_dec, OPUS_GET_PITCH(value)); else *value = st->DecControl.prevPitchLag; } break; case OPUS_GET_GAIN_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } *value = st->decode_gain; } break; case OPUS_SET_GAIN_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); if (value<-32768 || value>32767) { goto bad_arg; } st->decode_gain = value; } break; case OPUS_GET_LAST_PACKET_DURATION_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } *value = st->last_packet_duration; } break; case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); if(value<0 || value>1) { goto bad_arg; } ret = celt_decoder_ctl(celt_dec, OPUS_SET_PHASE_INVERSION_DISABLED(value)); } break; case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } ret = celt_decoder_ctl(celt_dec, OPUS_GET_PHASE_INVERSION_DISABLED(value)); } break; default: /*fprintf(stderr, "unknown opus_decoder_ctl() request: %d", request);*/ ret = OPUS_UNIMPLEMENTED; break; } va_end(ap); return ret; bad_arg: va_end(ap); return OPUS_BAD_ARG; } void opus_decoder_destroy(OpusDecoder *st) { opus_free(st); } int opus_packet_get_bandwidth(const unsigned char *data) { int bandwidth; if (data[0]&0x80) { bandwidth = OPUS_BANDWIDTH_MEDIUMBAND + ((data[0]>>5)&0x3); if (bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) bandwidth = OPUS_BANDWIDTH_NARROWBAND; } else if ((data[0]&0x60) == 0x60) { bandwidth = (data[0]&0x10) ? OPUS_BANDWIDTH_FULLBAND : OPUS_BANDWIDTH_SUPERWIDEBAND; } else { bandwidth = OPUS_BANDWIDTH_NARROWBAND + ((data[0]>>5)&0x3); } return bandwidth; } int opus_packet_get_nb_channels(const unsigned char *data) { return (data[0]&0x4) ? 2 : 1; } int opus_packet_get_nb_frames(const unsigned char packet[], opus_int32 len) { int count; if (len<1) return OPUS_BAD_ARG; count = packet[0]&0x3; if (count==0) return 1; else if (count!=3) return 2; else if (len<2) return OPUS_INVALID_PACKET; else return packet[1]&0x3F; } int opus_packet_get_nb_samples(const unsigned char packet[], opus_int32 len, opus_int32 Fs) { int samples; int count = opus_packet_get_nb_frames(packet, len); if (count<0) return count; samples = count*opus_packet_get_samples_per_frame(packet, Fs); /* Can't have more than 120 ms */ if (samples*25 > Fs*3) return OPUS_INVALID_PACKET; else return samples; } int opus_decoder_get_nb_samples(const OpusDecoder *dec, const unsigned char packet[], opus_int32 len) { return opus_packet_get_nb_samples(packet, len, dec->Fs); } jamulus-3.9.1+dfsg/libs/opus/src/opus_projection_encoder.c0000644000175000017500000003461714340334543022762 0ustar vimervimer/* Copyright (c) 2017 Google Inc. Written by Andrew Allen */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "mathops.h" #include "os_support.h" #include "opus_private.h" #include "opus_defines.h" #include "opus_projection.h" #include "opus_multistream.h" #include "stack_alloc.h" #include "mapping_matrix.h" struct OpusProjectionEncoder { opus_int32 mixing_matrix_size_in_bytes; opus_int32 demixing_matrix_size_in_bytes; /* Encoder states go here */ }; #if !defined(DISABLE_FLOAT_API) static void opus_projection_copy_channel_in_float( opus_val16 *dst, int dst_stride, const void *src, int src_stride, int src_channel, int frame_size, void *user_data ) { mapping_matrix_multiply_channel_in_float((const MappingMatrix*)user_data, (const float*)src, src_stride, dst, src_channel, dst_stride, frame_size); } #endif static void opus_projection_copy_channel_in_short( opus_val16 *dst, int dst_stride, const void *src, int src_stride, int src_channel, int frame_size, void *user_data ) { mapping_matrix_multiply_channel_in_short((const MappingMatrix*)user_data, (const opus_int16*)src, src_stride, dst, src_channel, dst_stride, frame_size); } static int get_order_plus_one_from_channels(int channels, int *order_plus_one) { int order_plus_one_; int acn_channels; int nondiegetic_channels; /* Allowed numbers of channels: * (1 + n)^2 + 2j, for n = 0...14 and j = 0 or 1. */ if (channels < 1 || channels > 227) return OPUS_BAD_ARG; order_plus_one_ = isqrt32(channels); acn_channels = order_plus_one_ * order_plus_one_; nondiegetic_channels = channels - acn_channels; if (nondiegetic_channels != 0 && nondiegetic_channels != 2) return OPUS_BAD_ARG; if (order_plus_one) *order_plus_one = order_plus_one_; return OPUS_OK; } static int get_streams_from_channels(int channels, int mapping_family, int *streams, int *coupled_streams, int *order_plus_one) { if (mapping_family == 3) { if (get_order_plus_one_from_channels(channels, order_plus_one) != OPUS_OK) return OPUS_BAD_ARG; if (streams) *streams = (channels + 1) / 2; if (coupled_streams) *coupled_streams = channels / 2; return OPUS_OK; } return OPUS_BAD_ARG; } static MappingMatrix *get_mixing_matrix(OpusProjectionEncoder *st) { /* void* cast avoids clang -Wcast-align warning */ return (MappingMatrix *)(void*)((char*)st + align(sizeof(OpusProjectionEncoder))); } static MappingMatrix *get_enc_demixing_matrix(OpusProjectionEncoder *st) { /* void* cast avoids clang -Wcast-align warning */ return (MappingMatrix *)(void*)((char*)st + align(sizeof(OpusProjectionEncoder) + st->mixing_matrix_size_in_bytes)); } static OpusMSEncoder *get_multistream_encoder(OpusProjectionEncoder *st) { /* void* cast avoids clang -Wcast-align warning */ return (OpusMSEncoder *)(void*)((char*)st + align(sizeof(OpusProjectionEncoder) + st->mixing_matrix_size_in_bytes + st->demixing_matrix_size_in_bytes)); } opus_int32 opus_projection_ambisonics_encoder_get_size(int channels, int mapping_family) { int nb_streams; int nb_coupled_streams; int order_plus_one; int mixing_matrix_rows, mixing_matrix_cols; int demixing_matrix_rows, demixing_matrix_cols; opus_int32 mixing_matrix_size, demixing_matrix_size; opus_int32 encoder_size; int ret; ret = get_streams_from_channels(channels, mapping_family, &nb_streams, &nb_coupled_streams, &order_plus_one); if (ret != OPUS_OK) return 0; if (order_plus_one == 2) { mixing_matrix_rows = mapping_matrix_foa_mixing.rows; mixing_matrix_cols = mapping_matrix_foa_mixing.cols; demixing_matrix_rows = mapping_matrix_foa_demixing.rows; demixing_matrix_cols = mapping_matrix_foa_demixing.cols; } else if (order_plus_one == 3) { mixing_matrix_rows = mapping_matrix_soa_mixing.rows; mixing_matrix_cols = mapping_matrix_soa_mixing.cols; demixing_matrix_rows = mapping_matrix_soa_demixing.rows; demixing_matrix_cols = mapping_matrix_soa_demixing.cols; } else if (order_plus_one == 4) { mixing_matrix_rows = mapping_matrix_toa_mixing.rows; mixing_matrix_cols = mapping_matrix_toa_mixing.cols; demixing_matrix_rows = mapping_matrix_toa_demixing.rows; demixing_matrix_cols = mapping_matrix_toa_demixing.cols; } else return 0; mixing_matrix_size = mapping_matrix_get_size(mixing_matrix_rows, mixing_matrix_cols); if (!mixing_matrix_size) return 0; demixing_matrix_size = mapping_matrix_get_size(demixing_matrix_rows, demixing_matrix_cols); if (!demixing_matrix_size) return 0; encoder_size = opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams); if (!encoder_size) return 0; return align(sizeof(OpusProjectionEncoder)) + mixing_matrix_size + demixing_matrix_size + encoder_size; } int opus_projection_ambisonics_encoder_init(OpusProjectionEncoder *st, opus_int32 Fs, int channels, int mapping_family, int *streams, int *coupled_streams, int application) { MappingMatrix *mixing_matrix; MappingMatrix *demixing_matrix; OpusMSEncoder *ms_encoder; int i; int ret; int order_plus_one; unsigned char mapping[255]; if (streams == NULL || coupled_streams == NULL) { return OPUS_BAD_ARG; } if (get_streams_from_channels(channels, mapping_family, streams, coupled_streams, &order_plus_one) != OPUS_OK) return OPUS_BAD_ARG; if (mapping_family == 3) { /* Assign mixing matrix based on available pre-computed matrices. */ mixing_matrix = get_mixing_matrix(st); if (order_plus_one == 2) { mapping_matrix_init(mixing_matrix, mapping_matrix_foa_mixing.rows, mapping_matrix_foa_mixing.cols, mapping_matrix_foa_mixing.gain, mapping_matrix_foa_mixing_data, sizeof(mapping_matrix_foa_mixing_data)); } else if (order_plus_one == 3) { mapping_matrix_init(mixing_matrix, mapping_matrix_soa_mixing.rows, mapping_matrix_soa_mixing.cols, mapping_matrix_soa_mixing.gain, mapping_matrix_soa_mixing_data, sizeof(mapping_matrix_soa_mixing_data)); } else if (order_plus_one == 4) { mapping_matrix_init(mixing_matrix, mapping_matrix_toa_mixing.rows, mapping_matrix_toa_mixing.cols, mapping_matrix_toa_mixing.gain, mapping_matrix_toa_mixing_data, sizeof(mapping_matrix_toa_mixing_data)); } else return OPUS_BAD_ARG; st->mixing_matrix_size_in_bytes = mapping_matrix_get_size( mixing_matrix->rows, mixing_matrix->cols); if (!st->mixing_matrix_size_in_bytes) return OPUS_BAD_ARG; /* Assign demixing matrix based on available pre-computed matrices. */ demixing_matrix = get_enc_demixing_matrix(st); if (order_plus_one == 2) { mapping_matrix_init(demixing_matrix, mapping_matrix_foa_demixing.rows, mapping_matrix_foa_demixing.cols, mapping_matrix_foa_demixing.gain, mapping_matrix_foa_demixing_data, sizeof(mapping_matrix_foa_demixing_data)); } else if (order_plus_one == 3) { mapping_matrix_init(demixing_matrix, mapping_matrix_soa_demixing.rows, mapping_matrix_soa_demixing.cols, mapping_matrix_soa_demixing.gain, mapping_matrix_soa_demixing_data, sizeof(mapping_matrix_soa_demixing_data)); } else if (order_plus_one == 4) { mapping_matrix_init(demixing_matrix, mapping_matrix_toa_demixing.rows, mapping_matrix_toa_demixing.cols, mapping_matrix_toa_demixing.gain, mapping_matrix_toa_demixing_data, sizeof(mapping_matrix_toa_demixing_data)); } else return OPUS_BAD_ARG; st->demixing_matrix_size_in_bytes = mapping_matrix_get_size( demixing_matrix->rows, demixing_matrix->cols); if (!st->demixing_matrix_size_in_bytes) return OPUS_BAD_ARG; } else return OPUS_UNIMPLEMENTED; /* Ensure matrices are large enough for desired coding scheme. */ if (*streams + *coupled_streams > mixing_matrix->rows || channels > mixing_matrix->cols || channels > demixing_matrix->rows || *streams + *coupled_streams > demixing_matrix->cols) return OPUS_BAD_ARG; /* Set trivial mapping so each input channel pairs with a matrix column. */ for (i = 0; i < channels; i++) mapping[i] = i; /* Initialize multistream encoder with provided settings. */ ms_encoder = get_multistream_encoder(st); ret = opus_multistream_encoder_init(ms_encoder, Fs, channels, *streams, *coupled_streams, mapping, application); return ret; } OpusProjectionEncoder *opus_projection_ambisonics_encoder_create( opus_int32 Fs, int channels, int mapping_family, int *streams, int *coupled_streams, int application, int *error) { int size; int ret; OpusProjectionEncoder *st; /* Allocate space for the projection encoder. */ size = opus_projection_ambisonics_encoder_get_size(channels, mapping_family); if (!size) { if (error) *error = OPUS_ALLOC_FAIL; return NULL; } st = (OpusProjectionEncoder *)opus_alloc(size); if (!st) { if (error) *error = OPUS_ALLOC_FAIL; return NULL; } /* Initialize projection encoder with provided settings. */ ret = opus_projection_ambisonics_encoder_init(st, Fs, channels, mapping_family, streams, coupled_streams, application); if (ret != OPUS_OK) { opus_free(st); st = NULL; } if (error) *error = ret; return st; } int opus_projection_encode(OpusProjectionEncoder *st, const opus_int16 *pcm, int frame_size, unsigned char *data, opus_int32 max_data_bytes) { return opus_multistream_encode_native(get_multistream_encoder(st), opus_projection_copy_channel_in_short, pcm, frame_size, data, max_data_bytes, 16, downmix_int, 0, get_mixing_matrix(st)); } #ifndef DISABLE_FLOAT_API #ifdef FIXED_POINT int opus_projection_encode_float(OpusProjectionEncoder *st, const float *pcm, int frame_size, unsigned char *data, opus_int32 max_data_bytes) { return opus_multistream_encode_native(get_multistream_encoder(st), opus_projection_copy_channel_in_float, pcm, frame_size, data, max_data_bytes, 16, downmix_float, 1, get_mixing_matrix(st)); } #else int opus_projection_encode_float(OpusProjectionEncoder *st, const float *pcm, int frame_size, unsigned char *data, opus_int32 max_data_bytes) { return opus_multistream_encode_native(get_multistream_encoder(st), opus_projection_copy_channel_in_float, pcm, frame_size, data, max_data_bytes, 24, downmix_float, 1, get_mixing_matrix(st)); } #endif #endif void opus_projection_encoder_destroy(OpusProjectionEncoder *st) { opus_free(st); } int opus_projection_encoder_ctl(OpusProjectionEncoder *st, int request, ...) { va_list ap; MappingMatrix *demixing_matrix; OpusMSEncoder *ms_encoder; int ret = OPUS_OK; ms_encoder = get_multistream_encoder(st); demixing_matrix = get_enc_demixing_matrix(st); va_start(ap, request); switch(request) { case OPUS_PROJECTION_GET_DEMIXING_MATRIX_SIZE_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } *value = ms_encoder->layout.nb_channels * (ms_encoder->layout.nb_streams + ms_encoder->layout.nb_coupled_streams) * sizeof(opus_int16); } break; case OPUS_PROJECTION_GET_DEMIXING_MATRIX_GAIN_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } *value = demixing_matrix->gain; } break; case OPUS_PROJECTION_GET_DEMIXING_MATRIX_REQUEST: { int i, j, k, l; int nb_input_streams; int nb_output_streams; unsigned char *external_char; opus_int16 *internal_short; opus_int32 external_size; opus_int32 internal_size; /* (I/O is in relation to the decoder's perspective). */ nb_input_streams = ms_encoder->layout.nb_streams + ms_encoder->layout.nb_coupled_streams; nb_output_streams = ms_encoder->layout.nb_channels; external_char = va_arg(ap, unsigned char *); external_size = va_arg(ap, opus_int32); if (!external_char) { goto bad_arg; } internal_short = mapping_matrix_get_data(demixing_matrix); internal_size = nb_input_streams * nb_output_streams * sizeof(opus_int16); if (external_size != internal_size) { goto bad_arg; } /* Copy demixing matrix subset to output destination. */ l = 0; for (i = 0; i < nb_input_streams; i++) { for (j = 0; j < nb_output_streams; j++) { k = demixing_matrix->rows * i + j; external_char[2*l] = (unsigned char)internal_short[k]; external_char[2*l+1] = (unsigned char)(internal_short[k] >> 8); l++; } } } break; default: { ret = opus_multistream_encoder_ctl_va_list(ms_encoder, request, ap); } break; } va_end(ap); return ret; bad_arg: va_end(ap); return OPUS_BAD_ARG; } jamulus-3.9.1+dfsg/libs/opus/src/repacketizer_demo.c0000644000175000017500000001471414340334543021531 0ustar vimervimer/* Copyright (c) 2011 Xiph.Org Foundation Written by Jean-Marc Valin */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "opus.h" #include #include #include #define MAX_PACKETOUT 32000 void usage(char *argv0) { fprintf(stderr, "usage: %s [options] input_file output_file\n", argv0); } static void int_to_char(opus_uint32 i, unsigned char ch[4]) { ch[0] = i>>24; ch[1] = (i>>16)&0xFF; ch[2] = (i>>8)&0xFF; ch[3] = i&0xFF; } static opus_uint32 char_to_int(unsigned char ch[4]) { return ((opus_uint32)ch[0]<<24) | ((opus_uint32)ch[1]<<16) | ((opus_uint32)ch[2]<< 8) | (opus_uint32)ch[3]; } int main(int argc, char *argv[]) { int i, eof=0; FILE *fin, *fout; unsigned char packets[48][1500]; int len[48]; int rng[48]; OpusRepacketizer *rp; unsigned char output_packet[MAX_PACKETOUT]; int merge = 1, split=0; if (argc < 3) { usage(argv[0]); return EXIT_FAILURE; } for (i=1;i48) { fprintf(stderr, "-merge parameter must be less than 48.\n"); return EXIT_FAILURE; } i++; } else if (strcmp(argv[i], "-split")==0) split = 1; else { fprintf(stderr, "Unknown option: %s\n", argv[i]); usage(argv[0]); return EXIT_FAILURE; } } fin = fopen(argv[argc-2], "r"); if(fin==NULL) { fprintf(stderr, "Error opening input file: %s\n", argv[argc-2]); return EXIT_FAILURE; } fout = fopen(argv[argc-1], "w"); if(fout==NULL) { fprintf(stderr, "Error opening output file: %s\n", argv[argc-1]); fclose(fin); return EXIT_FAILURE; } rp = opus_repacketizer_create(); while (!eof) { int err; int nb_packets=merge; opus_repacketizer_init(rp); for (i=0;i1500 || len[i]<0) { if (feof(fin)) { eof = 1; } else { fprintf(stderr, "Invalid payload length\n"); fclose(fin); fclose(fout); return EXIT_FAILURE; } break; } err = fread(ch, 1, 4, fin); rng[i] = char_to_int(ch); err = fread(packets[i], 1, len[i], fin); if (feof(fin)) { eof = 1; break; } err = opus_repacketizer_cat(rp, packets[i], len[i]); if (err!=OPUS_OK) { fprintf(stderr, "opus_repacketizer_cat() failed: %s\n", opus_strerror(err)); break; } } nb_packets = i; if (eof) break; if (!split) { err = opus_repacketizer_out(rp, output_packet, MAX_PACKETOUT); if (err>0) { unsigned char int_field[4]; int_to_char(err, int_field); if(fwrite(int_field, 1, 4, fout)!=4){ fprintf(stderr, "Error writing.\n"); return EXIT_FAILURE; } int_to_char(rng[nb_packets-1], int_field); if (fwrite(int_field, 1, 4, fout)!=4) { fprintf(stderr, "Error writing.\n"); return EXIT_FAILURE; } if (fwrite(output_packet, 1, err, fout)!=(unsigned)err) { fprintf(stderr, "Error writing.\n"); return EXIT_FAILURE; } /*fprintf(stderr, "out len = %d\n", err);*/ } else { fprintf(stderr, "opus_repacketizer_out() failed: %s\n", opus_strerror(err)); } } else { int nb_frames = opus_repacketizer_get_nb_frames(rp); for (i=0;i0) { unsigned char int_field[4]; int_to_char(err, int_field); if (fwrite(int_field, 1, 4, fout)!=4) { fprintf(stderr, "Error writing.\n"); return EXIT_FAILURE; } if (i==nb_frames-1) int_to_char(rng[nb_packets-1], int_field); else int_to_char(0, int_field); if (fwrite(int_field, 1, 4, fout)!=4) { fprintf(stderr, "Error writing.\n"); return EXIT_FAILURE; } if (fwrite(output_packet, 1, err, fout)!=(unsigned)err) { fprintf(stderr, "Error writing.\n"); return EXIT_FAILURE; } /*fprintf(stderr, "out len = %d\n", err);*/ } else { fprintf(stderr, "opus_repacketizer_out() failed: %s\n", opus_strerror(err)); } } } } fclose(fin); fclose(fout); return EXIT_SUCCESS; } jamulus-3.9.1+dfsg/libs/opus/src/analysis.h0000644000175000017500000000677714340334543017677 0ustar vimervimer/* Copyright (c) 2011 Xiph.Org Foundation Written by Jean-Marc Valin */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef ANALYSIS_H #define ANALYSIS_H #include "celt.h" #include "opus_private.h" #include "mlp.h" #define NB_FRAMES 8 #define NB_TBANDS 18 #define ANALYSIS_BUF_SIZE 720 /* 30 ms at 24 kHz */ /* At that point we can stop counting frames because it no longer matters. */ #define ANALYSIS_COUNT_MAX 10000 #define DETECT_SIZE 100 /* Uncomment this to print the MLP features on stdout. */ /*#define MLP_TRAINING*/ typedef struct { int arch; int application; opus_int32 Fs; #define TONALITY_ANALYSIS_RESET_START angle float angle[240]; float d_angle[240]; float d2_angle[240]; opus_val32 inmem[ANALYSIS_BUF_SIZE]; int mem_fill; /* number of usable samples in the buffer */ float prev_band_tonality[NB_TBANDS]; float prev_tonality; int prev_bandwidth; float E[NB_FRAMES][NB_TBANDS]; float logE[NB_FRAMES][NB_TBANDS]; float lowE[NB_TBANDS]; float highE[NB_TBANDS]; float meanE[NB_TBANDS+1]; float mem[32]; float cmean[8]; float std[9]; float Etracker; float lowECount; int E_count; int count; int analysis_offset; int write_pos; int read_pos; int read_subframe; float hp_ener_accum; int initialized; float rnn_state[MAX_NEURONS]; opus_val32 downmix_state[3]; AnalysisInfo info[DETECT_SIZE]; } TonalityAnalysisState; /** Initialize a TonalityAnalysisState struct. * * This performs some possibly slow initialization steps which should * not be repeated every analysis step. No allocated memory is retained * by the state struct, so no cleanup call is required. */ void tonality_analysis_init(TonalityAnalysisState *analysis, opus_int32 Fs); /** Reset a TonalityAnalysisState struct. * * Call this when there's a discontinuity in the data. */ void tonality_analysis_reset(TonalityAnalysisState *analysis); void tonality_get_info(TonalityAnalysisState *tonal, AnalysisInfo *info_out, int len); void run_analysis(TonalityAnalysisState *analysis, const CELTMode *celt_mode, const void *analysis_pcm, int analysis_frame_size, int frame_size, int c1, int c2, int C, opus_int32 Fs, int lsb_depth, downmix_func downmix, AnalysisInfo *analysis_info); #endif jamulus-3.9.1+dfsg/libs/opus/src/analysis.c0000644000175000017500000010645114340334543017660 0ustar vimervimer/* Copyright (c) 2011 Xiph.Org Foundation Written by Jean-Marc Valin */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define ANALYSIS_C #include #include "mathops.h" #include "kiss_fft.h" #include "celt.h" #include "modes.h" #include "arch.h" #include "quant_bands.h" #include "analysis.h" #include "mlp.h" #include "stack_alloc.h" #include "float_cast.h" #ifndef M_PI #define M_PI 3.141592653 #endif #ifndef DISABLE_FLOAT_API #define TRANSITION_PENALTY 10 static const float dct_table[128] = { 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.351851f, 0.338330f, 0.311806f, 0.273300f, 0.224292f, 0.166664f, 0.102631f, 0.034654f, -0.034654f,-0.102631f,-0.166664f,-0.224292f,-0.273300f,-0.311806f,-0.338330f,-0.351851f, 0.346760f, 0.293969f, 0.196424f, 0.068975f,-0.068975f,-0.196424f,-0.293969f,-0.346760f, -0.346760f,-0.293969f,-0.196424f,-0.068975f, 0.068975f, 0.196424f, 0.293969f, 0.346760f, 0.338330f, 0.224292f, 0.034654f,-0.166664f,-0.311806f,-0.351851f,-0.273300f,-0.102631f, 0.102631f, 0.273300f, 0.351851f, 0.311806f, 0.166664f,-0.034654f,-0.224292f,-0.338330f, 0.326641f, 0.135299f,-0.135299f,-0.326641f,-0.326641f,-0.135299f, 0.135299f, 0.326641f, 0.326641f, 0.135299f,-0.135299f,-0.326641f,-0.326641f,-0.135299f, 0.135299f, 0.326641f, 0.311806f, 0.034654f,-0.273300f,-0.338330f,-0.102631f, 0.224292f, 0.351851f, 0.166664f, -0.166664f,-0.351851f,-0.224292f, 0.102631f, 0.338330f, 0.273300f,-0.034654f,-0.311806f, 0.293969f,-0.068975f,-0.346760f,-0.196424f, 0.196424f, 0.346760f, 0.068975f,-0.293969f, -0.293969f, 0.068975f, 0.346760f, 0.196424f,-0.196424f,-0.346760f,-0.068975f, 0.293969f, 0.273300f,-0.166664f,-0.338330f, 0.034654f, 0.351851f, 0.102631f,-0.311806f,-0.224292f, 0.224292f, 0.311806f,-0.102631f,-0.351851f,-0.034654f, 0.338330f, 0.166664f,-0.273300f, }; static const float analysis_window[240] = { 0.000043f, 0.000171f, 0.000385f, 0.000685f, 0.001071f, 0.001541f, 0.002098f, 0.002739f, 0.003466f, 0.004278f, 0.005174f, 0.006156f, 0.007222f, 0.008373f, 0.009607f, 0.010926f, 0.012329f, 0.013815f, 0.015385f, 0.017037f, 0.018772f, 0.020590f, 0.022490f, 0.024472f, 0.026535f, 0.028679f, 0.030904f, 0.033210f, 0.035595f, 0.038060f, 0.040604f, 0.043227f, 0.045928f, 0.048707f, 0.051564f, 0.054497f, 0.057506f, 0.060591f, 0.063752f, 0.066987f, 0.070297f, 0.073680f, 0.077136f, 0.080665f, 0.084265f, 0.087937f, 0.091679f, 0.095492f, 0.099373f, 0.103323f, 0.107342f, 0.111427f, 0.115579f, 0.119797f, 0.124080f, 0.128428f, 0.132839f, 0.137313f, 0.141849f, 0.146447f, 0.151105f, 0.155823f, 0.160600f, 0.165435f, 0.170327f, 0.175276f, 0.180280f, 0.185340f, 0.190453f, 0.195619f, 0.200838f, 0.206107f, 0.211427f, 0.216797f, 0.222215f, 0.227680f, 0.233193f, 0.238751f, 0.244353f, 0.250000f, 0.255689f, 0.261421f, 0.267193f, 0.273005f, 0.278856f, 0.284744f, 0.290670f, 0.296632f, 0.302628f, 0.308658f, 0.314721f, 0.320816f, 0.326941f, 0.333097f, 0.339280f, 0.345492f, 0.351729f, 0.357992f, 0.364280f, 0.370590f, 0.376923f, 0.383277f, 0.389651f, 0.396044f, 0.402455f, 0.408882f, 0.415325f, 0.421783f, 0.428254f, 0.434737f, 0.441231f, 0.447736f, 0.454249f, 0.460770f, 0.467298f, 0.473832f, 0.480370f, 0.486912f, 0.493455f, 0.500000f, 0.506545f, 0.513088f, 0.519630f, 0.526168f, 0.532702f, 0.539230f, 0.545751f, 0.552264f, 0.558769f, 0.565263f, 0.571746f, 0.578217f, 0.584675f, 0.591118f, 0.597545f, 0.603956f, 0.610349f, 0.616723f, 0.623077f, 0.629410f, 0.635720f, 0.642008f, 0.648271f, 0.654508f, 0.660720f, 0.666903f, 0.673059f, 0.679184f, 0.685279f, 0.691342f, 0.697372f, 0.703368f, 0.709330f, 0.715256f, 0.721144f, 0.726995f, 0.732807f, 0.738579f, 0.744311f, 0.750000f, 0.755647f, 0.761249f, 0.766807f, 0.772320f, 0.777785f, 0.783203f, 0.788573f, 0.793893f, 0.799162f, 0.804381f, 0.809547f, 0.814660f, 0.819720f, 0.824724f, 0.829673f, 0.834565f, 0.839400f, 0.844177f, 0.848895f, 0.853553f, 0.858151f, 0.862687f, 0.867161f, 0.871572f, 0.875920f, 0.880203f, 0.884421f, 0.888573f, 0.892658f, 0.896677f, 0.900627f, 0.904508f, 0.908321f, 0.912063f, 0.915735f, 0.919335f, 0.922864f, 0.926320f, 0.929703f, 0.933013f, 0.936248f, 0.939409f, 0.942494f, 0.945503f, 0.948436f, 0.951293f, 0.954072f, 0.956773f, 0.959396f, 0.961940f, 0.964405f, 0.966790f, 0.969096f, 0.971321f, 0.973465f, 0.975528f, 0.977510f, 0.979410f, 0.981228f, 0.982963f, 0.984615f, 0.986185f, 0.987671f, 0.989074f, 0.990393f, 0.991627f, 0.992778f, 0.993844f, 0.994826f, 0.995722f, 0.996534f, 0.997261f, 0.997902f, 0.998459f, 0.998929f, 0.999315f, 0.999615f, 0.999829f, 0.999957f, 1.000000f, }; static const int tbands[NB_TBANDS+1] = { 4, 8, 12, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 136, 160, 192, 240 }; #define NB_TONAL_SKIP_BANDS 9 static opus_val32 silk_resampler_down2_hp( opus_val32 *S, /* I/O State vector [ 2 ] */ opus_val32 *out, /* O Output signal [ floor(len/2) ] */ const opus_val32 *in, /* I Input signal [ len ] */ int inLen /* I Number of input samples */ ) { int k, len2 = inLen/2; opus_val32 in32, out32, out32_hp, Y, X; opus_val64 hp_ener = 0; /* Internal variables and state are in Q10 format */ for( k = 0; k < len2; k++ ) { /* Convert to Q10 */ in32 = in[ 2 * k ]; /* All-pass section for even input sample */ Y = SUB32( in32, S[ 0 ] ); X = MULT16_32_Q15(QCONST16(0.6074371f, 15), Y); out32 = ADD32( S[ 0 ], X ); S[ 0 ] = ADD32( in32, X ); out32_hp = out32; /* Convert to Q10 */ in32 = in[ 2 * k + 1 ]; /* All-pass section for odd input sample, and add to output of previous section */ Y = SUB32( in32, S[ 1 ] ); X = MULT16_32_Q15(QCONST16(0.15063f, 15), Y); out32 = ADD32( out32, S[ 1 ] ); out32 = ADD32( out32, X ); S[ 1 ] = ADD32( in32, X ); Y = SUB32( -in32, S[ 2 ] ); X = MULT16_32_Q15(QCONST16(0.15063f, 15), Y); out32_hp = ADD32( out32_hp, S[ 2 ] ); out32_hp = ADD32( out32_hp, X ); S[ 2 ] = ADD32( -in32, X ); hp_ener += out32_hp*(opus_val64)out32_hp; /* Add, convert back to int16 and store to output */ out[ k ] = HALF32(out32); } #ifdef FIXED_POINT /* len2 can be up to 480, so we shift by 8 more to make it fit. */ hp_ener = hp_ener >> (2*SIG_SHIFT + 8); #endif return (opus_val32)hp_ener; } static opus_val32 downmix_and_resample(downmix_func downmix, const void *_x, opus_val32 *y, opus_val32 S[3], int subframe, int offset, int c1, int c2, int C, int Fs) { VARDECL(opus_val32, tmp); opus_val32 scale; int j; opus_val32 ret = 0; SAVE_STACK; if (subframe==0) return 0; if (Fs == 48000) { subframe *= 2; offset *= 2; } else if (Fs == 16000) { subframe = subframe*2/3; offset = offset*2/3; } ALLOC(tmp, subframe, opus_val32); downmix(_x, tmp, subframe, offset, c1, c2, C); #ifdef FIXED_POINT scale = (1<-1) scale /= 2; for (j=0;jarch = opus_select_arch(); tonal->Fs = Fs; /* Clear remaining fields. */ tonality_analysis_reset(tonal); } void tonality_analysis_reset(TonalityAnalysisState *tonal) { /* Clear non-reusable fields. */ char *start = (char*)&tonal->TONALITY_ANALYSIS_RESET_START; OPUS_CLEAR(start, sizeof(TonalityAnalysisState) - (start - (char*)tonal)); } void tonality_get_info(TonalityAnalysisState *tonal, AnalysisInfo *info_out, int len) { int pos; int curr_lookahead; float tonality_max; float tonality_avg; int tonality_count; int i; int pos0; float prob_avg; float prob_count; float prob_min, prob_max; float vad_prob; int mpos, vpos; int bandwidth_span; pos = tonal->read_pos; curr_lookahead = tonal->write_pos-tonal->read_pos; if (curr_lookahead<0) curr_lookahead += DETECT_SIZE; tonal->read_subframe += len/(tonal->Fs/400); while (tonal->read_subframe>=8) { tonal->read_subframe -= 8; tonal->read_pos++; } if (tonal->read_pos>=DETECT_SIZE) tonal->read_pos-=DETECT_SIZE; /* On long frames, look at the second analysis window rather than the first. */ if (len > tonal->Fs/50 && pos != tonal->write_pos) { pos++; if (pos==DETECT_SIZE) pos=0; } if (pos == tonal->write_pos) pos--; if (pos<0) pos = DETECT_SIZE-1; pos0 = pos; OPUS_COPY(info_out, &tonal->info[pos], 1); if (!info_out->valid) return; tonality_max = tonality_avg = info_out->tonality; tonality_count = 1; /* Look at the neighbouring frames and pick largest bandwidth found (to be safe). */ bandwidth_span = 6; /* If possible, look ahead for a tone to compensate for the delay in the tone detector. */ for (i=0;i<3;i++) { pos++; if (pos==DETECT_SIZE) pos = 0; if (pos == tonal->write_pos) break; tonality_max = MAX32(tonality_max, tonal->info[pos].tonality); tonality_avg += tonal->info[pos].tonality; tonality_count++; info_out->bandwidth = IMAX(info_out->bandwidth, tonal->info[pos].bandwidth); bandwidth_span--; } pos = pos0; /* Look back in time to see if any has a wider bandwidth than the current frame. */ for (i=0;iwrite_pos) break; info_out->bandwidth = IMAX(info_out->bandwidth, tonal->info[pos].bandwidth); } info_out->tonality = MAX32(tonality_avg/tonality_count, tonality_max-.2f); mpos = vpos = pos0; /* If we have enough look-ahead, compensate for the ~5-frame delay in the music prob and ~1 frame delay in the VAD prob. */ if (curr_lookahead > 15) { mpos += 5; if (mpos>=DETECT_SIZE) mpos -= DETECT_SIZE; vpos += 1; if (vpos>=DETECT_SIZE) vpos -= DETECT_SIZE; } /* The following calculations attempt to minimize a "badness function" for the transition. When switching from speech to music, the badness of switching at frame k is b_k = S*v_k + \sum_{i=0}^{k-1} v_i*(p_i - T) where v_i is the activity probability (VAD) at frame i, p_i is the music probability at frame i T is the probability threshold for switching S is the penalty for switching during active audio rather than silence the current frame has index i=0 Rather than apply badness to directly decide when to switch, what we compute instead is the threshold for which the optimal switching point is now. When considering whether to switch now (frame 0) or at frame k, we have: S*v_0 = S*v_k + \sum_{i=0}^{k-1} v_i*(p_i - T) which gives us: T = ( \sum_{i=0}^{k-1} v_i*p_i + S*(v_k-v_0) ) / ( \sum_{i=0}^{k-1} v_i ) We take the min threshold across all positive values of k (up to the maximum amount of lookahead we have) to give us the threshold for which the current frame is the optimal switch point. The last step is that we need to consider whether we want to switch at all. For that we use the average of the music probability over the entire window. If the threshold is higher than that average we're not going to switch, so we compute a min with the average as well. The result of all these min operations is music_prob_min, which gives the threshold for switching to music if we're currently encoding for speech. We do the exact opposite to compute music_prob_max which is used for switching from music to speech. */ prob_min = 1.f; prob_max = 0.f; vad_prob = tonal->info[vpos].activity_probability; prob_count = MAX16(.1f, vad_prob); prob_avg = MAX16(.1f, vad_prob)*tonal->info[mpos].music_prob; while (1) { float pos_vad; mpos++; if (mpos==DETECT_SIZE) mpos = 0; if (mpos == tonal->write_pos) break; vpos++; if (vpos==DETECT_SIZE) vpos = 0; if (vpos == tonal->write_pos) break; pos_vad = tonal->info[vpos].activity_probability; prob_min = MIN16((prob_avg - TRANSITION_PENALTY*(vad_prob - pos_vad))/prob_count, prob_min); prob_max = MAX16((prob_avg + TRANSITION_PENALTY*(vad_prob - pos_vad))/prob_count, prob_max); prob_count += MAX16(.1f, pos_vad); prob_avg += MAX16(.1f, pos_vad)*tonal->info[mpos].music_prob; } info_out->music_prob = prob_avg/prob_count; prob_min = MIN16(prob_avg/prob_count, prob_min); prob_max = MAX16(prob_avg/prob_count, prob_max); prob_min = MAX16(prob_min, 0.f); prob_max = MIN16(prob_max, 1.f); /* If we don't have enough look-ahead, do our best to make a decent decision. */ if (curr_lookahead < 10) { float pmin, pmax; pmin = prob_min; pmax = prob_max; pos = pos0; /* Look for min/max in the past. */ for (i=0;icount-1, 15);i++) { pos--; if (pos < 0) pos = DETECT_SIZE-1; pmin = MIN16(pmin, tonal->info[pos].music_prob); pmax = MAX16(pmax, tonal->info[pos].music_prob); } /* Bias against switching on active audio. */ pmin = MAX16(0.f, pmin - .1f*vad_prob); pmax = MIN16(1.f, pmax + .1f*vad_prob); prob_min += (1.f-.1f*curr_lookahead)*(pmin - prob_min); prob_max += (1.f-.1f*curr_lookahead)*(pmax - prob_max); } info_out->music_prob_min = prob_min; info_out->music_prob_max = prob_max; /* printf("%f %f %f %f %f\n", prob_min, prob_max, prob_avg/prob_count, vad_prob, info_out->music_prob); */ } static const float std_feature_bias[9] = { 5.684947f, 3.475288f, 1.770634f, 1.599784f, 3.773215f, 2.163313f, 1.260756f, 1.116868f, 1.918795f }; #define LEAKAGE_OFFSET 2.5f #define LEAKAGE_SLOPE 2.f #ifdef FIXED_POINT /* For fixed-point, the input is +/-2^15 shifted up by SIG_SHIFT, so we need to compensate for that in the energy. */ #define SCALE_COMPENS (1.f/((opus_int32)1<<(15+SIG_SHIFT))) #define SCALE_ENER(e) ((SCALE_COMPENS*SCALE_COMPENS)*(e)) #else #define SCALE_ENER(e) (e) #endif #ifdef FIXED_POINT static int is_digital_silence32(const opus_val32* pcm, int frame_size, int channels, int lsb_depth) { int silence = 0; opus_val32 sample_max = 0; #ifdef MLP_TRAINING return 0; #endif sample_max = celt_maxabs32(pcm, frame_size*channels); silence = (sample_max == 0); (void)lsb_depth; return silence; } #else #define is_digital_silence32(pcm, frame_size, channels, lsb_depth) is_digital_silence(pcm, frame_size, channels, lsb_depth) #endif static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt_mode, const void *x, int len, int offset, int c1, int c2, int C, int lsb_depth, downmix_func downmix) { int i, b; const kiss_fft_state *kfft; VARDECL(kiss_fft_cpx, in); VARDECL(kiss_fft_cpx, out); int N = 480, N2=240; float * OPUS_RESTRICT A = tonal->angle; float * OPUS_RESTRICT dA = tonal->d_angle; float * OPUS_RESTRICT d2A = tonal->d2_angle; VARDECL(float, tonality); VARDECL(float, noisiness); float band_tonality[NB_TBANDS]; float logE[NB_TBANDS]; float BFCC[8]; float features[25]; float frame_tonality; float max_frame_tonality; /*float tw_sum=0;*/ float frame_noisiness; const float pi4 = (float)(M_PI*M_PI*M_PI*M_PI); float slope=0; float frame_stationarity; float relativeE; float frame_probs[2]; float alpha, alphaE, alphaE2; float frame_loudness; float bandwidth_mask; int is_masked[NB_TBANDS+1]; int bandwidth=0; float maxE = 0; float noise_floor; int remaining; AnalysisInfo *info; float hp_ener; float tonality2[240]; float midE[8]; float spec_variability=0; float band_log2[NB_TBANDS+1]; float leakage_from[NB_TBANDS+1]; float leakage_to[NB_TBANDS+1]; float layer_out[MAX_NEURONS]; float below_max_pitch; float above_max_pitch; int is_silence; SAVE_STACK; if (!tonal->initialized) { tonal->mem_fill = 240; tonal->initialized = 1; } alpha = 1.f/IMIN(10, 1+tonal->count); alphaE = 1.f/IMIN(25, 1+tonal->count); /* Noise floor related decay for bandwidth detection: -2.2 dB/second */ alphaE2 = 1.f/IMIN(100, 1+tonal->count); if (tonal->count <= 1) alphaE2 = 1; if (tonal->Fs == 48000) { /* len and offset are now at 24 kHz. */ len/= 2; offset /= 2; } else if (tonal->Fs == 16000) { len = 3*len/2; offset = 3*offset/2; } kfft = celt_mode->mdct.kfft[0]; tonal->hp_ener_accum += (float)downmix_and_resample(downmix, x, &tonal->inmem[tonal->mem_fill], tonal->downmix_state, IMIN(len, ANALYSIS_BUF_SIZE-tonal->mem_fill), offset, c1, c2, C, tonal->Fs); if (tonal->mem_fill+len < ANALYSIS_BUF_SIZE) { tonal->mem_fill += len; /* Don't have enough to update the analysis */ RESTORE_STACK; return; } hp_ener = tonal->hp_ener_accum; info = &tonal->info[tonal->write_pos++]; if (tonal->write_pos>=DETECT_SIZE) tonal->write_pos-=DETECT_SIZE; is_silence = is_digital_silence32(tonal->inmem, ANALYSIS_BUF_SIZE, 1, lsb_depth); ALLOC(in, 480, kiss_fft_cpx); ALLOC(out, 480, kiss_fft_cpx); ALLOC(tonality, 240, float); ALLOC(noisiness, 240, float); for (i=0;iinmem[i]); in[i].i = (kiss_fft_scalar)(w*tonal->inmem[N2+i]); in[N-i-1].r = (kiss_fft_scalar)(w*tonal->inmem[N-i-1]); in[N-i-1].i = (kiss_fft_scalar)(w*tonal->inmem[N+N2-i-1]); } OPUS_MOVE(tonal->inmem, tonal->inmem+ANALYSIS_BUF_SIZE-240, 240); remaining = len - (ANALYSIS_BUF_SIZE-tonal->mem_fill); tonal->hp_ener_accum = (float)downmix_and_resample(downmix, x, &tonal->inmem[240], tonal->downmix_state, remaining, offset+ANALYSIS_BUF_SIZE-tonal->mem_fill, c1, c2, C, tonal->Fs); tonal->mem_fill = 240 + remaining; if (is_silence) { /* On silence, copy the previous analysis. */ int prev_pos = tonal->write_pos-2; if (prev_pos < 0) prev_pos += DETECT_SIZE; OPUS_COPY(info, &tonal->info[prev_pos], 1); RESTORE_STACK; return; } opus_fft(kfft, in, out, tonal->arch); #ifndef FIXED_POINT /* If there's any NaN on the input, the entire output will be NaN, so we only need to check one value. */ if (celt_isnan(out[0].r)) { info->valid = 0; RESTORE_STACK; return; } #endif for (i=1;iactivity = 0; frame_noisiness = 0; frame_stationarity = 0; if (!tonal->count) { for (b=0;blowE[b] = 1e10; tonal->highE[b] = -1e10; } } relativeE = 0; frame_loudness = 0; /* The energy of the very first band is special because of DC. */ { float E = 0; float X1r, X2r; X1r = 2*(float)out[0].r; X2r = 2*(float)out[0].i; E = X1r*X1r + X2r*X2r; for (i=1;i<4;i++) { float binE = out[i].r*(float)out[i].r + out[N-i].r*(float)out[N-i].r + out[i].i*(float)out[i].i + out[N-i].i*(float)out[N-i].i; E += binE; } E = SCALE_ENER(E); band_log2[0] = .5f*1.442695f*(float)log(E+1e-10f); } for (b=0;bvalid = 0; RESTORE_STACK; return; } #endif tonal->E[tonal->E_count][b] = E; frame_noisiness += nE/(1e-15f+E); frame_loudness += (float)sqrt(E+1e-10f); logE[b] = (float)log(E+1e-10f); band_log2[b+1] = .5f*1.442695f*(float)log(E+1e-10f); tonal->logE[tonal->E_count][b] = logE[b]; if (tonal->count==0) tonal->highE[b] = tonal->lowE[b] = logE[b]; if (tonal->highE[b] > tonal->lowE[b] + 7.5) { if (tonal->highE[b] - logE[b] > logE[b] - tonal->lowE[b]) tonal->highE[b] -= .01f; else tonal->lowE[b] += .01f; } if (logE[b] > tonal->highE[b]) { tonal->highE[b] = logE[b]; tonal->lowE[b] = MAX32(tonal->highE[b]-15, tonal->lowE[b]); } else if (logE[b] < tonal->lowE[b]) { tonal->lowE[b] = logE[b]; tonal->highE[b] = MIN32(tonal->lowE[b]+15, tonal->highE[b]); } relativeE += (logE[b]-tonal->lowE[b])/(1e-5f + (tonal->highE[b]-tonal->lowE[b])); L1=L2=0; for (i=0;iE[i][b]); L2 += tonal->E[i][b]; } stationarity = MIN16(0.99f,L1/(float)sqrt(1e-15+NB_FRAMES*L2)); stationarity *= stationarity; stationarity *= stationarity; frame_stationarity += stationarity; /*band_tonality[b] = tE/(1e-15+E)*/; band_tonality[b] = MAX16(tE/(1e-15f+E), stationarity*tonal->prev_band_tonality[b]); #if 0 if (b>=NB_TONAL_SKIP_BANDS) { frame_tonality += tweight[b]*band_tonality[b]; tw_sum += tweight[b]; } #else frame_tonality += band_tonality[b]; if (b>=NB_TBANDS-NB_TONAL_SKIP_BANDS) frame_tonality -= band_tonality[b-NB_TBANDS+NB_TONAL_SKIP_BANDS]; #endif max_frame_tonality = MAX16(max_frame_tonality, (1.f+.03f*(b-NB_TBANDS))*frame_tonality); slope += band_tonality[b]*(b-8); /*printf("%f %f ", band_tonality[b], stationarity);*/ tonal->prev_band_tonality[b] = band_tonality[b]; } leakage_from[0] = band_log2[0]; leakage_to[0] = band_log2[0] - LEAKAGE_OFFSET; for (b=1;b=0;b--) { float leak_slope = LEAKAGE_SLOPE*(tbands[b+1]-tbands[b])/4; leakage_from[b] = MIN16(leakage_from[b+1]+leak_slope, leakage_from[b]); leakage_to[b] = MAX16(leakage_to[b+1]-leak_slope, leakage_to[b]); } celt_assert(NB_TBANDS+1 <= LEAK_BANDS); for (b=0;bleak_boost[b] = IMIN(255, (int)floor(.5 + 64.f*boost)); } for (;bleak_boost[b] = 0; for (i=0;ilogE[i][k] - tonal->logE[j][k]; dist += tmp*tmp; } if (j!=i) mindist = MIN32(mindist, dist); } spec_variability += mindist; } spec_variability = (float)sqrt(spec_variability/NB_FRAMES/NB_TBANDS); bandwidth_mask = 0; bandwidth = 0; maxE = 0; noise_floor = 5.7e-4f/(1<<(IMAX(0,lsb_depth-8))); noise_floor *= noise_floor; below_max_pitch=0; above_max_pitch=0; for (b=0;bmeanE[b] = MAX32((1-alphaE2)*tonal->meanE[b], E); Em = MAX32(E, tonal->meanE[b]); /* Consider the band "active" only if all these conditions are met: 1) less than 90 dB below the peak band (maximal masking possible considering both the ATH and the loudness-dependent slope of the spreading function) 2) above the PCM quantization noise floor We use b+1 because the first CELT band isn't included in tbands[] */ if (E*1e9f > maxE && (Em > 3*noise_floor*(band_end-band_start) || E > noise_floor*(band_end-band_start))) bandwidth = b+1; /* Check if the band is masked (see below). */ is_masked[b] = E < (tonal->prev_bandwidth >= b+1 ? .01f : .05f)*bandwidth_mask; /* Use a simple follower with 13 dB/Bark slope for spreading function. */ bandwidth_mask = MAX32(.05f*bandwidth_mask, E); } /* Special case for the last two bands, for which we don't have spectrum but only the energy above 12 kHz. The difficulty here is that the high-pass we use leaks some LF energy, so we need to increase the threshold without accidentally cutting off the band. */ if (tonal->Fs == 48000) { float noise_ratio; float Em; float E = hp_ener*(1.f/(60*60)); noise_ratio = tonal->prev_bandwidth==20 ? 10.f : 30.f; #ifdef FIXED_POINT /* silk_resampler_down2_hp() shifted right by an extra 8 bits. */ E *= 256.f*(1.f/Q15ONE)*(1.f/Q15ONE); #endif above_max_pitch += E; tonal->meanE[b] = MAX32((1-alphaE2)*tonal->meanE[b], E); Em = MAX32(E, tonal->meanE[b]); if (Em > 3*noise_ratio*noise_floor*160 || E > noise_ratio*noise_floor*160) bandwidth = 20; /* Check if the band is masked (see below). */ is_masked[b] = E < (tonal->prev_bandwidth == 20 ? .01f : .05f)*bandwidth_mask; } if (above_max_pitch > below_max_pitch) info->max_pitch_ratio = below_max_pitch/above_max_pitch; else info->max_pitch_ratio = 1; /* In some cases, resampling aliasing can create a small amount of energy in the first band being cut. So if the last band is masked, we don't include it. */ if (bandwidth == 20 && is_masked[NB_TBANDS]) bandwidth-=2; else if (bandwidth > 0 && bandwidth <= NB_TBANDS && is_masked[bandwidth-1]) bandwidth--; if (tonal->count<=2) bandwidth = 20; frame_loudness = 20*(float)log10(frame_loudness); tonal->Etracker = MAX32(tonal->Etracker-.003f, frame_loudness); tonal->lowECount *= (1-alphaE); if (frame_loudness < tonal->Etracker-30) tonal->lowECount += alphaE; for (i=0;i<8;i++) { float sum=0; for (b=0;b<16;b++) sum += dct_table[i*16+b]*logE[b]; BFCC[i] = sum; } for (i=0;i<8;i++) { float sum=0; for (b=0;b<16;b++) sum += dct_table[i*16+b]*.5f*(tonal->highE[b]+tonal->lowE[b]); midE[i] = sum; } frame_stationarity /= NB_TBANDS; relativeE /= NB_TBANDS; if (tonal->count<10) relativeE = .5f; frame_noisiness /= NB_TBANDS; #if 1 info->activity = frame_noisiness + (1-frame_noisiness)*relativeE; #else info->activity = .5*(1+frame_noisiness-frame_stationarity); #endif frame_tonality = (max_frame_tonality/(NB_TBANDS-NB_TONAL_SKIP_BANDS)); frame_tonality = MAX16(frame_tonality, tonal->prev_tonality*.8f); tonal->prev_tonality = frame_tonality; slope /= 8*8; info->tonality_slope = slope; tonal->E_count = (tonal->E_count+1)%NB_FRAMES; tonal->count = IMIN(tonal->count+1, ANALYSIS_COUNT_MAX); info->tonality = frame_tonality; for (i=0;i<4;i++) features[i] = -0.12299f*(BFCC[i]+tonal->mem[i+24]) + 0.49195f*(tonal->mem[i]+tonal->mem[i+16]) + 0.69693f*tonal->mem[i+8] - 1.4349f*tonal->cmean[i]; for (i=0;i<4;i++) tonal->cmean[i] = (1-alpha)*tonal->cmean[i] + alpha*BFCC[i]; for (i=0;i<4;i++) features[4+i] = 0.63246f*(BFCC[i]-tonal->mem[i+24]) + 0.31623f*(tonal->mem[i]-tonal->mem[i+16]); for (i=0;i<3;i++) features[8+i] = 0.53452f*(BFCC[i]+tonal->mem[i+24]) - 0.26726f*(tonal->mem[i]+tonal->mem[i+16]) -0.53452f*tonal->mem[i+8]; if (tonal->count > 5) { for (i=0;i<9;i++) tonal->std[i] = (1-alpha)*tonal->std[i] + alpha*features[i]*features[i]; } for (i=0;i<4;i++) features[i] = BFCC[i]-midE[i]; for (i=0;i<8;i++) { tonal->mem[i+24] = tonal->mem[i+16]; tonal->mem[i+16] = tonal->mem[i+8]; tonal->mem[i+8] = tonal->mem[i]; tonal->mem[i] = BFCC[i]; } for (i=0;i<9;i++) features[11+i] = (float)sqrt(tonal->std[i]) - std_feature_bias[i]; features[18] = spec_variability - 0.78f; features[20] = info->tonality - 0.154723f; features[21] = info->activity - 0.724643f; features[22] = frame_stationarity - 0.743717f; features[23] = info->tonality_slope + 0.069216f; features[24] = tonal->lowECount - 0.067930f; compute_dense(&layer0, layer_out, features); compute_gru(&layer1, tonal->rnn_state, layer_out); compute_dense(&layer2, frame_probs, tonal->rnn_state); /* Probability of speech or music vs noise */ info->activity_probability = frame_probs[1]; info->music_prob = frame_probs[0]; /*printf("%f %f %f\n", frame_probs[0], frame_probs[1], info->music_prob);*/ #ifdef MLP_TRAINING for (i=0;i<25;i++) printf("%f ", features[i]); printf("\n"); #endif info->bandwidth = bandwidth; tonal->prev_bandwidth = bandwidth; /*printf("%d %d\n", info->bandwidth, info->opus_bandwidth);*/ info->noisiness = frame_noisiness; info->valid = 1; RESTORE_STACK; } void run_analysis(TonalityAnalysisState *analysis, const CELTMode *celt_mode, const void *analysis_pcm, int analysis_frame_size, int frame_size, int c1, int c2, int C, opus_int32 Fs, int lsb_depth, downmix_func downmix, AnalysisInfo *analysis_info) { int offset; int pcm_len; analysis_frame_size -= analysis_frame_size&1; if (analysis_pcm != NULL) { /* Avoid overflow/wrap-around of the analysis buffer */ analysis_frame_size = IMIN((DETECT_SIZE-5)*Fs/50, analysis_frame_size); pcm_len = analysis_frame_size - analysis->analysis_offset; offset = analysis->analysis_offset; while (pcm_len>0) { tonality_analysis(analysis, celt_mode, analysis_pcm, IMIN(Fs/50, pcm_len), offset, c1, c2, C, lsb_depth, downmix); offset += Fs/50; pcm_len -= Fs/50; } analysis->analysis_offset = analysis_frame_size; analysis->analysis_offset -= frame_size; } tonality_get_info(analysis, analysis_info, frame_size); } #endif /* DISABLE_FLOAT_API */ jamulus-3.9.1+dfsg/libs/opus/src/repacketizer.c0000644000175000017500000002326114340334543020522 0ustar vimervimer/* Copyright (c) 2011 Xiph.Org Foundation Written by Jean-Marc Valin */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "opus.h" #include "opus_private.h" #include "os_support.h" int opus_repacketizer_get_size(void) { return sizeof(OpusRepacketizer); } OpusRepacketizer *opus_repacketizer_init(OpusRepacketizer *rp) { rp->nb_frames = 0; return rp; } OpusRepacketizer *opus_repacketizer_create(void) { OpusRepacketizer *rp; rp=(OpusRepacketizer *)opus_alloc(opus_repacketizer_get_size()); if(rp==NULL)return NULL; return opus_repacketizer_init(rp); } void opus_repacketizer_destroy(OpusRepacketizer *rp) { opus_free(rp); } static int opus_repacketizer_cat_impl(OpusRepacketizer *rp, const unsigned char *data, opus_int32 len, int self_delimited) { unsigned char tmp_toc; int curr_nb_frames,ret; /* Set of check ToC */ if (len<1) return OPUS_INVALID_PACKET; if (rp->nb_frames == 0) { rp->toc = data[0]; rp->framesize = opus_packet_get_samples_per_frame(data, 8000); } else if ((rp->toc&0xFC) != (data[0]&0xFC)) { /*fprintf(stderr, "toc mismatch: 0x%x vs 0x%x\n", rp->toc, data[0]);*/ return OPUS_INVALID_PACKET; } curr_nb_frames = opus_packet_get_nb_frames(data, len); if(curr_nb_frames<1) return OPUS_INVALID_PACKET; /* Check the 120 ms maximum packet size */ if ((curr_nb_frames+rp->nb_frames)*rp->framesize > 960) { return OPUS_INVALID_PACKET; } ret=opus_packet_parse_impl(data, len, self_delimited, &tmp_toc, &rp->frames[rp->nb_frames], &rp->len[rp->nb_frames], NULL, NULL); if(ret<1)return ret; rp->nb_frames += curr_nb_frames; return OPUS_OK; } int opus_repacketizer_cat(OpusRepacketizer *rp, const unsigned char *data, opus_int32 len) { return opus_repacketizer_cat_impl(rp, data, len, 0); } int opus_repacketizer_get_nb_frames(OpusRepacketizer *rp) { return rp->nb_frames; } opus_int32 opus_repacketizer_out_range_impl(OpusRepacketizer *rp, int begin, int end, unsigned char *data, opus_int32 maxlen, int self_delimited, int pad) { int i, count; opus_int32 tot_size; opus_int16 *len; const unsigned char **frames; unsigned char * ptr; if (begin<0 || begin>=end || end>rp->nb_frames) { /*fprintf(stderr, "%d %d %d\n", begin, end, rp->nb_frames);*/ return OPUS_BAD_ARG; } count = end-begin; len = rp->len+begin; frames = rp->frames+begin; if (self_delimited) tot_size = 1 + (len[count-1]>=252); else tot_size = 0; ptr = data; if (count==1) { /* Code 0 */ tot_size += len[0]+1; if (tot_size > maxlen) return OPUS_BUFFER_TOO_SMALL; *ptr++ = rp->toc&0xFC; } else if (count==2) { if (len[1] == len[0]) { /* Code 1 */ tot_size += 2*len[0]+1; if (tot_size > maxlen) return OPUS_BUFFER_TOO_SMALL; *ptr++ = (rp->toc&0xFC) | 0x1; } else { /* Code 2 */ tot_size += len[0]+len[1]+2+(len[0]>=252); if (tot_size > maxlen) return OPUS_BUFFER_TOO_SMALL; *ptr++ = (rp->toc&0xFC) | 0x2; ptr += encode_size(len[0], ptr); } } if (count > 2 || (pad && tot_size < maxlen)) { /* Code 3 */ int vbr; int pad_amount=0; /* Restart the process for the padding case */ ptr = data; if (self_delimited) tot_size = 1 + (len[count-1]>=252); else tot_size = 0; vbr = 0; for (i=1;i=252) + len[i]; tot_size += len[count-1]; if (tot_size > maxlen) return OPUS_BUFFER_TOO_SMALL; *ptr++ = (rp->toc&0xFC) | 0x3; *ptr++ = count | 0x80; } else { tot_size += count*len[0]+2; if (tot_size > maxlen) return OPUS_BUFFER_TOO_SMALL; *ptr++ = (rp->toc&0xFC) | 0x3; *ptr++ = count; } pad_amount = pad ? (maxlen-tot_size) : 0; if (pad_amount != 0) { int nb_255s; data[1] |= 0x40; nb_255s = (pad_amount-1)/255; for (i=0;inb_frames, data, maxlen, 0, 0); } int opus_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len) { OpusRepacketizer rp; opus_int32 ret; if (len < 1) return OPUS_BAD_ARG; if (len==new_len) return OPUS_OK; else if (len > new_len) return OPUS_BAD_ARG; opus_repacketizer_init(&rp); /* Moving payload to the end of the packet so we can do in-place padding */ OPUS_MOVE(data+new_len-len, data, len); ret = opus_repacketizer_cat(&rp, data+new_len-len, len); if (ret != OPUS_OK) return ret; ret = opus_repacketizer_out_range_impl(&rp, 0, rp.nb_frames, data, new_len, 0, 1); if (ret > 0) return OPUS_OK; else return ret; } opus_int32 opus_packet_unpad(unsigned char *data, opus_int32 len) { OpusRepacketizer rp; opus_int32 ret; if (len < 1) return OPUS_BAD_ARG; opus_repacketizer_init(&rp); ret = opus_repacketizer_cat(&rp, data, len); if (ret < 0) return ret; ret = opus_repacketizer_out_range_impl(&rp, 0, rp.nb_frames, data, len, 0, 0); celt_assert(ret > 0 && ret <= len); return ret; } int opus_multistream_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len, int nb_streams) { int s; int count; unsigned char toc; opus_int16 size[48]; opus_int32 packet_offset; opus_int32 amount; if (len < 1) return OPUS_BAD_ARG; if (len==new_len) return OPUS_OK; else if (len > new_len) return OPUS_BAD_ARG; amount = new_len - len; /* Seek to last stream */ for (s=0;s #include #include #include #define OPUS_PI (3.14159265F) #define OPUS_COSF(_x) ((float)cos(_x)) #define OPUS_SINF(_x) ((float)sin(_x)) static void *check_alloc(void *_ptr){ if(_ptr==NULL){ fprintf(stderr,"Out of memory.\n"); exit(EXIT_FAILURE); } return _ptr; } static void *opus_malloc(size_t _size){ return check_alloc(malloc(_size)); } static void *opus_realloc(void *_ptr,size_t _size){ return check_alloc(realloc(_ptr,_size)); } static size_t read_pcm16(float **_samples,FILE *_fin,int _nchannels){ unsigned char buf[1024]; float *samples; size_t nsamples; size_t csamples; size_t xi; size_t nread; samples=NULL; nsamples=csamples=0; for(;;){ nread=fread(buf,2*_nchannels,1024/(2*_nchannels),_fin); if(nread<=0)break; if(nsamples+nread>csamples){ do csamples=csamples<<1|1; while(nsamples+nread>csamples); samples=(float *)opus_realloc(samples, _nchannels*csamples*sizeof(*samples)); } for(xi=0;xi=_window_sz)ti-=_window_sz; } re*=_downsample; im*=_downsample; _ps[(xi*ps_sz+xj)*_nchannels+ci]=re*re+im*im+100000; p[ci]+=_ps[(xi*ps_sz+xj)*_nchannels+ci]; } } if(_out){ _out[(xi*_nbands+bi)*_nchannels]=p[0]/(_bands[bi+1]-_bands[bi]); if(_nchannels==2){ _out[(xi*_nbands+bi)*_nchannels+1]=p[1]/(_bands[bi+1]-_bands[bi]); } } } } free(window); } #define NBANDS (21) #define NFREQS (240) /*Bands on which we compute the pseudo-NMR (Bark-derived CELT bands).*/ static const int BANDS[NBANDS+1]={ 0,2,4,6,8,10,12,14,16,20,24,28,32,40,48,56,68,80,96,120,156,200 }; #define TEST_WIN_SIZE (480) #define TEST_WIN_STEP (120) int main(int _argc,const char **_argv){ FILE *fin1; FILE *fin2; float *x; float *y; float *xb; float *X; float *Y; double err; float Q; size_t xlength; size_t ylength; size_t nframes; size_t xi; int ci; int xj; int bi; int nchannels; unsigned rate; int downsample; int ybands; int yfreqs; int max_compare; if(_argc<3||_argc>6){ fprintf(stderr,"Usage: %s [-s] [-r rate2] \n", _argv[0]); return EXIT_FAILURE; } nchannels=1; if(strcmp(_argv[1],"-s")==0){ nchannels=2; _argv++; } rate=48000; ybands=NBANDS; yfreqs=NFREQS; downsample=1; if(strcmp(_argv[1],"-r")==0){ rate=atoi(_argv[2]); if(rate!=8000&&rate!=12000&&rate!=16000&&rate!=24000&&rate!=48000){ fprintf(stderr, "Sampling rate must be 8000, 12000, 16000, 24000, or 48000\n"); return EXIT_FAILURE; } downsample=48000/rate; switch(rate){ case 8000:ybands=13;break; case 12000:ybands=15;break; case 16000:ybands=17;break; case 24000:ybands=19;break; } yfreqs=NFREQS/downsample; _argv+=2; } fin1=fopen(_argv[1],"rb"); if(fin1==NULL){ fprintf(stderr,"Error opening '%s'.\n",_argv[1]); return EXIT_FAILURE; } fin2=fopen(_argv[2],"rb"); if(fin2==NULL){ fprintf(stderr,"Error opening '%s'.\n",_argv[2]); fclose(fin1); return EXIT_FAILURE; } /*Read in the data and allocate scratch space.*/ xlength=read_pcm16(&x,fin1,2); if(nchannels==1){ for(xi=0;xi0;){ for(ci=0;ci0){ /*Temporal masking: -3 dB/2.5ms slope.*/ for(bi=0;bi=79&&xj<=81)im*=0.1F; if(xj==80)im*=0.1F; Eb+=im; } } Eb /= (BANDS[bi+1]-BANDS[bi])*nchannels; Ef += Eb*Eb; } /*Using a fixed normalization value means we're willing to accept slightly lower quality for lower sampling rates.*/ Ef/=NBANDS; Ef*=Ef; err+=Ef*Ef; } free(xb); free(X); free(Y); err=pow(err/nframes,1.0/16); Q=100*(1-0.5*log(1+err)/log(1.13)); if(Q<0){ fprintf(stderr,"Test vector FAILS\n"); fprintf(stderr,"Internal weighted error is %f\n",err); return EXIT_FAILURE; } else{ fprintf(stderr,"Test vector PASSES\n"); fprintf(stderr, "Opus quality metric: %.1f %% (internal weighted error is %f)\n",Q,err); return EXIT_SUCCESS; } } jamulus-3.9.1+dfsg/libs/opus/src/mapping_matrix.c0000644000175000017500000003576214340334543021062 0ustar vimervimer/* Copyright (c) 2017 Google Inc. Written by Andrew Allen */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "arch.h" #include "float_cast.h" #include "opus_private.h" #include "opus_defines.h" #include "mapping_matrix.h" #define MATRIX_INDEX(nb_rows, row, col) (nb_rows * col + row) opus_int32 mapping_matrix_get_size(int rows, int cols) { opus_int32 size; /* Mapping Matrix must only support up to 255 channels in or out. * Additionally, the total cell count must be <= 65004 octets in order * for the matrix to be stored in an OGG header. */ if (rows > 255 || cols > 255) return 0; size = rows * (opus_int32)cols * sizeof(opus_int16); if (size > 65004) return 0; return align(sizeof(MappingMatrix)) + align(size); } opus_int16 *mapping_matrix_get_data(const MappingMatrix *matrix) { /* void* cast avoids clang -Wcast-align warning */ return (opus_int16*)(void*)((char*)matrix + align(sizeof(MappingMatrix))); } void mapping_matrix_init(MappingMatrix * const matrix, int rows, int cols, int gain, const opus_int16 *data, opus_int32 data_size) { int i; opus_int16 *ptr; #if !defined(ENABLE_ASSERTIONS) (void)data_size; #endif celt_assert(align(data_size) == align(rows * cols * sizeof(opus_int16))); matrix->rows = rows; matrix->cols = cols; matrix->gain = gain; ptr = mapping_matrix_get_data(matrix); for (i = 0; i < rows * cols; i++) { ptr[i] = data[i]; } } #ifndef DISABLE_FLOAT_API void mapping_matrix_multiply_channel_in_float( const MappingMatrix *matrix, const float *input, int input_rows, opus_val16 *output, int output_row, int output_rows, int frame_size) { /* Matrix data is ordered col-wise. */ opus_int16* matrix_data; int i, col; celt_assert(input_rows <= matrix->cols && output_rows <= matrix->rows); matrix_data = mapping_matrix_get_data(matrix); for (i = 0; i < frame_size; i++) { float tmp = 0; for (col = 0; col < input_rows; col++) { tmp += matrix_data[MATRIX_INDEX(matrix->rows, output_row, col)] * input[MATRIX_INDEX(input_rows, col, i)]; } #if defined(FIXED_POINT) output[output_rows * i] = FLOAT2INT16((1/32768.f)*tmp); #else output[output_rows * i] = (1/32768.f)*tmp; #endif } } void mapping_matrix_multiply_channel_out_float( const MappingMatrix *matrix, const opus_val16 *input, int input_row, int input_rows, float *output, int output_rows, int frame_size ) { /* Matrix data is ordered col-wise. */ opus_int16* matrix_data; int i, row; float input_sample; celt_assert(input_rows <= matrix->cols && output_rows <= matrix->rows); matrix_data = mapping_matrix_get_data(matrix); for (i = 0; i < frame_size; i++) { #if defined(FIXED_POINT) input_sample = (1/32768.f)*input[input_rows * i]; #else input_sample = input[input_rows * i]; #endif for (row = 0; row < output_rows; row++) { float tmp = (1/32768.f)*matrix_data[MATRIX_INDEX(matrix->rows, row, input_row)] * input_sample; output[MATRIX_INDEX(output_rows, row, i)] += tmp; } } } #endif /* DISABLE_FLOAT_API */ void mapping_matrix_multiply_channel_in_short( const MappingMatrix *matrix, const opus_int16 *input, int input_rows, opus_val16 *output, int output_row, int output_rows, int frame_size) { /* Matrix data is ordered col-wise. */ opus_int16* matrix_data; int i, col; celt_assert(input_rows <= matrix->cols && output_rows <= matrix->rows); matrix_data = mapping_matrix_get_data(matrix); for (i = 0; i < frame_size; i++) { opus_val32 tmp = 0; for (col = 0; col < input_rows; col++) { #if defined(FIXED_POINT) tmp += ((opus_int32)matrix_data[MATRIX_INDEX(matrix->rows, output_row, col)] * (opus_int32)input[MATRIX_INDEX(input_rows, col, i)]) >> 8; #else tmp += matrix_data[MATRIX_INDEX(matrix->rows, output_row, col)] * input[MATRIX_INDEX(input_rows, col, i)]; #endif } #if defined(FIXED_POINT) output[output_rows * i] = (opus_int16)((tmp + 64) >> 7); #else output[output_rows * i] = (1/(32768.f*32768.f))*tmp; #endif } } void mapping_matrix_multiply_channel_out_short( const MappingMatrix *matrix, const opus_val16 *input, int input_row, int input_rows, opus_int16 *output, int output_rows, int frame_size) { /* Matrix data is ordered col-wise. */ opus_int16* matrix_data; int i, row; opus_int32 input_sample; celt_assert(input_rows <= matrix->cols && output_rows <= matrix->rows); matrix_data = mapping_matrix_get_data(matrix); for (i = 0; i < frame_size; i++) { #if defined(FIXED_POINT) input_sample = (opus_int32)input[input_rows * i]; #else input_sample = (opus_int32)FLOAT2INT16(input[input_rows * i]); #endif for (row = 0; row < output_rows; row++) { opus_int32 tmp = (opus_int32)matrix_data[MATRIX_INDEX(matrix->rows, row, input_row)] * input_sample; output[MATRIX_INDEX(output_rows, row, i)] += (tmp + 16384) >> 15; } } } const MappingMatrix mapping_matrix_foa_mixing = { 6, 6, 0 }; const opus_int16 mapping_matrix_foa_mixing_data[36] = { 16384, 0, -16384, 23170, 0, 0, 16384, 23170, 16384, 0, 0, 0, 16384, 0, -16384, -23170, 0, 0, 16384, -23170, 16384, 0, 0, 0, 0, 0, 0, 0, 32767, 0, 0, 0, 0, 0, 0, 32767 }; const MappingMatrix mapping_matrix_soa_mixing = { 11, 11, 0 }; const opus_int16 mapping_matrix_soa_mixing_data[121] = { 10923, 7723, 13377, -13377, 11585, 9459, 7723, -16384, -6689, 0, 0, 10923, 7723, 13377, 13377, -11585, 9459, 7723, 16384, -6689, 0, 0, 10923, -15447, 13377, 0, 0, -18919, 7723, 0, 13377, 0, 0, 10923, 7723, -13377, -13377, 11585, -9459, 7723, 16384, -6689, 0, 0, 10923, -7723, 0, 13377, -16384, 0, -15447, 0, 9459, 0, 0, 10923, -7723, 0, -13377, 16384, 0, -15447, 0, 9459, 0, 0, 10923, 15447, 0, 0, 0, 0, -15447, 0, -18919, 0, 0, 10923, 7723, -13377, 13377, -11585, -9459, 7723, -16384, -6689, 0, 0, 10923, -15447, -13377, 0, 0, 18919, 7723, 0, 13377, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32767, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32767 }; const MappingMatrix mapping_matrix_toa_mixing = { 18, 18, 0 }; const opus_int16 mapping_matrix_toa_mixing_data[324] = { 8208, 0, -881, 14369, 0, 0, -8192, -4163, 13218, 0, 0, 0, 11095, -8836, -6218, 14833, 0, 0, 8208, -10161, 881, 10161, -13218, -2944, -8192, 2944, 0, -10488, -6218, 6248, -11095, -6248, 0, -10488, 0, 0, 8208, 10161, 881, -10161, -13218, 2944, -8192, -2944, 0, 10488, -6218, -6248, -11095, 6248, 0, 10488, 0, 0, 8176, 5566, -11552, 5566, 9681, -11205, 8192, -11205, 0, 4920, -15158, 9756, -3334, 9756, 0, -4920, 0, 0, 8176, 7871, 11552, 0, 0, 15846, 8192, 0, -9681, -6958, 0, 13797, 3334, 0, -15158, 0, 0, 0, 8176, 0, 11552, 7871, 0, 0, 8192, 15846, 9681, 0, 0, 0, 3334, 13797, 15158, 6958, 0, 0, 8176, 5566, -11552, -5566, -9681, -11205, 8192, 11205, 0, 4920, 15158, 9756, -3334, -9756, 0, 4920, 0, 0, 8208, 14369, -881, 0, 0, -4163, -8192, 0, -13218, -14833, 0, -8836, 11095, 0, 6218, 0, 0, 0, 8208, 10161, 881, 10161, 13218, 2944, -8192, 2944, 0, 10488, 6218, -6248, -11095, -6248, 0, -10488, 0, 0, 8208, -14369, -881, 0, 0, 4163, -8192, 0, -13218, 14833, 0, 8836, 11095, 0, 6218, 0, 0, 0, 8208, 0, -881, -14369, 0, 0, -8192, 4163, 13218, 0, 0, 0, 11095, 8836, -6218, -14833, 0, 0, 8176, -5566, -11552, 5566, -9681, 11205, 8192, -11205, 0, -4920, 15158, -9756, -3334, 9756, 0, -4920, 0, 0, 8176, 0, 11552, -7871, 0, 0, 8192, -15846, 9681, 0, 0, 0, 3334, -13797, 15158, -6958, 0, 0, 8176, -7871, 11552, 0, 0, -15846, 8192, 0, -9681, 6958, 0, -13797, 3334, 0, -15158, 0, 0, 0, 8176, -5566, -11552, -5566, 9681, 11205, 8192, 11205, 0, -4920, -15158, -9756, -3334, -9756, 0, 4920, 0, 0, 8208, -10161, 881, -10161, 13218, -2944, -8192, -2944, 0, -10488, 6218, 6248, -11095, 6248, 0, 10488, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32767, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32767 }; const MappingMatrix mapping_matrix_foa_demixing = { 6, 6, 0 }; const opus_int16 mapping_matrix_foa_demixing_data[36] = { 16384, 16384, 16384, 16384, 0, 0, 0, 23170, 0, -23170, 0, 0, -16384, 16384, -16384, 16384, 0, 0, 23170, 0, -23170, 0, 0, 0, 0, 0, 0, 0, 32767, 0, 0, 0, 0, 0, 0, 32767 }; const MappingMatrix mapping_matrix_soa_demixing = { 11, 11, 3050 }; const opus_int16 mapping_matrix_soa_demixing_data[121] = { 2771, 2771, 2771, 2771, 2771, 2771, 2771, 2771, 2771, 0, 0, 10033, 10033, -20066, 10033, 14189, 14189, -28378, 10033, -20066, 0, 0, 3393, 3393, 3393, -3393, 0, 0, 0, -3393, -3393, 0, 0, -17378, 17378, 0, -17378, -24576, 24576, 0, 17378, 0, 0, 0, -14189, 14189, 0, -14189, -28378, 28378, 0, 14189, 0, 0, 0, 2399, 2399, -4799, -2399, 0, 0, 0, -2399, 4799, 0, 0, 1959, 1959, 1959, 1959, -3918, -3918, -3918, 1959, 1959, 0, 0, -4156, 4156, 0, 4156, 0, 0, 0, -4156, 0, 0, 0, 8192, 8192, -16384, 8192, 16384, 16384, -32768, 8192, -16384, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8312, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8312 }; const MappingMatrix mapping_matrix_toa_demixing = { 18, 18, 0 }; const opus_int16 mapping_matrix_toa_demixing_data[324] = { 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 0, 0, 0, -9779, 9779, 6263, 8857, 0, 6263, 13829, 9779, -13829, 0, -6263, 0, -8857, -6263, -9779, 0, 0, -3413, 3413, 3413, -11359, 11359, 11359, -11359, -3413, 3413, -3413, -3413, -11359, 11359, 11359, -11359, 3413, 0, 0, 13829, 9779, -9779, 6263, 0, 8857, -6263, 0, 9779, 0, -13829, 6263, -8857, 0, -6263, -9779, 0, 0, 0, -15617, -15617, 6406, 0, 0, -6406, 0, 15617, 0, 0, -6406, 0, 0, 6406, 15617, 0, 0, 0, -5003, 5003, -10664, 15081, 0, -10664, -7075, 5003, 7075, 0, 10664, 0, -15081, 10664, -5003, 0, 0, -8176, -8176, -8176, 8208, 8208, 8208, 8208, -8176, -8176, -8176, -8176, 8208, 8208, 8208, 8208, -8176, 0, 0, -7075, 5003, -5003, -10664, 0, 15081, 10664, 0, 5003, 0, 7075, -10664, -15081, 0, 10664, -5003, 0, 0, 15617, 0, 0, 0, -6406, 6406, 0, -15617, 0, -15617, 15617, 0, 6406, -6406, 0, 0, 0, 0, 0, -11393, 11393, 2993, -4233, 0, 2993, -16112, 11393, 16112, 0, -2993, 0, 4233, -2993, -11393, 0, 0, 0, -9974, -9974, -13617, 0, 0, 13617, 0, 9974, 0, 0, 13617, 0, 0, -13617, 9974, 0, 0, 0, 5579, -5579, 10185, 14403, 0, 10185, -7890, -5579, 7890, 0, -10185, 0, -14403, -10185, 5579, 0, 0, 11826, -11826, -11826, -901, 901, 901, -901, 11826, -11826, 11826, 11826, -901, 901, 901, -901, -11826, 0, 0, -7890, -5579, 5579, 10185, 0, 14403, -10185, 0, -5579, 0, 7890, 10185, -14403, 0, -10185, 5579, 0, 0, -9974, 0, 0, 0, -13617, 13617, 0, 9974, 0, 9974, -9974, 0, 13617, -13617, 0, 0, 0, 0, 16112, -11393, 11393, -2993, 0, 4233, 2993, 0, -11393, 0, -16112, -2993, -4233, 0, 2993, 11393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32767, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32767 }; jamulus-3.9.1+dfsg/libs/opus/src/opus_encoder.c0000644000175000017500000027245514340334543020532 0ustar vimervimer/* Copyright (c) 2010-2011 Xiph.Org Foundation, Skype Limited Written by Jean-Marc Valin and Koen Vos */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "celt.h" #include "entenc.h" #include "modes.h" #include "API.h" #include "stack_alloc.h" #include "float_cast.h" #include "opus.h" #include "arch.h" #include "pitch.h" #include "opus_private.h" #include "os_support.h" #include "cpu_support.h" #include "analysis.h" #include "mathops.h" #include "tuning_parameters.h" #ifdef FIXED_POINT #include "fixed/structs_FIX.h" #else #include "float/structs_FLP.h" #endif #define MAX_ENCODER_BUFFER 480 #ifndef DISABLE_FLOAT_API #define PSEUDO_SNR_THRESHOLD 316.23f /* 10^(25/10) */ #endif typedef struct { opus_val32 XX, XY, YY; opus_val16 smoothed_width; opus_val16 max_follower; } StereoWidthState; struct OpusEncoder { int celt_enc_offset; int silk_enc_offset; silk_EncControlStruct silk_mode; int application; int channels; int delay_compensation; int force_channels; int signal_type; int user_bandwidth; int max_bandwidth; int user_forced_mode; int voice_ratio; opus_int32 Fs; int use_vbr; int vbr_constraint; int variable_duration; opus_int32 bitrate_bps; opus_int32 user_bitrate_bps; int lsb_depth; int encoder_buffer; int lfe; int arch; int use_dtx; /* general DTX for both SILK and CELT */ #ifndef DISABLE_FLOAT_API TonalityAnalysisState analysis; #endif #define OPUS_ENCODER_RESET_START stream_channels int stream_channels; opus_int16 hybrid_stereo_width_Q14; opus_int32 variable_HP_smth2_Q15; opus_val16 prev_HB_gain; opus_val32 hp_mem[4]; int mode; int prev_mode; int prev_channels; int prev_framesize; int bandwidth; /* Bandwidth determined automatically from the rate (before any other adjustment) */ int auto_bandwidth; int silk_bw_switch; /* Sampling rate (at the API level) */ int first; opus_val16 * energy_masking; StereoWidthState width_mem; opus_val16 delay_buffer[MAX_ENCODER_BUFFER*2]; #ifndef DISABLE_FLOAT_API int detected_bandwidth; int nb_no_activity_frames; opus_val32 peak_signal_energy; #endif int nonfinal_frame; /* current frame is not the final in a packet */ opus_uint32 rangeFinal; }; /* Transition tables for the voice and music. First column is the middle (memoriless) threshold. The second column is the hysteresis (difference with the middle) */ static const opus_int32 mono_voice_bandwidth_thresholds[8] = { 9000, 700, /* NB<->MB */ 9000, 700, /* MB<->WB */ 13500, 1000, /* WB<->SWB */ 14000, 2000, /* SWB<->FB */ }; static const opus_int32 mono_music_bandwidth_thresholds[8] = { 9000, 700, /* NB<->MB */ 9000, 700, /* MB<->WB */ 11000, 1000, /* WB<->SWB */ 12000, 2000, /* SWB<->FB */ }; static const opus_int32 stereo_voice_bandwidth_thresholds[8] = { 9000, 700, /* NB<->MB */ 9000, 700, /* MB<->WB */ 13500, 1000, /* WB<->SWB */ 14000, 2000, /* SWB<->FB */ }; static const opus_int32 stereo_music_bandwidth_thresholds[8] = { 9000, 700, /* NB<->MB */ 9000, 700, /* MB<->WB */ 11000, 1000, /* WB<->SWB */ 12000, 2000, /* SWB<->FB */ }; /* Threshold bit-rates for switching between mono and stereo */ static const opus_int32 stereo_voice_threshold = 19000; static const opus_int32 stereo_music_threshold = 17000; /* Threshold bit-rate for switching between SILK/hybrid and CELT-only */ static const opus_int32 mode_thresholds[2][2] = { /* voice */ /* music */ { 64000, 10000}, /* mono */ { 44000, 10000}, /* stereo */ }; static const opus_int32 fec_thresholds[] = { 12000, 1000, /* NB */ 14000, 1000, /* MB */ 16000, 1000, /* WB */ 20000, 1000, /* SWB */ 22000, 1000, /* FB */ }; int opus_encoder_get_size(int channels) { int silkEncSizeBytes, celtEncSizeBytes; int ret; if (channels<1 || channels > 2) return 0; ret = silk_Get_Encoder_Size( &silkEncSizeBytes ); if (ret) return 0; silkEncSizeBytes = align(silkEncSizeBytes); celtEncSizeBytes = celt_encoder_get_size(channels); return align(sizeof(OpusEncoder))+silkEncSizeBytes+celtEncSizeBytes; } int opus_encoder_init(OpusEncoder* st, opus_int32 Fs, int channels, int application) { void *silk_enc; CELTEncoder *celt_enc; int err; int ret, silkEncSizeBytes; if((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)||(channels!=1&&channels!=2)|| (application != OPUS_APPLICATION_VOIP && application != OPUS_APPLICATION_AUDIO && application != OPUS_APPLICATION_RESTRICTED_LOWDELAY)) return OPUS_BAD_ARG; OPUS_CLEAR((char*)st, opus_encoder_get_size(channels)); /* Create SILK encoder */ ret = silk_Get_Encoder_Size( &silkEncSizeBytes ); if (ret) return OPUS_BAD_ARG; silkEncSizeBytes = align(silkEncSizeBytes); st->silk_enc_offset = align(sizeof(OpusEncoder)); st->celt_enc_offset = st->silk_enc_offset+silkEncSizeBytes; silk_enc = (char*)st+st->silk_enc_offset; celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset); st->stream_channels = st->channels = channels; st->Fs = Fs; st->arch = opus_select_arch(); ret = silk_InitEncoder( silk_enc, st->arch, &st->silk_mode ); if(ret)return OPUS_INTERNAL_ERROR; /* default SILK parameters */ st->silk_mode.nChannelsAPI = channels; st->silk_mode.nChannelsInternal = channels; st->silk_mode.API_sampleRate = st->Fs; st->silk_mode.maxInternalSampleRate = 16000; st->silk_mode.minInternalSampleRate = 8000; st->silk_mode.desiredInternalSampleRate = 16000; st->silk_mode.payloadSize_ms = 20; st->silk_mode.bitRate = 25000; st->silk_mode.packetLossPercentage = 0; st->silk_mode.complexity = 9; st->silk_mode.useInBandFEC = 0; st->silk_mode.useDTX = 0; st->silk_mode.useCBR = 0; st->silk_mode.reducedDependency = 0; /* Create CELT encoder */ /* Initialize CELT encoder */ err = celt_encoder_init(celt_enc, Fs, channels, st->arch); if(err!=OPUS_OK)return OPUS_INTERNAL_ERROR; celt_encoder_ctl(celt_enc, CELT_SET_SIGNALLING(0)); celt_encoder_ctl(celt_enc, OPUS_SET_COMPLEXITY(st->silk_mode.complexity)); st->use_vbr = 1; /* Makes constrained VBR the default (safer for real-time use) */ st->vbr_constraint = 1; st->user_bitrate_bps = OPUS_AUTO; st->bitrate_bps = 3000+Fs*channels; st->application = application; st->signal_type = OPUS_AUTO; st->user_bandwidth = OPUS_AUTO; st->max_bandwidth = OPUS_BANDWIDTH_FULLBAND; st->force_channels = OPUS_AUTO; st->user_forced_mode = OPUS_AUTO; st->voice_ratio = -1; st->encoder_buffer = st->Fs/100; st->lsb_depth = 24; st->variable_duration = OPUS_FRAMESIZE_ARG; /* Delay compensation of 4 ms (2.5 ms for SILK's extra look-ahead + 1.5 ms for SILK resamplers and stereo prediction) */ st->delay_compensation = st->Fs/250; st->hybrid_stereo_width_Q14 = 1 << 14; st->prev_HB_gain = Q15ONE; st->variable_HP_smth2_Q15 = silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 ); st->first = 1; st->mode = MODE_HYBRID; st->bandwidth = OPUS_BANDWIDTH_FULLBAND; #ifndef DISABLE_FLOAT_API tonality_analysis_init(&st->analysis, st->Fs); st->analysis.application = st->application; #endif return OPUS_OK; } static unsigned char gen_toc(int mode, int framerate, int bandwidth, int channels) { int period; unsigned char toc; period = 0; while (framerate < 400) { framerate <<= 1; period++; } if (mode == MODE_SILK_ONLY) { toc = (bandwidth-OPUS_BANDWIDTH_NARROWBAND)<<5; toc |= (period-2)<<3; } else if (mode == MODE_CELT_ONLY) { int tmp = bandwidth-OPUS_BANDWIDTH_MEDIUMBAND; if (tmp < 0) tmp = 0; toc = 0x80; toc |= tmp << 5; toc |= period<<3; } else /* Hybrid */ { toc = 0x60; toc |= (bandwidth-OPUS_BANDWIDTH_SUPERWIDEBAND)<<4; toc |= (period-2)<<3; } toc |= (channels==2)<<2; return toc; } #ifndef FIXED_POINT static void silk_biquad_float( const opus_val16 *in, /* I: Input signal */ const opus_int32 *B_Q28, /* I: MA coefficients [3] */ const opus_int32 *A_Q28, /* I: AR coefficients [2] */ opus_val32 *S, /* I/O: State vector [2] */ opus_val16 *out, /* O: Output signal */ const opus_int32 len, /* I: Signal length (must be even) */ int stride ) { /* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */ opus_int k; opus_val32 vout; opus_val32 inval; opus_val32 A[2], B[3]; A[0] = (opus_val32)(A_Q28[0] * (1.f/((opus_int32)1<<28))); A[1] = (opus_val32)(A_Q28[1] * (1.f/((opus_int32)1<<28))); B[0] = (opus_val32)(B_Q28[0] * (1.f/((opus_int32)1<<28))); B[1] = (opus_val32)(B_Q28[1] * (1.f/((opus_int32)1<<28))); B[2] = (opus_val32)(B_Q28[2] * (1.f/((opus_int32)1<<28))); /* Negate A_Q28 values and split in two parts */ for( k = 0; k < len; k++ ) { /* S[ 0 ], S[ 1 ]: Q12 */ inval = in[ k*stride ]; vout = S[ 0 ] + B[0]*inval; S[ 0 ] = S[1] - vout*A[0] + B[1]*inval; S[ 1 ] = - vout*A[1] + B[2]*inval + VERY_SMALL; /* Scale back to Q0 and saturate */ out[ k*stride ] = vout; } } #endif static void hp_cutoff(const opus_val16 *in, opus_int32 cutoff_Hz, opus_val16 *out, opus_val32 *hp_mem, int len, int channels, opus_int32 Fs, int arch) { opus_int32 B_Q28[ 3 ], A_Q28[ 2 ]; opus_int32 Fc_Q19, r_Q28, r_Q22; (void)arch; silk_assert( cutoff_Hz <= silk_int32_MAX / SILK_FIX_CONST( 1.5 * 3.14159 / 1000, 19 ) ); Fc_Q19 = silk_DIV32_16( silk_SMULBB( SILK_FIX_CONST( 1.5 * 3.14159 / 1000, 19 ), cutoff_Hz ), Fs/1000 ); silk_assert( Fc_Q19 > 0 && Fc_Q19 < 32768 ); r_Q28 = SILK_FIX_CONST( 1.0, 28 ) - silk_MUL( SILK_FIX_CONST( 0.92, 9 ), Fc_Q19 ); /* b = r * [ 1; -2; 1 ]; */ /* a = [ 1; -2 * r * ( 1 - 0.5 * Fc^2 ); r^2 ]; */ B_Q28[ 0 ] = r_Q28; B_Q28[ 1 ] = silk_LSHIFT( -r_Q28, 1 ); B_Q28[ 2 ] = r_Q28; /* -r * ( 2 - Fc * Fc ); */ r_Q22 = silk_RSHIFT( r_Q28, 6 ); A_Q28[ 0 ] = silk_SMULWW( r_Q22, silk_SMULWW( Fc_Q19, Fc_Q19 ) - SILK_FIX_CONST( 2.0, 22 ) ); A_Q28[ 1 ] = silk_SMULWW( r_Q22, r_Q22 ); #ifdef FIXED_POINT if( channels == 1 ) { silk_biquad_alt_stride1( in, B_Q28, A_Q28, hp_mem, out, len ); } else { silk_biquad_alt_stride2( in, B_Q28, A_Q28, hp_mem, out, len, arch ); } #else silk_biquad_float( in, B_Q28, A_Q28, hp_mem, out, len, channels ); if( channels == 2 ) { silk_biquad_float( in+1, B_Q28, A_Q28, hp_mem+2, out+1, len, channels ); } #endif } #ifdef FIXED_POINT static void dc_reject(const opus_val16 *in, opus_int32 cutoff_Hz, opus_val16 *out, opus_val32 *hp_mem, int len, int channels, opus_int32 Fs) { int c, i; int shift; /* Approximates -round(log2(6.3*cutoff_Hz/Fs)) */ shift=celt_ilog2(Fs/(cutoff_Hz*4)); for (c=0;cFs/400; if (st->user_bitrate_bps==OPUS_AUTO) return 60*st->Fs/frame_size + st->Fs*st->channels; else if (st->user_bitrate_bps==OPUS_BITRATE_MAX) return max_data_bytes*8*st->Fs/frame_size; else return st->user_bitrate_bps; } #ifndef DISABLE_FLOAT_API #ifdef FIXED_POINT #define PCM2VAL(x) FLOAT2INT16(x) #else #define PCM2VAL(x) SCALEIN(x) #endif void downmix_float(const void *_x, opus_val32 *y, int subframe, int offset, int c1, int c2, int C) { const float *x; int j; x = (const float *)_x; for (j=0;j-1) { for (j=0;j-1) { for (j=0;j= OPUS_FRAMESIZE_2_5_MS && variable_duration <= OPUS_FRAMESIZE_120_MS) { if (variable_duration <= OPUS_FRAMESIZE_40_MS) new_size = (Fs/400)<<(variable_duration-OPUS_FRAMESIZE_2_5_MS); else new_size = (variable_duration-OPUS_FRAMESIZE_2_5_MS-2)*Fs/50; } else return -1; if (new_size>frame_size) return -1; if (400*new_size!=Fs && 200*new_size!=Fs && 100*new_size!=Fs && 50*new_size!=Fs && 25*new_size!=Fs && 50*new_size!=3*Fs && 50*new_size!=4*Fs && 50*new_size!=5*Fs && 50*new_size!=6*Fs) return -1; return new_size; } opus_val16 compute_stereo_width(const opus_val16 *pcm, int frame_size, opus_int32 Fs, StereoWidthState *mem) { opus_val32 xx, xy, yy; opus_val16 sqrt_xx, sqrt_yy; opus_val16 qrrt_xx, qrrt_yy; int frame_rate; int i; opus_val16 short_alpha; frame_rate = Fs/frame_size; short_alpha = Q15ONE - MULT16_16(25, Q15ONE)/IMAX(50,frame_rate); xx=xy=yy=0; /* Unroll by 4. The frame size is always a multiple of 4 *except* for 2.5 ms frames at 12 kHz. Since this setting is very rare (and very stupid), we just discard the last two samples. */ for (i=0;iXX += MULT16_32_Q15(short_alpha, xx-mem->XX); mem->XY += MULT16_32_Q15(short_alpha, xy-mem->XY); mem->YY += MULT16_32_Q15(short_alpha, yy-mem->YY); mem->XX = MAX32(0, mem->XX); mem->XY = MAX32(0, mem->XY); mem->YY = MAX32(0, mem->YY); if (MAX32(mem->XX, mem->YY)>QCONST16(8e-4f, 18)) { opus_val16 corr; opus_val16 ldiff; opus_val16 width; sqrt_xx = celt_sqrt(mem->XX); sqrt_yy = celt_sqrt(mem->YY); qrrt_xx = celt_sqrt(sqrt_xx); qrrt_yy = celt_sqrt(sqrt_yy); /* Inter-channel correlation */ mem->XY = MIN32(mem->XY, sqrt_xx*sqrt_yy); corr = SHR32(frac_div32(mem->XY,EPSILON+MULT16_16(sqrt_xx,sqrt_yy)),16); /* Approximate loudness difference */ ldiff = MULT16_16(Q15ONE, ABS16(qrrt_xx-qrrt_yy))/(EPSILON+qrrt_xx+qrrt_yy); width = MULT16_16_Q15(celt_sqrt(QCONST32(1.f,30)-MULT16_16(corr,corr)), ldiff); /* Smoothing over one second */ mem->smoothed_width += (width-mem->smoothed_width)/frame_rate; /* Peak follower */ mem->max_follower = MAX16(mem->max_follower-QCONST16(.02f,15)/frame_rate, mem->smoothed_width); } /*printf("%f %f %f %f %f ", corr/(float)Q15ONE, ldiff/(float)Q15ONE, width/(float)Q15ONE, mem->smoothed_width/(float)Q15ONE, mem->max_follower/(float)Q15ONE);*/ return EXTRACT16(MIN32(Q15ONE, MULT16_16(20, mem->max_follower))); } static int decide_fec(int useInBandFEC, int PacketLoss_perc, int last_fec, int mode, int *bandwidth, opus_int32 rate) { int orig_bandwidth; if (!useInBandFEC || PacketLoss_perc == 0 || mode == MODE_CELT_ONLY) return 0; orig_bandwidth = *bandwidth; for (;;) { opus_int32 hysteresis; opus_int32 LBRR_rate_thres_bps; /* Compute threshold for using FEC at the current bandwidth setting */ LBRR_rate_thres_bps = fec_thresholds[2*(*bandwidth - OPUS_BANDWIDTH_NARROWBAND)]; hysteresis = fec_thresholds[2*(*bandwidth - OPUS_BANDWIDTH_NARROWBAND) + 1]; if (last_fec == 1) LBRR_rate_thres_bps -= hysteresis; if (last_fec == 0) LBRR_rate_thres_bps += hysteresis; LBRR_rate_thres_bps = silk_SMULWB( silk_MUL( LBRR_rate_thres_bps, 125 - silk_min( PacketLoss_perc, 25 ) ), SILK_FIX_CONST( 0.01, 16 ) ); /* If loss <= 5%, we look at whether we have enough rate to enable FEC. If loss > 5%, we decrease the bandwidth until we can enable FEC. */ if (rate > LBRR_rate_thres_bps) return 1; else if (PacketLoss_perc <= 5) return 0; else if (*bandwidth > OPUS_BANDWIDTH_NARROWBAND) (*bandwidth)--; else break; } /* Couldn't find any bandwidth to enable FEC, keep original bandwidth. */ *bandwidth = orig_bandwidth; return 0; } static int compute_silk_rate_for_hybrid(int rate, int bandwidth, int frame20ms, int vbr, int fec, int channels) { int entry; int i; int N; int silk_rate; static int rate_table[][5] = { /* |total| |-------- SILK------------| |-- No FEC -| |--- FEC ---| 10ms 20ms 10ms 20ms */ { 0, 0, 0, 0, 0}, {12000, 10000, 10000, 11000, 11000}, {16000, 13500, 13500, 15000, 15000}, {20000, 16000, 16000, 18000, 18000}, {24000, 18000, 18000, 21000, 21000}, {32000, 22000, 22000, 28000, 28000}, {64000, 38000, 38000, 50000, 50000} }; /* Do the allocation per-channel. */ rate /= channels; entry = 1 + frame20ms + 2*fec; N = sizeof(rate_table)/sizeof(rate_table[0]); for (i=1;i rate) break; } if (i == N) { silk_rate = rate_table[i-1][entry]; /* For now, just give 50% of the extra bits to SILK. */ silk_rate += (rate-rate_table[i-1][0])/2; } else { opus_int32 lo, hi, x0, x1; lo = rate_table[i-1][entry]; hi = rate_table[i][entry]; x0 = rate_table[i-1][0]; x1 = rate_table[i][0]; silk_rate = (lo*(x1-rate) + hi*(rate-x0))/(x1-x0); } if (!vbr) { /* Tiny boost to SILK for CBR. We should probably tune this better. */ silk_rate += 100; } if (bandwidth==OPUS_BANDWIDTH_SUPERWIDEBAND) silk_rate += 300; silk_rate *= channels; /* Small adjustment for stereo (calibrated for 32 kb/s, haven't tried other bitrates). */ if (channels == 2 && rate >= 12000) silk_rate -= 1000; return silk_rate; } /* Returns the equivalent bitrate corresponding to 20 ms frames, complexity 10 VBR operation. */ static opus_int32 compute_equiv_rate(opus_int32 bitrate, int channels, int frame_rate, int vbr, int mode, int complexity, int loss) { opus_int32 equiv; equiv = bitrate; /* Take into account overhead from smaller frames. */ if (frame_rate > 50) equiv -= (40*channels+20)*(frame_rate - 50); /* CBR is about a 8% penalty for both SILK and CELT. */ if (!vbr) equiv -= equiv/12; /* Complexity makes about 10% difference (from 0 to 10) in general. */ equiv = equiv * (90+complexity)/100; if (mode == MODE_SILK_ONLY || mode == MODE_HYBRID) { /* SILK complexity 0-1 uses the non-delayed-decision NSQ, which costs about 20%. */ if (complexity<2) equiv = equiv*4/5; equiv -= equiv*loss/(6*loss + 10); } else if (mode == MODE_CELT_ONLY) { /* CELT complexity 0-4 doesn't have the pitch filter, which costs about 10%. */ if (complexity<5) equiv = equiv*9/10; } else { /* Mode not known yet */ /* Half the SILK loss*/ equiv -= equiv*loss/(12*loss + 20); } return equiv; } #ifndef DISABLE_FLOAT_API int is_digital_silence(const opus_val16* pcm, int frame_size, int channels, int lsb_depth) { int silence = 0; opus_val32 sample_max = 0; #ifdef MLP_TRAINING return 0; #endif sample_max = celt_maxabs16(pcm, frame_size*channels); #ifdef FIXED_POINT silence = (sample_max == 0); (void)lsb_depth; #else silence = (sample_max <= (opus_val16) 1 / (1 << lsb_depth)); #endif return silence; } #ifdef FIXED_POINT static opus_val32 compute_frame_energy(const opus_val16 *pcm, int frame_size, int channels, int arch) { int i; opus_val32 sample_max; int max_shift; int shift; opus_val32 energy = 0; int len = frame_size*channels; (void)arch; /* Max amplitude in the signal */ sample_max = celt_maxabs16(pcm, len); /* Compute the right shift required in the MAC to avoid an overflow */ max_shift = celt_ilog2(len); shift = IMAX(0, (celt_ilog2(sample_max) << 1) + max_shift - 28); /* Compute the energy */ for (i=0; i= (PSEUDO_SNR_THRESHOLD * noise_energy); } } if (is_silence) { /* The number of consecutive DTX frames should be within the allowed bounds */ (*nb_no_activity_frames)++; if (*nb_no_activity_frames > NB_SPEECH_FRAMES_BEFORE_DTX) { if (*nb_no_activity_frames <= (NB_SPEECH_FRAMES_BEFORE_DTX + MAX_CONSECUTIVE_DTX)) /* Valid frame for DTX! */ return 1; else (*nb_no_activity_frames) = NB_SPEECH_FRAMES_BEFORE_DTX; } } else (*nb_no_activity_frames) = 0; return 0; } #endif static opus_int32 encode_multiframe_packet(OpusEncoder *st, const opus_val16 *pcm, int nb_frames, int frame_size, unsigned char *data, opus_int32 out_data_bytes, int to_celt, int lsb_depth, int float_api) { int i; int ret = 0; VARDECL(unsigned char, tmp_data); int bak_mode, bak_bandwidth, bak_channels, bak_to_mono; VARDECL(OpusRepacketizer, rp); int max_header_bytes; opus_int32 bytes_per_frame; opus_int32 cbr_bytes; opus_int32 repacketize_len; int tmp_len; ALLOC_STACK; /* Worst cases: * 2 frames: Code 2 with different compressed sizes * >2 frames: Code 3 VBR */ max_header_bytes = nb_frames == 2 ? 3 : (2+(nb_frames-1)*2); if (st->use_vbr || st->user_bitrate_bps==OPUS_BITRATE_MAX) repacketize_len = out_data_bytes; else { cbr_bytes = 3*st->bitrate_bps/(3*8*st->Fs/(frame_size*nb_frames)); repacketize_len = IMIN(cbr_bytes, out_data_bytes); } bytes_per_frame = IMIN(1276, 1+(repacketize_len-max_header_bytes)/nb_frames); ALLOC(tmp_data, nb_frames*bytes_per_frame, unsigned char); ALLOC(rp, 1, OpusRepacketizer); opus_repacketizer_init(rp); bak_mode = st->user_forced_mode; bak_bandwidth = st->user_bandwidth; bak_channels = st->force_channels; st->user_forced_mode = st->mode; st->user_bandwidth = st->bandwidth; st->force_channels = st->stream_channels; bak_to_mono = st->silk_mode.toMono; if (bak_to_mono) st->force_channels = 1; else st->prev_channels = st->stream_channels; for (i=0;isilk_mode.toMono = 0; st->nonfinal_frame = i<(nb_frames-1); /* When switching from SILK/Hybrid to CELT, only ask for a switch at the last frame */ if (to_celt && i==nb_frames-1) st->user_forced_mode = MODE_CELT_ONLY; tmp_len = opus_encode_native(st, pcm+i*(st->channels*frame_size), frame_size, tmp_data+i*bytes_per_frame, bytes_per_frame, lsb_depth, NULL, 0, 0, 0, 0, NULL, float_api); if (tmp_len<0) { RESTORE_STACK; return OPUS_INTERNAL_ERROR; } ret = opus_repacketizer_cat(rp, tmp_data+i*bytes_per_frame, tmp_len); if (ret<0) { RESTORE_STACK; return OPUS_INTERNAL_ERROR; } } ret = opus_repacketizer_out_range_impl(rp, 0, nb_frames, data, repacketize_len, 0, !st->use_vbr); if (ret<0) { RESTORE_STACK; return OPUS_INTERNAL_ERROR; } /* Discard configs that were forced locally for the purpose of repacketization */ st->user_forced_mode = bak_mode; st->user_bandwidth = bak_bandwidth; st->force_channels = bak_channels; st->silk_mode.toMono = bak_to_mono; RESTORE_STACK; return ret; } static int compute_redundancy_bytes(opus_int32 max_data_bytes, opus_int32 bitrate_bps, int frame_rate, int channels) { int redundancy_bytes_cap; int redundancy_bytes; opus_int32 redundancy_rate; int base_bits; opus_int32 available_bits; base_bits = (40*channels+20); /* Equivalent rate for 5 ms frames. */ redundancy_rate = bitrate_bps + base_bits*(200 - frame_rate); /* For VBR, further increase the bitrate if we can afford it. It's pretty short and we'll avoid artefacts. */ redundancy_rate = 3*redundancy_rate/2; redundancy_bytes = redundancy_rate/1600; /* Compute the max rate we can use given CBR or VBR with cap. */ available_bits = max_data_bytes*8 - 2*base_bits; redundancy_bytes_cap = (available_bits*240/(240+48000/frame_rate) + base_bits)/8; redundancy_bytes = IMIN(redundancy_bytes, redundancy_bytes_cap); /* It we can't get enough bits for redundancy to be worth it, rely on the decoder PLC. */ if (redundancy_bytes > 4 + 8*channels) redundancy_bytes = IMIN(257, redundancy_bytes); else redundancy_bytes = 0; return redundancy_bytes; } opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_size, unsigned char *data, opus_int32 out_data_bytes, int lsb_depth, const void *analysis_pcm, opus_int32 analysis_size, int c1, int c2, int analysis_channels, downmix_func downmix, int float_api) { void *silk_enc; CELTEncoder *celt_enc; int i; int ret=0; opus_int32 nBytes; ec_enc enc; int bytes_target; int prefill=0; int start_band = 0; int redundancy = 0; int redundancy_bytes = 0; /* Number of bytes to use for redundancy frame */ int celt_to_silk = 0; VARDECL(opus_val16, pcm_buf); int nb_compr_bytes; int to_celt = 0; opus_uint32 redundant_rng = 0; int cutoff_Hz, hp_freq_smth1; int voice_est; /* Probability of voice in Q7 */ opus_int32 equiv_rate; int delay_compensation; int frame_rate; opus_int32 max_rate; /* Max bitrate we're allowed to use */ int curr_bandwidth; opus_val16 HB_gain; opus_int32 max_data_bytes; /* Max number of bytes we're allowed to use */ int total_buffer; opus_val16 stereo_width; const CELTMode *celt_mode; #ifndef DISABLE_FLOAT_API AnalysisInfo analysis_info; int analysis_read_pos_bak=-1; int analysis_read_subframe_bak=-1; int is_silence = 0; #endif VARDECL(opus_val16, tmp_prefill); ALLOC_STACK; max_data_bytes = IMIN(1276, out_data_bytes); st->rangeFinal = 0; if (frame_size <= 0 || max_data_bytes <= 0) { RESTORE_STACK; return OPUS_BAD_ARG; } /* Cannot encode 100 ms in 1 byte */ if (max_data_bytes==1 && st->Fs==(frame_size*10)) { RESTORE_STACK; return OPUS_BUFFER_TOO_SMALL; } silk_enc = (char*)st+st->silk_enc_offset; celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset); if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY) delay_compensation = 0; else delay_compensation = st->delay_compensation; lsb_depth = IMIN(lsb_depth, st->lsb_depth); celt_encoder_ctl(celt_enc, CELT_GET_MODE(&celt_mode)); #ifndef DISABLE_FLOAT_API analysis_info.valid = 0; #ifdef FIXED_POINT if (st->silk_mode.complexity >= 10 && st->Fs>=16000) #else if (st->silk_mode.complexity >= 7 && st->Fs>=16000) #endif { is_silence = is_digital_silence(pcm, frame_size, st->channels, lsb_depth); analysis_read_pos_bak = st->analysis.read_pos; analysis_read_subframe_bak = st->analysis.read_subframe; run_analysis(&st->analysis, celt_mode, analysis_pcm, analysis_size, frame_size, c1, c2, analysis_channels, st->Fs, lsb_depth, downmix, &analysis_info); /* Track the peak signal energy */ if (!is_silence && analysis_info.activity_probability > DTX_ACTIVITY_THRESHOLD) st->peak_signal_energy = MAX32(MULT16_32_Q15(QCONST16(0.999f, 15), st->peak_signal_energy), compute_frame_energy(pcm, frame_size, st->channels, st->arch)); } else if (st->analysis.initialized) { tonality_analysis_reset(&st->analysis); } #else (void)analysis_pcm; (void)analysis_size; (void)c1; (void)c2; (void)analysis_channels; (void)downmix; #endif #ifndef DISABLE_FLOAT_API /* Reset voice_ratio if this frame is not silent or if analysis is disabled. * Otherwise, preserve voice_ratio from the last non-silent frame */ if (!is_silence) st->voice_ratio = -1; st->detected_bandwidth = 0; if (analysis_info.valid) { int analysis_bandwidth; if (st->signal_type == OPUS_AUTO) { float prob; if (st->prev_mode == 0) prob = analysis_info.music_prob; else if (st->prev_mode == MODE_CELT_ONLY) prob = analysis_info.music_prob_max; else prob = analysis_info.music_prob_min; st->voice_ratio = (int)floor(.5+100*(1-prob)); } analysis_bandwidth = analysis_info.bandwidth; if (analysis_bandwidth<=12) st->detected_bandwidth = OPUS_BANDWIDTH_NARROWBAND; else if (analysis_bandwidth<=14) st->detected_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND; else if (analysis_bandwidth<=16) st->detected_bandwidth = OPUS_BANDWIDTH_WIDEBAND; else if (analysis_bandwidth<=18) st->detected_bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND; else st->detected_bandwidth = OPUS_BANDWIDTH_FULLBAND; } #else st->voice_ratio = -1; #endif if (st->channels==2 && st->force_channels!=1) stereo_width = compute_stereo_width(pcm, frame_size, st->Fs, &st->width_mem); else stereo_width = 0; total_buffer = delay_compensation; st->bitrate_bps = user_bitrate_to_bitrate(st, frame_size, max_data_bytes); frame_rate = st->Fs/frame_size; if (!st->use_vbr) { int cbrBytes; /* Multiply by 12 to make sure the division is exact. */ int frame_rate12 = 12*st->Fs/frame_size; /* We need to make sure that "int" values always fit in 16 bits. */ cbrBytes = IMIN( (12*st->bitrate_bps/8 + frame_rate12/2)/frame_rate12, max_data_bytes); st->bitrate_bps = cbrBytes*(opus_int32)frame_rate12*8/12; /* Make sure we provide at least one byte to avoid failing. */ max_data_bytes = IMAX(1, cbrBytes); } if (max_data_bytes<3 || st->bitrate_bps < 3*frame_rate*8 || (frame_rate<50 && (max_data_bytes*frame_rate<300 || st->bitrate_bps < 2400))) { /*If the space is too low to do something useful, emit 'PLC' frames.*/ int tocmode = st->mode; int bw = st->bandwidth == 0 ? OPUS_BANDWIDTH_NARROWBAND : st->bandwidth; int packet_code = 0; int num_multiframes = 0; if (tocmode==0) tocmode = MODE_SILK_ONLY; if (frame_rate>100) tocmode = MODE_CELT_ONLY; /* 40 ms -> 2 x 20 ms if in CELT_ONLY or HYBRID mode */ if (frame_rate==25 && tocmode!=MODE_SILK_ONLY) { frame_rate = 50; packet_code = 1; } /* >= 60 ms frames */ if (frame_rate<=16) { /* 1 x 60 ms, 2 x 40 ms, 2 x 60 ms */ if (out_data_bytes==1 || (tocmode==MODE_SILK_ONLY && frame_rate!=10)) { tocmode = MODE_SILK_ONLY; packet_code = frame_rate <= 12; frame_rate = frame_rate == 12 ? 25 : 16; } else { num_multiframes = 50/frame_rate; frame_rate = 50; packet_code = 3; } } if(tocmode==MODE_SILK_ONLY&&bw>OPUS_BANDWIDTH_WIDEBAND) bw=OPUS_BANDWIDTH_WIDEBAND; else if (tocmode==MODE_CELT_ONLY&&bw==OPUS_BANDWIDTH_MEDIUMBAND) bw=OPUS_BANDWIDTH_NARROWBAND; else if (tocmode==MODE_HYBRID&&bw<=OPUS_BANDWIDTH_SUPERWIDEBAND) bw=OPUS_BANDWIDTH_SUPERWIDEBAND; data[0] = gen_toc(tocmode, frame_rate, bw, st->stream_channels); data[0] |= packet_code; ret = packet_code <= 1 ? 1 : 2; max_data_bytes = IMAX(max_data_bytes, ret); if (packet_code==3) data[1] = num_multiframes; if (!st->use_vbr) { ret = opus_packet_pad(data, ret, max_data_bytes); if (ret == OPUS_OK) ret = max_data_bytes; else ret = OPUS_INTERNAL_ERROR; } RESTORE_STACK; return ret; } max_rate = frame_rate*max_data_bytes*8; /* Equivalent 20-ms rate for mode/channel/bandwidth decisions */ equiv_rate = compute_equiv_rate(st->bitrate_bps, st->channels, st->Fs/frame_size, st->use_vbr, 0, st->silk_mode.complexity, st->silk_mode.packetLossPercentage); if (st->signal_type == OPUS_SIGNAL_VOICE) voice_est = 127; else if (st->signal_type == OPUS_SIGNAL_MUSIC) voice_est = 0; else if (st->voice_ratio >= 0) { voice_est = st->voice_ratio*327>>8; /* For AUDIO, never be more than 90% confident of having speech */ if (st->application == OPUS_APPLICATION_AUDIO) voice_est = IMIN(voice_est, 115); } else if (st->application == OPUS_APPLICATION_VOIP) voice_est = 115; else voice_est = 48; if (st->force_channels!=OPUS_AUTO && st->channels == 2) { st->stream_channels = st->force_channels; } else { #ifdef FUZZING /* Random mono/stereo decision */ if (st->channels == 2 && (rand()&0x1F)==0) st->stream_channels = 3-st->stream_channels; #else /* Rate-dependent mono-stereo decision */ if (st->channels == 2) { opus_int32 stereo_threshold; stereo_threshold = stereo_music_threshold + ((voice_est*voice_est*(stereo_voice_threshold-stereo_music_threshold))>>14); if (st->stream_channels == 2) stereo_threshold -= 1000; else stereo_threshold += 1000; st->stream_channels = (equiv_rate > stereo_threshold) ? 2 : 1; } else { st->stream_channels = st->channels; } #endif } /* Update equivalent rate for channels decision. */ equiv_rate = compute_equiv_rate(st->bitrate_bps, st->stream_channels, st->Fs/frame_size, st->use_vbr, 0, st->silk_mode.complexity, st->silk_mode.packetLossPercentage); /* Allow SILK DTX if DTX is enabled but the generalized DTX cannot be used, e.g. because of the complexity setting or sample rate. */ #ifndef DISABLE_FLOAT_API st->silk_mode.useDTX = st->use_dtx && !(analysis_info.valid || is_silence); #else st->silk_mode.useDTX = st->use_dtx; #endif /* Mode selection depending on application and signal type */ if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY) { st->mode = MODE_CELT_ONLY; } else if (st->user_forced_mode == OPUS_AUTO) { #ifdef FUZZING /* Random mode switching */ if ((rand()&0xF)==0) { if ((rand()&0x1)==0) st->mode = MODE_CELT_ONLY; else st->mode = MODE_SILK_ONLY; } else { if (st->prev_mode==MODE_CELT_ONLY) st->mode = MODE_CELT_ONLY; else st->mode = MODE_SILK_ONLY; } #else opus_int32 mode_voice, mode_music; opus_int32 threshold; /* Interpolate based on stereo width */ mode_voice = (opus_int32)(MULT16_32_Q15(Q15ONE-stereo_width,mode_thresholds[0][0]) + MULT16_32_Q15(stereo_width,mode_thresholds[1][0])); mode_music = (opus_int32)(MULT16_32_Q15(Q15ONE-stereo_width,mode_thresholds[1][1]) + MULT16_32_Q15(stereo_width,mode_thresholds[1][1])); /* Interpolate based on speech/music probability */ threshold = mode_music + ((voice_est*voice_est*(mode_voice-mode_music))>>14); /* Bias towards SILK for VoIP because of some useful features */ if (st->application == OPUS_APPLICATION_VOIP) threshold += 8000; /*printf("%f %d\n", stereo_width/(float)Q15ONE, threshold);*/ /* Hysteresis */ if (st->prev_mode == MODE_CELT_ONLY) threshold -= 4000; else if (st->prev_mode>0) threshold += 4000; st->mode = (equiv_rate >= threshold) ? MODE_CELT_ONLY: MODE_SILK_ONLY; /* When FEC is enabled and there's enough packet loss, use SILK */ if (st->silk_mode.useInBandFEC && st->silk_mode.packetLossPercentage > (128-voice_est)>>4) st->mode = MODE_SILK_ONLY; /* When encoding voice and DTX is enabled but the generalized DTX cannot be used, use SILK in order to make use of its DTX. */ if (st->silk_mode.useDTX && voice_est > 100) st->mode = MODE_SILK_ONLY; #endif /* If max_data_bytes represents less than 6 kb/s, switch to CELT-only mode */ if (max_data_bytes < (frame_rate > 50 ? 9000 : 6000)*frame_size / (st->Fs * 8)) st->mode = MODE_CELT_ONLY; } else { st->mode = st->user_forced_mode; } /* Override the chosen mode to make sure we meet the requested frame size */ if (st->mode != MODE_CELT_ONLY && frame_size < st->Fs/100) st->mode = MODE_CELT_ONLY; if (st->lfe) st->mode = MODE_CELT_ONLY; if (st->prev_mode > 0 && ((st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) || (st->mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY))) { redundancy = 1; celt_to_silk = (st->mode != MODE_CELT_ONLY); if (!celt_to_silk) { /* Switch to SILK/hybrid if frame size is 10 ms or more*/ if (frame_size >= st->Fs/100) { st->mode = st->prev_mode; to_celt = 1; } else { redundancy=0; } } } /* When encoding multiframes, we can ask for a switch to CELT only in the last frame. This switch * is processed above as the requested mode shouldn't interrupt stereo->mono transition. */ if (st->stream_channels == 1 && st->prev_channels ==2 && st->silk_mode.toMono==0 && st->mode != MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY) { /* Delay stereo->mono transition by two frames so that SILK can do a smooth downmix */ st->silk_mode.toMono = 1; st->stream_channels = 2; } else { st->silk_mode.toMono = 0; } /* Update equivalent rate with mode decision. */ equiv_rate = compute_equiv_rate(st->bitrate_bps, st->stream_channels, st->Fs/frame_size, st->use_vbr, st->mode, st->silk_mode.complexity, st->silk_mode.packetLossPercentage); if (st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) { silk_EncControlStruct dummy; silk_InitEncoder( silk_enc, st->arch, &dummy); prefill=1; } /* Automatic (rate-dependent) bandwidth selection */ if (st->mode == MODE_CELT_ONLY || st->first || st->silk_mode.allowBandwidthSwitch) { const opus_int32 *voice_bandwidth_thresholds, *music_bandwidth_thresholds; opus_int32 bandwidth_thresholds[8]; int bandwidth = OPUS_BANDWIDTH_FULLBAND; if (st->channels==2 && st->force_channels!=1) { voice_bandwidth_thresholds = stereo_voice_bandwidth_thresholds; music_bandwidth_thresholds = stereo_music_bandwidth_thresholds; } else { voice_bandwidth_thresholds = mono_voice_bandwidth_thresholds; music_bandwidth_thresholds = mono_music_bandwidth_thresholds; } /* Interpolate bandwidth thresholds depending on voice estimation */ for (i=0;i<8;i++) { bandwidth_thresholds[i] = music_bandwidth_thresholds[i] + ((voice_est*voice_est*(voice_bandwidth_thresholds[i]-music_bandwidth_thresholds[i]))>>14); } do { int threshold, hysteresis; threshold = bandwidth_thresholds[2*(bandwidth-OPUS_BANDWIDTH_MEDIUMBAND)]; hysteresis = bandwidth_thresholds[2*(bandwidth-OPUS_BANDWIDTH_MEDIUMBAND)+1]; if (!st->first) { if (st->auto_bandwidth >= bandwidth) threshold -= hysteresis; else threshold += hysteresis; } if (equiv_rate >= threshold) break; } while (--bandwidth>OPUS_BANDWIDTH_NARROWBAND); /* We don't use mediumband anymore, except when explicitly requested or during mode transitions. */ if (bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) bandwidth = OPUS_BANDWIDTH_WIDEBAND; st->bandwidth = st->auto_bandwidth = bandwidth; /* Prevents any transition to SWB/FB until the SILK layer has fully switched to WB mode and turned the variable LP filter off */ if (!st->first && st->mode != MODE_CELT_ONLY && !st->silk_mode.inWBmodeWithoutVariableLP && st->bandwidth > OPUS_BANDWIDTH_WIDEBAND) st->bandwidth = OPUS_BANDWIDTH_WIDEBAND; } if (st->bandwidth>st->max_bandwidth) st->bandwidth = st->max_bandwidth; if (st->user_bandwidth != OPUS_AUTO) st->bandwidth = st->user_bandwidth; /* This prevents us from using hybrid at unsafe CBR/max rates */ if (st->mode != MODE_CELT_ONLY && max_rate < 15000) { st->bandwidth = IMIN(st->bandwidth, OPUS_BANDWIDTH_WIDEBAND); } /* Prevents Opus from wasting bits on frequencies that are above the Nyquist rate of the input signal */ if (st->Fs <= 24000 && st->bandwidth > OPUS_BANDWIDTH_SUPERWIDEBAND) st->bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND; if (st->Fs <= 16000 && st->bandwidth > OPUS_BANDWIDTH_WIDEBAND) st->bandwidth = OPUS_BANDWIDTH_WIDEBAND; if (st->Fs <= 12000 && st->bandwidth > OPUS_BANDWIDTH_MEDIUMBAND) st->bandwidth = OPUS_BANDWIDTH_MEDIUMBAND; if (st->Fs <= 8000 && st->bandwidth > OPUS_BANDWIDTH_NARROWBAND) st->bandwidth = OPUS_BANDWIDTH_NARROWBAND; #ifndef DISABLE_FLOAT_API /* Use detected bandwidth to reduce the encoded bandwidth. */ if (st->detected_bandwidth && st->user_bandwidth == OPUS_AUTO) { int min_detected_bandwidth; /* Makes bandwidth detection more conservative just in case the detector gets it wrong when we could have coded a high bandwidth transparently. When operating in SILK/hybrid mode, we don't go below wideband to avoid more complicated switches that require redundancy. */ if (equiv_rate <= 18000*st->stream_channels && st->mode == MODE_CELT_ONLY) min_detected_bandwidth = OPUS_BANDWIDTH_NARROWBAND; else if (equiv_rate <= 24000*st->stream_channels && st->mode == MODE_CELT_ONLY) min_detected_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND; else if (equiv_rate <= 30000*st->stream_channels) min_detected_bandwidth = OPUS_BANDWIDTH_WIDEBAND; else if (equiv_rate <= 44000*st->stream_channels) min_detected_bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND; else min_detected_bandwidth = OPUS_BANDWIDTH_FULLBAND; st->detected_bandwidth = IMAX(st->detected_bandwidth, min_detected_bandwidth); st->bandwidth = IMIN(st->bandwidth, st->detected_bandwidth); } #endif st->silk_mode.LBRR_coded = decide_fec(st->silk_mode.useInBandFEC, st->silk_mode.packetLossPercentage, st->silk_mode.LBRR_coded, st->mode, &st->bandwidth, equiv_rate); celt_encoder_ctl(celt_enc, OPUS_SET_LSB_DEPTH(lsb_depth)); /* CELT mode doesn't support mediumband, use wideband instead */ if (st->mode == MODE_CELT_ONLY && st->bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) st->bandwidth = OPUS_BANDWIDTH_WIDEBAND; if (st->lfe) st->bandwidth = OPUS_BANDWIDTH_NARROWBAND; curr_bandwidth = st->bandwidth; /* Chooses the appropriate mode for speech *NEVER* switch to/from CELT-only mode here as this will invalidate some assumptions */ if (st->mode == MODE_SILK_ONLY && curr_bandwidth > OPUS_BANDWIDTH_WIDEBAND) st->mode = MODE_HYBRID; if (st->mode == MODE_HYBRID && curr_bandwidth <= OPUS_BANDWIDTH_WIDEBAND) st->mode = MODE_SILK_ONLY; /* Can't support higher than >60 ms frames, and >20 ms when in Hybrid or CELT-only modes */ if ((frame_size > st->Fs/50 && (st->mode != MODE_SILK_ONLY)) || frame_size > 3*st->Fs/50) { int enc_frame_size; int nb_frames; if (st->mode == MODE_SILK_ONLY) { if (frame_size == 2*st->Fs/25) /* 80 ms -> 2x 40 ms */ enc_frame_size = st->Fs/25; else if (frame_size == 3*st->Fs/25) /* 120 ms -> 2x 60 ms */ enc_frame_size = 3*st->Fs/50; else /* 100 ms -> 5x 20 ms */ enc_frame_size = st->Fs/50; } else enc_frame_size = st->Fs/50; nb_frames = frame_size/enc_frame_size; #ifndef DISABLE_FLOAT_API if (analysis_read_pos_bak!= -1) { st->analysis.read_pos = analysis_read_pos_bak; st->analysis.read_subframe = analysis_read_subframe_bak; } #endif ret = encode_multiframe_packet(st, pcm, nb_frames, enc_frame_size, data, out_data_bytes, to_celt, lsb_depth, float_api); RESTORE_STACK; return ret; } /* For the first frame at a new SILK bandwidth */ if (st->silk_bw_switch) { redundancy = 1; celt_to_silk = 1; st->silk_bw_switch = 0; /* Do a prefill without resetting the sampling rate control. */ prefill=2; } /* If we decided to go with CELT, make sure redundancy is off, no matter what we decided earlier. */ if (st->mode == MODE_CELT_ONLY) redundancy = 0; if (redundancy) { redundancy_bytes = compute_redundancy_bytes(max_data_bytes, st->bitrate_bps, frame_rate, st->stream_channels); if (redundancy_bytes == 0) redundancy = 0; } /* printf("%d %d %d %d\n", st->bitrate_bps, st->stream_channels, st->mode, curr_bandwidth); */ bytes_target = IMIN(max_data_bytes-redundancy_bytes, st->bitrate_bps * frame_size / (st->Fs * 8)) - 1; data += 1; ec_enc_init(&enc, data, max_data_bytes-1); ALLOC(pcm_buf, (total_buffer+frame_size)*st->channels, opus_val16); OPUS_COPY(pcm_buf, &st->delay_buffer[(st->encoder_buffer-total_buffer)*st->channels], total_buffer*st->channels); if (st->mode == MODE_CELT_ONLY) hp_freq_smth1 = silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 ); else hp_freq_smth1 = ((silk_encoder*)silk_enc)->state_Fxx[0].sCmn.variable_HP_smth1_Q15; st->variable_HP_smth2_Q15 = silk_SMLAWB( st->variable_HP_smth2_Q15, hp_freq_smth1 - st->variable_HP_smth2_Q15, SILK_FIX_CONST( VARIABLE_HP_SMTH_COEF2, 16 ) ); /* convert from log scale to Hertz */ cutoff_Hz = silk_log2lin( silk_RSHIFT( st->variable_HP_smth2_Q15, 8 ) ); if (st->application == OPUS_APPLICATION_VOIP) { hp_cutoff(pcm, cutoff_Hz, &pcm_buf[total_buffer*st->channels], st->hp_mem, frame_size, st->channels, st->Fs, st->arch); } else { dc_reject(pcm, 3, &pcm_buf[total_buffer*st->channels], st->hp_mem, frame_size, st->channels, st->Fs); } #ifndef FIXED_POINT if (float_api) { opus_val32 sum; sum = celt_inner_prod(&pcm_buf[total_buffer*st->channels], &pcm_buf[total_buffer*st->channels], frame_size*st->channels, st->arch); /* This should filter out both NaNs and ridiculous signals that could cause NaNs further down. */ if (!(sum < 1e9f) || celt_isnan(sum)) { OPUS_CLEAR(&pcm_buf[total_buffer*st->channels], frame_size*st->channels); st->hp_mem[0] = st->hp_mem[1] = st->hp_mem[2] = st->hp_mem[3] = 0; } } #endif /* SILK processing */ HB_gain = Q15ONE; if (st->mode != MODE_CELT_ONLY) { opus_int32 total_bitRate, celt_rate; opus_int activity; #ifdef FIXED_POINT const opus_int16 *pcm_silk; #else VARDECL(opus_int16, pcm_silk); ALLOC(pcm_silk, st->channels*frame_size, opus_int16); #endif activity = VAD_NO_DECISION; #ifndef DISABLE_FLOAT_API if( analysis_info.valid ) { /* Inform SILK about the Opus VAD decision */ activity = ( analysis_info.activity_probability >= DTX_ACTIVITY_THRESHOLD ); } #endif /* Distribute bits between SILK and CELT */ total_bitRate = 8 * bytes_target * frame_rate; if( st->mode == MODE_HYBRID ) { /* Base rate for SILK */ st->silk_mode.bitRate = compute_silk_rate_for_hybrid(total_bitRate, curr_bandwidth, st->Fs == 50 * frame_size, st->use_vbr, st->silk_mode.LBRR_coded, st->stream_channels); if (!st->energy_masking) { /* Increasingly attenuate high band when it gets allocated fewer bits */ celt_rate = total_bitRate - st->silk_mode.bitRate; HB_gain = Q15ONE - SHR32(celt_exp2(-celt_rate * QCONST16(1.f/1024, 10)), 1); } } else { /* SILK gets all bits */ st->silk_mode.bitRate = total_bitRate; } /* Surround masking for SILK */ if (st->energy_masking && st->use_vbr && !st->lfe) { opus_val32 mask_sum=0; opus_val16 masking_depth; opus_int32 rate_offset; int c; int end = 17; opus_int16 srate = 16000; if (st->bandwidth == OPUS_BANDWIDTH_NARROWBAND) { end = 13; srate = 8000; } else if (st->bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) { end = 15; srate = 12000; } for (c=0;cchannels;c++) { for(i=0;ienergy_masking[21*c+i], QCONST16(.5f, DB_SHIFT)), -QCONST16(2.0f, DB_SHIFT)); if (mask > 0) mask = HALF16(mask); mask_sum += mask; } } /* Conservative rate reduction, we cut the masking in half */ masking_depth = mask_sum / end*st->channels; masking_depth += QCONST16(.2f, DB_SHIFT); rate_offset = (opus_int32)PSHR32(MULT16_16(srate, masking_depth), DB_SHIFT); rate_offset = MAX32(rate_offset, -2*st->silk_mode.bitRate/3); /* Split the rate change between the SILK and CELT part for hybrid. */ if (st->bandwidth==OPUS_BANDWIDTH_SUPERWIDEBAND || st->bandwidth==OPUS_BANDWIDTH_FULLBAND) st->silk_mode.bitRate += 3*rate_offset/5; else st->silk_mode.bitRate += rate_offset; } st->silk_mode.payloadSize_ms = 1000 * frame_size / st->Fs; st->silk_mode.nChannelsAPI = st->channels; st->silk_mode.nChannelsInternal = st->stream_channels; if (curr_bandwidth == OPUS_BANDWIDTH_NARROWBAND) { st->silk_mode.desiredInternalSampleRate = 8000; } else if (curr_bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) { st->silk_mode.desiredInternalSampleRate = 12000; } else { celt_assert( st->mode == MODE_HYBRID || curr_bandwidth == OPUS_BANDWIDTH_WIDEBAND ); st->silk_mode.desiredInternalSampleRate = 16000; } if( st->mode == MODE_HYBRID ) { /* Don't allow bandwidth reduction at lowest bitrates in hybrid mode */ st->silk_mode.minInternalSampleRate = 16000; } else { st->silk_mode.minInternalSampleRate = 8000; } st->silk_mode.maxInternalSampleRate = 16000; if (st->mode == MODE_SILK_ONLY) { opus_int32 effective_max_rate = max_rate; if (frame_rate > 50) effective_max_rate = effective_max_rate*2/3; if (effective_max_rate < 8000) { st->silk_mode.maxInternalSampleRate = 12000; st->silk_mode.desiredInternalSampleRate = IMIN(12000, st->silk_mode.desiredInternalSampleRate); } if (effective_max_rate < 7000) { st->silk_mode.maxInternalSampleRate = 8000; st->silk_mode.desiredInternalSampleRate = IMIN(8000, st->silk_mode.desiredInternalSampleRate); } } st->silk_mode.useCBR = !st->use_vbr; /* Call SILK encoder for the low band */ /* Max bits for SILK, counting ToC, redundancy bytes, and optionally redundancy. */ st->silk_mode.maxBits = (max_data_bytes-1)*8; if (redundancy && redundancy_bytes >= 2) { /* Counting 1 bit for redundancy position and 20 bits for flag+size (only for hybrid). */ st->silk_mode.maxBits -= redundancy_bytes*8 + 1; if (st->mode == MODE_HYBRID) st->silk_mode.maxBits -= 20; } if (st->silk_mode.useCBR) { if (st->mode == MODE_HYBRID) { st->silk_mode.maxBits = IMIN(st->silk_mode.maxBits, st->silk_mode.bitRate * frame_size / st->Fs); } } else { /* Constrained VBR. */ if (st->mode == MODE_HYBRID) { /* Compute SILK bitrate corresponding to the max total bits available */ opus_int32 maxBitRate = compute_silk_rate_for_hybrid(st->silk_mode.maxBits*st->Fs / frame_size, curr_bandwidth, st->Fs == 50 * frame_size, st->use_vbr, st->silk_mode.LBRR_coded, st->stream_channels); st->silk_mode.maxBits = maxBitRate * frame_size / st->Fs; } } if (prefill) { opus_int32 zero=0; int prefill_offset; /* Use a smooth onset for the SILK prefill to avoid the encoder trying to encode a discontinuity. The exact location is what we need to avoid leaving any "gap" in the audio when mixing with the redundant CELT frame. Here we can afford to overwrite st->delay_buffer because the only thing that uses it before it gets rewritten is tmp_prefill[] and even then only the part after the ramp really gets used (rather than sent to the encoder and discarded) */ prefill_offset = st->channels*(st->encoder_buffer-st->delay_compensation-st->Fs/400); gain_fade(st->delay_buffer+prefill_offset, st->delay_buffer+prefill_offset, 0, Q15ONE, celt_mode->overlap, st->Fs/400, st->channels, celt_mode->window, st->Fs); OPUS_CLEAR(st->delay_buffer, prefill_offset); #ifdef FIXED_POINT pcm_silk = st->delay_buffer; #else for (i=0;iencoder_buffer*st->channels;i++) pcm_silk[i] = FLOAT2INT16(st->delay_buffer[i]); #endif silk_Encode( silk_enc, &st->silk_mode, pcm_silk, st->encoder_buffer, NULL, &zero, prefill, activity ); /* Prevent a second switch in the real encode call. */ st->silk_mode.opusCanSwitch = 0; } #ifdef FIXED_POINT pcm_silk = pcm_buf+total_buffer*st->channels; #else for (i=0;ichannels;i++) pcm_silk[i] = FLOAT2INT16(pcm_buf[total_buffer*st->channels + i]); #endif ret = silk_Encode( silk_enc, &st->silk_mode, pcm_silk, frame_size, &enc, &nBytes, 0, activity ); if( ret ) { /*fprintf (stderr, "SILK encode error: %d\n", ret);*/ /* Handle error */ RESTORE_STACK; return OPUS_INTERNAL_ERROR; } /* Extract SILK internal bandwidth for signaling in first byte */ if( st->mode == MODE_SILK_ONLY ) { if( st->silk_mode.internalSampleRate == 8000 ) { curr_bandwidth = OPUS_BANDWIDTH_NARROWBAND; } else if( st->silk_mode.internalSampleRate == 12000 ) { curr_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND; } else if( st->silk_mode.internalSampleRate == 16000 ) { curr_bandwidth = OPUS_BANDWIDTH_WIDEBAND; } } else { celt_assert( st->silk_mode.internalSampleRate == 16000 ); } st->silk_mode.opusCanSwitch = st->silk_mode.switchReady && !st->nonfinal_frame; if (nBytes==0) { st->rangeFinal = 0; data[-1] = gen_toc(st->mode, st->Fs/frame_size, curr_bandwidth, st->stream_channels); RESTORE_STACK; return 1; } /* FIXME: How do we allocate the redundancy for CBR? */ if (st->silk_mode.opusCanSwitch) { redundancy_bytes = compute_redundancy_bytes(max_data_bytes, st->bitrate_bps, frame_rate, st->stream_channels); redundancy = (redundancy_bytes != 0); celt_to_silk = 0; st->silk_bw_switch = 1; } } /* CELT processing */ { int endband=21; switch(curr_bandwidth) { case OPUS_BANDWIDTH_NARROWBAND: endband = 13; break; case OPUS_BANDWIDTH_MEDIUMBAND: case OPUS_BANDWIDTH_WIDEBAND: endband = 17; break; case OPUS_BANDWIDTH_SUPERWIDEBAND: endband = 19; break; case OPUS_BANDWIDTH_FULLBAND: endband = 21; break; } celt_encoder_ctl(celt_enc, CELT_SET_END_BAND(endband)); celt_encoder_ctl(celt_enc, CELT_SET_CHANNELS(st->stream_channels)); } celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(OPUS_BITRATE_MAX)); if (st->mode != MODE_SILK_ONLY) { opus_val32 celt_pred=2; celt_encoder_ctl(celt_enc, OPUS_SET_VBR(0)); /* We may still decide to disable prediction later */ if (st->silk_mode.reducedDependency) celt_pred = 0; celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(celt_pred)); if (st->mode == MODE_HYBRID) { if( st->use_vbr ) { celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(st->bitrate_bps-st->silk_mode.bitRate)); celt_encoder_ctl(celt_enc, OPUS_SET_VBR_CONSTRAINT(0)); } } else { if (st->use_vbr) { celt_encoder_ctl(celt_enc, OPUS_SET_VBR(1)); celt_encoder_ctl(celt_enc, OPUS_SET_VBR_CONSTRAINT(st->vbr_constraint)); celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(st->bitrate_bps)); } } } ALLOC(tmp_prefill, st->channels*st->Fs/400, opus_val16); if (st->mode != MODE_SILK_ONLY && st->mode != st->prev_mode && st->prev_mode > 0) { OPUS_COPY(tmp_prefill, &st->delay_buffer[(st->encoder_buffer-total_buffer-st->Fs/400)*st->channels], st->channels*st->Fs/400); } if (st->channels*(st->encoder_buffer-(frame_size+total_buffer)) > 0) { OPUS_MOVE(st->delay_buffer, &st->delay_buffer[st->channels*frame_size], st->channels*(st->encoder_buffer-frame_size-total_buffer)); OPUS_COPY(&st->delay_buffer[st->channels*(st->encoder_buffer-frame_size-total_buffer)], &pcm_buf[0], (frame_size+total_buffer)*st->channels); } else { OPUS_COPY(st->delay_buffer, &pcm_buf[(frame_size+total_buffer-st->encoder_buffer)*st->channels], st->encoder_buffer*st->channels); } /* gain_fade() and stereo_fade() need to be after the buffer copying because we don't want any of this to affect the SILK part */ if( st->prev_HB_gain < Q15ONE || HB_gain < Q15ONE ) { gain_fade(pcm_buf, pcm_buf, st->prev_HB_gain, HB_gain, celt_mode->overlap, frame_size, st->channels, celt_mode->window, st->Fs); } st->prev_HB_gain = HB_gain; if (st->mode != MODE_HYBRID || st->stream_channels==1) { if (equiv_rate > 32000) st->silk_mode.stereoWidth_Q14 = 16384; else if (equiv_rate < 16000) st->silk_mode.stereoWidth_Q14 = 0; else st->silk_mode.stereoWidth_Q14 = 16384 - 2048*(opus_int32)(32000-equiv_rate)/(equiv_rate-14000); } if( !st->energy_masking && st->channels == 2 ) { /* Apply stereo width reduction (at low bitrates) */ if( st->hybrid_stereo_width_Q14 < (1 << 14) || st->silk_mode.stereoWidth_Q14 < (1 << 14) ) { opus_val16 g1, g2; g1 = st->hybrid_stereo_width_Q14; g2 = (opus_val16)(st->silk_mode.stereoWidth_Q14); #ifdef FIXED_POINT g1 = g1==16384 ? Q15ONE : SHL16(g1,1); g2 = g2==16384 ? Q15ONE : SHL16(g2,1); #else g1 *= (1.f/16384); g2 *= (1.f/16384); #endif stereo_fade(pcm_buf, pcm_buf, g1, g2, celt_mode->overlap, frame_size, st->channels, celt_mode->window, st->Fs); st->hybrid_stereo_width_Q14 = st->silk_mode.stereoWidth_Q14; } } if ( st->mode != MODE_CELT_ONLY && ec_tell(&enc)+17+20*(st->mode == MODE_HYBRID) <= 8*(max_data_bytes-1)) { /* For SILK mode, the redundancy is inferred from the length */ if (st->mode == MODE_HYBRID) ec_enc_bit_logp(&enc, redundancy, 12); if (redundancy) { int max_redundancy; ec_enc_bit_logp(&enc, celt_to_silk, 1); if (st->mode == MODE_HYBRID) { /* Reserve the 8 bits needed for the redundancy length, and at least a few bits for CELT if possible */ max_redundancy = (max_data_bytes-1)-((ec_tell(&enc)+8+3+7)>>3); } else max_redundancy = (max_data_bytes-1)-((ec_tell(&enc)+7)>>3); /* Target the same bit-rate for redundancy as for the rest, up to a max of 257 bytes */ redundancy_bytes = IMIN(max_redundancy, redundancy_bytes); redundancy_bytes = IMIN(257, IMAX(2, redundancy_bytes)); if (st->mode == MODE_HYBRID) ec_enc_uint(&enc, redundancy_bytes-2, 256); } } else { redundancy = 0; } if (!redundancy) { st->silk_bw_switch = 0; redundancy_bytes = 0; } if (st->mode != MODE_CELT_ONLY)start_band=17; if (st->mode == MODE_SILK_ONLY) { ret = (ec_tell(&enc)+7)>>3; ec_enc_done(&enc); nb_compr_bytes = ret; } else { nb_compr_bytes = (max_data_bytes-1)-redundancy_bytes; ec_enc_shrink(&enc, nb_compr_bytes); } #ifndef DISABLE_FLOAT_API if (redundancy || st->mode != MODE_SILK_ONLY) celt_encoder_ctl(celt_enc, CELT_SET_ANALYSIS(&analysis_info)); #endif if (st->mode == MODE_HYBRID) { SILKInfo info; info.signalType = st->silk_mode.signalType; info.offset = st->silk_mode.offset; celt_encoder_ctl(celt_enc, CELT_SET_SILK_INFO(&info)); } /* 5 ms redundant frame for CELT->SILK */ if (redundancy && celt_to_silk) { int err; celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0)); celt_encoder_ctl(celt_enc, OPUS_SET_VBR(0)); celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(OPUS_BITRATE_MAX)); err = celt_encode_with_ec(celt_enc, pcm_buf, st->Fs/200, data+nb_compr_bytes, redundancy_bytes, NULL); if (err < 0) { RESTORE_STACK; return OPUS_INTERNAL_ERROR; } celt_encoder_ctl(celt_enc, OPUS_GET_FINAL_RANGE(&redundant_rng)); celt_encoder_ctl(celt_enc, OPUS_RESET_STATE); } celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(start_band)); if (st->mode != MODE_SILK_ONLY) { if (st->mode != st->prev_mode && st->prev_mode > 0) { unsigned char dummy[2]; celt_encoder_ctl(celt_enc, OPUS_RESET_STATE); /* Prefilling */ celt_encode_with_ec(celt_enc, tmp_prefill, st->Fs/400, dummy, 2, NULL); celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0)); } /* If false, we already busted the budget and we'll end up with a "PLC frame" */ if (ec_tell(&enc) <= 8*nb_compr_bytes) { /* Set the bitrate again if it was overridden in the redundancy code above*/ if (redundancy && celt_to_silk && st->mode==MODE_HYBRID && st->use_vbr) celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(st->bitrate_bps-st->silk_mode.bitRate)); celt_encoder_ctl(celt_enc, OPUS_SET_VBR(st->use_vbr)); ret = celt_encode_with_ec(celt_enc, pcm_buf, frame_size, NULL, nb_compr_bytes, &enc); if (ret < 0) { RESTORE_STACK; return OPUS_INTERNAL_ERROR; } /* Put CELT->SILK redundancy data in the right place. */ if (redundancy && celt_to_silk && st->mode==MODE_HYBRID && st->use_vbr) { OPUS_MOVE(data+ret, data+nb_compr_bytes, redundancy_bytes); nb_compr_bytes = nb_compr_bytes+redundancy_bytes; } } } /* 5 ms redundant frame for SILK->CELT */ if (redundancy && !celt_to_silk) { int err; unsigned char dummy[2]; int N2, N4; N2 = st->Fs/200; N4 = st->Fs/400; celt_encoder_ctl(celt_enc, OPUS_RESET_STATE); celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0)); celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0)); celt_encoder_ctl(celt_enc, OPUS_SET_VBR(0)); celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(OPUS_BITRATE_MAX)); if (st->mode == MODE_HYBRID) { /* Shrink packet to what the encoder actually used. */ nb_compr_bytes = ret; ec_enc_shrink(&enc, nb_compr_bytes); } /* NOTE: We could speed this up slightly (at the expense of code size) by just adding a function that prefills the buffer */ celt_encode_with_ec(celt_enc, pcm_buf+st->channels*(frame_size-N2-N4), N4, dummy, 2, NULL); err = celt_encode_with_ec(celt_enc, pcm_buf+st->channels*(frame_size-N2), N2, data+nb_compr_bytes, redundancy_bytes, NULL); if (err < 0) { RESTORE_STACK; return OPUS_INTERNAL_ERROR; } celt_encoder_ctl(celt_enc, OPUS_GET_FINAL_RANGE(&redundant_rng)); } /* Signalling the mode in the first byte */ data--; data[0] = gen_toc(st->mode, st->Fs/frame_size, curr_bandwidth, st->stream_channels); st->rangeFinal = enc.rng ^ redundant_rng; if (to_celt) st->prev_mode = MODE_CELT_ONLY; else st->prev_mode = st->mode; st->prev_channels = st->stream_channels; st->prev_framesize = frame_size; st->first = 0; /* DTX decision */ #ifndef DISABLE_FLOAT_API if (st->use_dtx && (analysis_info.valid || is_silence)) { if (decide_dtx_mode(analysis_info.activity_probability, &st->nb_no_activity_frames, st->peak_signal_energy, pcm, frame_size, st->channels, is_silence, st->arch)) { st->rangeFinal = 0; data[0] = gen_toc(st->mode, st->Fs/frame_size, curr_bandwidth, st->stream_channels); RESTORE_STACK; return 1; } } else { st->nb_no_activity_frames = 0; } #endif /* In the unlikely case that the SILK encoder busted its target, tell the decoder to call the PLC */ if (ec_tell(&enc) > (max_data_bytes-1)*8) { if (max_data_bytes < 2) { RESTORE_STACK; return OPUS_BUFFER_TOO_SMALL; } data[1] = 0; ret = 1; st->rangeFinal = 0; } else if (st->mode==MODE_SILK_ONLY&&!redundancy) { /*When in LPC only mode it's perfectly reasonable to strip off trailing zero bytes as the required range decoder behavior is to fill these in. This can't be done when the MDCT modes are used because the decoder needs to know the actual length for allocation purposes.*/ while(ret>2&&data[ret]==0)ret--; } /* Count ToC and redundancy */ ret += 1+redundancy_bytes; if (!st->use_vbr) { if (opus_packet_pad(data, ret, max_data_bytes) != OPUS_OK) { RESTORE_STACK; return OPUS_INTERNAL_ERROR; } ret = max_data_bytes; } RESTORE_STACK; return ret; } #ifdef FIXED_POINT #ifndef DISABLE_FLOAT_API opus_int32 opus_encode_float(OpusEncoder *st, const float *pcm, int analysis_frame_size, unsigned char *data, opus_int32 max_data_bytes) { int i, ret; int frame_size; VARDECL(opus_int16, in); ALLOC_STACK; frame_size = frame_size_select(analysis_frame_size, st->variable_duration, st->Fs); if (frame_size <= 0) { RESTORE_STACK; return OPUS_BAD_ARG; } ALLOC(in, frame_size*st->channels, opus_int16); for (i=0;ichannels;i++) in[i] = FLOAT2INT16(pcm[i]); ret = opus_encode_native(st, in, frame_size, data, max_data_bytes, 16, pcm, analysis_frame_size, 0, -2, st->channels, downmix_float, 1); RESTORE_STACK; return ret; } #endif opus_int32 opus_encode(OpusEncoder *st, const opus_int16 *pcm, int analysis_frame_size, unsigned char *data, opus_int32 out_data_bytes) { int frame_size; frame_size = frame_size_select(analysis_frame_size, st->variable_duration, st->Fs); return opus_encode_native(st, pcm, frame_size, data, out_data_bytes, 16, pcm, analysis_frame_size, 0, -2, st->channels, downmix_int, 0); } #else opus_int32 opus_encode(OpusEncoder *st, const opus_int16 *pcm, int analysis_frame_size, unsigned char *data, opus_int32 max_data_bytes) { int i, ret; int frame_size; VARDECL(float, in); ALLOC_STACK; frame_size = frame_size_select(analysis_frame_size, st->variable_duration, st->Fs); if (frame_size <= 0) { RESTORE_STACK; return OPUS_BAD_ARG; } ALLOC(in, frame_size*st->channels, float); for (i=0;ichannels;i++) in[i] = (1.0f/32768)*pcm[i]; ret = opus_encode_native(st, in, frame_size, data, max_data_bytes, 16, pcm, analysis_frame_size, 0, -2, st->channels, downmix_int, 0); RESTORE_STACK; return ret; } opus_int32 opus_encode_float(OpusEncoder *st, const float *pcm, int analysis_frame_size, unsigned char *data, opus_int32 out_data_bytes) { int frame_size; frame_size = frame_size_select(analysis_frame_size, st->variable_duration, st->Fs); return opus_encode_native(st, pcm, frame_size, data, out_data_bytes, 24, pcm, analysis_frame_size, 0, -2, st->channels, downmix_float, 1); } #endif int opus_encoder_ctl(OpusEncoder *st, int request, ...) { int ret; CELTEncoder *celt_enc; va_list ap; ret = OPUS_OK; va_start(ap, request); celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset); switch (request) { case OPUS_SET_APPLICATION_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); if ( (value != OPUS_APPLICATION_VOIP && value != OPUS_APPLICATION_AUDIO && value != OPUS_APPLICATION_RESTRICTED_LOWDELAY) || (!st->first && st->application != value)) { ret = OPUS_BAD_ARG; break; } st->application = value; #ifndef DISABLE_FLOAT_API st->analysis.application = value; #endif } break; case OPUS_GET_APPLICATION_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } *value = st->application; } break; case OPUS_SET_BITRATE_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); if (value != OPUS_AUTO && value != OPUS_BITRATE_MAX) { if (value <= 0) goto bad_arg; else if (value <= 500) value = 500; else if (value > (opus_int32)300000*st->channels) value = (opus_int32)300000*st->channels; } st->user_bitrate_bps = value; } break; case OPUS_GET_BITRATE_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } *value = user_bitrate_to_bitrate(st, st->prev_framesize, 1276); } break; case OPUS_SET_FORCE_CHANNELS_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); if((value<1 || value>st->channels) && value != OPUS_AUTO) { goto bad_arg; } st->force_channels = value; } break; case OPUS_GET_FORCE_CHANNELS_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } *value = st->force_channels; } break; case OPUS_SET_MAX_BANDWIDTH_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); if (value < OPUS_BANDWIDTH_NARROWBAND || value > OPUS_BANDWIDTH_FULLBAND) { goto bad_arg; } st->max_bandwidth = value; if (st->max_bandwidth == OPUS_BANDWIDTH_NARROWBAND) { st->silk_mode.maxInternalSampleRate = 8000; } else if (st->max_bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) { st->silk_mode.maxInternalSampleRate = 12000; } else { st->silk_mode.maxInternalSampleRate = 16000; } } break; case OPUS_GET_MAX_BANDWIDTH_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } *value = st->max_bandwidth; } break; case OPUS_SET_BANDWIDTH_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); if ((value < OPUS_BANDWIDTH_NARROWBAND || value > OPUS_BANDWIDTH_FULLBAND) && value != OPUS_AUTO) { goto bad_arg; } st->user_bandwidth = value; if (st->user_bandwidth == OPUS_BANDWIDTH_NARROWBAND) { st->silk_mode.maxInternalSampleRate = 8000; } else if (st->user_bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) { st->silk_mode.maxInternalSampleRate = 12000; } else { st->silk_mode.maxInternalSampleRate = 16000; } } break; case OPUS_GET_BANDWIDTH_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } *value = st->bandwidth; } break; case OPUS_SET_DTX_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); if(value<0 || value>1) { goto bad_arg; } st->use_dtx = value; } break; case OPUS_GET_DTX_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } *value = st->use_dtx; } break; case OPUS_SET_COMPLEXITY_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); if(value<0 || value>10) { goto bad_arg; } st->silk_mode.complexity = value; celt_encoder_ctl(celt_enc, OPUS_SET_COMPLEXITY(value)); } break; case OPUS_GET_COMPLEXITY_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } *value = st->silk_mode.complexity; } break; case OPUS_SET_INBAND_FEC_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); if(value<0 || value>1) { goto bad_arg; } st->silk_mode.useInBandFEC = value; } break; case OPUS_GET_INBAND_FEC_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } *value = st->silk_mode.useInBandFEC; } break; case OPUS_SET_PACKET_LOSS_PERC_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); if (value < 0 || value > 100) { goto bad_arg; } st->silk_mode.packetLossPercentage = value; celt_encoder_ctl(celt_enc, OPUS_SET_PACKET_LOSS_PERC(value)); } break; case OPUS_GET_PACKET_LOSS_PERC_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } *value = st->silk_mode.packetLossPercentage; } break; case OPUS_SET_VBR_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); if(value<0 || value>1) { goto bad_arg; } st->use_vbr = value; st->silk_mode.useCBR = 1-value; } break; case OPUS_GET_VBR_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } *value = st->use_vbr; } break; case OPUS_SET_VOICE_RATIO_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); if (value<-1 || value>100) { goto bad_arg; } st->voice_ratio = value; } break; case OPUS_GET_VOICE_RATIO_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } *value = st->voice_ratio; } break; case OPUS_SET_VBR_CONSTRAINT_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); if(value<0 || value>1) { goto bad_arg; } st->vbr_constraint = value; } break; case OPUS_GET_VBR_CONSTRAINT_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } *value = st->vbr_constraint; } break; case OPUS_SET_SIGNAL_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); if(value!=OPUS_AUTO && value!=OPUS_SIGNAL_VOICE && value!=OPUS_SIGNAL_MUSIC) { goto bad_arg; } st->signal_type = value; } break; case OPUS_GET_SIGNAL_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } *value = st->signal_type; } break; case OPUS_GET_LOOKAHEAD_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } *value = st->Fs/400; if (st->application != OPUS_APPLICATION_RESTRICTED_LOWDELAY) *value += st->delay_compensation; } break; case OPUS_GET_SAMPLE_RATE_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } *value = st->Fs; } break; case OPUS_GET_FINAL_RANGE_REQUEST: { opus_uint32 *value = va_arg(ap, opus_uint32*); if (!value) { goto bad_arg; } *value = st->rangeFinal; } break; case OPUS_SET_LSB_DEPTH_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); if (value<8 || value>24) { goto bad_arg; } st->lsb_depth=value; } break; case OPUS_GET_LSB_DEPTH_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } *value = st->lsb_depth; } break; case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); if (value != OPUS_FRAMESIZE_ARG && value != OPUS_FRAMESIZE_2_5_MS && value != OPUS_FRAMESIZE_5_MS && value != OPUS_FRAMESIZE_10_MS && value != OPUS_FRAMESIZE_20_MS && value != OPUS_FRAMESIZE_40_MS && value != OPUS_FRAMESIZE_60_MS && value != OPUS_FRAMESIZE_80_MS && value != OPUS_FRAMESIZE_100_MS && value != OPUS_FRAMESIZE_120_MS) { goto bad_arg; } st->variable_duration = value; } break; case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } *value = st->variable_duration; } break; case OPUS_SET_PREDICTION_DISABLED_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); if (value > 1 || value < 0) goto bad_arg; st->silk_mode.reducedDependency = value; } break; case OPUS_GET_PREDICTION_DISABLED_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) goto bad_arg; *value = st->silk_mode.reducedDependency; } break; case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); if(value<0 || value>1) { goto bad_arg; } celt_encoder_ctl(celt_enc, OPUS_SET_PHASE_INVERSION_DISABLED(value)); } break; case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } celt_encoder_ctl(celt_enc, OPUS_GET_PHASE_INVERSION_DISABLED(value)); } break; case OPUS_RESET_STATE: { void *silk_enc; silk_EncControlStruct dummy; char *start; silk_enc = (char*)st+st->silk_enc_offset; #ifndef DISABLE_FLOAT_API tonality_analysis_reset(&st->analysis); #endif start = (char*)&st->OPUS_ENCODER_RESET_START; OPUS_CLEAR(start, sizeof(OpusEncoder) - (start - (char*)st)); celt_encoder_ctl(celt_enc, OPUS_RESET_STATE); silk_InitEncoder( silk_enc, st->arch, &dummy ); st->stream_channels = st->channels; st->hybrid_stereo_width_Q14 = 1 << 14; st->prev_HB_gain = Q15ONE; st->first = 1; st->mode = MODE_HYBRID; st->bandwidth = OPUS_BANDWIDTH_FULLBAND; st->variable_HP_smth2_Q15 = silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 ); } break; case OPUS_SET_FORCE_MODE_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); if ((value < MODE_SILK_ONLY || value > MODE_CELT_ONLY) && value != OPUS_AUTO) { goto bad_arg; } st->user_forced_mode = value; } break; case OPUS_SET_LFE_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); st->lfe = value; ret = celt_encoder_ctl(celt_enc, OPUS_SET_LFE(value)); } break; case OPUS_SET_ENERGY_MASK_REQUEST: { opus_val16 *value = va_arg(ap, opus_val16*); st->energy_masking = value; ret = celt_encoder_ctl(celt_enc, OPUS_SET_ENERGY_MASK(value)); } break; case OPUS_GET_IN_DTX_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } if (st->silk_mode.useDTX && (st->prev_mode == MODE_SILK_ONLY || st->prev_mode == MODE_HYBRID)) { /* DTX determined by Silk. */ int n; void *silk_enc = (char*)st+st->silk_enc_offset; *value = 1; for (n=0;nsilk_mode.nChannelsInternal;n++) { *value = *value && ((silk_encoder*)silk_enc)->state_Fxx[n].sCmn.noSpeechCounter >= NB_SPEECH_FRAMES_BEFORE_DTX; } } #ifndef DISABLE_FLOAT_API else if (st->use_dtx) { /* DTX determined by Opus. */ *value = st->nb_no_activity_frames >= NB_SPEECH_FRAMES_BEFORE_DTX; } #endif else { *value = 0; } } break; case CELT_GET_MODE_REQUEST: { const CELTMode ** value = va_arg(ap, const CELTMode**); if (!value) { goto bad_arg; } ret = celt_encoder_ctl(celt_enc, CELT_GET_MODE(value)); } break; default: /* fprintf(stderr, "unknown opus_encoder_ctl() request: %d", request);*/ ret = OPUS_UNIMPLEMENTED; break; } va_end(ap); return ret; bad_arg: va_end(ap); return OPUS_BAD_ARG; } void opus_encoder_destroy(OpusEncoder *st) { opus_free(st); } jamulus-3.9.1+dfsg/libs/opus/src/mapping_matrix.h0000644000175000017500000000766314340334543021066 0ustar vimervimer/* Copyright (c) 2017 Google Inc. Written by Andrew Allen */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @file mapping_matrix.h * @brief Opus reference implementation mapping matrix API */ #ifndef MAPPING_MATRIX_H #define MAPPING_MATRIX_H #include "opus_types.h" #include "opus_projection.h" #ifdef __cplusplus extern "C" { #endif typedef struct MappingMatrix { int rows; /* number of channels outputted from matrix. */ int cols; /* number of channels inputted to matrix. */ int gain; /* in dB. S7.8-format. */ /* Matrix cell data goes here using col-wise ordering. */ } MappingMatrix; opus_int32 mapping_matrix_get_size(int rows, int cols); opus_int16 *mapping_matrix_get_data(const MappingMatrix *matrix); void mapping_matrix_init( MappingMatrix * const matrix, int rows, int cols, int gain, const opus_int16 *data, opus_int32 data_size ); #ifndef DISABLE_FLOAT_API void mapping_matrix_multiply_channel_in_float( const MappingMatrix *matrix, const float *input, int input_rows, opus_val16 *output, int output_row, int output_rows, int frame_size ); void mapping_matrix_multiply_channel_out_float( const MappingMatrix *matrix, const opus_val16 *input, int input_row, int input_rows, float *output, int output_rows, int frame_size ); #endif /* DISABLE_FLOAT_API */ void mapping_matrix_multiply_channel_in_short( const MappingMatrix *matrix, const opus_int16 *input, int input_rows, opus_val16 *output, int output_row, int output_rows, int frame_size ); void mapping_matrix_multiply_channel_out_short( const MappingMatrix *matrix, const opus_val16 *input, int input_row, int input_rows, opus_int16 *output, int output_rows, int frame_size ); /* Pre-computed mixing and demixing matrices for 1st to 3rd-order ambisonics. * foa: first-order ambisonics * soa: second-order ambisonics * toa: third-order ambisonics */ extern const MappingMatrix mapping_matrix_foa_mixing; extern const opus_int16 mapping_matrix_foa_mixing_data[36]; extern const MappingMatrix mapping_matrix_soa_mixing; extern const opus_int16 mapping_matrix_soa_mixing_data[121]; extern const MappingMatrix mapping_matrix_toa_mixing; extern const opus_int16 mapping_matrix_toa_mixing_data[324]; extern const MappingMatrix mapping_matrix_foa_demixing; extern const opus_int16 mapping_matrix_foa_demixing_data[36]; extern const MappingMatrix mapping_matrix_soa_demixing; extern const opus_int16 mapping_matrix_soa_demixing_data[121]; extern const MappingMatrix mapping_matrix_toa_demixing; extern const opus_int16 mapping_matrix_toa_demixing_data[324]; #ifdef __cplusplus } #endif #endif /* MAPPING_MATRIX_H */ jamulus-3.9.1+dfsg/libs/opus/src/opus_multistream.c0000644000175000017500000000517414340334543021451 0ustar vimervimer/* Copyright (c) 2011 Xiph.Org Foundation Written by Jean-Marc Valin */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "opus_multistream.h" #include "opus.h" #include "opus_private.h" #include "stack_alloc.h" #include #include "float_cast.h" #include "os_support.h" int validate_layout(const ChannelLayout *layout) { int i, max_channel; max_channel = layout->nb_streams+layout->nb_coupled_streams; if (max_channel>255) return 0; for (i=0;inb_channels;i++) { if (layout->mapping[i] >= max_channel && layout->mapping[i] != 255) return 0; } return 1; } int get_left_channel(const ChannelLayout *layout, int stream_id, int prev) { int i; i = (prev<0) ? 0 : prev+1; for (;inb_channels;i++) { if (layout->mapping[i]==stream_id*2) return i; } return -1; } int get_right_channel(const ChannelLayout *layout, int stream_id, int prev) { int i; i = (prev<0) ? 0 : prev+1; for (;inb_channels;i++) { if (layout->mapping[i]==stream_id*2+1) return i; } return -1; } int get_mono_channel(const ChannelLayout *layout, int stream_id, int prev) { int i; i = (prev<0) ? 0 : prev+1; for (;inb_channels;i++) { if (layout->mapping[i]==stream_id+layout->nb_coupled_streams) return i; } return -1; } jamulus-3.9.1+dfsg/libs/opus/src/opus_multistream_decoder.c0000644000175000017500000003517214340334543023137 0ustar vimervimer/* Copyright (c) 2011 Xiph.Org Foundation Written by Jean-Marc Valin */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "opus_multistream.h" #include "opus.h" #include "opus_private.h" #include "stack_alloc.h" #include #include "float_cast.h" #include "os_support.h" /* DECODER */ #if defined(ENABLE_HARDENING) || defined(ENABLE_ASSERTIONS) static void validate_ms_decoder(OpusMSDecoder *st) { validate_layout(&st->layout); } #define VALIDATE_MS_DECODER(st) validate_ms_decoder(st) #else #define VALIDATE_MS_DECODER(st) #endif opus_int32 opus_multistream_decoder_get_size(int nb_streams, int nb_coupled_streams) { int coupled_size; int mono_size; if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0; coupled_size = opus_decoder_get_size(2); mono_size = opus_decoder_get_size(1); return align(sizeof(OpusMSDecoder)) + nb_coupled_streams * align(coupled_size) + (nb_streams-nb_coupled_streams) * align(mono_size); } int opus_multistream_decoder_init( OpusMSDecoder *st, opus_int32 Fs, int channels, int streams, int coupled_streams, const unsigned char *mapping ) { int coupled_size; int mono_size; int i, ret; char *ptr; if ((channels>255) || (channels<1) || (coupled_streams>streams) || (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams)) return OPUS_BAD_ARG; st->layout.nb_channels = channels; st->layout.nb_streams = streams; st->layout.nb_coupled_streams = coupled_streams; for (i=0;ilayout.nb_channels;i++) st->layout.mapping[i] = mapping[i]; if (!validate_layout(&st->layout)) return OPUS_BAD_ARG; ptr = (char*)st + align(sizeof(OpusMSDecoder)); coupled_size = opus_decoder_get_size(2); mono_size = opus_decoder_get_size(1); for (i=0;ilayout.nb_coupled_streams;i++) { ret=opus_decoder_init((OpusDecoder*)ptr, Fs, 2); if(ret!=OPUS_OK)return ret; ptr += align(coupled_size); } for (;ilayout.nb_streams;i++) { ret=opus_decoder_init((OpusDecoder*)ptr, Fs, 1); if(ret!=OPUS_OK)return ret; ptr += align(mono_size); } return OPUS_OK; } OpusMSDecoder *opus_multistream_decoder_create( opus_int32 Fs, int channels, int streams, int coupled_streams, const unsigned char *mapping, int *error ) { int ret; OpusMSDecoder *st; if ((channels>255) || (channels<1) || (coupled_streams>streams) || (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams)) { if (error) *error = OPUS_BAD_ARG; return NULL; } st = (OpusMSDecoder *)opus_alloc(opus_multistream_decoder_get_size(streams, coupled_streams)); if (st==NULL) { if (error) *error = OPUS_ALLOC_FAIL; return NULL; } ret = opus_multistream_decoder_init(st, Fs, channels, streams, coupled_streams, mapping); if (error) *error = ret; if (ret != OPUS_OK) { opus_free(st); st = NULL; } return st; } static int opus_multistream_packet_validate(const unsigned char *data, opus_int32 len, int nb_streams, opus_int32 Fs) { int s; int count; unsigned char toc; opus_int16 size[48]; int samples=0; opus_int32 packet_offset; for (s=0;slayout.nb_streams-1) { RESTORE_STACK; return OPUS_INVALID_PACKET; } if (!do_plc) { int ret = opus_multistream_packet_validate(data, len, st->layout.nb_streams, Fs); if (ret < 0) { RESTORE_STACK; return ret; } else if (ret > frame_size) { RESTORE_STACK; return OPUS_BUFFER_TOO_SMALL; } } for (s=0;slayout.nb_streams;s++) { OpusDecoder *dec; opus_int32 packet_offset; int ret; dec = (OpusDecoder*)ptr; ptr += (s < st->layout.nb_coupled_streams) ? align(coupled_size) : align(mono_size); if (!do_plc && len<=0) { RESTORE_STACK; return OPUS_INTERNAL_ERROR; } packet_offset = 0; ret = opus_decode_native(dec, data, len, buf, frame_size, decode_fec, s!=st->layout.nb_streams-1, &packet_offset, soft_clip); data += packet_offset; len -= packet_offset; if (ret <= 0) { RESTORE_STACK; return ret; } frame_size = ret; if (s < st->layout.nb_coupled_streams) { int chan, prev; prev = -1; /* Copy "left" audio to the channel(s) where it belongs */ while ( (chan = get_left_channel(&st->layout, s, prev)) != -1) { (*copy_channel_out)(pcm, st->layout.nb_channels, chan, buf, 2, frame_size, user_data); prev = chan; } prev = -1; /* Copy "right" audio to the channel(s) where it belongs */ while ( (chan = get_right_channel(&st->layout, s, prev)) != -1) { (*copy_channel_out)(pcm, st->layout.nb_channels, chan, buf+1, 2, frame_size, user_data); prev = chan; } } else { int chan, prev; prev = -1; /* Copy audio to the channel(s) where it belongs */ while ( (chan = get_mono_channel(&st->layout, s, prev)) != -1) { (*copy_channel_out)(pcm, st->layout.nb_channels, chan, buf, 1, frame_size, user_data); prev = chan; } } } /* Handle muted channels */ for (c=0;clayout.nb_channels;c++) { if (st->layout.mapping[c] == 255) { (*copy_channel_out)(pcm, st->layout.nb_channels, c, NULL, 0, frame_size, user_data); } } RESTORE_STACK; return frame_size; } #if !defined(DISABLE_FLOAT_API) static void opus_copy_channel_out_float( void *dst, int dst_stride, int dst_channel, const opus_val16 *src, int src_stride, int frame_size, void *user_data ) { float *float_dst; opus_int32 i; (void)user_data; float_dst = (float*)dst; if (src != NULL) { for (i=0;ilayout.nb_streams;s++) { OpusDecoder *dec; dec = (OpusDecoder*)ptr; if (s < st->layout.nb_coupled_streams) ptr += align(coupled_size); else ptr += align(mono_size); ret = opus_decoder_ctl(dec, request, &tmp); if (ret != OPUS_OK) break; *value ^= tmp; } } break; case OPUS_RESET_STATE: { int s; for (s=0;slayout.nb_streams;s++) { OpusDecoder *dec; dec = (OpusDecoder*)ptr; if (s < st->layout.nb_coupled_streams) ptr += align(coupled_size); else ptr += align(mono_size); ret = opus_decoder_ctl(dec, OPUS_RESET_STATE); if (ret != OPUS_OK) break; } } break; case OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST: { int s; opus_int32 stream_id; OpusDecoder **value; stream_id = va_arg(ap, opus_int32); if (stream_id<0 || stream_id >= st->layout.nb_streams) goto bad_arg; value = va_arg(ap, OpusDecoder**); if (!value) { goto bad_arg; } for (s=0;slayout.nb_coupled_streams) ptr += align(coupled_size); else ptr += align(mono_size); } *value = (OpusDecoder*)ptr; } break; case OPUS_SET_GAIN_REQUEST: case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST: { int s; /* This works for int32 params */ opus_int32 value = va_arg(ap, opus_int32); for (s=0;slayout.nb_streams;s++) { OpusDecoder *dec; dec = (OpusDecoder*)ptr; if (s < st->layout.nb_coupled_streams) ptr += align(coupled_size); else ptr += align(mono_size); ret = opus_decoder_ctl(dec, request, value); if (ret != OPUS_OK) break; } } break; default: ret = OPUS_UNIMPLEMENTED; break; } return ret; bad_arg: return OPUS_BAD_ARG; } int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...) { int ret; va_list ap; va_start(ap, request); ret = opus_multistream_decoder_ctl_va_list(st, request, ap); va_end(ap); return ret; } void opus_multistream_decoder_destroy(OpusMSDecoder *st) { opus_free(st); } jamulus-3.9.1+dfsg/libs/opus/src/mlp_data.c0000644000175000017500000005704114340334543017616 0ustar vimervimer/*This file is automatically generated from a Keras model*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "mlp.h" static const opus_int8 layer0_weights[800] = { -30, -9, 2, -12, 5, -1, 8, 9, 9, 8, -13, 18, -17, -34, -5, 17, -11, 0, -4, 10, 2, 10, 15, -8, 2, -1, 0, 5, 13, -3, -16, 1, -5, 3, 7, -28, -13, 6, 36, -3, 19, -60, -17, -28, 7, -11, -30, -7, 2, -42, -21, -3, 6, -22, 33, -9, 7, -30, 21, -14, 24, -11, -20, -18, -5, -12, 12, -49, -50, -49, 16, 9, -37, -1, 9, 34, -13, -31, -31, 12, 16, 44, -42, 2, -9, 8, -18, -6, 9, 36, 19, 11, 13, 12, -21, 3, -28, -12, 3, 33, 25, -14, 11, 1, -94, -39, 18, -12, -11, -15, -7, 49, 52, 10, -43, 9, 57, 8, 21, -6, 14, -15, 44, -8, 7, -30, -13, -2, -9, 25, -2, -127, 18, -11, -52, 26, -27, 27, 10, -10, 7, 43, 6, -24, 41, 10, -18, -27, 10, 17, 9, 10, -17, -10, 20, -6, 22, 55, 35, -80, 36, 25, -24, -36, 15, 9, -19, 88, 19, 64, -51, -35, 17, 0, -7, 41, -16, 27, 4, 15, -1, 18, -16, 47, -39, -54, -8, 13, -25, -20, 102, -18, -5, 44, 11, -28, 71, 2, -51, -5, 5, 2, -83, -9, -29, 8, 21, -53, 58, -37, -7, 13, 38, 9, 34, -1, -41, 21, 4, -24, -36, -33, -21, 32, 75, -2, 1, -68, -1, 47, -29, 32, 20, 12, -65, -87, 5, 16, -12, 24, 40, 15, 7, 19, -26, -17, 17, 6, -2, -37, -30, -9, 32, -127, -39, 0, -31, -27, 4, -22, 23, -6, -77, 35, -61, 32, -37, -24, 13, -11, -1, -40, -3, 17, -7, 13, 11, 59, -19, 10, 6, -18, 0, 13, 3, -6, -23, 19, 11, -17, 13, -1, -80, 40, -53, 69, -29, -54, 0, -4, 33, -25, -2, 38, 35, 36, -15, 46, 2, -13, -16, -8, -8, 12, -24, -9, -55, -5, -9, 32, 11, 7, 12, -18, -10, -86, -38, 54, 37, -25, 18, -43, 7, -27, -27, -54, 13, 9, 22, 70, 6, 35, -7, 23, -15, -44, -6, 7, -66, -85, 32, 40, -19, -9, -7, 12, -15, 7, 2, 6, -35, 11, 28, 0, 26, 14, 1, 1, 4, 12, 18, 35, 22, -18, -3, 14, -1, 7, 14, -8, -14, -3, 4, -3, -19, -7, -1, -25, -27, 25, -26, -2, 33, -22, -27, -25, 4, -9, 7, 21, 26, -30, 10, -9, -20, 11, 27, 10, 5, -18, 14, -4, 2, -17, -5, -7, -9, -13, 15, 29, 1, -10, -16, -10, 35, 36, -7, -22, -44, 17, 30, 22, 21, -1, 22, -11, 32, -8, -7, 5, -10, 5, 30, -20, 29, -20, -34, 12, -4, -6, 6, -13, 10, -5, -68, -1, 24, 9, 19, -24, -64, 31, 19, 27, -26, 75, -45, 41, 39, -42, 8, 6, 23, -30, 16, -25, 30, 34, 8, -38, -3, 18, 16, -31, 22, -4, -9, 1, 20, 9, 38, -32, 0, -45, 0, -6, -13, 11, -25, -32, -22, 31, -24, -11, -11, -4, -4, 20, -34, 22, 20, 9, -25, 27, -5, 28, -29, 29, 6, 21, -6, -18, 54, 4, -46, 23, 21, -14, -31, 36, -41, -24, 4, 22, 10, 11, 7, 36, -32, -13, -52, -17, 24, 28, -37, -36, -1, 24, 9, -38, 35, 48, 18, 2, -1, 45, 10, 39, 24, -38, 13, 8, -16, 8, 25, 11, 7, -29, -11, 7, 20, -30, -38, -45, 14, -18, -28, -9, 65, 61, 22, -53, -38, -16, 36, 46, 20, -39, 32, -61, -6, -6, -36, -33, -18, -28, 56, 101, 45, 11, -28, -23, -29, -61, 20, -47, 2, 48, 27, -17, 1, 40, 1, 3, -51, 15, 35, 28, 22, 35, 53, -61, -29, 12, -6, -21, 10, 3, -20, 2, -25, 1, -6, 31, 11, -3, 1, -10, -52, 6, 126, -105, 122, 127, -128, 127, 127, -128, 127, 108, 12, 127, 48, -128, -36, -128, 127, 127, -128, -128, 127, 89, -128, 127, -128, -128, -128, 127, 127, -128, -128, -93, -82, 20, 125, 65, -82, 127, 38, -74, 81, 88, -88, 79, 51, -47, -111, -26, 14, 83, -88, -112, 24, 35, -101, 98, -99, -48, -45, 46, 83, -60, -79, 45, -20, -41, 9, 4, 52, 54, 93, -10, 4, 13, 3, 123, 6, 94, -111, -69, -14, -31, 10, 12, 53, -79, -11, -21, -2, -44, -72, 92, 65, -57, 56, -38, 127, -56, -128, 127, 127, -128, 86, 117, -75, -128, 127, -19, -99, -112, 127, -128, 127, -48, 114, 118, -128, -128, 117, -17, -6, 121, -128, 127, -128, 82, 54, -106, 127, 127, -33, 100, -39, -23, 18, -78, -34, -29, -1, -30, 127, -26, 127, -128, 126, -128, 27, -23, -79, -120, -127, 127, 72, 66, 29, 7, -66, -56, -117, -128 }; static const opus_int8 layer0_bias[32] = { 51, -16, 1, 13, -5, -6, -16, -7, 11, -6, 106, 26, 28, -14, 21, -29, 7, 18, -18, -17, 21, -17, -9, 20, -25, -3, -34, 48, 11, -13, -31, -20 }; static const opus_int8 layer1_weights[2304] = { 22, -1, -7, 7, 29, -27, -31, -17, -13, 33, 44, -8, 11, 33, 24, 78, 15, 19, 30, -2, -24, 5, 49, 5, 36, 29, -14, -11, -48, -33, 21, -42, -38, -12, 55, -37, 54, -8, 1, 36, 17, 0, 51, 31, 59, 7, -12, 53, 4, 32, -14, 48, 5, -10, -16, -8, 1, -16, -56, -24, -6, 18, -2, 23, 6, 46, -6, -10, 20, 35, -44, -15, -49, 36, 16, 5, -7, -79, -67, 12, 70, -3, -79, -54, -85, -24, 47, -22, 33, 21, 69, -1, 11, 22, 14, -16, -16, -22, -28, -11, 11, -41, 31, -26, -33, -19, -4, 27, 32, -50, 5, -10, -38, -22, -8, 35, -31, 1, -41, -15, -11, 44, 28, -17, -41, -23, 17, 2, -23, -26, -13, -13, -17, 6, 14, -31, -25, 9, -19, 39, -8, 4, 31, -1, -45, -11, -28, -92, -46, -15, 21, 118, -22, 45, -51, 11, -20, -20, -15, 13, -21, -97, -29, -32, -23, -42, 94, 1, 23, -8, 63, -3, -46, 19, -26, 32, -40, -74, -26, 26, -4, -13, 30, -20, -30, -25, -14, -31, -45, -43, 4, -60, -48, -12, -34, 2, 2, 3, 13, 15, 11, 16, 5, 46, -9, -55, -16, -57, 29, 14, 38, -50, -2, -44, -11, -8, 52, -27, -38, -7, 20, 47, 17, -59, 0, 47, 46, -63, 35, -17, 19, 33, 68, -19, 2, 15, -16, 28, -16, -103, 26, -35, 47, -39, -60, 30, 31, -23, -52, -13, 116, 47, -25, 30, 40, 30, -22, 2, 12, -27, -18, 31, -10, 27, -8, -66, 12, 14, 4, -26, -28, -13, 3, 13, -26, -51, 37, 5, 2, -21, 47, 3, 13, 25, -41, -27, -8, -4, 5, -76, -33, 28, 10, 9, -46, -74, 19, 28, 25, 31, 54, -55, 68, 38, -24, -32, 2, 4, 68, 11, -1, 99, 5, 16, -2, -74, 40, 26, -26, 33, 31, -1, -68, 14, -6, 25, 9, 29, 60, 61, 7, -7, 0, -24, 7, 77, 4, -1, 16, -7, 13, -15, -19, 28, -31, -24, -16, 37, 24, 13, 30, 10, -30, 11, 11, -10, 22, 60, 28, 45, -3, -40, -62, -5, -102, 9, -32, -27, -54, 21, 15, -5, 37, -43, -11, 37, -19, 47, -64, -128, -27, -114, 21, -66, 59, 46, -3, -12, -87, -9, 4, 19, -113, -36, 78, 57, -26, -38, -77, -10, 6, 6, -75, 25, -97, -11, 33, -46, 1, 13, -21, -33, -20, 16, -6, -3, -11, -4, -27, 38, 8, -41, -2, -33, 18, 19, -26, 1, -29, -22, -4, -14, -55, -11, -80, -3, 11, 34, 90, 51, 11, 17, 43, 36, 127, -32, 29, 103, 9, 27, 13, 64, 56, 70, -14, 3, -12, 10, 37, 3, 12, -22, -10, 46, 28, 10, 20, 26, -24, 18, 9, 7, 14, 34, -5, -7, 31, -14, -56, 11, -18, -8, -17, -7, -10, -40, 10, -33, -32, -43, 5, 9, 11, -4, 10, 50, -12, -5, 46, 9, 7, 1, 11, 15, 91, -17, 7, -50, 23, 6, -30, -99, 0, -17, 14, 8, -10, -25, -30, -69, -62, 31, 127, 114, -23, 101, -5, -54, -6, -22, 7, -56, 39, 18, -29, 0, 46, 8, -79, 4, -21, 18, -32, 62, -12, -8, -12, -58, 31, -32, 17, 6, -24, 25, 24, 9, -4, -19, 45, 6, 17, -14, 5, -27, 16, -4, -41, 25, -36, 5, 15, 12, 50, 27, 25, 23, -44, -69, -9, -19, -48, -8, 4, 12, -6, 13, -19, -30, -36, 26, 37, -1, -3, -30, -42, -14, -10, -20, 26, -54, -27, -44, 4, 73, -26, 90, 32, -69, -29, -16, 3, 103, 15, -17, 37, 24, -23, -31, 33, -37, -64, 25, 13, -81, -28, -32, 27, 5, -35, -23, 15, -22, 19, -7, 9, 30, 19, -23, 27, -13, 43, 29, -29, -6, 9, -40, -33, -33, -32, 9, 11, -48, -8, -23, -52, 46, 17, -22, -42, 35, -15, -41, 16, 34, 31, -42, -19, -11, 55, 7, -39, 89, -11, -33, 20, -14, 22, 32, 3, -17, -6, 14, 34, 1, 55, -21, -90, -8, 18, 27, 13, -29, 21, 15, -33, -51, -9, -11, 4, -16, -18, 23, -4, -4, 48, 1, 7, 29, -14, -12, -16, 17, 35, 8, 0, -7, -2, 9, 8, 17, -6, 53, -32, -21, -50, 5, 99, -60, -5, -53, 10, -31, 12, -5, 7, 80, 36, 18, -31, 9, 98, 36, -63, -35, 4, -13, -28, -24, 28, -13, 18, 16, -1, -18, -34, 10, 20, 7, 4, 29, 11, 25, -7, 36, 14, 45, 24, 1, -16, 30, 6, 35, -6, -11, -24, 13, -1, 27, 39, 20, 48, -11, -4, -13, 28, 11, -31, -18, 31, -29, 22, -2, -20, -16, 5, 30, -12, -28, -3, 93, -16, 23, 18, -29, 6, -54, -37, 28, -3, -3, -47, -3, -36, -55, -3, 41, -10, 47, -2, 23, 42, -7, -71, -27, 83, -64, 7, -24, 8, 26, -17, 15, 12, 31, -30, -38, -13, -33, -56, 4, -17, 20, 18, 1, -30, -5, -6, -31, -14, -37, 0, 22, 10, -30, 37, -17, 18, 6, 5, 23, -36, -32, 14, 18, -13, -61, -52, -69, 44, -30, 16, 18, -4, -25, 14, 81, 26, -8, -23, -59, 52, -104, 17, 119, -32, 26, 17, 1, 23, 45, 29, -64, -57, -14, 73, 21, -13, -13, 9, -68, -7, -52, 3, 24, -39, 44, -15, 27, 14, 19, -9, -28, -11, 5, 3, -34, -2, 2, 22, -6, -23, 4, 3, 13, -22, -13, -10, -18, 29, 6, 44, -13, -24, -8, 2, 30, 14, 43, 6, 17, -73, -6, -7, 20, -80, -7, -7, -28, 15, -69, -38, -5, -100, -35, 15, -79, 23, 29, -18, -27, 21, -66, -37, 8, -22, -39, 48, 4, -13, 1, -9, 11, -29, 22, 6, -49, 32, -14, 47, -18, -4, 44, -52, -74, 43, 30, 23, -14, 5, 0, -27, 4, -7, 10, -4, 10, 1, -16, 11, -18, -2, -5, 2, -11, 0, -20, -4, 38, 74, 59, 39, 64, -10, 26, -3, -40, -68, 3, -30, -51, 8, -19, -27, -46, 51, 52, 54, 36, 90, 92, 14, 13, -5, 0, 16, -62, 16, 11, -47, -37, -6, -5, 21, 54, -57, 32, 42, -6, 62, -9, 16, 21, 24, 9, -10, -4, 33, 50, 13, -15, 1, -35, -48, 18, -11, -17, -67, -13, 21, 38, -44, 36, -16, 29, 17, 5, -10, 18, 17, -32, 2, 8, 22, -56, -15, -32, 40, 43, 19, 46, -7, -100, -96, 19, 53, 24, 21, -26, -48, -101, -82, 61, 38, -85, -28, -34, -1, 63, -5, -5, 39, 39, -38, 32, -12, -28, 20, 40, -8, 2, 31, 12, -35, -13, 20, -25, 30, 8, 3, -13, -9, -20, 2, -13, 24, 37, -10, 33, 6, 20, -16, -24, -6, -6, -19, -5, 22, 21, 10, 11, -4, -39, -1, 6, 49, 41, -15, -57, 21, -62, 77, -69, -13, 0, -74, 1, -7, -38, -8, 6, 63, 28, 4, 26, -52, 82, 63, 13, 45, -33, 44, -52, -65, -21, -46, -49, 64, -17, 32, 24, 68, -39, -16, -5, -26, 28, 5, -61, -28, 2, 24, 11, -12, -33, 9, -37, -3, -28, 22, -37, -12, 19, 0, -18, -2, 14, 1, 4, 8, -9, -2, 43, -17, -2, -66, -31, 56, -40, -87, -36, -2, -4, -42, -45, -1, 31, -43, -15, 27, 63, -11, 32, -10, -33, 27, -19, 4, 15, -26, -34, 29, -4, -39, -65, 14, -20, -21, -17, -36, 13, 59, 47, -38, -33, 13, -37, -8, -37, -7, -6, -76, -31, -12, -46, 7, 24, -21, -30, -14, 9, 15, -12, -13, 47, -27, -25, -1, -39, 0, 20, -9, 6, 7, 4, 3, 7, 39, 50, 22, -7, 14, -20, 1, 70, -28, 29, -41, 10, -16, -5, -28, -2, -37, 32, -18, 17, 62, -11, -20, -50, 36, 21, -62, -12, -56, 52, 50, 17, 3, 48, 44, -41, -25, 3, 16, -3, 0, 33, -6, 15, 27, 34, -25, 22, 9, 17, -11, 36, 16, -2, 12, 21, -52, 45, -2, -10, 46, 21, -18, 67, -28, -13, 30, 37, 42, 16, -9, 11, 75, 7, -64, -40, -10, 29, 57, -23, 5, 53, -77, 3, -17, -5, 47, -55, -35, -36, -13, 52, -53, -71, 52, -111, -23, -26, -28, 29, -43, 55, -19, 43, -19, 54, -12, -33, -44, -39, -19, -10, -31, -10, 21, 38, -57, -20, 2, -25, 8, -6, 50, 12, 15, 25, -25, 15, -30, -6, 9, 25, 37, 19, -4, 31, -22, 2, 4, 2, 36, 7, 3, -34, -80, 36, -10, -2, -5, 31, -36, 49, -70, 20, -36, 21, 24, 25, -46, -51, 36, -58, -48, -40, -10, 55, 71, 47, 10, -1, 1, 2, -46, -68, 16, 13, 0, -74, -29, 73, -52, -18, -11, 7, -44, -82, -32, -70, -28, -1, -39, -68, -6, -41, 12, -22, -16, 40, -11, -25, 51, -9, 21, 4, 4, -34, 7, -78, 16, 6, -38, -30, -2, -44, 32, 0, 22, 64, 5, -72, -2, -14, -10, -16, -8, -25, 12, 102, -58, 37, -10, -23, 15, 49, 7, -7, 2, -20, -32, 45, -6, 48, 28, 30, 33, -1, 22, -6, 30, 65, -17, 29, 74, 37, -26, -10, 15, -24, 19, -66, 22, -10, -31, -1, -18, -9, 11, 37, -4, 45, 5, 41, 17, 1, 1, 24, -58, 41, 5, -51, 14, 8, 43, 16, -10, -1, 45, 32, -64, 3, -33, -25, -3, -27, -68, 12, 23, -11, -13, -37, -40, 4, -21, -12, 32, -23, -19, 76, 41, -23, -24, -44, -65, -1, -15, 1, 71, 63, 5, 20, -3, 21, -23, 31, -32, 18, -2, 27, 31, 46, -5, -39, -5, -35, 18, -18, -40, -10, 3, 12, 2, -2, -22, 40, 5, -6, 60, 36, 3, 29, -27, 10, 25, -54, 5, 26, 39, 35, -24, -37, 30, -91, 28, -4, -21, -27, -39, -6, 5, 12, -128, 38, -16, 29, -95, -29, 82, -2, 35, 2, 12, 8, -22, 10, 80, -47, 2, -25, -73, -79, 16, -30, -32, -66, 48, 21, -45, -11, -47, 14, -27, -17, -7, 15, -44, -14, -44, -26, -32, 26, -23, 17, -7, -28, 26, -6, 28, 6, -26, 2, 13, -14, -23, -14, 19, 46, 16, 2, -33, -21, 28, -17, -42, 44, -37, 1, -39, 28, 84, -46, 15, 10, 13, -44, 72, -26, 26, 32, -28, -12, -83, 2, 10, -30, -44, -10, -28, 53, 45, 65, 0, -25, 57, 36, -33, 6, 29, 44, -53, 11, 19, -2, -27, 35, 32, 49, 4, 23, 38, 36, 24, 10, 51, -39, 4, -7, 26, 37, -35, 11, -47, -18, 28, 16, -35, 42, 17, -21, -41, 28, 14, -12, 11, -45, 7, -43, -15, 18, -5, 38, -40, -50, -30, -21, 9, -98, 13, 12, 23, 75, -56, -7, -3, -4, -1, -34, 12, -49, 11, 26, -18, -28, -17, 33, 13, -14, 40, 24, -72, -37, 10, 17, -6, 22, 16, 16, -6, -12, -30, -14, 10, 40, -23, 12, 15, -3, -15, 13, -56, -4, -30, 1, -3, -17, 27, 50, -5, 64, -36, -19, 7, 29, 22, 25, 9, -16, -58, -69, -40, -61, -71, -14, 42, 93, 26, 11, -6, -58, -11, 70, -52, 19, 9, -30, -33, 11, -37, -47, -21, -22, -40, 10, 47, 4, -23, 17, 48, 41, -48, 14, 10, 15, 34, -23, -2, -47, 23, -32, -13, -10, -26, -26, -4, 16, 38, -14, 0, -12, -7, -7, 20, 44, -1, -32, -27, -16, 4, -6, -18, 14, 5, 4, -29, 28, 7, -7, 15, -11, -20, -45, -36, 16, 84, 34, -59, -30, 22, 126, 8, 68, 79, -17, 21, -68, 37, 5, 15, 63, 49, 127, -90, 85, 43, 7, 16, 9, 6, -45, -57, -43, 57, 11, -23, -11, -29, 60, -26, 0, 7, 42, -24, 10, 23, -25, 8, -7, -40, 19, -17, 35, 4, 27, -39, -91, 27, -36, 34, 2, 16, -24, 25, 7, -21, 5, 17, 10, -22, -30, 9, -17, -61, -26, 33, 21, 58, -51, -14, 69, -38, 20, 7, 80, -4, -65, -6, -27, 53, -12, 47, -1, -15, 1, 60, 102, -79, -4, 12, 9, 22, 37, -8, -4, 37, 2, -3, -15, -16, -11, -5, 19, -6, -43, 20, -25, -18, 10, -27, 0, -28, -27, -11, 10, -18, -2, -4, -16, 26, 14, -6, 7, -6, 1, 53, -2, -29, 23, 9, -30, -6, -4, -6, 56, 70, 0, -33, -20, -17, -9, -24, 46, -5, -105, 47, -46, -51, 20, 20, -53, -81, -1, -7, 75, -5, -21, -65, 12, -52, 22, -50, -12, 49, 54, 76, -81, 10, 45, -41, -59, 18, -19, 25, 14, -31, -53, -5, 12, 31, 84, -23, 2, 7, 2, 10, -32, 39, -2, -12, 1, -9, 0, -10, -11, 9, 15, -8, -2, 2, -1, 10, 14, -5, -40, 19, -7, -7, 26, -4, 2, 1, -27, 35, 32, 21, -31, 26, 43, -9, 4, -32, 40, -62, -52, 36, 22, 38, 22, 36, -96, 6, -10, -23, -49, 15, -33, -18, -3, 0, 41, 21, -19, 21, 23, -39, -23, -6, 6, 47, 56, 4, 74, 0, -98, 29, -47, -14, -36, 21, -22, 22, 16, 13, 12, 16, -5, 13, 17, -13, -15, 1, -34, -26, 26, 12, 32, 27, 13, -67, 27, 2, 8, 10, 18, 16, 20, -17, -17, 57, -64, 5, 14, 19, 31, -18, -44, -46, -16, 4, -25, 17, -126, -24, 39, 4, 8, 55, -25, -34, 39, -16, 3, 9, 71, 72, -31, -55, 6, 10, -25, 32, -85, -21, 18, -8, 15, 12, -27, -7, 1, -21, -2, -5, 48, -16, 18, 1, -22, -26, 16, 14, -31, 27, -6, -15, -21, 4, -14, 18, -36 }; static const opus_int8 layer1_recur_weights[1728] = { 20, 67, -99, 12, 41, -25, 49, -44, 35, 81, 110, 47, 34, -66, -14, 14, -60, 34, 29, -73, 10, 41, 35, 89, 7, -35, 22, 7, 27, -20, -6, 56, 26, 66, 6, 33, -55, 53, 1, -21, 14, 17, 68, 55, 59, 0, 18, -9, 5, -41, 6, -5, -114, -12, 29, 42, -23, 10, 81, -27, 20, -53, -30, -62, 40, 95, 25, -4, 3, 18, -8, -15, -29, -82, 2, -57, -3, -61, -29, -29, 49, 2, -55, 5, -69, -99, -49, -51, 6, -25, 12, 89, 44, -33, 5, 41, 1, 23, -37, -37, -28, -48, 3, 4, -41, -30, -57, -35, -39, -1, -13, -56, -5, 50, 49, 41, -4, -4, 33, -22, -1, 33, 34, 18, 40, -42, 12, 1, -6, -2, 18, 17, 39, 44, 11, 65, -60, -45, 10, 91, 21, 9, -62, -11, 8, 69, 37, 24, -30, 21, 26, -27, 1, -28, 24, 66, -8, 6, -71, 34, 24, 44, 58, -78, -19, 57, 17, -60, 1, 12, -3, -1, -40, 22, 11, -5, 25, 12, 1, 72, 79, 7, -50, 23, 18, 13, 21, -11, -20, 5, 77, -94, 24, 15, 57, -51, 3, 36, 53, -1, 4, 14, 30, -31, 22, 40, 32, -11, -34, -36, -59, 58, 25, 21, -54, -23, 40, 46, 18, 0, 12, 54, -96, -99, -59, 5, 119, -38, 50, 55, 12, -16, 67, 0, 34, 35, 39, 35, -1, 69, 24, 27, -30, -35, -4, -70, 2, -44, -7, -6, 19, -9, 60, 44, -21, -10, 37, 43, -16, -3, 30, -15, -65, 31, -55, 18, -98, 76, 64, 25, 24, -18, -7, -68, -10, 38, 27, -60, 36, 33, 16, 30, 34, -39, -37, 31, 12, 53, -54, 14, -26, -49, -128, -13, -5, -22, -11, -85, 55, -8, -51, -11, -33, -10, -31, -76, -41, 23, 44, -40, -54, -127, -101, 19, -23, -15, 15, 27, 58, -60, 8, 14, -33, 1, 48, -9, -11, -123, 3, 53, 23, 4, -28, 22, 2, -29, -67, 36, 12, 7, 55, -21, 88, 20, -1, -21, -17, 3, 41, 32, -10, -14, -5, -57, 67, 57, 21, 23, -2, -27, -73, -24, 120, 21, 18, -35, 42, -7, 3, -45, -25, 76, -34, 50, 11, -54, -91, 3, -113, -20, -5, 47, 15, -47, 17, 27, -3, -26, -7, 10, 7, 74, -40, 64, -7, -5, -24, -49, -24, -3, -10, 27, -17, -8, -3, 14, -27, 33, 13, 39, 28, -7, -38, 29, 16, 44, 19, 55, -3, 9, -13, -57, 43, 43, 31, 0, -93, -17, 19, -56, 4, -12, -25, 37, -85, -13, -118, 33, -17, 56, 71, -80, -4, 6, -11, -18, 47, -52, 25, 9, 48, -107, 1, 21, 20, -3, 10, -16, -4, 24, 17, 31, -61, -18, -50, 24, -10, 12, 71, 26, 11, -3, 4, 1, 0, -7, -40, 18, 38, -34, 38, 17, 8, -34, 2, 21, 123, -32, -26, 43, 14, -34, -1, -9, 37, -16, 6, -17, -62, 68, 22, 17, 11, -75, 33, -80, 62, -9, -75, 76, 36, -41, -8, -40, -11, -71, 40, -39, 62, -49, -81, 16, -9, -52, 52, 61, 17, -103, -27, -10, -8, -54, -57, 21, 23, -16, -52, 36, 18, 10, -5, 8, 15, -29, 5, -19, -37, 8, -53, 6, 19, -37, 38, -17, 48, 10, 0, 81, 46, 70, -29, 101, 11, 44, -44, -3, 24, 11, 3, 14, -9, 11, 14, -45, 13, 46, -3, -57, 68, 44, 63, 98, 25, -28, -23, 15, 32, -10, 53, -6, -2, -9, -6, 16, -107, -11, -11, -28, 59, 57, -22, 38, 42, 83, 27, 5, 29, -30, 12, -21, -13, 31, 38, -21, 58, -10, -10, -15, -2, -5, 11, 12, -73, -28, -38, 22, 2, -25, 73, -52, -12, -55, 32, -63, 21, 51, 33, 52, -26, 55, -26, -26, 57, -32, -4, -52, -61, 21, -33, -91, -51, 69, -90, -53, -38, -44, 12, -76, -20, 77, -45, -7, 86, 43, -109, -33, -105, -40, -121, -10, 0, -72, 45, -51, -75, -49, -38, -1, -62, 18, -1, 30, -44, -14, -10, -67, 40, -10, -34, 46, -64, -32, 29, -13, 33, 3, -32, -5, 28, -27, -25, 93, 24, 68, -40, 57, 23, -3, -21, -58, 17, -39, -17, -22, -89, 11, 18, -46, 27, 24, 46, 127, 61, 87, 31, 127, -36, 47, -23, 47, 127, -24, 110, 122, 30, 100, 0, 96, -12, 6, 50, 44, -13, 73, 4, 55, -11, -15, 49, 42, -6, 20, -35, 58, 18, 38, 42, 72, 19, -21, 11, 9, -37, 7, 29, 31, 16, -17, 13, -50, 19, 5, -23, 51, -16, -5, 4, -24, 76, 10, -53, -28, -7, -65, 74, 40, -16, -29, 32, -16, -49, -35, -3, 59, -96, -50, -43, -43, -61, -15, -8, -36, -34, -33, -14, 11, -3, -39, 4, -114, -123, -11, -49, -21, 14, -56, 1, 43, -63, 26, 40, 18, -10, -26, -14, -15, -35, -35, -11, 32, -44, -67, 2, 22, 7, 3, -9, -30, -51, -28, 28, 6, -22, 16, 34, -25, -52, -54, -8, -6, 5, 8, 20, -16, -17, -44, 27, 3, 31, -5, -48, -1, -3, 116, 11, 71, -31, -47, 109, 50, -22, -12, -57, 32, 66, 8, -25, -93, -54, -10, 19, -76, -34, 97, 48, -36, -18, -30, -39, -26, -12, 28, 14, 12, -12, -31, 38, 2, 10, 4, -40, 20, 16, -61, 2, 64, 39, 5, 15, 33, 40, -61, -49, 93, -10, 33, 28, -11, -27, -18, 39, -62, -6, -6, 62, 11, -8, 38, -67, 12, 27, 39, -27, 123, -18, -6, -65, 83, -64, 20, 19, -11, 33, 24, 17, 56, 78, 7, -15, 54, -101, -9, 115, -96, 50, 51, 35, 34, 27, 37, -40, -11, 8, -36, 42, -45, 2, -23, 0, 67, -8, -9, -13, 50, -14, -27, 4, 0, -8, -14, 30, -9, 29, 15, 9, -38, 37, -8, 50, -46, 54, 41, -11, -8, -11, -26, 39, 45, 14, -26, -17, -27, 69, 38, 39, 98, 66, 0, 42, 123, -101, -19, -83, 117, -32, 56, 10, 12, -88, 79, -53, 56, 63, 95, -62, 9, 36, -13, -79, -16, 37, -46, 35, -34, 14, 17, -54, 5, 21, -7, 7, 63, 56, 15, 27, -76, -25, 4, -26, -63, 28, -67, -52, 43, -47, -70, 40, -12, 40, -66, -37, 0, 35, 37, -53, 4, -17, -51, 11, 21, 14, -34, -4, 24, -42, 29, 22, 7, 28, 12, 37, 39, -39, -19, 65, -60, -50, -2, 1, 82, 39, 19, -23, -43, -22, -67, -35, -34, 32, 102, 81, 127, 36, 67, -45, 1, -67, -52, -4, 35, 20, 28, 71, 86, -35, -9, -83, -34, 12, 9, -23, 2, 14, 28, -23, 7, -25, 45, 7, 17, -37, 0, -19, 31, 26, 40, -27, -16, 17, 5, -21, 23, 24, 96, -55, 52, -19, -14, -6, 1, 50, -34, 86, -53, 38, 2, -52, -36, -13, 60, -85, -120, 32, 7, -12, 22, 70, -7, -94, 38, -76, -31, -20, 15, -28, 7, 6, 40, 53, 88, 3, 38, 18, -8, -22, -23, 51, 37, -9, 13, -32, 25, -21, 27, 31, 20, 18, -9, -13, 1, 21, -24, -13, 39, 15, -11, -29, -36, 18, 15, 8, 27, 21, -94, -1, -22, 49, 66, -1, 6, -3, -40, -18, 6, 28, 12, 33, -59, 62, 60, -48, 90, -1, 108, 9, 18, -2, 27, 77, -65, 82, -48, -38, -19, -11, 127, 50, 66, 18, -13, -22, 60, -38, 40, -14, -26, -13, 38, 67, 57, 30, 33, 26, 36, 38, -17, 27, -28, 20, 12, -64, 18, 5, -33, -27, 13, -26, 32, 35, -5, -48, -14, 92, 43, -47, -14, 40, 11, 51, 66, 22, -63, -16, -61, 4, -28, 27, 20, -33, -30, -21, -29, -53, 31, -40, 24, 43, -4, -19, 21, 67, 20, 100, -16, -93, 78, -6, -18, -52, -37, -9, 66, -31, -8, 26, 18, 4, 24, -22, 17, -2, -13, 27, 0, 8, -18, -25, 5, -21, -24, -7, 18, -93, 21, 7, 2, -75, 69, 50, -5, -15, -17, 60, -42, 55, 1, -4, 3, 10, 46, 16, -13, 45, -7, -10, -44, -108, 49, 2, -15, -64, -12, -72, 32, -38, -45, 10, -54, 13, -13, -27, -36, -64, 58, -62, -101, 88, -86, -71, -39, -9, -128, 32, 15, -4, 54, -16, -39, -26, -36, 46, 48, -64, -10, 19, 30, -13, 34, -8, 50, 60, -22, -6, -11, -30, 5, 50, 32, 56, 0, 25, 6, 68, 11, -29, 45, -9, -12, 4, 1, 18, -49, 0, -38, -19, 90, 29, 35, 51, 8, -48, 96, -1, -12, -9, -32, -63, -65, -7, 38, 89, 28, -85, -28, -23, -25, -128, 56, 79, -36, 99, -6, -37, 7, -13, -69, -46, -29, 25, 64, -21, 17, 1, 42, -66, 1, 80, 26, -32, 21, 15, 15, 6, 6, -10, 15, 127, 5, 38, 27, 87, -57, -25, 11, 72, -21, -5, 11, -13, -66, 78, 36, -3, 41, -21, 8, -33, 23, 73, 28, 57, -25, -5, 4, -22, -47, 15, 4, -57, -72, 33, 1, 18, 2, 53, -71, -99, -21, -3, -111, 108, 71, -14, 82, 25, 61, -48, 5, 9, -51, -20, -25, -3, 14, -33, 14, -3, -34, 22, 12, -19, -38, -16, 2, 21, 16, 26, -31, 75, 44, -31, 16, 26, 66, 17, -9, -22, -22, 22, -44, 22, 27, 2, 58, -14, 10, -73, -42, 55, -25, -61, 72, -1, 30, -58, -25, 63, 26, -48, -40, 26, -30, 60, 8, -17, -1, -18, -20, 43, -20, -4, -28, 127, -106, 29, 70, 64, -27, 39, -33, -5, -88, -40, -52, 26, 44, -17, 23, 2, -49, 22, -9, -8, 86, 49, -43, -60, 1, 10, 45, 36, -53, -4, 33, 38, 48, -72, 1, 19, 21, -65, 4, -5, -62, 27, -25, 17, -6, 6, -45, -39, -46, 4, 26, 127, -9, 18, -33, -18, -3, 33, 2, -5, 15, -26, -22, -117, -63, -17, -59, 61, -74, 7, -47, -58, -128, -67, 15, -16, -128, 12, 2, 20, 9, -48, -40, 43, 3, -40, -16, -38, -6, -22, -28, -16, -59, -22, 6, -5, 11, -12, -66, -40, 27, -62, -44, -19, 38, -3, 39, -8, 40, -24, 13, 21, 50, -60, -22, 53, -29, -6, 1, 22, -59, 0, 17, -39, 115 }; static const opus_int8 layer1_bias[72] = { -42, 20, 16, 0, 105, 60, 1, -97, 24, 60, 18, 13, 62, 25, 127, 34, 79, 55, 118, 127, 95, 31, -4, 87, 21, 12, 2, -14, 18, 23, 8, 17, -1, -8, 5, 4, 24, 37, 21, 13, 36, 13, 17, 18, 37, 30, 33, 1, 8, -16, -11, -5, -31, -3, -5, 0, 6, 3, 58, -7, -1, -16, 5, -13, 16, 10, -2, -14, 11, -4, 3, -11 }; static const opus_int8 layer2_weights[48] = { -113, -88, 31, -128, -126, -61, 85, -35, 118, -128, -61, 127, -128, -17, -128, 127, 104, -9, -128, 33, 45, 127, 5, 83, 84, -128, -85, -128, -45, 48, -53, -128, 46, 127, -17, 125, 117, -41, -117, -91, -127, -68, -1, -89, -80, 32, 106, 7 }; static const opus_int8 layer2_bias[2] = { 14, 117 }; const DenseLayer layer0 = { layer0_bias, layer0_weights, 25, 32, 0 }; const GRULayer layer1 = { layer1_bias, layer1_weights, layer1_recur_weights, 32, 24 }; const DenseLayer layer2 = { layer2_bias, layer2_weights, 24, 2, 1 }; jamulus-3.9.1+dfsg/libs/opus/src/opus_projection_decoder.c0000644000175000017500000001731114340334543022740 0ustar vimervimer/* Copyright (c) 2017 Google Inc. Written by Andrew Allen */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "mathops.h" #include "os_support.h" #include "opus_private.h" #include "opus_defines.h" #include "opus_projection.h" #include "opus_multistream.h" #include "mapping_matrix.h" #include "stack_alloc.h" struct OpusProjectionDecoder { opus_int32 demixing_matrix_size_in_bytes; /* Encoder states go here */ }; #if !defined(DISABLE_FLOAT_API) static void opus_projection_copy_channel_out_float( void *dst, int dst_stride, int dst_channel, const opus_val16 *src, int src_stride, int frame_size, void *user_data) { float *float_dst; const MappingMatrix *matrix; float_dst = (float *)dst; matrix = (const MappingMatrix *)user_data; if (dst_channel == 0) OPUS_CLEAR(float_dst, frame_size * dst_stride); if (src != NULL) mapping_matrix_multiply_channel_out_float(matrix, src, dst_channel, src_stride, float_dst, dst_stride, frame_size); } #endif static void opus_projection_copy_channel_out_short( void *dst, int dst_stride, int dst_channel, const opus_val16 *src, int src_stride, int frame_size, void *user_data) { opus_int16 *short_dst; const MappingMatrix *matrix; short_dst = (opus_int16 *)dst; matrix = (const MappingMatrix *)user_data; if (dst_channel == 0) OPUS_CLEAR(short_dst, frame_size * dst_stride); if (src != NULL) mapping_matrix_multiply_channel_out_short(matrix, src, dst_channel, src_stride, short_dst, dst_stride, frame_size); } static MappingMatrix *get_dec_demixing_matrix(OpusProjectionDecoder *st) { /* void* cast avoids clang -Wcast-align warning */ return (MappingMatrix*)(void*)((char*)st + align(sizeof(OpusProjectionDecoder))); } static OpusMSDecoder *get_multistream_decoder(OpusProjectionDecoder *st) { /* void* cast avoids clang -Wcast-align warning */ return (OpusMSDecoder*)(void*)((char*)st + align(sizeof(OpusProjectionDecoder) + st->demixing_matrix_size_in_bytes)); } opus_int32 opus_projection_decoder_get_size(int channels, int streams, int coupled_streams) { opus_int32 matrix_size; opus_int32 decoder_size; matrix_size = mapping_matrix_get_size(streams + coupled_streams, channels); if (!matrix_size) return 0; decoder_size = opus_multistream_decoder_get_size(streams, coupled_streams); if (!decoder_size) return 0; return align(sizeof(OpusProjectionDecoder)) + matrix_size + decoder_size; } int opus_projection_decoder_init(OpusProjectionDecoder *st, opus_int32 Fs, int channels, int streams, int coupled_streams, unsigned char *demixing_matrix, opus_int32 demixing_matrix_size) { int nb_input_streams; opus_int32 expected_matrix_size; int i, ret; unsigned char mapping[255]; VARDECL(opus_int16, buf); ALLOC_STACK; /* Verify supplied matrix size. */ nb_input_streams = streams + coupled_streams; expected_matrix_size = nb_input_streams * channels * sizeof(opus_int16); if (expected_matrix_size != demixing_matrix_size) { RESTORE_STACK; return OPUS_BAD_ARG; } /* Convert demixing matrix input into internal format. */ ALLOC(buf, nb_input_streams * channels, opus_int16); for (i = 0; i < nb_input_streams * channels; i++) { int s = demixing_matrix[2*i + 1] << 8 | demixing_matrix[2*i]; s = ((s & 0xFFFF) ^ 0x8000) - 0x8000; buf[i] = (opus_int16)s; } /* Assign demixing matrix. */ st->demixing_matrix_size_in_bytes = mapping_matrix_get_size(channels, nb_input_streams); if (!st->demixing_matrix_size_in_bytes) { RESTORE_STACK; return OPUS_BAD_ARG; } mapping_matrix_init(get_dec_demixing_matrix(st), channels, nb_input_streams, 0, buf, demixing_matrix_size); /* Set trivial mapping so each input channel pairs with a matrix column. */ for (i = 0; i < channels; i++) mapping[i] = i; ret = opus_multistream_decoder_init( get_multistream_decoder(st), Fs, channels, streams, coupled_streams, mapping); RESTORE_STACK; return ret; } OpusProjectionDecoder *opus_projection_decoder_create( opus_int32 Fs, int channels, int streams, int coupled_streams, unsigned char *demixing_matrix, opus_int32 demixing_matrix_size, int *error) { int size; int ret; OpusProjectionDecoder *st; /* Allocate space for the projection decoder. */ size = opus_projection_decoder_get_size(channels, streams, coupled_streams); if (!size) { if (error) *error = OPUS_ALLOC_FAIL; return NULL; } st = (OpusProjectionDecoder *)opus_alloc(size); if (!st) { if (error) *error = OPUS_ALLOC_FAIL; return NULL; } /* Initialize projection decoder with provided settings. */ ret = opus_projection_decoder_init(st, Fs, channels, streams, coupled_streams, demixing_matrix, demixing_matrix_size); if (ret != OPUS_OK) { opus_free(st); st = NULL; } if (error) *error = ret; return st; } #ifdef FIXED_POINT int opus_projection_decode(OpusProjectionDecoder *st, const unsigned char *data, opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec) { return opus_multistream_decode_native(get_multistream_decoder(st), data, len, pcm, opus_projection_copy_channel_out_short, frame_size, decode_fec, 0, get_dec_demixing_matrix(st)); } #else int opus_projection_decode(OpusProjectionDecoder *st, const unsigned char *data, opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec) { return opus_multistream_decode_native(get_multistream_decoder(st), data, len, pcm, opus_projection_copy_channel_out_short, frame_size, decode_fec, 1, get_dec_demixing_matrix(st)); } #endif #ifndef DISABLE_FLOAT_API int opus_projection_decode_float(OpusProjectionDecoder *st, const unsigned char *data, opus_int32 len, float *pcm, int frame_size, int decode_fec) { return opus_multistream_decode_native(get_multistream_decoder(st), data, len, pcm, opus_projection_copy_channel_out_float, frame_size, decode_fec, 0, get_dec_demixing_matrix(st)); } #endif int opus_projection_decoder_ctl(OpusProjectionDecoder *st, int request, ...) { va_list ap; int ret = OPUS_OK; va_start(ap, request); ret = opus_multistream_decoder_ctl_va_list(get_multistream_decoder(st), request, ap); va_end(ap); return ret; } void opus_projection_decoder_destroy(OpusProjectionDecoder *st) { opus_free(st); } jamulus-3.9.1+dfsg/libs/opus/src/opus.c0000644000175000017500000002324614340334543017023 0ustar vimervimer/* Copyright (c) 2011 Xiph.Org Foundation, Skype Limited Written by Jean-Marc Valin and Koen Vos */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "opus.h" #include "opus_private.h" #ifndef DISABLE_FLOAT_API OPUS_EXPORT void opus_pcm_soft_clip(float *_x, int N, int C, float *declip_mem) { int c; int i; float *x; if (C<1 || N<1 || !_x || !declip_mem) return; /* First thing: saturate everything to +/- 2 which is the highest level our non-linearity can handle. At the point where the signal reaches +/-2, the derivative will be zero anyway, so this doesn't introduce any discontinuity in the derivative. */ for (i=0;i=0) break; x[i*C] = x[i*C]+a*x[i*C]*x[i*C]; } curr=0; x0 = x[0]; while(1) { int start, end; float maxval; int special=0; int peak_pos; for (i=curr;i1 || x[i*C]<-1) break; } if (i==N) { a=0; break; } peak_pos = i; start=end=i; maxval=ABS16(x[i*C]); /* Look for first zero crossing before clipping */ while (start>0 && x[i*C]*x[(start-1)*C]>=0) start--; /* Look for first zero crossing after clipping */ while (end=0) { /* Look for other peaks until the next zero-crossing. */ if (ABS16(x[end*C])>maxval) { maxval = ABS16(x[end*C]); peak_pos = end; } end++; } /* Detect the special case where we clip before the first zero crossing */ special = (start==0 && x[i*C]*x[0]>=0); /* Compute a such that maxval + a*maxval^2 = 1 */ a=(maxval-1)/(maxval*maxval); /* Slightly boost "a" by 2^-22. This is just enough to ensure -ffast-math does not cause output values larger than +/-1, but small enough not to matter even for 24-bit output. */ a += a*2.4e-7f; if (x[i*C]>0) a = -a; /* Apply soft clipping */ for (i=start;i=2) { /* Add a linear ramp from the first sample to the signal peak. This avoids a discontinuity at the beginning of the frame. */ float delta; float offset = x0-x[0]; delta = offset / peak_pos; for (i=curr;i>2; return 2; } } static int parse_size(const unsigned char *data, opus_int32 len, opus_int16 *size) { if (len<1) { *size = -1; return -1; } else if (data[0]<252) { *size = data[0]; return 1; } else if (len<2) { *size = -1; return -1; } else { *size = 4*data[1] + data[0]; return 2; } } int opus_packet_get_samples_per_frame(const unsigned char *data, opus_int32 Fs) { int audiosize; if (data[0]&0x80) { audiosize = ((data[0]>>3)&0x3); audiosize = (Fs<>3)&0x3); if (audiosize == 3) audiosize = Fs*60/1000; else audiosize = (Fs< len) return OPUS_INVALID_PACKET; data += bytes; last_size = len-size[0]; break; /* Multiple CBR/VBR frames (from 0 to 120 ms) */ default: /*case 3:*/ if (len<1) return OPUS_INVALID_PACKET; /* Number of frames encoded in bits 0 to 5 */ ch = *data++; count = ch&0x3F; if (count <= 0 || framesize*(opus_int32)count > 5760) return OPUS_INVALID_PACKET; len--; /* Padding flag is bit 6 */ if (ch&0x40) { int p; do { int tmp; if (len<=0) return OPUS_INVALID_PACKET; p = *data++; len--; tmp = p==255 ? 254: p; len -= tmp; pad += tmp; } while (p==255); } if (len<0) return OPUS_INVALID_PACKET; /* VBR flag is bit 7 */ cbr = !(ch&0x80); if (!cbr) { /* VBR case */ last_size = len; for (i=0;i len) return OPUS_INVALID_PACKET; data += bytes; last_size -= bytes+size[i]; } if (last_size<0) return OPUS_INVALID_PACKET; } else if (!self_delimited) { /* CBR case */ last_size = len/count; if (last_size*count!=len) return OPUS_INVALID_PACKET; for (i=0;i len) return OPUS_INVALID_PACKET; data += bytes; /* For CBR packets, apply the size to all the frames. */ if (cbr) { if (size[count-1]*count > len) return OPUS_INVALID_PACKET; for (i=0;i last_size) return OPUS_INVALID_PACKET; } else { /* Because it's not encoded explicitly, it's possible the size of the last packet (or all the packets, for the CBR case) is larger than 1275. Reject them here.*/ if (last_size > 1275) return OPUS_INVALID_PACKET; size[count-1] = (opus_int16)last_size; } if (payload_offset) *payload_offset = (int)(data-data0); for (i=0;i #include "float_cast.h" #include "os_support.h" #include "mathops.h" #include "mdct.h" #include "modes.h" #include "bands.h" #include "quant_bands.h" #include "pitch.h" typedef struct { int nb_streams; int nb_coupled_streams; unsigned char mapping[8]; } VorbisLayout; /* Index is nb_channel-1*/ static const VorbisLayout vorbis_mappings[8] = { {1, 0, {0}}, /* 1: mono */ {1, 1, {0, 1}}, /* 2: stereo */ {2, 1, {0, 2, 1}}, /* 3: 1-d surround */ {2, 2, {0, 1, 2, 3}}, /* 4: quadraphonic surround */ {3, 2, {0, 4, 1, 2, 3}}, /* 5: 5-channel surround */ {4, 2, {0, 4, 1, 2, 3, 5}}, /* 6: 5.1 surround */ {4, 3, {0, 4, 1, 2, 3, 5, 6}}, /* 7: 6.1 surround */ {5, 3, {0, 6, 1, 2, 3, 4, 5, 7}}, /* 8: 7.1 surround */ }; static opus_val32 *ms_get_preemph_mem(OpusMSEncoder *st) { int s; char *ptr; int coupled_size, mono_size; coupled_size = opus_encoder_get_size(2); mono_size = opus_encoder_get_size(1); ptr = (char*)st + align(sizeof(OpusMSEncoder)); for (s=0;slayout.nb_streams;s++) { if (s < st->layout.nb_coupled_streams) ptr += align(coupled_size); else ptr += align(mono_size); } /* void* cast avoids clang -Wcast-align warning */ return (opus_val32*)(void*)(ptr+st->layout.nb_channels*120*sizeof(opus_val32)); } static opus_val32 *ms_get_window_mem(OpusMSEncoder *st) { int s; char *ptr; int coupled_size, mono_size; coupled_size = opus_encoder_get_size(2); mono_size = opus_encoder_get_size(1); ptr = (char*)st + align(sizeof(OpusMSEncoder)); for (s=0;slayout.nb_streams;s++) { if (s < st->layout.nb_coupled_streams) ptr += align(coupled_size); else ptr += align(mono_size); } /* void* cast avoids clang -Wcast-align warning */ return (opus_val32*)(void*)ptr; } static int validate_ambisonics(int nb_channels, int *nb_streams, int *nb_coupled_streams) { int order_plus_one; int acn_channels; int nondiegetic_channels; if (nb_channels < 1 || nb_channels > 227) return 0; order_plus_one = isqrt32(nb_channels); acn_channels = order_plus_one * order_plus_one; nondiegetic_channels = nb_channels - acn_channels; if (nondiegetic_channels != 0 && nondiegetic_channels != 2) return 0; if (nb_streams) *nb_streams = acn_channels + (nondiegetic_channels != 0); if (nb_coupled_streams) *nb_coupled_streams = nondiegetic_channels != 0; return 1; } static int validate_encoder_layout(const ChannelLayout *layout) { int s; for (s=0;snb_streams;s++) { if (s < layout->nb_coupled_streams) { if (get_left_channel(layout, s, -1)==-1) return 0; if (get_right_channel(layout, s, -1)==-1) return 0; } else { if (get_mono_channel(layout, s, -1)==-1) return 0; } } return 1; } static void channel_pos(int channels, int pos[8]) { /* Position in the mix: 0 don't mix, 1: left, 2: center, 3:right */ if (channels==4) { pos[0]=1; pos[1]=3; pos[2]=1; pos[3]=3; } else if (channels==3||channels==5||channels==6) { pos[0]=1; pos[1]=2; pos[2]=3; pos[3]=1; pos[4]=3; pos[5]=0; } else if (channels==7) { pos[0]=1; pos[1]=2; pos[2]=3; pos[3]=1; pos[4]=3; pos[5]=2; pos[6]=0; } else if (channels==8) { pos[0]=1; pos[1]=2; pos[2]=3; pos[3]=1; pos[4]=3; pos[5]=1; pos[6]=3; pos[7]=0; } } #if 1 /* Computes a rough approximation of log2(2^a + 2^b) */ static opus_val16 logSum(opus_val16 a, opus_val16 b) { opus_val16 max; opus_val32 diff; opus_val16 frac; static const opus_val16 diff_table[17] = { QCONST16(0.5000000f, DB_SHIFT), QCONST16(0.2924813f, DB_SHIFT), QCONST16(0.1609640f, DB_SHIFT), QCONST16(0.0849625f, DB_SHIFT), QCONST16(0.0437314f, DB_SHIFT), QCONST16(0.0221971f, DB_SHIFT), QCONST16(0.0111839f, DB_SHIFT), QCONST16(0.0056136f, DB_SHIFT), QCONST16(0.0028123f, DB_SHIFT) }; int low; if (a>b) { max = a; diff = SUB32(EXTEND32(a),EXTEND32(b)); } else { max = b; diff = SUB32(EXTEND32(b),EXTEND32(a)); } if (!(diff < QCONST16(8.f, DB_SHIFT))) /* inverted to catch NaNs */ return max; #ifdef FIXED_POINT low = SHR32(diff, DB_SHIFT-1); frac = SHL16(diff - SHL16(low, DB_SHIFT-1), 16-DB_SHIFT); #else low = (int)floor(2*diff); frac = 2*diff - low; #endif return max + diff_table[low] + MULT16_16_Q15(frac, SUB16(diff_table[low+1], diff_table[low])); } #else opus_val16 logSum(opus_val16 a, opus_val16 b) { return log2(pow(4, a)+ pow(4, b))/2; } #endif void surround_analysis(const CELTMode *celt_mode, const void *pcm, opus_val16 *bandLogE, opus_val32 *mem, opus_val32 *preemph_mem, int len, int overlap, int channels, int rate, opus_copy_channel_in_func copy_channel_in, int arch ) { int c; int i; int LM; int pos[8] = {0}; int upsample; int frame_size; int freq_size; opus_val16 channel_offset; opus_val32 bandE[21]; opus_val16 maskLogE[3][21]; VARDECL(opus_val32, in); VARDECL(opus_val16, x); VARDECL(opus_val32, freq); SAVE_STACK; upsample = resampling_factor(rate); frame_size = len*upsample; freq_size = IMIN(960, frame_size); /* LM = log2(frame_size / 120) */ for (LM=0;LMmaxLM;LM++) if (celt_mode->shortMdctSize<preemph, preemph_mem+c, 0); #ifndef FIXED_POINT { opus_val32 sum; sum = celt_inner_prod(in, in, frame_size+overlap, 0); /* This should filter out both NaNs and ridiculous signals that could cause NaNs further down. */ if (!(sum < 1e18f) || celt_isnan(sum)) { OPUS_CLEAR(in, frame_size+overlap); preemph_mem[c] = 0; } } #endif OPUS_CLEAR(bandE, 21); for (frame=0;framemdct, in+960*frame, freq, celt_mode->window, overlap, celt_mode->maxLM-LM, 1, arch); if (upsample != 1) { int bound = freq_size/upsample; for (i=0;i=0;i--) bandLogE[21*c+i] = MAX16(bandLogE[21*c+i], bandLogE[21*c+i+1]-QCONST16(2.f, DB_SHIFT)); if (pos[c]==1) { for (i=0;i<21;i++) maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]); } else if (pos[c]==3) { for (i=0;i<21;i++) maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]); } else if (pos[c]==2) { for (i=0;i<21;i++) { maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]-QCONST16(.5f, DB_SHIFT)); maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]-QCONST16(.5f, DB_SHIFT)); } } #if 0 for (i=0;i<21;i++) printf("%f ", bandLogE[21*c+i]); float sum=0; for (i=0;i<21;i++) sum += bandLogE[21*c+i]; printf("%f ", sum/21); #endif OPUS_COPY(mem+c*overlap, in+frame_size, overlap); } for (i=0;i<21;i++) maskLogE[1][i] = MIN32(maskLogE[0][i],maskLogE[2][i]); channel_offset = HALF16(celt_log2(QCONST32(2.f,14)/(channels-1))); for (c=0;c<3;c++) for (i=0;i<21;i++) maskLogE[c][i] += channel_offset; #if 0 for (c=0;c<3;c++) { for (i=0;i<21;i++) printf("%f ", maskLogE[c][i]); } #endif for (c=0;cnb_streams||nb_coupled_streams<0)return 0; coupled_size = opus_encoder_get_size(2); mono_size = opus_encoder_get_size(1); return align(sizeof(OpusMSEncoder)) + nb_coupled_streams * align(coupled_size) + (nb_streams-nb_coupled_streams) * align(mono_size); } opus_int32 opus_multistream_surround_encoder_get_size(int channels, int mapping_family) { int nb_streams; int nb_coupled_streams; opus_int32 size; if (mapping_family==0) { if (channels==1) { nb_streams=1; nb_coupled_streams=0; } else if (channels==2) { nb_streams=1; nb_coupled_streams=1; } else return 0; } else if (mapping_family==1 && channels<=8 && channels>=1) { nb_streams=vorbis_mappings[channels-1].nb_streams; nb_coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams; } else if (mapping_family==255) { nb_streams=channels; nb_coupled_streams=0; } else if (mapping_family==2) { if (!validate_ambisonics(channels, &nb_streams, &nb_coupled_streams)) return 0; } else return 0; size = opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams); if (channels>2) { size += channels*(120*sizeof(opus_val32) + sizeof(opus_val32)); } return size; } static int opus_multistream_encoder_init_impl( OpusMSEncoder *st, opus_int32 Fs, int channels, int streams, int coupled_streams, const unsigned char *mapping, int application, MappingType mapping_type ) { int coupled_size; int mono_size; int i, ret; char *ptr; if ((channels>255) || (channels<1) || (coupled_streams>streams) || (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams)) return OPUS_BAD_ARG; st->arch = opus_select_arch(); st->layout.nb_channels = channels; st->layout.nb_streams = streams; st->layout.nb_coupled_streams = coupled_streams; if (mapping_type != MAPPING_TYPE_SURROUND) st->lfe_stream = -1; st->bitrate_bps = OPUS_AUTO; st->application = application; st->variable_duration = OPUS_FRAMESIZE_ARG; for (i=0;ilayout.nb_channels;i++) st->layout.mapping[i] = mapping[i]; if (!validate_layout(&st->layout)) return OPUS_BAD_ARG; if (mapping_type == MAPPING_TYPE_SURROUND && !validate_encoder_layout(&st->layout)) return OPUS_BAD_ARG; if (mapping_type == MAPPING_TYPE_AMBISONICS && !validate_ambisonics(st->layout.nb_channels, NULL, NULL)) return OPUS_BAD_ARG; ptr = (char*)st + align(sizeof(OpusMSEncoder)); coupled_size = opus_encoder_get_size(2); mono_size = opus_encoder_get_size(1); for (i=0;ilayout.nb_coupled_streams;i++) { ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 2, application); if(ret!=OPUS_OK)return ret; if (i==st->lfe_stream) opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1)); ptr += align(coupled_size); } for (;ilayout.nb_streams;i++) { ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 1, application); if (i==st->lfe_stream) opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1)); if(ret!=OPUS_OK)return ret; ptr += align(mono_size); } if (mapping_type == MAPPING_TYPE_SURROUND) { OPUS_CLEAR(ms_get_preemph_mem(st), channels); OPUS_CLEAR(ms_get_window_mem(st), channels*120); } st->mapping_type = mapping_type; return OPUS_OK; } int opus_multistream_encoder_init( OpusMSEncoder *st, opus_int32 Fs, int channels, int streams, int coupled_streams, const unsigned char *mapping, int application ) { return opus_multistream_encoder_init_impl(st, Fs, channels, streams, coupled_streams, mapping, application, MAPPING_TYPE_NONE); } int opus_multistream_surround_encoder_init( OpusMSEncoder *st, opus_int32 Fs, int channels, int mapping_family, int *streams, int *coupled_streams, unsigned char *mapping, int application ) { MappingType mapping_type; if ((channels>255) || (channels<1)) return OPUS_BAD_ARG; st->lfe_stream = -1; if (mapping_family==0) { if (channels==1) { *streams=1; *coupled_streams=0; mapping[0]=0; } else if (channels==2) { *streams=1; *coupled_streams=1; mapping[0]=0; mapping[1]=1; } else return OPUS_UNIMPLEMENTED; } else if (mapping_family==1 && channels<=8 && channels>=1) { int i; *streams=vorbis_mappings[channels-1].nb_streams; *coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams; for (i=0;i=6) st->lfe_stream = *streams-1; } else if (mapping_family==255) { int i; *streams=channels; *coupled_streams=0; for(i=0;i2 && mapping_family==1) { mapping_type = MAPPING_TYPE_SURROUND; } else if (mapping_family==2) { mapping_type = MAPPING_TYPE_AMBISONICS; } else { mapping_type = MAPPING_TYPE_NONE; } return opus_multistream_encoder_init_impl(st, Fs, channels, *streams, *coupled_streams, mapping, application, mapping_type); } OpusMSEncoder *opus_multistream_encoder_create( opus_int32 Fs, int channels, int streams, int coupled_streams, const unsigned char *mapping, int application, int *error ) { int ret; OpusMSEncoder *st; if ((channels>255) || (channels<1) || (coupled_streams>streams) || (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams)) { if (error) *error = OPUS_BAD_ARG; return NULL; } st = (OpusMSEncoder *)opus_alloc(opus_multistream_encoder_get_size(streams, coupled_streams)); if (st==NULL) { if (error) *error = OPUS_ALLOC_FAIL; return NULL; } ret = opus_multistream_encoder_init(st, Fs, channels, streams, coupled_streams, mapping, application); if (ret != OPUS_OK) { opus_free(st); st = NULL; } if (error) *error = ret; return st; } OpusMSEncoder *opus_multistream_surround_encoder_create( opus_int32 Fs, int channels, int mapping_family, int *streams, int *coupled_streams, unsigned char *mapping, int application, int *error ) { int ret; opus_int32 size; OpusMSEncoder *st; if ((channels>255) || (channels<1)) { if (error) *error = OPUS_BAD_ARG; return NULL; } size = opus_multistream_surround_encoder_get_size(channels, mapping_family); if (!size) { if (error) *error = OPUS_UNIMPLEMENTED; return NULL; } st = (OpusMSEncoder *)opus_alloc(size); if (st==NULL) { if (error) *error = OPUS_ALLOC_FAIL; return NULL; } ret = opus_multistream_surround_encoder_init(st, Fs, channels, mapping_family, streams, coupled_streams, mapping, application); if (ret != OPUS_OK) { opus_free(st); st = NULL; } if (error) *error = ret; return st; } static void surround_rate_allocation( OpusMSEncoder *st, opus_int32 *rate, int frame_size, opus_int32 Fs ) { int i; opus_int32 channel_rate; int stream_offset; int lfe_offset; int coupled_ratio; /* Q8 */ int lfe_ratio; /* Q8 */ int nb_lfe; int nb_uncoupled; int nb_coupled; int nb_normal; opus_int32 channel_offset; opus_int32 bitrate; int total; nb_lfe = (st->lfe_stream!=-1); nb_coupled = st->layout.nb_coupled_streams; nb_uncoupled = st->layout.nb_streams-nb_coupled-nb_lfe; nb_normal = 2*nb_coupled + nb_uncoupled; /* Give each non-LFE channel enough bits per channel for coding band energy. */ channel_offset = 40*IMAX(50, Fs/frame_size); if (st->bitrate_bps==OPUS_AUTO) { bitrate = nb_normal*(channel_offset + Fs + 10000) + 8000*nb_lfe; } else if (st->bitrate_bps==OPUS_BITRATE_MAX) { bitrate = nb_normal*300000 + nb_lfe*128000; } else { bitrate = st->bitrate_bps; } /* Give LFE some basic stream_channel allocation but never exceed 1/20 of the total rate for the non-energy part to avoid problems at really low rate. */ lfe_offset = IMIN(bitrate/20, 3000) + 15*IMAX(50, Fs/frame_size); /* We give each stream (coupled or uncoupled) a starting bitrate. This models the main saving of coupled channels over uncoupled. */ stream_offset = (bitrate - channel_offset*nb_normal - lfe_offset*nb_lfe)/nb_normal/2; stream_offset = IMAX(0, IMIN(20000, stream_offset)); /* Coupled streams get twice the mono rate after the offset is allocated. */ coupled_ratio = 512; /* Should depend on the bitrate, for now we assume LFE gets 1/8 the bits of mono */ lfe_ratio = 32; total = (nb_uncoupled<<8) /* mono */ + coupled_ratio*nb_coupled /* stereo */ + nb_lfe*lfe_ratio; channel_rate = 256*(opus_int64)(bitrate - lfe_offset*nb_lfe - stream_offset*(nb_coupled+nb_uncoupled) - channel_offset*nb_normal)/total; for (i=0;ilayout.nb_streams;i++) { if (ilayout.nb_coupled_streams) rate[i] = 2*channel_offset + IMAX(0, stream_offset+(channel_rate*coupled_ratio>>8)); else if (i!=st->lfe_stream) rate[i] = channel_offset + IMAX(0, stream_offset + channel_rate); else rate[i] = IMAX(0, lfe_offset+(channel_rate*lfe_ratio>>8)); } } static void ambisonics_rate_allocation( OpusMSEncoder *st, opus_int32 *rate, int frame_size, opus_int32 Fs ) { int i; opus_int32 total_rate; opus_int32 per_stream_rate; const int nb_channels = st->layout.nb_streams + st->layout.nb_coupled_streams; if (st->bitrate_bps==OPUS_AUTO) { total_rate = (st->layout.nb_coupled_streams + st->layout.nb_streams) * (Fs+60*Fs/frame_size) + st->layout.nb_streams * (opus_int32)15000; } else if (st->bitrate_bps==OPUS_BITRATE_MAX) { total_rate = nb_channels * 320000; } else { total_rate = st->bitrate_bps; } /* Allocate equal number of bits to Ambisonic (uncoupled) and non-diegetic * (coupled) streams */ per_stream_rate = total_rate / st->layout.nb_streams; for (i = 0; i < st->layout.nb_streams; i++) { rate[i] = per_stream_rate; } } static opus_int32 rate_allocation( OpusMSEncoder *st, opus_int32 *rate, int frame_size ) { int i; opus_int32 rate_sum=0; opus_int32 Fs; char *ptr; ptr = (char*)st + align(sizeof(OpusMSEncoder)); opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs)); if (st->mapping_type == MAPPING_TYPE_AMBISONICS) { ambisonics_rate_allocation(st, rate, frame_size, Fs); } else { surround_rate_allocation(st, rate, frame_size, Fs); } for (i=0;ilayout.nb_streams;i++) { rate[i] = IMAX(rate[i], 500); rate_sum += rate[i]; } return rate_sum; } /* Max size in case the encoder decides to return six frames (6 x 20 ms = 120 ms) */ #define MS_FRAME_TMP (6*1275+12) int opus_multistream_encode_native ( OpusMSEncoder *st, opus_copy_channel_in_func copy_channel_in, const void *pcm, int analysis_frame_size, unsigned char *data, opus_int32 max_data_bytes, int lsb_depth, downmix_func downmix, int float_api, void *user_data ) { opus_int32 Fs; int coupled_size; int mono_size; int s; char *ptr; int tot_size; VARDECL(opus_val16, buf); VARDECL(opus_val16, bandSMR); unsigned char tmp_data[MS_FRAME_TMP]; OpusRepacketizer rp; opus_int32 vbr; const CELTMode *celt_mode; opus_int32 bitrates[256]; opus_val16 bandLogE[42]; opus_val32 *mem = NULL; opus_val32 *preemph_mem=NULL; int frame_size; opus_int32 rate_sum; opus_int32 smallest_packet; ALLOC_STACK; if (st->mapping_type == MAPPING_TYPE_SURROUND) { preemph_mem = ms_get_preemph_mem(st); mem = ms_get_window_mem(st); } ptr = (char*)st + align(sizeof(OpusMSEncoder)); opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs)); opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_VBR(&vbr)); opus_encoder_ctl((OpusEncoder*)ptr, CELT_GET_MODE(&celt_mode)); frame_size = frame_size_select(analysis_frame_size, st->variable_duration, Fs); if (frame_size <= 0) { RESTORE_STACK; return OPUS_BAD_ARG; } /* Smallest packet the encoder can produce. */ smallest_packet = st->layout.nb_streams*2-1; /* 100 ms needs an extra byte per stream for the ToC. */ if (Fs/frame_size == 10) smallest_packet += st->layout.nb_streams; if (max_data_bytes < smallest_packet) { RESTORE_STACK; return OPUS_BUFFER_TOO_SMALL; } ALLOC(buf, 2*frame_size, opus_val16); coupled_size = opus_encoder_get_size(2); mono_size = opus_encoder_get_size(1); ALLOC(bandSMR, 21*st->layout.nb_channels, opus_val16); if (st->mapping_type == MAPPING_TYPE_SURROUND) { surround_analysis(celt_mode, pcm, bandSMR, mem, preemph_mem, frame_size, 120, st->layout.nb_channels, Fs, copy_channel_in, st->arch); } /* Compute bitrate allocation between streams (this could be a lot better) */ rate_sum = rate_allocation(st, bitrates, frame_size); if (!vbr) { if (st->bitrate_bps == OPUS_AUTO) { max_data_bytes = IMIN(max_data_bytes, 3*rate_sum/(3*8*Fs/frame_size)); } else if (st->bitrate_bps != OPUS_BITRATE_MAX) { max_data_bytes = IMIN(max_data_bytes, IMAX(smallest_packet, 3*st->bitrate_bps/(3*8*Fs/frame_size))); } } ptr = (char*)st + align(sizeof(OpusMSEncoder)); for (s=0;slayout.nb_streams;s++) { OpusEncoder *enc; enc = (OpusEncoder*)ptr; if (s < st->layout.nb_coupled_streams) ptr += align(coupled_size); else ptr += align(mono_size); opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrates[s])); if (st->mapping_type == MAPPING_TYPE_SURROUND) { opus_int32 equiv_rate; equiv_rate = st->bitrate_bps; if (frame_size*50 < Fs) equiv_rate -= 60*(Fs/frame_size - 50)*st->layout.nb_channels; if (equiv_rate > 10000*st->layout.nb_channels) opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND)); else if (equiv_rate > 7000*st->layout.nb_channels) opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_SUPERWIDEBAND)); else if (equiv_rate > 5000*st->layout.nb_channels) opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_WIDEBAND)); else opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND)); if (s < st->layout.nb_coupled_streams) { /* To preserve the spatial image, force stereo CELT on coupled streams */ opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY)); opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(2)); } } else if (st->mapping_type == MAPPING_TYPE_AMBISONICS) { opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY)); } } ptr = (char*)st + align(sizeof(OpusMSEncoder)); /* Counting ToC */ tot_size = 0; for (s=0;slayout.nb_streams;s++) { OpusEncoder *enc; int len; int curr_max; int c1, c2; int ret; opus_repacketizer_init(&rp); enc = (OpusEncoder*)ptr; if (s < st->layout.nb_coupled_streams) { int i; int left, right; left = get_left_channel(&st->layout, s, -1); right = get_right_channel(&st->layout, s, -1); (*copy_channel_in)(buf, 2, pcm, st->layout.nb_channels, left, frame_size, user_data); (*copy_channel_in)(buf+1, 2, pcm, st->layout.nb_channels, right, frame_size, user_data); ptr += align(coupled_size); if (st->mapping_type == MAPPING_TYPE_SURROUND) { for (i=0;i<21;i++) { bandLogE[i] = bandSMR[21*left+i]; bandLogE[21+i] = bandSMR[21*right+i]; } } c1 = left; c2 = right; } else { int i; int chan = get_mono_channel(&st->layout, s, -1); (*copy_channel_in)(buf, 1, pcm, st->layout.nb_channels, chan, frame_size, user_data); ptr += align(mono_size); if (st->mapping_type == MAPPING_TYPE_SURROUND) { for (i=0;i<21;i++) bandLogE[i] = bandSMR[21*chan+i]; } c1 = chan; c2 = -1; } if (st->mapping_type == MAPPING_TYPE_SURROUND) opus_encoder_ctl(enc, OPUS_SET_ENERGY_MASK(bandLogE)); /* number of bytes left (+Toc) */ curr_max = max_data_bytes - tot_size; /* Reserve one byte for the last stream and two for the others */ curr_max -= IMAX(0,2*(st->layout.nb_streams-s-1)-1); /* For 100 ms, reserve an extra byte per stream for the ToC */ if (Fs/frame_size == 10) curr_max -= st->layout.nb_streams-s-1; curr_max = IMIN(curr_max,MS_FRAME_TMP); /* Repacketizer will add one or two bytes for self-delimited frames */ if (s != st->layout.nb_streams-1) curr_max -= curr_max>253 ? 2 : 1; if (!vbr && s == st->layout.nb_streams-1) opus_encoder_ctl(enc, OPUS_SET_BITRATE(curr_max*(8*Fs/frame_size))); len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max, lsb_depth, pcm, analysis_frame_size, c1, c2, st->layout.nb_channels, downmix, float_api); if (len<0) { RESTORE_STACK; return len; } /* We need to use the repacketizer to add the self-delimiting lengths while taking into account the fact that the encoder can now return more than one frame at a time (e.g. 60 ms CELT-only) */ ret = opus_repacketizer_cat(&rp, tmp_data, len); /* If the opus_repacketizer_cat() fails, then something's seriously wrong with the encoder. */ if (ret != OPUS_OK) { RESTORE_STACK; return OPUS_INTERNAL_ERROR; } len = opus_repacketizer_out_range_impl(&rp, 0, opus_repacketizer_get_nb_frames(&rp), data, max_data_bytes-tot_size, s != st->layout.nb_streams-1, !vbr && s == st->layout.nb_streams-1); data += len; tot_size += len; } /*printf("\n");*/ RESTORE_STACK; return tot_size; } #if !defined(DISABLE_FLOAT_API) static void opus_copy_channel_in_float( opus_val16 *dst, int dst_stride, const void *src, int src_stride, int src_channel, int frame_size, void *user_data ) { const float *float_src; opus_int32 i; (void)user_data; float_src = (const float *)src; for (i=0;ilayout.nb_channels, IMAX(500*st->layout.nb_channels, value)); } st->bitrate_bps = value; } break; case OPUS_GET_BITRATE_REQUEST: { int s; opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } *value = 0; for (s=0;slayout.nb_streams;s++) { opus_int32 rate; OpusEncoder *enc; enc = (OpusEncoder*)ptr; if (s < st->layout.nb_coupled_streams) ptr += align(coupled_size); else ptr += align(mono_size); opus_encoder_ctl(enc, request, &rate); *value += rate; } } break; case OPUS_GET_LSB_DEPTH_REQUEST: case OPUS_GET_VBR_REQUEST: case OPUS_GET_APPLICATION_REQUEST: case OPUS_GET_BANDWIDTH_REQUEST: case OPUS_GET_COMPLEXITY_REQUEST: case OPUS_GET_PACKET_LOSS_PERC_REQUEST: case OPUS_GET_DTX_REQUEST: case OPUS_GET_VOICE_RATIO_REQUEST: case OPUS_GET_VBR_CONSTRAINT_REQUEST: case OPUS_GET_SIGNAL_REQUEST: case OPUS_GET_LOOKAHEAD_REQUEST: case OPUS_GET_SAMPLE_RATE_REQUEST: case OPUS_GET_INBAND_FEC_REQUEST: case OPUS_GET_FORCE_CHANNELS_REQUEST: case OPUS_GET_PREDICTION_DISABLED_REQUEST: case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST: { OpusEncoder *enc; /* For int32* GET params, just query the first stream */ opus_int32 *value = va_arg(ap, opus_int32*); enc = (OpusEncoder*)ptr; ret = opus_encoder_ctl(enc, request, value); } break; case OPUS_GET_FINAL_RANGE_REQUEST: { int s; opus_uint32 *value = va_arg(ap, opus_uint32*); opus_uint32 tmp; if (!value) { goto bad_arg; } *value=0; for (s=0;slayout.nb_streams;s++) { OpusEncoder *enc; enc = (OpusEncoder*)ptr; if (s < st->layout.nb_coupled_streams) ptr += align(coupled_size); else ptr += align(mono_size); ret = opus_encoder_ctl(enc, request, &tmp); if (ret != OPUS_OK) break; *value ^= tmp; } } break; case OPUS_SET_LSB_DEPTH_REQUEST: case OPUS_SET_COMPLEXITY_REQUEST: case OPUS_SET_VBR_REQUEST: case OPUS_SET_VBR_CONSTRAINT_REQUEST: case OPUS_SET_MAX_BANDWIDTH_REQUEST: case OPUS_SET_BANDWIDTH_REQUEST: case OPUS_SET_SIGNAL_REQUEST: case OPUS_SET_APPLICATION_REQUEST: case OPUS_SET_INBAND_FEC_REQUEST: case OPUS_SET_PACKET_LOSS_PERC_REQUEST: case OPUS_SET_DTX_REQUEST: case OPUS_SET_FORCE_MODE_REQUEST: case OPUS_SET_FORCE_CHANNELS_REQUEST: case OPUS_SET_PREDICTION_DISABLED_REQUEST: case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST: { int s; /* This works for int32 params */ opus_int32 value = va_arg(ap, opus_int32); for (s=0;slayout.nb_streams;s++) { OpusEncoder *enc; enc = (OpusEncoder*)ptr; if (s < st->layout.nb_coupled_streams) ptr += align(coupled_size); else ptr += align(mono_size); ret = opus_encoder_ctl(enc, request, value); if (ret != OPUS_OK) break; } } break; case OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST: { int s; opus_int32 stream_id; OpusEncoder **value; stream_id = va_arg(ap, opus_int32); if (stream_id<0 || stream_id >= st->layout.nb_streams) goto bad_arg; value = va_arg(ap, OpusEncoder**); if (!value) { goto bad_arg; } for (s=0;slayout.nb_coupled_streams) ptr += align(coupled_size); else ptr += align(mono_size); } *value = (OpusEncoder*)ptr; } break; case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); st->variable_duration = value; } break; case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } *value = st->variable_duration; } break; case OPUS_RESET_STATE: { int s; if (st->mapping_type == MAPPING_TYPE_SURROUND) { OPUS_CLEAR(ms_get_preemph_mem(st), st->layout.nb_channels); OPUS_CLEAR(ms_get_window_mem(st), st->layout.nb_channels*120); } for (s=0;slayout.nb_streams;s++) { OpusEncoder *enc; enc = (OpusEncoder*)ptr; if (s < st->layout.nb_coupled_streams) ptr += align(coupled_size); else ptr += align(mono_size); ret = opus_encoder_ctl(enc, OPUS_RESET_STATE); if (ret != OPUS_OK) break; } } break; default: ret = OPUS_UNIMPLEMENTED; break; } return ret; bad_arg: return OPUS_BAD_ARG; } int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...) { int ret; va_list ap; va_start(ap, request); ret = opus_multistream_encoder_ctl_va_list(st, request, ap); va_end(ap); return ret; } void opus_multistream_encoder_destroy(OpusMSEncoder *st) { opus_free(st); } jamulus-3.9.1+dfsg/libs/opus/src/opus_private.h0000644000175000017500000001514614340334543020562 0ustar vimervimer/* Copyright (c) 2012 Xiph.Org Foundation Written by Jean-Marc Valin */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef OPUS_PRIVATE_H #define OPUS_PRIVATE_H #include "arch.h" #include "opus.h" #include "celt.h" #include /* va_list */ #include /* offsetof */ struct OpusRepacketizer { unsigned char toc; int nb_frames; const unsigned char *frames[48]; opus_int16 len[48]; int framesize; }; typedef struct ChannelLayout { int nb_channels; int nb_streams; int nb_coupled_streams; unsigned char mapping[256]; } ChannelLayout; typedef enum { MAPPING_TYPE_NONE, MAPPING_TYPE_SURROUND, MAPPING_TYPE_AMBISONICS } MappingType; struct OpusMSEncoder { ChannelLayout layout; int arch; int lfe_stream; int application; int variable_duration; MappingType mapping_type; opus_int32 bitrate_bps; /* Encoder states go here */ /* then opus_val32 window_mem[channels*120]; */ /* then opus_val32 preemph_mem[channels]; */ }; struct OpusMSDecoder { ChannelLayout layout; /* Decoder states go here */ }; int opus_multistream_encoder_ctl_va_list(struct OpusMSEncoder *st, int request, va_list ap); int opus_multistream_decoder_ctl_va_list(struct OpusMSDecoder *st, int request, va_list ap); int validate_layout(const ChannelLayout *layout); int get_left_channel(const ChannelLayout *layout, int stream_id, int prev); int get_right_channel(const ChannelLayout *layout, int stream_id, int prev); int get_mono_channel(const ChannelLayout *layout, int stream_id, int prev); typedef void (*opus_copy_channel_in_func)( opus_val16 *dst, int dst_stride, const void *src, int src_stride, int src_channel, int frame_size, void *user_data ); typedef void (*opus_copy_channel_out_func)( void *dst, int dst_stride, int dst_channel, const opus_val16 *src, int src_stride, int frame_size, void *user_data ); #define MODE_SILK_ONLY 1000 #define MODE_HYBRID 1001 #define MODE_CELT_ONLY 1002 #define OPUS_SET_VOICE_RATIO_REQUEST 11018 #define OPUS_GET_VOICE_RATIO_REQUEST 11019 /** Configures the encoder's expected percentage of voice * opposed to music or other signals. * * @note This interface is currently more aspiration than actuality. It's * ultimately expected to bias an automatic signal classifier, but it currently * just shifts the static bitrate to mode mapping around a little bit. * * @param[in] x int: Voice percentage in the range 0-100, inclusive. * @hideinitializer */ #define OPUS_SET_VOICE_RATIO(x) OPUS_SET_VOICE_RATIO_REQUEST, __opus_check_int(x) /** Gets the encoder's configured voice ratio value, @see OPUS_SET_VOICE_RATIO * * @param[out] x int*: Voice percentage in the range 0-100, inclusive. * @hideinitializer */ #define OPUS_GET_VOICE_RATIO(x) OPUS_GET_VOICE_RATIO_REQUEST, __opus_check_int_ptr(x) #define OPUS_SET_FORCE_MODE_REQUEST 11002 #define OPUS_SET_FORCE_MODE(x) OPUS_SET_FORCE_MODE_REQUEST, __opus_check_int(x) typedef void (*downmix_func)(const void *, opus_val32 *, int, int, int, int, int); void downmix_float(const void *_x, opus_val32 *sub, int subframe, int offset, int c1, int c2, int C); void downmix_int(const void *_x, opus_val32 *sub, int subframe, int offset, int c1, int c2, int C); int is_digital_silence(const opus_val16* pcm, int frame_size, int channels, int lsb_depth); int encode_size(int size, unsigned char *data); opus_int32 frame_size_select(opus_int32 frame_size, int variable_duration, opus_int32 Fs); opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_size, unsigned char *data, opus_int32 out_data_bytes, int lsb_depth, const void *analysis_pcm, opus_int32 analysis_size, int c1, int c2, int analysis_channels, downmix_func downmix, int float_api); int opus_decode_native(OpusDecoder *st, const unsigned char *data, opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec, int self_delimited, opus_int32 *packet_offset, int soft_clip); /* Make sure everything is properly aligned. */ static OPUS_INLINE int align(int i) { struct foo {char c; union { void* p; opus_int32 i; opus_val32 v; } u;}; unsigned int alignment = offsetof(struct foo, u); /* Optimizing compilers should optimize div and multiply into and for all sensible alignment values. */ return ((i + alignment - 1) / alignment) * alignment; } int opus_packet_parse_impl(const unsigned char *data, opus_int32 len, int self_delimited, unsigned char *out_toc, const unsigned char *frames[48], opus_int16 size[48], int *payload_offset, opus_int32 *packet_offset); opus_int32 opus_repacketizer_out_range_impl(OpusRepacketizer *rp, int begin, int end, unsigned char *data, opus_int32 maxlen, int self_delimited, int pad); int pad_frame(unsigned char *data, opus_int32 len, opus_int32 new_len); int opus_multistream_encode_native ( struct OpusMSEncoder *st, opus_copy_channel_in_func copy_channel_in, const void *pcm, int analysis_frame_size, unsigned char *data, opus_int32 max_data_bytes, int lsb_depth, downmix_func downmix, int float_api, void *user_data ); int opus_multistream_decode_native( struct OpusMSDecoder *st, const unsigned char *data, opus_int32 len, void *pcm, opus_copy_channel_out_func copy_channel_out, int frame_size, int decode_fec, int soft_clip, void *user_data ); #endif /* OPUS_PRIVATE_H */ jamulus-3.9.1+dfsg/libs/opus/package_version0000644000175000017500000000003014340334543020147 0ustar vimervimerPACKAGE_VERSION="1.3.1" jamulus-3.9.1+dfsg/libs/opus/config.h.cmake.in0000644000175000017500000000006014340334543020171 0ustar vimervimer#cmakedefine PACKAGE_VERSION "@PACKAGE_VERSION@"jamulus-3.9.1+dfsg/libs/opus/ChangeLog0000644000175000017500000000000014340334543016633 0ustar vimervimerjamulus-3.9.1+dfsg/libs/opus/opus.pc.in0000644000175000017500000000053314340334543017013 0ustar vimervimer# Opus codec reference implementation pkg-config file prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: Opus Description: Opus IETF audio codec (@PC_BUILD@ build) URL: https://opus-codec.org/ Version: @VERSION@ Requires: Conflicts: Libs: -L${libdir} -lopus Libs.private: @LIBM@ Cflags: -I${includedir}/opus jamulus-3.9.1+dfsg/libs/opus/configure0000755000175000017500000173501614340334543017017 0ustar vimervimer#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for opus 1.3.1. # # Report bugs to . # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and opus@xiph.org $0: about your system, including any error possibly output $0: before this message. Then install a modern shell, or $0: manually run the script under such a shell if you do $0: have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" SHELL=${CONFIG_SHELL-/bin/sh} test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='opus' PACKAGE_TARNAME='opus' PACKAGE_VERSION='1.3.1' PACKAGE_STRING='opus 1.3.1' PACKAGE_BUGREPORT='opus@xiph.org' PACKAGE_URL='' ac_unique_file="src/opus_encoder.c" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS PC_BUILD EXTRA_PROGRAMS_FALSE EXTRA_PROGRAMS_TRUE HAVE_DOXYGEN_FALSE HAVE_DOXYGEN_TRUE HAVE_DOT HAVE_DOXYGEN OPUS_HAVE_RTCD HAVE_ARM_NE10_FALSE HAVE_ARM_NE10_TRUE HAVE_ARM_NEON_INTR_FALSE HAVE_ARM_NEON_INTR_TRUE CPU_ARM_FALSE CPU_ARM_TRUE OPUS_X86_AVX_CFLAGS OPUS_X86_SSE4_1_CFLAGS OPUS_X86_SSE2_CFLAGS OPUS_X86_SSE_CFLAGS NE10_LIBS NE10_CFLAGS HAVE_ARM_NE10 OPUS_ARM_NEON_INTR_CFLAGS ARM_NEON_INTR_CFLAGS X86_AVX_CFLAGS X86_SSE4_1_CFLAGS X86_SSE2_CFLAGS X86_SSE_CFLAGS HAVE_AVX_FALSE HAVE_AVX_TRUE HAVE_SSE4_1_FALSE HAVE_SSE4_1_TRUE HAVE_SSE2_FALSE HAVE_SSE2_TRUE HAVE_SSE_FALSE HAVE_SSE_TRUE ARM2GNU_PARAMS OPUS_ARM_MAY_HAVE_NEON OPUS_ARM_MAY_HAVE_MEDIA OPUS_ARM_MAY_HAVE_EDSP OPUS_ARM_EXTERNAL_ASM_FALSE OPUS_ARM_EXTERNAL_ASM_TRUE HAVE_PERL OPUS_ARM_INLINE_ASM_FALSE OPUS_ARM_INLINE_ASM_TRUE CUSTOM_MODES_FALSE CUSTOM_MODES_TRUE DISABLE_FLOAT_API_FALSE DISABLE_FLOAT_API_TRUE FIXED_POINT_FALSE FIXED_POINT_TRUE LIBM am__fastdepCCAS_FALSE am__fastdepCCAS_TRUE CCASDEPMODE CCASFLAGS CCAS CPP LT_SYS_LIBRARY_PATH OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL RANLIB ac_ct_AR AR DLLTOOL OBJDUMP LN_S NM ac_ct_DUMPBIN DUMPBIN LD FGREP EGREP GREP SED am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC LIBTOOL host_os host_vendor host_cpu host build_os build_vendor build_cpu build MAINT MAINTAINER_MODE_FALSE MAINTAINER_MODE_TRUE am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM OPUS_LT_AGE OPUS_LT_REVISION OPUS_LT_CURRENT AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_silent_rules enable_maintainer_mode enable_shared enable_static with_pic enable_fast_install with_aix_soname enable_dependency_tracking with_gnu_ld with_sysroot enable_libtool_lock enable_fixed_point enable_fixed_point_debug enable_float_api enable_custom_modes enable_float_approx enable_asm enable_rtcd enable_intrinsics with_NE10 with_NE10_libraries with_NE10_includes enable_assertions enable_hardening enable_fuzzing enable_check_asm enable_doc enable_extra_programs enable_rfc8251 enable_stack_protector ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS LT_SYS_LIBRARY_PATH CPP CCAS CCASFLAGS X86_SSE_CFLAGS X86_SSE2_CFLAGS X86_SSE4_1_CFLAGS X86_AVX_CFLAGS ARM_NEON_INTR_CFLAGS' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures opus 1.3.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/opus] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of opus 1.3.1:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-silent-rules less verbose build output (undo: "make V=1") --disable-silent-rules verbose build output (undo: "make V=0") --disable-maintainer-mode disable make rules and dependencies not useful (and sometimes confusing) to the casual installer --enable-shared[=PKGS] build shared libraries [default=yes] --enable-static[=PKGS] build static libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build --disable-libtool-lock avoid locking (might break parallel builds) --enable-fixed-point compile without floating point (for machines without a fast enough FPU) --enable-fixed-point-debug debug fixed-point implementation --disable-float-api compile without the floating point API (for machines with no float library) --enable-custom-modes enable non-Opus modes, e.g. 44.1 kHz & 2^n frames --enable-float-approx enable fast approximations for floating point --disable-asm Disable assembly optimizations --disable-rtcd Disable run-time CPU capabilities detection --disable-intrinsics Disable intrinsics optimizations --enable-assertions enable additional software error checking --disable-hardening disable run-time checks that are cheap and safe for use in production --enable-fuzzing causes the encoder to make random decisions (do not use in production) --enable-check-asm enable bit-exactness checks between optimized and c implementations --disable-doc Do not build API documentation --disable-extra-programs Do not build extra programs (demo and tests) --disable-rfc8251 Disable bitstream fixes from RFC 8251 --disable-stack-protector Disable compiler stack hardening Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-aix-soname=aix|svr4|both shared library versioning (aka "SONAME") variant to provide on AIX, [default=aix]. --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified). --with-NE10=PFX Prefix where libNE10 is installed (optional) --with-NE10-libraries=DIR Directory where libNE10 library is installed (optional) --with-NE10-includes=DIR Directory where libNE10 header files are installed (optional) Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory LT_SYS_LIBRARY_PATH User-defined run-time library search path. CPP C preprocessor CCAS assembler compiler command (defaults to CC) CCASFLAGS assembler compiler flags (defaults to CFLAGS) X86_SSE_CFLAGS C compiler flags to compile SSE intrinsics [default=-msse] X86_SSE2_CFLAGS C compiler flags to compile SSE2 intrinsics [default=-msse2] X86_SSE4_1_CFLAGS C compiler flags to compile SSE4.1 intrinsics [default=-msse4.1] X86_AVX_CFLAGS C compiler flags to compile AVX intrinsics [default=-mavx] ARM_NEON_INTR_CFLAGS C compiler flags to compile ARM NEON intrinsics [default=-mfpu=neon / -mfpu=neon -mfloat-abi=softfp] Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF opus configure 1.3.1 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ( $as_echo "## ---------------------------- ## ## Report this to opus@xiph.org ## ## ---------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by opus $as_me 1.3.1, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=0;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' # For libtool. OPUS_LT_CURRENT=8 OPUS_LT_REVISION=0 OPUS_LT_AGE=8 am__api_version='1.15' ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='opus' VERSION='1.3.1' # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # mkdir_p='$(MKDIR_P)' # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar pax cpio none' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 $as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } # Check whether --enable-maintainer-mode was given. if test "${enable_maintainer_mode+set}" = set; then : enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval else USE_MAINTAINER_MODE=yes fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 $as_echo "$USE_MAINTAINER_MODE" >&6; } if test $USE_MAINTAINER_MODE = yes; then MAINTAINER_MODE_TRUE= MAINTAINER_MODE_FALSE='#' else MAINTAINER_MODE_TRUE='#' MAINTAINER_MODE_FALSE= fi MAINT=$MAINTAINER_MODE_TRUE # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac case $host_os in *mingw32* ) MINGW32=yes;; * ) MINGW32=no;; esac case `pwd` in *\ * | *\ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 $as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.4.6' macro_revision='2.4.6' ltmain=$ac_aux_dir/ltmain.sh # Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\(["`$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 $as_echo_n "checking how to print strings... " >&6; } # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "" } case $ECHO in printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 $as_echo "printf" >&6; } ;; print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 $as_echo "print -r" >&6; } ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 $as_echo "cat" >&6; } ;; esac DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 $as_echo_n "checking whether $CC understands -c and -o together... " >&6; } if ${am_cv_prog_cc_c_o+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 $as_echo "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 $as_echo "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } if ${ac_cv_path_FGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else if test -z "$FGREP"; then ac_path_FGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in fgrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_FGREP" || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in *GNU*) ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_FGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_FGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_FGREP=$FGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 $as_echo "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" test -z "$GREP" && GREP=grep # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 $as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } if ${lt_cv_path_NM+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM=$NM else lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. tmp_nm=$ac_dir/$lt_tmp_nm if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 $as_echo "$lt_cv_path_NM" >&6; } if test no != "$lt_cv_path_NM"; then NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else if test -n "$ac_tool_prefix"; then for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 $as_echo "$DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$DUMPBIN" && break done fi if test -z "$DUMPBIN"; then ac_ct_DUMPBIN=$DUMPBIN for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 $as_echo "$ac_ct_DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_DUMPBIN" && break done if test "x$ac_ct_DUMPBIN" = x; then DUMPBIN=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN fi fi case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: ;; esac fi if test : != "$DUMPBIN"; then NM=$DUMPBIN fi fi test -z "$NM" && NM=nm { $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 $as_echo_n "checking the name lister ($NM) interface... " >&6; } if ${lt_cv_nm_interface+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 $as_echo "$lt_cv_nm_interface" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi # find the maximum length of command line arguments { $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 $as_echo_n "checking the maximum length of command line arguments... " >&6; } if ${lt_cv_sys_max_cmd_len+:} false; then : $as_echo_n "(cached) " >&6 else i=0 teststring=ABCD case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac fi if test -n "$lt_cv_sys_max_cmd_len"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 $as_echo "$lt_cv_sys_max_cmd_len" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 $as_echo "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len : ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 $as_echo_n "checking how to convert $build file names to $host format... " >&6; } if ${lt_cv_to_host_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac fi to_host_file_cmd=$lt_cv_to_host_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 $as_echo "$lt_cv_to_host_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 $as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } if ${lt_cv_to_tool_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else #assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac fi to_tool_file_cmd=$lt_cv_to_tool_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 $as_echo "$lt_cv_to_tool_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 $as_echo_n "checking for $LD option to reload object files... " >&6; } if ${lt_cv_ld_reload_flag+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_reload_flag='-r' fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 $as_echo "$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in cygwin* | mingw* | pw32* | cegcc*) if test yes != "$GCC"; then reload_cmds=false fi ;; darwin*) if test yes = "$GCC"; then reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 $as_echo "$OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 $as_echo "$ac_ct_OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi test -z "$OBJDUMP" && OBJDUMP=objdump { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 $as_echo_n "checking how to recognize dependent libraries... " >&6; } if ${lt_cv_deplibs_check_method+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # that responds to the $file_magic_cmd with a given extended regex. # If you have 'file' or equivalent on your system and you're not sure # whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[3-9]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd* | bitrig*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; os2*) lt_cv_deplibs_check_method=pass_all ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 $as_echo "$lt_cv_deplibs_check_method" >&6; } file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 $as_echo "$DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 $as_echo "$ac_ct_DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi test -z "$DLLTOOL" && DLLTOOL=dlltool { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 $as_echo_n "checking how to associate runtime and link libraries... " >&6; } if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 $as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO if test -n "$ac_tool_prefix"; then for ac_prog in ar do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} : ${AR_FLAGS=cru} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 $as_echo_n "checking for archiver @FILE support... " >&6; } if ${lt_cv_ar_at_file+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ar_at_file=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 $as_echo "$lt_cv_ar_at_file" >&6; } if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi test -z "$RANLIB" && RANLIB=: # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. { $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 $as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } if ${lt_cv_sys_global_symbol_pipe+:} false; then : $as_echo_n "(cached) " >&6 else # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) if test ia64 = "$host_cpu"; then symcode='[ABCDEGRST]' fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; sco3.2v5*) symcode='[DT]' ;; sysv4.2uw2*) symcode='[DT]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[ABDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" lt_c_name_lib_hook="\ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" else # Disable hooks by default. lt_cv_sys_global_symbol_to_import= lt_cdecl_hook= lt_c_name_hook= lt_c_name_lib_hook= fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ " /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ " /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ " {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ " s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= fi done fi if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 $as_echo "failed" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; } fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then nm_file_list_spec='@' fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 $as_echo_n "checking for sysroot... " >&6; } # Check whether --with-sysroot was given. if test "${with_sysroot+set}" = set; then : withval=$with_sysroot; else with_sysroot=no fi lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 $as_echo "$with_sysroot" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 $as_echo "${lt_sysroot:-no}" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 $as_echo_n "checking for a working dd... " >&6; } if ${ac_cv_path_lt_DD+:} false; then : $as_echo_n "(cached) " >&6 else printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i : ${lt_DD:=$DD} if test -z "$lt_DD"; then ac_path_lt_DD_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in dd; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_lt_DD" || continue if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: fi $ac_path_lt_DD_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_lt_DD"; then : fi else ac_cv_path_lt_DD=$lt_DD fi rm -f conftest.i conftest2.i conftest.out fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 $as_echo "$ac_cv_path_lt_DD" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 $as_echo_n "checking how to truncate binary pipes... " >&6; } if ${lt_cv_truncate_bin+:} false; then : $as_echo_n "(cached) " >&6 else printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i lt_cv_truncate_bin= if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" fi rm -f conftest.i conftest2.i conftest.out test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 $as_echo "$lt_cv_truncate_bin" >&6; } # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in $*""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } # Check whether --enable-libtool-lock was given. if test "${enable_libtool_lock+set}" = set; then : enableval=$enable_libtool_lock; fi test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out what ABI is being produced by ac_compile, and set mode # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; *ELF-64*) HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test yes = "$lt_cv_prog_gnu_ld"; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; mips64*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then emul=elf case `/usr/bin/file conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; *64-bit*) emul="${emul}64" ;; esac case `/usr/bin/file conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; *LSB*) emul="${emul}ltsmip" ;; esac case `/usr/bin/file conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; esac LD="${LD-ld} -m $emul" fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when # doing 32-bit compilation for a host where ld defaults to 64-bit, or # vice versa); the common cases where no linker options are needed do # not appear in the list. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `/usr/bin/file conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*linux*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 $as_echo_n "checking whether the C compiler needs -belf... " >&6; } if ${lt_cv_cc_needs_belf+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_cc_needs_belf=yes else lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 $as_echo "$lt_cv_cc_needs_belf" >&6; } if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD=${LD-ld}_sol2 fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks=$enable_libtool_lock if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. set dummy ${ac_tool_prefix}mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$MANIFEST_TOOL"; then ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL if test -n "$MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 $as_echo "$MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_MANIFEST_TOOL"; then ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL # Extract the first word of "mt", so it can be a program name with args. set dummy mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_MANIFEST_TOOL"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL if test -n "$ac_ct_MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 $as_echo "$ac_ct_MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_MANIFEST_TOOL" = x; then MANIFEST_TOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL fi else MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" fi test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 $as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } if ${lt_cv_path_mainfest_tool+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&5 if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 $as_echo "$lt_cv_path_mainfest_tool" >&6; } if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi case $host_os in rhapsody* | darwin*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 $as_echo "$DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 $as_echo "$ac_ct_DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL fi else DSYMUTIL="$ac_cv_prog_DSYMUTIL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 $as_echo "$NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_NMEDIT="nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 $as_echo "$ac_ct_NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT fi else NMEDIT="$ac_cv_prog_NMEDIT" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 $as_echo "$LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_LIPO="lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 $as_echo "$ac_ct_LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO fi else LIPO="$ac_cv_prog_LIPO" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 $as_echo "$OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL="otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 $as_echo "$ac_ct_OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL fi else OTOOL="$ac_cv_prog_OTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 $as_echo "$OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL64="otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 $as_echo "$ac_ct_OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 fi else OTOOL64="$ac_cv_prog_OTOOL64" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 $as_echo_n "checking for -single_module linker flag... " >&6; } if ${lt_cv_apple_cc_single_mod+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_apple_cc_single_mod=no if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&5 $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&5 # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 fi rm -rf libconftest.dylib* rm -f conftest.* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 $as_echo "$lt_cv_apple_cc_single_mod" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } if ${lt_cv_ld_exported_symbols_list+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_ld_exported_symbols_list=yes else lt_cv_ld_exported_symbols_list=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 $as_echo_n "checking for -force_load linker flag... " >&6; } if ${lt_cv_ld_force_load+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 echo "$AR cru libconftest.a conftest.o" >&5 $AR cru libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&5 elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&5 fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 $as_echo "$lt_cv_ld_force_load" >&6; } case $host_os in rhapsody* | darwin1.[012]) _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[91]*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; 10.[012][,.]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac # func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x$2 in x) ;; *:) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" ;; x:*) eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" ;; *::*) eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" ;; *) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" ;; esac } ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in dlfcn.h do : ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default " if test "x$ac_cv_header_dlfcn_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DLFCN_H 1 _ACEOF fi done # Set options enable_dlopen=no enable_win32_dll=no # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then : enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS=$lt_save_ifs ;; esac else enable_shared=yes fi # Check whether --enable-static was given. if test "${enable_static+set}" = set; then : enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS=$lt_save_ifs ;; esac else enable_static=yes fi # Check whether --with-pic was given. if test "${with_pic+set}" = set; then : withval=$with_pic; lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac else pic_mode=default fi # Check whether --enable-fast-install was given. if test "${enable_fast_install+set}" = set; then : enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS=$lt_save_ifs ;; esac else enable_fast_install=yes fi shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[5-9]*,yes) { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 $as_echo_n "checking which variant of shared library versioning to provide... " >&6; } # Check whether --with-aix-soname was given. if test "${with_aix_soname+set}" = set; then : withval=$with_aix_soname; case $withval in aix|svr4|both) ;; *) as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 ;; esac lt_cv_with_aix_soname=$with_aix_soname else if ${lt_cv_with_aix_soname+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_with_aix_soname=aix fi with_aix_soname=$lt_cv_with_aix_soname fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 $as_echo "$with_aix_soname" >&6; } if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac # This can be used to rebuild libtool when needed LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' test -z "$LN_S" && LN_S="ln -s" if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 $as_echo_n "checking for objdir... " >&6; } if ${lt_cv_objdir+:} false; then : $as_echo_n "(cached) " >&6 else rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 $as_echo "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir cat >>confdefs.h <<_ACEOF #define LT_OBJDIR "$lt_cv_objdir/" _ACEOF case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a '.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld old_CC=$CC old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o func_cc_basename $compiler cc_basename=$func_cc_basename_result # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 $as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/${ac_tool_prefix}file"; then lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 $as_echo_n "checking for file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/file"; then lt_cv_path_MAGIC_CMD=$ac_dir/"file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac # Use C for the default configuration in the libtool script lt_save_CC=$CC ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= if test yes = "$GCC"; then case $cc_basename in nvcc*) lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; *) lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 $as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= if test yes = "$GCC"; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi lt_prog_compiler_pic='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; *) lt_prog_compiler_pic='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 lt_prog_compiler_wl='-Xlinker ' if test -n "$lt_prog_compiler_pic"; then lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' case $cc_basename in nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; esac ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static='$wl-static' ;; esac ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64, which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # Lahey Fortran 8.1. lf95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='--shared' lt_prog_compiler_static='--static' ;; nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; tcc*) # Fabrice Bellard et al's Tiny C Compiler lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; *Sun\ F* | *Sun*Fortran*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Intel*\ [CF]*Compiler*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; *Portland\ Group*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; esac ;; esac ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; rdos*) lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if ${lt_cv_prog_compiler_pic+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic=$lt_prog_compiler_pic fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 $as_echo "$lt_cv_prog_compiler_pic" >&6; } lt_prog_compiler_pic=$lt_cv_prog_compiler_pic # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } if ${lt_cv_prog_compiler_pic_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 $as_echo "$lt_cv_prog_compiler_pic_works" >&6; } if test yes = "$lt_cv_prog_compiler_pic_works"; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if ${lt_cv_prog_compiler_static_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works=yes fi else lt_cv_prog_compiler_static_works=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 $as_echo "$lt_cv_prog_compiler_static_works" >&6; } if test yes = "$lt_cv_prog_compiler_static_works"; then : else lt_prog_compiler_static= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } hard_links=nottested if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test no = "$hard_links"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } runpath_var= allow_undefined_flag= always_export_symbols=no archive_cmds= archive_expsym_cmds= compiler_needs_object=no enable_shared_with_static_runtimes=no export_dynamic_flag_spec= export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' hardcode_automatic=no hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported inherit_rpath=no link_all_deplibs=unknown module_cmds= module_expsym_cmds= old_archive_from_new_cmds= old_archive_from_expsyms_cmds= thread_safe_flag_spec= whole_archive_flag_spec= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ' (' and ')$', so one must not match beginning or # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', # as well as any symbol that contains 'd'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd* | bitrig*) with_gnu_ld=no ;; esac ld_shlibs=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; *\ \(GNU\ Binutils\)\ [3-9]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' export_dynamic_flag_spec='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test ia64 != "$host_cpu"; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' export_dynamic_flag_spec='$wl--export-all-symbols' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; haiku*) archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' link_all_deplibs=yes ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported shrext_cmds=.dll archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='$wl-rpath,$libdir' export_dynamic_flag_spec='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; nagfor*) # NAGFOR 5.3 tmp_sharedflag='-Wl,-shared' ;; xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) export_dynamic_flag_spec='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test no = "$ld_shlibs"; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds='' hardcode_direct=yes hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes file_list_spec='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # traditional, no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. hardcode_direct=no hardcode_direct_absolute=no ;; esac if test yes = "$GCC"; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag="$shared_flag "'$wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi export_dynamic_flag_spec='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag=' $wl-bernotok' allow_undefined_flag=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' fi archive_cmds_need_lc=yes archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes file_list_spec='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' postlink_cmds='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_from_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' enable_shared_with_static_runtimes=yes ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported if test yes = "$lt_cv_ld_force_load"; then whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec='' fi link_all_deplibs=yes allow_undefined_flag=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" else ld_shlibs=no fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test yes = "$GCC"; then archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='$wl-E' ;; hpux10*) if test yes,no = "$GCC,$with_gnu_ld"; then archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 $as_echo_n "checking if $CC understands -b... " >&6; } if ${lt_cv_prog_compiler__b+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler__b=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -b" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler__b=yes fi else lt_cv_prog_compiler__b=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 $as_echo "$lt_cv_prog_compiler__b" >&6; } if test yes = "$lt_cv_prog_compiler__b"; then archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi ;; esac fi if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test yes = "$GCC"; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 $as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } if ${lt_cv_irix_exported_symbol+:} false; then : $as_echo_n "(cached) " >&6 else save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (void) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_irix_exported_symbol=yes else lt_cv_irix_exported_symbol=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 $as_echo "$lt_cv_irix_exported_symbol" >&6; } if test yes = "$lt_cv_irix_exported_symbol"; then archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes ;; linux*) case $cc_basename in tcc*) # Fabrice Bellard et al's Tiny C Compiler ld_shlibs=yes archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; *nto* | *qnx*) ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='$wl-rpath,$libdir' export_dynamic_flag_spec='$wl-E' else archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='$wl-rpath,$libdir' fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported shrext_cmds=.dll archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes ;; osf3*) if test yes = "$GCC"; then allow_undefined_flag=' $wl-expect_unresolved $wl\*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test yes = "$GCC"; then allow_undefined_flag=' $wl-expect_unresolved $wl\*' archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi archive_cmds_need_lc='no' hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z defs' if test yes = "$GCC"; then wlarc='$wl' archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='$wl' archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test yes = "$GCC"; then whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi ;; esac link_all_deplibs=yes ;; sunos4*) if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) case $host_vendor in sni) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds='$CC -r -o $output$reload_objs' hardcode_direct=no ;; motorola) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag='$wl-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag='$wl-z,text' allow_undefined_flag='$wl-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='$wl-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='$wl-Bexport' runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='$wl-Blargedynsym' ;; esac fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 $as_echo "$ld_shlibs" >&6; } test no = "$ld_shlibs" && can_build_shared=no with_gnu_ld=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test yes,yes = "$GCC,$enable_shared"; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } if ${lt_cv_archive_cmds_need_lc+:} false; then : $as_echo_n "(cached) " >&6 else $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc=no else lt_cv_archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 $as_echo "$lt_cv_archive_cmds_need_lc" >&6; } archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } if test yes = "$GCC"; then case $host_os in darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` # ...but if some path component already ends with the multilib dir we assume # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= ;; esac for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" elif test -n "$lt_multi_os_dir"; then test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS = " "; FS = "/|\n";} { lt_foo = ""; lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[lt_foo]++; } if (lt_freq[lt_foo] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's|/\([A-Za-z]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a(lib.so.V)' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. hardcode_libdir_flag_spec='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if ${lt_cv_shlibpath_overrides_runpath+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Add ABI-specific directories to the system library path. sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || test yes = "$hardcode_automatic"; then # We can hardcode non-existent directories. if test no != "$hardcode_direct" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && test no != "$hardcode_minus_L"; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 $as_echo "$hardcode_action" >&6; } if test relink = "$hardcode_action" || test yes = "$inherit_rpath"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; tpf*) # Don't try to run any link tests for TPF. We know it's impossible # because TPF is a cross-compiler, and we know how we open DSOs. lt_cv_dlopen=dlopen lt_cv_dlopen_libs= lt_cv_dlopen_self=no ;; *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes; then : lt_cv_dlopen=shl_load else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 $as_echo_n "checking for shl_load in -ldld... " >&6; } if ${ac_cv_lib_dld_shl_load+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); int main () { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_shl_load=yes else ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 $as_echo "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes; then : lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld else ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes; then : lt_cv_dlopen=dlopen else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 $as_echo_n "checking for dlopen in -lsvld... " >&6; } if ${ac_cv_lib_svld_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_svld_dlopen=yes else ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes; then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 $as_echo_n "checking for dld_link in -ldld... " >&6; } if ${ac_cv_lib_dld_dld_link+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dld_link (); int main () { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_dld_link=yes else ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 $as_echo "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes; then : lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld fi fi fi fi fi fi ;; esac if test no = "$lt_cv_dlopen"; then enable_dlopen=no else enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS=$CPPFLAGS test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 $as_echo_n "checking whether a program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self+:} false; then : $as_echo_n "(cached) " >&6 else if test yes = "$cross_compiling"; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 $as_echo "$lt_cv_dlopen_self" >&6; } if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self_static+:} false; then : $as_echo_n "(cached) " >&6 else if test yes = "$cross_compiling"; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 $as_echo "$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS=$save_CPPFLAGS LDFLAGS=$save_LDFLAGS LIBS=$save_LIBS ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi striplib= old_striplib= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 $as_echo_n "checking whether stripping libraries is possible... " >&6; } if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP"; then striplib="$STRIP -x" old_striplib="$STRIP -S" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; esac fi # Report what library types will actually be built { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 $as_echo_n "checking if libtool supports shared libraries... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 $as_echo "$can_build_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 $as_echo_n "checking whether to build shared libraries... " >&6; } test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 $as_echo "$enable_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 $as_echo_n "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 $as_echo "$enable_static" >&6; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CC=$lt_save_CC ac_config_commands="$ac_config_commands libtool" # Only expand once: { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5 $as_echo_n "checking for $CC option to accept ISO C99... " >&6; } if ${ac_cv_prog_cc_c99+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c99=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include #include // Check varargs macros. These examples are taken from C99 6.10.3.5. #define debug(...) fprintf (stderr, __VA_ARGS__) #define showlist(...) puts (#__VA_ARGS__) #define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) static void test_varargs_macros (void) { int x = 1234; int y = 5678; debug ("Flag"); debug ("X = %d\n", x); showlist (The first, second, and third items.); report (x>y, "x is %d but y is %d", x, y); } // Check long long types. #define BIG64 18446744073709551615ull #define BIG32 4294967295ul #define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) #if !BIG_OK your preprocessor is broken; #endif #if BIG_OK #else your preprocessor is broken; #endif static long long int bignum = -9223372036854775807LL; static unsigned long long int ubignum = BIG64; struct incomplete_array { int datasize; double data[]; }; struct named_init { int number; const wchar_t *name; double average; }; typedef const char *ccp; static inline int test_restrict (ccp restrict text) { // See if C++-style comments work. // Iterate through items via the restricted pointer. // Also check for declarations in for loops. for (unsigned int i = 0; *(text+i) != '\0'; ++i) continue; return 0; } // Check varargs and va_copy. static void test_varargs (const char *format, ...) { va_list args; va_start (args, format); va_list args_copy; va_copy (args_copy, args); const char *str; int number; float fnumber; while (*format) { switch (*format++) { case 's': // string str = va_arg (args_copy, const char *); break; case 'd': // int number = va_arg (args_copy, int); break; case 'f': // float fnumber = va_arg (args_copy, double); break; default: break; } } va_end (args_copy); va_end (args); } int main () { // Check bool. _Bool success = false; // Check restrict. if (test_restrict ("String literal") == 0) success = true; char *restrict newvar = "Another string"; // Check varargs. test_varargs ("s, d' f .", "string", 65, 34.234); test_varargs_macros (); // Check flexible array members. struct incomplete_array *ia = malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); ia->datasize = 10; for (int i = 0; i < ia->datasize; ++i) ia->data[i] = i * 1.234; // Check named initializers. struct named_init ni = { .number = 34, .name = L"Test wide string", .average = 543.34343, }; ni.number = 58; int dynamic_array[ni.number]; dynamic_array[ni.number - 1] = 543; // work around unused variable warnings return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x' || dynamic_array[ni.number - 1] != 543); ; return 0; } _ACEOF for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99 do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c99=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c99" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c99" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c99" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 $as_echo "$ac_cv_prog_cc_c99" >&6; } ;; esac if test "x$ac_cv_prog_cc_c99" != xno; then : fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if ${ac_cv_c_const+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __cplusplus /* Ultrix mips cc rejects this sort of thing. */ typedef int charset[2]; const charset cs = { 0, 0 }; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this sort of thing. */ char tx; char *t = &tx; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; } bx; struct s *b = &bx; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_const=yes else ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then $as_echo "#define const /**/" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 $as_echo_n "checking for inline... " >&6; } if ${ac_cv_c_inline+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; static $ac_kw foo_t static_foo () {return 0; } $ac_kw foo_t foo () {return 0; } #endif _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_inline=$ac_kw fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_inline" != no && break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 $as_echo "$ac_cv_c_inline" >&6; } case $ac_cv_c_inline in inline | yes) ;; *) case $ac_cv_c_inline in no) ac_val=;; *) ac_val=$ac_cv_c_inline;; esac cat >>confdefs.h <<_ACEOF #ifndef __cplusplus #define inline $ac_val #endif _ACEOF ;; esac # By default we simply use the C compiler to build assembly code. test "${CCAS+set}" = set || CCAS=$CC test "${CCASFLAGS+set}" = set || CCASFLAGS=$CFLAGS depcc="$CCAS" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CCAS_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CCAS_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CCAS_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CCAS_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CCAS_dependencies_compiler_type" >&5 $as_echo "$am_cv_CCAS_dependencies_compiler_type" >&6; } CCASDEPMODE=depmode=$am_cv_CCAS_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CCAS_dependencies_compiler_type" = gcc3; then am__fastdepCCAS_TRUE= am__fastdepCCAS_FALSE='#' else am__fastdepCCAS_TRUE='#' am__fastdepCCAS_FALSE= fi $as_echo "#define OPUS_BUILD /**/" >>confdefs.h #Use a hacked up version of autoconf's AC_C_RESTRICT because it's not #strong enough a test to detect old buggy versions of GCC (e.g. 2.95.3) #Note: Both this and the test for variable-size arrays below are also # done by AC_PROG_CC_C99, but not thoroughly enough apparently. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C/C++ restrict keyword" >&5 $as_echo_n "checking for C/C++ restrict keyword... " >&6; } if ${ac_cv_c_restrict+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_restrict=no # The order here caters to the fact that C++ does not require restrict. for ac_kw in __restrict __restrict__ _Restrict restrict; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ typedef int * int_ptr; int foo (int_ptr $ac_kw ip, int * $ac_kw baz[]) { return ip[0]; } int main () { int s[1]; int * $ac_kw t = s; t[0] = 0; return foo(t, (void *)0) ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_restrict=$ac_kw fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_restrict" != no && break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_restrict" >&5 $as_echo "$ac_cv_c_restrict" >&6; } case $ac_cv_c_restrict in restrict) ;; no) $as_echo "#define restrict /**/" >>confdefs.h ;; *) cat >>confdefs.h <<_ACEOF #define restrict $ac_cv_c_restrict _ACEOF ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C99 variable-size arrays" >&5 $as_echo_n "checking for C99 variable-size arrays... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { static int x; char a[++x]; a[sizeof a - 1] = 0; int N; return a[0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : has_var_arrays=yes use_alloca="no (using var arrays)" $as_echo "#define VAR_ARRAYS 1" >>confdefs.h else has_var_arrays=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $has_var_arrays" >&5 $as_echo "$has_var_arrays" >&6; } if test "$has_var_arrays" = "no"; then : for ac_header in alloca.h do : ac_fn_c_check_header_mongrel "$LINENO" "alloca.h" "ac_cv_header_alloca_h" "$ac_includes_default" if test "x$ac_cv_header_alloca_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_ALLOCA_H 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5 $as_echo_n "checking for alloca... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int foo=10; int *array = alloca(foo); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : use_alloca=yes; $as_echo "#define USE_ALLOCA /**/" >>confdefs.h else use_alloca=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $use_alloca" >&5 $as_echo "$use_alloca" >&6; } fi LIBM= case $host in *-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _mwvalidcheckl in -lmw" >&5 $as_echo_n "checking for _mwvalidcheckl in -lmw... " >&6; } if ${ac_cv_lib_mw__mwvalidcheckl+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lmw $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char _mwvalidcheckl (); int main () { return _mwvalidcheckl (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_mw__mwvalidcheckl=yes else ac_cv_lib_mw__mwvalidcheckl=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mw__mwvalidcheckl" >&5 $as_echo "$ac_cv_lib_mw__mwvalidcheckl" >&6; } if test "x$ac_cv_lib_mw__mwvalidcheckl" = xyes; then : LIBM=-lmw fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cos in -lm" >&5 $as_echo_n "checking for cos in -lm... " >&6; } if ${ac_cv_lib_m_cos+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char cos (); int main () { return cos (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_cos=yes else ac_cv_lib_m_cos=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_cos" >&5 $as_echo "$ac_cv_lib_m_cos" >&6; } if test "x$ac_cv_lib_m_cos" = xyes; then : LIBM="$LIBM -lm" fi ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cos in -lm" >&5 $as_echo_n "checking for cos in -lm... " >&6; } if ${ac_cv_lib_m_cos+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char cos (); int main () { return cos (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_cos=yes else ac_cv_lib_m_cos=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_cos" >&5 $as_echo "$ac_cv_lib_m_cos" >&6; } if test "x$ac_cv_lib_m_cos" = xyes; then : LIBM=-lm fi ;; esac # Check whether --enable-fixed-point was given. if test "${enable_fixed_point+set}" = set; then : enableval=$enable_fixed_point; else enable_fixed_point=no fi if test "$enable_fixed_point" = "yes"; then : enable_float="no" $as_echo "#define FIXED_POINT 1" >>confdefs.h PC_BUILD="fixed-point" else enable_float="yes"; PC_BUILD="floating-point" fi if test "$enable_fixed_point" = "yes"; then FIXED_POINT_TRUE= FIXED_POINT_FALSE='#' else FIXED_POINT_TRUE='#' FIXED_POINT_FALSE= fi # Check whether --enable-fixed-point-debug was given. if test "${enable_fixed_point_debug+set}" = set; then : enableval=$enable_fixed_point_debug; else enable_fixed_point_debug=no fi if test "$enable_fixed_point_debug" = "yes"; then : $as_echo "#define FIXED_DEBUG 1" >>confdefs.h fi # Check whether --enable-float_api was given. if test "${enable_float_api+set}" = set; then : enableval=$enable_float_api; else enable_float_api=yes fi if test "$enable_float_api" = "no"; then DISABLE_FLOAT_API_TRUE= DISABLE_FLOAT_API_FALSE='#' else DISABLE_FLOAT_API_TRUE='#' DISABLE_FLOAT_API_FALSE= fi if test "$enable_float_api" = "no"; then : $as_echo "#define DISABLE_FLOAT_API 1" >>confdefs.h fi # Check whether --enable-custom-modes was given. if test "${enable_custom_modes+set}" = set; then : enableval=$enable_custom_modes; else enable_custom_modes=no fi if test "$enable_custom_modes" = "yes"; then : $as_echo "#define CUSTOM_MODES 1" >>confdefs.h PC_BUILD="$PC_BUILD, custom modes" fi if test "$enable_custom_modes" = "yes"; then CUSTOM_MODES_TRUE= CUSTOM_MODES_FALSE='#' else CUSTOM_MODES_TRUE='#' CUSTOM_MODES_FALSE= fi has_float_approx=no #case "$host_cpu" in #i[[3456]]86 | x86_64 | powerpc64 | powerpc32 | ia64) # has_float_approx=yes # ;; #esac # Check whether --enable-float-approx was given. if test "${enable_float_approx+set}" = set; then : enableval=$enable_float_approx; if test "$enable_float_approx" = "yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Floating point approximations are not supported on all platforms." >&5 $as_echo "$as_me: WARNING: Floating point approximations are not supported on all platforms." >&2;} fi else enable_float_approx=$has_float_approx fi if test "$enable_float_approx" = "yes"; then : $as_echo "#define FLOAT_APPROX 1" >>confdefs.h fi # Check whether --enable-asm was given. if test "${enable_asm+set}" = set; then : enableval=$enable_asm; else enable_asm=yes fi # Check whether --enable-rtcd was given. if test "${enable_rtcd+set}" = set; then : enableval=$enable_rtcd; else enable_rtcd=yes fi # Check whether --enable-intrinsics was given. if test "${enable_intrinsics+set}" = set; then : enableval=$enable_intrinsics; else enable_intrinsics=yes fi rtcd_support=no cpu_arm=no if test x"${enable_asm}" = x"yes"; then : inline_optimization="No inline ASM for your platform, please send patches" case $host_cpu in arm*) if test "$enable_float" != "yes"; then : cpu_arm=yes $as_echo "#define OPUS_ARM_ASM /**/" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports gcc-style inline assembly" >&5 $as_echo_n "checking if compiler supports gcc-style inline assembly... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifdef __GNUC_MINOR__ #if (__GNUC__ * 1000 + __GNUC_MINOR__) < 3004 #error GCC before 3.4 has critical bugs compiling inline assembly #endif #endif __asm__ (""::) ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test "X$flag_ok" = Xyes ; then inline_optimization="ARM" true else inline_optimization="disabled" true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if assembler supports EDSP instructions on ARM" >&5 $as_echo_n "checking if assembler supports EDSP instructions on ARM... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { __asm__("qadd r3,r3,r3") ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } OPUS_ARM_INLINE_EDSP=1 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } OPUS_ARM_INLINE_EDSP=0 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking if assembler supports ARMv6 media instructions on ARM" >&5 $as_echo_n "checking if assembler supports ARMv6 media instructions on ARM... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { __asm__("shadd8 r3,r3,r3") ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } OPUS_ARM_INLINE_MEDIA=1 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } OPUS_ARM_INLINE_MEDIA=0 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking if assembler supports NEON instructions on ARM" >&5 $as_echo_n "checking if assembler supports NEON instructions on ARM... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { __asm__("vorr d0,d0,d0") ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } OPUS_ARM_INLINE_NEON=1 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } OPUS_ARM_INLINE_NEON=0 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test x"$inline_optimization" = x"ARM"; then : if true; then OPUS_ARM_INLINE_ASM_TRUE= OPUS_ARM_INLINE_ASM_FALSE='#' else OPUS_ARM_INLINE_ASM_TRUE='#' OPUS_ARM_INLINE_ASM_FALSE= fi $as_echo "#define OPUS_ARM_INLINE_ASM 1" >>confdefs.h if test x"$OPUS_ARM_INLINE_EDSP" = x"1"; then : $as_echo "#define OPUS_ARM_INLINE_EDSP 1" >>confdefs.h inline_optimization="$inline_optimization (EDSP)" fi if test x"$OPUS_ARM_INLINE_MEDIA" = x"1"; then : $as_echo "#define OPUS_ARM_INLINE_MEDIA 1" >>confdefs.h inline_optimization="$inline_optimization (Media)" fi if test x"$OPUS_ARM_INLINE_NEON" = x"1"; then : $as_echo "#define OPUS_ARM_INLINE_NEON 1" >>confdefs.h inline_optimization="$inline_optimization (NEON)" fi fi # Extract the first word of "perl", so it can be a program name with args. set dummy perl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_HAVE_PERL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$HAVE_PERL"; then ac_cv_prog_HAVE_PERL="$HAVE_PERL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_HAVE_PERL="yes" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_HAVE_PERL" && ac_cv_prog_HAVE_PERL="no" fi fi HAVE_PERL=$ac_cv_prog_HAVE_PERL if test -n "$HAVE_PERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_PERL" >&5 $as_echo "$HAVE_PERL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test x"$HAVE_PERL" = x"yes"; then : if true; then OPUS_ARM_EXTERNAL_ASM_TRUE= OPUS_ARM_EXTERNAL_ASM_FALSE='#' else OPUS_ARM_EXTERNAL_ASM_TRUE='#' OPUS_ARM_EXTERNAL_ASM_FALSE= fi asm_optimization="ARM" if test x"$OPUS_ARM_INLINE_EDSP" = x"1"; then : OPUS_ARM_PRESUME_EDSP=1 OPUS_ARM_MAY_HAVE_EDSP=1 else OPUS_ARM_PRESUME_EDSP=0 OPUS_ARM_MAY_HAVE_EDSP=0 fi if test x"$OPUS_ARM_INLINE_MEDIA" = x"1"; then : OPUS_ARM_PRESUME_MEDIA=1 OPUS_ARM_MAY_HAVE_MEDIA=1 else OPUS_ARM_PRESUME_MEDIA=0 OPUS_ARM_MAY_HAVE_MEDIA=0 fi if test x"$OPUS_ARM_INLINE_NEON" = x"1"; then : OPUS_ARM_PRESUME_NEON=1 OPUS_ARM_MAY_HAVE_NEON=1 else OPUS_ARM_PRESUME_NEON=0 OPUS_ARM_MAY_HAVE_NEON=0 fi if test x"$enable_rtcd" = x"yes"; then : if test x"$OPUS_ARM_MAY_HAVE_EDSP" != x"1"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: Trying to force-enable armv5e EDSP instructions..." >&5 $as_echo "$as_me: Trying to force-enable armv5e EDSP instructions..." >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking if assembler supports EDSP instructions on ARM" >&5 $as_echo_n "checking if assembler supports EDSP instructions on ARM... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { __asm__(".arch armv5te\n.object_arch armv4t\nqadd r3,r3,r3") ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } OPUS_ARM_MAY_HAVE_EDSP=1 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test x"$OPUS_ARM_MAY_HAVE_MEDIA" != x"1"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: Trying to force-enable ARMv6 media instructions..." >&5 $as_echo "$as_me: Trying to force-enable ARMv6 media instructions..." >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking if assembler supports ARMv6 media instructions on ARM" >&5 $as_echo_n "checking if assembler supports ARMv6 media instructions on ARM... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { __asm__(".arch armv6\n.object_arch armv4t\nshadd8 r3,r3,r3") ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } OPUS_ARM_MAY_HAVE_MEDIA=1 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test x"$OPUS_ARM_MAY_HAVE_NEON" != x"1"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: Trying to force-enable NEON instructions..." >&5 $as_echo "$as_me: Trying to force-enable NEON instructions..." >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking if assembler supports NEON instructions on ARM" >&5 $as_echo_n "checking if assembler supports NEON instructions on ARM... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { __asm__(".arch armv7-a\n.fpu neon\n.object_arch armv4t\nvorr d0,d0,d0") ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } OPUS_ARM_MAY_HAVE_NEON=1 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi fi rtcd_support= if test x"$OPUS_ARM_MAY_HAVE_EDSP" = x"1"; then : $as_echo "#define OPUS_ARM_MAY_HAVE_EDSP 1" >>confdefs.h if test x"$OPUS_ARM_PRESUME_EDSP" = x"1"; then : $as_echo "#define OPUS_ARM_PRESUME_EDSP 1" >>confdefs.h asm_optimization="$asm_optimization (EDSP)" else rtcd_support="$rtcd_support (EDSP)" fi fi if test x"$OPUS_ARM_MAY_HAVE_MEDIA" = x"1"; then : $as_echo "#define OPUS_ARM_MAY_HAVE_MEDIA 1" >>confdefs.h if test x"$OPUS_ARM_PRESUME_MEDIA" = x"1"; then : $as_echo "#define OPUS_ARM_PRESUME_MEDIA 1" >>confdefs.h asm_optimization="$asm_optimization (Media)" else rtcd_support="$rtcd_support (Media)" fi fi if test x"$OPUS_ARM_MAY_HAVE_NEON" = x"1"; then : $as_echo "#define OPUS_ARM_MAY_HAVE_NEON 1" >>confdefs.h if test x"$OPUS_ARM_PRESUME_NEON" = x"1"; then : $as_echo "#define OPUS_ARM_PRESUME_NEON 1" >>confdefs.h asm_optimization="$asm_optimization (NEON)" else rtcd_support="$rtcd_support (NEON)" fi fi if test x"$rtcd_support" != x""; then : rtcd_support=ARM"$rtcd_support" else rtcd_support="no" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for apple style tools" >&5 $as_echo_n "checking for apple style tools... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __APPLE__ #error 1 #endif int main () { ; return 0; } _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; }; ARM2GNU_PARAMS="--apple" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; }; ARM2GNU_PARAMS="" fi rm -f conftest.err conftest.i conftest.$ac_ext else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** ARM assembly requires perl -- disabling optimizations" >&5 $as_echo "$as_me: WARNING: *** ARM assembly requires perl -- disabling optimizations" >&2;} asm_optimization="(missing perl dependency for ARM)" fi fi ;; esac else inline_optimization="disabled" asm_optimization="disabled" fi if test x"${inline_optimization%% *}" = x"ARM"; then OPUS_ARM_INLINE_ASM_TRUE= OPUS_ARM_INLINE_ASM_FALSE='#' else OPUS_ARM_INLINE_ASM_TRUE='#' OPUS_ARM_INLINE_ASM_FALSE= fi if test x"${asm_optimization%% *}" = x"ARM"; then OPUS_ARM_EXTERNAL_ASM_TRUE= OPUS_ARM_EXTERNAL_ASM_FALSE='#' else OPUS_ARM_EXTERNAL_ASM_TRUE='#' OPUS_ARM_EXTERNAL_ASM_FALSE= fi if false; then HAVE_SSE_TRUE= HAVE_SSE_FALSE='#' else HAVE_SSE_TRUE='#' HAVE_SSE_FALSE= fi if false; then HAVE_SSE2_TRUE= HAVE_SSE2_FALSE='#' else HAVE_SSE2_TRUE='#' HAVE_SSE2_FALSE= fi if false; then HAVE_SSE4_1_TRUE= HAVE_SSE4_1_FALSE='#' else HAVE_SSE4_1_TRUE='#' HAVE_SSE4_1_FALSE= fi if false; then HAVE_AVX_TRUE= HAVE_AVX_FALSE='#' else HAVE_AVX_TRUE='#' HAVE_AVX_FALSE= fi # With GCC on ARM32 softfp architectures (e.g. Android, or older Ubuntu) you need to specify # -mfloat-abi=softfp for -mfpu=neon to work. However, on ARM32 hardfp architectures (e.g. newer Ubuntu), # this option will break things. # As a heuristic, if host matches arm*eabi* but not arm*hf*, it's probably soft-float. case $host in #( arm*hf*) : RESOLVED_DEFAULT_ARM_NEON_INTR_CFLAGS="-mfpu=neon" ;; #( arm*eabi*) : RESOLVED_DEFAULT_ARM_NEON_INTR_CFLAGS="-mfpu=neon -mfloat-abi=softfp" ;; #( *) : RESOLVED_DEFAULT_ARM_NEON_INTR_CFLAGS="-mfpu=neon" ;; esac if ${X86_SSE_CFLAGS+:} false; then : else X86_SSE_CFLAGS="-msse" fi if ${X86_SSE2_CFLAGS+:} false; then : else X86_SSE2_CFLAGS="-msse2" fi if ${X86_SSE4_1_CFLAGS+:} false; then : else X86_SSE4_1_CFLAGS="-msse4.1" fi if ${X86_AVX_CFLAGS+:} false; then : else X86_AVX_CFLAGS="-mavx" fi if ${ARM_NEON_INTR_CFLAGS+:} false; then : else ARM_NEON_INTR_CFLAGS="$RESOLVED_DEFAULT_ARM_NEON_INTR_CFLAGS" fi if test x"$enable_intrinsics" = x"yes"; then : intrinsics_support="" case $host_cpu in #( arm*|aarch64*) : cpu_arm=yes { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports ARM Neon intrinsics" >&5 $as_echo_n "checking if compiler supports ARM Neon intrinsics... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { static float32x4_t A0, A1, SUMM; SUMM = vmlaq_f32(SUMM, A0, A1); return (int)vgetq_lane_f32(SUMM, 0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : OPUS_ARM_MAY_HAVE_NEON_INTR=1 OPUS_ARM_PRESUME_NEON_INTR=1 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else OPUS_ARM_PRESUME_NEON_INTR=0 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports ARM Neon intrinsics with $ARM_NEON_INTR_CFLAGS" >&5 $as_echo_n "checking if compiler supports ARM Neon intrinsics with $ARM_NEON_INTR_CFLAGS... " >&6; } save_CFLAGS="$CFLAGS"; CFLAGS="$CFLAGS $ARM_NEON_INTR_CFLAGS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { static float32x4_t A0, A1, SUMM; SUMM = vmlaq_f32(SUMM, A0, A1); return (int)vgetq_lane_f32(SUMM, 0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } OPUS_ARM_MAY_HAVE_NEON_INTR=1 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } OPUS_ARM_MAY_HAVE_NEON_INTR=0 fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$save_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test x"$OPUS_ARM_MAY_HAVE_NEON_INTR" = x"1" && test x"$OPUS_ARM_PRESUME_NEON_INTR" != x"1"; then : OPUS_ARM_NEON_INTR_CFLAGS="$ARM_NEON_INTR_CFLAGS" fi if test x"$OPUS_ARM_MAY_HAVE_NEON_INTR" = x"1"; then : $as_echo "#define OPUS_ARM_MAY_HAVE_NEON_INTR 1" >>confdefs.h intrinsics_support="$intrinsics_support (NEON)" if test x"$enable_rtcd" != x"no" && test x"$OPUS_ARM_PRESUME_NEON_INTR" != x"1"; then : if test x"$rtcd_support" = x"no"; then : rtcd_support="ARM (NEON Intrinsics)" else rtcd_support="$rtcd_support (NEON Intrinsics)" fi fi if test x"$OPUS_ARM_PRESUME_NEON_INTR" = x"1"; then : $as_echo "#define OPUS_ARM_PRESUME_NEON_INTR 1" >>confdefs.h fi # Check whether --with-NE10 was given. if test "${with_NE10+set}" = set; then : withval=$with_NE10; NE10_prefix="$withval" else NE10_prefix="" fi # Check whether --with-NE10-libraries was given. if test "${with_NE10_libraries+set}" = set; then : withval=$with_NE10_libraries; NE10_libraries="$withval" else NE10_libraries="" fi # Check whether --with-NE10-includes was given. if test "${with_NE10_includes+set}" = set; then : withval=$with_NE10_includes; NE10_includes="$withval" else NE10_includes="" fi if test "x$NE10_libraries" != "x" ; then NE10_LIBS="-L$NE10_libraries" elif test "x$NE10_prefix" = "xno" || test "x$NE10_prefix" = "xyes" ; then NE10_LIBS="" elif test "x$NE10_prefix" != "x" ; then NE10_LIBS="-L$NE10_prefix/lib" elif test "x$prefix" != "xNONE" ; then NE10_LIBS="-L$prefix/lib" fi if test "x$NE10_prefix" != "xno" ; then NE10_LIBS="$NE10_LIBS -lNE10" fi if test "x$NE10_includes" != "x" ; then NE10_CFLAGS="-I$NE10_includes" elif test "x$NE10_prefix" = "xno" || test "x$NE10_prefix" = "xyes" ; then NE10_CFLAGS="" elif test "x$NE10_prefix" != "x" ; then NE10_CFLAGS="-I$NE10_prefix/include" elif test "x$prefix" != "xNONE"; then NE10_CFLAGS="-I$prefix/include" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for NE10" >&5 $as_echo_n "checking for NE10... " >&6; } save_CFLAGS="$CFLAGS"; CFLAGS="$CFLAGS $NE10_CFLAGS" save_LIBS="$LIBS"; LIBS="$LIBS $NE10_LIBS $LIBM" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { ne10_fft_cfg_float32_t cfg; cfg = ne10_fft_alloc_c2c_float32_neon(480); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : HAVE_ARM_NE10=1 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else HAVE_ARM_NE10=0 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } NE10_CFLAGS="" NE10_LIBS="" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$save_CFLAGS"; LIBS="$save_LIBS" #Now we know if libNE10 is installed or not if test x"$HAVE_ARM_NE10" = x"1"; then : $as_echo "#define HAVE_ARM_NE10 1" >>confdefs.h fi if test x"$NE10_LIBS" != x""; then : intrinsics_support="$intrinsics_support (NE10)" if test x"enable_rtcd" != x"" \ && test x"$OPUS_ARM_PRESUME_NEON_INTR" != x"1"; then : rtcd_support="$rtcd_support (NE10)" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports Aarch64 Neon intrinsics" >&5 $as_echo_n "checking if compiler supports Aarch64 Neon intrinsics... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { static int32_t IN; static int16_t OUT; OUT = vqmovns_s32(IN); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : OPUS_ARM_MAY_HAVE_AARCH64_NEON_INTR=1 OPUS_ARM_PRESUME_AARCH64_NEON_INTR=1 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else OPUS_ARM_PRESUME_AARCH64_NEON_INTR=0 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports Aarch64 Neon intrinsics with $ARM_NEON_INTR_CFLAGS" >&5 $as_echo_n "checking if compiler supports Aarch64 Neon intrinsics with $ARM_NEON_INTR_CFLAGS... " >&6; } save_CFLAGS="$CFLAGS"; CFLAGS="$CFLAGS $ARM_NEON_INTR_CFLAGS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { static int32_t IN; static int16_t OUT; OUT = vqmovns_s32(IN); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } OPUS_ARM_MAY_HAVE_AARCH64_NEON_INTR=1 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } OPUS_ARM_MAY_HAVE_AARCH64_NEON_INTR=0 fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$save_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test x"$OPUS_ARM_PRESUME_AARCH64_NEON_INTR" = x"1"; then : $as_echo "#define OPUS_ARM_PRESUME_AARCH64_NEON_INTR 1" >>confdefs.h intrinsics_support="$intrinsics_support (NEON Aarch64)" fi if test x"$intrinsics_support" = x""; then : intrinsics_support=no else intrinsics_support="ARM$intrinsics_support" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Compiler does not support ARM intrinsics" >&5 $as_echo "$as_me: WARNING: Compiler does not support ARM intrinsics" >&2;} intrinsics_support=no fi ;; #( i?86|x86_64) : { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports SSE intrinsics" >&5 $as_echo_n "checking if compiler supports SSE intrinsics... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { __m128 mtest; mtest = _mm_set1_ps((float)time(NULL)); mtest = _mm_mul_ps(mtest, mtest); return _mm_cvtss_si32(mtest); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : OPUS_X86_MAY_HAVE_SSE=1 OPUS_X86_PRESUME_SSE=1 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else OPUS_X86_PRESUME_SSE=0 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports SSE intrinsics with $X86_SSE_CFLAGS" >&5 $as_echo_n "checking if compiler supports SSE intrinsics with $X86_SSE_CFLAGS... " >&6; } save_CFLAGS="$CFLAGS"; CFLAGS="$CFLAGS $X86_SSE_CFLAGS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { __m128 mtest; mtest = _mm_set1_ps((float)time(NULL)); mtest = _mm_mul_ps(mtest, mtest); return _mm_cvtss_si32(mtest); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } OPUS_X86_MAY_HAVE_SSE=1 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } OPUS_X86_MAY_HAVE_SSE=0 fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$save_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test x"$OPUS_X86_MAY_HAVE_SSE" = x"1" && test x"$OPUS_X86_PRESUME_SSE" != x"1"; then : OPUS_X86_SSE_CFLAGS="$X86_SSE_CFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports SSE2 intrinsics" >&5 $as_echo_n "checking if compiler supports SSE2 intrinsics... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { __m128i mtest; mtest = _mm_set1_epi32((int)time(NULL)); mtest = _mm_mul_epu32(mtest, mtest); return _mm_cvtsi128_si32(mtest); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : OPUS_X86_MAY_HAVE_SSE2=1 OPUS_X86_PRESUME_SSE2=1 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else OPUS_X86_PRESUME_SSE2=0 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports SSE2 intrinsics with $X86_SSE2_CFLAGS" >&5 $as_echo_n "checking if compiler supports SSE2 intrinsics with $X86_SSE2_CFLAGS... " >&6; } save_CFLAGS="$CFLAGS"; CFLAGS="$CFLAGS $X86_SSE2_CFLAGS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { __m128i mtest; mtest = _mm_set1_epi32((int)time(NULL)); mtest = _mm_mul_epu32(mtest, mtest); return _mm_cvtsi128_si32(mtest); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } OPUS_X86_MAY_HAVE_SSE2=1 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } OPUS_X86_MAY_HAVE_SSE2=0 fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$save_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test x"$OPUS_X86_MAY_HAVE_SSE2" = x"1" && test x"$OPUS_X86_PRESUME_SSE2" != x"1"; then : OPUS_X86_SSE2_CFLAGS="$X86_SSE2_CFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports SSE4.1 intrinsics" >&5 $as_echo_n "checking if compiler supports SSE4.1 intrinsics... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { __m128i mtest; mtest = _mm_set1_epi32((int)time(NULL)); mtest = _mm_mul_epi32(mtest, mtest); return _mm_cvtsi128_si32(mtest); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : OPUS_X86_MAY_HAVE_SSE4_1=1 OPUS_X86_PRESUME_SSE4_1=1 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else OPUS_X86_PRESUME_SSE4_1=0 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports SSE4.1 intrinsics with $X86_SSE4_1_CFLAGS" >&5 $as_echo_n "checking if compiler supports SSE4.1 intrinsics with $X86_SSE4_1_CFLAGS... " >&6; } save_CFLAGS="$CFLAGS"; CFLAGS="$CFLAGS $X86_SSE4_1_CFLAGS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { __m128i mtest; mtest = _mm_set1_epi32((int)time(NULL)); mtest = _mm_mul_epi32(mtest, mtest); return _mm_cvtsi128_si32(mtest); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } OPUS_X86_MAY_HAVE_SSE4_1=1 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } OPUS_X86_MAY_HAVE_SSE4_1=0 fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$save_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test x"$OPUS_X86_MAY_HAVE_SSE4_1" = x"1" && test x"$OPUS_X86_PRESUME_SSE4_1" != x"1"; then : OPUS_X86_SSE4_1_CFLAGS="$X86_SSE4_1_CFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports AVX intrinsics" >&5 $as_echo_n "checking if compiler supports AVX intrinsics... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { __m256 mtest; mtest = _mm256_set1_ps((float)time(NULL)); mtest = _mm256_addsub_ps(mtest, mtest); return _mm_cvtss_si32(_mm256_extractf128_ps(mtest, 0)); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : OPUS_X86_MAY_HAVE_AVX=1 OPUS_X86_PRESUME_AVX=1 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else OPUS_X86_PRESUME_AVX=0 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports AVX intrinsics with $X86_AVX_CFLAGS" >&5 $as_echo_n "checking if compiler supports AVX intrinsics with $X86_AVX_CFLAGS... " >&6; } save_CFLAGS="$CFLAGS"; CFLAGS="$CFLAGS $X86_AVX_CFLAGS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { __m256 mtest; mtest = _mm256_set1_ps((float)time(NULL)); mtest = _mm256_addsub_ps(mtest, mtest); return _mm_cvtss_si32(_mm256_extractf128_ps(mtest, 0)); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } OPUS_X86_MAY_HAVE_AVX=1 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } OPUS_X86_MAY_HAVE_AVX=0 fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$save_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test x"$OPUS_X86_MAY_HAVE_AVX" = x"1" && test x"$OPUS_X86_PRESUME_AVX" != x"1"; then : OPUS_X86_AVX_CFLAGS="$X86_AVX_CFLAGS" fi if test x"$rtcd_support" = x"no"; then : rtcd_support="" fi if test x"$OPUS_X86_MAY_HAVE_SSE" = x"1"; then : $as_echo "#define OPUS_X86_MAY_HAVE_SSE 1" >>confdefs.h intrinsics_support="$intrinsics_support SSE" if test x"$OPUS_X86_PRESUME_SSE" = x"1"; then : $as_echo "#define OPUS_X86_PRESUME_SSE 1" >>confdefs.h else rtcd_support="$rtcd_support SSE" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Compiler does not support SSE intrinsics" >&5 $as_echo "$as_me: WARNING: Compiler does not support SSE intrinsics" >&2;} fi if test x"$OPUS_X86_MAY_HAVE_SSE2" = x"1"; then : $as_echo "#define OPUS_X86_MAY_HAVE_SSE2 1" >>confdefs.h intrinsics_support="$intrinsics_support SSE2" if test x"$OPUS_X86_PRESUME_SSE2" = x"1"; then : $as_echo "#define OPUS_X86_PRESUME_SSE2 1" >>confdefs.h else rtcd_support="$rtcd_support SSE2" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Compiler does not support SSE2 intrinsics" >&5 $as_echo "$as_me: WARNING: Compiler does not support SSE2 intrinsics" >&2;} fi if test x"$OPUS_X86_MAY_HAVE_SSE4_1" = x"1"; then : $as_echo "#define OPUS_X86_MAY_HAVE_SSE4_1 1" >>confdefs.h intrinsics_support="$intrinsics_support SSE4.1" if test x"$OPUS_X86_PRESUME_SSE4_1" = x"1"; then : $as_echo "#define OPUS_X86_PRESUME_SSE4_1 1" >>confdefs.h else rtcd_support="$rtcd_support SSE4.1" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Compiler does not support SSE4.1 intrinsics" >&5 $as_echo "$as_me: WARNING: Compiler does not support SSE4.1 intrinsics" >&2;} fi if test x"$OPUS_X86_MAY_HAVE_AVX" = x"1"; then : $as_echo "#define OPUS_X86_MAY_HAVE_AVX 1" >>confdefs.h intrinsics_support="$intrinsics_support AVX" if test x"$OPUS_X86_PRESUME_AVX" = x"1"; then : $as_echo "#define OPUS_X86_PRESUME_AVX 1" >>confdefs.h else rtcd_support="$rtcd_support AVX" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Compiler does not support AVX intrinsics" >&5 $as_echo "$as_me: WARNING: Compiler does not support AVX intrinsics" >&2;} fi if test x"$intrinsics_support" = x""; then : intrinsics_support=no else intrinsics_support="x86$intrinsics_support" fi if test x"$rtcd_support" = x""; then : rtcd_support=no elif rtcd_support="x86$rtcd_support"; then : fi if test x"$enable_rtcd" = x"yes" && test x"$rtcd_support" != x""; then : get_cpuid_by_asm="no" { $as_echo "$as_me:${as_lineno-$LINENO}: checking How to get X86 CPU Info" >&5 $as_echo_n "checking How to get X86 CPU Info... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { unsigned int CPUInfo0; unsigned int CPUInfo1; unsigned int CPUInfo2; unsigned int CPUInfo3; unsigned int InfoType; __asm__ __volatile__ ( "cpuid": "=a" (CPUInfo0), "=b" (CPUInfo1), "=c" (CPUInfo2), "=d" (CPUInfo3) : "a" (InfoType), "c" (0) ); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : get_cpuid_by_asm="yes" { $as_echo "$as_me:${as_lineno-$LINENO}: result: Inline Assembly" >&5 $as_echo "Inline Assembly" >&6; } $as_echo "#define CPU_INFO_BY_ASM 1" >>confdefs.h else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { unsigned int CPUInfo0; unsigned int CPUInfo1; unsigned int CPUInfo2; unsigned int CPUInfo3; unsigned int InfoType; __get_cpuid(InfoType, &CPUInfo0, &CPUInfo1, &CPUInfo2, &CPUInfo3); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: C method" >&5 $as_echo "C method" >&6; } $as_echo "#define CPU_INFO_BY_C 1" >>confdefs.h else as_fn_error $? "no supported Get CPU Info method, please disable run-time CPU capabilities detection or intrinsics" "$LINENO" 5 fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi ;; #( *) : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No intrinsics support for your architecture" >&5 $as_echo "$as_me: WARNING: No intrinsics support for your architecture" >&2;} intrinsics_support="no" ;; esac else intrinsics_support="no" fi if test "$cpu_arm" = "yes"; then CPU_ARM_TRUE= CPU_ARM_FALSE='#' else CPU_ARM_TRUE='#' CPU_ARM_FALSE= fi if test x"$OPUS_ARM_MAY_HAVE_NEON_INTR" = x"1"; then HAVE_ARM_NEON_INTR_TRUE= HAVE_ARM_NEON_INTR_FALSE='#' else HAVE_ARM_NEON_INTR_TRUE='#' HAVE_ARM_NEON_INTR_FALSE= fi if test x"$HAVE_ARM_NE10" = x"1"; then HAVE_ARM_NE10_TRUE= HAVE_ARM_NE10_FALSE='#' else HAVE_ARM_NE10_TRUE='#' HAVE_ARM_NE10_FALSE= fi if test x"$OPUS_X86_MAY_HAVE_SSE" = x"1"; then HAVE_SSE_TRUE= HAVE_SSE_FALSE='#' else HAVE_SSE_TRUE='#' HAVE_SSE_FALSE= fi if test x"$OPUS_X86_MAY_HAVE_SSE2" = x"1"; then HAVE_SSE2_TRUE= HAVE_SSE2_FALSE='#' else HAVE_SSE2_TRUE='#' HAVE_SSE2_FALSE= fi if test x"$OPUS_X86_MAY_HAVE_SSE4_1" = x"1"; then HAVE_SSE4_1_TRUE= HAVE_SSE4_1_FALSE='#' else HAVE_SSE4_1_TRUE='#' HAVE_SSE4_1_FALSE= fi if test x"$OPUS_X86_MAY_HAVE_AVX" = x"1"; then HAVE_AVX_TRUE= HAVE_AVX_FALSE='#' else HAVE_AVX_TRUE='#' HAVE_AVX_FALSE= fi if test x"$enable_rtcd" = x"yes"; then : if test x"$rtcd_support" != x"no"; then : $as_echo "#define OPUS_HAVE_RTCD 1" >>confdefs.h OPUS_HAVE_RTCD=1 fi else rtcd_support="disabled" fi # Check whether --enable-assertions was given. if test "${enable_assertions+set}" = set; then : enableval=$enable_assertions; else enable_assertions=no fi if test "$enable_assertions" = "yes"; then : $as_echo "#define ENABLE_ASSERTIONS 1" >>confdefs.h fi # Check whether --enable-hardening was given. if test "${enable_hardening+set}" = set; then : enableval=$enable_hardening; else enable_hardening=yes fi if test "$enable_hardening" = "yes"; then : $as_echo "#define ENABLE_HARDENING 1" >>confdefs.h fi # Check whether --enable-fuzzing was given. if test "${enable_fuzzing+set}" = set; then : enableval=$enable_fuzzing; else enable_fuzzing=no fi if test "$enable_fuzzing" = "yes"; then : $as_echo "#define FUZZING 1" >>confdefs.h fi # Check whether --enable-check-asm was given. if test "${enable_check_asm+set}" = set; then : enableval=$enable_check_asm; else enable_check_asm=no fi if test "$enable_check_asm" = "yes"; then : $as_echo "#define OPUS_CHECK_ASM 1" >>confdefs.h fi # Check whether --enable-doc was given. if test "${enable_doc+set}" = set; then : enableval=$enable_doc; else enable_doc=yes fi if test "$enable_doc" = "yes"; then : # Extract the first word of "doxygen", so it can be a program name with args. set dummy doxygen; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_HAVE_DOXYGEN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$HAVE_DOXYGEN"; then ac_cv_prog_HAVE_DOXYGEN="$HAVE_DOXYGEN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_HAVE_DOXYGEN="yes" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_HAVE_DOXYGEN" && ac_cv_prog_HAVE_DOXYGEN="no" fi fi HAVE_DOXYGEN=$ac_cv_prog_HAVE_DOXYGEN if test -n "$HAVE_DOXYGEN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_DOXYGEN" >&5 $as_echo "$HAVE_DOXYGEN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "dot", so it can be a program name with args. set dummy dot; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_HAVE_DOT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$HAVE_DOT"; then ac_cv_prog_HAVE_DOT="$HAVE_DOT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_HAVE_DOT="yes" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_HAVE_DOT" && ac_cv_prog_HAVE_DOT="no" fi fi HAVE_DOT=$ac_cv_prog_HAVE_DOT if test -n "$HAVE_DOT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_DOT" >&5 $as_echo "$HAVE_DOT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else HAVE_DOXYGEN=no fi if test "$HAVE_DOXYGEN" = "yes"; then HAVE_DOXYGEN_TRUE= HAVE_DOXYGEN_FALSE='#' else HAVE_DOXYGEN_TRUE='#' HAVE_DOXYGEN_FALSE= fi # Check whether --enable-extra-programs was given. if test "${enable_extra_programs+set}" = set; then : enableval=$enable_extra_programs; else enable_extra_programs=yes fi if test "$enable_extra_programs" = "yes"; then EXTRA_PROGRAMS_TRUE= EXTRA_PROGRAMS_FALSE='#' else EXTRA_PROGRAMS_TRUE='#' EXTRA_PROGRAMS_FALSE= fi # Check whether --enable-rfc8251 was given. if test "${enable_rfc8251+set}" = set; then : enableval=$enable_rfc8251; else enable_rfc8251=yes fi if test "$enable_rfc8251" = "no"; then : $as_echo "#define DISABLE_UPDATE_DRAFT 1" >>confdefs.h fi saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -fvisibility=hidden" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if ${CC} supports -fvisibility=hidden" >&5 $as_echo_n "checking if ${CC} supports -fvisibility=hidden... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ char foo; _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext on_x86=no case "$host_cpu" in i[3456]86 | x86_64) on_x86=yes ;; esac on_windows=no case $host in *cygwin*|*mingw*) on_windows=yes ;; esac # Check whether --enable-stack-protector was given. if test "${enable_stack_protector+set}" = set; then : enableval=$enable_stack_protector; else if test "$ac_cv_c_compiler_gnu" = "yes" && test "$on_x86" = "yes" && test "$on_windows" = "no"; then : enable_stack_protector=yes else enable_stack_protector=no fi fi if test "$enable_stack_protector" = "yes"; then : saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -fstack-protector-strong" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if ${CC} supports -fstack-protector-strong" >&5 $as_echo_n "checking if ${CC} supports -fstack-protector-strong... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { char foo; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } enable_stack_protector=no CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi if test x$ac_cv_c_compiler_gnu = xyes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to add -D_FORTIFY_SOURCE=2 to CFLAGS" >&5 $as_echo_n "checking whether to add -D_FORTIFY_SOURCE=2 to CFLAGS... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main() { #ifndef _FORTIFY_SOURCE return 0; #else this_is_an_error; #endif } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } CFLAGS="$CFLAGS -D_FORTIFY_SOURCE=2" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi CFLAGS="$CFLAGS -W" warn_CFLAGS="-Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes" saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $warn_CFLAGS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if ${CC} supports ${warn_CFLAGS}" >&5 $as_echo_n "checking if ${CC} supports ${warn_CFLAGS}... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ char foo; _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext saved_LIBS="$LIBS" LIBS="$LIBS $LIBM" for ac_func in lrintf do : ac_fn_c_check_func "$LINENO" "lrintf" "ac_cv_func_lrintf" if test "x$ac_cv_func_lrintf" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LRINTF 1 _ACEOF fi done for ac_func in lrint do : ac_fn_c_check_func "$LINENO" "lrint" "ac_cv_func_lrint" if test "x$ac_cv_func_lrint" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LRINT 1 _ACEOF fi done LIBS="$saved_LIBS" for ac_func in __malloc_hook do : ac_fn_c_check_func "$LINENO" "__malloc_hook" "ac_cv_func___malloc_hook" if test "x$ac_cv_func___malloc_hook" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE___MALLOC_HOOK 1 _ACEOF fi done ac_config_files="$ac_config_files Makefile opus.pc opus-uninstalled.pc celt/arm/armopts.s doc/Makefile doc/Doxyfile" ac_config_headers="$ac_config_headers config.h" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs { $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 $as_echo_n "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 $as_echo "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCCAS_TRUE}" && test -z "${am__fastdepCCAS_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCCAS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${FIXED_POINT_TRUE}" && test -z "${FIXED_POINT_FALSE}"; then as_fn_error $? "conditional \"FIXED_POINT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${DISABLE_FLOAT_API_TRUE}" && test -z "${DISABLE_FLOAT_API_FALSE}"; then as_fn_error $? "conditional \"DISABLE_FLOAT_API\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${CUSTOM_MODES_TRUE}" && test -z "${CUSTOM_MODES_FALSE}"; then as_fn_error $? "conditional \"CUSTOM_MODES\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${OPUS_ARM_INLINE_ASM_TRUE}" && test -z "${OPUS_ARM_INLINE_ASM_FALSE}"; then as_fn_error $? "conditional \"OPUS_ARM_INLINE_ASM\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${OPUS_ARM_EXTERNAL_ASM_TRUE}" && test -z "${OPUS_ARM_EXTERNAL_ASM_FALSE}"; then as_fn_error $? "conditional \"OPUS_ARM_EXTERNAL_ASM\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${OPUS_ARM_INLINE_ASM_TRUE}" && test -z "${OPUS_ARM_INLINE_ASM_FALSE}"; then as_fn_error $? "conditional \"OPUS_ARM_INLINE_ASM\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${OPUS_ARM_EXTERNAL_ASM_TRUE}" && test -z "${OPUS_ARM_EXTERNAL_ASM_FALSE}"; then as_fn_error $? "conditional \"OPUS_ARM_EXTERNAL_ASM\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_SSE_TRUE}" && test -z "${HAVE_SSE_FALSE}"; then as_fn_error $? "conditional \"HAVE_SSE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_SSE2_TRUE}" && test -z "${HAVE_SSE2_FALSE}"; then as_fn_error $? "conditional \"HAVE_SSE2\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_SSE4_1_TRUE}" && test -z "${HAVE_SSE4_1_FALSE}"; then as_fn_error $? "conditional \"HAVE_SSE4_1\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_AVX_TRUE}" && test -z "${HAVE_AVX_FALSE}"; then as_fn_error $? "conditional \"HAVE_AVX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${CPU_ARM_TRUE}" && test -z "${CPU_ARM_FALSE}"; then as_fn_error $? "conditional \"CPU_ARM\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_ARM_NEON_INTR_TRUE}" && test -z "${HAVE_ARM_NEON_INTR_FALSE}"; then as_fn_error $? "conditional \"HAVE_ARM_NEON_INTR\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_ARM_NE10_TRUE}" && test -z "${HAVE_ARM_NE10_FALSE}"; then as_fn_error $? "conditional \"HAVE_ARM_NE10\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_SSE_TRUE}" && test -z "${HAVE_SSE_FALSE}"; then as_fn_error $? "conditional \"HAVE_SSE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_SSE2_TRUE}" && test -z "${HAVE_SSE2_FALSE}"; then as_fn_error $? "conditional \"HAVE_SSE2\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_SSE4_1_TRUE}" && test -z "${HAVE_SSE4_1_FALSE}"; then as_fn_error $? "conditional \"HAVE_SSE4_1\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_AVX_TRUE}" && test -z "${HAVE_AVX_FALSE}"; then as_fn_error $? "conditional \"HAVE_AVX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_DOXYGEN_TRUE}" && test -z "${HAVE_DOXYGEN_FALSE}"; then as_fn_error $? "conditional \"HAVE_DOXYGEN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${EXTRA_PROGRAMS_TRUE}" && test -z "${EXTRA_PROGRAMS_FALSE}"; then as_fn_error $? "conditional \"EXTRA_PROGRAMS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by opus $as_me 1.3.1, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ opus config.status 1.3.1 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`' objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`' hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } # Quote evaled strings. for var in SHELL \ ECHO \ PATH_SEPARATOR \ SED \ GREP \ EGREP \ FGREP \ LD \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ OBJDUMP \ deplibs_check_method \ file_magic_cmd \ file_magic_glob \ want_nocaseglob \ DLLTOOL \ sharedlib_from_linklib_cmd \ AR \ AR_FLAGS \ archiver_list_spec \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_import \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ lt_cv_nm_interface \ nm_file_list_spec \ lt_cv_truncate_bin \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_pic \ lt_prog_compiler_wl \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ MANIFEST_TOOL \ DSYMUTIL \ NMEDIT \ LIPO \ OTOOL \ OTOOL64 \ shrext_cmds \ export_dynamic_flag_spec \ whole_archive_flag_spec \ compiler_needs_object \ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ hardcode_libdir_separator \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ install_override_mode \ finish_eval \ old_striplib \ striplib; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in reload_cmds \ old_postinstall_cmds \ old_postuninstall_cmds \ old_archive_cmds \ extract_expsyms_cmds \ old_archive_from_new_cmds \ old_archive_from_expsyms_cmds \ archive_cmds \ archive_expsym_cmds \ module_cmds \ module_expsym_cmds \ export_symbols_cmds \ prelink_cmds \ postlink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ configure_time_dlsearch_path \ configure_time_lt_sys_library_path; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done ac_aux_dir='$ac_aux_dir' # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' RM='$RM' ofile='$ofile' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "opus.pc") CONFIG_FILES="$CONFIG_FILES opus.pc" ;; "opus-uninstalled.pc") CONFIG_FILES="$CONFIG_FILES opus-uninstalled.pc" ;; "celt/arm/armopts.s") CONFIG_FILES="$CONFIG_FILES celt/arm/armopts.s" ;; "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; "doc/Doxyfile") CONFIG_FILES="$CONFIG_FILES doc/Doxyfile" ;; "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; "libtool":C) # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. # Written by Gordon Matzigkeit, 1996 # Copyright (C) 2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program or library that is built # using GNU Libtool, you may include this file under the same # distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # The names of the tagged configurations supported by this script. available_tags='' # Configured defaults for sys_lib_dlsearch_path munging. : \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} # ### BEGIN LIBTOOL CONFIG # Which release of libtool.m4 was used? macro_version=$macro_version macro_revision=$macro_revision # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # What type of objects to build. pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # Shared archive member basename,for filename based shared library versioning on AIX. shared_archive_member_spec=$shared_archive_member_spec # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that protects backslashes. ECHO=$lt_ECHO # The PATH separator for the build system. PATH_SEPARATOR=$lt_PATH_SEPARATOR # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="\$SED -e 1s/^X//" # A grep program that handles long lines. GREP=$lt_GREP # An ERE matcher. EGREP=$lt_EGREP # A literal string matcher. FGREP=$lt_FGREP # A BSD- or MS-compatible name lister. NM=$lt_NM # Whether we need soft or hard links. LN_S=$lt_LN_S # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Object file suffix (normally "o"). objext=$ac_objext # Executable file suffix (normally ""). exeext=$exeext # whether the shell understands "unset". lt_unset=$lt_unset # turn spaces into newlines. SP2NL=$lt_lt_SP2NL # turn newlines into spaces. NL2SP=$lt_lt_NL2SP # convert \$build file names to \$host format. to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd # An object symbol dumper. OBJDUMP=$lt_OBJDUMP # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method = "file_magic". file_magic_cmd=$lt_file_magic_cmd # How to find potential files when deplibs_check_method = "file_magic". file_magic_glob=$lt_file_magic_glob # Find potential files using nocaseglob when deplibs_check_method = "file_magic". want_nocaseglob=$lt_want_nocaseglob # DLL creation program. DLLTOOL=$lt_DLLTOOL # Command to associate shared and link libraries. sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd # The archiver. AR=$lt_AR # Flags to create an archive. AR_FLAGS=$lt_AR_FLAGS # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec # A symbol stripping program. STRIP=$lt_STRIP # Commands used to install an old-style archive. RANLIB=$lt_RANLIB old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Whether to use a lock for old archive extraction. lock_old_archive_extraction=$lock_old_archive_extraction # A C compiler. LTCC=$lt_CC # LTCC compiler flags. LTCFLAGS=$lt_CFLAGS # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm into a list of symbols to manually relocate. global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix # The name lister interface. nm_interface=$lt_lt_cv_nm_interface # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec # The root where to search for dependent libraries,and where our libraries should be installed. lt_sysroot=$lt_sysroot # Command to truncate a binary pipe. lt_truncate_bin=$lt_lt_cv_truncate_bin # The name of the directory that contains temporary libtool files. objdir=$objdir # Used to examine libraries when file_magic_cmd begins with "file". MAGIC_CMD=$MAGIC_CMD # Must we lock files when doing compilation? need_locks=$lt_need_locks # Manifest tool. MANIFEST_TOOL=$lt_MANIFEST_TOOL # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL # Tool to change global to local symbols on Mac OS X. NMEDIT=$lt_NMEDIT # Tool to manipulate fat objects and archives on Mac OS X. LIPO=$lt_LIPO # ldd/readelf like tool for Mach-O binaries on Mac OS X. OTOOL=$lt_OTOOL # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. OTOOL64=$lt_OTOOL64 # Old archive suffix (normally "a"). libext=$libext # Shared library suffix (normally ".so"). shrext_cmds=$lt_shrext_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Variables whose values should be saved in libtool wrapper scripts and # restored at link time. variables_saved_for_relink=$lt_variables_saved_for_relink # Do we need the "lib" prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Library versioning type. version_type=$version_type # Shared library runtime path variable. runpath_var=$runpath_var # Shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Permission mode override for installation of shared libraries. install_override_mode=$lt_install_override_mode # Command to use after installation of a shared archive. postinstall_cmds=$lt_postinstall_cmds # Command to use after uninstallation of a shared archive. postuninstall_cmds=$lt_postuninstall_cmds # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # As "finish_cmds", except a single script fragment to be evaled but # not shown. finish_eval=$lt_finish_eval # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Detected run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path # Explicit LT_SYS_LIBRARY_PATH set during ./configure time. configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # The linker used to build libraries. LD=$lt_LD # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds # A language specific compiler. CC=$lt_compiler # Is the compiler the GNU compiler? with_gcc=$GCC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \$shlibpath_var if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds # Specify filename containing input files. file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # ### END LIBTOOL CONFIG _LT_EOF cat <<'_LT_EOF' >> "$cfgfile" # ### BEGIN FUNCTIONS SHARED WITH CONFIGURE # func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x$2 in x) ;; *:) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" ;; x:*) eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" ;; *::*) eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" ;; *) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" ;; esac } # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in $*""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } # ### END FUNCTIONS SHARED WITH CONFIGURE _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac ltmain=$ac_aux_dir/ltmain.sh # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi { $as_echo "$as_me:${as_lineno-$LINENO}: ------------------------------------------------------------------------ $PACKAGE_NAME $PACKAGE_VERSION: Automatic configuration OK. Compiler support: C99 var arrays: ................ ${has_var_arrays} C99 lrintf: .................... ${ac_cv_func_lrintf} Use alloca: .................... ${use_alloca} General configuration: Floating point support: ........ ${enable_float} Fast float approximations: ..... ${enable_float_approx} Fixed point debugging: ......... ${enable_fixed_point_debug} Inline Assembly Optimizations: . ${inline_optimization} External Assembly Optimizations: ${asm_optimization} Intrinsics Optimizations: ...... ${intrinsics_support} Run-time CPU detection: ........ ${rtcd_support} Custom modes: .................. ${enable_custom_modes} Assertion checking: ............ ${enable_assertions} Hardening: ..................... ${enable_hardening} Fuzzing: ....................... ${enable_fuzzing} Check ASM: ..................... ${enable_check_asm} API documentation: ............. ${enable_doc} Extra programs: ................ ${enable_extra_programs} ------------------------------------------------------------------------ Type \"make; make install\" to compile and install Type \"make check\" to run the test suite " >&5 $as_echo "$as_me: ------------------------------------------------------------------------ $PACKAGE_NAME $PACKAGE_VERSION: Automatic configuration OK. Compiler support: C99 var arrays: ................ ${has_var_arrays} C99 lrintf: .................... ${ac_cv_func_lrintf} Use alloca: .................... ${use_alloca} General configuration: Floating point support: ........ ${enable_float} Fast float approximations: ..... ${enable_float_approx} Fixed point debugging: ......... ${enable_fixed_point_debug} Inline Assembly Optimizations: . ${inline_optimization} External Assembly Optimizations: ${asm_optimization} Intrinsics Optimizations: ...... ${intrinsics_support} Run-time CPU detection: ........ ${rtcd_support} Custom modes: .................. ${enable_custom_modes} Assertion checking: ............ ${enable_assertions} Hardening: ..................... ${enable_hardening} Fuzzing: ....................... ${enable_fuzzing} Check ASM: ..................... ${enable_check_asm} API documentation: ............. ${enable_doc} Extra programs: ................ ${enable_extra_programs} ------------------------------------------------------------------------ Type \"make; make install\" to compile and install Type \"make check\" to run the test suite " >&6;} jamulus-3.9.1+dfsg/libs/opus/opus_sources.mk0000644000175000017500000000052114340334543020153 0ustar vimervimerOPUS_SOURCES = \ src/opus.c \ src/opus_decoder.c \ src/opus_encoder.c \ src/opus_multistream.c \ src/opus_multistream_encoder.c \ src/opus_multistream_decoder.c \ src/repacketizer.c \ src/opus_projection_encoder.c \ src/opus_projection_decoder.c \ src/mapping_matrix.c OPUS_SOURCES_FLOAT = \ src/analysis.c \ src/mlp.c \ src/mlp_data.c jamulus-3.9.1+dfsg/libs/opus/missing0000755000175000017500000001533114340334543016475 0ustar vimervimer#! /bin/sh # Common wrapper for a few potentially missing GNU programs. scriptversion=2016-01-11.22; # UTC # Copyright (C) 1996-2017 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try '$0 --help' for more information" exit 1 fi case $1 in --is-lightweight) # Used by our autoconf macros to check whether the available missing # script is modern enough. exit 0 ;; --run) # Back-compat with the calling convention used by older automake. shift ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit Supported PROGRAM values: aclocal autoconf autoheader autom4te automake makeinfo bison yacc flex lex help2man Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 'g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: unknown '$1' option" echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac # Run the given program, remember its exit status. "$@"; st=$? # If it succeeded, we are done. test $st -eq 0 && exit 0 # Also exit now if we it failed (or wasn't found), and '--version' was # passed; such an option is passed most likely to detect whether the # program is present and works. case $2 in --version|--help) exit $st;; esac # Exit code 63 means version mismatch. This often happens when the user # tries to use an ancient version of a tool on a file that requires a # minimum version. if test $st -eq 63; then msg="probably too old" elif test $st -eq 127; then # Program was missing. msg="missing on your system" else # Program was found and executed, but failed. Give up. exit $st fi perl_URL=http://www.perl.org/ flex_URL=http://flex.sourceforge.net/ gnu_software_URL=http://www.gnu.org/software program_details () { case $1 in aclocal|automake) echo "The '$1' program is part of the GNU Automake package:" echo "<$gnu_software_URL/automake>" echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/autoconf>" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; autoconf|autom4te|autoheader) echo "The '$1' program is part of the GNU Autoconf package:" echo "<$gnu_software_URL/autoconf/>" echo "It also requires GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; esac } give_advice () { # Normalize program name to check for. normalized_program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` printf '%s\n' "'$1' is $msg." configure_deps="'configure.ac' or m4 files included by 'configure.ac'" case $normalized_program in autoconf*) echo "You should only need it if you modified 'configure.ac'," echo "or m4 files included by it." program_details 'autoconf' ;; autoheader*) echo "You should only need it if you modified 'acconfig.h' or" echo "$configure_deps." program_details 'autoheader' ;; automake*) echo "You should only need it if you modified 'Makefile.am' or" echo "$configure_deps." program_details 'automake' ;; aclocal*) echo "You should only need it if you modified 'acinclude.m4' or" echo "$configure_deps." program_details 'aclocal' ;; autom4te*) echo "You might have modified some maintainer files that require" echo "the 'autom4te' program to be rebuilt." program_details 'autom4te' ;; bison*|yacc*) echo "You should only need it if you modified a '.y' file." echo "You may want to install the GNU Bison package:" echo "<$gnu_software_URL/bison/>" ;; lex*|flex*) echo "You should only need it if you modified a '.l' file." echo "You may want to install the Fast Lexical Analyzer package:" echo "<$flex_URL>" ;; help2man*) echo "You should only need it if you modified a dependency" \ "of a man page." echo "You may want to install the GNU Help2man package:" echo "<$gnu_software_URL/help2man/>" ;; makeinfo*) echo "You should only need it if you modified a '.texi' file, or" echo "any other file indirectly affecting the aspect of the manual." echo "You might want to install the Texinfo package:" echo "<$gnu_software_URL/texinfo/>" echo "The spurious makeinfo call might also be the consequence of" echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" echo "want to install GNU make:" echo "<$gnu_software_URL/make/>" ;; *) echo "You might have modified some files without having the proper" echo "tools for further handling them. Check the 'README' file, it" echo "often tells you about the needed prerequisites for installing" echo "this package. You may also peek at any GNU archive site, in" echo "case some other package contains this missing '$1' program." ;; esac } give_advice "$1" | sed -e '1s/^/WARNING: /' \ -e '2,$s/^/ /' >&2 # Propagate the correct exit status (expected to be 127 for a program # not found, 63 for a program that failed due to version mismatch). exit $st # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: jamulus-3.9.1+dfsg/libs/opus/doc/0000755000175000017500000000000014340334543015640 5ustar vimervimerjamulus-3.9.1+dfsg/libs/opus/doc/footer.html0000644000175000017500000000133714340334543020030 0ustar vimervimer
For more information visit the Opus Website.
jamulus-3.9.1+dfsg/libs/opus/doc/opus_logo.svg0000644000175000017500000002072414340334543020374 0ustar vimervimer jamulus-3.9.1+dfsg/libs/opus/doc/trivial_example.c0000644000175000017500000001244414340334543021176 0ustar vimervimer/* Copyright (c) 2013 Jean-Marc Valin */ /* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* This is meant to be a simple example of encoding and decoding audio using Opus. It should make it easy to understand how the Opus API works. For more information, see the full API documentation at: https://www.opus-codec.org/docs/ */ #include #include #include #include #include /*The frame size is hardcoded for this sample code but it doesn't have to be*/ #define FRAME_SIZE 960 #define SAMPLE_RATE 48000 #define CHANNELS 2 #define APPLICATION OPUS_APPLICATION_AUDIO #define BITRATE 64000 #define MAX_FRAME_SIZE 6*960 #define MAX_PACKET_SIZE (3*1276) int main(int argc, char **argv) { char *inFile; FILE *fin; char *outFile; FILE *fout; opus_int16 in[FRAME_SIZE*CHANNELS]; opus_int16 out[MAX_FRAME_SIZE*CHANNELS]; unsigned char cbits[MAX_PACKET_SIZE]; int nbBytes; /*Holds the state of the encoder and decoder */ OpusEncoder *encoder; OpusDecoder *decoder; int err; if (argc != 3) { fprintf(stderr, "usage: trivial_example input.pcm output.pcm\n"); fprintf(stderr, "input and output are 16-bit little-endian raw files\n"); return EXIT_FAILURE; } /*Create a new encoder state */ encoder = opus_encoder_create(SAMPLE_RATE, CHANNELS, APPLICATION, &err); if (err<0) { fprintf(stderr, "failed to create an encoder: %s\n", opus_strerror(err)); return EXIT_FAILURE; } /* Set the desired bit-rate. You can also set other parameters if needed. The Opus library is designed to have good defaults, so only set parameters you know you need. Doing otherwise is likely to result in worse quality, but better. */ err = opus_encoder_ctl(encoder, OPUS_SET_BITRATE(BITRATE)); if (err<0) { fprintf(stderr, "failed to set bitrate: %s\n", opus_strerror(err)); return EXIT_FAILURE; } inFile = argv[1]; fin = fopen(inFile, "r"); if (fin==NULL) { fprintf(stderr, "failed to open input file: %s\n", strerror(errno)); return EXIT_FAILURE; } /* Create a new decoder state. */ decoder = opus_decoder_create(SAMPLE_RATE, CHANNELS, &err); if (err<0) { fprintf(stderr, "failed to create decoder: %s\n", opus_strerror(err)); return EXIT_FAILURE; } outFile = argv[2]; fout = fopen(outFile, "w"); if (fout==NULL) { fprintf(stderr, "failed to open output file: %s\n", strerror(errno)); return EXIT_FAILURE; } while (1) { int i; unsigned char pcm_bytes[MAX_FRAME_SIZE*CHANNELS*2]; int frame_size; /* Read a 16 bits/sample audio frame. */ fread(pcm_bytes, sizeof(short)*CHANNELS, FRAME_SIZE, fin); if (feof(fin)) break; /* Convert from little-endian ordering. */ for (i=0;i>8)&0xFF; } /* Write the decoded audio to file. */ fwrite(pcm_bytes, sizeof(short), frame_size*CHANNELS, fout); } /*Destroy the encoder state*/ opus_encoder_destroy(encoder); opus_decoder_destroy(decoder); fclose(fin); fclose(fout); return EXIT_SUCCESS; } jamulus-3.9.1+dfsg/libs/opus/doc/Makefile.am0000644000175000017500000000233414340334543017676 0ustar vimervimer## Process this file with automake to produce Makefile.in DOCINPUTS = $(top_srcdir)/include/opus.h \ $(top_srcdir)/include/opus_multistream.h \ $(top_srcdir)/include/opus_defines.h \ $(top_srcdir)/include/opus_types.h \ $(top_srcdir)/include/opus_custom.h \ $(top_srcdir)/doc/header.html \ $(top_srcdir)/doc/footer.html \ $(top_srcdir)/doc/customdoxygen.css EXTRA_DIST = customdoxygen.css Doxyfile.in footer.html header.html \ opus_logo.svg trivial_example.c if HAVE_DOXYGEN all-local: doxygen-build.stamp doxygen-build.stamp: Doxyfile $(DOCINPUTS) doxygen touch $@ install-data-local: $(INSTALL) -d $(DESTDIR)$(docdir)/html/search for f in `find html -type f \! -name "installdox"`; do \ $(INSTALL_DATA) $$f $(DESTDIR)$(docdir)/$$f; \ done $(INSTALL) -d $(DESTDIR)$(mandir)/man3 cd man && find man3 -type f -name opus_*.3 \ -exec $(INSTALL_DATA) \{} $(DESTDIR)$(mandir)/man3 \; clean-local: $(RM) -r html $(RM) -r latex $(RM) -r man $(RM) doxygen-build.stamp $(RM) doxygen_sqlite3.db uninstall-local: $(RM) -r $(DESTDIR)$(docdir)/html $(RM) $(DESTDIR)$(mandir)/man3/opus_*.3 $(DESTDIR)$(mandir)/man3/opus.h.3 endif jamulus-3.9.1+dfsg/libs/opus/doc/customdoxygen.css0000644000175000017500000004271214340334543021270 0ustar vimervimer/* The standard CSS for doxygen */ body, table, div, p, dl { font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif; font-size: 13px; line-height: 1.3; } /* @group Heading Levels */ h1 { font-size: 150%; } .title { font-size: 150%; font-weight: bold; margin: 10px 2px; } h2 { font-size: 120%; } h3 { font-size: 100%; } dt { font-weight: bold; } div.multicol { -moz-column-gap: 1em; -webkit-column-gap: 1em; -moz-column-count: 3; -webkit-column-count: 3; } p.startli, p.startdd, p.starttd { margin-top: 2px; } p.endli { margin-bottom: 0px; } p.enddd { margin-bottom: 4px; } p.endtd { margin-bottom: 2px; } /* @end */ caption { font-weight: bold; } span.legend { font-size: 70%; text-align: center; } h3.version { font-size: 90%; text-align: center; } div.qindex, div.navtab{ background-color: #F1F1F1; border: 1px solid #BDBDBD; text-align: center; } div.qindex, div.navpath { width: 100%; line-height: 140%; } div.navtab { margin-right: 15px; } /* @group Link Styling */ a { color: #646464; font-weight: normal; text-decoration: none; } .contents a:visited { color: #747474; } a:hover { text-decoration: underline; } a.qindex { font-weight: bold; } a.qindexHL { font-weight: bold; background-color: #B8B8B8; color: #ffffff; border: 1px double #A8A8A8; } .contents a.qindexHL:visited { color: #ffffff; } a.el { font-weight: bold; } a.elRef { } a.code, a.code:visited { color: #4665A2; } a.codeRef, a.codeRef:visited { color: #4665A2; } /* @end */ dl.el { margin-left: -1cm; } .fragment { font-family: monospace, fixed; font-size: 105%; } pre.fragment { border: 1px solid #D5D5D5; background-color: #FCFCFC; padding: 4px 6px; margin: 4px 8px 4px 2px; overflow: auto; word-wrap: break-word; font-size: 9pt; line-height: 125%; } div.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px; padding: 0.2em; border: solid thin #333; border-radius: 0.5em; -webkit-border-radius: .5em; -moz-border-radius: .5em; box-shadow: 2px 2px 3px #999; -webkit-box-shadow: 2px 2px 3px #999; -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000); } div.groupHeader { margin-left: 16px; margin-top: 12px; font-weight: bold; } div.groupText { margin-left: 16px; font-style: italic; } body { background-color: white; color: black; margin: 0; } div.contents { margin-top: 10px; margin-left: 8px; margin-right: 8px; } td.indexkey { background-color: #F1F1F1; font-weight: bold; border: 1px solid #D5D5D5; margin: 2px 0px 2px 0; padding: 2px 10px; white-space: nowrap; vertical-align: top; } td.indexvalue { background-color: #F1F1F1; border: 1px solid #D5D5D5; padding: 2px 10px; margin: 2px 0px; } tr.memlist { background-color: #F2F2F2; } p.formulaDsp { text-align: center; } img.formulaDsp { } img.formulaInl { vertical-align: middle; } div.center { text-align: center; margin-top: 0px; margin-bottom: 0px; padding: 0px; } div.center img { border: 0px; } address.footer { text-align: right; padding-right: 12px; } img.footer { border: 0px; vertical-align: middle; } /* @group Code Colorization */ span.keyword { color: #008000 } span.keywordtype { color: #604020 } span.keywordflow { color: #e08000 } span.comment { color: #800000 } span.preprocessor { color: #806020 } span.stringliteral { color: #002080 } span.charliteral { color: #008080 } span.vhdldigit { color: #ff00ff } span.vhdlchar { color: #000000 } span.vhdlkeyword { color: #700070 } span.vhdllogic { color: #ff0000 } blockquote { background-color: #F9F9F9; border-left: 2px solid #B8B8B8; margin: 0 24px 0 4px; padding: 0 12px 0 16px; } /* @end */ /* .search { color: #003399; font-weight: bold; } form.search { margin-bottom: 0px; margin-top: 0px; } input.search { font-size: 75%; color: #000080; font-weight: normal; background-color: #e8eef2; } */ td.tiny { font-size: 75%; } .dirtab { padding: 4px; border-collapse: collapse; border: 1px solid #BDBDBD; } th.dirtab { background: #F1F1F1; font-weight: bold; } hr { height: 0px; border: none; border-top: 1px solid #7A7A7A; } hr.footer { height: 1px; } /* @group Member Descriptions */ table.memberdecls { border-spacing: 0px; padding: 0px; } .mdescLeft, .mdescRight, .memItemLeft, .memItemRight, .memTemplItemLeft, .memTemplItemRight, .memTemplParams { background-color: #FAFAFA; border: none; margin: 4px; padding: 1px 0 0 8px; } .mdescLeft, .mdescRight { padding: 0px 8px 4px 8px; color: #555; } .memItemLeft, .memItemRight, .memTemplParams { border-top: 1px solid #D5D5D5; } .memItemLeft, .memTemplItemLeft { white-space: nowrap; } .memItemRight { width: 100%; } .memTemplParams { color: #747474; white-space: nowrap; } /* @end */ /* @group Member Details */ /* Styles for detailed member documentation */ .memtemplate { font-size: 80%; color: #747474; font-weight: normal; margin-left: 9px; } .memnav { background-color: #F1F1F1; border: 1px solid #BDBDBD; text-align: center; margin: 2px; margin-right: 15px; padding: 2px; } .mempage { width: 100%; } .memitem { padding: 0; margin-bottom: 10px; margin-right: 5px; } .memname { white-space: nowrap; font-weight: bold; margin-left: 6px; } .memproto, dl.reflist dt { border-top: 1px solid #C0C0C0; border-left: 1px solid #C0C0C0; border-right: 1px solid #C0C0C0; padding: 6px 0px 6px 0px; color: #3D3D3D; font-weight: bold; text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); /* opera specific markup */ box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); border-top-right-radius: 8px; border-top-left-radius: 8px; /* firefox specific markup */ -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; -moz-border-radius-topright: 8px; -moz-border-radius-topleft: 8px; /* webkit specific markup */ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); -webkit-border-top-right-radius: 8px; -webkit-border-top-left-radius: 8px; background-image:url('nav_f.png'); background-repeat:repeat-x; background-color: #EAEAEA; } .memdoc, dl.reflist dd { border-bottom: 1px solid #C0C0C0; border-left: 1px solid #C0C0C0; border-right: 1px solid #C0C0C0; padding: 2px 5px; background-color: #FCFCFC; border-top-width: 0; /* opera specific markup */ border-bottom-left-radius: 8px; border-bottom-right-radius: 8px; box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); /* firefox specific markup */ -moz-border-radius-bottomleft: 8px; -moz-border-radius-bottomright: 8px; -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; background-image: -moz-linear-gradient(center top, #FFFFFF 0%, #FFFFFF 60%, #F9F9F9 95%, #F2F2F2); /* webkit specific markup */ -webkit-border-bottom-left-radius: 8px; -webkit-border-bottom-right-radius: 8px; -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); background-image: -webkit-gradient(linear,center top,center bottom,from(#FFFFFF), color-stop(0.6,#FFFFFF), color-stop(0.60,#FFFFFF), color-stop(0.95,#F9F9F9), to(#F2F2F2)); } dl.reflist dt { padding: 5px; } dl.reflist dd { margin: 0px 0px 10px 0px; padding: 5px; } .paramkey { text-align: right; } .paramtype { white-space: nowrap; } .paramname { color: #602020; white-space: nowrap; } .paramname em { font-style: normal; } .params, .retval, .exception, .tparams { border-spacing: 6px 2px; } .params .paramname, .retval .paramname { font-weight: bold; vertical-align: top; } .params .paramtype { font-style: italic; vertical-align: top; } .params .paramdir { font-family: "courier new",courier,monospace; vertical-align: top; } /* @end */ /* @group Directory (tree) */ /* for the tree view */ .ftvtree { font-family: sans-serif; margin: 0px; } /* these are for tree view when used as main index */ .directory { font-size: 9pt; font-weight: bold; margin: 5px; } .directory h3 { margin: 0px; margin-top: 1em; font-size: 11pt; } /* The following two styles can be used to replace the root node title with an image of your choice. Simply uncomment the next two styles, specify the name of your image and be sure to set 'height' to the proper pixel height of your image. */ /* .directory h3.swap { height: 61px; background-repeat: no-repeat; background-image: url("yourimage.gif"); } .directory h3.swap span { display: none; } */ .directory > h3 { margin-top: 0; } .directory p { margin: 0px; white-space: nowrap; } .directory div { display: none; margin: 0px; } .directory img { vertical-align: -30%; } /* these are for tree view when not used as main index */ .directory-alt { font-size: 100%; font-weight: bold; } .directory-alt h3 { margin: 0px; margin-top: 1em; font-size: 11pt; } .directory-alt > h3 { margin-top: 0; } .directory-alt p { margin: 0px; white-space: nowrap; } .directory-alt div { display: none; margin: 0px; } .directory-alt img { vertical-align: -30%; } /* @end */ div.dynheader { margin-top: 8px; } address { font-style: normal; color: #464646; } table.doxtable { border-collapse:collapse; margin-top: 4px; margin-bottom: 4px; } table.doxtable td, table.doxtable th { border: 1px solid #4A4A4A; padding: 3px 7px 2px; } table.doxtable th { background-color: #5B5B5B; color: #FFFFFF; font-size: 110%; padding-bottom: 4px; padding-top: 5px; } table.fieldtable { width: 100%; margin-bottom: 10px; border: 1px solid #C0C0C0; border-spacing: 0px; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); } .fieldtable td, .fieldtable th { padding: 3px 7px 2px; } .fieldtable td.fieldtype, .fieldtable td.fieldname { white-space: nowrap; border-right: 1px solid #C0C0C0; border-bottom: 1px solid #C0C0C0; vertical-align: top; } .fieldtable td.fielddoc { border-bottom: 1px solid #C0C0C0; width: 100%; } .fieldtable tr:last-child td { border-bottom: none; } .fieldtable th { background-image:url('nav_f.png'); background-repeat:repeat-x; background-color: #EAEAEA; font-size: 90%; color: #3D3D3D; padding-bottom: 4px; padding-top: 5px; text-align:left; -moz-border-radius-topleft: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-left-radius: 4px; -webkit-border-top-right-radius: 4px; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom: 1px solid #C0C0C0; } .tabsearch { top: 0px; left: 10px; height: 36px; background-image: url('tab_b.png'); z-index: 101; overflow: hidden; font-size: 13px; } .navpath ul { font-size: 11px; background-image:url('tab_b.png'); background-repeat:repeat-x; height:30px; line-height:30px; color:#ABABAB; border:solid 1px #D3D3D3; overflow:hidden; margin:0px; padding:0px; } .navpath li { list-style-type:none; float:left; padding-left:10px; padding-right:15px; background-image:url('bc_s.png'); background-repeat:no-repeat; background-position:right; color:#595959; } .navpath li.navelem a { height:32px; display:block; text-decoration: none; outline: none; } .navpath li.navelem a:hover { color:#929292; } .navpath li.footer { list-style-type:none; float:right; padding-left:10px; padding-right:15px; background-image:none; background-repeat:no-repeat; background-position:right; color:#595959; font-size: 8pt; } div.summary { float: right; font-size: 8pt; padding-right: 5px; width: 50%; text-align: right; } div.summary a { white-space: nowrap; } div.ingroups { margin-left: 5px; font-size: 8pt; padding-left: 5px; width: 50%; text-align: left; } div.ingroups a { white-space: nowrap; } div.header { background-image:url('nav_h.png'); background-repeat:repeat-x; background-color: #FAFAFA; margin: 0px; border-bottom: 1px solid #D5D5D5; } div.headertitle { padding: 5px 5px 5px 7px; } dl { padding: 0 0 0 10px; } /* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */ dl.section { border-left:4px solid; padding: 0 0 0 6px; } dl.note { border-color: #D0C000; } dl.warning, dl.attention { border-color: #FF0000; } dl.pre, dl.post, dl.invariant { border-color: #00D000; } dl.deprecated { border-color: #505050; } dl.todo { border-color: #00C0E0; } dl.test { border-color: #3030E0; } dl.bug { border-color: #C08050; } dl.section dd { margin-bottom: 6px; } #projectlogo { text-align: center; vertical-align: bottom; border-collapse: separate; } #projectlogo img { border: 0px none; } #projectname { font: 300% Tahoma, Arial,sans-serif; margin: 0px; padding: 2px 0px; } #projectbrief { font: 120% Tahoma, Arial,sans-serif; margin: 0px; padding: 0px; } #projectnumber { font: 100% Tahoma, Arial,sans-serif; margin: 0px; padding: 0px; } #titlearea { padding: 0px; margin: 0px; width: 100%; border-bottom: 1px solid #848484; } .image { text-align: center; } .dotgraph { text-align: center; } .mscgraph { text-align: center; } .caption { font-weight: bold; } div.zoom { border: 1px solid #AFAFAF; } dl.citelist { margin-bottom:50px; } dl.citelist dt { color:#545454; float:left; font-weight:bold; margin-right:10px; padding:5px; } dl.citelist dd { margin:2px 0; padding:5px 0; } div.toc { padding: 14px 25px; background-color: #F7F7F7; border: 1px solid #E3E3E3; border-radius: 7px 7px 7px 7px; float: right; height: auto; margin: 0 20px 10px 10px; width: 200px; } div.toc li { background: url("bdwn.png") no-repeat scroll 0 5px transparent; font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif; margin-top: 5px; padding-left: 10px; padding-top: 2px; } div.toc h3 { font: bold 12px/1.2 Arial,FreeSans,sans-serif; color: #747474; border-bottom: 0 none; margin: 0; } div.toc ul { list-style: none outside none; border: medium none; padding: 0px; } div.toc li.level1 { margin-left: 0px; } div.toc li.level2 { margin-left: 15px; } div.toc li.level3 { margin-left: 30px; } div.toc li.level4 { margin-left: 45px; } @media print { #top { display: none; } #side-nav { display: none; } #nav-path { display: none; } body { overflow:visible; } h1, h2, h3, h4, h5, h6 { page-break-after: avoid; } .summary { display: none; } .memitem { page-break-inside: avoid; } #doc-content { margin-left:0 !important; height:auto !important; width:auto !important; overflow:inherit; display:inline; } pre.fragment { overflow: visible; text-wrap: unrestricted; white-space: -moz-pre-wrap; /* Moz */ white-space: -pre-wrap; /* Opera 4-6 */ white-space: -o-pre-wrap; /* Opera 7 */ white-space: pre-wrap; /* CSS3 */ word-wrap: break-word; /* IE 5.5+ */ } } jamulus-3.9.1+dfsg/libs/opus/doc/Doxyfile.in0000644000175000017500000003545514340334543017767 0ustar vimervimer# Doxyfile 1.8.10 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a double hash (##) is considered a comment and is placed in # front of the TAG it is preceding. # # All text after a single hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists, items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (\" \"). # Only non-default options are included below to improve portability # between doxygen versions. # #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # The PROJECT_NAME tag is a single word (or a sequence of words surrounded by # double-quotes, unless you are using Doxywizard) that should identify the # project for which the documentation is generated. This name is used in the # title of most generated pages and in a few other places. # The default value is: My Project. PROJECT_NAME = Opus # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version # control system is used. PROJECT_NUMBER = @VERSION@ # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a # quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = "Opus audio codec (RFC 6716): API and operations manual" # With the PROJECT_LOGO tag one can specify a logo or an icon that is included # in the documentation. The maximum height of the logo should not exceed 55 # pixels and the maximum width should not exceed 200 pixels. Doxygen will copy # the logo to the output directory. PROJECT_LOGO = # If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path # before files name in the file list and in the header files. If set to NO the # shortest path that makes the file name unique will be used # The default value is: YES. FULL_PATH_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the # first line (until the first dot) of a Javadoc-style comment as the brief # description. If set to NO, the Javadoc-style will behave just like regular Qt- # style comments (thus requiring an explicit @brief command for a brief # description.) # The default value is: NO. JAVADOC_AUTOBRIEF = YES # The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen # uses this value to replace tabs by spaces in code fragments. # Minimum value: 1, maximum value: 16, default value: 4. TAB_SIZE = 8 # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources # only. Doxygen will then generate output that is more tailored for C. For # instance, some of the names that are used will be different. The list of all # members will be omitted, etc. # The default value is: NO. OPTIMIZE_OUTPUT_FOR_C = YES #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in # documentation are documented, even if no documentation was available. Private # class members and static file members will be hidden unless the # EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. # Note: This will also disable the warnings about undocumented members that are # normally produced when WARNINGS is set to YES. # The default value is: NO. EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will # be included in the documentation. # The default value is: NO. EXTRACT_PRIVATE = NO # If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file # names in lower-case letters. If set to YES, upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. # The default value is: system dependent. CASE_SENSE_NAMES = YES # The ENABLED_SECTIONS tag can be used to enable conditional documentation # sections, marked by \if ... \endif and \cond # ... \endcond blocks. ENABLED_SECTIONS = #--------------------------------------------------------------------------- # Configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated to # standard output by doxygen. If QUIET is set to YES this implies that the # messages are off. # The default value is: NO. QUIET = YES # The WARNINGS tag can be used to turn on/off the warning messages that are # generated to standard error (stderr) by doxygen. If WARNINGS is set to YES # this implies that the warnings are on. # # Tip: Turn warnings on while writing the documentation. # The default value is: YES. WARNINGS = YES #--------------------------------------------------------------------------- # Configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag is used to specify the files and/or directories that contain # documented source files. You may enter file names like myfile.cpp or # directories like /usr/src/myproject. Separate the files or directories with # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. INPUT = @top_srcdir@/include/opus.h \ @top_srcdir@/include/opus_types.h \ @top_srcdir@/include/opus_defines.h \ @top_srcdir@/include/opus_multistream.h \ @top_srcdir@/include/opus_custom.h # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. # # Note that relative paths are relative to the directory from which doxygen is # run. EXCLUDE = #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all # compounds will be generated. Enable this if the project contains a lot of # classes, structs, unions or interfaces. # The default value is: YES. ALPHABETICAL_INDEX = NO #--------------------------------------------------------------------------- # Configuration options related to the HTML output #--------------------------------------------------------------------------- # The HTML_HEADER tag can be used to specify a user-defined HTML header file for # each generated HTML page. If the tag is left blank doxygen will generate a # standard header. # # To get valid HTML the header file that includes any scripts and style sheets # that doxygen needs, which is dependent on the configuration options used (e.g. # the setting GENERATE_TREEVIEW). It is highly recommended to start with a # default header using # doxygen -w html new_header.html new_footer.html new_stylesheet.css # YourConfigFile # and then modify the file new_header.html. See also section "Doxygen usage" # for information on how to generate the default header that doxygen normally # uses. # Note: The header is subject to change so you typically have to regenerate the # default header when upgrading to a newer version of doxygen. For a description # of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_HEADER = @top_srcdir@/doc/header.html # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each # generated HTML page. If the tag is left blank doxygen will generate a standard # footer. See HTML_HEADER for more information on how to generate a default # footer and what special commands can be used inside the footer. See also # section "Doxygen usage" for information on how to generate the default footer # that doxygen normally uses. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FOOTER = @top_srcdir@/doc/footer.html # The HTML_STYLESHEET tag can be used to specify a user-defined cascading style # sheet that is used by each HTML page. It can be used to fine-tune the look of # the HTML output. If left blank doxygen will generate a default style sheet. # See also section "Doxygen usage" for information on how to generate the style # sheet that doxygen normally uses. # Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as # it is more robust and this tag (HTML_STYLESHEET) will in the future become # obsolete. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_STYLESHEET = @top_srcdir@/doc/customdoxygen.css # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that the # files will be copied as-is; there are no commands or markers available. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_FILES = @top_srcdir@/doc/opus_logo.svg # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors # in the HTML output. For a value of 0 the output will use grayscales only. A # value of 255 will produce the most vivid colors. # Minimum value: 0, maximum value: 255, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_SAT = 0 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting this # to YES can help to show when doxygen was last run and thus if the # documentation is up to date. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_TIMESTAMP = YES # When MathJax is enabled you need to specify the location relative to the HTML # output directory using the MATHJAX_RELPATH option. The destination directory # should contain the MathJax.js script. For instance, if the mathjax directory # is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax # Content Delivery Network so you can quickly see the result without installing # MathJax. However, it is strongly recommended to install a local copy of # MathJax from http://www.mathjax.org before deployment. # The default value is: http://cdn.mathjax.org/mathjax/latest. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_RELPATH = https://www.mathjax.org/mathjax #--------------------------------------------------------------------------- # Configuration options related to the LaTeX output #--------------------------------------------------------------------------- # The PAPER_TYPE tag can be used to set the paper type that is used by the # printer. # Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x # 14 inches) and executive (7.25 x 10.5 inches). # The default value is: a4. # This tag requires that the tag GENERATE_LATEX is set to YES. PAPER_TYPE = letter #--------------------------------------------------------------------------- # Configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for # classes and files. # The default value is: NO. GENERATE_MAN = YES #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names # in the source code. If set to NO, only conditional compilation will be # performed. Macro expansion can be done in a controlled way by setting # EXPAND_ONLY_PREDEF to YES. # The default value is: NO. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. MACRO_EXPANSION = YES # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then # the macro expansion is limited to the macros specified with the PREDEFINED and # EXPAND_AS_DEFINED tags. # The default value is: NO. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. EXPAND_ONLY_PREDEF = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by the # preprocessor. # This tag requires that the tag SEARCH_INCLUDES is set to YES. INCLUDE_PATH = # The PREDEFINED tag can be used to specify one or more macro names that are # defined before the preprocessor is started (similar to the -D option of e.g. # gcc). The argument of the tag is a list of macros of the form: name or # name=definition (no spaces). If the definition and the "=" are omitted, "=1" # is assumed. To prevent a macro definition from being undefined via #undef or # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. PREDEFINED = OPUS_EXPORT= \ OPUS_CUSTOM_EXPORT= \ OPUS_CUSTOM_EXPORT_STATIC= \ OPUS_WARN_UNUSED_RESULT= \ OPUS_ARG_NONNULL(_x)= #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz (see: # http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent # Bell Labs. # Debian defaults to YES here, while Fedora and Homebrew default to NO. # So we set this based on whether the graphviz package is available at # configure time. # HAVE_DOT = @HAVE_DOT@ jamulus-3.9.1+dfsg/libs/opus/doc/TODO0000644000175000017500000000024114340334543016325 0ustar vimervimerdefine audio bandwidth as frequency range repeat padding recommendation ptime: refer to RFC Opus does not provide any confidentiality or integrity protection jamulus-3.9.1+dfsg/libs/opus/doc/header.html0000644000175000017500000000352514340334543017763 0ustar vimervimer $projectname: $title $title $treeview $search $mathjax
Opus
$projectbrief
$projectnumber
$projectbrief
$searchbox
jamulus-3.9.1+dfsg/libs/opus/doc/Makefile.in0000644000175000017500000003534414340334543017716 0ustar vimervimer# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/as-gcc-inline-assembly.m4 \ $(top_srcdir)/m4/ax_add_fortify_source.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/opus-intrinsics.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = Doxyfile CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Doxyfile.in $(srcdir)/Makefile.in TODO DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ ARM2GNU_PARAMS = @ARM2GNU_PARAMS@ ARM_NEON_INTR_CFLAGS = @ARM_NEON_INTR_CFLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCAS = @CCAS@ CCASDEPMODE = @CCASDEPMODE@ CCASFLAGS = @CCASFLAGS@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_ARM_NE10 = @HAVE_ARM_NE10@ HAVE_DOT = @HAVE_DOT@ HAVE_DOXYGEN = @HAVE_DOXYGEN@ HAVE_PERL = @HAVE_PERL@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBM = @LIBM@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NE10_CFLAGS = @NE10_CFLAGS@ NE10_LIBS = @NE10_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPUS_ARM_MAY_HAVE_EDSP = @OPUS_ARM_MAY_HAVE_EDSP@ OPUS_ARM_MAY_HAVE_MEDIA = @OPUS_ARM_MAY_HAVE_MEDIA@ OPUS_ARM_MAY_HAVE_NEON = @OPUS_ARM_MAY_HAVE_NEON@ OPUS_ARM_NEON_INTR_CFLAGS = @OPUS_ARM_NEON_INTR_CFLAGS@ OPUS_HAVE_RTCD = @OPUS_HAVE_RTCD@ OPUS_LT_AGE = @OPUS_LT_AGE@ OPUS_LT_CURRENT = @OPUS_LT_CURRENT@ OPUS_LT_REVISION = @OPUS_LT_REVISION@ OPUS_X86_AVX_CFLAGS = @OPUS_X86_AVX_CFLAGS@ OPUS_X86_SSE2_CFLAGS = @OPUS_X86_SSE2_CFLAGS@ OPUS_X86_SSE4_1_CFLAGS = @OPUS_X86_SSE4_1_CFLAGS@ OPUS_X86_SSE_CFLAGS = @OPUS_X86_SSE_CFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PC_BUILD = @PC_BUILD@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ X86_AVX_CFLAGS = @X86_AVX_CFLAGS@ X86_SSE2_CFLAGS = @X86_SSE2_CFLAGS@ X86_SSE4_1_CFLAGS = @X86_SSE4_1_CFLAGS@ X86_SSE_CFLAGS = @X86_SSE_CFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ DOCINPUTS = $(top_srcdir)/include/opus.h \ $(top_srcdir)/include/opus_multistream.h \ $(top_srcdir)/include/opus_defines.h \ $(top_srcdir)/include/opus_types.h \ $(top_srcdir)/include/opus_custom.h \ $(top_srcdir)/doc/header.html \ $(top_srcdir)/doc/footer.html \ $(top_srcdir)/doc/customdoxygen.css EXTRA_DIST = customdoxygen.css Doxyfile.in footer.html header.html \ opus_logo.svg trivial_example.c all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): Doxyfile: $(top_builddir)/config.status $(srcdir)/Doxyfile.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am @HAVE_DOXYGEN_FALSE@all-local: all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." @HAVE_DOXYGEN_FALSE@install-data-local: @HAVE_DOXYGEN_FALSE@uninstall-local: @HAVE_DOXYGEN_FALSE@clean-local: clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-data-local install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-local .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-libtool clean-local cscopelist-am ctags-am distclean \ distclean-generic distclean-libtool distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-data-local install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ uninstall-am uninstall-local .PRECIOUS: Makefile @HAVE_DOXYGEN_TRUE@all-local: doxygen-build.stamp @HAVE_DOXYGEN_TRUE@doxygen-build.stamp: Doxyfile $(DOCINPUTS) @HAVE_DOXYGEN_TRUE@ doxygen @HAVE_DOXYGEN_TRUE@ touch $@ @HAVE_DOXYGEN_TRUE@install-data-local: @HAVE_DOXYGEN_TRUE@ $(INSTALL) -d $(DESTDIR)$(docdir)/html/search @HAVE_DOXYGEN_TRUE@ for f in `find html -type f \! -name "installdox"`; do \ @HAVE_DOXYGEN_TRUE@ $(INSTALL_DATA) $$f $(DESTDIR)$(docdir)/$$f; \ @HAVE_DOXYGEN_TRUE@ done @HAVE_DOXYGEN_TRUE@ $(INSTALL) -d $(DESTDIR)$(mandir)/man3 @HAVE_DOXYGEN_TRUE@ cd man && find man3 -type f -name opus_*.3 \ @HAVE_DOXYGEN_TRUE@ -exec $(INSTALL_DATA) \{} $(DESTDIR)$(mandir)/man3 \; @HAVE_DOXYGEN_TRUE@clean-local: @HAVE_DOXYGEN_TRUE@ $(RM) -r html @HAVE_DOXYGEN_TRUE@ $(RM) -r latex @HAVE_DOXYGEN_TRUE@ $(RM) -r man @HAVE_DOXYGEN_TRUE@ $(RM) doxygen-build.stamp @HAVE_DOXYGEN_TRUE@ $(RM) doxygen_sqlite3.db @HAVE_DOXYGEN_TRUE@uninstall-local: @HAVE_DOXYGEN_TRUE@ $(RM) -r $(DESTDIR)$(docdir)/html @HAVE_DOXYGEN_TRUE@ $(RM) $(DESTDIR)$(mandir)/man3/opus_*.3 $(DESTDIR)$(mandir)/man3/opus.h.3 # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: jamulus-3.9.1+dfsg/libs/opus/aclocal.m40000644000175000017500000012745114340334543016745 0ustar vimervimer# generated automatically by aclocal 1.15.1 -*- Autoconf -*- # Copyright (C) 1996-2017 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, [m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # Copyright (C) 2002-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.15' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.15.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.15.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # Figure out how to run the assembler. -*- Autoconf -*- # Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_AS # ---------- AC_DEFUN([AM_PROG_AS], [# By default we simply use the C compiler to build assembly code. AC_REQUIRE([AC_PROG_CC]) test "${CCAS+set}" = set || CCAS=$CC test "${CCASFLAGS+set}" = set || CCASFLAGS=$CFLAGS AC_ARG_VAR([CCAS], [assembler compiler command (defaults to CC)]) AC_ARG_VAR([CCASFLAGS], [assembler compiler flags (defaults to CFLAGS)]) _AM_IF_OPTION([no-dependencies],, [_AM_DEPENDENCIES([CCAS])])dnl ]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], [$1], [CXX], [depcc="$CXX" am_compiler_list=], [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], [$1], [UPC], [depcc="$UPC" am_compiler_list=], [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE([dependency-tracking], [dnl AS_HELP_STRING( [--enable-dependency-tracking], [do not reject slow dependency extractors]) AS_HELP_STRING( [--disable-dependency-tracking], [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each '.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC]) [_AM_PROG_CC_C_O ]) # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) AC_REQUIRE([AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) fi fi dnl The trailing newline in this macro's definition is deliberate, for dnl backward compatibility and to allow trailing 'dnl'-style comments dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. ]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) # Copyright (C) 2003-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering # Copyright (C) 1996-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAINTAINER_MODE([DEFAULT-MODE]) # ---------------------------------- # Control maintainer-specific portions of Makefiles. # Default is to disable them, unless 'enable' is passed literally. # For symmetry, 'disable' may be passed as well. Anyway, the user # can override the default with the --enable/--disable switch. AC_DEFUN([AM_MAINTAINER_MODE], [m4_case(m4_default([$1], [disable]), [enable], [m4_define([am_maintainer_other], [disable])], [disable], [m4_define([am_maintainer_other], [enable])], [m4_define([am_maintainer_other], [enable]) m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) dnl maintainer-mode's default is 'disable' unless 'enable' is passed AC_ARG_ENABLE([maintainer-mode], [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode], am_maintainer_other[ make rules and dependencies not useful (and sometimes confusing) to the casual installer])], [USE_MAINTAINER_MODE=$enableval], [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) AC_MSG_RESULT([$USE_MAINTAINER_MODE]) AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) MAINT=$MAINTAINER_MODE_TRUE AC_SUBST([MAINT])dnl ] ) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it is modern enough. # If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_CC_C_O # --------------- # Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC # to automatically call this. AC_DEFUN([_AM_PROG_CC_C_O], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl AC_LANG_PUSH([C])dnl AC_CACHE_CHECK( [whether $CC understands -c and -o together], [am_cv_prog_cc_c_o], [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i]) if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) # Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_RUN_LOG(COMMAND) # ------------------- # Run COMMAND, save the exit status in ac_status, and log it. # (This has been adapted from Autoconf's _AC_RUN_LOG macro.) AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi if test "$[2]" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT([yes]) # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) # Copyright (C) 2009-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT # ("yes" being less verbose, "no" or empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) case $enable_silent_rules in @%:@ ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) # Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar # AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar], [# The POSIX 1988 'ustar' format is defined with fixed-size fields. # There is notably a 21 bits limit for the UID and the GID. In fact, # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 # and bug#13588). am_max_uid=2097151 # 2^21 - 1 am_max_gid=$am_max_uid # The $UID and $GID variables are not portable, so we need to resort # to the POSIX-mandated id(1) utility. Errors in the 'id' calls # below are definitely unexpected, so allow the users to see them # (that is, avoid stderr redirection). am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) if test $am_uid -le $am_max_uid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) if test $am_gid -le $am_max_gid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi], [pax], [], [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_$1-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([m4/as-gcc-inline-assembly.m4]) m4_include([m4/ax_add_fortify_source.m4]) m4_include([m4/libtool.m4]) m4_include([m4/ltoptions.m4]) m4_include([m4/ltsugar.m4]) m4_include([m4/ltversion.m4]) m4_include([m4/lt~obsolete.m4]) m4_include([m4/opus-intrinsics.m4]) jamulus-3.9.1+dfsg/libs/opus/opus_config.cmake0000644000175000017500000000225114340334543020410 0ustar vimervimerinclude(opus_functions.cmake) configure_file(config.h.cmake.in config.h @ONLY) add_definitions(-DHAVE_CONFIG_H) set_property(GLOBAL PROPERTY USE_FOLDERS ON) set_property(GLOBAL PROPERTY C_STANDARD 99) if(MSVC) add_definitions(-D_CRT_SECURE_NO_WARNINGS) endif() include(CheckLibraryExists) check_library_exists(m floor "" HAVE_LIBM) if(HAVE_LIBM) list(APPEND OPUS_REQUIRED_LIBRARIES m) endif() if(CMAKE_SYSTEM_PROCESSOR MATCHES "(i[0-9]86|x86|X86|amd64|AMD64|x86_64)") if(CMAKE_SIZEOF_VOID_P EQUAL 8) set(OPUS_CPU_X64 1) else() set(OPUS_CPU_X86 1) endif() elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm") set(OPUS_CPU_ARM 1) endif() opus_supports_cpu_detection(RUNTIME_CPU_CAPABILITY_DETECTION) if(OPUS_CPU_X86 OR OPUS_CPU_X64) opus_detect_sse(COMPILER_SUPPORT_SIMD) elseif(OPUS_CPU_ARM) opus_detect_neon(COMPILER_SUPPORT_NEON) if(COMPILER_SUPPORT_NEON) option(OPUS_USE_NEON "Option to turn off SSE" ON) option(OPUS_MAY_SUPPORT_NEON "Does runtime check for neon support" ON) option(OPUS_PRESUME_NEON "Assume target CPU has NEON support" OFF) if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64") set(OPUS_PRESUME_NEON ON) endif() endif() endif() jamulus-3.9.1+dfsg/libs/opus/test-driver0000755000175000017500000001104114340334543017266 0ustar vimervimer#! /bin/sh # test-driver - basic testsuite driver script. scriptversion=2016-01-11.22; # UTC # Copyright (C) 2011-2017 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . # Make unconditional expansion of undefined variables an error. This # helps a lot in preventing typo-related bugs. set -u usage_error () { echo "$0: $*" >&2 print_usage >&2 exit 2 } print_usage () { cat <$log_file 2>&1 estatus=$? if test $enable_hard_errors = no && test $estatus -eq 99; then tweaked_estatus=1 else tweaked_estatus=$estatus fi case $tweaked_estatus:$expect_failure in 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; 0:*) col=$grn res=PASS recheck=no gcopy=no;; 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; *:*) col=$red res=FAIL recheck=yes gcopy=yes;; esac # Report the test outcome and exit status in the logs, so that one can # know whether the test passed or failed simply by looking at the '.log' # file, without the need of also peaking into the corresponding '.trs' # file (automake bug#11814). echo "$res $test_name (exit status: $estatus)" >>$log_file # Report outcome to console. echo "${col}${res}${std}: $test_name" # Register the test result, and other relevant metadata. echo ":test-result: $res" > $trs_file echo ":global-test-result: $res" >> $trs_file echo ":recheck: $recheck" >> $trs_file echo ":copy-in-global-log: $gcopy" >> $trs_file # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: jamulus-3.9.1+dfsg/libs/opus/opus-uninstalled.pc.in0000644000175000017500000000050214340334543021327 0ustar vimervimer# Opus codec reference implementation uninstalled pkg-config file libdir=${pcfiledir}/.libs includedir=${pcfiledir} Name: opus uninstalled Description: Opus IETF audio codec (not installed, @PC_BUILD@) Version: @VERSION@ Requires: Conflicts: Libs: ${libdir}/libopus.la @LIBM@ Cflags: -I${pcfiledir}/@top_srcdir@/include jamulus-3.9.1+dfsg/libs/opus/Makefile.unix0000644000175000017500000001056314340334543017522 0ustar vimervimer#################### COMPILE OPTIONS ####################### # Uncomment this for fixed-point build #FIXED_POINT=1 # It is strongly recommended to uncomment one of these # VAR_ARRAYS: Use C99 variable-length arrays for stack allocation # USE_ALLOCA: Use alloca() for stack allocation # If none is defined, then the fallback is a non-threadsafe global array CFLAGS := -DUSE_ALLOCA $(CFLAGS) #CFLAGS := -DVAR_ARRAYS $(CFLAGS) # These options affect performance # HAVE_LRINTF: Use C99 intrinsics to speed up float-to-int conversion #CFLAGS := -DHAVE_LRINTF $(CFLAGS) ###################### END OF OPTIONS ###################### -include package_version include silk_sources.mk include celt_sources.mk include opus_sources.mk ifdef FIXED_POINT SILK_SOURCES += $(SILK_SOURCES_FIXED) else SILK_SOURCES += $(SILK_SOURCES_FLOAT) OPUS_SOURCES += $(OPUS_SOURCES_FLOAT) endif EXESUFFIX = LIBPREFIX = lib LIBSUFFIX = .a OBJSUFFIX = .o CC = $(TOOLCHAIN_PREFIX)cc$(TOOLCHAIN_SUFFIX) AR = $(TOOLCHAIN_PREFIX)ar RANLIB = $(TOOLCHAIN_PREFIX)ranlib CP = $(TOOLCHAIN_PREFIX)cp cppflags-from-defines = $(addprefix -D,$(1)) cppflags-from-includes = $(addprefix -I,$(1)) ldflags-from-ldlibdirs = $(addprefix -L,$(1)) ldlibs-from-libs = $(addprefix -l,$(1)) WARNINGS = -Wall -W -Wstrict-prototypes -Wextra -Wcast-align -Wnested-externs -Wshadow CFLAGS += -O2 -g $(WARNINGS) -DOPUS_BUILD CINCLUDES = include silk celt ifdef FIXED_POINT CFLAGS += -DFIXED_POINT=1 -DDISABLE_FLOAT_API CINCLUDES += silk/fixed else CINCLUDES += silk/float endif LIBS = m LDLIBDIRS = ./ CFLAGS += $(call cppflags-from-defines,$(CDEFINES)) CFLAGS += $(call cppflags-from-includes,$(CINCLUDES)) LDFLAGS += $(call ldflags-from-ldlibdirs,$(LDLIBDIRS)) LDLIBS += $(call ldlibs-from-libs,$(LIBS)) COMPILE.c.cmdline = $(CC) -c $(CFLAGS) -o $@ $< LINK.o = $(CC) $(LDPREFLAGS) $(LDFLAGS) LINK.o.cmdline = $(LINK.o) $^ $(LDLIBS) -o $@$(EXESUFFIX) ARCHIVE.cmdline = $(AR) $(ARFLAGS) $@ $^ && $(RANLIB) $@ %$(OBJSUFFIX):%.c $(COMPILE.c.cmdline) %$(OBJSUFFIX):%.cpp $(COMPILE.cpp.cmdline) # Directives # Variable definitions LIB_NAME = opus TARGET = $(LIBPREFIX)$(LIB_NAME)$(LIBSUFFIX) SRCS_C = $(SILK_SOURCES) $(CELT_SOURCES) $(OPUS_SOURCES) OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(SRCS_C)) OPUSDEMO_SRCS_C = src/opus_demo.c OPUSDEMO_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(OPUSDEMO_SRCS_C)) TESTOPUSAPI_SRCS_C = tests/test_opus_api.c TESTOPUSAPI_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(TESTOPUSAPI_SRCS_C)) TESTOPUSDECODE_SRCS_C = tests/test_opus_decode.c TESTOPUSDECODE_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(TESTOPUSDECODE_SRCS_C)) TESTOPUSENCODE_SRCS_C = tests/test_opus_encode.c tests/opus_encode_regressions.c TESTOPUSENCODE_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(TESTOPUSENCODE_SRCS_C)) TESTOPUSPADDING_SRCS_C = tests/test_opus_padding.c TESTOPUSPADDING_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(TESTOPUSPADDING_SRCS_C)) OPUSCOMPARE_SRCS_C = src/opus_compare.c OPUSCOMPARE_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(OPUSCOMPARE_SRCS_C)) TESTS := test_opus_api test_opus_decode test_opus_encode test_opus_padding # Rules all: lib opus_demo opus_compare $(TESTS) lib: $(TARGET) check: all for test in $(TESTS); do ./$$test; done $(TARGET): $(OBJS) $(ARCHIVE.cmdline) opus_demo$(EXESUFFIX): $(OPUSDEMO_OBJS) $(TARGET) $(LINK.o.cmdline) test_opus_api$(EXESUFFIX): $(TESTOPUSAPI_OBJS) $(TARGET) $(LINK.o.cmdline) test_opus_decode$(EXESUFFIX): $(TESTOPUSDECODE_OBJS) $(TARGET) $(LINK.o.cmdline) test_opus_encode$(EXESUFFIX): $(TESTOPUSENCODE_OBJS) $(TARGET) $(LINK.o.cmdline) test_opus_padding$(EXESUFFIX): $(TESTOPUSPADDING_OBJS) $(TARGET) $(LINK.o.cmdline) opus_compare$(EXESUFFIX): $(OPUSCOMPARE_OBJS) $(LINK.o.cmdline) celt/celt.o: CFLAGS += -DPACKAGE_VERSION='$(PACKAGE_VERSION)' celt/celt.o: package_version package_version: force @if [ -x ./update_version ]; then \ ./update_version || true; \ elif [ ! -e ./package_version ]; then \ echo 'PACKAGE_VERSION="unknown"' > ./package_version; \ fi force: clean: rm -f opus_demo$(EXESUFFIX) opus_compare$(EXESUFFIX) $(TARGET) \ test_opus_api$(EXESUFFIX) test_opus_decode$(EXESUFFIX) \ test_opus_encode$(EXESUFFIX) test_opus_padding$(EXESUFFIX) \ $(OBJS) $(OPUSDEMO_OBJS) $(OPUSCOMPARE_OBJS) $(TESTOPUSAPI_OBJS) \ $(TESTOPUSDECODE_OBJS) $(TESTOPUSENCODE_OBJS) $(TESTOPUSPADDING_OBJS) .PHONY: all lib clean force check jamulus-3.9.1+dfsg/libs/opus/AUTHORS0000644000175000017500000000035714340334543016150 0ustar vimervimerJean-Marc Valin (jmvalin@jmvalin.ca) Koen Vos (koenvos74@gmail.com) Timothy Terriberry (tterribe@xiph.org) Karsten Vandborg Sorensen (karsten.vandborg.sorensen@skype.net) Soren Skak Jensen (ssjensen@gn.com) Gregory Maxwell (greg@xiph.org) jamulus-3.9.1+dfsg/libs/opus/Makefile.in0000644000175000017500000045473414340334543017161 0ustar vimervimer# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @FIXED_POINT_TRUE@am__append_1 = $(SILK_SOURCES_FIXED) @FIXED_POINT_TRUE@@HAVE_SSE4_1_TRUE@am__append_2 = $(SILK_SOURCES_SSE4_1) $(SILK_SOURCES_FIXED_SSE4_1) @FIXED_POINT_TRUE@@HAVE_ARM_NEON_INTR_TRUE@am__append_3 = $(SILK_SOURCES_FIXED_ARM_NEON_INTR) @FIXED_POINT_FALSE@am__append_4 = $(SILK_SOURCES_FLOAT) @FIXED_POINT_FALSE@@HAVE_SSE4_1_TRUE@am__append_5 = $(SILK_SOURCES_SSE4_1) @DISABLE_FLOAT_API_FALSE@am__append_6 = $(OPUS_SOURCES_FLOAT) @HAVE_SSE_TRUE@am__append_7 = $(CELT_SOURCES_SSE) @HAVE_SSE2_TRUE@am__append_8 = $(CELT_SOURCES_SSE2) @HAVE_SSE4_1_TRUE@am__append_9 = $(CELT_SOURCES_SSE4_1) @CPU_ARM_TRUE@am__append_10 = $(CELT_SOURCES_ARM) @CPU_ARM_TRUE@am__append_11 = $(SILK_SOURCES_ARM) @CPU_ARM_TRUE@@HAVE_ARM_NEON_INTR_TRUE@am__append_12 = $(CELT_SOURCES_ARM_NEON_INTR) @CPU_ARM_TRUE@@HAVE_ARM_NEON_INTR_TRUE@am__append_13 = $(SILK_SOURCES_ARM_NEON_INTR) @CPU_ARM_TRUE@@HAVE_ARM_NE10_TRUE@am__append_14 = $(CELT_SOURCES_ARM_NE10) @OPUS_ARM_EXTERNAL_ASM_TRUE@am__append_15 = libarmasm.la @EXTRA_PROGRAMS_TRUE@noinst_PROGRAMS = \ @EXTRA_PROGRAMS_TRUE@ celt/tests/test_unit_cwrs32$(EXEEXT) \ @EXTRA_PROGRAMS_TRUE@ celt/tests/test_unit_dft$(EXEEXT) \ @EXTRA_PROGRAMS_TRUE@ celt/tests/test_unit_entropy$(EXEEXT) \ @EXTRA_PROGRAMS_TRUE@ celt/tests/test_unit_laplace$(EXEEXT) \ @EXTRA_PROGRAMS_TRUE@ celt/tests/test_unit_mathops$(EXEEXT) \ @EXTRA_PROGRAMS_TRUE@ celt/tests/test_unit_mdct$(EXEEXT) \ @EXTRA_PROGRAMS_TRUE@ celt/tests/test_unit_rotation$(EXEEXT) \ @EXTRA_PROGRAMS_TRUE@ celt/tests/test_unit_types$(EXEEXT) \ @EXTRA_PROGRAMS_TRUE@ opus_compare$(EXEEXT) opus_demo$(EXEEXT) \ @EXTRA_PROGRAMS_TRUE@ repacketizer_demo$(EXEEXT) \ @EXTRA_PROGRAMS_TRUE@ silk/tests/test_unit_LPC_inv_pred_gain$(EXEEXT) \ @EXTRA_PROGRAMS_TRUE@ tests/test_opus_api$(EXEEXT) \ @EXTRA_PROGRAMS_TRUE@ tests/test_opus_decode$(EXEEXT) \ @EXTRA_PROGRAMS_TRUE@ tests/test_opus_encode$(EXEEXT) \ @EXTRA_PROGRAMS_TRUE@ tests/test_opus_padding$(EXEEXT) \ @EXTRA_PROGRAMS_TRUE@ tests/test_opus_projection$(EXEEXT) \ @EXTRA_PROGRAMS_TRUE@ $(am__EXEEXT_1) @EXTRA_PROGRAMS_TRUE@TESTS = celt/tests/test_unit_cwrs32$(EXEEXT) \ @EXTRA_PROGRAMS_TRUE@ celt/tests/test_unit_dft$(EXEEXT) \ @EXTRA_PROGRAMS_TRUE@ celt/tests/test_unit_entropy$(EXEEXT) \ @EXTRA_PROGRAMS_TRUE@ celt/tests/test_unit_laplace$(EXEEXT) \ @EXTRA_PROGRAMS_TRUE@ celt/tests/test_unit_mathops$(EXEEXT) \ @EXTRA_PROGRAMS_TRUE@ celt/tests/test_unit_mdct$(EXEEXT) \ @EXTRA_PROGRAMS_TRUE@ celt/tests/test_unit_rotation$(EXEEXT) \ @EXTRA_PROGRAMS_TRUE@ celt/tests/test_unit_types$(EXEEXT) \ @EXTRA_PROGRAMS_TRUE@ silk/tests/test_unit_LPC_inv_pred_gain$(EXEEXT) \ @EXTRA_PROGRAMS_TRUE@ tests/test_opus_api$(EXEEXT) \ @EXTRA_PROGRAMS_TRUE@ tests/test_opus_decode$(EXEEXT) \ @EXTRA_PROGRAMS_TRUE@ tests/test_opus_encode$(EXEEXT) \ @EXTRA_PROGRAMS_TRUE@ tests/test_opus_padding$(EXEEXT) \ @EXTRA_PROGRAMS_TRUE@ tests/test_opus_projection$(EXEEXT) @EXTRA_PROGRAMS_TRUE@@OPUS_ARM_EXTERNAL_ASM_TRUE@am__append_16 = libarmasm.la @EXTRA_PROGRAMS_TRUE@@OPUS_ARM_EXTERNAL_ASM_TRUE@am__append_17 = libarmasm.la @EXTRA_PROGRAMS_TRUE@@OPUS_ARM_EXTERNAL_ASM_TRUE@am__append_18 = libarmasm.la @EXTRA_PROGRAMS_TRUE@@OPUS_ARM_EXTERNAL_ASM_TRUE@am__append_19 = libarmasm.la @EXTRA_PROGRAMS_TRUE@@OPUS_ARM_EXTERNAL_ASM_TRUE@am__append_20 = libarmasm.la @EXTRA_PROGRAMS_TRUE@@OPUS_ARM_EXTERNAL_ASM_TRUE@am__append_21 = libarmasm.la @CUSTOM_MODES_TRUE@am__append_22 = include/opus_custom.h @CUSTOM_MODES_TRUE@@EXTRA_PROGRAMS_TRUE@am__append_23 = opus_custom_demo subdir = . SUBDIRS = ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/as-gcc-inline-assembly.m4 \ $(top_srcdir)/m4/ax_add_fortify_source.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/opus-intrinsics.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ $(am__configure_deps) $(noinst_HEADERS) \ $(am__pkginclude_HEADERS_DIST) $(am__DIST_COMMON) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = opus.pc opus-uninstalled.pc celt/arm/armopts.s CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(m4datadir)" \ "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(pkgincludedir)" LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES) libarmasm_la_LIBADD = am__libarmasm_la_SOURCES_DIST = celt/arm/celt_pitch_xcorr_arm-gnu.S am__dirstamp = $(am__leading_dot)dirstamp am__objects_1 = celt/arm/celt_pitch_xcorr_arm-gnu.lo @CPU_ARM_TRUE@@OPUS_ARM_EXTERNAL_ASM_TRUE@am_libarmasm_la_OBJECTS = \ @CPU_ARM_TRUE@@OPUS_ARM_EXTERNAL_ASM_TRUE@ $(am__objects_1) libarmasm_la_OBJECTS = $(am_libarmasm_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = @CPU_ARM_TRUE@@OPUS_ARM_EXTERNAL_ASM_TRUE@am_libarmasm_la_rpath = am__DEPENDENCIES_1 = libopus_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__append_15) am__libopus_la_SOURCES_DIST = celt/bands.c celt/celt.c \ celt/celt_encoder.c celt/celt_decoder.c celt/cwrs.c \ celt/entcode.c celt/entdec.c celt/entenc.c celt/kiss_fft.c \ celt/laplace.c celt/mathops.c celt/mdct.c celt/modes.c \ celt/pitch.c celt/celt_lpc.c celt/quant_bands.c celt/rate.c \ celt/vq.c celt/x86/x86cpu.c celt/x86/x86_celt_map.c \ celt/x86/pitch_sse.c celt/x86/pitch_sse2.c celt/x86/vq_sse2.c \ celt/x86/celt_lpc_sse4_1.c celt/x86/pitch_sse4_1.c \ celt/arm/armcpu.c celt/arm/arm_celt_map.c \ celt/arm/celt_neon_intr.c celt/arm/pitch_neon_intr.c \ celt/arm/celt_fft_ne10.c celt/arm/celt_mdct_ne10.c silk/CNG.c \ silk/code_signs.c silk/init_decoder.c silk/decode_core.c \ silk/decode_frame.c silk/decode_parameters.c \ silk/decode_indices.c silk/decode_pulses.c \ silk/decoder_set_fs.c silk/dec_API.c silk/enc_API.c \ silk/encode_indices.c silk/encode_pulses.c silk/gain_quant.c \ silk/interpolate.c silk/LP_variable_cutoff.c \ silk/NLSF_decode.c silk/NSQ.c silk/NSQ_del_dec.c silk/PLC.c \ silk/shell_coder.c silk/tables_gain.c silk/tables_LTP.c \ silk/tables_NLSF_CB_NB_MB.c silk/tables_NLSF_CB_WB.c \ silk/tables_other.c silk/tables_pitch_lag.c \ silk/tables_pulses_per_block.c silk/VAD.c \ silk/control_audio_bandwidth.c silk/quant_LTP_gains.c \ silk/VQ_WMat_EC.c silk/HP_variable_cutoff.c silk/NLSF_encode.c \ silk/NLSF_VQ.c silk/NLSF_unpack.c silk/NLSF_del_dec_quant.c \ silk/process_NLSFs.c silk/stereo_LR_to_MS.c \ silk/stereo_MS_to_LR.c silk/check_control_input.c \ silk/control_SNR.c silk/init_encoder.c silk/control_codec.c \ silk/A2NLSF.c silk/ana_filt_bank_1.c silk/biquad_alt.c \ silk/bwexpander_32.c silk/bwexpander.c silk/debug.c \ silk/decode_pitch.c silk/inner_prod_aligned.c silk/lin2log.c \ silk/log2lin.c silk/LPC_analysis_filter.c \ silk/LPC_inv_pred_gain.c silk/table_LSF_cos.c silk/NLSF2A.c \ silk/NLSF_stabilize.c silk/NLSF_VQ_weights_laroia.c \ silk/pitch_est_tables.c silk/resampler.c \ silk/resampler_down2_3.c silk/resampler_down2.c \ silk/resampler_private_AR2.c silk/resampler_private_down_FIR.c \ silk/resampler_private_IIR_FIR.c \ silk/resampler_private_up2_HQ.c silk/resampler_rom.c \ silk/sigm_Q15.c silk/sort.c silk/sum_sqr_shift.c \ silk/stereo_decode_pred.c silk/stereo_encode_pred.c \ silk/stereo_find_predictor.c silk/stereo_quant_pred.c \ silk/LPC_fit.c silk/fixed/LTP_analysis_filter_FIX.c \ silk/fixed/LTP_scale_ctrl_FIX.c silk/fixed/corrMatrix_FIX.c \ silk/fixed/encode_frame_FIX.c silk/fixed/find_LPC_FIX.c \ silk/fixed/find_LTP_FIX.c silk/fixed/find_pitch_lags_FIX.c \ silk/fixed/find_pred_coefs_FIX.c \ silk/fixed/noise_shape_analysis_FIX.c \ silk/fixed/process_gains_FIX.c \ silk/fixed/regularize_correlations_FIX.c \ silk/fixed/residual_energy16_FIX.c \ silk/fixed/residual_energy_FIX.c \ silk/fixed/warped_autocorrelation_FIX.c \ silk/fixed/apply_sine_window_FIX.c silk/fixed/autocorr_FIX.c \ silk/fixed/burg_modified_FIX.c silk/fixed/k2a_FIX.c \ silk/fixed/k2a_Q16_FIX.c silk/fixed/pitch_analysis_core_FIX.c \ silk/fixed/vector_ops_FIX.c silk/fixed/schur64_FIX.c \ silk/fixed/schur_FIX.c silk/x86/NSQ_sse4_1.c \ silk/x86/NSQ_del_dec_sse4_1.c silk/x86/x86_silk_map.c \ silk/x86/VAD_sse4_1.c silk/x86/VQ_WMat_EC_sse4_1.c \ silk/fixed/x86/vector_ops_FIX_sse4_1.c \ silk/fixed/x86/burg_modified_FIX_sse4_1.c \ silk/fixed/arm/warped_autocorrelation_FIX_neon_intr.c \ silk/float/apply_sine_window_FLP.c silk/float/corrMatrix_FLP.c \ silk/float/encode_frame_FLP.c silk/float/find_LPC_FLP.c \ silk/float/find_LTP_FLP.c silk/float/find_pitch_lags_FLP.c \ silk/float/find_pred_coefs_FLP.c \ silk/float/LPC_analysis_filter_FLP.c \ silk/float/LTP_analysis_filter_FLP.c \ silk/float/LTP_scale_ctrl_FLP.c \ silk/float/noise_shape_analysis_FLP.c \ silk/float/process_gains_FLP.c \ silk/float/regularize_correlations_FLP.c \ silk/float/residual_energy_FLP.c \ silk/float/warped_autocorrelation_FLP.c \ silk/float/wrappers_FLP.c silk/float/autocorrelation_FLP.c \ silk/float/burg_modified_FLP.c silk/float/bwexpander_FLP.c \ silk/float/energy_FLP.c silk/float/inner_product_FLP.c \ silk/float/k2a_FLP.c silk/float/LPC_inv_pred_gain_FLP.c \ silk/float/pitch_analysis_core_FLP.c \ silk/float/scale_copy_vector_FLP.c \ silk/float/scale_vector_FLP.c silk/float/schur_FLP.c \ silk/float/sort_FLP.c silk/arm/arm_silk_map.c \ silk/arm/biquad_alt_neon_intr.c \ silk/arm/LPC_inv_pred_gain_neon_intr.c \ silk/arm/NSQ_del_dec_neon_intr.c silk/arm/NSQ_neon.c \ src/opus.c src/opus_decoder.c src/opus_encoder.c \ src/opus_multistream.c src/opus_multistream_encoder.c \ src/opus_multistream_decoder.c src/repacketizer.c \ src/opus_projection_encoder.c src/opus_projection_decoder.c \ src/mapping_matrix.c src/analysis.c src/mlp.c src/mlp_data.c am__objects_2 = celt/x86/x86cpu.lo celt/x86/x86_celt_map.lo \ celt/x86/pitch_sse.lo @HAVE_SSE_TRUE@am__objects_3 = $(am__objects_2) am__objects_4 = celt/x86/pitch_sse2.lo celt/x86/vq_sse2.lo @HAVE_SSE2_TRUE@am__objects_5 = $(am__objects_4) am__objects_6 = celt/x86/celt_lpc_sse4_1.lo celt/x86/pitch_sse4_1.lo @HAVE_SSE4_1_TRUE@am__objects_7 = $(am__objects_6) am__objects_8 = celt/arm/armcpu.lo celt/arm/arm_celt_map.lo @CPU_ARM_TRUE@am__objects_9 = $(am__objects_8) am__objects_10 = celt/arm/celt_neon_intr.lo \ celt/arm/pitch_neon_intr.lo @CPU_ARM_TRUE@@HAVE_ARM_NEON_INTR_TRUE@am__objects_11 = \ @CPU_ARM_TRUE@@HAVE_ARM_NEON_INTR_TRUE@ $(am__objects_10) am__objects_12 = celt/arm/celt_fft_ne10.lo celt/arm/celt_mdct_ne10.lo @CPU_ARM_TRUE@@HAVE_ARM_NE10_TRUE@am__objects_13 = $(am__objects_12) am__objects_14 = celt/bands.lo celt/celt.lo celt/celt_encoder.lo \ celt/celt_decoder.lo celt/cwrs.lo celt/entcode.lo \ celt/entdec.lo celt/entenc.lo celt/kiss_fft.lo celt/laplace.lo \ celt/mathops.lo celt/mdct.lo celt/modes.lo celt/pitch.lo \ celt/celt_lpc.lo celt/quant_bands.lo celt/rate.lo celt/vq.lo \ $(am__objects_3) $(am__objects_5) $(am__objects_7) \ $(am__objects_9) $(am__objects_11) $(am__objects_13) am__objects_15 = silk/fixed/LTP_analysis_filter_FIX.lo \ silk/fixed/LTP_scale_ctrl_FIX.lo silk/fixed/corrMatrix_FIX.lo \ silk/fixed/encode_frame_FIX.lo silk/fixed/find_LPC_FIX.lo \ silk/fixed/find_LTP_FIX.lo silk/fixed/find_pitch_lags_FIX.lo \ silk/fixed/find_pred_coefs_FIX.lo \ silk/fixed/noise_shape_analysis_FIX.lo \ silk/fixed/process_gains_FIX.lo \ silk/fixed/regularize_correlations_FIX.lo \ silk/fixed/residual_energy16_FIX.lo \ silk/fixed/residual_energy_FIX.lo \ silk/fixed/warped_autocorrelation_FIX.lo \ silk/fixed/apply_sine_window_FIX.lo silk/fixed/autocorr_FIX.lo \ silk/fixed/burg_modified_FIX.lo silk/fixed/k2a_FIX.lo \ silk/fixed/k2a_Q16_FIX.lo \ silk/fixed/pitch_analysis_core_FIX.lo \ silk/fixed/vector_ops_FIX.lo silk/fixed/schur64_FIX.lo \ silk/fixed/schur_FIX.lo @FIXED_POINT_TRUE@am__objects_16 = $(am__objects_15) am__objects_17 = silk/x86/NSQ_sse4_1.lo silk/x86/NSQ_del_dec_sse4_1.lo \ silk/x86/x86_silk_map.lo silk/x86/VAD_sse4_1.lo \ silk/x86/VQ_WMat_EC_sse4_1.lo am__objects_18 = silk/fixed/x86/vector_ops_FIX_sse4_1.lo \ silk/fixed/x86/burg_modified_FIX_sse4_1.lo @FIXED_POINT_TRUE@@HAVE_SSE4_1_TRUE@am__objects_19 = \ @FIXED_POINT_TRUE@@HAVE_SSE4_1_TRUE@ $(am__objects_17) \ @FIXED_POINT_TRUE@@HAVE_SSE4_1_TRUE@ $(am__objects_18) am__objects_20 = \ silk/fixed/arm/warped_autocorrelation_FIX_neon_intr.lo @FIXED_POINT_TRUE@@HAVE_ARM_NEON_INTR_TRUE@am__objects_21 = \ @FIXED_POINT_TRUE@@HAVE_ARM_NEON_INTR_TRUE@ $(am__objects_20) am__objects_22 = silk/float/apply_sine_window_FLP.lo \ silk/float/corrMatrix_FLP.lo silk/float/encode_frame_FLP.lo \ silk/float/find_LPC_FLP.lo silk/float/find_LTP_FLP.lo \ silk/float/find_pitch_lags_FLP.lo \ silk/float/find_pred_coefs_FLP.lo \ silk/float/LPC_analysis_filter_FLP.lo \ silk/float/LTP_analysis_filter_FLP.lo \ silk/float/LTP_scale_ctrl_FLP.lo \ silk/float/noise_shape_analysis_FLP.lo \ silk/float/process_gains_FLP.lo \ silk/float/regularize_correlations_FLP.lo \ silk/float/residual_energy_FLP.lo \ silk/float/warped_autocorrelation_FLP.lo \ silk/float/wrappers_FLP.lo silk/float/autocorrelation_FLP.lo \ silk/float/burg_modified_FLP.lo silk/float/bwexpander_FLP.lo \ silk/float/energy_FLP.lo silk/float/inner_product_FLP.lo \ silk/float/k2a_FLP.lo silk/float/LPC_inv_pred_gain_FLP.lo \ silk/float/pitch_analysis_core_FLP.lo \ silk/float/scale_copy_vector_FLP.lo \ silk/float/scale_vector_FLP.lo silk/float/schur_FLP.lo \ silk/float/sort_FLP.lo @FIXED_POINT_FALSE@am__objects_23 = $(am__objects_22) @FIXED_POINT_FALSE@@HAVE_SSE4_1_TRUE@am__objects_24 = \ @FIXED_POINT_FALSE@@HAVE_SSE4_1_TRUE@ $(am__objects_17) am__objects_25 = am__objects_26 = silk/arm/arm_silk_map.lo \ silk/arm/biquad_alt_neon_intr.lo \ silk/arm/LPC_inv_pred_gain_neon_intr.lo \ silk/arm/NSQ_del_dec_neon_intr.lo silk/arm/NSQ_neon.lo @CPU_ARM_TRUE@@HAVE_ARM_NEON_INTR_TRUE@am__objects_27 = \ @CPU_ARM_TRUE@@HAVE_ARM_NEON_INTR_TRUE@ $(am__objects_26) am__objects_28 = silk/CNG.lo silk/code_signs.lo silk/init_decoder.lo \ silk/decode_core.lo silk/decode_frame.lo \ silk/decode_parameters.lo silk/decode_indices.lo \ silk/decode_pulses.lo silk/decoder_set_fs.lo silk/dec_API.lo \ silk/enc_API.lo silk/encode_indices.lo silk/encode_pulses.lo \ silk/gain_quant.lo silk/interpolate.lo \ silk/LP_variable_cutoff.lo silk/NLSF_decode.lo silk/NSQ.lo \ silk/NSQ_del_dec.lo silk/PLC.lo silk/shell_coder.lo \ silk/tables_gain.lo silk/tables_LTP.lo \ silk/tables_NLSF_CB_NB_MB.lo silk/tables_NLSF_CB_WB.lo \ silk/tables_other.lo silk/tables_pitch_lag.lo \ silk/tables_pulses_per_block.lo silk/VAD.lo \ silk/control_audio_bandwidth.lo silk/quant_LTP_gains.lo \ silk/VQ_WMat_EC.lo silk/HP_variable_cutoff.lo \ silk/NLSF_encode.lo silk/NLSF_VQ.lo silk/NLSF_unpack.lo \ silk/NLSF_del_dec_quant.lo silk/process_NLSFs.lo \ silk/stereo_LR_to_MS.lo silk/stereo_MS_to_LR.lo \ silk/check_control_input.lo silk/control_SNR.lo \ silk/init_encoder.lo silk/control_codec.lo silk/A2NLSF.lo \ silk/ana_filt_bank_1.lo silk/biquad_alt.lo \ silk/bwexpander_32.lo silk/bwexpander.lo silk/debug.lo \ silk/decode_pitch.lo silk/inner_prod_aligned.lo \ silk/lin2log.lo silk/log2lin.lo silk/LPC_analysis_filter.lo \ silk/LPC_inv_pred_gain.lo silk/table_LSF_cos.lo silk/NLSF2A.lo \ silk/NLSF_stabilize.lo silk/NLSF_VQ_weights_laroia.lo \ silk/pitch_est_tables.lo silk/resampler.lo \ silk/resampler_down2_3.lo silk/resampler_down2.lo \ silk/resampler_private_AR2.lo \ silk/resampler_private_down_FIR.lo \ silk/resampler_private_IIR_FIR.lo \ silk/resampler_private_up2_HQ.lo silk/resampler_rom.lo \ silk/sigm_Q15.lo silk/sort.lo silk/sum_sqr_shift.lo \ silk/stereo_decode_pred.lo silk/stereo_encode_pred.lo \ silk/stereo_find_predictor.lo silk/stereo_quant_pred.lo \ silk/LPC_fit.lo $(am__objects_16) $(am__objects_19) \ $(am__objects_21) $(am__objects_23) $(am__objects_24) \ $(am__objects_25) $(am__objects_27) am__objects_29 = src/analysis.lo src/mlp.lo src/mlp_data.lo @DISABLE_FLOAT_API_FALSE@am__objects_30 = $(am__objects_29) am__objects_31 = src/opus.lo src/opus_decoder.lo src/opus_encoder.lo \ src/opus_multistream.lo src/opus_multistream_encoder.lo \ src/opus_multistream_decoder.lo src/repacketizer.lo \ src/opus_projection_encoder.lo src/opus_projection_decoder.lo \ src/mapping_matrix.lo $(am__objects_30) am_libopus_la_OBJECTS = $(am__objects_14) $(am__objects_28) \ $(am__objects_31) libopus_la_OBJECTS = $(am_libopus_la_OBJECTS) libopus_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libopus_la_LDFLAGS) $(LDFLAGS) -o $@ @CUSTOM_MODES_TRUE@@EXTRA_PROGRAMS_TRUE@am__EXEEXT_1 = opus_custom_demo$(EXEEXT) PROGRAMS = $(noinst_PROGRAMS) am__celt_tests_test_unit_cwrs32_SOURCES_DIST = \ celt/tests/test_unit_cwrs32.c @EXTRA_PROGRAMS_TRUE@am_celt_tests_test_unit_cwrs32_OBJECTS = \ @EXTRA_PROGRAMS_TRUE@ celt/tests/test_unit_cwrs32.$(OBJEXT) celt_tests_test_unit_cwrs32_OBJECTS = \ $(am_celt_tests_test_unit_cwrs32_OBJECTS) @EXTRA_PROGRAMS_TRUE@celt_tests_test_unit_cwrs32_DEPENDENCIES = \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_1) am__celt_tests_test_unit_dft_SOURCES_DIST = \ celt/tests/test_unit_dft.c @EXTRA_PROGRAMS_TRUE@am_celt_tests_test_unit_dft_OBJECTS = \ @EXTRA_PROGRAMS_TRUE@ celt/tests/test_unit_dft.$(OBJEXT) celt_tests_test_unit_dft_OBJECTS = \ $(am_celt_tests_test_unit_dft_OBJECTS) am__DEPENDENCIES_2 = celt/x86/x86cpu.lo celt/x86/x86_celt_map.lo \ celt/x86/pitch_sse.lo @HAVE_SSE_TRUE@am__DEPENDENCIES_3 = $(am__DEPENDENCIES_2) am__DEPENDENCIES_4 = celt/x86/pitch_sse2.lo celt/x86/vq_sse2.lo @HAVE_SSE2_TRUE@am__DEPENDENCIES_5 = $(am__DEPENDENCIES_4) am__DEPENDENCIES_6 = celt/x86/celt_lpc_sse4_1.lo \ celt/x86/pitch_sse4_1.lo @HAVE_SSE4_1_TRUE@am__DEPENDENCIES_7 = $(am__DEPENDENCIES_6) am__DEPENDENCIES_8 = celt/arm/armcpu.lo celt/arm/arm_celt_map.lo @CPU_ARM_TRUE@am__DEPENDENCIES_9 = $(am__DEPENDENCIES_8) am__DEPENDENCIES_10 = celt/arm/celt_neon_intr.lo \ celt/arm/pitch_neon_intr.lo @CPU_ARM_TRUE@@HAVE_ARM_NEON_INTR_TRUE@am__DEPENDENCIES_11 = \ @CPU_ARM_TRUE@@HAVE_ARM_NEON_INTR_TRUE@ $(am__DEPENDENCIES_10) am__DEPENDENCIES_12 = celt/arm/celt_fft_ne10.lo \ celt/arm/celt_mdct_ne10.lo @CPU_ARM_TRUE@@HAVE_ARM_NE10_TRUE@am__DEPENDENCIES_13 = \ @CPU_ARM_TRUE@@HAVE_ARM_NE10_TRUE@ $(am__DEPENDENCIES_12) am__DEPENDENCIES_14 = celt/bands.lo celt/celt.lo celt/celt_encoder.lo \ celt/celt_decoder.lo celt/cwrs.lo celt/entcode.lo \ celt/entdec.lo celt/entenc.lo celt/kiss_fft.lo celt/laplace.lo \ celt/mathops.lo celt/mdct.lo celt/modes.lo celt/pitch.lo \ celt/celt_lpc.lo celt/quant_bands.lo celt/rate.lo celt/vq.lo \ $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_5) \ $(am__DEPENDENCIES_7) $(am__DEPENDENCIES_9) \ $(am__DEPENDENCIES_11) $(am__DEPENDENCIES_13) @EXTRA_PROGRAMS_TRUE@am__DEPENDENCIES_15 = $(am__DEPENDENCIES_14) @EXTRA_PROGRAMS_TRUE@celt_tests_test_unit_dft_DEPENDENCIES = \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_15) \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_1) \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_1) $(am__append_18) am__celt_tests_test_unit_entropy_SOURCES_DIST = \ celt/tests/test_unit_entropy.c @EXTRA_PROGRAMS_TRUE@am_celt_tests_test_unit_entropy_OBJECTS = \ @EXTRA_PROGRAMS_TRUE@ celt/tests/test_unit_entropy.$(OBJEXT) celt_tests_test_unit_entropy_OBJECTS = \ $(am_celt_tests_test_unit_entropy_OBJECTS) @EXTRA_PROGRAMS_TRUE@celt_tests_test_unit_entropy_DEPENDENCIES = \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_1) am__celt_tests_test_unit_laplace_SOURCES_DIST = \ celt/tests/test_unit_laplace.c @EXTRA_PROGRAMS_TRUE@am_celt_tests_test_unit_laplace_OBJECTS = \ @EXTRA_PROGRAMS_TRUE@ celt/tests/test_unit_laplace.$(OBJEXT) celt_tests_test_unit_laplace_OBJECTS = \ $(am_celt_tests_test_unit_laplace_OBJECTS) @EXTRA_PROGRAMS_TRUE@celt_tests_test_unit_laplace_DEPENDENCIES = \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_1) am__celt_tests_test_unit_mathops_SOURCES_DIST = \ celt/tests/test_unit_mathops.c @EXTRA_PROGRAMS_TRUE@am_celt_tests_test_unit_mathops_OBJECTS = \ @EXTRA_PROGRAMS_TRUE@ celt/tests/test_unit_mathops.$(OBJEXT) celt_tests_test_unit_mathops_OBJECTS = \ $(am_celt_tests_test_unit_mathops_OBJECTS) @EXTRA_PROGRAMS_TRUE@celt_tests_test_unit_mathops_DEPENDENCIES = \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_15) \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_1) \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_1) $(am__append_19) am__celt_tests_test_unit_mdct_SOURCES_DIST = \ celt/tests/test_unit_mdct.c @EXTRA_PROGRAMS_TRUE@am_celt_tests_test_unit_mdct_OBJECTS = \ @EXTRA_PROGRAMS_TRUE@ celt/tests/test_unit_mdct.$(OBJEXT) celt_tests_test_unit_mdct_OBJECTS = \ $(am_celt_tests_test_unit_mdct_OBJECTS) @EXTRA_PROGRAMS_TRUE@celt_tests_test_unit_mdct_DEPENDENCIES = \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_15) \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_1) \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_1) $(am__append_20) am__celt_tests_test_unit_rotation_SOURCES_DIST = \ celt/tests/test_unit_rotation.c @EXTRA_PROGRAMS_TRUE@am_celt_tests_test_unit_rotation_OBJECTS = \ @EXTRA_PROGRAMS_TRUE@ celt/tests/test_unit_rotation.$(OBJEXT) celt_tests_test_unit_rotation_OBJECTS = \ $(am_celt_tests_test_unit_rotation_OBJECTS) @EXTRA_PROGRAMS_TRUE@celt_tests_test_unit_rotation_DEPENDENCIES = \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_15) \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_1) \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_1) $(am__append_21) am__celt_tests_test_unit_types_SOURCES_DIST = \ celt/tests/test_unit_types.c @EXTRA_PROGRAMS_TRUE@am_celt_tests_test_unit_types_OBJECTS = \ @EXTRA_PROGRAMS_TRUE@ celt/tests/test_unit_types.$(OBJEXT) celt_tests_test_unit_types_OBJECTS = \ $(am_celt_tests_test_unit_types_OBJECTS) @EXTRA_PROGRAMS_TRUE@celt_tests_test_unit_types_DEPENDENCIES = \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_1) am__opus_compare_SOURCES_DIST = src/opus_compare.c @EXTRA_PROGRAMS_TRUE@am_opus_compare_OBJECTS = \ @EXTRA_PROGRAMS_TRUE@ src/opus_compare.$(OBJEXT) opus_compare_OBJECTS = $(am_opus_compare_OBJECTS) @EXTRA_PROGRAMS_TRUE@opus_compare_DEPENDENCIES = \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_1) am__opus_custom_demo_SOURCES_DIST = celt/opus_custom_demo.c @CUSTOM_MODES_TRUE@@EXTRA_PROGRAMS_TRUE@am_opus_custom_demo_OBJECTS = celt/opus_custom_demo.$(OBJEXT) opus_custom_demo_OBJECTS = $(am_opus_custom_demo_OBJECTS) @CUSTOM_MODES_TRUE@@EXTRA_PROGRAMS_TRUE@opus_custom_demo_DEPENDENCIES = \ @CUSTOM_MODES_TRUE@@EXTRA_PROGRAMS_TRUE@ libopus.la \ @CUSTOM_MODES_TRUE@@EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_1) am__opus_demo_SOURCES_DIST = src/opus_demo.c @EXTRA_PROGRAMS_TRUE@am_opus_demo_OBJECTS = src/opus_demo.$(OBJEXT) opus_demo_OBJECTS = $(am_opus_demo_OBJECTS) @EXTRA_PROGRAMS_TRUE@opus_demo_DEPENDENCIES = libopus.la \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_1) \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_1) am__repacketizer_demo_SOURCES_DIST = src/repacketizer_demo.c @EXTRA_PROGRAMS_TRUE@am_repacketizer_demo_OBJECTS = \ @EXTRA_PROGRAMS_TRUE@ src/repacketizer_demo.$(OBJEXT) repacketizer_demo_OBJECTS = $(am_repacketizer_demo_OBJECTS) @EXTRA_PROGRAMS_TRUE@repacketizer_demo_DEPENDENCIES = libopus.la \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_1) \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_1) am__silk_tests_test_unit_LPC_inv_pred_gain_SOURCES_DIST = \ silk/tests/test_unit_LPC_inv_pred_gain.c @EXTRA_PROGRAMS_TRUE@am_silk_tests_test_unit_LPC_inv_pred_gain_OBJECTS = silk/tests/test_unit_LPC_inv_pred_gain.$(OBJEXT) silk_tests_test_unit_LPC_inv_pred_gain_OBJECTS = \ $(am_silk_tests_test_unit_LPC_inv_pred_gain_OBJECTS) am__DEPENDENCIES_16 = silk/fixed/LTP_analysis_filter_FIX.lo \ silk/fixed/LTP_scale_ctrl_FIX.lo silk/fixed/corrMatrix_FIX.lo \ silk/fixed/encode_frame_FIX.lo silk/fixed/find_LPC_FIX.lo \ silk/fixed/find_LTP_FIX.lo silk/fixed/find_pitch_lags_FIX.lo \ silk/fixed/find_pred_coefs_FIX.lo \ silk/fixed/noise_shape_analysis_FIX.lo \ silk/fixed/process_gains_FIX.lo \ silk/fixed/regularize_correlations_FIX.lo \ silk/fixed/residual_energy16_FIX.lo \ silk/fixed/residual_energy_FIX.lo \ silk/fixed/warped_autocorrelation_FIX.lo \ silk/fixed/apply_sine_window_FIX.lo silk/fixed/autocorr_FIX.lo \ silk/fixed/burg_modified_FIX.lo silk/fixed/k2a_FIX.lo \ silk/fixed/k2a_Q16_FIX.lo \ silk/fixed/pitch_analysis_core_FIX.lo \ silk/fixed/vector_ops_FIX.lo silk/fixed/schur64_FIX.lo \ silk/fixed/schur_FIX.lo @FIXED_POINT_TRUE@am__DEPENDENCIES_17 = $(am__DEPENDENCIES_16) am__DEPENDENCIES_18 = silk/x86/NSQ_sse4_1.lo \ silk/x86/NSQ_del_dec_sse4_1.lo silk/x86/x86_silk_map.lo \ silk/x86/VAD_sse4_1.lo silk/x86/VQ_WMat_EC_sse4_1.lo am__DEPENDENCIES_19 = silk/fixed/x86/vector_ops_FIX_sse4_1.lo \ silk/fixed/x86/burg_modified_FIX_sse4_1.lo @FIXED_POINT_TRUE@@HAVE_SSE4_1_TRUE@am__DEPENDENCIES_20 = \ @FIXED_POINT_TRUE@@HAVE_SSE4_1_TRUE@ $(am__DEPENDENCIES_18) \ @FIXED_POINT_TRUE@@HAVE_SSE4_1_TRUE@ $(am__DEPENDENCIES_19) am__DEPENDENCIES_21 = \ silk/fixed/arm/warped_autocorrelation_FIX_neon_intr.lo @FIXED_POINT_TRUE@@HAVE_ARM_NEON_INTR_TRUE@am__DEPENDENCIES_22 = $(am__DEPENDENCIES_21) am__DEPENDENCIES_23 = silk/float/apply_sine_window_FLP.lo \ silk/float/corrMatrix_FLP.lo silk/float/encode_frame_FLP.lo \ silk/float/find_LPC_FLP.lo silk/float/find_LTP_FLP.lo \ silk/float/find_pitch_lags_FLP.lo \ silk/float/find_pred_coefs_FLP.lo \ silk/float/LPC_analysis_filter_FLP.lo \ silk/float/LTP_analysis_filter_FLP.lo \ silk/float/LTP_scale_ctrl_FLP.lo \ silk/float/noise_shape_analysis_FLP.lo \ silk/float/process_gains_FLP.lo \ silk/float/regularize_correlations_FLP.lo \ silk/float/residual_energy_FLP.lo \ silk/float/warped_autocorrelation_FLP.lo \ silk/float/wrappers_FLP.lo silk/float/autocorrelation_FLP.lo \ silk/float/burg_modified_FLP.lo silk/float/bwexpander_FLP.lo \ silk/float/energy_FLP.lo silk/float/inner_product_FLP.lo \ silk/float/k2a_FLP.lo silk/float/LPC_inv_pred_gain_FLP.lo \ silk/float/pitch_analysis_core_FLP.lo \ silk/float/scale_copy_vector_FLP.lo \ silk/float/scale_vector_FLP.lo silk/float/schur_FLP.lo \ silk/float/sort_FLP.lo @FIXED_POINT_FALSE@am__DEPENDENCIES_24 = $(am__DEPENDENCIES_23) @FIXED_POINT_FALSE@@HAVE_SSE4_1_TRUE@am__DEPENDENCIES_25 = \ @FIXED_POINT_FALSE@@HAVE_SSE4_1_TRUE@ $(am__DEPENDENCIES_18) am__DEPENDENCIES_26 = silk/arm/arm_silk_map.lo \ silk/arm/biquad_alt_neon_intr.lo \ silk/arm/LPC_inv_pred_gain_neon_intr.lo \ silk/arm/NSQ_del_dec_neon_intr.lo silk/arm/NSQ_neon.lo @CPU_ARM_TRUE@@HAVE_ARM_NEON_INTR_TRUE@am__DEPENDENCIES_27 = \ @CPU_ARM_TRUE@@HAVE_ARM_NEON_INTR_TRUE@ $(am__DEPENDENCIES_26) am__DEPENDENCIES_28 = silk/CNG.lo silk/code_signs.lo \ silk/init_decoder.lo silk/decode_core.lo silk/decode_frame.lo \ silk/decode_parameters.lo silk/decode_indices.lo \ silk/decode_pulses.lo silk/decoder_set_fs.lo silk/dec_API.lo \ silk/enc_API.lo silk/encode_indices.lo silk/encode_pulses.lo \ silk/gain_quant.lo silk/interpolate.lo \ silk/LP_variable_cutoff.lo silk/NLSF_decode.lo silk/NSQ.lo \ silk/NSQ_del_dec.lo silk/PLC.lo silk/shell_coder.lo \ silk/tables_gain.lo silk/tables_LTP.lo \ silk/tables_NLSF_CB_NB_MB.lo silk/tables_NLSF_CB_WB.lo \ silk/tables_other.lo silk/tables_pitch_lag.lo \ silk/tables_pulses_per_block.lo silk/VAD.lo \ silk/control_audio_bandwidth.lo silk/quant_LTP_gains.lo \ silk/VQ_WMat_EC.lo silk/HP_variable_cutoff.lo \ silk/NLSF_encode.lo silk/NLSF_VQ.lo silk/NLSF_unpack.lo \ silk/NLSF_del_dec_quant.lo silk/process_NLSFs.lo \ silk/stereo_LR_to_MS.lo silk/stereo_MS_to_LR.lo \ silk/check_control_input.lo silk/control_SNR.lo \ silk/init_encoder.lo silk/control_codec.lo silk/A2NLSF.lo \ silk/ana_filt_bank_1.lo silk/biquad_alt.lo \ silk/bwexpander_32.lo silk/bwexpander.lo silk/debug.lo \ silk/decode_pitch.lo silk/inner_prod_aligned.lo \ silk/lin2log.lo silk/log2lin.lo silk/LPC_analysis_filter.lo \ silk/LPC_inv_pred_gain.lo silk/table_LSF_cos.lo silk/NLSF2A.lo \ silk/NLSF_stabilize.lo silk/NLSF_VQ_weights_laroia.lo \ silk/pitch_est_tables.lo silk/resampler.lo \ silk/resampler_down2_3.lo silk/resampler_down2.lo \ silk/resampler_private_AR2.lo \ silk/resampler_private_down_FIR.lo \ silk/resampler_private_IIR_FIR.lo \ silk/resampler_private_up2_HQ.lo silk/resampler_rom.lo \ silk/sigm_Q15.lo silk/sort.lo silk/sum_sqr_shift.lo \ silk/stereo_decode_pred.lo silk/stereo_encode_pred.lo \ silk/stereo_find_predictor.lo silk/stereo_quant_pred.lo \ silk/LPC_fit.lo $(am__DEPENDENCIES_17) $(am__DEPENDENCIES_20) \ $(am__DEPENDENCIES_22) $(am__DEPENDENCIES_24) \ $(am__DEPENDENCIES_25) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_27) @EXTRA_PROGRAMS_TRUE@am__DEPENDENCIES_29 = $(am__DEPENDENCIES_28) @EXTRA_PROGRAMS_TRUE@silk_tests_test_unit_LPC_inv_pred_gain_DEPENDENCIES = \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_29) \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_15) \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_1) \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_1) $(am__append_17) am__tests_test_opus_api_SOURCES_DIST = tests/test_opus_api.c \ tests/test_opus_common.h @EXTRA_PROGRAMS_TRUE@am_tests_test_opus_api_OBJECTS = \ @EXTRA_PROGRAMS_TRUE@ tests/test_opus_api.$(OBJEXT) tests_test_opus_api_OBJECTS = $(am_tests_test_opus_api_OBJECTS) @EXTRA_PROGRAMS_TRUE@tests_test_opus_api_DEPENDENCIES = libopus.la \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_1) \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_1) am__tests_test_opus_decode_SOURCES_DIST = tests/test_opus_decode.c \ tests/test_opus_common.h @EXTRA_PROGRAMS_TRUE@am_tests_test_opus_decode_OBJECTS = \ @EXTRA_PROGRAMS_TRUE@ tests/test_opus_decode.$(OBJEXT) tests_test_opus_decode_OBJECTS = $(am_tests_test_opus_decode_OBJECTS) @EXTRA_PROGRAMS_TRUE@tests_test_opus_decode_DEPENDENCIES = libopus.la \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_1) \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_1) am__tests_test_opus_encode_SOURCES_DIST = tests/test_opus_encode.c \ tests/opus_encode_regressions.c tests/test_opus_common.h @EXTRA_PROGRAMS_TRUE@am_tests_test_opus_encode_OBJECTS = \ @EXTRA_PROGRAMS_TRUE@ tests/test_opus_encode.$(OBJEXT) \ @EXTRA_PROGRAMS_TRUE@ tests/opus_encode_regressions.$(OBJEXT) tests_test_opus_encode_OBJECTS = $(am_tests_test_opus_encode_OBJECTS) @EXTRA_PROGRAMS_TRUE@tests_test_opus_encode_DEPENDENCIES = libopus.la \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_1) \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_1) am__tests_test_opus_padding_SOURCES_DIST = tests/test_opus_padding.c \ tests/test_opus_common.h @EXTRA_PROGRAMS_TRUE@am_tests_test_opus_padding_OBJECTS = \ @EXTRA_PROGRAMS_TRUE@ tests/test_opus_padding.$(OBJEXT) tests_test_opus_padding_OBJECTS = \ $(am_tests_test_opus_padding_OBJECTS) @EXTRA_PROGRAMS_TRUE@tests_test_opus_padding_DEPENDENCIES = \ @EXTRA_PROGRAMS_TRUE@ libopus.la $(am__DEPENDENCIES_1) \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_1) am__tests_test_opus_projection_SOURCES_DIST = \ tests/test_opus_projection.c tests/test_opus_common.h @EXTRA_PROGRAMS_TRUE@am_tests_test_opus_projection_OBJECTS = \ @EXTRA_PROGRAMS_TRUE@ tests/test_opus_projection.$(OBJEXT) tests_test_opus_projection_OBJECTS = \ $(am_tests_test_opus_projection_OBJECTS) am__DEPENDENCIES_30 = src/analysis.lo src/mlp.lo src/mlp_data.lo @DISABLE_FLOAT_API_FALSE@am__DEPENDENCIES_31 = $(am__DEPENDENCIES_30) am__DEPENDENCIES_32 = src/opus.lo src/opus_decoder.lo \ src/opus_encoder.lo src/opus_multistream.lo \ src/opus_multistream_encoder.lo \ src/opus_multistream_decoder.lo src/repacketizer.lo \ src/opus_projection_encoder.lo src/opus_projection_decoder.lo \ src/mapping_matrix.lo $(am__DEPENDENCIES_31) @EXTRA_PROGRAMS_TRUE@am__DEPENDENCIES_33 = $(am__DEPENDENCIES_32) @EXTRA_PROGRAMS_TRUE@tests_test_opus_projection_DEPENDENCIES = \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_33) \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_29) \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_15) \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_1) \ @EXTRA_PROGRAMS_TRUE@ $(am__DEPENDENCIES_1) $(am__append_16) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CPPASCOMPILE = $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) LTCPPASCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CCASFLAGS) $(CCASFLAGS) AM_V_CPPAS = $(am__v_CPPAS_@AM_V@) am__v_CPPAS_ = $(am__v_CPPAS_@AM_DEFAULT_V@) am__v_CPPAS_0 = @echo " CPPAS " $@; am__v_CPPAS_1 = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libarmasm_la_SOURCES) $(libopus_la_SOURCES) \ $(celt_tests_test_unit_cwrs32_SOURCES) \ $(celt_tests_test_unit_dft_SOURCES) \ $(celt_tests_test_unit_entropy_SOURCES) \ $(celt_tests_test_unit_laplace_SOURCES) \ $(celt_tests_test_unit_mathops_SOURCES) \ $(celt_tests_test_unit_mdct_SOURCES) \ $(celt_tests_test_unit_rotation_SOURCES) \ $(celt_tests_test_unit_types_SOURCES) $(opus_compare_SOURCES) \ $(opus_custom_demo_SOURCES) $(opus_demo_SOURCES) \ $(repacketizer_demo_SOURCES) \ $(silk_tests_test_unit_LPC_inv_pred_gain_SOURCES) \ $(tests_test_opus_api_SOURCES) \ $(tests_test_opus_decode_SOURCES) \ $(tests_test_opus_encode_SOURCES) \ $(tests_test_opus_padding_SOURCES) \ $(tests_test_opus_projection_SOURCES) DIST_SOURCES = $(am__libarmasm_la_SOURCES_DIST) \ $(am__libopus_la_SOURCES_DIST) \ $(am__celt_tests_test_unit_cwrs32_SOURCES_DIST) \ $(am__celt_tests_test_unit_dft_SOURCES_DIST) \ $(am__celt_tests_test_unit_entropy_SOURCES_DIST) \ $(am__celt_tests_test_unit_laplace_SOURCES_DIST) \ $(am__celt_tests_test_unit_mathops_SOURCES_DIST) \ $(am__celt_tests_test_unit_mdct_SOURCES_DIST) \ $(am__celt_tests_test_unit_rotation_SOURCES_DIST) \ $(am__celt_tests_test_unit_types_SOURCES_DIST) \ $(am__opus_compare_SOURCES_DIST) \ $(am__opus_custom_demo_SOURCES_DIST) \ $(am__opus_demo_SOURCES_DIST) \ $(am__repacketizer_demo_SOURCES_DIST) \ $(am__silk_tests_test_unit_LPC_inv_pred_gain_SOURCES_DIST) \ $(am__tests_test_opus_api_SOURCES_DIST) \ $(am__tests_test_opus_decode_SOURCES_DIST) \ $(am__tests_test_opus_encode_SOURCES_DIST) \ $(am__tests_test_opus_padding_SOURCES_DIST) \ $(am__tests_test_opus_projection_SOURCES_DIST) RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac DATA = $(m4data_DATA) $(pkgconfig_DATA) am__pkginclude_HEADERS_DIST = include/opus.h \ include/opus_multistream.h include/opus_types.h \ include/opus_defines.h include/opus_projection.h \ include/opus_custom.h HEADERS = $(noinst_HEADERS) $(pkginclude_HEADERS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ cscope check recheck distdir dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ $(LISP)config.h.in # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags CSCOPE = cscope am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` RECHECK_LOGS = $(TEST_LOGS) TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/celt_headers.mk \ $(srcdir)/celt_sources.mk $(srcdir)/config.h.in \ $(srcdir)/opus-uninstalled.pc.in $(srcdir)/opus.pc.in \ $(srcdir)/opus_headers.mk $(srcdir)/opus_sources.mk \ $(srcdir)/silk_headers.mk $(srcdir)/silk_sources.mk \ $(top_srcdir)/celt/arm/armopts.s.in AUTHORS COPYING ChangeLog \ INSTALL NEWS README compile config.guess config.sub depcomp \ install-sh ltmain.sh missing test-driver DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ ARM2GNU_PARAMS = @ARM2GNU_PARAMS@ ARM_NEON_INTR_CFLAGS = @ARM_NEON_INTR_CFLAGS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCAS = @CCAS@ CCASDEPMODE = @CCASDEPMODE@ CCASFLAGS = @CCASFLAGS@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_ARM_NE10 = @HAVE_ARM_NE10@ HAVE_DOT = @HAVE_DOT@ HAVE_DOXYGEN = @HAVE_DOXYGEN@ HAVE_PERL = @HAVE_PERL@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBM = @LIBM@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NE10_CFLAGS = @NE10_CFLAGS@ NE10_LIBS = @NE10_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPUS_ARM_MAY_HAVE_EDSP = @OPUS_ARM_MAY_HAVE_EDSP@ OPUS_ARM_MAY_HAVE_MEDIA = @OPUS_ARM_MAY_HAVE_MEDIA@ OPUS_ARM_MAY_HAVE_NEON = @OPUS_ARM_MAY_HAVE_NEON@ OPUS_ARM_NEON_INTR_CFLAGS = @OPUS_ARM_NEON_INTR_CFLAGS@ OPUS_HAVE_RTCD = @OPUS_HAVE_RTCD@ OPUS_LT_AGE = @OPUS_LT_AGE@ OPUS_LT_CURRENT = @OPUS_LT_CURRENT@ OPUS_LT_REVISION = @OPUS_LT_REVISION@ OPUS_X86_AVX_CFLAGS = @OPUS_X86_AVX_CFLAGS@ OPUS_X86_SSE2_CFLAGS = @OPUS_X86_SSE2_CFLAGS@ OPUS_X86_SSE4_1_CFLAGS = @OPUS_X86_SSE4_1_CFLAGS@ OPUS_X86_SSE_CFLAGS = @OPUS_X86_SSE_CFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PC_BUILD = @PC_BUILD@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ X86_AVX_CFLAGS = @X86_AVX_CFLAGS@ X86_SSE2_CFLAGS = @X86_SSE2_CFLAGS@ X86_SSE4_1_CFLAGS = @X86_SSE4_1_CFLAGS@ X86_SSE_CFLAGS = @X86_SSE_CFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = subdir-objects ACLOCAL_AMFLAGS = -I m4 lib_LTLIBRARIES = libopus.la DIST_SUBDIRS = doc AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/celt -I$(top_srcdir)/silk \ -I$(top_srcdir)/silk/float -I$(top_srcdir)/silk/fixed $(NE10_CFLAGS) CELT_SOURCES = celt/bands.c celt/celt.c celt/celt_encoder.c \ celt/celt_decoder.c celt/cwrs.c celt/entcode.c celt/entdec.c \ celt/entenc.c celt/kiss_fft.c celt/laplace.c celt/mathops.c \ celt/mdct.c celt/modes.c celt/pitch.c celt/celt_lpc.c \ celt/quant_bands.c celt/rate.c celt/vq.c $(am__append_7) \ $(am__append_8) $(am__append_9) $(am__append_10) \ $(am__append_12) $(am__append_14) CELT_SOURCES_SSE = \ celt/x86/x86cpu.c \ celt/x86/x86_celt_map.c \ celt/x86/pitch_sse.c CELT_SOURCES_SSE2 = \ celt/x86/pitch_sse2.c \ celt/x86/vq_sse2.c CELT_SOURCES_SSE4_1 = \ celt/x86/celt_lpc_sse4_1.c \ celt/x86/pitch_sse4_1.c CELT_SOURCES_ARM = \ celt/arm/armcpu.c \ celt/arm/arm_celt_map.c CELT_SOURCES_ARM_ASM = \ celt/arm/celt_pitch_xcorr_arm.s CELT_AM_SOURCES_ARM_ASM = \ celt/arm/armopts.s.in CELT_SOURCES_ARM_NEON_INTR = \ celt/arm/celt_neon_intr.c \ celt/arm/pitch_neon_intr.c CELT_SOURCES_ARM_NE10 = \ celt/arm/celt_fft_ne10.c \ celt/arm/celt_mdct_ne10.c SILK_SOURCES = silk/CNG.c silk/code_signs.c silk/init_decoder.c \ silk/decode_core.c silk/decode_frame.c \ silk/decode_parameters.c silk/decode_indices.c \ silk/decode_pulses.c silk/decoder_set_fs.c silk/dec_API.c \ silk/enc_API.c silk/encode_indices.c silk/encode_pulses.c \ silk/gain_quant.c silk/interpolate.c silk/LP_variable_cutoff.c \ silk/NLSF_decode.c silk/NSQ.c silk/NSQ_del_dec.c silk/PLC.c \ silk/shell_coder.c silk/tables_gain.c silk/tables_LTP.c \ silk/tables_NLSF_CB_NB_MB.c silk/tables_NLSF_CB_WB.c \ silk/tables_other.c silk/tables_pitch_lag.c \ silk/tables_pulses_per_block.c silk/VAD.c \ silk/control_audio_bandwidth.c silk/quant_LTP_gains.c \ silk/VQ_WMat_EC.c silk/HP_variable_cutoff.c silk/NLSF_encode.c \ silk/NLSF_VQ.c silk/NLSF_unpack.c silk/NLSF_del_dec_quant.c \ silk/process_NLSFs.c silk/stereo_LR_to_MS.c \ silk/stereo_MS_to_LR.c silk/check_control_input.c \ silk/control_SNR.c silk/init_encoder.c silk/control_codec.c \ silk/A2NLSF.c silk/ana_filt_bank_1.c silk/biquad_alt.c \ silk/bwexpander_32.c silk/bwexpander.c silk/debug.c \ silk/decode_pitch.c silk/inner_prod_aligned.c silk/lin2log.c \ silk/log2lin.c silk/LPC_analysis_filter.c \ silk/LPC_inv_pred_gain.c silk/table_LSF_cos.c silk/NLSF2A.c \ silk/NLSF_stabilize.c silk/NLSF_VQ_weights_laroia.c \ silk/pitch_est_tables.c silk/resampler.c \ silk/resampler_down2_3.c silk/resampler_down2.c \ silk/resampler_private_AR2.c silk/resampler_private_down_FIR.c \ silk/resampler_private_IIR_FIR.c \ silk/resampler_private_up2_HQ.c silk/resampler_rom.c \ silk/sigm_Q15.c silk/sort.c silk/sum_sqr_shift.c \ silk/stereo_decode_pred.c silk/stereo_encode_pred.c \ silk/stereo_find_predictor.c silk/stereo_quant_pred.c \ silk/LPC_fit.c $(am__append_1) $(am__append_2) $(am__append_3) \ $(am__append_4) $(am__append_5) $(am__append_11) \ $(am__append_13) SILK_SOURCES_SSE4_1 = \ silk/x86/NSQ_sse4_1.c \ silk/x86/NSQ_del_dec_sse4_1.c \ silk/x86/x86_silk_map.c \ silk/x86/VAD_sse4_1.c \ silk/x86/VQ_WMat_EC_sse4_1.c SILK_SOURCES_ARM_NEON_INTR = \ silk/arm/arm_silk_map.c \ silk/arm/biquad_alt_neon_intr.c \ silk/arm/LPC_inv_pred_gain_neon_intr.c \ silk/arm/NSQ_del_dec_neon_intr.c \ silk/arm/NSQ_neon.c SILK_SOURCES_FIXED = \ silk/fixed/LTP_analysis_filter_FIX.c \ silk/fixed/LTP_scale_ctrl_FIX.c \ silk/fixed/corrMatrix_FIX.c \ silk/fixed/encode_frame_FIX.c \ silk/fixed/find_LPC_FIX.c \ silk/fixed/find_LTP_FIX.c \ silk/fixed/find_pitch_lags_FIX.c \ silk/fixed/find_pred_coefs_FIX.c \ silk/fixed/noise_shape_analysis_FIX.c \ silk/fixed/process_gains_FIX.c \ silk/fixed/regularize_correlations_FIX.c \ silk/fixed/residual_energy16_FIX.c \ silk/fixed/residual_energy_FIX.c \ silk/fixed/warped_autocorrelation_FIX.c \ silk/fixed/apply_sine_window_FIX.c \ silk/fixed/autocorr_FIX.c \ silk/fixed/burg_modified_FIX.c \ silk/fixed/k2a_FIX.c \ silk/fixed/k2a_Q16_FIX.c \ silk/fixed/pitch_analysis_core_FIX.c \ silk/fixed/vector_ops_FIX.c \ silk/fixed/schur64_FIX.c \ silk/fixed/schur_FIX.c SILK_SOURCES_FIXED_SSE4_1 = \ silk/fixed/x86/vector_ops_FIX_sse4_1.c \ silk/fixed/x86/burg_modified_FIX_sse4_1.c SILK_SOURCES_FIXED_ARM_NEON_INTR = \ silk/fixed/arm/warped_autocorrelation_FIX_neon_intr.c SILK_SOURCES_FLOAT = \ silk/float/apply_sine_window_FLP.c \ silk/float/corrMatrix_FLP.c \ silk/float/encode_frame_FLP.c \ silk/float/find_LPC_FLP.c \ silk/float/find_LTP_FLP.c \ silk/float/find_pitch_lags_FLP.c \ silk/float/find_pred_coefs_FLP.c \ silk/float/LPC_analysis_filter_FLP.c \ silk/float/LTP_analysis_filter_FLP.c \ silk/float/LTP_scale_ctrl_FLP.c \ silk/float/noise_shape_analysis_FLP.c \ silk/float/process_gains_FLP.c \ silk/float/regularize_correlations_FLP.c \ silk/float/residual_energy_FLP.c \ silk/float/warped_autocorrelation_FLP.c \ silk/float/wrappers_FLP.c \ silk/float/autocorrelation_FLP.c \ silk/float/burg_modified_FLP.c \ silk/float/bwexpander_FLP.c \ silk/float/energy_FLP.c \ silk/float/inner_product_FLP.c \ silk/float/k2a_FLP.c \ silk/float/LPC_inv_pred_gain_FLP.c \ silk/float/pitch_analysis_core_FLP.c \ silk/float/scale_copy_vector_FLP.c \ silk/float/scale_vector_FLP.c \ silk/float/schur_FLP.c \ silk/float/sort_FLP.c OPUS_SOURCES = src/opus.c src/opus_decoder.c src/opus_encoder.c \ src/opus_multistream.c src/opus_multistream_encoder.c \ src/opus_multistream_decoder.c src/repacketizer.c \ src/opus_projection_encoder.c src/opus_projection_decoder.c \ src/mapping_matrix.c $(am__append_6) OPUS_SOURCES_FLOAT = \ src/analysis.c \ src/mlp.c \ src/mlp_data.c @CPU_ARM_TRUE@@OPUS_ARM_EXTERNAL_ASM_TRUE@noinst_LTLIBRARIES = libarmasm.la @CPU_ARM_TRUE@@OPUS_ARM_EXTERNAL_ASM_TRUE@libarmasm_la_SOURCES = $(CELT_SOURCES_ARM_ASM:.s=-gnu.S) @CPU_ARM_TRUE@@OPUS_ARM_EXTERNAL_ASM_TRUE@BUILT_SOURCES = $(CELT_SOURCES_ARM_ASM:.s=-gnu.S) \ @CPU_ARM_TRUE@@OPUS_ARM_EXTERNAL_ASM_TRUE@ $(CELT_AM_SOURCES_ARM_ASM:.s.in=.s) \ @CPU_ARM_TRUE@@OPUS_ARM_EXTERNAL_ASM_TRUE@ $(CELT_AM_SOURCES_ARM_ASM:.s.in=-gnu.S) CLEANFILES = $(CELT_SOURCES_ARM_ASM:.s=-gnu.S) \ $(CELT_AM_SOURCES_ARM_ASM:.s.in=-gnu.S) CELT_HEAD = \ celt/arch.h \ celt/bands.h \ celt/celt.h \ celt/cpu_support.h \ include/opus_types.h \ include/opus_defines.h \ include/opus_custom.h \ celt/cwrs.h \ celt/ecintrin.h \ celt/entcode.h \ celt/entdec.h \ celt/entenc.h \ celt/fixed_debug.h \ celt/fixed_generic.h \ celt/float_cast.h \ celt/_kiss_fft_guts.h \ celt/kiss_fft.h \ celt/laplace.h \ celt/mathops.h \ celt/mdct.h \ celt/mfrngcod.h \ celt/modes.h \ celt/os_support.h \ celt/pitch.h \ celt/celt_lpc.h \ celt/x86/celt_lpc_sse.h \ celt/quant_bands.h \ celt/rate.h \ celt/stack_alloc.h \ celt/vq.h \ celt/static_modes_float.h \ celt/static_modes_fixed.h \ celt/static_modes_float_arm_ne10.h \ celt/static_modes_fixed_arm_ne10.h \ celt/arm/armcpu.h \ celt/arm/fixed_armv4.h \ celt/arm/fixed_armv5e.h \ celt/arm/fixed_arm64.h \ celt/arm/kiss_fft_armv4.h \ celt/arm/kiss_fft_armv5e.h \ celt/arm/pitch_arm.h \ celt/arm/fft_arm.h \ celt/arm/mdct_arm.h \ celt/mips/celt_mipsr1.h \ celt/mips/fixed_generic_mipsr1.h \ celt/mips/kiss_fft_mipsr1.h \ celt/mips/mdct_mipsr1.h \ celt/mips/pitch_mipsr1.h \ celt/mips/vq_mipsr1.h \ celt/x86/pitch_sse.h \ celt/x86/vq_sse.h \ celt/x86/x86cpu.h SILK_HEAD = \ silk/debug.h \ silk/control.h \ silk/errors.h \ silk/API.h \ silk/typedef.h \ silk/define.h \ silk/main.h \ silk/x86/main_sse.h \ silk/PLC.h \ silk/structs.h \ silk/tables.h \ silk/tuning_parameters.h \ silk/Inlines.h \ silk/MacroCount.h \ silk/MacroDebug.h \ silk/macros.h \ silk/NSQ.h \ silk/pitch_est_defines.h \ silk/resampler_private.h \ silk/resampler_rom.h \ silk/resampler_structs.h \ silk/SigProc_FIX.h \ silk/x86/SigProc_FIX_sse.h \ silk/arm/biquad_alt_arm.h \ silk/arm/LPC_inv_pred_gain_arm.h \ silk/arm/macros_armv4.h \ silk/arm/macros_armv5e.h \ silk/arm/macros_arm64.h \ silk/arm/SigProc_FIX_armv4.h \ silk/arm/SigProc_FIX_armv5e.h \ silk/arm/NSQ_del_dec_arm.h \ silk/arm/NSQ_neon.h \ silk/fixed/main_FIX.h \ silk/fixed/structs_FIX.h \ silk/fixed/arm/warped_autocorrelation_FIX_arm.h \ silk/fixed/mips/noise_shape_analysis_FIX_mipsr1.h \ silk/fixed/mips/warped_autocorrelation_FIX_mipsr1.h \ silk/float/main_FLP.h \ silk/float/structs_FLP.h \ silk/float/SigProc_FLP.h \ silk/mips/macros_mipsr1.h \ silk/mips/NSQ_del_dec_mipsr1.h \ silk/mips/sigproc_fix_mipsr1.h OPUS_HEAD = \ include/opus.h \ include/opus_multistream.h \ include/opus_projection.h \ src/opus_private.h \ src/analysis.h \ src/mapping_matrix.h \ src/mlp.h \ src/tansig_table.h libopus_la_SOURCES = $(CELT_SOURCES) $(SILK_SOURCES) $(OPUS_SOURCES) libopus_la_LDFLAGS = -no-undefined -version-info @OPUS_LT_CURRENT@:@OPUS_LT_REVISION@:@OPUS_LT_AGE@ libopus_la_LIBADD = $(NE10_LIBS) $(LIBM) $(am__append_15) pkginclude_HEADERS = include/opus.h include/opus_multistream.h \ include/opus_types.h include/opus_defines.h \ include/opus_projection.h $(am__append_22) noinst_HEADERS = $(OPUS_HEAD) $(SILK_HEAD) $(CELT_HEAD) @EXTRA_PROGRAMS_TRUE@opus_demo_SOURCES = src/opus_demo.c @EXTRA_PROGRAMS_TRUE@opus_demo_LDADD = libopus.la $(NE10_LIBS) $(LIBM) @EXTRA_PROGRAMS_TRUE@repacketizer_demo_SOURCES = src/repacketizer_demo.c @EXTRA_PROGRAMS_TRUE@repacketizer_demo_LDADD = libopus.la $(NE10_LIBS) $(LIBM) @EXTRA_PROGRAMS_TRUE@opus_compare_SOURCES = src/opus_compare.c @EXTRA_PROGRAMS_TRUE@opus_compare_LDADD = $(LIBM) @EXTRA_PROGRAMS_TRUE@tests_test_opus_api_SOURCES = tests/test_opus_api.c tests/test_opus_common.h @EXTRA_PROGRAMS_TRUE@tests_test_opus_api_LDADD = libopus.la $(NE10_LIBS) $(LIBM) @EXTRA_PROGRAMS_TRUE@tests_test_opus_encode_SOURCES = tests/test_opus_encode.c tests/opus_encode_regressions.c tests/test_opus_common.h @EXTRA_PROGRAMS_TRUE@tests_test_opus_encode_LDADD = libopus.la $(NE10_LIBS) $(LIBM) @EXTRA_PROGRAMS_TRUE@tests_test_opus_decode_SOURCES = tests/test_opus_decode.c tests/test_opus_common.h @EXTRA_PROGRAMS_TRUE@tests_test_opus_decode_LDADD = libopus.la $(NE10_LIBS) $(LIBM) @EXTRA_PROGRAMS_TRUE@tests_test_opus_padding_SOURCES = tests/test_opus_padding.c tests/test_opus_common.h @EXTRA_PROGRAMS_TRUE@tests_test_opus_padding_LDADD = libopus.la $(NE10_LIBS) $(LIBM) @EXTRA_PROGRAMS_TRUE@CELT_OBJ = $(CELT_SOURCES:.c=.lo) @EXTRA_PROGRAMS_TRUE@SILK_OBJ = $(SILK_SOURCES:.c=.lo) @EXTRA_PROGRAMS_TRUE@OPUS_OBJ = $(OPUS_SOURCES:.c=.lo) @EXTRA_PROGRAMS_TRUE@tests_test_opus_projection_SOURCES = tests/test_opus_projection.c tests/test_opus_common.h @EXTRA_PROGRAMS_TRUE@tests_test_opus_projection_LDADD = $(OPUS_OBJ) \ @EXTRA_PROGRAMS_TRUE@ $(SILK_OBJ) $(CELT_OBJ) $(NE10_LIBS) \ @EXTRA_PROGRAMS_TRUE@ $(LIBM) $(am__append_16) @EXTRA_PROGRAMS_TRUE@silk_tests_test_unit_LPC_inv_pred_gain_SOURCES = silk/tests/test_unit_LPC_inv_pred_gain.c @EXTRA_PROGRAMS_TRUE@silk_tests_test_unit_LPC_inv_pred_gain_LDADD = \ @EXTRA_PROGRAMS_TRUE@ $(SILK_OBJ) $(CELT_OBJ) $(NE10_LIBS) \ @EXTRA_PROGRAMS_TRUE@ $(LIBM) $(am__append_17) @EXTRA_PROGRAMS_TRUE@celt_tests_test_unit_cwrs32_SOURCES = celt/tests/test_unit_cwrs32.c @EXTRA_PROGRAMS_TRUE@celt_tests_test_unit_cwrs32_LDADD = $(LIBM) @EXTRA_PROGRAMS_TRUE@celt_tests_test_unit_dft_SOURCES = celt/tests/test_unit_dft.c @EXTRA_PROGRAMS_TRUE@celt_tests_test_unit_dft_LDADD = $(CELT_OBJ) \ @EXTRA_PROGRAMS_TRUE@ $(NE10_LIBS) $(LIBM) $(am__append_18) @EXTRA_PROGRAMS_TRUE@celt_tests_test_unit_entropy_SOURCES = celt/tests/test_unit_entropy.c @EXTRA_PROGRAMS_TRUE@celt_tests_test_unit_entropy_LDADD = $(LIBM) @EXTRA_PROGRAMS_TRUE@celt_tests_test_unit_laplace_SOURCES = celt/tests/test_unit_laplace.c @EXTRA_PROGRAMS_TRUE@celt_tests_test_unit_laplace_LDADD = $(LIBM) @EXTRA_PROGRAMS_TRUE@celt_tests_test_unit_mathops_SOURCES = celt/tests/test_unit_mathops.c @EXTRA_PROGRAMS_TRUE@celt_tests_test_unit_mathops_LDADD = $(CELT_OBJ) \ @EXTRA_PROGRAMS_TRUE@ $(NE10_LIBS) $(LIBM) $(am__append_19) @EXTRA_PROGRAMS_TRUE@celt_tests_test_unit_mdct_SOURCES = celt/tests/test_unit_mdct.c @EXTRA_PROGRAMS_TRUE@celt_tests_test_unit_mdct_LDADD = $(CELT_OBJ) \ @EXTRA_PROGRAMS_TRUE@ $(NE10_LIBS) $(LIBM) $(am__append_20) @EXTRA_PROGRAMS_TRUE@celt_tests_test_unit_rotation_SOURCES = celt/tests/test_unit_rotation.c @EXTRA_PROGRAMS_TRUE@celt_tests_test_unit_rotation_LDADD = \ @EXTRA_PROGRAMS_TRUE@ $(CELT_OBJ) $(NE10_LIBS) $(LIBM) \ @EXTRA_PROGRAMS_TRUE@ $(am__append_21) @EXTRA_PROGRAMS_TRUE@celt_tests_test_unit_types_SOURCES = celt/tests/test_unit_types.c @EXTRA_PROGRAMS_TRUE@celt_tests_test_unit_types_LDADD = $(LIBM) @CUSTOM_MODES_TRUE@@EXTRA_PROGRAMS_TRUE@opus_custom_demo_SOURCES = celt/opus_custom_demo.c @CUSTOM_MODES_TRUE@@EXTRA_PROGRAMS_TRUE@opus_custom_demo_LDADD = libopus.la $(LIBM) EXTRA_DIST = opus.pc.in \ opus-uninstalled.pc.in \ opus.m4 \ Makefile.mips \ Makefile.unix \ CMakeLists.txt \ config.h.cmake.in \ opus_config.cmake \ opus_functions.cmake \ opus_sources.cmake \ OpusConfig.cmake.in \ tests/run_vectors.sh \ celt/arm/arm2gnu.pl \ celt/arm/celt_pitch_xcorr_arm.s \ win32/VS2015/opus.vcxproj \ win32/VS2015/test_opus_encode.vcxproj.filters \ win32/VS2015/test_opus_encode.vcxproj \ win32/VS2015/opus_demo.vcxproj \ win32/VS2015/test_opus_api.vcxproj.filters \ win32/VS2015/test_opus_api.vcxproj \ win32/VS2015/test_opus_decode.vcxproj.filters \ win32/VS2015/opus_demo.vcxproj.filters \ win32/VS2015/opus.vcxproj.filters \ win32/VS2015/test_opus_decode.vcxproj \ win32/VS2015/opus.sln \ win32/VS2015/common.props \ win32/genversion.bat \ win32/config.h pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = opus.pc m4datadir = $(datadir)/aclocal m4data_DATA = opus.m4 OPT_UNIT_TEST_OBJ = $(celt_tests_test_unit_mathops_SOURCES:.c=.o) \ $(celt_tests_test_unit_rotation_SOURCES:.c=.o) \ $(celt_tests_test_unit_mdct_SOURCES:.c=.o) \ $(celt_tests_test_unit_dft_SOURCES:.c=.o) \ $(silk_tests_test_unit_LPC_inv_pred_gain_SOURCES:.c=.o) @HAVE_SSE_TRUE@SSE_OBJ = $(CELT_SOURCES_SSE:.c=.lo) @HAVE_SSE2_TRUE@SSE2_OBJ = $(CELT_SOURCES_SSE2:.c=.lo) @HAVE_SSE4_1_TRUE@SSE4_1_OBJ = $(CELT_SOURCES_SSE4_1:.c=.lo) \ @HAVE_SSE4_1_TRUE@ $(SILK_SOURCES_SSE4_1:.c=.lo) \ @HAVE_SSE4_1_TRUE@ $(SILK_SOURCES_FIXED_SSE4_1:.c=.lo) @HAVE_ARM_NEON_INTR_TRUE@ARM_NEON_INTR_OBJ = $(CELT_SOURCES_ARM_NEON_INTR:.c=.lo) \ @HAVE_ARM_NEON_INTR_TRUE@ $(SILK_SOURCES_ARM_NEON_INTR:.c=.lo) \ @HAVE_ARM_NEON_INTR_TRUE@ $(SILK_SOURCES_FIXED_ARM_NEON_INTR:.c=.lo) all: $(BUILT_SOURCES) config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: .SUFFIXES: .S .c .lo .log .o .obj .test .test$(EXEEXT) .trs am--refresh: Makefile @: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/celt_sources.mk $(srcdir)/silk_sources.mk $(srcdir)/opus_sources.mk $(srcdir)/celt_headers.mk $(srcdir)/silk_headers.mk $(srcdir)/opus_headers.mk $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(srcdir)/celt_sources.mk $(srcdir)/silk_sources.mk $(srcdir)/opus_sources.mk $(srcdir)/celt_headers.mk $(srcdir)/silk_headers.mk $(srcdir)/opus_headers.mk $(am__empty): $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): config.h: stamp-h1 @test -f $@ || rm -f stamp-h1 @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 opus.pc: $(top_builddir)/config.status $(srcdir)/opus.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ opus-uninstalled.pc: $(top_builddir)/config.status $(srcdir)/opus-uninstalled.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ celt/arm/armopts.s: $(top_builddir)/config.status $(top_srcdir)/celt/arm/armopts.s.in cd $(top_builddir) && $(SHELL) ./config.status $@ install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } celt/arm/$(am__dirstamp): @$(MKDIR_P) celt/arm @: > celt/arm/$(am__dirstamp) celt/arm/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) celt/arm/$(DEPDIR) @: > celt/arm/$(DEPDIR)/$(am__dirstamp) celt/arm/celt_pitch_xcorr_arm-gnu.lo: celt/arm/$(am__dirstamp) \ celt/arm/$(DEPDIR)/$(am__dirstamp) libarmasm.la: $(libarmasm_la_OBJECTS) $(libarmasm_la_DEPENDENCIES) $(EXTRA_libarmasm_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(am_libarmasm_la_rpath) $(libarmasm_la_OBJECTS) $(libarmasm_la_LIBADD) $(LIBS) celt/$(am__dirstamp): @$(MKDIR_P) celt @: > celt/$(am__dirstamp) celt/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) celt/$(DEPDIR) @: > celt/$(DEPDIR)/$(am__dirstamp) celt/bands.lo: celt/$(am__dirstamp) celt/$(DEPDIR)/$(am__dirstamp) celt/celt.lo: celt/$(am__dirstamp) celt/$(DEPDIR)/$(am__dirstamp) celt/celt_encoder.lo: celt/$(am__dirstamp) \ celt/$(DEPDIR)/$(am__dirstamp) celt/celt_decoder.lo: celt/$(am__dirstamp) \ celt/$(DEPDIR)/$(am__dirstamp) celt/cwrs.lo: celt/$(am__dirstamp) celt/$(DEPDIR)/$(am__dirstamp) celt/entcode.lo: celt/$(am__dirstamp) celt/$(DEPDIR)/$(am__dirstamp) celt/entdec.lo: celt/$(am__dirstamp) celt/$(DEPDIR)/$(am__dirstamp) celt/entenc.lo: celt/$(am__dirstamp) celt/$(DEPDIR)/$(am__dirstamp) celt/kiss_fft.lo: celt/$(am__dirstamp) celt/$(DEPDIR)/$(am__dirstamp) celt/laplace.lo: celt/$(am__dirstamp) celt/$(DEPDIR)/$(am__dirstamp) celt/mathops.lo: celt/$(am__dirstamp) celt/$(DEPDIR)/$(am__dirstamp) celt/mdct.lo: celt/$(am__dirstamp) celt/$(DEPDIR)/$(am__dirstamp) celt/modes.lo: celt/$(am__dirstamp) celt/$(DEPDIR)/$(am__dirstamp) celt/pitch.lo: celt/$(am__dirstamp) celt/$(DEPDIR)/$(am__dirstamp) celt/celt_lpc.lo: celt/$(am__dirstamp) celt/$(DEPDIR)/$(am__dirstamp) celt/quant_bands.lo: celt/$(am__dirstamp) \ celt/$(DEPDIR)/$(am__dirstamp) celt/rate.lo: celt/$(am__dirstamp) celt/$(DEPDIR)/$(am__dirstamp) celt/vq.lo: celt/$(am__dirstamp) celt/$(DEPDIR)/$(am__dirstamp) celt/x86/$(am__dirstamp): @$(MKDIR_P) celt/x86 @: > celt/x86/$(am__dirstamp) celt/x86/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) celt/x86/$(DEPDIR) @: > celt/x86/$(DEPDIR)/$(am__dirstamp) celt/x86/x86cpu.lo: celt/x86/$(am__dirstamp) \ celt/x86/$(DEPDIR)/$(am__dirstamp) celt/x86/x86_celt_map.lo: celt/x86/$(am__dirstamp) \ celt/x86/$(DEPDIR)/$(am__dirstamp) celt/x86/pitch_sse.lo: celt/x86/$(am__dirstamp) \ celt/x86/$(DEPDIR)/$(am__dirstamp) celt/x86/pitch_sse2.lo: celt/x86/$(am__dirstamp) \ celt/x86/$(DEPDIR)/$(am__dirstamp) celt/x86/vq_sse2.lo: celt/x86/$(am__dirstamp) \ celt/x86/$(DEPDIR)/$(am__dirstamp) celt/x86/celt_lpc_sse4_1.lo: celt/x86/$(am__dirstamp) \ celt/x86/$(DEPDIR)/$(am__dirstamp) celt/x86/pitch_sse4_1.lo: celt/x86/$(am__dirstamp) \ celt/x86/$(DEPDIR)/$(am__dirstamp) celt/arm/armcpu.lo: celt/arm/$(am__dirstamp) \ celt/arm/$(DEPDIR)/$(am__dirstamp) celt/arm/arm_celt_map.lo: celt/arm/$(am__dirstamp) \ celt/arm/$(DEPDIR)/$(am__dirstamp) celt/arm/celt_neon_intr.lo: celt/arm/$(am__dirstamp) \ celt/arm/$(DEPDIR)/$(am__dirstamp) celt/arm/pitch_neon_intr.lo: celt/arm/$(am__dirstamp) \ celt/arm/$(DEPDIR)/$(am__dirstamp) celt/arm/celt_fft_ne10.lo: celt/arm/$(am__dirstamp) \ celt/arm/$(DEPDIR)/$(am__dirstamp) celt/arm/celt_mdct_ne10.lo: celt/arm/$(am__dirstamp) \ celt/arm/$(DEPDIR)/$(am__dirstamp) silk/$(am__dirstamp): @$(MKDIR_P) silk @: > silk/$(am__dirstamp) silk/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) silk/$(DEPDIR) @: > silk/$(DEPDIR)/$(am__dirstamp) silk/CNG.lo: silk/$(am__dirstamp) silk/$(DEPDIR)/$(am__dirstamp) silk/code_signs.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/init_decoder.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/decode_core.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/decode_frame.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/decode_parameters.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/decode_indices.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/decode_pulses.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/decoder_set_fs.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/dec_API.lo: silk/$(am__dirstamp) silk/$(DEPDIR)/$(am__dirstamp) silk/enc_API.lo: silk/$(am__dirstamp) silk/$(DEPDIR)/$(am__dirstamp) silk/encode_indices.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/encode_pulses.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/gain_quant.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/interpolate.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/LP_variable_cutoff.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/NLSF_decode.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/NSQ.lo: silk/$(am__dirstamp) silk/$(DEPDIR)/$(am__dirstamp) silk/NSQ_del_dec.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/PLC.lo: silk/$(am__dirstamp) silk/$(DEPDIR)/$(am__dirstamp) silk/shell_coder.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/tables_gain.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/tables_LTP.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/tables_NLSF_CB_NB_MB.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/tables_NLSF_CB_WB.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/tables_other.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/tables_pitch_lag.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/tables_pulses_per_block.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/VAD.lo: silk/$(am__dirstamp) silk/$(DEPDIR)/$(am__dirstamp) silk/control_audio_bandwidth.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/quant_LTP_gains.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/VQ_WMat_EC.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/HP_variable_cutoff.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/NLSF_encode.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/NLSF_VQ.lo: silk/$(am__dirstamp) silk/$(DEPDIR)/$(am__dirstamp) silk/NLSF_unpack.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/NLSF_del_dec_quant.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/process_NLSFs.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/stereo_LR_to_MS.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/stereo_MS_to_LR.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/check_control_input.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/control_SNR.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/init_encoder.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/control_codec.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/A2NLSF.lo: silk/$(am__dirstamp) silk/$(DEPDIR)/$(am__dirstamp) silk/ana_filt_bank_1.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/biquad_alt.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/bwexpander_32.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/bwexpander.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/debug.lo: silk/$(am__dirstamp) silk/$(DEPDIR)/$(am__dirstamp) silk/decode_pitch.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/inner_prod_aligned.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/lin2log.lo: silk/$(am__dirstamp) silk/$(DEPDIR)/$(am__dirstamp) silk/log2lin.lo: silk/$(am__dirstamp) silk/$(DEPDIR)/$(am__dirstamp) silk/LPC_analysis_filter.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/LPC_inv_pred_gain.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/table_LSF_cos.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/NLSF2A.lo: silk/$(am__dirstamp) silk/$(DEPDIR)/$(am__dirstamp) silk/NLSF_stabilize.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/NLSF_VQ_weights_laroia.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/pitch_est_tables.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/resampler.lo: silk/$(am__dirstamp) silk/$(DEPDIR)/$(am__dirstamp) silk/resampler_down2_3.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/resampler_down2.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/resampler_private_AR2.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/resampler_private_down_FIR.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/resampler_private_IIR_FIR.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/resampler_private_up2_HQ.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/resampler_rom.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/sigm_Q15.lo: silk/$(am__dirstamp) silk/$(DEPDIR)/$(am__dirstamp) silk/sort.lo: silk/$(am__dirstamp) silk/$(DEPDIR)/$(am__dirstamp) silk/sum_sqr_shift.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/stereo_decode_pred.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/stereo_encode_pred.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/stereo_find_predictor.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/stereo_quant_pred.lo: silk/$(am__dirstamp) \ silk/$(DEPDIR)/$(am__dirstamp) silk/LPC_fit.lo: silk/$(am__dirstamp) silk/$(DEPDIR)/$(am__dirstamp) silk/fixed/$(am__dirstamp): @$(MKDIR_P) silk/fixed @: > silk/fixed/$(am__dirstamp) silk/fixed/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) silk/fixed/$(DEPDIR) @: > silk/fixed/$(DEPDIR)/$(am__dirstamp) silk/fixed/LTP_analysis_filter_FIX.lo: silk/fixed/$(am__dirstamp) \ silk/fixed/$(DEPDIR)/$(am__dirstamp) silk/fixed/LTP_scale_ctrl_FIX.lo: silk/fixed/$(am__dirstamp) \ silk/fixed/$(DEPDIR)/$(am__dirstamp) silk/fixed/corrMatrix_FIX.lo: silk/fixed/$(am__dirstamp) \ silk/fixed/$(DEPDIR)/$(am__dirstamp) silk/fixed/encode_frame_FIX.lo: silk/fixed/$(am__dirstamp) \ silk/fixed/$(DEPDIR)/$(am__dirstamp) silk/fixed/find_LPC_FIX.lo: silk/fixed/$(am__dirstamp) \ silk/fixed/$(DEPDIR)/$(am__dirstamp) silk/fixed/find_LTP_FIX.lo: silk/fixed/$(am__dirstamp) \ silk/fixed/$(DEPDIR)/$(am__dirstamp) silk/fixed/find_pitch_lags_FIX.lo: silk/fixed/$(am__dirstamp) \ silk/fixed/$(DEPDIR)/$(am__dirstamp) silk/fixed/find_pred_coefs_FIX.lo: silk/fixed/$(am__dirstamp) \ silk/fixed/$(DEPDIR)/$(am__dirstamp) silk/fixed/noise_shape_analysis_FIX.lo: silk/fixed/$(am__dirstamp) \ silk/fixed/$(DEPDIR)/$(am__dirstamp) silk/fixed/process_gains_FIX.lo: silk/fixed/$(am__dirstamp) \ silk/fixed/$(DEPDIR)/$(am__dirstamp) silk/fixed/regularize_correlations_FIX.lo: silk/fixed/$(am__dirstamp) \ silk/fixed/$(DEPDIR)/$(am__dirstamp) silk/fixed/residual_energy16_FIX.lo: silk/fixed/$(am__dirstamp) \ silk/fixed/$(DEPDIR)/$(am__dirstamp) silk/fixed/residual_energy_FIX.lo: silk/fixed/$(am__dirstamp) \ silk/fixed/$(DEPDIR)/$(am__dirstamp) silk/fixed/warped_autocorrelation_FIX.lo: silk/fixed/$(am__dirstamp) \ silk/fixed/$(DEPDIR)/$(am__dirstamp) silk/fixed/apply_sine_window_FIX.lo: silk/fixed/$(am__dirstamp) \ silk/fixed/$(DEPDIR)/$(am__dirstamp) silk/fixed/autocorr_FIX.lo: silk/fixed/$(am__dirstamp) \ silk/fixed/$(DEPDIR)/$(am__dirstamp) silk/fixed/burg_modified_FIX.lo: silk/fixed/$(am__dirstamp) \ silk/fixed/$(DEPDIR)/$(am__dirstamp) silk/fixed/k2a_FIX.lo: silk/fixed/$(am__dirstamp) \ silk/fixed/$(DEPDIR)/$(am__dirstamp) silk/fixed/k2a_Q16_FIX.lo: silk/fixed/$(am__dirstamp) \ silk/fixed/$(DEPDIR)/$(am__dirstamp) silk/fixed/pitch_analysis_core_FIX.lo: silk/fixed/$(am__dirstamp) \ silk/fixed/$(DEPDIR)/$(am__dirstamp) silk/fixed/vector_ops_FIX.lo: silk/fixed/$(am__dirstamp) \ silk/fixed/$(DEPDIR)/$(am__dirstamp) silk/fixed/schur64_FIX.lo: silk/fixed/$(am__dirstamp) \ silk/fixed/$(DEPDIR)/$(am__dirstamp) silk/fixed/schur_FIX.lo: silk/fixed/$(am__dirstamp) \ silk/fixed/$(DEPDIR)/$(am__dirstamp) silk/x86/$(am__dirstamp): @$(MKDIR_P) silk/x86 @: > silk/x86/$(am__dirstamp) silk/x86/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) silk/x86/$(DEPDIR) @: > silk/x86/$(DEPDIR)/$(am__dirstamp) silk/x86/NSQ_sse4_1.lo: silk/x86/$(am__dirstamp) \ silk/x86/$(DEPDIR)/$(am__dirstamp) silk/x86/NSQ_del_dec_sse4_1.lo: silk/x86/$(am__dirstamp) \ silk/x86/$(DEPDIR)/$(am__dirstamp) silk/x86/x86_silk_map.lo: silk/x86/$(am__dirstamp) \ silk/x86/$(DEPDIR)/$(am__dirstamp) silk/x86/VAD_sse4_1.lo: silk/x86/$(am__dirstamp) \ silk/x86/$(DEPDIR)/$(am__dirstamp) silk/x86/VQ_WMat_EC_sse4_1.lo: silk/x86/$(am__dirstamp) \ silk/x86/$(DEPDIR)/$(am__dirstamp) silk/fixed/x86/$(am__dirstamp): @$(MKDIR_P) silk/fixed/x86 @: > silk/fixed/x86/$(am__dirstamp) silk/fixed/x86/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) silk/fixed/x86/$(DEPDIR) @: > silk/fixed/x86/$(DEPDIR)/$(am__dirstamp) silk/fixed/x86/vector_ops_FIX_sse4_1.lo: \ silk/fixed/x86/$(am__dirstamp) \ silk/fixed/x86/$(DEPDIR)/$(am__dirstamp) silk/fixed/x86/burg_modified_FIX_sse4_1.lo: \ silk/fixed/x86/$(am__dirstamp) \ silk/fixed/x86/$(DEPDIR)/$(am__dirstamp) silk/fixed/arm/$(am__dirstamp): @$(MKDIR_P) silk/fixed/arm @: > silk/fixed/arm/$(am__dirstamp) silk/fixed/arm/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) silk/fixed/arm/$(DEPDIR) @: > silk/fixed/arm/$(DEPDIR)/$(am__dirstamp) silk/fixed/arm/warped_autocorrelation_FIX_neon_intr.lo: \ silk/fixed/arm/$(am__dirstamp) \ silk/fixed/arm/$(DEPDIR)/$(am__dirstamp) silk/float/$(am__dirstamp): @$(MKDIR_P) silk/float @: > silk/float/$(am__dirstamp) silk/float/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) silk/float/$(DEPDIR) @: > silk/float/$(DEPDIR)/$(am__dirstamp) silk/float/apply_sine_window_FLP.lo: silk/float/$(am__dirstamp) \ silk/float/$(DEPDIR)/$(am__dirstamp) silk/float/corrMatrix_FLP.lo: silk/float/$(am__dirstamp) \ silk/float/$(DEPDIR)/$(am__dirstamp) silk/float/encode_frame_FLP.lo: silk/float/$(am__dirstamp) \ silk/float/$(DEPDIR)/$(am__dirstamp) silk/float/find_LPC_FLP.lo: silk/float/$(am__dirstamp) \ silk/float/$(DEPDIR)/$(am__dirstamp) silk/float/find_LTP_FLP.lo: silk/float/$(am__dirstamp) \ silk/float/$(DEPDIR)/$(am__dirstamp) silk/float/find_pitch_lags_FLP.lo: silk/float/$(am__dirstamp) \ silk/float/$(DEPDIR)/$(am__dirstamp) silk/float/find_pred_coefs_FLP.lo: silk/float/$(am__dirstamp) \ silk/float/$(DEPDIR)/$(am__dirstamp) silk/float/LPC_analysis_filter_FLP.lo: silk/float/$(am__dirstamp) \ silk/float/$(DEPDIR)/$(am__dirstamp) silk/float/LTP_analysis_filter_FLP.lo: silk/float/$(am__dirstamp) \ silk/float/$(DEPDIR)/$(am__dirstamp) silk/float/LTP_scale_ctrl_FLP.lo: silk/float/$(am__dirstamp) \ silk/float/$(DEPDIR)/$(am__dirstamp) silk/float/noise_shape_analysis_FLP.lo: silk/float/$(am__dirstamp) \ silk/float/$(DEPDIR)/$(am__dirstamp) silk/float/process_gains_FLP.lo: silk/float/$(am__dirstamp) \ silk/float/$(DEPDIR)/$(am__dirstamp) silk/float/regularize_correlations_FLP.lo: silk/float/$(am__dirstamp) \ silk/float/$(DEPDIR)/$(am__dirstamp) silk/float/residual_energy_FLP.lo: silk/float/$(am__dirstamp) \ silk/float/$(DEPDIR)/$(am__dirstamp) silk/float/warped_autocorrelation_FLP.lo: silk/float/$(am__dirstamp) \ silk/float/$(DEPDIR)/$(am__dirstamp) silk/float/wrappers_FLP.lo: silk/float/$(am__dirstamp) \ silk/float/$(DEPDIR)/$(am__dirstamp) silk/float/autocorrelation_FLP.lo: silk/float/$(am__dirstamp) \ silk/float/$(DEPDIR)/$(am__dirstamp) silk/float/burg_modified_FLP.lo: silk/float/$(am__dirstamp) \ silk/float/$(DEPDIR)/$(am__dirstamp) silk/float/bwexpander_FLP.lo: silk/float/$(am__dirstamp) \ silk/float/$(DEPDIR)/$(am__dirstamp) silk/float/energy_FLP.lo: silk/float/$(am__dirstamp) \ silk/float/$(DEPDIR)/$(am__dirstamp) silk/float/inner_product_FLP.lo: silk/float/$(am__dirstamp) \ silk/float/$(DEPDIR)/$(am__dirstamp) silk/float/k2a_FLP.lo: silk/float/$(am__dirstamp) \ silk/float/$(DEPDIR)/$(am__dirstamp) silk/float/LPC_inv_pred_gain_FLP.lo: silk/float/$(am__dirstamp) \ silk/float/$(DEPDIR)/$(am__dirstamp) silk/float/pitch_analysis_core_FLP.lo: silk/float/$(am__dirstamp) \ silk/float/$(DEPDIR)/$(am__dirstamp) silk/float/scale_copy_vector_FLP.lo: silk/float/$(am__dirstamp) \ silk/float/$(DEPDIR)/$(am__dirstamp) silk/float/scale_vector_FLP.lo: silk/float/$(am__dirstamp) \ silk/float/$(DEPDIR)/$(am__dirstamp) silk/float/schur_FLP.lo: silk/float/$(am__dirstamp) \ silk/float/$(DEPDIR)/$(am__dirstamp) silk/float/sort_FLP.lo: silk/float/$(am__dirstamp) \ silk/float/$(DEPDIR)/$(am__dirstamp) silk/arm/$(am__dirstamp): @$(MKDIR_P) silk/arm @: > silk/arm/$(am__dirstamp) silk/arm/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) silk/arm/$(DEPDIR) @: > silk/arm/$(DEPDIR)/$(am__dirstamp) silk/arm/arm_silk_map.lo: silk/arm/$(am__dirstamp) \ silk/arm/$(DEPDIR)/$(am__dirstamp) silk/arm/biquad_alt_neon_intr.lo: silk/arm/$(am__dirstamp) \ silk/arm/$(DEPDIR)/$(am__dirstamp) silk/arm/LPC_inv_pred_gain_neon_intr.lo: silk/arm/$(am__dirstamp) \ silk/arm/$(DEPDIR)/$(am__dirstamp) silk/arm/NSQ_del_dec_neon_intr.lo: silk/arm/$(am__dirstamp) \ silk/arm/$(DEPDIR)/$(am__dirstamp) silk/arm/NSQ_neon.lo: silk/arm/$(am__dirstamp) \ silk/arm/$(DEPDIR)/$(am__dirstamp) src/$(am__dirstamp): @$(MKDIR_P) src @: > src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/$(DEPDIR) @: > src/$(DEPDIR)/$(am__dirstamp) src/opus.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) src/opus_decoder.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) src/opus_encoder.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) src/opus_multistream.lo: src/$(am__dirstamp) \ src/$(DEPDIR)/$(am__dirstamp) src/opus_multistream_encoder.lo: src/$(am__dirstamp) \ src/$(DEPDIR)/$(am__dirstamp) src/opus_multistream_decoder.lo: src/$(am__dirstamp) \ src/$(DEPDIR)/$(am__dirstamp) src/repacketizer.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) src/opus_projection_encoder.lo: src/$(am__dirstamp) \ src/$(DEPDIR)/$(am__dirstamp) src/opus_projection_decoder.lo: src/$(am__dirstamp) \ src/$(DEPDIR)/$(am__dirstamp) src/mapping_matrix.lo: src/$(am__dirstamp) \ src/$(DEPDIR)/$(am__dirstamp) src/analysis.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) src/mlp.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) src/mlp_data.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) libopus.la: $(libopus_la_OBJECTS) $(libopus_la_DEPENDENCIES) $(EXTRA_libopus_la_DEPENDENCIES) $(AM_V_CCLD)$(libopus_la_LINK) -rpath $(libdir) $(libopus_la_OBJECTS) $(libopus_la_LIBADD) $(LIBS) clean-noinstPROGRAMS: @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list celt/tests/$(am__dirstamp): @$(MKDIR_P) celt/tests @: > celt/tests/$(am__dirstamp) celt/tests/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) celt/tests/$(DEPDIR) @: > celt/tests/$(DEPDIR)/$(am__dirstamp) celt/tests/test_unit_cwrs32.$(OBJEXT): celt/tests/$(am__dirstamp) \ celt/tests/$(DEPDIR)/$(am__dirstamp) celt/tests/test_unit_cwrs32$(EXEEXT): $(celt_tests_test_unit_cwrs32_OBJECTS) $(celt_tests_test_unit_cwrs32_DEPENDENCIES) $(EXTRA_celt_tests_test_unit_cwrs32_DEPENDENCIES) celt/tests/$(am__dirstamp) @rm -f celt/tests/test_unit_cwrs32$(EXEEXT) $(AM_V_CCLD)$(LINK) $(celt_tests_test_unit_cwrs32_OBJECTS) $(celt_tests_test_unit_cwrs32_LDADD) $(LIBS) celt/tests/test_unit_dft.$(OBJEXT): celt/tests/$(am__dirstamp) \ celt/tests/$(DEPDIR)/$(am__dirstamp) celt/tests/test_unit_dft$(EXEEXT): $(celt_tests_test_unit_dft_OBJECTS) $(celt_tests_test_unit_dft_DEPENDENCIES) $(EXTRA_celt_tests_test_unit_dft_DEPENDENCIES) celt/tests/$(am__dirstamp) @rm -f celt/tests/test_unit_dft$(EXEEXT) $(AM_V_CCLD)$(LINK) $(celt_tests_test_unit_dft_OBJECTS) $(celt_tests_test_unit_dft_LDADD) $(LIBS) celt/tests/test_unit_entropy.$(OBJEXT): celt/tests/$(am__dirstamp) \ celt/tests/$(DEPDIR)/$(am__dirstamp) celt/tests/test_unit_entropy$(EXEEXT): $(celt_tests_test_unit_entropy_OBJECTS) $(celt_tests_test_unit_entropy_DEPENDENCIES) $(EXTRA_celt_tests_test_unit_entropy_DEPENDENCIES) celt/tests/$(am__dirstamp) @rm -f celt/tests/test_unit_entropy$(EXEEXT) $(AM_V_CCLD)$(LINK) $(celt_tests_test_unit_entropy_OBJECTS) $(celt_tests_test_unit_entropy_LDADD) $(LIBS) celt/tests/test_unit_laplace.$(OBJEXT): celt/tests/$(am__dirstamp) \ celt/tests/$(DEPDIR)/$(am__dirstamp) celt/tests/test_unit_laplace$(EXEEXT): $(celt_tests_test_unit_laplace_OBJECTS) $(celt_tests_test_unit_laplace_DEPENDENCIES) $(EXTRA_celt_tests_test_unit_laplace_DEPENDENCIES) celt/tests/$(am__dirstamp) @rm -f celt/tests/test_unit_laplace$(EXEEXT) $(AM_V_CCLD)$(LINK) $(celt_tests_test_unit_laplace_OBJECTS) $(celt_tests_test_unit_laplace_LDADD) $(LIBS) celt/tests/test_unit_mathops.$(OBJEXT): celt/tests/$(am__dirstamp) \ celt/tests/$(DEPDIR)/$(am__dirstamp) celt/tests/test_unit_mathops$(EXEEXT): $(celt_tests_test_unit_mathops_OBJECTS) $(celt_tests_test_unit_mathops_DEPENDENCIES) $(EXTRA_celt_tests_test_unit_mathops_DEPENDENCIES) celt/tests/$(am__dirstamp) @rm -f celt/tests/test_unit_mathops$(EXEEXT) $(AM_V_CCLD)$(LINK) $(celt_tests_test_unit_mathops_OBJECTS) $(celt_tests_test_unit_mathops_LDADD) $(LIBS) celt/tests/test_unit_mdct.$(OBJEXT): celt/tests/$(am__dirstamp) \ celt/tests/$(DEPDIR)/$(am__dirstamp) celt/tests/test_unit_mdct$(EXEEXT): $(celt_tests_test_unit_mdct_OBJECTS) $(celt_tests_test_unit_mdct_DEPENDENCIES) $(EXTRA_celt_tests_test_unit_mdct_DEPENDENCIES) celt/tests/$(am__dirstamp) @rm -f celt/tests/test_unit_mdct$(EXEEXT) $(AM_V_CCLD)$(LINK) $(celt_tests_test_unit_mdct_OBJECTS) $(celt_tests_test_unit_mdct_LDADD) $(LIBS) celt/tests/test_unit_rotation.$(OBJEXT): celt/tests/$(am__dirstamp) \ celt/tests/$(DEPDIR)/$(am__dirstamp) celt/tests/test_unit_rotation$(EXEEXT): $(celt_tests_test_unit_rotation_OBJECTS) $(celt_tests_test_unit_rotation_DEPENDENCIES) $(EXTRA_celt_tests_test_unit_rotation_DEPENDENCIES) celt/tests/$(am__dirstamp) @rm -f celt/tests/test_unit_rotation$(EXEEXT) $(AM_V_CCLD)$(LINK) $(celt_tests_test_unit_rotation_OBJECTS) $(celt_tests_test_unit_rotation_LDADD) $(LIBS) celt/tests/test_unit_types.$(OBJEXT): celt/tests/$(am__dirstamp) \ celt/tests/$(DEPDIR)/$(am__dirstamp) celt/tests/test_unit_types$(EXEEXT): $(celt_tests_test_unit_types_OBJECTS) $(celt_tests_test_unit_types_DEPENDENCIES) $(EXTRA_celt_tests_test_unit_types_DEPENDENCIES) celt/tests/$(am__dirstamp) @rm -f celt/tests/test_unit_types$(EXEEXT) $(AM_V_CCLD)$(LINK) $(celt_tests_test_unit_types_OBJECTS) $(celt_tests_test_unit_types_LDADD) $(LIBS) src/opus_compare.$(OBJEXT): src/$(am__dirstamp) \ src/$(DEPDIR)/$(am__dirstamp) opus_compare$(EXEEXT): $(opus_compare_OBJECTS) $(opus_compare_DEPENDENCIES) $(EXTRA_opus_compare_DEPENDENCIES) @rm -f opus_compare$(EXEEXT) $(AM_V_CCLD)$(LINK) $(opus_compare_OBJECTS) $(opus_compare_LDADD) $(LIBS) celt/opus_custom_demo.$(OBJEXT): celt/$(am__dirstamp) \ celt/$(DEPDIR)/$(am__dirstamp) opus_custom_demo$(EXEEXT): $(opus_custom_demo_OBJECTS) $(opus_custom_demo_DEPENDENCIES) $(EXTRA_opus_custom_demo_DEPENDENCIES) @rm -f opus_custom_demo$(EXEEXT) $(AM_V_CCLD)$(LINK) $(opus_custom_demo_OBJECTS) $(opus_custom_demo_LDADD) $(LIBS) src/opus_demo.$(OBJEXT): src/$(am__dirstamp) \ src/$(DEPDIR)/$(am__dirstamp) opus_demo$(EXEEXT): $(opus_demo_OBJECTS) $(opus_demo_DEPENDENCIES) $(EXTRA_opus_demo_DEPENDENCIES) @rm -f opus_demo$(EXEEXT) $(AM_V_CCLD)$(LINK) $(opus_demo_OBJECTS) $(opus_demo_LDADD) $(LIBS) src/repacketizer_demo.$(OBJEXT): src/$(am__dirstamp) \ src/$(DEPDIR)/$(am__dirstamp) repacketizer_demo$(EXEEXT): $(repacketizer_demo_OBJECTS) $(repacketizer_demo_DEPENDENCIES) $(EXTRA_repacketizer_demo_DEPENDENCIES) @rm -f repacketizer_demo$(EXEEXT) $(AM_V_CCLD)$(LINK) $(repacketizer_demo_OBJECTS) $(repacketizer_demo_LDADD) $(LIBS) silk/tests/$(am__dirstamp): @$(MKDIR_P) silk/tests @: > silk/tests/$(am__dirstamp) silk/tests/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) silk/tests/$(DEPDIR) @: > silk/tests/$(DEPDIR)/$(am__dirstamp) silk/tests/test_unit_LPC_inv_pred_gain.$(OBJEXT): \ silk/tests/$(am__dirstamp) \ silk/tests/$(DEPDIR)/$(am__dirstamp) silk/tests/test_unit_LPC_inv_pred_gain$(EXEEXT): $(silk_tests_test_unit_LPC_inv_pred_gain_OBJECTS) $(silk_tests_test_unit_LPC_inv_pred_gain_DEPENDENCIES) $(EXTRA_silk_tests_test_unit_LPC_inv_pred_gain_DEPENDENCIES) silk/tests/$(am__dirstamp) @rm -f silk/tests/test_unit_LPC_inv_pred_gain$(EXEEXT) $(AM_V_CCLD)$(LINK) $(silk_tests_test_unit_LPC_inv_pred_gain_OBJECTS) $(silk_tests_test_unit_LPC_inv_pred_gain_LDADD) $(LIBS) tests/$(am__dirstamp): @$(MKDIR_P) tests @: > tests/$(am__dirstamp) tests/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) tests/$(DEPDIR) @: > tests/$(DEPDIR)/$(am__dirstamp) tests/test_opus_api.$(OBJEXT): tests/$(am__dirstamp) \ tests/$(DEPDIR)/$(am__dirstamp) tests/test_opus_api$(EXEEXT): $(tests_test_opus_api_OBJECTS) $(tests_test_opus_api_DEPENDENCIES) $(EXTRA_tests_test_opus_api_DEPENDENCIES) tests/$(am__dirstamp) @rm -f tests/test_opus_api$(EXEEXT) $(AM_V_CCLD)$(LINK) $(tests_test_opus_api_OBJECTS) $(tests_test_opus_api_LDADD) $(LIBS) tests/test_opus_decode.$(OBJEXT): tests/$(am__dirstamp) \ tests/$(DEPDIR)/$(am__dirstamp) tests/test_opus_decode$(EXEEXT): $(tests_test_opus_decode_OBJECTS) $(tests_test_opus_decode_DEPENDENCIES) $(EXTRA_tests_test_opus_decode_DEPENDENCIES) tests/$(am__dirstamp) @rm -f tests/test_opus_decode$(EXEEXT) $(AM_V_CCLD)$(LINK) $(tests_test_opus_decode_OBJECTS) $(tests_test_opus_decode_LDADD) $(LIBS) tests/test_opus_encode.$(OBJEXT): tests/$(am__dirstamp) \ tests/$(DEPDIR)/$(am__dirstamp) tests/opus_encode_regressions.$(OBJEXT): tests/$(am__dirstamp) \ tests/$(DEPDIR)/$(am__dirstamp) tests/test_opus_encode$(EXEEXT): $(tests_test_opus_encode_OBJECTS) $(tests_test_opus_encode_DEPENDENCIES) $(EXTRA_tests_test_opus_encode_DEPENDENCIES) tests/$(am__dirstamp) @rm -f tests/test_opus_encode$(EXEEXT) $(AM_V_CCLD)$(LINK) $(tests_test_opus_encode_OBJECTS) $(tests_test_opus_encode_LDADD) $(LIBS) tests/test_opus_padding.$(OBJEXT): tests/$(am__dirstamp) \ tests/$(DEPDIR)/$(am__dirstamp) tests/test_opus_padding$(EXEEXT): $(tests_test_opus_padding_OBJECTS) $(tests_test_opus_padding_DEPENDENCIES) $(EXTRA_tests_test_opus_padding_DEPENDENCIES) tests/$(am__dirstamp) @rm -f tests/test_opus_padding$(EXEEXT) $(AM_V_CCLD)$(LINK) $(tests_test_opus_padding_OBJECTS) $(tests_test_opus_padding_LDADD) $(LIBS) tests/test_opus_projection.$(OBJEXT): tests/$(am__dirstamp) \ tests/$(DEPDIR)/$(am__dirstamp) tests/test_opus_projection$(EXEEXT): $(tests_test_opus_projection_OBJECTS) $(tests_test_opus_projection_DEPENDENCIES) $(EXTRA_tests_test_opus_projection_DEPENDENCIES) tests/$(am__dirstamp) @rm -f tests/test_opus_projection$(EXEEXT) $(AM_V_CCLD)$(LINK) $(tests_test_opus_projection_OBJECTS) $(tests_test_opus_projection_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f celt/*.$(OBJEXT) -rm -f celt/*.lo -rm -f celt/arm/*.$(OBJEXT) -rm -f celt/arm/*.lo -rm -f celt/tests/*.$(OBJEXT) -rm -f celt/x86/*.$(OBJEXT) -rm -f celt/x86/*.lo -rm -f silk/*.$(OBJEXT) -rm -f silk/*.lo -rm -f silk/arm/*.$(OBJEXT) -rm -f silk/arm/*.lo -rm -f silk/fixed/*.$(OBJEXT) -rm -f silk/fixed/*.lo -rm -f silk/fixed/arm/*.$(OBJEXT) -rm -f silk/fixed/arm/*.lo -rm -f silk/fixed/x86/*.$(OBJEXT) -rm -f silk/fixed/x86/*.lo -rm -f silk/float/*.$(OBJEXT) -rm -f silk/float/*.lo -rm -f silk/tests/*.$(OBJEXT) -rm -f silk/x86/*.$(OBJEXT) -rm -f silk/x86/*.lo -rm -f src/*.$(OBJEXT) -rm -f src/*.lo -rm -f tests/*.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@celt/$(DEPDIR)/bands.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/$(DEPDIR)/celt.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/$(DEPDIR)/celt_decoder.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/$(DEPDIR)/celt_encoder.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/$(DEPDIR)/celt_lpc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/$(DEPDIR)/cwrs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/$(DEPDIR)/entcode.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/$(DEPDIR)/entdec.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/$(DEPDIR)/entenc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/$(DEPDIR)/kiss_fft.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/$(DEPDIR)/laplace.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/$(DEPDIR)/mathops.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/$(DEPDIR)/mdct.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/$(DEPDIR)/modes.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/$(DEPDIR)/opus_custom_demo.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/$(DEPDIR)/pitch.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/$(DEPDIR)/quant_bands.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/$(DEPDIR)/rate.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/$(DEPDIR)/vq.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/arm/$(DEPDIR)/arm_celt_map.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/arm/$(DEPDIR)/armcpu.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/arm/$(DEPDIR)/celt_fft_ne10.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/arm/$(DEPDIR)/celt_mdct_ne10.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/arm/$(DEPDIR)/celt_neon_intr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/arm/$(DEPDIR)/celt_pitch_xcorr_arm-gnu.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/arm/$(DEPDIR)/pitch_neon_intr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/tests/$(DEPDIR)/test_unit_cwrs32.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/tests/$(DEPDIR)/test_unit_dft.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/tests/$(DEPDIR)/test_unit_entropy.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/tests/$(DEPDIR)/test_unit_laplace.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/tests/$(DEPDIR)/test_unit_mathops.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/tests/$(DEPDIR)/test_unit_mdct.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/tests/$(DEPDIR)/test_unit_rotation.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/tests/$(DEPDIR)/test_unit_types.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/x86/$(DEPDIR)/celt_lpc_sse4_1.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/x86/$(DEPDIR)/pitch_sse.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/x86/$(DEPDIR)/pitch_sse2.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/x86/$(DEPDIR)/pitch_sse4_1.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/x86/$(DEPDIR)/vq_sse2.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/x86/$(DEPDIR)/x86_celt_map.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@celt/x86/$(DEPDIR)/x86cpu.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/A2NLSF.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/CNG.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/HP_variable_cutoff.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/LPC_analysis_filter.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/LPC_fit.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/LPC_inv_pred_gain.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/LP_variable_cutoff.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/NLSF2A.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/NLSF_VQ.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/NLSF_VQ_weights_laroia.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/NLSF_decode.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/NLSF_del_dec_quant.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/NLSF_encode.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/NLSF_stabilize.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/NLSF_unpack.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/NSQ.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/NSQ_del_dec.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/PLC.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/VAD.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/VQ_WMat_EC.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/ana_filt_bank_1.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/biquad_alt.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/bwexpander.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/bwexpander_32.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/check_control_input.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/code_signs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/control_SNR.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/control_audio_bandwidth.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/control_codec.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/debug.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/dec_API.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/decode_core.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/decode_frame.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/decode_indices.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/decode_parameters.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/decode_pitch.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/decode_pulses.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/decoder_set_fs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/enc_API.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/encode_indices.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/encode_pulses.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/gain_quant.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/init_decoder.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/init_encoder.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/inner_prod_aligned.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/interpolate.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/lin2log.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/log2lin.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/pitch_est_tables.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/process_NLSFs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/quant_LTP_gains.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/resampler.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/resampler_down2.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/resampler_down2_3.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/resampler_private_AR2.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/resampler_private_IIR_FIR.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/resampler_private_down_FIR.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/resampler_private_up2_HQ.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/resampler_rom.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/shell_coder.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/sigm_Q15.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/sort.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/stereo_LR_to_MS.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/stereo_MS_to_LR.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/stereo_decode_pred.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/stereo_encode_pred.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/stereo_find_predictor.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/stereo_quant_pred.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/sum_sqr_shift.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/table_LSF_cos.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/tables_LTP.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/tables_NLSF_CB_NB_MB.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/tables_NLSF_CB_WB.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/tables_gain.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/tables_other.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/tables_pitch_lag.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/$(DEPDIR)/tables_pulses_per_block.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/arm/$(DEPDIR)/LPC_inv_pred_gain_neon_intr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/arm/$(DEPDIR)/NSQ_del_dec_neon_intr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/arm/$(DEPDIR)/NSQ_neon.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/arm/$(DEPDIR)/arm_silk_map.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/arm/$(DEPDIR)/biquad_alt_neon_intr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/fixed/$(DEPDIR)/LTP_analysis_filter_FIX.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/fixed/$(DEPDIR)/LTP_scale_ctrl_FIX.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/fixed/$(DEPDIR)/apply_sine_window_FIX.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/fixed/$(DEPDIR)/autocorr_FIX.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/fixed/$(DEPDIR)/burg_modified_FIX.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/fixed/$(DEPDIR)/corrMatrix_FIX.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/fixed/$(DEPDIR)/encode_frame_FIX.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/fixed/$(DEPDIR)/find_LPC_FIX.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/fixed/$(DEPDIR)/find_LTP_FIX.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/fixed/$(DEPDIR)/find_pitch_lags_FIX.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/fixed/$(DEPDIR)/find_pred_coefs_FIX.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/fixed/$(DEPDIR)/k2a_FIX.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/fixed/$(DEPDIR)/k2a_Q16_FIX.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/fixed/$(DEPDIR)/noise_shape_analysis_FIX.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/fixed/$(DEPDIR)/pitch_analysis_core_FIX.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/fixed/$(DEPDIR)/process_gains_FIX.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/fixed/$(DEPDIR)/regularize_correlations_FIX.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/fixed/$(DEPDIR)/residual_energy16_FIX.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/fixed/$(DEPDIR)/residual_energy_FIX.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/fixed/$(DEPDIR)/schur64_FIX.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/fixed/$(DEPDIR)/schur_FIX.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/fixed/$(DEPDIR)/vector_ops_FIX.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/fixed/$(DEPDIR)/warped_autocorrelation_FIX.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/fixed/arm/$(DEPDIR)/warped_autocorrelation_FIX_neon_intr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/fixed/x86/$(DEPDIR)/burg_modified_FIX_sse4_1.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/fixed/x86/$(DEPDIR)/vector_ops_FIX_sse4_1.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/float/$(DEPDIR)/LPC_analysis_filter_FLP.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/float/$(DEPDIR)/LPC_inv_pred_gain_FLP.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/float/$(DEPDIR)/LTP_analysis_filter_FLP.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/float/$(DEPDIR)/LTP_scale_ctrl_FLP.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/float/$(DEPDIR)/apply_sine_window_FLP.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/float/$(DEPDIR)/autocorrelation_FLP.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/float/$(DEPDIR)/burg_modified_FLP.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/float/$(DEPDIR)/bwexpander_FLP.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/float/$(DEPDIR)/corrMatrix_FLP.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/float/$(DEPDIR)/encode_frame_FLP.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/float/$(DEPDIR)/energy_FLP.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/float/$(DEPDIR)/find_LPC_FLP.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/float/$(DEPDIR)/find_LTP_FLP.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/float/$(DEPDIR)/find_pitch_lags_FLP.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/float/$(DEPDIR)/find_pred_coefs_FLP.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/float/$(DEPDIR)/inner_product_FLP.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/float/$(DEPDIR)/k2a_FLP.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/float/$(DEPDIR)/noise_shape_analysis_FLP.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/float/$(DEPDIR)/pitch_analysis_core_FLP.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/float/$(DEPDIR)/process_gains_FLP.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/float/$(DEPDIR)/regularize_correlations_FLP.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/float/$(DEPDIR)/residual_energy_FLP.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/float/$(DEPDIR)/scale_copy_vector_FLP.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/float/$(DEPDIR)/scale_vector_FLP.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/float/$(DEPDIR)/schur_FLP.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/float/$(DEPDIR)/sort_FLP.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/float/$(DEPDIR)/warped_autocorrelation_FLP.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/float/$(DEPDIR)/wrappers_FLP.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/tests/$(DEPDIR)/test_unit_LPC_inv_pred_gain.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/x86/$(DEPDIR)/NSQ_del_dec_sse4_1.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/x86/$(DEPDIR)/NSQ_sse4_1.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/x86/$(DEPDIR)/VAD_sse4_1.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/x86/$(DEPDIR)/VQ_WMat_EC_sse4_1.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@silk/x86/$(DEPDIR)/x86_silk_map.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/analysis.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/mapping_matrix.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/mlp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/mlp_data.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/opus.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/opus_compare.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/opus_decoder.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/opus_demo.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/opus_encoder.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/opus_multistream.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/opus_multistream_decoder.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/opus_multistream_encoder.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/opus_projection_decoder.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/opus_projection_encoder.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/repacketizer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/repacketizer_demo.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/opus_encode_regressions.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test_opus_api.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test_opus_decode.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test_opus_encode.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test_opus_padding.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test_opus_projection.Po@am__quote@ .S.o: @am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCCAS_TRUE@ $(CPPASCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCCAS_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(CPPASCOMPILE) -c -o $@ $< .S.obj: @am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCCAS_TRUE@ $(CPPASCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCCAS_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(CPPASCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .S.lo: @am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCCAS_TRUE@ $(LTCPPASCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCCAS_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(LTCPPASCOMPILE) -c -o $@ $< .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs -rm -rf celt/.libs celt/_libs -rm -rf celt/arm/.libs celt/arm/_libs -rm -rf celt/tests/.libs celt/tests/_libs -rm -rf celt/x86/.libs celt/x86/_libs -rm -rf silk/.libs silk/_libs -rm -rf silk/arm/.libs silk/arm/_libs -rm -rf silk/fixed/.libs silk/fixed/_libs -rm -rf silk/fixed/arm/.libs silk/fixed/arm/_libs -rm -rf silk/fixed/x86/.libs silk/fixed/x86/_libs -rm -rf silk/float/.libs silk/float/_libs -rm -rf silk/tests/.libs silk/tests/_libs -rm -rf silk/x86/.libs silk/x86/_libs -rm -rf src/.libs src/_libs -rm -rf tests/.libs tests/_libs distclean-libtool: -rm -f libtool config.lt install-m4dataDATA: $(m4data_DATA) @$(NORMAL_INSTALL) @list='$(m4data_DATA)'; test -n "$(m4datadir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(m4datadir)'"; \ $(MKDIR_P) "$(DESTDIR)$(m4datadir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(m4datadir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(m4datadir)" || exit $$?; \ done uninstall-m4dataDATA: @$(NORMAL_UNINSTALL) @list='$(m4data_DATA)'; test -n "$(m4datadir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(m4datadir)'; $(am__uninstall_files_from_dir) install-pkgconfigDATA: $(pkgconfig_DATA) @$(NORMAL_INSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ done uninstall-pkgconfigDATA: @$(NORMAL_UNINSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) install-pkgincludeHEADERS: $(pkginclude_HEADERS) @$(NORMAL_INSTALL) @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \ done uninstall-pkgincludeHEADERS: @$(NORMAL_UNINSTALL) @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscope: cscope.files test ! -s cscope.files \ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) clean-cscope: -rm -f cscope.files cscope.files: clean-cscope cscopelist cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? celt/tests/test_unit_cwrs32.log: celt/tests/test_unit_cwrs32$(EXEEXT) @p='celt/tests/test_unit_cwrs32$(EXEEXT)'; \ b='celt/tests/test_unit_cwrs32'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) celt/tests/test_unit_dft.log: celt/tests/test_unit_dft$(EXEEXT) @p='celt/tests/test_unit_dft$(EXEEXT)'; \ b='celt/tests/test_unit_dft'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) celt/tests/test_unit_entropy.log: celt/tests/test_unit_entropy$(EXEEXT) @p='celt/tests/test_unit_entropy$(EXEEXT)'; \ b='celt/tests/test_unit_entropy'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) celt/tests/test_unit_laplace.log: celt/tests/test_unit_laplace$(EXEEXT) @p='celt/tests/test_unit_laplace$(EXEEXT)'; \ b='celt/tests/test_unit_laplace'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) celt/tests/test_unit_mathops.log: celt/tests/test_unit_mathops$(EXEEXT) @p='celt/tests/test_unit_mathops$(EXEEXT)'; \ b='celt/tests/test_unit_mathops'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) celt/tests/test_unit_mdct.log: celt/tests/test_unit_mdct$(EXEEXT) @p='celt/tests/test_unit_mdct$(EXEEXT)'; \ b='celt/tests/test_unit_mdct'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) celt/tests/test_unit_rotation.log: celt/tests/test_unit_rotation$(EXEEXT) @p='celt/tests/test_unit_rotation$(EXEEXT)'; \ b='celt/tests/test_unit_rotation'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) celt/tests/test_unit_types.log: celt/tests/test_unit_types$(EXEEXT) @p='celt/tests/test_unit_types$(EXEEXT)'; \ b='celt/tests/test_unit_types'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) silk/tests/test_unit_LPC_inv_pred_gain.log: silk/tests/test_unit_LPC_inv_pred_gain$(EXEEXT) @p='silk/tests/test_unit_LPC_inv_pred_gain$(EXEEXT)'; \ b='silk/tests/test_unit_LPC_inv_pred_gain'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/test_opus_api.log: tests/test_opus_api$(EXEEXT) @p='tests/test_opus_api$(EXEEXT)'; \ b='tests/test_opus_api'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/test_opus_decode.log: tests/test_opus_decode$(EXEEXT) @p='tests/test_opus_decode$(EXEEXT)'; \ b='tests/test_opus_decode'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/test_opus_encode.log: tests/test_opus_encode$(EXEEXT) @p='tests/test_opus_encode$(EXEEXT)'; \ b='tests/test_opus_encode'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/test_opus_padding.log: tests/test_opus_padding$(EXEEXT) @p='tests/test_opus_padding$(EXEEXT)'; \ b='tests/test_opus_padding'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/test_opus_projection.log: tests/test_opus_projection$(EXEEXT) @p='tests/test_opus_projection$(EXEEXT)'; \ b='tests/test_opus_projection'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-tarZ: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__post_remove_distdir) dist dist-all: $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build/sub \ && ../../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-recursive all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(DATA) $(HEADERS) \ config.h all-local installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(m4datadir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(pkgincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -rm -f celt/$(DEPDIR)/$(am__dirstamp) -rm -f celt/$(am__dirstamp) -rm -f celt/arm/$(DEPDIR)/$(am__dirstamp) -rm -f celt/arm/$(am__dirstamp) -rm -f celt/tests/$(DEPDIR)/$(am__dirstamp) -rm -f celt/tests/$(am__dirstamp) -rm -f celt/x86/$(DEPDIR)/$(am__dirstamp) -rm -f celt/x86/$(am__dirstamp) -rm -f silk/$(DEPDIR)/$(am__dirstamp) -rm -f silk/$(am__dirstamp) -rm -f silk/arm/$(DEPDIR)/$(am__dirstamp) -rm -f silk/arm/$(am__dirstamp) -rm -f silk/fixed/$(DEPDIR)/$(am__dirstamp) -rm -f silk/fixed/$(am__dirstamp) -rm -f silk/fixed/arm/$(DEPDIR)/$(am__dirstamp) -rm -f silk/fixed/arm/$(am__dirstamp) -rm -f silk/fixed/x86/$(DEPDIR)/$(am__dirstamp) -rm -f silk/fixed/x86/$(am__dirstamp) -rm -f silk/float/$(DEPDIR)/$(am__dirstamp) -rm -f silk/float/$(am__dirstamp) -rm -f silk/tests/$(DEPDIR)/$(am__dirstamp) -rm -f silk/tests/$(am__dirstamp) -rm -f silk/x86/$(DEPDIR)/$(am__dirstamp) -rm -f silk/x86/$(am__dirstamp) -rm -f src/$(DEPDIR)/$(am__dirstamp) -rm -f src/$(am__dirstamp) -rm -f tests/$(DEPDIR)/$(am__dirstamp) -rm -f tests/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-recursive clean-am: clean-generic clean-libLTLIBRARIES clean-libtool clean-local \ clean-noinstLTLIBRARIES clean-noinstPROGRAMS mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf celt/$(DEPDIR) celt/arm/$(DEPDIR) celt/tests/$(DEPDIR) celt/x86/$(DEPDIR) silk/$(DEPDIR) silk/arm/$(DEPDIR) silk/fixed/$(DEPDIR) silk/fixed/arm/$(DEPDIR) silk/fixed/x86/$(DEPDIR) silk/float/$(DEPDIR) silk/tests/$(DEPDIR) silk/x86/$(DEPDIR) src/$(DEPDIR) tests/$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-hdr distclean-libtool distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-data-local install-m4dataDATA \ install-pkgconfigDATA install-pkgincludeHEADERS install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-libLTLIBRARIES install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -rf celt/$(DEPDIR) celt/arm/$(DEPDIR) celt/tests/$(DEPDIR) celt/x86/$(DEPDIR) silk/$(DEPDIR) silk/arm/$(DEPDIR) silk/fixed/$(DEPDIR) silk/fixed/arm/$(DEPDIR) silk/fixed/x86/$(DEPDIR) silk/float/$(DEPDIR) silk/tests/$(DEPDIR) silk/x86/$(DEPDIR) src/$(DEPDIR) tests/$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-libLTLIBRARIES uninstall-local \ uninstall-m4dataDATA uninstall-pkgconfigDATA \ uninstall-pkgincludeHEADERS .MAKE: $(am__recursive_targets) all check check-am install install-am \ install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am all-local \ am--refresh check check-TESTS check-am clean clean-cscope \ clean-generic clean-libLTLIBRARIES clean-libtool clean-local \ clean-noinstLTLIBRARIES clean-noinstPROGRAMS cscope \ cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ dist-gzip dist-hook dist-lzip dist-shar dist-tarZ dist-xz \ dist-zip distcheck distclean distclean-compile \ distclean-generic distclean-hdr distclean-libtool \ distclean-tags distcleancheck distdir distuninstallcheck dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-data-local install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am \ install-libLTLIBRARIES install-m4dataDATA install-man \ install-pdf install-pdf-am install-pkgconfigDATA \ install-pkgincludeHEADERS install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am recheck tags tags-am \ uninstall uninstall-am uninstall-libLTLIBRARIES \ uninstall-local uninstall-m4dataDATA uninstall-pkgconfigDATA \ uninstall-pkgincludeHEADERS .PRECIOUS: Makefile # Provide the full test output for failed tests when using the parallel # test suite (which is enabled by default with automake 1.13+). export VERBOSE = yes # Targets to build and install just the library without the docs opus check-opus install-opus: export NO_DOXYGEN = 1 opus: all check-opus: check install-opus: install # Or just the docs docs: ( cd doc && $(MAKE) $(AM_MAKEFLAGS) ) install-docs: ( cd doc && $(MAKE) $(AM_MAKEFLAGS) install ) # Or everything (by default) all-local: @[ -n "$(NO_DOXYGEN)" ] || ( cd doc && $(MAKE) $(AM_MAKEFLAGS) ) install-data-local: @[ -n "$(NO_DOXYGEN)" ] || ( cd doc && $(MAKE) $(AM_MAKEFLAGS) install ) clean-local: -( cd doc && $(MAKE) $(AM_MAKEFLAGS) clean ) uninstall-local: ( cd doc && $(MAKE) $(AM_MAKEFLAGS) uninstall ) # We check this every time make is run, with configure.ac being touched to # trigger an update of the build system files if update_version changes the # current PACKAGE_VERSION (or if package_version was modified manually by a # user with either AUTO_UPDATE=no or no update_version script present - the # latter being the normal case for tarball releases). # # We can't just add the package_version file to CONFIGURE_DEPENDENCIES since # simply running autoconf will not actually regenerate configure for us when # the content of that file changes (due to autoconf dependency checking not # knowing about that without us creating yet another file for it to include). # # The MAKECMDGOALS check is a gnu-make'ism, but will degrade 'gracefully' for # makes that don't support it. The only loss of functionality is not forcing # an update of package_version for `make dist` if AUTO_UPDATE=no, but that is # unlikely to be a real problem for any real user. $(top_srcdir)/configure.ac: force @case "$(MAKECMDGOALS)" in \ dist-hook) exit 0 ;; \ dist-* | dist | distcheck | distclean) _arg=release ;; \ esac; \ if ! $(top_srcdir)/update_version $$_arg 2> /dev/null; then \ if [ ! -e $(top_srcdir)/package_version ]; then \ echo 'PACKAGE_VERSION="unknown"' > $(top_srcdir)/package_version; \ fi; \ . $(top_srcdir)/package_version || exit 1; \ [ "$(PACKAGE_VERSION)" != "$$PACKAGE_VERSION" ] || exit 0; \ fi; \ touch $@ force: # Create a minimal package_version file when make dist is run. dist-hook: echo 'PACKAGE_VERSION="$(PACKAGE_VERSION)"' > $(top_distdir)/package_version .PHONY: opus check-opus install-opus docs install-docs # automake doesn't do dependency tracking for asm files, that I can tell $(CELT_SOURCES_ARM_ASM:%.s=%-gnu.S): celt/arm/armopts-gnu.S $(CELT_SOURCES_ARM_ASM:%.s=%-gnu.S): $(top_srcdir)/celt/arm/arm2gnu.pl # convert ARM asm to GNU as format %-gnu.S: $(top_srcdir)/%.s $(top_srcdir)/celt/arm/arm2gnu.pl @ARM2GNU_PARAMS@ < $< > $@ # For autoconf-modified sources (e.g., armopts.s) %-gnu.S: %.s $(top_srcdir)/celt/arm/arm2gnu.pl @ARM2GNU_PARAMS@ < $< > $@ @HAVE_SSE_TRUE@$(SSE_OBJ): CFLAGS += $(OPUS_X86_SSE_CFLAGS) @HAVE_SSE2_TRUE@$(SSE2_OBJ): CFLAGS += $(OPUS_X86_SSE2_CFLAGS) @HAVE_SSE4_1_TRUE@$(SSE4_1_OBJ): CFLAGS += $(OPUS_X86_SSE4_1_CFLAGS) @HAVE_ARM_NEON_INTR_TRUE@$(ARM_NEON_INTR_OBJ): CFLAGS += \ @HAVE_ARM_NEON_INTR_TRUE@ $(OPUS_ARM_NEON_INTR_CFLAGS) $(NE10_CFLAGS) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: jamulus-3.9.1+dfsg/libs/opus/opus_sources.cmake0000644000175000017500000000403414340334543020627 0ustar vimervimerinclude(opus_functions.cmake) get_opus_sources(SILK_SOURCES silk_sources.mk silk_sources) get_opus_sources(SILK_SOURCES_FLOAT silk_sources.mk silk_sources_float) get_opus_sources(SILK_SOURCES_FIXED silk_sources.mk silk_sources_fixed) get_opus_sources(SILK_SOURCES_SSE4_1 silk_sources.mk silk_sources_sse4_1) get_opus_sources(SILK_SOURCES_FIXED_SSE4_1 silk_sources.mk silk_sources_fixed_sse4_1) get_opus_sources(SILK_SOURCES_ARM_NEON_INTR silk_sources.mk silk_sources_arm_neon_intr) get_opus_sources(SILK_SOURCES_FIXED_ARM_NEON_INTR silk_sources.mk silk_sources_fixed_arm_neon_intr) get_opus_sources(OPUS_SOURCES opus_sources.mk opus_sources) get_opus_sources(OPUS_SOURCES_FLOAT opus_sources.mk opus_sources_float) get_opus_sources(CELT_SOURCES celt_sources.mk celt_sources) get_opus_sources(CELT_SOURCES_SSE celt_sources.mk celt_sources_sse) get_opus_sources(CELT_SOURCES_SSE2 celt_sources.mk celt_sources_sse2) get_opus_sources(CELT_SOURCES_SSE4_1 celt_sources.mk celt_sources_sse4_1) get_opus_sources(CELT_SOURCES_ARM celt_sources.mk celt_sources_arm) get_opus_sources(CELT_SOURCES_ARM_ASM celt_sources.mk celt_sources_arm_asm) get_opus_sources(CELT_AM_SOURCES_ARM_ASM celt_sources.mk celt_am_sources_arm_asm) get_opus_sources(CELT_SOURCES_ARM_NEON_INTR celt_sources.mk celt_sources_arm_neon_intr) get_opus_sources(CELT_SOURCES_ARM_NE10 celt_sources.mk celt_sources_arm_ne10) get_opus_sources(opus_demo_SOURCES Makefile.am opus_demo_sources) get_opus_sources(opus_custom_demo_SOURCES Makefile.am opus_custom_demo_sources) get_opus_sources(opus_compare_SOURCES Makefile.am opus_compare_sources) get_opus_sources(tests_test_opus_api_SOURCES Makefile.am test_opus_api_sources) get_opus_sources(tests_test_opus_encode_SOURCES Makefile.am test_opus_encode_sources) get_opus_sources(tests_test_opus_decode_SOURCES Makefile.am test_opus_decode_sources) get_opus_sources(tests_test_opus_padding_SOURCES Makefile.am test_opus_padding_sources) jamulus-3.9.1+dfsg/libs/opus/opus.m40000644000175000017500000000775714340334543016343 0ustar vimervimer# Configure paths for libopus # Gregory Maxwell 08-30-2012 # Shamelessly stolen from Jack Moffitt (libogg) who # Shamelessly stole from Owen Taylor and Manish Singh dnl XIPH_PATH_OPUS([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) dnl Test for libopus, and define OPUS_CFLAGS and OPUS_LIBS dnl AC_DEFUN([XIPH_PATH_OPUS], [dnl dnl Get the cflags and libraries dnl AC_ARG_WITH(opus,AC_HELP_STRING([--with-opus=PFX],[Prefix where opus is installed (optional)]), opus_prefix="$withval", opus_prefix="") AC_ARG_WITH(opus-libraries,AC_HELP_STRING([--with-opus-libraries=DIR],[Directory where the opus library is installed (optional)]), opus_libraries="$withval", opus_libraries="") AC_ARG_WITH(opus-includes,AC_HELP_STRING([--with-opus-includes=DIR],[Directory where the opus header files are installed (optional)]), opus_includes="$withval", opus_includes="") AC_ARG_ENABLE(opustest,AC_HELP_STRING([--disable-opustest],[Do not try to compile and run a test opus program]),, enable_opustest=yes) if test "x$opus_libraries" != "x" ; then OPUS_LIBS="-L$opus_libraries" elif test "x$opus_prefix" = "xno" || test "x$opus_prefix" = "xyes" ; then OPUS_LIBS="" elif test "x$opus_prefix" != "x" ; then OPUS_LIBS="-L$opus_prefix/lib" elif test "x$prefix" != "xNONE" ; then OPUS_LIBS="-L$prefix/lib" fi if test "x$opus_prefix" != "xno" ; then OPUS_LIBS="$OPUS_LIBS -lopus" fi if test "x$opus_includes" != "x" ; then OPUS_CFLAGS="-I$opus_includes" elif test "x$opus_prefix" = "xno" || test "x$opus_prefix" = "xyes" ; then OPUS_CFLAGS="" elif test "x$opus_prefix" != "x" ; then OPUS_CFLAGS="-I$opus_prefix/include" elif test "x$prefix" != "xNONE"; then OPUS_CFLAGS="-I$prefix/include" fi AC_MSG_CHECKING(for Opus) if test "x$opus_prefix" = "xno" ; then no_opus="disabled" enable_opustest="no" else no_opus="" fi if test "x$enable_opustest" = "xyes" ; then ac_save_CFLAGS="$CFLAGS" ac_save_LIBS="$LIBS" CFLAGS="$CFLAGS $OPUS_CFLAGS" LIBS="$LIBS $OPUS_LIBS" dnl dnl Now check if the installed Opus is sufficiently new. dnl rm -f conf.opustest AC_TRY_RUN([ #include #include #include #include int main () { system("touch conf.opustest"); return 0; } ],, no_opus=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) CFLAGS="$ac_save_CFLAGS" LIBS="$ac_save_LIBS" fi if test "x$no_opus" = "xdisabled" ; then AC_MSG_RESULT(no) ifelse([$2], , :, [$2]) elif test "x$no_opus" = "x" ; then AC_MSG_RESULT(yes) ifelse([$1], , :, [$1]) else AC_MSG_RESULT(no) if test -f conf.opustest ; then : else echo "*** Could not run Opus test program, checking why..." CFLAGS="$CFLAGS $OPUS_CFLAGS" LIBS="$LIBS $OPUS_LIBS" AC_TRY_LINK([ #include #include ], [ return 0; ], [ echo "*** The test program compiled, but did not run. This usually means" echo "*** that the run-time linker is not finding Opus or finding the wrong" echo "*** version of Opus. If it is not finding Opus, you'll need to set your" echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" echo "*** to the installed location Also, make sure you have run ldconfig if that" echo "*** is required on your system" echo "***" echo "*** If you have an old version installed, it is best to remove it, although" echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"], [ echo "*** The test program failed to compile or link. See the file config.log for the" echo "*** exact error that occurred. This usually means Opus was incorrectly installed" echo "*** or that you have moved Opus since it was installed." ]) CFLAGS="$ac_save_CFLAGS" LIBS="$ac_save_LIBS" fi OPUS_CFLAGS="" OPUS_LIBS="" ifelse([$2], , :, [$2]) fi AC_SUBST(OPUS_CFLAGS) AC_SUBST(OPUS_LIBS) rm -f conf.opustest ]) jamulus-3.9.1+dfsg/libs/opus/celt_headers.mk0000644000175000017500000000216714340334543020054 0ustar vimervimerCELT_HEAD = \ celt/arch.h \ celt/bands.h \ celt/celt.h \ celt/cpu_support.h \ include/opus_types.h \ include/opus_defines.h \ include/opus_custom.h \ celt/cwrs.h \ celt/ecintrin.h \ celt/entcode.h \ celt/entdec.h \ celt/entenc.h \ celt/fixed_debug.h \ celt/fixed_generic.h \ celt/float_cast.h \ celt/_kiss_fft_guts.h \ celt/kiss_fft.h \ celt/laplace.h \ celt/mathops.h \ celt/mdct.h \ celt/mfrngcod.h \ celt/modes.h \ celt/os_support.h \ celt/pitch.h \ celt/celt_lpc.h \ celt/x86/celt_lpc_sse.h \ celt/quant_bands.h \ celt/rate.h \ celt/stack_alloc.h \ celt/vq.h \ celt/static_modes_float.h \ celt/static_modes_fixed.h \ celt/static_modes_float_arm_ne10.h \ celt/static_modes_fixed_arm_ne10.h \ celt/arm/armcpu.h \ celt/arm/fixed_armv4.h \ celt/arm/fixed_armv5e.h \ celt/arm/fixed_arm64.h \ celt/arm/kiss_fft_armv4.h \ celt/arm/kiss_fft_armv5e.h \ celt/arm/pitch_arm.h \ celt/arm/fft_arm.h \ celt/arm/mdct_arm.h \ celt/mips/celt_mipsr1.h \ celt/mips/fixed_generic_mipsr1.h \ celt/mips/kiss_fft_mipsr1.h \ celt/mips/mdct_mipsr1.h \ celt/mips/pitch_mipsr1.h \ celt/mips/vq_mipsr1.h \ celt/x86/pitch_sse.h \ celt/x86/vq_sse.h \ celt/x86/x86cpu.h jamulus-3.9.1+dfsg/.editorconfig0000644000175000017500000000105414340334543015631 0ustar vimervimer# See https://editorconfig.org/ # This file is used by editors, but also by automation such as `shfmt`. # This is the top-most .editorconfig file root = true [*] end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true [*.{cpp,h,mm,nsi,pro,ps1,py,sh}] indent_style = space indent_size = 4 [*.{yaml,yml}] indent_style = space indent_size = 2 [*.sh] shell_variant = bash binary_next_line = false switch_case_indent = true space_redirects = true keep_padding = true function_next_line = false [libs/**] ignore = true jamulus-3.9.1+dfsg/APPLEAPPSTORE.LICENCE.WAIVER0000644000175000017500000000360714340334543017161 0ustar vimervimerThe inclusion of Jamulus in the App Store is the only practical way of allowing its use on Apple mobile devices. Although Apple will assert the GPL as the "Custom EULA” for Jamulus, their T&Cs impose some extra conditions. This act of addition when distributing the software is not allowed under the GPL. However, Apple's terms apply to those who obtain Jamulus from the App Store. It does not affect the copyright holders' assertion of the GPL, or otherwise affect the Jamulus project: https://www.apple.com/legal/internet-services/itunes/us/terms.html Moreover, there are no provisions in the Apple terms and conditions that we identify as being unacceptable to the copyright holders, or to the Jamulus project overall. Anyone using App Store services would already be accepting Apple’s terms for their use of any service they are obtaining. This includes being unable to re-distribute the software. The copyright holders do not want a legal conflict to prevent the distribution of Jamulus on the Apple App Store. Therefore, and in consideration of the above points, we the copyright holders in Jamulus hereby waive any objections to the fact that Apple would be violating the GPL in making Jamulus available on the App Store. Apple reserves the right to change its terms. If at any time they do that in a way that we find unacceptable, we will remove Jamulus from the App Store. This waiver applies solely to the specific case of obtaining Jamulus from the Apple App Store. All other distribution methods must fully comply with the terms of the GPL. Dissent Any Jamulus contributor who does not wish their code to be published via the App Store must ensure their code is not so published. This can be achieved for example by removing their code from the Jamulus source, or by using technical measures (e.g. #ifdef) to ensure the code in question will not be compiled and included for App Store releases. [ends] jamulus-3.9.1+dfsg/README.md0000644000175000017500000000567314340334543014446 0ustar vimervimer[![Homepage picture](https://github.com/jamulussoftware/jamuluswebsite/blob/release/assets/img/jamulusbannersmall.png)](https://jamulus.io) [![Auto-Build](https://github.com/jamulussoftware/jamulus/actions/workflows/autobuild.yml/badge.svg)](https://github.com/jamulussoftware/jamulus/actions/workflows/autobuild.yml) # Jamulus - Internet Jam Session Software Jamulus enables musicians to perform in real-time together over the internet. A Jamulus server collects the incoming audio data from each Jamulus client, mixes that data and then sends that mix back to each client. Jamulus can support large numbers of clients with minimal latency and modest bandwidth requirements. Jamulus is [**free and open source software**](https://www.gnu.org/philosophy/free-sw.en.html) (FOSS) licensed under the [GPL](https://www.gnu.org/licenses/old-licenses/gpl-2.0.html) and runs under **Windows** ([ASIO](https://www.steinberg.net) or [JACK](https://jackaudio.org)), **MacOS** ([Core Audio](https://developer.apple.com/documentation/coreaudio)) and **Linux** ([JACK](https://jackaudio.org)). It is based on the [Qt framework](https://www.qt.io) and uses the [OPUS](https://www.opus-codec.org/) audio codec. ## Installation [Please see the Getting Started page](https://jamulus.io/wiki/Getting-Started) containing instructions for installing and using Jamulus for your platform. ## Help Official documentation for Jamulus is on the [Jamulus homepage](https://jamulus.io) See also the [discussion forums](https://github.com/jamulussoftware/jamulus/discussions). If you have issues, feel free to ask for help there. Bugs and feature requests can be [reported here](https://github.com/jamulussoftware/jamulus/issues) ## Compilation [Please see these instructions](COMPILING.md) ## Contributing See the [contributing instructions](CONTRIBUTING.md) ## Acknowledgements Jamulus contains code from different sources (see also [COPYING](COPYING)). The developers wish to thank the maintainers of these projects for making their efforts available to us under their respective licences: * Qt cross-platform application framework: [qt.io](https://www.qt.io) * Opus Interactive Audio Codec: [opus-codec.org](https://www.opus-codec.org/) * Audio reverberation code: by Perry R. Cook and Gary P. Scavone, 1995 - 2004 (taken from "The Synthesis ToolKit in C++ (STK)"): [ccrma.stanford.edu/software/stk/](https://ccrma.stanford.edu/software/stk/) * Some pixmaps are from the Open Clip Art Library (OCAL): [openclipart.com](https://openclipart.org/) * Country flag icons from Mark James: [famfamfam.com](http://www.famfamfam.com) * ASIO is a trademark and software of Steinberg Media Technologies GmbH We would also like to acknowledge the contributors listed in the [Github Contributors list](https://github.com/jamulussoftware/jamulus/graphs/contributors).