[
  {
    "path": ".github/workflows/rust.yml",
    "content": "name: Rust\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\nenv:\n  CARGO_TERM_COLOR: always\n\njobs:\n  build:\n\n    runs-on: ubuntu-latest\n\n    steps:\n    - uses: actions/checkout@v2\n    # - name: Load loopback driver\n    #  run: sudo modprobe snd-aloop\n    - name: Install dependencies 1\n      run: sudo apt-get update\n    - name: Install dependencies 2  \n      run: sudo apt-get install --no-install-recommends -y libasound2-dev      \n    - name: Build\n      run: cargo check --verbose --all\n    - name: Build no-std\n      run: cargo check --no-default-features --verbose --all\n    # - name: Run tests\n    #  run: cargo test --verbose --all\n"
  },
  {
    "path": ".gitignore",
    "content": "target/\n**/*.rs.bk\nCargo.lock\n.idea/\n"
  },
  {
    "path": "Cargo.toml",
    "content": "[package]\nname = \"alsa\"\nversion = \"0.11.0\"\nauthors = [\"David Henningsson <coding@diwic.se>\"]\n\ndescription = \"Thin but safe wrappers for ALSA (Linux sound API)\"\nrepository = \"https://github.com/diwic/alsa-rs\"\ndocumentation = \"http://docs.rs/alsa\"\nkeywords = [\"ALSA\", \"audio\", \"sound\"]\nlicense = \"Apache-2.0/MIT\"\ncategories = [\"multimedia::audio\", \"api-bindings\"]\nreadme = \"README.md\"\nedition = \"2021\"\ninclude = [\"README.md\", \"LICENSE-*\", \"Cargo.toml\", \"src/\"]\nexclude = [\"examples/\"]\n\n[dependencies]\nlibc = \"0.2.178\"\nalsa-sys = \"0.4.0\"\nbitflags = \"2.4.0\"\ncfg-if = \"1.0\"\n\n[dev-dependencies]\nanyhow = \"1.0\"\n\n[badges]\nis-it-maintained-issue-resolution = { repository = \"diwic/alsa-rs\" }\nis-it-maintained-open-issues = { repository = \"diwic/alsa-rs\" }\n\n[features]\ndefault = [\"std\"]\nstd = []\n\n[lints.rust]\nmissing-debug-implementations = \"warn\"\n"
  },
  {
    "path": "LICENSE-APACHE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n"
  },
  {
    "path": "LICENSE-MIT",
    "content": "MIT License\n\nCopyright (c) 2015-2021 David Henningsson, and other contributors.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "ALSA bindings for Rust\n=======================\n\nThin but safe wrappers for [ALSA](https://alsa-project.org), the most\ncommon API for accessing audio devices on Linux.\n\n[![crates.io](https://img.shields.io/crates/v/alsa.svg)](https://crates.io/crates/alsa)\n[![API documentation](https://docs.rs/alsa/badge.svg)](https://docs.rs/alsa)\n[![license](https://img.shields.io/crates/l/alsa.svg)](https://crates.io/crates/alsa)\n\nThe ALSA API is rather big, so everything is not covered yet, but expect the following to work:\n\n * Audio Playback (example in `pcm` module docs)\n\n * Audio Recording\n\n * Mixer controls\n\n * HCtl API (jack detection example in `hctl` module docs)\n\n * Raw midi\n\n * Midi sequencer (most of it)\n\n * Ctl API\n\n * Device name hints (example in `device_name` module docs)\n\n * Enumerations of all of the above\n\n * Poll and/or wait for all of the above\n\nThe following is not yet implemented (mostly because nobody asked for them) :\n\n * Separate timer API (snd_timer_*)\n\n * Config API (snd_config_*)\n\n * Plug-in API\n\nQuickstart guide / API design:\n\n * Most functions map 1-to-1 to alsa-lib functions, e g, `ctl::CardInfo::get_id()` is a wrapper around\n   `snd_ctl_card_info_get_id` and the [alsa-lib documentation](https://www.alsa-project.org/alsa-doc/alsa-lib/)\n   can be consulted for additional information.\n\n * Structs are RAII and closed/freed on drop, e g, when a `PCM` struct is dropped, `snd_pcm_close` is called.\n\n * To read and write buffers, call the `io_*` methods. It will return a separate struct from which you can\n   read or write, and which can also be used for mmap (if supported by the driver).\n\n * Error handling - most alsa-lib functions can return errors, so the return value from these is a `Result`.\n\n * Enumeration of cards, devices etc is done through structs implementing `Iterator`.\n\n * Many structs implement `poll::Descriptors`, to combine with your favorite async framework.\n   Or just use `wait` if you don't need non-blocking functionality.\n   \nNotes:\n\n * To run the tests successfully, there must be a \"default\" sound card configured. This is usually not a problem when running on normal hardware, but some CI systems, docker images etc, might not have that configured by default. \n\n"
  },
  {
    "path": "examples/ctl_list.rs",
    "content": "//! Example that enumerates controls for a device.\n\nuse alsa::Card;\nuse alsa::card::Iter;\nuse alsa::ctl::Ctl;\nuse alsa::Error;\n\nfn list_controls_for_card(card: &Card) -> Result<(), Error>{\n    // Get a Ctl for the card\n    let ctl_id = format!(\"hw:{}\", card.get_index());\n    let ctl = Ctl::new(&ctl_id, false)?;\n\n    println!(\"card {}\", ctl_id);\n\n    // Query the elements\n    let elems = ctl.elem_list()?;\n    for list_index in 0..elems.get_used() {\n        let numeric_id = elems.get_numid(list_index)?;\n        let name = elems.get_name(list_index)?;\n        println!(\"  {}: {}\", numeric_id, name);\n    }\n\n    Ok(())\n}\n\nfn main() {\n    let cards = Iter::new();\n    cards.for_each(|card| if let Ok(c) = card { list_controls_for_card(&c).unwrap_or_default() });\n}\n"
  },
  {
    "path": "examples/midi_enumerate.rs",
    "content": "//! Example that enumerates hardware and PCM devices.\n\nuse alsa::Card;\nuse alsa::card::Iter as CardIter;\nuse alsa::ctl::{Ctl};\nuse alsa::{Error};\nuse alsa::rawmidi::Iter as MidiIter;\n\nuse alsa::seq::{ClientIter, Seq, PortIter, PortSubscribeIter, QuerySubsType, Addr};\n    \npub fn list_rawmidi_for_card(card: &Card) -> Result<(), Error> {\n    // Get a Ctl for the card\n    let ctl_id = format!(\"hw:{}\", card.get_index());\n    let ctl = Ctl::new(&ctl_id, false)?;\n\n    // Read card id and name\n    let cardinfo = ctl.card_info()?;\n    let card_id = cardinfo.get_id()?;\n    let card_name = cardinfo.get_name()?;\n    let subdevices:Vec<_> = MidiIter::new(&ctl).filter_map(|d| d.ok()).collect();\n    if !subdevices.is_empty() {\n        println!(\"card_id: {:?} card_name {:?} \", card_id, card_name);\n        for info in &subdevices {\n            println!(\"subdevice: {:?} {:?} {:?}\", info.get_subdevice(), info.get_subdevice_name().unwrap(), info.get_stream());\n        }\n        println!();\n\n    }\n    Ok(())\n}\n\npub fn list_rawmidi_devices() {\n    let cards = CardIter::new();\n    cards.for_each(|card| if let Ok(c) = card { list_rawmidi_for_card(&c).unwrap_or_default() });\n}\n\npub fn list_sequencer_port() {\n    let seq = Seq::open(None, None, false).unwrap();\n    println!(\"Seq client {:?}\", seq.client_id().unwrap());\n    println!();\n\n    seq.set_client_name(&c\"ALSA_RS_EXAMPLE\").unwrap();\n    for client in ClientIter::new(&seq) {\n        println!(\"Client {:?} {:?}\", client.get_client(), client.get_name().unwrap());\n        for port in PortIter::new(&seq, client.get_client()) {\n            println!(\"  Port {:?} {:?}\", port.get_port(), port.get_name().unwrap());\n            for sub in PortSubscribeIter::new(&seq, Addr { client: client.get_client(), port: port.get_port() } , QuerySubsType::READ) {\n                println!(\"    READ {:?}\", sub.get_dest());\n            }\n            for sub in PortSubscribeIter::new(&seq, Addr { client: client.get_client(), port: port.get_port() } , QuerySubsType::WRITE) {\n                println!(\"    WRITE {:?}\", sub.get_dest());\n            }\n        }\n        println!();\n    }\n}\n\nfn main() {\n    println!(\"\\n--- Raw MIDI devices ---\");\n    list_rawmidi_devices();\n    println!(\"\\n--- MIDI Sequencer Clients, Ports and Subscribers ---\");\n    list_sequencer_port();\n}"
  },
  {
    "path": "examples/pcm_enumerate.rs",
    "content": "//! Example that enumerates hardware and PCM devices.\n\nuse alsa::Card;\nuse alsa::card::Iter;\nuse alsa::device_name::HintIter;\nuse alsa::ctl::{Ctl, DeviceIter};\nuse alsa::{Direction, Error};\n\n// Each card can have multiple devices and subdevices, list them all\nfn list_devices_for_card(card: &Card, direction: Direction) -> Result<(), Error>{\n    // Get a Ctl for the card\n    let ctl_id = format!(\"hw:{}\", card.get_index());\n    let ctl = Ctl::new(&ctl_id, false)?;\n\n    // Read card id and name\n    let cardinfo = ctl.card_info()?;\n    let card_id = cardinfo.get_id()?;\n    let card_name = cardinfo.get_name()?;\n    for device in DeviceIter::new(&ctl) {\n        // Read info from Ctl\n        let pcm_info = match ctl.pcm_info(device as u32, 0, direction) {\n            // If pcm_info returns ENOENT, there are no streams in this direction\n            Err(x) if x.errno() == libc::ENOENT => continue,\n            x => x,\n        }?;\n\n        // Read PCM name\n        let pcm_name = pcm_info.get_name()?.to_string();\n\n        println!(\"card: {:<2} id: {:<10} device: {:<2} card name: '{}' PCM name: '{}'\", card.get_index(), card_id, device, card_name, pcm_name);\n\n        // Loop through subdevices and get their names\n        let subdevs = pcm_info.get_subdevices_count();\n        for subdev in 0..subdevs {\n            // Get subdevice name\n            let pcm_info = ctl.pcm_info(device as u32, subdev, direction)?;\n            let subdev_name = pcm_info.get_subdevice_name()?;\n\n            println!(\"  subdevice: {:<2} name: '{}'\", subdev, subdev_name);\n        }\n    }\n\n    Ok(())\n}\n\npub fn list_hw_devices(direction: Direction) {\n    let cards = Iter::new();\n    cards.for_each(|card| if let Ok(c) = card { list_devices_for_card(&c, direction).unwrap_or_default() });\n}\n\npub fn list_pcm_devices(direction: Direction) {\n    let hints = HintIter::new_str(None, \"pcm\").unwrap();\n    for hint in hints {\n        // When Direction is None it means that both the PCM supports both playback and capture\n        if hint.name.is_some() && hint.desc.is_some() && (hint.direction.is_none() || hint.direction.map(|dir| dir == direction).unwrap_or_default()) {\n            println!(\"name: {:<35} desc: {:?}\", hint.name.unwrap(), hint.desc.unwrap());\n        }\n    }\n}\n\nfn main() {\n    println!(\"\\n--- Hardware playback devices ---\");\n    list_hw_devices(Direction::Playback);\n    println!(\"\\n--- Hardware capture devices ---\");\n    list_hw_devices(Direction::Capture);\n\n    println!(\"\\n--- PCM playback devices ---\");\n    list_pcm_devices(Direction::Playback);\n    println!(\"\\n--- PCM capture devices ---\");\n    list_pcm_devices(Direction::Capture);\n}"
  },
  {
    "path": "examples/pcm_record.rs",
    "content": "//! Example that continously reads data and displays its RMS volume.\n\nuse alsa::pcm::*;\nuse alsa::{Direction, ValueOr, Error};\n\nfn start_capture(device: &str) -> Result<PCM, Error> {\n    let pcm = PCM::new(device, Direction::Capture, false)?;\n    {\n        // For this example, we assume 44100Hz, one channel, 16 bit audio.\n        let hwp = HwParams::any(&pcm)?;\n        hwp.set_channels(1)?;\n        hwp.set_rate(44100, ValueOr::Nearest)?;\n        hwp.set_format(Format::s16())?;\n        hwp.set_access(Access::RWInterleaved)?;\n        pcm.hw_params(&hwp)?;\n    }\n    pcm.start()?;\n    Ok(pcm)\n}\n\n// Calculates RMS (root mean square) as a way to determine volume\nfn rms(buf: &[i16]) -> f64 {\n    if buf.len() == 0 { return 0f64; }\n    let mut sum = 0f64;\n    for &x in buf {\n        sum += (x as f64) * (x as f64);\n    }\n    let r = (sum / (buf.len() as f64)).sqrt();\n    // Convert value to decibels\n    20.0 * (r / (i16::MAX as f64)).log10()\n}\n\n\nfn read_loop(pcm: &PCM) -> Result<(), Error> {\n    let io = pcm.io_i16()?;\n    let mut buf = [0i16; 8192];\n    loop {\n        // Block while waiting for 8192 samples to be read from the device.\n        assert_eq!(io.readi(&mut buf)?, buf.len());\n        let r = rms(&buf);\n        println!(\"RMS: {:.1} dB\", r);\n    }\n}\n\nfn main() {\n    // The \"default\" device is usually directed to the sound server process,\n    // e g PulseAudio or PipeWire.\n    let capture = start_capture(\"default\").unwrap();\n    read_loop(&capture).unwrap();\n}"
  },
  {
    "path": "examples/trigger_hstamp.rs",
    "content": "use alsa::{\n    pcm::{Access, Format, HwParams},\n    Direction, ValueOr, PCM,\n};\n\nuse anyhow::Result; // Sorry for the extra dep :D\n\nfn main() -> Result<()> {\n    // Also tried specifying the hw card name, but it doesn't matter\n    let pcm = PCM::new(\"default\", Direction::Capture, false)?;\n\n    {\n        let hwp = HwParams::any(&pcm)?;\n        hwp.set_channels(2)?;\n        hwp.set_rate(16000, ValueOr::Nearest)?;\n        hwp.set_format(Format::s32())?;\n        hwp.set_access(Access::RWInterleaved)?;\n        pcm.hw_params(&hwp)?;\n    }\n\n    {\n        let swp = pcm.sw_params_current()?;\n        swp.set_tstamp_mode(true)?;\n        swp.set_tstamp_type(alsa::pcm::TstampType::Monotonic)?; // Tried with every kind of timestamp type, it doesn't matter\n        pcm.sw_params(&swp)?;\n    }\n\n    let mut buffer = [0i32; 8000];\n\n    pcm.start()?;\n\n    let pcm_io = pcm.io_i32()?;\n\n    loop {\n        // Debug: check if timestamps are enabled (it returns true as expected)\n        let params = pcm.sw_params_current()?;\n        println!(\"timestamps enabled: {}\", params.get_tstamp_mode()?);\n\n        let read_bytes = pcm_io.readi(&mut buffer)?;\n        assert!(read_bytes > 0);\n\n        // I've also tried to construct the status object just once outside the loop but nothing changes\n        let status = pcm.status()?;\n        \n        dbg!(&status);\n\n        // The following \"htstamp\" functions all wrongly return a timespec struct with 0 seconds and 0 nanoseconds\n        // when using Rust >=1.88 (even tried on Nightly to check if it worked on there)\n        let audio_htstamp = status.get_audio_htstamp();\n        println!(\"{} {}\", audio_htstamp.tv_sec, audio_htstamp.tv_nsec);\n\n        let htstamp = status.get_htstamp();\n        println!(\"{} {}\", htstamp.tv_sec, htstamp.tv_nsec);\n\n        let trigger_htstamp = status.get_trigger_htstamp();\n        println!(\"{} {}\", trigger_htstamp.tv_sec, trigger_htstamp.tv_nsec);\n    }\n}\n"
  },
  {
    "path": "src/card.rs",
    "content": "//! Sound card enumeration\nuse libc::{c_int, c_char};\nuse super::error::*;\nuse crate::alsa;\nuse core::ffi::CStr;\nuse ::alloc::string::String;\n\n/// An ALSA sound card, uniquely identified by its index.\n#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]\npub struct Card(c_int);\n\n/// Iterate over existing sound cards.\n#[derive(Debug)]\npub struct Iter(c_int);\n\nimpl Iter {\n    pub fn new() -> Iter { Iter(-1) }\n}\n\nimpl Iterator for Iter {\n    type Item = Result<Card>;\n\n    fn next(&mut self) -> Option<Result<Card>> {\n        match acheck!(snd_card_next(&mut self.0)) {\n            Ok(_) if self.0 == -1 => None,\n            Ok(_) => Some(Ok(Card(self.0))),\n            Err(e) => Some(Err(e)),\n        }\n    }\n}\n\nimpl Card {\n    pub fn new(index: c_int) -> Card { Card(index) }\n    pub fn from_str(s: &CStr) -> Result<Card> {\n        acheck!(snd_card_get_index(s.as_ptr())).map(Card)\n    }\n    pub fn get_name(&self) -> Result<String> {\n        let mut c: *mut c_char = ::core::ptr::null_mut();\n        acheck!(snd_card_get_name(self.0, &mut c))\n            .and_then(|_| from_alloc(\"snd_card_get_name\", c)) \n    }\n    pub fn get_longname(&self) -> Result<String> {\n        let mut c: *mut c_char = ::core::ptr::null_mut();\n        acheck!(snd_card_get_longname(self.0, &mut c))\n            .and_then(|_| from_alloc(\"snd_card_get_longname\", c)) \n    }\n\n    pub fn get_index(&self) -> c_int { self.0 }\n}\n\n#[test]\nfn print_cards() {\n    extern crate std;\n    for a in Iter::new().map(|a| a.unwrap()) {\n        std::println!(\"Card #{}: {} ({})\", a.get_index(), a.get_name().unwrap(), a.get_longname().unwrap())\n    }\n}\n"
  },
  {
    "path": "src/chmap.rs",
    "content": "use crate::alsa;\nuse core::{fmt, mem, slice};\nuse super::error::*;\nuse ::alloc::vec::Vec;\nuse ::alloc::vec;\n\nalsa_enum!(\n    /// [SND_CHMAP_TYPE_xxx](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html) constants\n    ChmapType, ALL_CHMAP_TYPES[4],\n\n    None = SND_CHMAP_TYPE_NONE,\n    Fixed = SND_CHMAP_TYPE_FIXED,\n    Var = SND_CHMAP_TYPE_VAR,\n    Paired = SND_CHMAP_TYPE_PAIRED,\n);\n\nalsa_enum!(\n    /// [SND_CHMAP_xxx](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html) constants\n    ChmapPosition, ALL_CHMAP_POSITIONS[37],\n\n    Unknown = SND_CHMAP_UNKNOWN,\n    NA = SND_CHMAP_NA,\n    Mono = SND_CHMAP_MONO,\n    FL = SND_CHMAP_FL,\n    FR = SND_CHMAP_FR,\n    RL = SND_CHMAP_RL,\n    RR = SND_CHMAP_RR,\n    FC = SND_CHMAP_FC,\n    LFE = SND_CHMAP_LFE,\n    SL = SND_CHMAP_SL,\n    SR = SND_CHMAP_SR,\n    RC = SND_CHMAP_RC,\n    FLC = SND_CHMAP_FLC,\n    FRC = SND_CHMAP_FRC,\n    RLC = SND_CHMAP_RLC,\n    RRC = SND_CHMAP_RRC,\n    FLW = SND_CHMAP_FLW,\n    FRW = SND_CHMAP_FRW,\n    FLH = SND_CHMAP_FLH,\n    FCH = SND_CHMAP_FCH,\n    FRH = SND_CHMAP_FRH,\n    TC = SND_CHMAP_TC,\n    TFL = SND_CHMAP_TFL,\n    TFR = SND_CHMAP_TFR,\n    TFC = SND_CHMAP_TFC,\n    TRL = SND_CHMAP_TRL,\n    TRR = SND_CHMAP_TRR,\n    TRC = SND_CHMAP_TRC,\n    TFLC = SND_CHMAP_TFLC,\n    TFRC = SND_CHMAP_TFRC,\n    TSL = SND_CHMAP_TSL,\n    TSR = SND_CHMAP_TSR,\n    LLFE = SND_CHMAP_LLFE,\n    RLFE = SND_CHMAP_RLFE,\n    BC = SND_CHMAP_BC,\n    BLC = SND_CHMAP_BLC,\n    BRC = SND_CHMAP_BRC,\n);\n\nimpl fmt::Display for ChmapPosition {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        let s = unsafe { alsa::snd_pcm_chmap_long_name(*self as libc::c_uint) };\n        let s = from_const(\"snd_pcm_chmap_long_name\", s)?;\n        write!(f, \"{}\", s)\n    }\n}\n\n\n/// [snd_pcm_chmap_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html) wrapper\n#[derive(Debug)]\npub struct Chmap(*mut alsa::snd_pcm_chmap_t, bool);\n\nimpl Drop for Chmap {\n    fn drop(&mut self) { if self.1 { unsafe { libc::free(self.0 as *mut libc::c_void) }}}\n}\n\nimpl Chmap {\n    fn set_channels(&mut self, c: libc::c_uint) { unsafe { (*self.0) .channels = c }}\n    fn as_slice_mut(&mut self) -> &mut [libc::c_uint] {\n        unsafe { slice::from_raw_parts_mut((*self.0).pos.as_mut_ptr(), (*self.0).channels as usize) }\n    }\n    fn as_slice(&self) -> &[libc::c_uint] {\n        unsafe { slice::from_raw_parts((*self.0).pos.as_ptr(), (*self.0).channels as usize) }\n    }\n}\n\nimpl fmt::Display for Chmap {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        let mut buf: Vec<libc::c_char> = vec![0; 512];\n        acheck!(snd_pcm_chmap_print(self.0, buf.len() as libc::size_t, buf.as_mut_ptr()))?;\n        let s = from_const(\"snd_pcm_chmap_print\", buf.as_mut_ptr())?;\n        write!(f, \"{}\", s)\n    }\n}\n\nimpl<'a> From<&'a [ChmapPosition]> for Chmap {\n    fn from(a: &'a [ChmapPosition]) -> Chmap {\n        let p = unsafe { libc::malloc((mem::size_of::<alsa::snd_pcm_chmap_t>() + mem::size_of::<libc::c_uint>() * a.len()) as libc::size_t) };\n        if p.is_null() { panic!(\"Out of memory\") }\n        let mut r = Chmap(p as *mut alsa::snd_pcm_chmap_t, true);\n        r.set_channels(a.len() as libc::c_uint);\n        for (i,v) in r.as_slice_mut().iter_mut().enumerate() { *v = a[i] as libc::c_uint }\n        r\n    }\n}\n\nimpl<'a> From<&'a Chmap> for Vec<ChmapPosition> {\n    fn from(a: &'a Chmap) -> Vec<ChmapPosition> {\n        a.as_slice().iter().map(|&v| ChmapPosition::from_c_int(v as libc::c_int, \"\").unwrap()).collect()\n    }\n}\n\npub fn chmap_new(a: *mut alsa::snd_pcm_chmap_t) -> Chmap { Chmap(a, true) }\npub fn chmap_handle(a: &Chmap) -> *mut alsa::snd_pcm_chmap_t { a.0 }\n\n\n/// Iterator over available channel maps - see [snd_pcm_chmap_query_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html)\n#[derive(Debug)]\npub struct ChmapsQuery(*mut *mut alsa::snd_pcm_chmap_query_t, isize);\n\nimpl Drop for ChmapsQuery {\n    fn drop(&mut self) { unsafe { alsa::snd_pcm_free_chmaps(self.0) }}\n}\n\npub fn chmaps_query_new(a: *mut *mut alsa::snd_pcm_chmap_query_t) -> ChmapsQuery { ChmapsQuery(a, 0) }\n\nimpl Iterator for ChmapsQuery {\n    type Item = (ChmapType, Chmap);\n    fn next(&mut self) -> Option<Self::Item> {\n        if self.0.is_null() { return None; }\n        let p = unsafe { *self.0.offset(self.1) };\n        if p.is_null() { return None; }\n        self.1 += 1;\n        let t = ChmapType::from_c_int(unsafe { (*p).type_ } as libc::c_int, \"snd_pcm_query_chmaps\").unwrap();\n        let m = Chmap(unsafe { &mut (*p).map }, false);\n        Some((t, m))\n    }\n}\n\n\n#[test]\nfn chmap_for_first_pcm() {\n    extern crate std;\n    use super::*;\n    use ::alloc::ffi::CString;\n    use crate::device_name::HintIter;\n\n    use crate::Output;\n\n    let output = Output::local_error_handler().unwrap();\n\n    let i = HintIter::new(None, &*CString::new(\"pcm\").unwrap()).unwrap();\n    for p in i.map(|n| n.name.unwrap()) {\n        std::println!(\"Chmaps for {:?}:\", p);\n        match PCM::open(&CString::new(p).unwrap(),  Direction::Playback, false) {\n            Ok(a) => for c in a.query_chmaps() {\n               std::println!(\"  {:?}, {}\", c.0, c.1);\n            },\n            Err(a) => std::println!(\"  {}\", a) // It's okay to have entries in the name hint array that can't be opened\n        }\n    }\n\n    output.borrow_mut().buffer_string(|buf| {\n        let str = CString::new(buf).unwrap();\n        std::println!(\"Errors:\\n{}\", str.to_str().unwrap());\n    });\n\n}\n"
  },
  {
    "path": "src/config.rs",
    "content": "//! Configuration file API\n//!\n//! For now, just contains functions regarding the global configuration\n//! stored as a cache inside alsa-lib. Calling `update_free_global` might help\n//! against valgrind reporting memory leaks.\nuse crate::{alsa};\nuse super::error::*;\nuse super::Output;\nuse core::ptr;\n\npub fn update() -> Result<bool> {\n\tacheck!(snd_config_update()).map(|x| x != 0)\n}\n\npub fn update_free_global() -> Result<()> {\n\tacheck!(snd_config_update_free_global()).map(|_| ())\n}\n\n/// [snd_config_t](https://alsa-project.org/alsa-doc/alsa-lib/group___config.html) wrapper\n#[derive(Debug)]\npub struct Config(*mut alsa::snd_config_t);\n\nimpl Drop for Config {\n    fn drop(&mut self) { unsafe { alsa::snd_config_unref(self.0) }; }\n}\n\npub fn update_ref() -> Result<Config> {\n\tlet mut top = ptr::null_mut();\n\tacheck!(snd_config_update_ref(&mut top)).map(|_| Config(top))\n}\n\nimpl Config {\n    pub fn save(&self, o: &mut Output) -> Result<()> {\n        acheck!(snd_config_save(self.0, super::io::output_handle(o))).map(|_| ())\n    }\n}\n\n#[test]\nfn config_save() {\n    extern crate std;\n\tlet c = update_ref().unwrap();\n    let mut outp = Output::buffer_open().unwrap();\n\tc.save(&mut outp).unwrap();\n    std::println!(\"== Config save ==\\n{}\", outp);\n}\n"
  },
  {
    "path": "src/ctl_int.rs",
    "content": "\nuse crate::alsa;\nuse super::pcm::Info;\nuse core::ffi::CStr;\nuse ::alloc::ffi::CString;\nuse super::Direction;\nuse super::error::*;\nuse super::mixer::MilliBel;\nuse super::Round;\nuse core::{ptr, mem, fmt, cmp};\nuse crate::{Card, poll};\nuse core::cell::UnsafeCell;\nuse libc::{c_uint, c_void, size_t, c_long, c_int, pollfd, c_short};\n\n/// We prefer not to allocate for every ElemId, ElemInfo or ElemValue.\n/// But we don't know if these will increase in the future or on other platforms.\n/// Unfortunately, Rust does not support alloca, so hard-code the sizes for now.\n\nconst ELEM_ID_SIZE: usize = 64;\n// const ELEM_VALUE_SIZE: usize = 1224;\n// const ELEM_INFO_SIZE: usize = 272;\n\n/// [snd_ctl_pcm_next_device](https://www.alsa-project.org/alsa-doc/alsa-lib/control_8c.html#accbb0be6e5ca7361ffec0ea304ed1b05) wrapper.\n/// Iterate over devices of a card.\n#[derive(Debug)]\npub struct DeviceIter<'a>(&'a Ctl, c_int);\n\nimpl<'a> DeviceIter<'a>{\n    pub fn new(ctl: &'a Ctl) -> DeviceIter<'a> {\n        DeviceIter(ctl, -1)\n    }\n}\n\nimpl<'a> Iterator for DeviceIter<'a> {\n    type Item = c_int;\n\n    fn next(&mut self) -> Option<c_int> {\n        match acheck!(snd_ctl_pcm_next_device(self.0.0, &mut self.1)) {\n            Ok(_) if self.1 == -1 => None,\n            Ok(_) => Some(self.1),\n            Err(_) => None,\n        }\n    }\n}\n\n/// [snd_ctl_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html) wrapper\n#[derive(Debug)]\npub struct Ctl(*mut alsa::snd_ctl_t);\n\nunsafe impl Send for Ctl {}\n\nimpl Ctl {\n    /// Wrapper around open that takes a &str instead of a &CStr\n    pub fn new(c: &str, nonblock: bool) -> Result<Self> {\n        Self::open(&CString::new(c).unwrap(), nonblock)\n    }\n\n    /// Open does not support async mode (it's not very Rustic anyway)\n    pub fn open(c: &CStr, nonblock: bool) -> Result<Ctl> {\n        let mut r = ptr::null_mut();\n        let flags = if nonblock { 1 } else { 0 }; // FIXME: alsa::SND_CTL_NONBLOCK does not exist in alsa-sys\n        acheck!(snd_ctl_open(&mut r, c.as_ptr(), flags)).map(|_| Ctl(r))\n    }\n\n    pub fn from_card(c: &Card, nonblock: bool) -> Result<Ctl> {\n        let s = ::alloc::format!(\"hw:{}\", c.get_index());\n        Ctl::open(&CString::new(s).unwrap(), nonblock)\n    }\n\n    pub fn card_info(&self) -> Result<CardInfo> { CardInfo::new().and_then(|c|\n        acheck!(snd_ctl_card_info(self.0, c.0)).map(|_| c)) }\n\n    pub fn wait(&self, timeout_ms: Option<u32>) -> Result<bool> {\n        acheck!(snd_ctl_wait(self.0, timeout_ms.map(|x| x as c_int).unwrap_or(-1))).map(|i| i == 1) }\n\n    pub fn get_db_range(&self, id: &ElemId) -> Result<(MilliBel, MilliBel)> {\n        let mut min: c_long = 0;\n        let mut max: c_long = 0;\n        acheck!(snd_ctl_get_dB_range(self.0, elem_id_ptr(id), &mut min, &mut max))\n            .map(|_| (MilliBel(min as i64), MilliBel(max as i64)))\n    }\n\n    pub fn convert_to_db(&self, id: &ElemId, volume: i64) -> Result<MilliBel> {\n        let mut m: c_long = 0;\n        acheck!(snd_ctl_convert_to_dB(self.0, elem_id_ptr(id), volume as c_long, &mut m))\n            .map(|_| MilliBel(m as i64))\n    }\n\n    pub fn convert_from_db(&self, id: &ElemId, mb: MilliBel, dir: Round) -> Result<i64> {\n        let mut m: c_long = 0;\n        acheck!(snd_ctl_convert_from_dB(self.0, elem_id_ptr(id), mb.0 as c_long, &mut m, dir as c_int))\n            .map(|_| m as i64)\n    }\n\n    pub fn elem_read(&self, val: &mut ElemValue) -> Result<()> {\n        acheck!(snd_ctl_elem_read(self.0, elem_value_ptr(val))).map(|_| ())\n    }\n\n    pub fn elem_write(&self, val: &ElemValue) -> Result<()> {\n        acheck!(snd_ctl_elem_write(self.0, elem_value_ptr(val))).map(|_| ())\n    }\n\n    pub fn elem_lock(&self, id: &ElemId) -> Result<i32> {\n        acheck!(snd_ctl_elem_lock(self.0, elem_id_ptr(id)))\n    }\n\n    pub fn elem_unlock(&self, id: &ElemId) -> Result<i32> {\n        acheck!(snd_ctl_elem_unlock(self.0, elem_id_ptr(id)))\n    }\n\n    pub fn elem_list(&self) -> Result<ElemList> {\n        // obtain the list of all the elements now that we know how many there are\n        let list = elem_list_new(|list| {\n            acheck!(snd_ctl_elem_list(self.0, list.0))?;\n            Ok(list.get_count())\n        })?;\n        acheck!(snd_ctl_elem_list(self.0, list.0))?;\n        Ok(list)\n    }\n\n    /// Note: According to alsa-lib documentation, you're also supposed to have functionality for\n    /// returning whether or not you are subscribed. This does not work in practice, so I'm not\n    /// including that here.\n    pub fn subscribe_events(&self, subscribe: bool) -> Result<()> {\n        acheck!(snd_ctl_subscribe_events(self.0, if subscribe { 1 } else { 0 })).map(|_| ())\n    }\n\n    pub fn read(&self) -> Result<Option<Event>> {\n        let e = event_new()?;\n        acheck!(snd_ctl_read(self.0, e.0)).map(|r| if r == 1 { Some(e) } else { None })\n    }\n\n    pub fn pcm_info(&self, device: u32, subdevice: u32, direction: Direction) -> Result<Info> {\n        Info::new().and_then(|mut info| {\n            info.set_device(device);\n            info.set_subdevice(subdevice);\n            info.set_stream(direction);\n            acheck!(snd_ctl_pcm_info(self.0, info.0)).map(|_| info )\n        })\n    }\n}\n\nimpl Drop for Ctl {\n    fn drop(&mut self) { unsafe { alsa::snd_ctl_close(self.0) }; }\n}\n\nimpl poll::Descriptors for Ctl {\n    fn count(&self) -> usize {\n        unsafe { alsa::snd_ctl_poll_descriptors_count(self.0) as usize }\n    }\n    fn fill(&self, p: &mut [pollfd]) -> Result<usize> {\n        let z = unsafe { alsa::snd_ctl_poll_descriptors(self.0, p.as_mut_ptr(), p.len() as c_uint) };\n        from_code(\"snd_ctl_poll_descriptors\", z).map(|_| z as usize)\n    }\n    fn revents(&self, p: &[pollfd]) -> Result<poll::Flags> {\n        let mut r = 0;\n        let z = unsafe { alsa::snd_ctl_poll_descriptors_revents(self.0, p.as_ptr() as *mut pollfd, p.len() as c_uint, &mut r) };\n        from_code(\"snd_ctl_poll_descriptors_revents\", z).map(|_| poll::Flags::from_bits_truncate(r as c_short))\n    }\n}\n\n\npub fn ctl_ptr(a: &Ctl) -> *mut alsa::snd_ctl_t { a.0 }\n\n/// [snd_ctl_card_info_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html) wrapper\n#[derive(Debug)]\npub struct CardInfo(*mut alsa::snd_ctl_card_info_t);\n\nimpl Drop for CardInfo {\n    fn drop(&mut self) { unsafe { alsa::snd_ctl_card_info_free(self.0) }}\n}\n\nimpl CardInfo {\n    fn new() -> Result<CardInfo> {\n        let mut p = ptr::null_mut();\n        acheck!(snd_ctl_card_info_malloc(&mut p)).map(|_| CardInfo(p))\n    }\n\n    pub fn get_id(&self) -> Result<&str> {\n        from_const(\"snd_ctl_card_info_get_id\", unsafe { alsa::snd_ctl_card_info_get_id(self.0) })}\n    pub fn get_driver(&self) -> Result<&str> {\n        from_const(\"snd_ctl_card_info_get_driver\", unsafe { alsa::snd_ctl_card_info_get_driver(self.0) })}\n    pub fn get_components(&self) -> Result<&str> {\n        from_const(\"snd_ctl_card_info_get_components\", unsafe { alsa::snd_ctl_card_info_get_components(self.0) })}\n    pub fn get_longname(&self) -> Result<&str> {\n        from_const(\"snd_ctl_card_info_get_longname\", unsafe { alsa::snd_ctl_card_info_get_longname(self.0) })}\n    pub fn get_name(&self) -> Result<&str> {\n        from_const(\"snd_ctl_card_info_get_name\", unsafe { alsa::snd_ctl_card_info_get_name(self.0) })}\n    pub fn get_mixername(&self) -> Result<&str> {\n        from_const(\"snd_ctl_card_info_get_mixername\", unsafe { alsa::snd_ctl_card_info_get_mixername(self.0) })}\n    pub fn get_card(&self) -> Card { Card::new(unsafe { alsa::snd_ctl_card_info_get_card(self.0) })}\n}\n\nalsa_enum!(\n    /// [SND_CTL_ELEM_IFACE_xxx](http://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html) constants\n    ElemIface, ALL_ELEMIFACE[7],\n\n    Card = SND_CTL_ELEM_IFACE_CARD,\n    Hwdep = SND_CTL_ELEM_IFACE_HWDEP,\n    Mixer = SND_CTL_ELEM_IFACE_MIXER,\n    PCM = SND_CTL_ELEM_IFACE_PCM,\n    Rawmidi = SND_CTL_ELEM_IFACE_RAWMIDI,\n    Timer = SND_CTL_ELEM_IFACE_TIMER,\n    Sequencer = SND_CTL_ELEM_IFACE_SEQUENCER,\n);\n\nalsa_enum!(\n    /// [SND_CTL_ELEM_TYPE_xxx](http://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html) constants\n    ElemType, ALL_ELEMTYPE[7],\n\n    None = SND_CTL_ELEM_TYPE_NONE,\n    Boolean = SND_CTL_ELEM_TYPE_BOOLEAN,\n    Integer = SND_CTL_ELEM_TYPE_INTEGER,\n    Enumerated = SND_CTL_ELEM_TYPE_ENUMERATED,\n    Bytes = SND_CTL_ELEM_TYPE_BYTES,\n    IEC958 = SND_CTL_ELEM_TYPE_IEC958,\n    Integer64 = SND_CTL_ELEM_TYPE_INTEGER64,\n);\n\n/// [snd_ctl_elem_value_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html) wrapper\npub struct ElemValue {\n    ptr: *mut alsa::snd_ctl_elem_value_t,\n    etype: ElemType,\n    count: u32,\n}\n\nimpl Drop for ElemValue {\n    fn drop(&mut self) { unsafe { alsa::snd_ctl_elem_value_free(self.ptr) }; }\n}\n\npub fn elem_value_ptr(a: &ElemValue) -> *mut alsa::snd_ctl_elem_value_t { a.ptr }\n\npub fn elem_value_new(t: ElemType, count: u32) -> Result<ElemValue> {\n    let mut p = ptr::null_mut();\n    acheck!(snd_ctl_elem_value_malloc(&mut p))\n        .map(|_| ElemValue { ptr: p, etype: t, count })\n}\n\nimpl ElemValue {\n\n    pub fn set_id(&mut self, id: &ElemId) {\n        unsafe { alsa::snd_ctl_elem_value_set_id(self.ptr, elem_id_ptr(id)) }\n    }\n\n    // Note: The get_bytes hands out a reference to inside the object. Therefore, we can't treat\n    // the content as \"cell\"ed, but must take a \"&mut self\" (to make sure the reference\n    // from get_bytes has been dropped when calling a set_* function).\n\n    pub fn get_boolean(&self, idx: u32) -> Option<bool> {\n        if self.etype != ElemType::Boolean || idx >= self.count { None }\n        else { Some( unsafe { alsa::snd_ctl_elem_value_get_boolean(self.ptr, idx as c_uint) } != 0) }\n    }\n\n    pub fn set_boolean(&mut self, idx: u32, val: bool) -> Option<()> {\n        if self.etype != ElemType::Boolean || idx >= self.count { None }\n        else { unsafe { alsa::snd_ctl_elem_value_set_boolean(self.ptr, idx as c_uint, if val {1} else {0}) }; Some(()) }\n    }\n\n    pub fn get_integer(&self, idx: u32) -> Option<i32> {\n        if self.etype != ElemType::Integer || idx >= self.count { None }\n        else { Some( unsafe { alsa::snd_ctl_elem_value_get_integer(self.ptr, idx as c_uint) } as i32) }\n    }\n\n    pub fn set_integer(&mut self, idx: u32, val: i32) -> Option<()> {\n        if self.etype != ElemType::Integer || idx >= self.count { None }\n        else { unsafe { alsa::snd_ctl_elem_value_set_integer(self.ptr, idx as c_uint, val as c_long) }; Some(()) }\n    }\n\n    pub fn get_integer64(&self, idx: u32) -> Option<i64> {\n        if self.etype != ElemType::Integer64 || idx >= self.count { None }\n        else { Some( unsafe { alsa::snd_ctl_elem_value_get_integer64(self.ptr, idx as c_uint) } as i64) }\n    }\n\n    pub fn set_integer64(&mut self, idx: u32, val: i64) -> Option<()> {\n        if self.etype != ElemType::Integer || idx >= self.count { None }\n        else { unsafe { alsa::snd_ctl_elem_value_set_integer64(self.ptr, idx as c_uint, val) }; Some(()) }\n    }\n\n    pub fn get_enumerated(&self, idx: u32) -> Option<u32> {\n        if self.etype != ElemType::Enumerated || idx >= self.count { None }\n        else { Some( unsafe { alsa::snd_ctl_elem_value_get_enumerated(self.ptr, idx as c_uint) } as u32) }\n    }\n\n    pub fn set_enumerated(&mut self, idx: u32, val: u32) -> Option<()> {\n        if self.etype != ElemType::Enumerated || idx >= self.count { None }\n        else { unsafe { alsa::snd_ctl_elem_value_set_enumerated(self.ptr, idx as c_uint, val as c_uint) }; Some(()) }\n    }\n\n    pub fn get_byte(&self, idx: u32) -> Option<u8> {\n        if self.etype != ElemType::Bytes || idx >= self.count { None }\n        else { Some( unsafe { alsa::snd_ctl_elem_value_get_byte(self.ptr, idx as c_uint) } as u8) }\n    }\n\n    pub fn set_byte(&mut self, idx: u32, val: u8) -> Option<()> {\n        if self.etype != ElemType::Bytes || idx >= self.count { None }\n        else { unsafe { alsa::snd_ctl_elem_value_set_byte(self.ptr, idx as c_uint, val) }; Some(()) }\n    }\n\n    pub fn get_bytes(&self) -> Option<&[u8]> {\n        if self.etype != ElemType::Bytes { None }\n        else { Some( unsafe { ::core::slice::from_raw_parts(\n            alsa::snd_ctl_elem_value_get_bytes(self.ptr) as *const u8, self.count as usize) } ) }\n    }\n\n    pub fn set_bytes(&mut self, val: &[u8]) -> Option<()> {\n        if self.etype != ElemType::Bytes || val.len() != self.count as usize { None }\n\n        // Note: the alsa-lib function definition is broken. First, the pointer is declared as mut even\n        // though it's const, and second, there is a \"value\" missing between \"elem\" and \"set_bytes\".\n        else { unsafe { alsa::snd_ctl_elem_set_bytes(self.ptr, val.as_ptr() as *mut c_void, val.len() as size_t) }; Some(()) }\n    }\n\n    /// Creates a new ElemValue.\n    pub fn new(t: ElemType) -> Result<ElemValue> {\n        // See max length in include/uapi/sound/asound.h in linux kernel for these values\n        let count = match t {\n            ElemType::None => 1,\n            ElemType::Boolean => 128,\n            ElemType::Integer => 128,\n            ElemType::Enumerated => 128,\n            ElemType::Bytes => 512,\n            ElemType::IEC958 => 1,\n            ElemType::Integer64 => 64,\n        };\n        // if count > maxcount { return Err(Error::new(Some(\"ElemValue::new - count too large\".into()), 1)) }\n        let ev = elem_value_new(t, count)?;\n        unsafe { alsa::snd_ctl_elem_value_clear(elem_value_ptr(&ev)) };\n        Ok(ev)\n    }\n\n}\n\nimpl fmt::Debug for ElemValue {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        use self::ElemType::*;\n        write!(f, \"ElemValue({:?}\", self.etype)?;\n        for a in 0..self.count { match self.etype {\n            Boolean => write!(f, \",{:?}\", self.get_boolean(a).unwrap()),\n            Integer => write!(f, \",{:?}\", self.get_integer(a).unwrap()),\n            Integer64 => write!(f, \",{:?}\", self.get_integer64(a).unwrap()),\n            Enumerated => write!(f, \",{:?}\", self.get_enumerated(a).unwrap()),\n            Bytes => write!(f, \",{:?}\", self.get_byte(a).unwrap()),\n            _ => Ok(()),\n        }?};\n        write!(f, \")\")\n    }\n}\n\n/// [snd_ctl_elem_info_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html) wrapper\n#[derive(Debug)]\npub struct ElemInfo(*mut alsa::snd_ctl_elem_info_t);\n\npub fn elem_info_ptr(a: &ElemInfo) -> *mut alsa::snd_ctl_elem_info_t { a.0 }\n\nimpl Drop for ElemInfo {\n    fn drop(&mut self) { unsafe { alsa::snd_ctl_elem_info_free(self.0) }; }\n}\n\npub fn elem_info_new() -> Result<ElemInfo> {\n    let mut p = ptr::null_mut();\n    acheck!(snd_ctl_elem_info_malloc(&mut p)).map(|_| ElemInfo(p))\n}\n\nimpl ElemInfo {\n    pub fn get_type(&self) -> ElemType { ElemType::from_c_int(\n        unsafe { alsa::snd_ctl_elem_info_get_type(self.0) } as c_int, \"snd_ctl_elem_info_get_type\").unwrap() }\n    pub fn get_count(&self) -> u32 { unsafe { alsa::snd_ctl_elem_info_get_count(self.0) as u32 } }\n}\n\n//\n// Non-allocating version of ElemId\n//\n\n/// [snd_ctl_elem_id_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html) wrapper\npub struct ElemId(UnsafeCell<[u8; ELEM_ID_SIZE]>);\n\npub fn elem_id_new() -> Result<ElemId> {\n    assert!(unsafe { alsa::snd_ctl_elem_id_sizeof() } as usize <= ELEM_ID_SIZE);\n    Ok(ElemId(UnsafeCell::new(unsafe { mem::zeroed() })))\n}\n\n#[inline]\npub fn elem_id_ptr(a: &ElemId) -> *mut alsa::snd_ctl_elem_id_t { a.0.get() as *mut _ as *mut alsa::snd_ctl_elem_id_t }\n\nunsafe impl Send for ElemId {}\n\nimpl Clone for ElemId {\n    fn clone(&self) -> Self {\n        ElemId(UnsafeCell::new(unsafe { *self.0.get() }))\n    }\n}\n\n//\n// Allocating version of ElemId\n//\n\n/*\n\n/// [snd_ctl_elem_id_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html) wrapper\npub struct ElemId(*mut alsa::snd_ctl_elem_id_t);\n\nimpl Drop for ElemId {\n    fn drop(&mut self) { unsafe { alsa::snd_ctl_elem_id_free(self.0) }; }\n}\n\npub fn elem_id_new() -> Result<ElemId> {\n    let mut p = ptr::null_mut();\n    acheck!(snd_ctl_elem_id_malloc(&mut p)).map(|_| ElemId(p))\n}\n\npub fn elem_id_ptr(a: &ElemId) -> *mut alsa::snd_ctl_elem_id_t { a.0 }\n\n*/\n\nimpl ElemId {\n    pub fn get_name(&self) -> Result<&str> {\n        from_const(\"snd_hctl_elem_id_get_name\", unsafe { alsa::snd_ctl_elem_id_get_name(elem_id_ptr(self)) })}\n    pub fn get_device(&self) -> u32 { unsafe { alsa::snd_ctl_elem_id_get_device(elem_id_ptr(self)) as u32 }}\n    pub fn get_subdevice(&self) -> u32 { unsafe { alsa::snd_ctl_elem_id_get_subdevice(elem_id_ptr(self)) as u32 }}\n    pub fn get_numid(&self) -> u32 { unsafe { alsa::snd_ctl_elem_id_get_numid(elem_id_ptr(self)) as u32 }}\n    pub fn get_index(&self) -> u32 { unsafe { alsa::snd_ctl_elem_id_get_index(elem_id_ptr(self)) as u32 }}\n    pub fn get_interface(&self) -> ElemIface { ElemIface::from_c_int(\n        unsafe { alsa::snd_ctl_elem_id_get_interface(elem_id_ptr(self)) } as c_int, \"snd_ctl_elem_id_get_interface\").unwrap() }\n\n    pub fn set_device(&mut self, v: u32) { unsafe { alsa::snd_ctl_elem_id_set_device(elem_id_ptr(self), v) }}\n    pub fn set_subdevice(&mut self, v: u32) { unsafe { alsa::snd_ctl_elem_id_set_subdevice(elem_id_ptr(self), v) }}\n    pub fn set_numid(&mut self, v: u32) { unsafe { alsa::snd_ctl_elem_id_set_numid(elem_id_ptr(self), v) }}\n    pub fn set_index(&mut self, v: u32) { unsafe { alsa::snd_ctl_elem_id_set_index(elem_id_ptr(self), v) }}\n    pub fn set_interface(&mut self, v: ElemIface) { unsafe { alsa::snd_ctl_elem_id_set_interface(elem_id_ptr(self), v as u32) }}\n    pub fn set_name(&mut self, v: &CStr) { unsafe { alsa::snd_ctl_elem_id_set_name(elem_id_ptr(self), v.as_ptr()) }}\n\n    /// Creates a new ElemId.\n    ///\n    /// To ensure safety (i e make sure we never have an invalid interface enum), we need to supply it to the \"new\" function.\n    pub fn new(iface: ElemIface) -> Self {\n        let mut r = elem_id_new().unwrap();\n        r.set_interface(iface);\n        r\n    }\n}\n\nimpl cmp::Eq for ElemId {}\n\nimpl cmp::PartialEq for ElemId {\n    fn eq(&self, a: &ElemId) -> bool {\n        self.get_numid() == a.get_numid() && self.get_interface() == a.get_interface() &&\n        self.get_index() == a.get_index() && self.get_device() == a.get_device() &&\n        self.get_subdevice() == a.get_subdevice() && self.get_name().ok() == a.get_name().ok()\n    }\n}\n\nimpl fmt::Debug for ElemId {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        let index = self.get_index();\n        let device = self.get_device();\n        let subdevice = self.get_subdevice();\n\n        write!(f, \"ElemId(#{}, {:?}, {:?}\", self.get_numid(), self.get_interface(), self.get_name())?;\n        if index > 0 { write!(f, \", index={}\", index)? };\n        if device > 0 || subdevice > 0 { write!(f, \", device={}\", device)? };\n        if subdevice > 0 { write!(f, \", subdevice={}\", device)? };\n        write!(f, \")\")\n    }\n}\n\n/// [snd_ctl_elem_list_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html) wrapper\n#[derive(Debug)]\npub struct ElemList(*mut alsa::snd_ctl_elem_list_t);\n\nimpl Drop for ElemList {\n    fn drop(&mut self) {\n        unsafe { alsa::snd_ctl_elem_list_free_space(self.0) };\n        unsafe { alsa::snd_ctl_elem_list_free(self.0) };\n    }\n}\n\nfn elem_list_new<F: FnOnce(&ElemList) -> Result<u32>>(f: F) -> Result<ElemList> {\n    let mut p = ptr::null_mut();\n    let list = acheck!(snd_ctl_elem_list_malloc(&mut p)).map(|_| ElemList(p))?;\n    let count = f(&list)?;\n    if count > 0 {\n        acheck!(snd_ctl_elem_list_alloc_space(list.0, count))?;\n    }\n    Ok(list)\n}\n\nimpl ElemList {\n    #[inline]\n    fn ensure_valid_index(&self, index: u32) -> Result<()> {\n        if index >= self.get_used() {\n            Err(Error::new(\"snd_ctl_elem_list_*\", libc::EINVAL))\n        } else {\n            Ok(())\n        }\n    }\n\n    pub(crate) fn get_count(&self) -> u32 { unsafe { alsa::snd_ctl_elem_list_get_count(self.0) } }\n    pub fn get_used(&self) -> u32 { unsafe { alsa::snd_ctl_elem_list_get_used(self.0) } }\n    pub fn get_id(&self, index: u32) -> Result<ElemId> {\n        self.ensure_valid_index(index)?;\n        let elem_id = elem_id_new()?;\n        unsafe { alsa::snd_ctl_elem_list_get_id(self.0, index, elem_id_ptr(&elem_id)) };\n        Ok(elem_id)\n    }\n    pub fn get_numid(&self, index: u32) -> Result<u32> { self.ensure_valid_index(index)?; Ok(unsafe { alsa::snd_ctl_elem_list_get_numid(self.0, index) }) }\n    pub fn get_interface(&self, index: u32) -> Result<ElemIface> {\n        self.ensure_valid_index(index)?;\n        ElemIface::from_c_int(unsafe { alsa::snd_ctl_elem_list_get_interface(self.0, index) } as c_int, \"snd_ctl_elem_list_get_interface\")\n    }\n    pub fn get_device(&self, index: u32) -> Result<u32> { self.ensure_valid_index(index)?; Ok(unsafe { alsa::snd_ctl_elem_list_get_device(self.0, index) }) }\n    pub fn get_subdevice(&self, index: u32) -> Result<u32> { self.ensure_valid_index(index)?; Ok(unsafe { alsa::snd_ctl_elem_list_get_subdevice(self.0, index) }) }\n    pub fn get_name(&self, index: u32) -> Result<&str> {\n        self.ensure_valid_index(index)?;\n        from_const(\"snd_ctl_elem_list_get_name\", unsafe { alsa::snd_ctl_elem_list_get_name(self.0, index) })\n    }\n    pub fn get_index(&self, index: u32) -> Result<u32> { self.ensure_valid_index(index)?; Ok(unsafe { alsa::snd_ctl_elem_list_get_index(self.0, index) }) }\n}\n\n/// [snd_ctl_event_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html) wrapper\n#[derive(Debug)]\npub struct Event(*mut alsa::snd_ctl_event_t);\n\nimpl Drop for Event {\n    fn drop(&mut self) { unsafe { alsa::snd_ctl_event_free(self.0) }; }\n}\n\npub fn event_new() -> Result<Event> {\n    let mut p = ptr::null_mut();\n    acheck!(snd_ctl_event_malloc(&mut p)).map(|_| Event(p))\n}\n\nimpl Event {\n    pub fn get_mask(&self) -> EventMask { EventMask(unsafe { alsa::snd_ctl_event_elem_get_mask(self.0) as u32 })}\n    pub fn get_id(&self) -> ElemId {\n        let r = elem_id_new().unwrap();\n        unsafe { alsa::snd_ctl_event_elem_get_id(self.0, elem_id_ptr(&r)) };\n        r\n    }\n}\n\n\n/// [SND_CTL_EVENT_MASK_XXX](http://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html) bitmask\n#[derive(Default, Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]\npub struct EventMask(pub u32);\n\nimpl EventMask {\n   pub fn remove(&self) -> bool { return self.0 & 0xffffffff == 0xffffffff }\n   pub fn value(&self) -> bool { return (!self.remove()) && (self.0 & (1 << 0) != 0); }\n   pub fn info(&self) -> bool { return (!self.remove()) && (self.0 & (1 << 1) != 0); }\n   pub fn add(&self) -> bool { return (!self.remove()) && (self.0 & (1 << 2) != 0); }\n   pub fn tlv(&self) -> bool { return (!self.remove()) && (self.0 & (1 << 3) != 0); }\n}\n\n#[test]\nfn print_sizeof() {\n    extern crate std;\n    let elemid = unsafe { alsa::snd_ctl_elem_id_sizeof() } as usize;\n    let elemvalue = unsafe { alsa::snd_ctl_elem_value_sizeof() } as usize;\n    let eleminfo = unsafe { alsa::snd_ctl_elem_info_sizeof() } as usize;\n\n    assert!(elemid <= ELEM_ID_SIZE);\n//    assert!(elemvalue <= ELEM_VALUE_SIZE);\n//    assert!(eleminfo <= ELEM_INFO_SIZE);\n\n    std::println!(\"Elem id: {}, Elem value: {}, Elem info: {}\", elemid, elemvalue, eleminfo);\n}\n"
  },
  {
    "path": "src/device_name.rs",
    "content": "//! Enumerate devices in the alsa library configuration\n//!\n//! # Example\n//! Print all devices found in various categories.\n//!\n//! ```\n//! use std::ffi::CString;\n//! use alsa::device_name::HintIter;\n//!\n//! for t in &[\"pcm\", \"ctl\", \"rawmidi\", \"timer\", \"seq\", \"hwdep\"] {\n//!     println!(\"{} devices:\", t);\n//!     let i = HintIter::new(None, &*CString::new(*t).unwrap()).unwrap();\n//!     for a in i { println!(\"  {:?}\", a) }\n//! }\n//! ```\n\nuse core::ptr;\nuse libc::{c_void, c_int};\nuse crate::alsa;\nuse super::{Card, Direction};\nuse super::error::*;\nuse core::ffi::CStr;\nuse ::alloc::ffi::CString;\nuse ::alloc::string::String;\n\n/// [snd_device_name_hint](http://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html) wrapper\n#[derive(Debug)]\npub struct HintIter(*mut *mut c_void, isize);\n\nimpl Drop for HintIter {\n    fn drop(&mut self) { unsafe { alsa::snd_device_name_free_hint(self.0); }}\n}\n\nimpl HintIter {\n    /// typical interfaces are: \"pcm\", \"ctl\", \"rawmidi\", \"timer\", \"seq\" and \"hwdep\".\n    pub fn new(card: Option<&Card>, iface: &CStr) -> Result<HintIter> {\n        let mut p = ptr::null_mut();\n        let cnr = card.map(|c| c.get_index()).unwrap_or(-1) as c_int;\n        acheck!(snd_device_name_hint(cnr, iface.as_ptr(), &mut p))\n            .map(|_| HintIter(p, 0))\n    }\n\n    /// A constructor variant that takes the interface as a Rust string slice.\n    pub fn new_str(card: Option<&Card>, iface: &str) -> Result<HintIter> {\n        HintIter::new(card, &CString::new(iface).unwrap())\n    }\n}\n\nimpl Iterator for HintIter {\n    type Item = Hint;\n    fn next(&mut self) -> Option<Hint> {\n        if self.0.is_null() { return None; }\n        let p = unsafe { *self.0.offset(self.1) };\n        if p.is_null() { return None; }\n        self.1 += 1;\n        Some(Hint::new(p))\n    }\n}\n\n\n/// [snd_device_name_get_hint](http://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html) wrapper\n#[derive(Debug, Clone)]\npub struct Hint {\n    pub name: Option<String>,\n    pub desc: Option<String>,\n    pub direction: Option<Direction>,\n}\n\nimpl Hint {\n    fn get_str(p: *const c_void, name: &str) -> Option<String> {\n        let name = CString::new(name).unwrap();\n        let c = unsafe { alsa::snd_device_name_get_hint(p, name.as_ptr()) };\n        from_alloc(\"snd_device_name_get_hint\", c).ok()\n    }\n\n    fn new(p: *const c_void) -> Hint {\n       let d = Hint::get_str(p, \"IOID\").and_then(|x| match &*x {\n            \"Input\" => Some(Direction::Capture),\n            \"Output\" => Some(Direction::Playback),\n            _ => None,\n       });\n       Hint { name: Hint::get_str(p, \"NAME\"), desc: Hint::get_str(p, \"DESC\"), direction: d }\n    }\n}\n\n#[test]\nfn print_hints() {\n    extern crate std;\n    for t in &[\"pcm\", \"ctl\", \"rawmidi\", \"timer\", \"seq\", \"hwdep\"] {\n        std::println!(\"{} devices:\", t);\n        let i = HintIter::new(None, &*CString::new(*t).unwrap()).unwrap();\n        for a in i { std::println!(\"  {:?}\", a) }\n    }\n}\n"
  },
  {
    "path": "src/direct/asound_ioctl.rs",
    "content": "/* automatically generated by rust-bindgen */\n\n#[repr(C)]\n#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]\npub struct __BindgenBitfieldUnit<Storage, Align>\nwhere\n    Storage: AsRef<[u8]> + AsMut<[u8]>,\n{\n    storage: Storage,\n    align: [Align; 0],\n}\n\nimpl<Storage, Align> __BindgenBitfieldUnit<Storage, Align>\nwhere\n    Storage: AsRef<[u8]> + AsMut<[u8]>,\n{\n    #[inline]\n    pub fn new(storage: Storage) -> Self {\n        Self { storage, align: [] }\n    }\n\n    #[inline]\n    pub fn get_bit(&self, index: usize) -> bool {\n        debug_assert!(index / 8 < self.storage.as_ref().len());\n\n        let byte_index = index / 8;\n        let byte = self.storage.as_ref()[byte_index];\n\n        let bit_index = index % 8;\n        let mask = 1 << bit_index;\n\n        byte & mask == mask\n    }\n\n    #[inline]\n    pub fn set_bit(&mut self, index: usize, val: bool) {\n        debug_assert!(index / 8 < self.storage.as_ref().len());\n\n        let byte_index = index / 8;\n        let byte = &mut self.storage.as_mut()[byte_index];\n\n        let bit_index = index % 8;\n        let mask = 1 << bit_index;\n\n        if val {\n            *byte |= mask;\n        } else {\n            *byte &= !mask;\n        }\n    }\n\n    #[inline]\n    pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 {\n        debug_assert!(bit_width <= 64);\n        debug_assert!(bit_offset / 8 < self.storage.as_ref().len());\n        debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len());\n\n        let mut val = 0;\n\n        for i in 0..(bit_width as usize) {\n            if self.get_bit(i + bit_offset) {\n                val |= 1 << i;\n            }\n        }\n\n        val\n    }\n\n    #[inline]\n    pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) {\n        debug_assert!(bit_width <= 64);\n        debug_assert!(bit_offset / 8 < self.storage.as_ref().len());\n        debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len());\n\n        for i in 0..(bit_width as usize) {\n            let mask = 1 << i;\n            let val_bit_is_set = val & mask == mask;\n            self.set_bit(i + bit_offset, val_bit_is_set);\n        }\n    }\n}\n#[repr(C)]\n#[derive(Default)]\npub struct __IncompleteArrayField<T>(::core::marker::PhantomData<T>);\nimpl<T> __IncompleteArrayField<T> {\n    #[inline]\n    pub fn new() -> Self {\n        __IncompleteArrayField(::core::marker::PhantomData)\n    }\n    #[inline]\n    pub unsafe fn as_ptr(&self) -> *const T {\n        ::core::mem::transmute(self)\n    }\n    #[inline]\n    pub unsafe fn as_mut_ptr(&mut self) -> *mut T {\n        ::core::mem::transmute(self)\n    }\n    #[inline]\n    pub unsafe fn as_slice(&self, len: usize) -> &[T] {\n        ::core::slice::from_raw_parts(self.as_ptr(), len)\n    }\n    #[inline]\n    pub unsafe fn as_mut_slice(&mut self, len: usize) -> &mut [T] {\n        ::core::slice::from_raw_parts_mut(self.as_mut_ptr(), len)\n    }\n}\nimpl<T> ::core::fmt::Debug for __IncompleteArrayField<T> {\n    fn fmt(&self, fmt: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {\n        fmt.write_str(\"__IncompleteArrayField\")\n    }\n}\nimpl<T> ::core::clone::Clone for __IncompleteArrayField<T> {\n    #[inline]\n    fn clone(&self) -> Self {\n        Self::new()\n    }\n}\nimpl<T> ::core::marker::Copy for __IncompleteArrayField<T> {}\npub const __BITS_PER_LONG: u32 = 64;\npub const __FD_SETSIZE: u32 = 1024;\npub const _FEATURES_H: u32 = 1;\npub const _DEFAULT_SOURCE: u32 = 1;\npub const __USE_ISOC11: u32 = 1;\npub const __USE_ISOC99: u32 = 1;\npub const __USE_ISOC95: u32 = 1;\npub const __USE_POSIX_IMPLICITLY: u32 = 1;\npub const _POSIX_SOURCE: u32 = 1;\npub const _POSIX_C_SOURCE: u32 = 200809;\npub const __USE_POSIX: u32 = 1;\npub const __USE_POSIX2: u32 = 1;\npub const __USE_POSIX199309: u32 = 1;\npub const __USE_POSIX199506: u32 = 1;\npub const __USE_XOPEN2K: u32 = 1;\npub const __USE_XOPEN2K8: u32 = 1;\npub const _ATFILE_SOURCE: u32 = 1;\npub const __USE_MISC: u32 = 1;\npub const __USE_ATFILE: u32 = 1;\npub const __USE_FORTIFY_LEVEL: u32 = 0;\npub const _STDC_PREDEF_H: u32 = 1;\npub const __STDC_IEC_559__: u32 = 1;\npub const __STDC_IEC_559_COMPLEX__: u32 = 1;\npub const __STDC_ISO_10646__: u32 = 201505;\npub const __STDC_NO_THREADS__: u32 = 1;\npub const __GNU_LIBRARY__: u32 = 6;\npub const __GLIBC__: u32 = 2;\npub const __GLIBC_MINOR__: u32 = 23;\npub const _SYS_CDEFS_H: u32 = 1;\npub const __WORDSIZE: u32 = 64;\npub const __WORDSIZE_TIME64_COMPAT32: u32 = 1;\npub const __SYSCALL_WORDSIZE: u32 = 64;\npub const _STDLIB_H: u32 = 1;\npub const WNOHANG: u32 = 1;\npub const WUNTRACED: u32 = 2;\npub const WSTOPPED: u32 = 2;\npub const WEXITED: u32 = 4;\npub const WCONTINUED: u32 = 8;\npub const WNOWAIT: u32 = 16777216;\npub const __WNOTHREAD: u32 = 536870912;\npub const __WALL: u32 = 1073741824;\npub const __WCLONE: u32 = 2147483648;\npub const __ENUM_IDTYPE_T: u32 = 1;\npub const __W_CONTINUED: u32 = 65535;\npub const __WCOREFLAG: u32 = 128;\npub const _ENDIAN_H: u32 = 1;\npub const __LITTLE_ENDIAN: u32 = 1234;\npub const __BIG_ENDIAN: u32 = 4321;\npub const __PDP_ENDIAN: u32 = 3412;\npub const __BYTE_ORDER: u32 = 1234;\npub const __FLOAT_WORD_ORDER: u32 = 1234;\npub const LITTLE_ENDIAN: u32 = 1234;\npub const BIG_ENDIAN: u32 = 4321;\npub const PDP_ENDIAN: u32 = 3412;\npub const BYTE_ORDER: u32 = 1234;\npub const _BITS_BYTESWAP_H: u32 = 1;\npub const _BITS_TYPES_H: u32 = 1;\npub const _BITS_TYPESIZES_H: u32 = 1;\npub const __OFF_T_MATCHES_OFF64_T: u32 = 1;\npub const __INO_T_MATCHES_INO64_T: u32 = 1;\npub const __ldiv_t_defined: u32 = 1;\npub const __lldiv_t_defined: u32 = 1;\npub const RAND_MAX: u32 = 2147483647;\npub const EXIT_FAILURE: u32 = 1;\npub const EXIT_SUCCESS: u32 = 0;\npub const _SYS_TYPES_H: u32 = 1;\npub const __clock_t_defined: u32 = 1;\npub const __time_t_defined: u32 = 1;\npub const __clockid_t_defined: u32 = 1;\npub const __timer_t_defined: u32 = 1;\npub const __BIT_TYPES_DEFINED__: u32 = 1;\npub const _SYS_SELECT_H: u32 = 1;\npub const __FD_ZERO_STOS: &'static [u8; 6usize] = b\"stosq\\0\";\npub const _SIGSET_H_types: u32 = 1;\npub const __timespec_defined: u32 = 1;\npub const _STRUCT_TIMEVAL: u32 = 1;\npub const FD_SETSIZE: u32 = 1024;\npub const _SYS_SYSMACROS_H: u32 = 1;\npub const _BITS_PTHREADTYPES_H: u32 = 1;\npub const __SIZEOF_PTHREAD_ATTR_T: u32 = 56;\npub const __SIZEOF_PTHREAD_MUTEX_T: u32 = 40;\npub const __SIZEOF_PTHREAD_MUTEXATTR_T: u32 = 4;\npub const __SIZEOF_PTHREAD_COND_T: u32 = 48;\npub const __SIZEOF_PTHREAD_CONDATTR_T: u32 = 4;\npub const __SIZEOF_PTHREAD_RWLOCK_T: u32 = 56;\npub const __SIZEOF_PTHREAD_RWLOCKATTR_T: u32 = 8;\npub const __SIZEOF_PTHREAD_BARRIER_T: u32 = 32;\npub const __SIZEOF_PTHREAD_BARRIERATTR_T: u32 = 4;\npub const __have_pthread_attr_t: u32 = 1;\npub const __PTHREAD_MUTEX_HAVE_PREV: u32 = 1;\npub const __PTHREAD_RWLOCK_INT_FLAGS_SHARED: u32 = 1;\npub const _ALLOCA_H: u32 = 1;\npub const SNDRV_PCM_INFO_MMAP: u32 = 1;\npub const SNDRV_PCM_INFO_MMAP_VALID: u32 = 2;\npub const SNDRV_PCM_INFO_DOUBLE: u32 = 4;\npub const SNDRV_PCM_INFO_BATCH: u32 = 16;\npub const SNDRV_PCM_INFO_SYNC_APPLPTR: u32 = 32;\npub const SNDRV_PCM_INFO_INTERLEAVED: u32 = 256;\npub const SNDRV_PCM_INFO_NONINTERLEAVED: u32 = 512;\npub const SNDRV_PCM_INFO_COMPLEX: u32 = 1024;\npub const SNDRV_PCM_INFO_BLOCK_TRANSFER: u32 = 65536;\npub const SNDRV_PCM_INFO_OVERRANGE: u32 = 131072;\npub const SNDRV_PCM_INFO_RESUME: u32 = 262144;\npub const SNDRV_PCM_INFO_PAUSE: u32 = 524288;\npub const SNDRV_PCM_INFO_HALF_DUPLEX: u32 = 1048576;\npub const SNDRV_PCM_INFO_JOINT_DUPLEX: u32 = 2097152;\npub const SNDRV_PCM_INFO_SYNC_START: u32 = 4194304;\npub const SNDRV_PCM_INFO_NO_PERIOD_WAKEUP: u32 = 8388608;\npub const SNDRV_PCM_INFO_HAS_WALL_CLOCK: u32 = 16777216;\npub const SNDRV_PCM_INFO_HAS_LINK_ATIME: u32 = 16777216;\npub const SNDRV_PCM_INFO_HAS_LINK_ABSOLUTE_ATIME: u32 = 33554432;\npub const SNDRV_PCM_INFO_HAS_LINK_ESTIMATED_ATIME: u32 = 67108864;\npub const SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME: u32 = 134217728;\npub const SNDRV_PCM_INFO_DRAIN_TRIGGER: u32 = 1073741824;\npub const SNDRV_PCM_INFO_FIFO_IN_FRAMES: u32 = 2147483648;\npub const SNDRV_PCM_HW_PARAM_ACCESS: u32 = 0;\npub const SNDRV_PCM_HW_PARAM_FORMAT: u32 = 1;\npub const SNDRV_PCM_HW_PARAM_SUBFORMAT: u32 = 2;\npub const SNDRV_PCM_HW_PARAM_FIRST_MASK: u32 = 0;\npub const SNDRV_PCM_HW_PARAM_LAST_MASK: u32 = 2;\npub const SNDRV_PCM_HW_PARAM_SAMPLE_BITS: u32 = 8;\npub const SNDRV_PCM_HW_PARAM_FRAME_BITS: u32 = 9;\npub const SNDRV_PCM_HW_PARAM_CHANNELS: u32 = 10;\npub const SNDRV_PCM_HW_PARAM_RATE: u32 = 11;\npub const SNDRV_PCM_HW_PARAM_PERIOD_TIME: u32 = 12;\npub const SNDRV_PCM_HW_PARAM_PERIOD_SIZE: u32 = 13;\npub const SNDRV_PCM_HW_PARAM_PERIOD_BYTES: u32 = 14;\npub const SNDRV_PCM_HW_PARAM_PERIODS: u32 = 15;\npub const SNDRV_PCM_HW_PARAM_BUFFER_TIME: u32 = 16;\npub const SNDRV_PCM_HW_PARAM_BUFFER_SIZE: u32 = 17;\npub const SNDRV_PCM_HW_PARAM_BUFFER_BYTES: u32 = 18;\npub const SNDRV_PCM_HW_PARAM_TICK_TIME: u32 = 19;\npub const SNDRV_PCM_HW_PARAM_FIRST_INTERVAL: u32 = 8;\npub const SNDRV_PCM_HW_PARAM_LAST_INTERVAL: u32 = 19;\npub const SNDRV_PCM_HW_PARAMS_NORESAMPLE: u32 = 1;\npub const SNDRV_PCM_HW_PARAMS_EXPORT_BUFFER: u32 = 2;\npub const SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP: u32 = 4;\npub const SNDRV_MASK_MAX: u32 = 256;\npub const SNDRV_PCM_SYNC_PTR_HWSYNC: u32 = 1;\npub const SNDRV_PCM_SYNC_PTR_APPL: u32 = 2;\npub const SNDRV_PCM_SYNC_PTR_AVAIL_MIN: u32 = 4;\npub const SNDRV_CHMAP_POSITION_MASK: u32 = 65535;\npub const SNDRV_CHMAP_PHASE_INVERSE: u32 = 65536;\npub const SNDRV_CHMAP_DRIVER_SPEC: u32 = 131072;\npub const SNDRV_RAWMIDI_INFO_OUTPUT: u32 = 1;\npub const SNDRV_RAWMIDI_INFO_INPUT: u32 = 2;\npub const SNDRV_RAWMIDI_INFO_DUPLEX: u32 = 4;\npub const SNDRV_TIMER_GLOBAL_SYSTEM: u32 = 0;\npub const SNDRV_TIMER_GLOBAL_RTC: u32 = 1;\npub const SNDRV_TIMER_GLOBAL_HPET: u32 = 2;\npub const SNDRV_TIMER_GLOBAL_HRTIMER: u32 = 3;\npub const SNDRV_TIMER_FLG_SLAVE: u32 = 1;\npub const SNDRV_TIMER_PSFLG_AUTO: u32 = 1;\npub const SNDRV_TIMER_PSFLG_EXCLUSIVE: u32 = 2;\npub const SNDRV_TIMER_PSFLG_EARLY_EVENT: u32 = 4;\npub const SNDRV_CTL_ELEM_ACCESS_READ: u32 = 1;\npub const SNDRV_CTL_ELEM_ACCESS_WRITE: u32 = 2;\npub const SNDRV_CTL_ELEM_ACCESS_READWRITE: u32 = 3;\npub const SNDRV_CTL_ELEM_ACCESS_VOLATILE: u32 = 4;\npub const SNDRV_CTL_ELEM_ACCESS_TIMESTAMP: u32 = 8;\npub const SNDRV_CTL_ELEM_ACCESS_TLV_READ: u32 = 16;\npub const SNDRV_CTL_ELEM_ACCESS_TLV_WRITE: u32 = 32;\npub const SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE: u32 = 48;\npub const SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND: u32 = 64;\npub const SNDRV_CTL_ELEM_ACCESS_INACTIVE: u32 = 256;\npub const SNDRV_CTL_ELEM_ACCESS_LOCK: u32 = 512;\npub const SNDRV_CTL_ELEM_ACCESS_OWNER: u32 = 1024;\npub const SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK: u32 = 268435456;\npub const SNDRV_CTL_ELEM_ACCESS_USER: u32 = 536870912;\npub const SNDRV_CTL_POWER_D0: u32 = 0;\npub const SNDRV_CTL_POWER_D1: u32 = 256;\npub const SNDRV_CTL_POWER_D2: u32 = 512;\npub const SNDRV_CTL_POWER_D3: u32 = 768;\npub const SNDRV_CTL_POWER_D3hot: u32 = 768;\npub const SNDRV_CTL_POWER_D3cold: u32 = 769;\npub const SNDRV_CTL_ELEM_ID_NAME_MAXLEN: u32 = 44;\npub const SNDRV_CTL_EVENT_MASK_VALUE: u32 = 1;\npub const SNDRV_CTL_EVENT_MASK_INFO: u32 = 2;\npub const SNDRV_CTL_EVENT_MASK_ADD: u32 = 4;\npub const SNDRV_CTL_EVENT_MASK_TLV: u32 = 8;\npub const SNDRV_CTL_EVENT_MASK_REMOVE: i32 = -1;\npub const SNDRV_CTL_NAME_NONE: &'static [u8; 1usize] = b\"\\0\";\npub const SNDRV_CTL_NAME_PLAYBACK: &'static [u8; 10usize] = b\"Playback \\0\";\npub const SNDRV_CTL_NAME_CAPTURE: &'static [u8; 9usize] = b\"Capture \\0\";\npub const SNDRV_CTL_NAME_IEC958_NONE: &'static [u8; 1usize] = b\"\\0\";\npub const SNDRV_CTL_NAME_IEC958_SWITCH: &'static [u8; 7usize] = b\"Switch\\0\";\npub const SNDRV_CTL_NAME_IEC958_VOLUME: &'static [u8; 7usize] = b\"Volume\\0\";\npub const SNDRV_CTL_NAME_IEC958_DEFAULT: &'static [u8; 8usize] = b\"Default\\0\";\npub const SNDRV_CTL_NAME_IEC958_MASK: &'static [u8; 5usize] = b\"Mask\\0\";\npub const SNDRV_CTL_NAME_IEC958_CON_MASK: &'static [u8; 9usize] = b\"Con Mask\\0\";\npub const SNDRV_CTL_NAME_IEC958_PRO_MASK: &'static [u8; 9usize] = b\"Pro Mask\\0\";\npub const SNDRV_CTL_NAME_IEC958_PCM_STREAM: &'static [u8; 11usize] = b\"PCM Stream\\0\";\npub type __s8 = ::core::ffi::c_schar;\npub type __u8 = ::core::ffi::c_uchar;\npub type __s16 = ::core::ffi::c_short;\npub type __u16 = ::core::ffi::c_ushort;\npub type __s32 = ::core::ffi::c_int;\npub type __u32 = ::core::ffi::c_uint;\npub type __s64 = ::core::ffi::c_longlong;\npub type __u64 = ::core::ffi::c_ulonglong;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __kernel_fd_set {\n    pub fds_bits: [::core::ffi::c_ulong; 16usize],\n}\n#[test]\nfn bindgen_test_layout___kernel_fd_set() {\n    assert_eq!(\n        ::core::mem::size_of::<__kernel_fd_set>(),\n        128usize,\n        concat!(\"Size of: \", stringify!(__kernel_fd_set))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<__kernel_fd_set>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__kernel_fd_set))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<__kernel_fd_set>())).fds_bits as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__kernel_fd_set),\n            \"::\",\n            stringify!(fds_bits)\n        )\n    );\n}\npub type __kernel_sighandler_t =\n    ::core::option::Option<unsafe extern \"C\" fn(arg1: ::core::ffi::c_int)>;\npub type __kernel_key_t = ::core::ffi::c_int;\npub type __kernel_mqd_t = ::core::ffi::c_int;\npub type __kernel_old_uid_t = ::core::ffi::c_ushort;\npub type __kernel_old_gid_t = ::core::ffi::c_ushort;\npub type __kernel_old_dev_t = ::core::ffi::c_ulong;\npub type __kernel_long_t = ::core::ffi::c_long;\npub type __kernel_ulong_t = ::core::ffi::c_ulong;\npub type __kernel_ino_t = __kernel_ulong_t;\npub type __kernel_mode_t = ::core::ffi::c_uint;\npub type __kernel_pid_t = ::core::ffi::c_int;\npub type __kernel_ipc_pid_t = ::core::ffi::c_int;\npub type __kernel_uid_t = ::core::ffi::c_uint;\npub type __kernel_gid_t = ::core::ffi::c_uint;\npub type __kernel_suseconds_t = __kernel_long_t;\npub type __kernel_daddr_t = ::core::ffi::c_int;\npub type __kernel_uid32_t = ::core::ffi::c_uint;\npub type __kernel_gid32_t = ::core::ffi::c_uint;\npub type __kernel_size_t = __kernel_ulong_t;\npub type __kernel_ssize_t = __kernel_long_t;\npub type __kernel_ptrdiff_t = __kernel_long_t;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __kernel_fsid_t {\n    pub val: [::core::ffi::c_int; 2usize],\n}\n#[test]\nfn bindgen_test_layout___kernel_fsid_t() {\n    assert_eq!(\n        ::core::mem::size_of::<__kernel_fsid_t>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(__kernel_fsid_t))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<__kernel_fsid_t>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(__kernel_fsid_t))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<__kernel_fsid_t>())).val as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__kernel_fsid_t),\n            \"::\",\n            stringify!(val)\n        )\n    );\n}\npub type __kernel_off_t = __kernel_long_t;\npub type __kernel_loff_t = ::core::ffi::c_longlong;\npub type __kernel_time_t = __kernel_long_t;\npub type __kernel_clock_t = __kernel_long_t;\npub type __kernel_timer_t = ::core::ffi::c_int;\npub type __kernel_clockid_t = ::core::ffi::c_int;\npub type __kernel_caddr_t = *mut ::core::ffi::c_char;\npub type __kernel_uid16_t = ::core::ffi::c_ushort;\npub type __kernel_gid16_t = ::core::ffi::c_ushort;\npub type __le16 = __u16;\npub type __be16 = __u16;\npub type __le32 = __u32;\npub type __be32 = __u32;\npub type __le64 = __u64;\npub type __be64 = __u64;\npub type __sum16 = __u16;\npub type __wsum = __u32;\npub type wchar_t = ::core::ffi::c_int;\npub const idtype_t_P_ALL: idtype_t = 0;\npub const idtype_t_P_PID: idtype_t = 1;\npub const idtype_t_P_PGID: idtype_t = 2;\npub type idtype_t = u32;\npub type __u_char = ::core::ffi::c_uchar;\npub type __u_short = ::core::ffi::c_ushort;\npub type __u_int = ::core::ffi::c_uint;\npub type __u_long = ::core::ffi::c_ulong;\npub type __int8_t = ::core::ffi::c_schar;\npub type __uint8_t = ::core::ffi::c_uchar;\npub type __int16_t = ::core::ffi::c_short;\npub type __uint16_t = ::core::ffi::c_ushort;\npub type __int32_t = ::core::ffi::c_int;\npub type __uint32_t = ::core::ffi::c_uint;\npub type __int64_t = ::core::ffi::c_long;\npub type __uint64_t = ::core::ffi::c_ulong;\npub type __quad_t = ::core::ffi::c_long;\npub type __u_quad_t = ::core::ffi::c_ulong;\npub type __dev_t = ::core::ffi::c_ulong;\npub type __uid_t = ::core::ffi::c_uint;\npub type __gid_t = ::core::ffi::c_uint;\npub type __ino_t = ::core::ffi::c_ulong;\npub type __ino64_t = ::core::ffi::c_ulong;\npub type __mode_t = ::core::ffi::c_uint;\npub type __nlink_t = ::core::ffi::c_ulong;\npub type __off_t = ::core::ffi::c_long;\npub type __off64_t = ::core::ffi::c_long;\npub type __pid_t = ::core::ffi::c_int;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __fsid_t {\n    pub __val: [::core::ffi::c_int; 2usize],\n}\n#[test]\nfn bindgen_test_layout___fsid_t() {\n    assert_eq!(\n        ::core::mem::size_of::<__fsid_t>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(__fsid_t))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<__fsid_t>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(__fsid_t))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<__fsid_t>())).__val as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__fsid_t),\n            \"::\",\n            stringify!(__val)\n        )\n    );\n}\npub type __clock_t = ::core::ffi::c_long;\npub type __rlim_t = ::core::ffi::c_ulong;\npub type __rlim64_t = ::core::ffi::c_ulong;\npub type __id_t = ::core::ffi::c_uint;\npub type __time_t = ::core::ffi::c_long;\npub type __useconds_t = ::core::ffi::c_uint;\npub type __suseconds_t = ::core::ffi::c_long;\npub type __daddr_t = ::core::ffi::c_int;\npub type __key_t = ::core::ffi::c_int;\npub type __clockid_t = ::core::ffi::c_int;\npub type __timer_t = *mut ::core::ffi::c_void;\npub type __blksize_t = ::core::ffi::c_long;\npub type __blkcnt_t = ::core::ffi::c_long;\npub type __blkcnt64_t = ::core::ffi::c_long;\npub type __fsblkcnt_t = ::core::ffi::c_ulong;\npub type __fsblkcnt64_t = ::core::ffi::c_ulong;\npub type __fsfilcnt_t = ::core::ffi::c_ulong;\npub type __fsfilcnt64_t = ::core::ffi::c_ulong;\npub type __fsword_t = ::core::ffi::c_long;\npub type __ssize_t = ::core::ffi::c_long;\npub type __syscall_slong_t = ::core::ffi::c_long;\npub type __syscall_ulong_t = ::core::ffi::c_ulong;\npub type __loff_t = __off64_t;\npub type __qaddr_t = *mut __quad_t;\npub type __caddr_t = *mut ::core::ffi::c_char;\npub type __intptr_t = ::core::ffi::c_long;\npub type __socklen_t = ::core::ffi::c_uint;\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union wait {\n    pub w_status: ::core::ffi::c_int,\n    pub __wait_terminated: wait__bindgen_ty_1,\n    pub __wait_stopped: wait__bindgen_ty_2,\n    _bindgen_union_align: u32,\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct wait__bindgen_ty_1 {\n    pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize], u8>,\n    pub __bindgen_align: [u32; 0usize],\n}\n#[test]\nfn bindgen_test_layout_wait__bindgen_ty_1() {\n    assert_eq!(\n        ::core::mem::size_of::<wait__bindgen_ty_1>(),\n        4usize,\n        concat!(\"Size of: \", stringify!(wait__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<wait__bindgen_ty_1>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(wait__bindgen_ty_1))\n    );\n}\nimpl wait__bindgen_ty_1 {\n    #[inline]\n    pub fn __w_termsig(&self) -> ::core::ffi::c_uint {\n        unsafe { ::core::mem::transmute(self._bitfield_1.get(0usize, 7u8) as u32) }\n    }\n    #[inline]\n    pub fn set___w_termsig(&mut self, val: ::core::ffi::c_uint) {\n        unsafe {\n            let val: u32 = ::core::mem::transmute(val);\n            self._bitfield_1.set(0usize, 7u8, val as u64)\n        }\n    }\n    #[inline]\n    pub fn __w_coredump(&self) -> ::core::ffi::c_uint {\n        unsafe { ::core::mem::transmute(self._bitfield_1.get(7usize, 1u8) as u32) }\n    }\n    #[inline]\n    pub fn set___w_coredump(&mut self, val: ::core::ffi::c_uint) {\n        unsafe {\n            let val: u32 = ::core::mem::transmute(val);\n            self._bitfield_1.set(7usize, 1u8, val as u64)\n        }\n    }\n    #[inline]\n    pub fn __w_retcode(&self) -> ::core::ffi::c_uint {\n        unsafe { ::core::mem::transmute(self._bitfield_1.get(8usize, 8u8) as u32) }\n    }\n    #[inline]\n    pub fn set___w_retcode(&mut self, val: ::core::ffi::c_uint) {\n        unsafe {\n            let val: u32 = ::core::mem::transmute(val);\n            self._bitfield_1.set(8usize, 8u8, val as u64)\n        }\n    }\n    #[inline]\n    pub fn new_bitfield_1(\n        __w_termsig: ::core::ffi::c_uint,\n        __w_coredump: ::core::ffi::c_uint,\n        __w_retcode: ::core::ffi::c_uint,\n    ) -> __BindgenBitfieldUnit<[u8; 4usize], u8> {\n        let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize], u8> =\n            Default::default();\n        __bindgen_bitfield_unit.set(0usize, 7u8, {\n            let __w_termsig: u32 = unsafe { ::core::mem::transmute(__w_termsig) };\n            __w_termsig as u64\n        });\n        __bindgen_bitfield_unit.set(7usize, 1u8, {\n            let __w_coredump: u32 = unsafe { ::core::mem::transmute(__w_coredump) };\n            __w_coredump as u64\n        });\n        __bindgen_bitfield_unit.set(8usize, 8u8, {\n            let __w_retcode: u32 = unsafe { ::core::mem::transmute(__w_retcode) };\n            __w_retcode as u64\n        });\n        __bindgen_bitfield_unit\n    }\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct wait__bindgen_ty_2 {\n    pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize], u8>,\n    pub __bindgen_align: [u32; 0usize],\n}\n#[test]\nfn bindgen_test_layout_wait__bindgen_ty_2() {\n    assert_eq!(\n        ::core::mem::size_of::<wait__bindgen_ty_2>(),\n        4usize,\n        concat!(\"Size of: \", stringify!(wait__bindgen_ty_2))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<wait__bindgen_ty_2>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(wait__bindgen_ty_2))\n    );\n}\nimpl wait__bindgen_ty_2 {\n    #[inline]\n    pub fn __w_stopval(&self) -> ::core::ffi::c_uint {\n        unsafe { ::core::mem::transmute(self._bitfield_1.get(0usize, 8u8) as u32) }\n    }\n    #[inline]\n    pub fn set___w_stopval(&mut self, val: ::core::ffi::c_uint) {\n        unsafe {\n            let val: u32 = ::core::mem::transmute(val);\n            self._bitfield_1.set(0usize, 8u8, val as u64)\n        }\n    }\n    #[inline]\n    pub fn __w_stopsig(&self) -> ::core::ffi::c_uint {\n        unsafe { ::core::mem::transmute(self._bitfield_1.get(8usize, 8u8) as u32) }\n    }\n    #[inline]\n    pub fn set___w_stopsig(&mut self, val: ::core::ffi::c_uint) {\n        unsafe {\n            let val: u32 = ::core::mem::transmute(val);\n            self._bitfield_1.set(8usize, 8u8, val as u64)\n        }\n    }\n    #[inline]\n    pub fn new_bitfield_1(\n        __w_stopval: ::core::ffi::c_uint,\n        __w_stopsig: ::core::ffi::c_uint,\n    ) -> __BindgenBitfieldUnit<[u8; 4usize], u8> {\n        let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize], u8> =\n            Default::default();\n        __bindgen_bitfield_unit.set(0usize, 8u8, {\n            let __w_stopval: u32 = unsafe { ::core::mem::transmute(__w_stopval) };\n            __w_stopval as u64\n        });\n        __bindgen_bitfield_unit.set(8usize, 8u8, {\n            let __w_stopsig: u32 = unsafe { ::core::mem::transmute(__w_stopsig) };\n            __w_stopsig as u64\n        });\n        __bindgen_bitfield_unit\n    }\n}\n#[test]\nfn bindgen_test_layout_wait() {\n    assert_eq!(\n        ::core::mem::size_of::<wait>(),\n        4usize,\n        concat!(\"Size of: \", stringify!(wait))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<wait>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(wait))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<wait>())).w_status as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(wait),\n            \"::\",\n            stringify!(w_status)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<wait>())).__wait_terminated as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(wait),\n            \"::\",\n            stringify!(__wait_terminated)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<wait>())).__wait_stopped as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(wait),\n            \"::\",\n            stringify!(__wait_stopped)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union __WAIT_STATUS {\n    pub __uptr: *mut wait,\n    pub __iptr: *mut ::core::ffi::c_int,\n    _bindgen_union_align: u64,\n}\n#[test]\nfn bindgen_test_layout___WAIT_STATUS() {\n    assert_eq!(\n        ::core::mem::size_of::<__WAIT_STATUS>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(__WAIT_STATUS))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<__WAIT_STATUS>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__WAIT_STATUS))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<__WAIT_STATUS>())).__uptr as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__WAIT_STATUS),\n            \"::\",\n            stringify!(__uptr)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<__WAIT_STATUS>())).__iptr as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__WAIT_STATUS),\n            \"::\",\n            stringify!(__iptr)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct div_t {\n    pub quot: ::core::ffi::c_int,\n    pub rem: ::core::ffi::c_int,\n}\n#[test]\nfn bindgen_test_layout_div_t() {\n    assert_eq!(\n        ::core::mem::size_of::<div_t>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(div_t))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<div_t>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(div_t))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<div_t>())).quot as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(div_t),\n            \"::\",\n            stringify!(quot)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<div_t>())).rem as *const _ as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(div_t),\n            \"::\",\n            stringify!(rem)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct ldiv_t {\n    pub quot: ::core::ffi::c_long,\n    pub rem: ::core::ffi::c_long,\n}\n#[test]\nfn bindgen_test_layout_ldiv_t() {\n    assert_eq!(\n        ::core::mem::size_of::<ldiv_t>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(ldiv_t))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<ldiv_t>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(ldiv_t))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<ldiv_t>())).quot as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ldiv_t),\n            \"::\",\n            stringify!(quot)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<ldiv_t>())).rem as *const _ as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(ldiv_t),\n            \"::\",\n            stringify!(rem)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct lldiv_t {\n    pub quot: ::core::ffi::c_longlong,\n    pub rem: ::core::ffi::c_longlong,\n}\n#[test]\nfn bindgen_test_layout_lldiv_t() {\n    assert_eq!(\n        ::core::mem::size_of::<lldiv_t>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(lldiv_t))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<lldiv_t>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(lldiv_t))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<lldiv_t>())).quot as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(lldiv_t),\n            \"::\",\n            stringify!(quot)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<lldiv_t>())).rem as *const _ as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(lldiv_t),\n            \"::\",\n            stringify!(rem)\n        )\n    );\n}\nextern \"C\" {\n    pub fn __ctype_get_mb_cur_max() -> usize;\n}\nextern \"C\" {\n    pub fn atof(__nptr: *const ::core::ffi::c_char) -> f64;\n}\nextern \"C\" {\n    pub fn atoi(__nptr: *const ::core::ffi::c_char) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn atol(__nptr: *const ::core::ffi::c_char) -> ::core::ffi::c_long;\n}\nextern \"C\" {\n    pub fn atoll(__nptr: *const ::core::ffi::c_char) -> ::core::ffi::c_longlong;\n}\nextern \"C\" {\n    pub fn strtod(\n        __nptr: *const ::core::ffi::c_char,\n        __endptr: *mut *mut ::core::ffi::c_char,\n    ) -> f64;\n}\nextern \"C\" {\n    pub fn strtof(\n        __nptr: *const ::core::ffi::c_char,\n        __endptr: *mut *mut ::core::ffi::c_char,\n    ) -> f32;\n}\nextern \"C\" {\n    pub fn strtold(\n        __nptr: *const ::core::ffi::c_char,\n        __endptr: *mut *mut ::core::ffi::c_char,\n    ) -> f64;\n}\nextern \"C\" {\n    pub fn strtol(\n        __nptr: *const ::core::ffi::c_char,\n        __endptr: *mut *mut ::core::ffi::c_char,\n        __base: ::core::ffi::c_int,\n    ) -> ::core::ffi::c_long;\n}\nextern \"C\" {\n    pub fn strtoul(\n        __nptr: *const ::core::ffi::c_char,\n        __endptr: *mut *mut ::core::ffi::c_char,\n        __base: ::core::ffi::c_int,\n    ) -> ::core::ffi::c_ulong;\n}\nextern \"C\" {\n    pub fn strtoq(\n        __nptr: *const ::core::ffi::c_char,\n        __endptr: *mut *mut ::core::ffi::c_char,\n        __base: ::core::ffi::c_int,\n    ) -> ::core::ffi::c_longlong;\n}\nextern \"C\" {\n    pub fn strtouq(\n        __nptr: *const ::core::ffi::c_char,\n        __endptr: *mut *mut ::core::ffi::c_char,\n        __base: ::core::ffi::c_int,\n    ) -> ::core::ffi::c_ulonglong;\n}\nextern \"C\" {\n    pub fn strtoll(\n        __nptr: *const ::core::ffi::c_char,\n        __endptr: *mut *mut ::core::ffi::c_char,\n        __base: ::core::ffi::c_int,\n    ) -> ::core::ffi::c_longlong;\n}\nextern \"C\" {\n    pub fn strtoull(\n        __nptr: *const ::core::ffi::c_char,\n        __endptr: *mut *mut ::core::ffi::c_char,\n        __base: ::core::ffi::c_int,\n    ) -> ::core::ffi::c_ulonglong;\n}\nextern \"C\" {\n    pub fn l64a(__n: ::core::ffi::c_long) -> *mut ::core::ffi::c_char;\n}\nextern \"C\" {\n    pub fn a64l(__s: *const ::core::ffi::c_char) -> ::core::ffi::c_long;\n}\npub type u_char = __u_char;\npub type u_short = __u_short;\npub type u_int = __u_int;\npub type u_long = __u_long;\npub type quad_t = __quad_t;\npub type u_quad_t = __u_quad_t;\npub type fsid_t = __fsid_t;\npub type loff_t = __loff_t;\npub type ino_t = __ino_t;\npub type dev_t = __dev_t;\npub type gid_t = __gid_t;\npub type mode_t = __mode_t;\npub type nlink_t = __nlink_t;\npub type uid_t = __uid_t;\npub type off_t = __off_t;\npub type pid_t = __pid_t;\npub type id_t = __id_t;\npub type daddr_t = __daddr_t;\npub type caddr_t = __caddr_t;\npub type key_t = __key_t;\npub type clock_t = __clock_t;\npub type time_t = __time_t;\npub type clockid_t = __clockid_t;\npub type timer_t = __timer_t;\npub type ulong = ::core::ffi::c_ulong;\npub type ushort = ::core::ffi::c_ushort;\npub type uint = ::core::ffi::c_uint;\npub type u_int8_t = ::core::ffi::c_uchar;\npub type u_int16_t = ::core::ffi::c_ushort;\npub type u_int32_t = ::core::ffi::c_uint;\npub type u_int64_t = ::core::ffi::c_ulong;\npub type register_t = ::core::ffi::c_long;\npub type __sig_atomic_t = ::core::ffi::c_int;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __sigset_t {\n    pub __val: [::core::ffi::c_ulong; 16usize],\n}\n#[test]\nfn bindgen_test_layout___sigset_t() {\n    assert_eq!(\n        ::core::mem::size_of::<__sigset_t>(),\n        128usize,\n        concat!(\"Size of: \", stringify!(__sigset_t))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<__sigset_t>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__sigset_t))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<__sigset_t>())).__val as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__sigset_t),\n            \"::\",\n            stringify!(__val)\n        )\n    );\n}\npub type sigset_t = __sigset_t;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct timespec {\n    pub tv_sec: __time_t,\n    pub tv_nsec: __syscall_slong_t,\n}\n#[test]\nfn bindgen_test_layout_timespec() {\n    assert_eq!(\n        ::core::mem::size_of::<timespec>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(timespec))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<timespec>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(timespec))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<timespec>())).tv_sec as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(timespec),\n            \"::\",\n            stringify!(tv_sec)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<timespec>())).tv_nsec as *const _ as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(timespec),\n            \"::\",\n            stringify!(tv_nsec)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct timeval {\n    pub tv_sec: __time_t,\n    pub tv_usec: __suseconds_t,\n}\n#[test]\nfn bindgen_test_layout_timeval() {\n    assert_eq!(\n        ::core::mem::size_of::<timeval>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(timeval))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<timeval>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(timeval))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<timeval>())).tv_sec as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(timeval),\n            \"::\",\n            stringify!(tv_sec)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<timeval>())).tv_usec as *const _ as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(timeval),\n            \"::\",\n            stringify!(tv_usec)\n        )\n    );\n}\npub type suseconds_t = __suseconds_t;\npub type __fd_mask = ::core::ffi::c_long;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct fd_set {\n    pub __fds_bits: [__fd_mask; 16usize],\n}\n#[test]\nfn bindgen_test_layout_fd_set() {\n    assert_eq!(\n        ::core::mem::size_of::<fd_set>(),\n        128usize,\n        concat!(\"Size of: \", stringify!(fd_set))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<fd_set>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(fd_set))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<fd_set>())).__fds_bits as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(fd_set),\n            \"::\",\n            stringify!(__fds_bits)\n        )\n    );\n}\npub type fd_mask = __fd_mask;\nextern \"C\" {\n    pub fn select(\n        __nfds: ::core::ffi::c_int,\n        __readfds: *mut fd_set,\n        __writefds: *mut fd_set,\n        __exceptfds: *mut fd_set,\n        __timeout: *mut timeval,\n    ) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn pselect(\n        __nfds: ::core::ffi::c_int,\n        __readfds: *mut fd_set,\n        __writefds: *mut fd_set,\n        __exceptfds: *mut fd_set,\n        __timeout: *const timespec,\n        __sigmask: *const __sigset_t,\n    ) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn gnu_dev_major(__dev: ::core::ffi::c_ulonglong) -> ::core::ffi::c_uint;\n}\nextern \"C\" {\n    pub fn gnu_dev_minor(__dev: ::core::ffi::c_ulonglong) -> ::core::ffi::c_uint;\n}\nextern \"C\" {\n    pub fn gnu_dev_makedev(\n        __major: ::core::ffi::c_uint,\n        __minor: ::core::ffi::c_uint,\n    ) -> ::core::ffi::c_ulonglong;\n}\npub type blksize_t = __blksize_t;\npub type blkcnt_t = __blkcnt_t;\npub type fsblkcnt_t = __fsblkcnt_t;\npub type fsfilcnt_t = __fsfilcnt_t;\npub type pthread_t = ::core::ffi::c_ulong;\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pthread_attr_t {\n    pub __size: [::core::ffi::c_char; 56usize],\n    pub __align: ::core::ffi::c_long,\n    _bindgen_union_align: [u64; 7usize],\n}\n#[test]\nfn bindgen_test_layout_pthread_attr_t() {\n    assert_eq!(\n        ::core::mem::size_of::<pthread_attr_t>(),\n        56usize,\n        concat!(\"Size of: \", stringify!(pthread_attr_t))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<pthread_attr_t>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pthread_attr_t))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<pthread_attr_t>())).__size as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_attr_t),\n            \"::\",\n            stringify!(__size)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<pthread_attr_t>())).__align as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_attr_t),\n            \"::\",\n            stringify!(__align)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct __pthread_internal_list {\n    pub __prev: *mut __pthread_internal_list,\n    pub __next: *mut __pthread_internal_list,\n}\n#[test]\nfn bindgen_test_layout___pthread_internal_list() {\n    assert_eq!(\n        ::core::mem::size_of::<__pthread_internal_list>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(__pthread_internal_list))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<__pthread_internal_list>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(__pthread_internal_list))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<__pthread_internal_list>())).__prev as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__pthread_internal_list),\n            \"::\",\n            stringify!(__prev)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<__pthread_internal_list>())).__next as *const _ as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(__pthread_internal_list),\n            \"::\",\n            stringify!(__next)\n        )\n    );\n}\npub type __pthread_list_t = __pthread_internal_list;\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pthread_mutex_t {\n    pub __data: pthread_mutex_t___pthread_mutex_s,\n    pub __size: [::core::ffi::c_char; 40usize],\n    pub __align: ::core::ffi::c_long,\n    _bindgen_union_align: [u64; 5usize],\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pthread_mutex_t___pthread_mutex_s {\n    pub __lock: ::core::ffi::c_int,\n    pub __count: ::core::ffi::c_uint,\n    pub __owner: ::core::ffi::c_int,\n    pub __nusers: ::core::ffi::c_uint,\n    pub __kind: ::core::ffi::c_int,\n    pub __spins: ::core::ffi::c_short,\n    pub __elision: ::core::ffi::c_short,\n    pub __list: __pthread_list_t,\n}\n#[test]\nfn bindgen_test_layout_pthread_mutex_t___pthread_mutex_s() {\n    assert_eq!(\n        ::core::mem::size_of::<pthread_mutex_t___pthread_mutex_s>(),\n        40usize,\n        concat!(\"Size of: \", stringify!(pthread_mutex_t___pthread_mutex_s))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<pthread_mutex_t___pthread_mutex_s>(),\n        8usize,\n        concat!(\n            \"Alignment of \",\n            stringify!(pthread_mutex_t___pthread_mutex_s)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<pthread_mutex_t___pthread_mutex_s>())).__lock as *const _\n                as usize\n        },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_mutex_t___pthread_mutex_s),\n            \"::\",\n            stringify!(__lock)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<pthread_mutex_t___pthread_mutex_s>())).__count as *const _\n                as usize\n        },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_mutex_t___pthread_mutex_s),\n            \"::\",\n            stringify!(__count)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<pthread_mutex_t___pthread_mutex_s>())).__owner as *const _\n                as usize\n        },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_mutex_t___pthread_mutex_s),\n            \"::\",\n            stringify!(__owner)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<pthread_mutex_t___pthread_mutex_s>())).__nusers as *const _\n                as usize\n        },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_mutex_t___pthread_mutex_s),\n            \"::\",\n            stringify!(__nusers)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<pthread_mutex_t___pthread_mutex_s>())).__kind as *const _\n                as usize\n        },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_mutex_t___pthread_mutex_s),\n            \"::\",\n            stringify!(__kind)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<pthread_mutex_t___pthread_mutex_s>())).__spins as *const _\n                as usize\n        },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_mutex_t___pthread_mutex_s),\n            \"::\",\n            stringify!(__spins)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<pthread_mutex_t___pthread_mutex_s>())).__elision as *const _\n                as usize\n        },\n        22usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_mutex_t___pthread_mutex_s),\n            \"::\",\n            stringify!(__elision)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<pthread_mutex_t___pthread_mutex_s>())).__list as *const _\n                as usize\n        },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_mutex_t___pthread_mutex_s),\n            \"::\",\n            stringify!(__list)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pthread_mutex_t() {\n    assert_eq!(\n        ::core::mem::size_of::<pthread_mutex_t>(),\n        40usize,\n        concat!(\"Size of: \", stringify!(pthread_mutex_t))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<pthread_mutex_t>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pthread_mutex_t))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<pthread_mutex_t>())).__data as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_mutex_t),\n            \"::\",\n            stringify!(__data)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<pthread_mutex_t>())).__size as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_mutex_t),\n            \"::\",\n            stringify!(__size)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<pthread_mutex_t>())).__align as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_mutex_t),\n            \"::\",\n            stringify!(__align)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pthread_mutexattr_t {\n    pub __size: [::core::ffi::c_char; 4usize],\n    pub __align: ::core::ffi::c_int,\n    _bindgen_union_align: u32,\n}\n#[test]\nfn bindgen_test_layout_pthread_mutexattr_t() {\n    assert_eq!(\n        ::core::mem::size_of::<pthread_mutexattr_t>(),\n        4usize,\n        concat!(\"Size of: \", stringify!(pthread_mutexattr_t))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<pthread_mutexattr_t>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pthread_mutexattr_t))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<pthread_mutexattr_t>())).__size as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_mutexattr_t),\n            \"::\",\n            stringify!(__size)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<pthread_mutexattr_t>())).__align as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_mutexattr_t),\n            \"::\",\n            stringify!(__align)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pthread_cond_t {\n    pub __data: pthread_cond_t__bindgen_ty_1,\n    pub __size: [::core::ffi::c_char; 48usize],\n    pub __align: ::core::ffi::c_longlong,\n    _bindgen_union_align: [u64; 6usize],\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pthread_cond_t__bindgen_ty_1 {\n    pub __lock: ::core::ffi::c_int,\n    pub __futex: ::core::ffi::c_uint,\n    pub __total_seq: ::core::ffi::c_ulonglong,\n    pub __wakeup_seq: ::core::ffi::c_ulonglong,\n    pub __woken_seq: ::core::ffi::c_ulonglong,\n    pub __mutex: *mut ::core::ffi::c_void,\n    pub __nwaiters: ::core::ffi::c_uint,\n    pub __broadcast_seq: ::core::ffi::c_uint,\n}\n#[test]\nfn bindgen_test_layout_pthread_cond_t__bindgen_ty_1() {\n    assert_eq!(\n        ::core::mem::size_of::<pthread_cond_t__bindgen_ty_1>(),\n        48usize,\n        concat!(\"Size of: \", stringify!(pthread_cond_t__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<pthread_cond_t__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pthread_cond_t__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<pthread_cond_t__bindgen_ty_1>())).__lock as *const _ as usize\n        },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_cond_t__bindgen_ty_1),\n            \"::\",\n            stringify!(__lock)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<pthread_cond_t__bindgen_ty_1>())).__futex as *const _ as usize\n        },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_cond_t__bindgen_ty_1),\n            \"::\",\n            stringify!(__futex)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<pthread_cond_t__bindgen_ty_1>())).__total_seq as *const _\n                as usize\n        },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_cond_t__bindgen_ty_1),\n            \"::\",\n            stringify!(__total_seq)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<pthread_cond_t__bindgen_ty_1>())).__wakeup_seq as *const _\n                as usize\n        },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_cond_t__bindgen_ty_1),\n            \"::\",\n            stringify!(__wakeup_seq)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<pthread_cond_t__bindgen_ty_1>())).__woken_seq as *const _\n                as usize\n        },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_cond_t__bindgen_ty_1),\n            \"::\",\n            stringify!(__woken_seq)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<pthread_cond_t__bindgen_ty_1>())).__mutex as *const _ as usize\n        },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_cond_t__bindgen_ty_1),\n            \"::\",\n            stringify!(__mutex)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<pthread_cond_t__bindgen_ty_1>())).__nwaiters as *const _ as usize\n        },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_cond_t__bindgen_ty_1),\n            \"::\",\n            stringify!(__nwaiters)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<pthread_cond_t__bindgen_ty_1>())).__broadcast_seq as *const _\n                as usize\n        },\n        44usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_cond_t__bindgen_ty_1),\n            \"::\",\n            stringify!(__broadcast_seq)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pthread_cond_t() {\n    assert_eq!(\n        ::core::mem::size_of::<pthread_cond_t>(),\n        48usize,\n        concat!(\"Size of: \", stringify!(pthread_cond_t))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<pthread_cond_t>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pthread_cond_t))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<pthread_cond_t>())).__data as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_cond_t),\n            \"::\",\n            stringify!(__data)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<pthread_cond_t>())).__size as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_cond_t),\n            \"::\",\n            stringify!(__size)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<pthread_cond_t>())).__align as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_cond_t),\n            \"::\",\n            stringify!(__align)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pthread_condattr_t {\n    pub __size: [::core::ffi::c_char; 4usize],\n    pub __align: ::core::ffi::c_int,\n    _bindgen_union_align: u32,\n}\n#[test]\nfn bindgen_test_layout_pthread_condattr_t() {\n    assert_eq!(\n        ::core::mem::size_of::<pthread_condattr_t>(),\n        4usize,\n        concat!(\"Size of: \", stringify!(pthread_condattr_t))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<pthread_condattr_t>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pthread_condattr_t))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<pthread_condattr_t>())).__size as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_condattr_t),\n            \"::\",\n            stringify!(__size)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<pthread_condattr_t>())).__align as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_condattr_t),\n            \"::\",\n            stringify!(__align)\n        )\n    );\n}\npub type pthread_key_t = ::core::ffi::c_uint;\npub type pthread_once_t = ::core::ffi::c_int;\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pthread_rwlock_t {\n    pub __data: pthread_rwlock_t__bindgen_ty_1,\n    pub __size: [::core::ffi::c_char; 56usize],\n    pub __align: ::core::ffi::c_long,\n    _bindgen_union_align: [u64; 7usize],\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct pthread_rwlock_t__bindgen_ty_1 {\n    pub __lock: ::core::ffi::c_int,\n    pub __nr_readers: ::core::ffi::c_uint,\n    pub __readers_wakeup: ::core::ffi::c_uint,\n    pub __writer_wakeup: ::core::ffi::c_uint,\n    pub __nr_readers_queued: ::core::ffi::c_uint,\n    pub __nr_writers_queued: ::core::ffi::c_uint,\n    pub __writer: ::core::ffi::c_int,\n    pub __shared: ::core::ffi::c_int,\n    pub __rwelision: ::core::ffi::c_schar,\n    pub __pad1: [::core::ffi::c_uchar; 7usize],\n    pub __pad2: ::core::ffi::c_ulong,\n    pub __flags: ::core::ffi::c_uint,\n}\n#[test]\nfn bindgen_test_layout_pthread_rwlock_t__bindgen_ty_1() {\n    assert_eq!(\n        ::core::mem::size_of::<pthread_rwlock_t__bindgen_ty_1>(),\n        56usize,\n        concat!(\"Size of: \", stringify!(pthread_rwlock_t__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<pthread_rwlock_t__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pthread_rwlock_t__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<pthread_rwlock_t__bindgen_ty_1>())).__lock as *const _ as usize\n        },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_rwlock_t__bindgen_ty_1),\n            \"::\",\n            stringify!(__lock)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<pthread_rwlock_t__bindgen_ty_1>())).__nr_readers as *const _\n                as usize\n        },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_rwlock_t__bindgen_ty_1),\n            \"::\",\n            stringify!(__nr_readers)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<pthread_rwlock_t__bindgen_ty_1>())).__readers_wakeup as *const _\n                as usize\n        },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_rwlock_t__bindgen_ty_1),\n            \"::\",\n            stringify!(__readers_wakeup)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<pthread_rwlock_t__bindgen_ty_1>())).__writer_wakeup as *const _\n                as usize\n        },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_rwlock_t__bindgen_ty_1),\n            \"::\",\n            stringify!(__writer_wakeup)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<pthread_rwlock_t__bindgen_ty_1>())).__nr_readers_queued\n                as *const _ as usize\n        },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_rwlock_t__bindgen_ty_1),\n            \"::\",\n            stringify!(__nr_readers_queued)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<pthread_rwlock_t__bindgen_ty_1>())).__nr_writers_queued\n                as *const _ as usize\n        },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_rwlock_t__bindgen_ty_1),\n            \"::\",\n            stringify!(__nr_writers_queued)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<pthread_rwlock_t__bindgen_ty_1>())).__writer as *const _ as usize\n        },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_rwlock_t__bindgen_ty_1),\n            \"::\",\n            stringify!(__writer)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<pthread_rwlock_t__bindgen_ty_1>())).__shared as *const _ as usize\n        },\n        28usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_rwlock_t__bindgen_ty_1),\n            \"::\",\n            stringify!(__shared)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<pthread_rwlock_t__bindgen_ty_1>())).__rwelision as *const _\n                as usize\n        },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_rwlock_t__bindgen_ty_1),\n            \"::\",\n            stringify!(__rwelision)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<pthread_rwlock_t__bindgen_ty_1>())).__pad1 as *const _ as usize\n        },\n        33usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_rwlock_t__bindgen_ty_1),\n            \"::\",\n            stringify!(__pad1)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<pthread_rwlock_t__bindgen_ty_1>())).__pad2 as *const _ as usize\n        },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_rwlock_t__bindgen_ty_1),\n            \"::\",\n            stringify!(__pad2)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<pthread_rwlock_t__bindgen_ty_1>())).__flags as *const _ as usize\n        },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_rwlock_t__bindgen_ty_1),\n            \"::\",\n            stringify!(__flags)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_pthread_rwlock_t() {\n    assert_eq!(\n        ::core::mem::size_of::<pthread_rwlock_t>(),\n        56usize,\n        concat!(\"Size of: \", stringify!(pthread_rwlock_t))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<pthread_rwlock_t>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pthread_rwlock_t))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<pthread_rwlock_t>())).__data as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_rwlock_t),\n            \"::\",\n            stringify!(__data)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<pthread_rwlock_t>())).__size as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_rwlock_t),\n            \"::\",\n            stringify!(__size)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<pthread_rwlock_t>())).__align as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_rwlock_t),\n            \"::\",\n            stringify!(__align)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pthread_rwlockattr_t {\n    pub __size: [::core::ffi::c_char; 8usize],\n    pub __align: ::core::ffi::c_long,\n    _bindgen_union_align: u64,\n}\n#[test]\nfn bindgen_test_layout_pthread_rwlockattr_t() {\n    assert_eq!(\n        ::core::mem::size_of::<pthread_rwlockattr_t>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(pthread_rwlockattr_t))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<pthread_rwlockattr_t>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pthread_rwlockattr_t))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<pthread_rwlockattr_t>())).__size as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_rwlockattr_t),\n            \"::\",\n            stringify!(__size)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<pthread_rwlockattr_t>())).__align as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_rwlockattr_t),\n            \"::\",\n            stringify!(__align)\n        )\n    );\n}\npub type pthread_spinlock_t = ::core::ffi::c_int;\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pthread_barrier_t {\n    pub __size: [::core::ffi::c_char; 32usize],\n    pub __align: ::core::ffi::c_long,\n    _bindgen_union_align: [u64; 4usize],\n}\n#[test]\nfn bindgen_test_layout_pthread_barrier_t() {\n    assert_eq!(\n        ::core::mem::size_of::<pthread_barrier_t>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(pthread_barrier_t))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<pthread_barrier_t>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(pthread_barrier_t))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<pthread_barrier_t>())).__size as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_barrier_t),\n            \"::\",\n            stringify!(__size)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<pthread_barrier_t>())).__align as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_barrier_t),\n            \"::\",\n            stringify!(__align)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union pthread_barrierattr_t {\n    pub __size: [::core::ffi::c_char; 4usize],\n    pub __align: ::core::ffi::c_int,\n    _bindgen_union_align: u32,\n}\n#[test]\nfn bindgen_test_layout_pthread_barrierattr_t() {\n    assert_eq!(\n        ::core::mem::size_of::<pthread_barrierattr_t>(),\n        4usize,\n        concat!(\"Size of: \", stringify!(pthread_barrierattr_t))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<pthread_barrierattr_t>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(pthread_barrierattr_t))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<pthread_barrierattr_t>())).__size as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_barrierattr_t),\n            \"::\",\n            stringify!(__size)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<pthread_barrierattr_t>())).__align as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(pthread_barrierattr_t),\n            \"::\",\n            stringify!(__align)\n        )\n    );\n}\nextern \"C\" {\n    pub fn random() -> ::core::ffi::c_long;\n}\nextern \"C\" {\n    pub fn srandom(__seed: ::core::ffi::c_uint);\n}\nextern \"C\" {\n    pub fn initstate(\n        __seed: ::core::ffi::c_uint,\n        __statebuf: *mut ::core::ffi::c_char,\n        __statelen: usize,\n    ) -> *mut ::core::ffi::c_char;\n}\nextern \"C\" {\n    pub fn setstate(__statebuf: *mut ::core::ffi::c_char) -> *mut ::core::ffi::c_char;\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct random_data {\n    pub fptr: *mut i32,\n    pub rptr: *mut i32,\n    pub state: *mut i32,\n    pub rand_type: ::core::ffi::c_int,\n    pub rand_deg: ::core::ffi::c_int,\n    pub rand_sep: ::core::ffi::c_int,\n    pub end_ptr: *mut i32,\n}\n#[test]\nfn bindgen_test_layout_random_data() {\n    assert_eq!(\n        ::core::mem::size_of::<random_data>(),\n        48usize,\n        concat!(\"Size of: \", stringify!(random_data))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<random_data>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(random_data))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<random_data>())).fptr as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(random_data),\n            \"::\",\n            stringify!(fptr)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<random_data>())).rptr as *const _ as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(random_data),\n            \"::\",\n            stringify!(rptr)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<random_data>())).state as *const _ as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(random_data),\n            \"::\",\n            stringify!(state)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<random_data>())).rand_type as *const _ as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(random_data),\n            \"::\",\n            stringify!(rand_type)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<random_data>())).rand_deg as *const _ as usize },\n        28usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(random_data),\n            \"::\",\n            stringify!(rand_deg)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<random_data>())).rand_sep as *const _ as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(random_data),\n            \"::\",\n            stringify!(rand_sep)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<random_data>())).end_ptr as *const _ as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(random_data),\n            \"::\",\n            stringify!(end_ptr)\n        )\n    );\n}\nextern \"C\" {\n    pub fn random_r(__buf: *mut random_data, __result: *mut i32) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn srandom_r(\n        __seed: ::core::ffi::c_uint,\n        __buf: *mut random_data,\n    ) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn initstate_r(\n        __seed: ::core::ffi::c_uint,\n        __statebuf: *mut ::core::ffi::c_char,\n        __statelen: usize,\n        __buf: *mut random_data,\n    ) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn setstate_r(\n        __statebuf: *mut ::core::ffi::c_char,\n        __buf: *mut random_data,\n    ) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn rand() -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn srand(__seed: ::core::ffi::c_uint);\n}\nextern \"C\" {\n    pub fn rand_r(__seed: *mut ::core::ffi::c_uint) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn drand48() -> f64;\n}\nextern \"C\" {\n    pub fn erand48(__xsubi: *mut ::core::ffi::c_ushort) -> f64;\n}\nextern \"C\" {\n    pub fn lrand48() -> ::core::ffi::c_long;\n}\nextern \"C\" {\n    pub fn nrand48(__xsubi: *mut ::core::ffi::c_ushort) -> ::core::ffi::c_long;\n}\nextern \"C\" {\n    pub fn mrand48() -> ::core::ffi::c_long;\n}\nextern \"C\" {\n    pub fn jrand48(__xsubi: *mut ::core::ffi::c_ushort) -> ::core::ffi::c_long;\n}\nextern \"C\" {\n    pub fn srand48(__seedval: ::core::ffi::c_long);\n}\nextern \"C\" {\n    pub fn seed48(__seed16v: *mut ::core::ffi::c_ushort) -> *mut ::core::ffi::c_ushort;\n}\nextern \"C\" {\n    pub fn lcong48(__param: *mut ::core::ffi::c_ushort);\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct drand48_data {\n    pub __x: [::core::ffi::c_ushort; 3usize],\n    pub __old_x: [::core::ffi::c_ushort; 3usize],\n    pub __c: ::core::ffi::c_ushort,\n    pub __init: ::core::ffi::c_ushort,\n    pub __a: ::core::ffi::c_ulonglong,\n}\n#[test]\nfn bindgen_test_layout_drand48_data() {\n    assert_eq!(\n        ::core::mem::size_of::<drand48_data>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(drand48_data))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<drand48_data>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(drand48_data))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<drand48_data>())).__x as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(drand48_data),\n            \"::\",\n            stringify!(__x)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<drand48_data>())).__old_x as *const _ as usize },\n        6usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(drand48_data),\n            \"::\",\n            stringify!(__old_x)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<drand48_data>())).__c as *const _ as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(drand48_data),\n            \"::\",\n            stringify!(__c)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<drand48_data>())).__init as *const _ as usize },\n        14usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(drand48_data),\n            \"::\",\n            stringify!(__init)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<drand48_data>())).__a as *const _ as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(drand48_data),\n            \"::\",\n            stringify!(__a)\n        )\n    );\n}\nextern \"C\" {\n    pub fn drand48_r(__buffer: *mut drand48_data, __result: *mut f64) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn erand48_r(\n        __xsubi: *mut ::core::ffi::c_ushort,\n        __buffer: *mut drand48_data,\n        __result: *mut f64,\n    ) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn lrand48_r(\n        __buffer: *mut drand48_data,\n        __result: *mut ::core::ffi::c_long,\n    ) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn nrand48_r(\n        __xsubi: *mut ::core::ffi::c_ushort,\n        __buffer: *mut drand48_data,\n        __result: *mut ::core::ffi::c_long,\n    ) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn mrand48_r(\n        __buffer: *mut drand48_data,\n        __result: *mut ::core::ffi::c_long,\n    ) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn jrand48_r(\n        __xsubi: *mut ::core::ffi::c_ushort,\n        __buffer: *mut drand48_data,\n        __result: *mut ::core::ffi::c_long,\n    ) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn srand48_r(\n        __seedval: ::core::ffi::c_long,\n        __buffer: *mut drand48_data,\n    ) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn seed48_r(\n        __seed16v: *mut ::core::ffi::c_ushort,\n        __buffer: *mut drand48_data,\n    ) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn lcong48_r(\n        __param: *mut ::core::ffi::c_ushort,\n        __buffer: *mut drand48_data,\n    ) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn malloc(__size: usize) -> *mut ::core::ffi::c_void;\n}\nextern \"C\" {\n    pub fn calloc(__nmemb: usize, __size: usize) -> *mut ::core::ffi::c_void;\n}\nextern \"C\" {\n    pub fn realloc(\n        __ptr: *mut ::core::ffi::c_void,\n        __size: usize,\n    ) -> *mut ::core::ffi::c_void;\n}\nextern \"C\" {\n    pub fn free(__ptr: *mut ::core::ffi::c_void);\n}\nextern \"C\" {\n    pub fn cfree(__ptr: *mut ::core::ffi::c_void);\n}\nextern \"C\" {\n    pub fn alloca(__size: usize) -> *mut ::core::ffi::c_void;\n}\nextern \"C\" {\n    pub fn valloc(__size: usize) -> *mut ::core::ffi::c_void;\n}\nextern \"C\" {\n    pub fn posix_memalign(\n        __memptr: *mut *mut ::core::ffi::c_void,\n        __alignment: usize,\n        __size: usize,\n    ) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn aligned_alloc(__alignment: usize, __size: usize) -> *mut ::core::ffi::c_void;\n}\nextern \"C\" {\n    pub fn abort();\n}\nextern \"C\" {\n    pub fn atexit(__func: ::core::option::Option<unsafe extern \"C\" fn()>) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn at_quick_exit(\n        __func: ::core::option::Option<unsafe extern \"C\" fn()>,\n    ) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn on_exit(\n        __func: ::core::option::Option<\n            unsafe extern \"C\" fn(\n                __status: ::core::ffi::c_int,\n                __arg: *mut ::core::ffi::c_void,\n            ),\n        >,\n        __arg: *mut ::core::ffi::c_void,\n    ) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn exit(__status: ::core::ffi::c_int);\n}\nextern \"C\" {\n    pub fn quick_exit(__status: ::core::ffi::c_int);\n}\nextern \"C\" {\n    pub fn _Exit(__status: ::core::ffi::c_int);\n}\nextern \"C\" {\n    pub fn getenv(__name: *const ::core::ffi::c_char) -> *mut ::core::ffi::c_char;\n}\nextern \"C\" {\n    pub fn putenv(__string: *mut ::core::ffi::c_char) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn setenv(\n        __name: *const ::core::ffi::c_char,\n        __value: *const ::core::ffi::c_char,\n        __replace: ::core::ffi::c_int,\n    ) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn unsetenv(__name: *const ::core::ffi::c_char) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn clearenv() -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn mktemp(__template: *mut ::core::ffi::c_char) -> *mut ::core::ffi::c_char;\n}\nextern \"C\" {\n    pub fn mkstemp(__template: *mut ::core::ffi::c_char) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn mkstemps(\n        __template: *mut ::core::ffi::c_char,\n        __suffixlen: ::core::ffi::c_int,\n    ) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn mkdtemp(__template: *mut ::core::ffi::c_char) -> *mut ::core::ffi::c_char;\n}\nextern \"C\" {\n    pub fn system(__command: *const ::core::ffi::c_char) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn realpath(\n        __name: *const ::core::ffi::c_char,\n        __resolved: *mut ::core::ffi::c_char,\n    ) -> *mut ::core::ffi::c_char;\n}\npub type __compar_fn_t = ::core::option::Option<\n    unsafe extern \"C\" fn(arg1: *const ::core::ffi::c_void, arg2: *const ::core::ffi::c_void)\n        -> ::core::ffi::c_int,\n>;\nextern \"C\" {\n    pub fn bsearch(\n        __key: *const ::core::ffi::c_void,\n        __base: *const ::core::ffi::c_void,\n        __nmemb: usize,\n        __size: usize,\n        __compar: __compar_fn_t,\n    ) -> *mut ::core::ffi::c_void;\n}\nextern \"C\" {\n    pub fn qsort(\n        __base: *mut ::core::ffi::c_void,\n        __nmemb: usize,\n        __size: usize,\n        __compar: __compar_fn_t,\n    );\n}\nextern \"C\" {\n    pub fn abs(__x: ::core::ffi::c_int) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn labs(__x: ::core::ffi::c_long) -> ::core::ffi::c_long;\n}\nextern \"C\" {\n    pub fn llabs(__x: ::core::ffi::c_longlong) -> ::core::ffi::c_longlong;\n}\nextern \"C\" {\n    pub fn div(__numer: ::core::ffi::c_int, __denom: ::core::ffi::c_int) -> div_t;\n}\nextern \"C\" {\n    pub fn ldiv(__numer: ::core::ffi::c_long, __denom: ::core::ffi::c_long) -> ldiv_t;\n}\nextern \"C\" {\n    pub fn lldiv(\n        __numer: ::core::ffi::c_longlong,\n        __denom: ::core::ffi::c_longlong,\n    ) -> lldiv_t;\n}\nextern \"C\" {\n    pub fn ecvt(\n        __value: f64,\n        __ndigit: ::core::ffi::c_int,\n        __decpt: *mut ::core::ffi::c_int,\n        __sign: *mut ::core::ffi::c_int,\n    ) -> *mut ::core::ffi::c_char;\n}\nextern \"C\" {\n    pub fn fcvt(\n        __value: f64,\n        __ndigit: ::core::ffi::c_int,\n        __decpt: *mut ::core::ffi::c_int,\n        __sign: *mut ::core::ffi::c_int,\n    ) -> *mut ::core::ffi::c_char;\n}\nextern \"C\" {\n    pub fn gcvt(\n        __value: f64,\n        __ndigit: ::core::ffi::c_int,\n        __buf: *mut ::core::ffi::c_char,\n    ) -> *mut ::core::ffi::c_char;\n}\nextern \"C\" {\n    pub fn qecvt(\n        __value: f64,\n        __ndigit: ::core::ffi::c_int,\n        __decpt: *mut ::core::ffi::c_int,\n        __sign: *mut ::core::ffi::c_int,\n    ) -> *mut ::core::ffi::c_char;\n}\nextern \"C\" {\n    pub fn qfcvt(\n        __value: f64,\n        __ndigit: ::core::ffi::c_int,\n        __decpt: *mut ::core::ffi::c_int,\n        __sign: *mut ::core::ffi::c_int,\n    ) -> *mut ::core::ffi::c_char;\n}\nextern \"C\" {\n    pub fn qgcvt(\n        __value: f64,\n        __ndigit: ::core::ffi::c_int,\n        __buf: *mut ::core::ffi::c_char,\n    ) -> *mut ::core::ffi::c_char;\n}\nextern \"C\" {\n    pub fn ecvt_r(\n        __value: f64,\n        __ndigit: ::core::ffi::c_int,\n        __decpt: *mut ::core::ffi::c_int,\n        __sign: *mut ::core::ffi::c_int,\n        __buf: *mut ::core::ffi::c_char,\n        __len: usize,\n    ) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn fcvt_r(\n        __value: f64,\n        __ndigit: ::core::ffi::c_int,\n        __decpt: *mut ::core::ffi::c_int,\n        __sign: *mut ::core::ffi::c_int,\n        __buf: *mut ::core::ffi::c_char,\n        __len: usize,\n    ) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn qecvt_r(\n        __value: f64,\n        __ndigit: ::core::ffi::c_int,\n        __decpt: *mut ::core::ffi::c_int,\n        __sign: *mut ::core::ffi::c_int,\n        __buf: *mut ::core::ffi::c_char,\n        __len: usize,\n    ) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn qfcvt_r(\n        __value: f64,\n        __ndigit: ::core::ffi::c_int,\n        __decpt: *mut ::core::ffi::c_int,\n        __sign: *mut ::core::ffi::c_int,\n        __buf: *mut ::core::ffi::c_char,\n        __len: usize,\n    ) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn mblen(__s: *const ::core::ffi::c_char, __n: usize) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn mbtowc(\n        __pwc: *mut wchar_t,\n        __s: *const ::core::ffi::c_char,\n        __n: usize,\n    ) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn wctomb(__s: *mut ::core::ffi::c_char, __wchar: wchar_t) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn mbstowcs(__pwcs: *mut wchar_t, __s: *const ::core::ffi::c_char, __n: usize) -> usize;\n}\nextern \"C\" {\n    pub fn wcstombs(__s: *mut ::core::ffi::c_char, __pwcs: *const wchar_t, __n: usize) -> usize;\n}\nextern \"C\" {\n    pub fn rpmatch(__response: *const ::core::ffi::c_char) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn getsubopt(\n        __optionp: *mut *mut ::core::ffi::c_char,\n        __tokens: *const *const ::core::ffi::c_char,\n        __valuep: *mut *mut ::core::ffi::c_char,\n    ) -> ::core::ffi::c_int;\n}\nextern \"C\" {\n    pub fn getloadavg(__loadavg: *mut f64, __nelem: ::core::ffi::c_int)\n        -> ::core::ffi::c_int;\n}\n/// *\n/// Digital audio interface\t\t\t\t\t    *\n/// *\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct snd_aes_iec958 {\n    pub status: [::core::ffi::c_uchar; 24usize],\n    pub subcode: [::core::ffi::c_uchar; 147usize],\n    pub pad: ::core::ffi::c_uchar,\n    pub dig_subframe: [::core::ffi::c_uchar; 4usize],\n}\n#[test]\nfn bindgen_test_layout_snd_aes_iec958() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_aes_iec958>(),\n        176usize,\n        concat!(\"Size of: \", stringify!(snd_aes_iec958))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_aes_iec958>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(snd_aes_iec958))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_aes_iec958>())).status as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_aes_iec958),\n            \"::\",\n            stringify!(status)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_aes_iec958>())).subcode as *const _ as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_aes_iec958),\n            \"::\",\n            stringify!(subcode)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_aes_iec958>())).pad as *const _ as usize },\n        171usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_aes_iec958),\n            \"::\",\n            stringify!(pad)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_aes_iec958>())).dig_subframe as *const _ as usize },\n        172usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_aes_iec958),\n            \"::\",\n            stringify!(dig_subframe)\n        )\n    );\n}\n/// *\n/// CEA-861 Audio InfoFrame. Used in HDMI and DisplayPort\t\t    *\n/// *\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct snd_cea_861_aud_if {\n    pub db1_ct_cc: ::core::ffi::c_uchar,\n    pub db2_sf_ss: ::core::ffi::c_uchar,\n    pub db3: ::core::ffi::c_uchar,\n    pub db4_ca: ::core::ffi::c_uchar,\n    pub db5_dminh_lsv: ::core::ffi::c_uchar,\n}\n#[test]\nfn bindgen_test_layout_snd_cea_861_aud_if() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_cea_861_aud_if>(),\n        5usize,\n        concat!(\"Size of: \", stringify!(snd_cea_861_aud_if))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_cea_861_aud_if>(),\n        1usize,\n        concat!(\"Alignment of \", stringify!(snd_cea_861_aud_if))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_cea_861_aud_if>())).db1_ct_cc as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_cea_861_aud_if),\n            \"::\",\n            stringify!(db1_ct_cc)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_cea_861_aud_if>())).db2_sf_ss as *const _ as usize },\n        1usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_cea_861_aud_if),\n            \"::\",\n            stringify!(db2_sf_ss)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_cea_861_aud_if>())).db3 as *const _ as usize },\n        2usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_cea_861_aud_if),\n            \"::\",\n            stringify!(db3)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_cea_861_aud_if>())).db4_ca as *const _ as usize },\n        3usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_cea_861_aud_if),\n            \"::\",\n            stringify!(db4_ca)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_cea_861_aud_if>())).db5_dminh_lsv as *const _ as usize\n        },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_cea_861_aud_if),\n            \"::\",\n            stringify!(db5_dminh_lsv)\n        )\n    );\n}\npub const SNDRV_HWDEP_IFACE_OPL2: _bindgen_ty_1 = 0;\npub const SNDRV_HWDEP_IFACE_OPL3: _bindgen_ty_1 = 1;\npub const SNDRV_HWDEP_IFACE_OPL4: _bindgen_ty_1 = 2;\npub const SNDRV_HWDEP_IFACE_SB16CSP: _bindgen_ty_1 = 3;\npub const SNDRV_HWDEP_IFACE_EMU10K1: _bindgen_ty_1 = 4;\npub const SNDRV_HWDEP_IFACE_YSS225: _bindgen_ty_1 = 5;\npub const SNDRV_HWDEP_IFACE_ICS2115: _bindgen_ty_1 = 6;\npub const SNDRV_HWDEP_IFACE_SSCAPE: _bindgen_ty_1 = 7;\npub const SNDRV_HWDEP_IFACE_VX: _bindgen_ty_1 = 8;\npub const SNDRV_HWDEP_IFACE_MIXART: _bindgen_ty_1 = 9;\npub const SNDRV_HWDEP_IFACE_USX2Y: _bindgen_ty_1 = 10;\npub const SNDRV_HWDEP_IFACE_EMUX_WAVETABLE: _bindgen_ty_1 = 11;\npub const SNDRV_HWDEP_IFACE_BLUETOOTH: _bindgen_ty_1 = 12;\npub const SNDRV_HWDEP_IFACE_USX2Y_PCM: _bindgen_ty_1 = 13;\npub const SNDRV_HWDEP_IFACE_PCXHR: _bindgen_ty_1 = 14;\npub const SNDRV_HWDEP_IFACE_SB_RC: _bindgen_ty_1 = 15;\npub const SNDRV_HWDEP_IFACE_HDA: _bindgen_ty_1 = 16;\npub const SNDRV_HWDEP_IFACE_USB_STREAM: _bindgen_ty_1 = 17;\npub const SNDRV_HWDEP_IFACE_FW_DICE: _bindgen_ty_1 = 18;\npub const SNDRV_HWDEP_IFACE_FW_FIREWORKS: _bindgen_ty_1 = 19;\npub const SNDRV_HWDEP_IFACE_FW_BEBOB: _bindgen_ty_1 = 20;\npub const SNDRV_HWDEP_IFACE_FW_OXFW: _bindgen_ty_1 = 21;\npub const SNDRV_HWDEP_IFACE_FW_DIGI00X: _bindgen_ty_1 = 22;\npub const SNDRV_HWDEP_IFACE_FW_TASCAM: _bindgen_ty_1 = 23;\npub const SNDRV_HWDEP_IFACE_LINE6: _bindgen_ty_1 = 24;\npub const SNDRV_HWDEP_IFACE_FW_MOTU: _bindgen_ty_1 = 25;\npub const SNDRV_HWDEP_IFACE_FW_FIREFACE: _bindgen_ty_1 = 26;\npub const SNDRV_HWDEP_IFACE_LAST: _bindgen_ty_1 = 26;\npub type _bindgen_ty_1 = u32;\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct snd_hwdep_info {\n    pub device: ::core::ffi::c_uint,\n    pub card: ::core::ffi::c_int,\n    pub id: [::core::ffi::c_uchar; 64usize],\n    pub name: [::core::ffi::c_uchar; 80usize],\n    pub iface: ::core::ffi::c_int,\n    pub reserved: [::core::ffi::c_uchar; 64usize],\n}\n#[test]\nfn bindgen_test_layout_snd_hwdep_info() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_hwdep_info>(),\n        220usize,\n        concat!(\"Size of: \", stringify!(snd_hwdep_info))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_hwdep_info>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(snd_hwdep_info))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_hwdep_info>())).device as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_hwdep_info),\n            \"::\",\n            stringify!(device)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_hwdep_info>())).card as *const _ as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_hwdep_info),\n            \"::\",\n            stringify!(card)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_hwdep_info>())).id as *const _ as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_hwdep_info),\n            \"::\",\n            stringify!(id)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_hwdep_info>())).name as *const _ as usize },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_hwdep_info),\n            \"::\",\n            stringify!(name)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_hwdep_info>())).iface as *const _ as usize },\n        152usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_hwdep_info),\n            \"::\",\n            stringify!(iface)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_hwdep_info>())).reserved as *const _ as usize },\n        156usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_hwdep_info),\n            \"::\",\n            stringify!(reserved)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct snd_hwdep_dsp_status {\n    pub version: ::core::ffi::c_uint,\n    pub id: [::core::ffi::c_uchar; 32usize],\n    pub num_dsps: ::core::ffi::c_uint,\n    pub dsp_loaded: ::core::ffi::c_uint,\n    pub chip_ready: ::core::ffi::c_uint,\n    pub reserved: [::core::ffi::c_uchar; 16usize],\n}\n#[test]\nfn bindgen_test_layout_snd_hwdep_dsp_status() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_hwdep_dsp_status>(),\n        64usize,\n        concat!(\"Size of: \", stringify!(snd_hwdep_dsp_status))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_hwdep_dsp_status>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(snd_hwdep_dsp_status))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_hwdep_dsp_status>())).version as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_hwdep_dsp_status),\n            \"::\",\n            stringify!(version)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_hwdep_dsp_status>())).id as *const _ as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_hwdep_dsp_status),\n            \"::\",\n            stringify!(id)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_hwdep_dsp_status>())).num_dsps as *const _ as usize },\n        36usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_hwdep_dsp_status),\n            \"::\",\n            stringify!(num_dsps)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_hwdep_dsp_status>())).dsp_loaded as *const _ as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_hwdep_dsp_status),\n            \"::\",\n            stringify!(dsp_loaded)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_hwdep_dsp_status>())).chip_ready as *const _ as usize },\n        44usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_hwdep_dsp_status),\n            \"::\",\n            stringify!(chip_ready)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_hwdep_dsp_status>())).reserved as *const _ as usize },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_hwdep_dsp_status),\n            \"::\",\n            stringify!(reserved)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct snd_hwdep_dsp_image {\n    pub index: ::core::ffi::c_uint,\n    pub name: [::core::ffi::c_uchar; 64usize],\n    pub image: *mut ::core::ffi::c_uchar,\n    pub length: usize,\n    pub driver_data: ::core::ffi::c_ulong,\n}\n#[test]\nfn bindgen_test_layout_snd_hwdep_dsp_image() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_hwdep_dsp_image>(),\n        96usize,\n        concat!(\"Size of: \", stringify!(snd_hwdep_dsp_image))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_hwdep_dsp_image>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(snd_hwdep_dsp_image))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_hwdep_dsp_image>())).index as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_hwdep_dsp_image),\n            \"::\",\n            stringify!(index)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_hwdep_dsp_image>())).name as *const _ as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_hwdep_dsp_image),\n            \"::\",\n            stringify!(name)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_hwdep_dsp_image>())).image as *const _ as usize },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_hwdep_dsp_image),\n            \"::\",\n            stringify!(image)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_hwdep_dsp_image>())).length as *const _ as usize },\n        80usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_hwdep_dsp_image),\n            \"::\",\n            stringify!(length)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_hwdep_dsp_image>())).driver_data as *const _ as usize },\n        88usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_hwdep_dsp_image),\n            \"::\",\n            stringify!(driver_data)\n        )\n    );\n}\npub type snd_pcm_uframes_t = ::core::ffi::c_ulong;\npub type snd_pcm_sframes_t = ::core::ffi::c_long;\npub const SNDRV_PCM_CLASS_GENERIC: _bindgen_ty_2 = 0;\npub const SNDRV_PCM_CLASS_MULTI: _bindgen_ty_2 = 1;\npub const SNDRV_PCM_CLASS_MODEM: _bindgen_ty_2 = 2;\npub const SNDRV_PCM_CLASS_DIGITIZER: _bindgen_ty_2 = 3;\npub const SNDRV_PCM_CLASS_LAST: _bindgen_ty_2 = 3;\npub type _bindgen_ty_2 = u32;\npub const SNDRV_PCM_SUBCLASS_GENERIC_MIX: _bindgen_ty_3 = 0;\npub const SNDRV_PCM_SUBCLASS_MULTI_MIX: _bindgen_ty_3 = 1;\npub const SNDRV_PCM_SUBCLASS_LAST: _bindgen_ty_3 = 1;\npub type _bindgen_ty_3 = u32;\npub const SNDRV_PCM_STREAM_PLAYBACK: _bindgen_ty_4 = 0;\npub const SNDRV_PCM_STREAM_CAPTURE: _bindgen_ty_4 = 1;\npub const SNDRV_PCM_STREAM_LAST: _bindgen_ty_4 = 1;\npub type _bindgen_ty_4 = u32;\npub type snd_pcm_access_t = ::core::ffi::c_int;\npub type snd_pcm_format_t = ::core::ffi::c_int;\npub type snd_pcm_subformat_t = ::core::ffi::c_int;\npub type snd_pcm_state_t = ::core::ffi::c_int;\npub const SNDRV_PCM_MMAP_OFFSET_DATA: _bindgen_ty_5 = 0;\npub const SNDRV_PCM_MMAP_OFFSET_STATUS: _bindgen_ty_5 = 2147483648;\npub const SNDRV_PCM_MMAP_OFFSET_CONTROL: _bindgen_ty_5 = 2164260864;\npub type _bindgen_ty_5 = u32;\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union snd_pcm_sync_id {\n    pub id: [::core::ffi::c_uchar; 16usize],\n    pub id16: [::core::ffi::c_ushort; 8usize],\n    pub id32: [::core::ffi::c_uint; 4usize],\n    _bindgen_union_align: [u32; 4usize],\n}\n#[test]\nfn bindgen_test_layout_snd_pcm_sync_id() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_pcm_sync_id>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(snd_pcm_sync_id))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_pcm_sync_id>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(snd_pcm_sync_id))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_sync_id>())).id as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_sync_id),\n            \"::\",\n            stringify!(id)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_sync_id>())).id16 as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_sync_id),\n            \"::\",\n            stringify!(id16)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_sync_id>())).id32 as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_sync_id),\n            \"::\",\n            stringify!(id32)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct snd_pcm_info {\n    pub device: ::core::ffi::c_uint,\n    pub subdevice: ::core::ffi::c_uint,\n    pub stream: ::core::ffi::c_int,\n    pub card: ::core::ffi::c_int,\n    pub id: [::core::ffi::c_uchar; 64usize],\n    pub name: [::core::ffi::c_uchar; 80usize],\n    pub subname: [::core::ffi::c_uchar; 32usize],\n    pub dev_class: ::core::ffi::c_int,\n    pub dev_subclass: ::core::ffi::c_int,\n    pub subdevices_count: ::core::ffi::c_uint,\n    pub subdevices_avail: ::core::ffi::c_uint,\n    pub sync: snd_pcm_sync_id,\n    pub reserved: [::core::ffi::c_uchar; 64usize],\n}\n#[test]\nfn bindgen_test_layout_snd_pcm_info() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_pcm_info>(),\n        288usize,\n        concat!(\"Size of: \", stringify!(snd_pcm_info))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_pcm_info>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(snd_pcm_info))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_info>())).device as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_info),\n            \"::\",\n            stringify!(device)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_info>())).subdevice as *const _ as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_info),\n            \"::\",\n            stringify!(subdevice)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_info>())).stream as *const _ as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_info),\n            \"::\",\n            stringify!(stream)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_info>())).card as *const _ as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_info),\n            \"::\",\n            stringify!(card)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_info>())).id as *const _ as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_info),\n            \"::\",\n            stringify!(id)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_info>())).name as *const _ as usize },\n        80usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_info),\n            \"::\",\n            stringify!(name)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_info>())).subname as *const _ as usize },\n        160usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_info),\n            \"::\",\n            stringify!(subname)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_info>())).dev_class as *const _ as usize },\n        192usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_info),\n            \"::\",\n            stringify!(dev_class)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_info>())).dev_subclass as *const _ as usize },\n        196usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_info),\n            \"::\",\n            stringify!(dev_subclass)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_info>())).subdevices_count as *const _ as usize },\n        200usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_info),\n            \"::\",\n            stringify!(subdevices_count)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_info>())).subdevices_avail as *const _ as usize },\n        204usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_info),\n            \"::\",\n            stringify!(subdevices_avail)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_info>())).sync as *const _ as usize },\n        208usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_info),\n            \"::\",\n            stringify!(sync)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_info>())).reserved as *const _ as usize },\n        224usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_info),\n            \"::\",\n            stringify!(reserved)\n        )\n    );\n}\npub type snd_pcm_hw_param_t = ::core::ffi::c_int;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct snd_interval {\n    pub min: ::core::ffi::c_uint,\n    pub max: ::core::ffi::c_uint,\n    pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize], u8>,\n    pub __bindgen_padding_0: [u8; 3usize],\n}\n#[test]\nfn bindgen_test_layout_snd_interval() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_interval>(),\n        12usize,\n        concat!(\"Size of: \", stringify!(snd_interval))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_interval>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(snd_interval))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_interval>())).min as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_interval),\n            \"::\",\n            stringify!(min)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_interval>())).max as *const _ as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_interval),\n            \"::\",\n            stringify!(max)\n        )\n    );\n}\nimpl snd_interval {\n    #[inline]\n    pub fn openmin(&self) -> ::core::ffi::c_uint {\n        unsafe { ::core::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) }\n    }\n    #[inline]\n    pub fn set_openmin(&mut self, val: ::core::ffi::c_uint) {\n        unsafe {\n            let val: u32 = ::core::mem::transmute(val);\n            self._bitfield_1.set(0usize, 1u8, val as u64)\n        }\n    }\n    #[inline]\n    pub fn openmax(&self) -> ::core::ffi::c_uint {\n        unsafe { ::core::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) }\n    }\n    #[inline]\n    pub fn set_openmax(&mut self, val: ::core::ffi::c_uint) {\n        unsafe {\n            let val: u32 = ::core::mem::transmute(val);\n            self._bitfield_1.set(1usize, 1u8, val as u64)\n        }\n    }\n    #[inline]\n    pub fn integer(&self) -> ::core::ffi::c_uint {\n        unsafe { ::core::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u32) }\n    }\n    #[inline]\n    pub fn set_integer(&mut self, val: ::core::ffi::c_uint) {\n        unsafe {\n            let val: u32 = ::core::mem::transmute(val);\n            self._bitfield_1.set(2usize, 1u8, val as u64)\n        }\n    }\n    #[inline]\n    pub fn empty(&self) -> ::core::ffi::c_uint {\n        unsafe { ::core::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u32) }\n    }\n    #[inline]\n    pub fn set_empty(&mut self, val: ::core::ffi::c_uint) {\n        unsafe {\n            let val: u32 = ::core::mem::transmute(val);\n            self._bitfield_1.set(3usize, 1u8, val as u64)\n        }\n    }\n    #[inline]\n    pub fn new_bitfield_1(\n        openmin: ::core::ffi::c_uint,\n        openmax: ::core::ffi::c_uint,\n        integer: ::core::ffi::c_uint,\n        empty: ::core::ffi::c_uint,\n    ) -> __BindgenBitfieldUnit<[u8; 1usize], u8> {\n        let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize], u8> =\n            Default::default();\n        __bindgen_bitfield_unit.set(0usize, 1u8, {\n            let openmin: u32 = unsafe { ::core::mem::transmute(openmin) };\n            openmin as u64\n        });\n        __bindgen_bitfield_unit.set(1usize, 1u8, {\n            let openmax: u32 = unsafe { ::core::mem::transmute(openmax) };\n            openmax as u64\n        });\n        __bindgen_bitfield_unit.set(2usize, 1u8, {\n            let integer: u32 = unsafe { ::core::mem::transmute(integer) };\n            integer as u64\n        });\n        __bindgen_bitfield_unit.set(3usize, 1u8, {\n            let empty: u32 = unsafe { ::core::mem::transmute(empty) };\n            empty as u64\n        });\n        __bindgen_bitfield_unit\n    }\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct snd_mask {\n    pub bits: [__u32; 8usize],\n}\n#[test]\nfn bindgen_test_layout_snd_mask() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_mask>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(snd_mask))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_mask>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(snd_mask))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_mask>())).bits as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_mask),\n            \"::\",\n            stringify!(bits)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct snd_pcm_hw_params {\n    pub flags: ::core::ffi::c_uint,\n    pub masks: [snd_mask; 3usize],\n    pub mres: [snd_mask; 5usize],\n    pub intervals: [snd_interval; 12usize],\n    pub ires: [snd_interval; 9usize],\n    pub rmask: ::core::ffi::c_uint,\n    pub cmask: ::core::ffi::c_uint,\n    pub info: ::core::ffi::c_uint,\n    pub msbits: ::core::ffi::c_uint,\n    pub rate_num: ::core::ffi::c_uint,\n    pub rate_den: ::core::ffi::c_uint,\n    pub fifo_size: snd_pcm_uframes_t,\n    pub reserved: [::core::ffi::c_uchar; 64usize],\n}\n#[test]\nfn bindgen_test_layout_snd_pcm_hw_params() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_pcm_hw_params>(),\n        608usize,\n        concat!(\"Size of: \", stringify!(snd_pcm_hw_params))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_pcm_hw_params>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(snd_pcm_hw_params))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_hw_params>())).flags as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_hw_params),\n            \"::\",\n            stringify!(flags)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_hw_params>())).masks as *const _ as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_hw_params),\n            \"::\",\n            stringify!(masks)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_hw_params>())).mres as *const _ as usize },\n        100usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_hw_params),\n            \"::\",\n            stringify!(mres)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_hw_params>())).intervals as *const _ as usize },\n        260usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_hw_params),\n            \"::\",\n            stringify!(intervals)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_hw_params>())).ires as *const _ as usize },\n        404usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_hw_params),\n            \"::\",\n            stringify!(ires)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_hw_params>())).rmask as *const _ as usize },\n        512usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_hw_params),\n            \"::\",\n            stringify!(rmask)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_hw_params>())).cmask as *const _ as usize },\n        516usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_hw_params),\n            \"::\",\n            stringify!(cmask)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_hw_params>())).info as *const _ as usize },\n        520usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_hw_params),\n            \"::\",\n            stringify!(info)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_hw_params>())).msbits as *const _ as usize },\n        524usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_hw_params),\n            \"::\",\n            stringify!(msbits)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_hw_params>())).rate_num as *const _ as usize },\n        528usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_hw_params),\n            \"::\",\n            stringify!(rate_num)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_hw_params>())).rate_den as *const _ as usize },\n        532usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_hw_params),\n            \"::\",\n            stringify!(rate_den)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_hw_params>())).fifo_size as *const _ as usize },\n        536usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_hw_params),\n            \"::\",\n            stringify!(fifo_size)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_hw_params>())).reserved as *const _ as usize },\n        544usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_hw_params),\n            \"::\",\n            stringify!(reserved)\n        )\n    );\n}\npub const SNDRV_PCM_TSTAMP_NONE: _bindgen_ty_6 = 0;\npub const SNDRV_PCM_TSTAMP_ENABLE: _bindgen_ty_6 = 1;\npub const SNDRV_PCM_TSTAMP_LAST: _bindgen_ty_6 = 1;\npub type _bindgen_ty_6 = u32;\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct snd_pcm_sw_params {\n    pub tstamp_mode: ::core::ffi::c_int,\n    pub period_step: ::core::ffi::c_uint,\n    pub sleep_min: ::core::ffi::c_uint,\n    pub avail_min: snd_pcm_uframes_t,\n    pub xfer_align: snd_pcm_uframes_t,\n    pub start_threshold: snd_pcm_uframes_t,\n    pub stop_threshold: snd_pcm_uframes_t,\n    pub silence_threshold: snd_pcm_uframes_t,\n    pub silence_size: snd_pcm_uframes_t,\n    pub boundary: snd_pcm_uframes_t,\n    pub proto: ::core::ffi::c_uint,\n    pub tstamp_type: ::core::ffi::c_uint,\n    pub reserved: [::core::ffi::c_uchar; 56usize],\n}\n#[test]\nfn bindgen_test_layout_snd_pcm_sw_params() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_pcm_sw_params>(),\n        136usize,\n        concat!(\"Size of: \", stringify!(snd_pcm_sw_params))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_pcm_sw_params>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(snd_pcm_sw_params))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_sw_params>())).tstamp_mode as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_sw_params),\n            \"::\",\n            stringify!(tstamp_mode)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_sw_params>())).period_step as *const _ as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_sw_params),\n            \"::\",\n            stringify!(period_step)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_sw_params>())).sleep_min as *const _ as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_sw_params),\n            \"::\",\n            stringify!(sleep_min)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_sw_params>())).avail_min as *const _ as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_sw_params),\n            \"::\",\n            stringify!(avail_min)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_sw_params>())).xfer_align as *const _ as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_sw_params),\n            \"::\",\n            stringify!(xfer_align)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_pcm_sw_params>())).start_threshold as *const _ as usize\n        },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_sw_params),\n            \"::\",\n            stringify!(start_threshold)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_pcm_sw_params>())).stop_threshold as *const _ as usize\n        },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_sw_params),\n            \"::\",\n            stringify!(stop_threshold)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_pcm_sw_params>())).silence_threshold as *const _ as usize\n        },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_sw_params),\n            \"::\",\n            stringify!(silence_threshold)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_sw_params>())).silence_size as *const _ as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_sw_params),\n            \"::\",\n            stringify!(silence_size)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_sw_params>())).boundary as *const _ as usize },\n        64usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_sw_params),\n            \"::\",\n            stringify!(boundary)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_sw_params>())).proto as *const _ as usize },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_sw_params),\n            \"::\",\n            stringify!(proto)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_sw_params>())).tstamp_type as *const _ as usize },\n        76usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_sw_params),\n            \"::\",\n            stringify!(tstamp_type)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_sw_params>())).reserved as *const _ as usize },\n        80usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_sw_params),\n            \"::\",\n            stringify!(reserved)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct snd_pcm_channel_info {\n    pub channel: ::core::ffi::c_uint,\n    pub offset: __kernel_off_t,\n    pub first: ::core::ffi::c_uint,\n    pub step: ::core::ffi::c_uint,\n}\n#[test]\nfn bindgen_test_layout_snd_pcm_channel_info() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_pcm_channel_info>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(snd_pcm_channel_info))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_pcm_channel_info>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(snd_pcm_channel_info))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_channel_info>())).channel as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_channel_info),\n            \"::\",\n            stringify!(channel)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_channel_info>())).offset as *const _ as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_channel_info),\n            \"::\",\n            stringify!(offset)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_channel_info>())).first as *const _ as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_channel_info),\n            \"::\",\n            stringify!(first)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_channel_info>())).step as *const _ as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_channel_info),\n            \"::\",\n            stringify!(step)\n        )\n    );\n}\npub const SNDRV_PCM_AUDIO_TSTAMP_TYPE_COMPAT: _bindgen_ty_7 = 0;\npub const SNDRV_PCM_AUDIO_TSTAMP_TYPE_DEFAULT: _bindgen_ty_7 = 1;\npub const SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK: _bindgen_ty_7 = 2;\npub const SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_ABSOLUTE: _bindgen_ty_7 = 3;\npub const SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_ESTIMATED: _bindgen_ty_7 = 4;\npub const SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED: _bindgen_ty_7 = 5;\npub const SNDRV_PCM_AUDIO_TSTAMP_TYPE_LAST: _bindgen_ty_7 = 5;\npub type _bindgen_ty_7 = u32;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct snd_pcm_status {\n    pub state: snd_pcm_state_t,\n    pub trigger_tstamp: timespec,\n    pub tstamp: timespec,\n    pub appl_ptr: snd_pcm_uframes_t,\n    pub hw_ptr: snd_pcm_uframes_t,\n    pub delay: snd_pcm_sframes_t,\n    pub avail: snd_pcm_uframes_t,\n    pub avail_max: snd_pcm_uframes_t,\n    pub overrange: snd_pcm_uframes_t,\n    pub suspended_state: snd_pcm_state_t,\n    pub audio_tstamp_data: __u32,\n    pub audio_tstamp: timespec,\n    pub driver_tstamp: timespec,\n    pub audio_tstamp_accuracy: __u32,\n    pub reserved: [::core::ffi::c_uchar; 20usize],\n}\n#[test]\nfn bindgen_test_layout_snd_pcm_status() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_pcm_status>(),\n        152usize,\n        concat!(\"Size of: \", stringify!(snd_pcm_status))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_pcm_status>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(snd_pcm_status))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_status>())).state as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_status),\n            \"::\",\n            stringify!(state)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_status>())).trigger_tstamp as *const _ as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_status),\n            \"::\",\n            stringify!(trigger_tstamp)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_status>())).tstamp as *const _ as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_status),\n            \"::\",\n            stringify!(tstamp)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_status>())).appl_ptr as *const _ as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_status),\n            \"::\",\n            stringify!(appl_ptr)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_status>())).hw_ptr as *const _ as usize },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_status),\n            \"::\",\n            stringify!(hw_ptr)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_status>())).delay as *const _ as usize },\n        56usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_status),\n            \"::\",\n            stringify!(delay)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_status>())).avail as *const _ as usize },\n        64usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_status),\n            \"::\",\n            stringify!(avail)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_status>())).avail_max as *const _ as usize },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_status),\n            \"::\",\n            stringify!(avail_max)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_status>())).overrange as *const _ as usize },\n        80usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_status),\n            \"::\",\n            stringify!(overrange)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_status>())).suspended_state as *const _ as usize },\n        88usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_status),\n            \"::\",\n            stringify!(suspended_state)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_pcm_status>())).audio_tstamp_data as *const _ as usize\n        },\n        92usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_status),\n            \"::\",\n            stringify!(audio_tstamp_data)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_status>())).audio_tstamp as *const _ as usize },\n        96usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_status),\n            \"::\",\n            stringify!(audio_tstamp)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_status>())).driver_tstamp as *const _ as usize },\n        112usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_status),\n            \"::\",\n            stringify!(driver_tstamp)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_pcm_status>())).audio_tstamp_accuracy as *const _ as usize\n        },\n        128usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_status),\n            \"::\",\n            stringify!(audio_tstamp_accuracy)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_status>())).reserved as *const _ as usize },\n        132usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_status),\n            \"::\",\n            stringify!(reserved)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct snd_pcm_mmap_status {\n    pub state: snd_pcm_state_t,\n    pub pad1: ::core::ffi::c_int,\n    pub hw_ptr: snd_pcm_uframes_t,\n    pub tstamp: timespec,\n    pub suspended_state: snd_pcm_state_t,\n    pub audio_tstamp: timespec,\n}\n#[test]\nfn bindgen_test_layout_snd_pcm_mmap_status() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_pcm_mmap_status>(),\n        56usize,\n        concat!(\"Size of: \", stringify!(snd_pcm_mmap_status))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_pcm_mmap_status>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(snd_pcm_mmap_status))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_mmap_status>())).state as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_mmap_status),\n            \"::\",\n            stringify!(state)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_mmap_status>())).pad1 as *const _ as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_mmap_status),\n            \"::\",\n            stringify!(pad1)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_mmap_status>())).hw_ptr as *const _ as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_mmap_status),\n            \"::\",\n            stringify!(hw_ptr)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_mmap_status>())).tstamp as *const _ as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_mmap_status),\n            \"::\",\n            stringify!(tstamp)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_pcm_mmap_status>())).suspended_state as *const _ as usize\n        },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_mmap_status),\n            \"::\",\n            stringify!(suspended_state)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_pcm_mmap_status>())).audio_tstamp as *const _ as usize\n        },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_mmap_status),\n            \"::\",\n            stringify!(audio_tstamp)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct snd_pcm_mmap_control {\n    pub appl_ptr: snd_pcm_uframes_t,\n    pub avail_min: snd_pcm_uframes_t,\n}\n#[test]\nfn bindgen_test_layout_snd_pcm_mmap_control() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_pcm_mmap_control>(),\n        16usize,\n        concat!(\"Size of: \", stringify!(snd_pcm_mmap_control))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_pcm_mmap_control>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(snd_pcm_mmap_control))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_mmap_control>())).appl_ptr as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_mmap_control),\n            \"::\",\n            stringify!(appl_ptr)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_mmap_control>())).avail_min as *const _ as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_mmap_control),\n            \"::\",\n            stringify!(avail_min)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct snd_pcm_sync_ptr {\n    pub flags: ::core::ffi::c_uint,\n    pub s: snd_pcm_sync_ptr__bindgen_ty_1,\n    pub c: snd_pcm_sync_ptr__bindgen_ty_2,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union snd_pcm_sync_ptr__bindgen_ty_1 {\n    pub status: snd_pcm_mmap_status,\n    pub reserved: [::core::ffi::c_uchar; 64usize],\n    _bindgen_union_align: [u64; 8usize],\n}\n#[test]\nfn bindgen_test_layout_snd_pcm_sync_ptr__bindgen_ty_1() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_pcm_sync_ptr__bindgen_ty_1>(),\n        64usize,\n        concat!(\"Size of: \", stringify!(snd_pcm_sync_ptr__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_pcm_sync_ptr__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(snd_pcm_sync_ptr__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_pcm_sync_ptr__bindgen_ty_1>())).status as *const _ as usize\n        },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_sync_ptr__bindgen_ty_1),\n            \"::\",\n            stringify!(status)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_pcm_sync_ptr__bindgen_ty_1>())).reserved as *const _ as usize\n        },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_sync_ptr__bindgen_ty_1),\n            \"::\",\n            stringify!(reserved)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union snd_pcm_sync_ptr__bindgen_ty_2 {\n    pub control: snd_pcm_mmap_control,\n    pub reserved: [::core::ffi::c_uchar; 64usize],\n    _bindgen_union_align: [u64; 8usize],\n}\n#[test]\nfn bindgen_test_layout_snd_pcm_sync_ptr__bindgen_ty_2() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_pcm_sync_ptr__bindgen_ty_2>(),\n        64usize,\n        concat!(\"Size of: \", stringify!(snd_pcm_sync_ptr__bindgen_ty_2))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_pcm_sync_ptr__bindgen_ty_2>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(snd_pcm_sync_ptr__bindgen_ty_2))\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_pcm_sync_ptr__bindgen_ty_2>())).control as *const _ as usize\n        },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_sync_ptr__bindgen_ty_2),\n            \"::\",\n            stringify!(control)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_pcm_sync_ptr__bindgen_ty_2>())).reserved as *const _ as usize\n        },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_sync_ptr__bindgen_ty_2),\n            \"::\",\n            stringify!(reserved)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_snd_pcm_sync_ptr() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_pcm_sync_ptr>(),\n        136usize,\n        concat!(\"Size of: \", stringify!(snd_pcm_sync_ptr))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_pcm_sync_ptr>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(snd_pcm_sync_ptr))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_sync_ptr>())).flags as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_sync_ptr),\n            \"::\",\n            stringify!(flags)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_sync_ptr>())).s as *const _ as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_sync_ptr),\n            \"::\",\n            stringify!(s)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_pcm_sync_ptr>())).c as *const _ as usize },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_pcm_sync_ptr),\n            \"::\",\n            stringify!(c)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct snd_xferi {\n    pub result: snd_pcm_sframes_t,\n    pub buf: *mut ::core::ffi::c_void,\n    pub frames: snd_pcm_uframes_t,\n}\n#[test]\nfn bindgen_test_layout_snd_xferi() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_xferi>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(snd_xferi))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_xferi>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(snd_xferi))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_xferi>())).result as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_xferi),\n            \"::\",\n            stringify!(result)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_xferi>())).buf as *const _ as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_xferi),\n            \"::\",\n            stringify!(buf)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_xferi>())).frames as *const _ as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_xferi),\n            \"::\",\n            stringify!(frames)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct snd_xfern {\n    pub result: snd_pcm_sframes_t,\n    pub bufs: *mut *mut ::core::ffi::c_void,\n    pub frames: snd_pcm_uframes_t,\n}\n#[test]\nfn bindgen_test_layout_snd_xfern() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_xfern>(),\n        24usize,\n        concat!(\"Size of: \", stringify!(snd_xfern))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_xfern>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(snd_xfern))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_xfern>())).result as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_xfern),\n            \"::\",\n            stringify!(result)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_xfern>())).bufs as *const _ as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_xfern),\n            \"::\",\n            stringify!(bufs)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_xfern>())).frames as *const _ as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_xfern),\n            \"::\",\n            stringify!(frames)\n        )\n    );\n}\npub const SNDRV_PCM_TSTAMP_TYPE_GETTIMEOFDAY: _bindgen_ty_8 = 0;\npub const SNDRV_PCM_TSTAMP_TYPE_MONOTONIC: _bindgen_ty_8 = 1;\npub const SNDRV_PCM_TSTAMP_TYPE_MONOTONIC_RAW: _bindgen_ty_8 = 2;\npub const SNDRV_PCM_TSTAMP_TYPE_LAST: _bindgen_ty_8 = 2;\npub type _bindgen_ty_8 = u32;\npub const SNDRV_CHMAP_UNKNOWN: _bindgen_ty_9 = 0;\npub const SNDRV_CHMAP_NA: _bindgen_ty_9 = 1;\npub const SNDRV_CHMAP_MONO: _bindgen_ty_9 = 2;\npub const SNDRV_CHMAP_FL: _bindgen_ty_9 = 3;\npub const SNDRV_CHMAP_FR: _bindgen_ty_9 = 4;\npub const SNDRV_CHMAP_RL: _bindgen_ty_9 = 5;\npub const SNDRV_CHMAP_RR: _bindgen_ty_9 = 6;\npub const SNDRV_CHMAP_FC: _bindgen_ty_9 = 7;\npub const SNDRV_CHMAP_LFE: _bindgen_ty_9 = 8;\npub const SNDRV_CHMAP_SL: _bindgen_ty_9 = 9;\npub const SNDRV_CHMAP_SR: _bindgen_ty_9 = 10;\npub const SNDRV_CHMAP_RC: _bindgen_ty_9 = 11;\npub const SNDRV_CHMAP_FLC: _bindgen_ty_9 = 12;\npub const SNDRV_CHMAP_FRC: _bindgen_ty_9 = 13;\npub const SNDRV_CHMAP_RLC: _bindgen_ty_9 = 14;\npub const SNDRV_CHMAP_RRC: _bindgen_ty_9 = 15;\npub const SNDRV_CHMAP_FLW: _bindgen_ty_9 = 16;\npub const SNDRV_CHMAP_FRW: _bindgen_ty_9 = 17;\npub const SNDRV_CHMAP_FLH: _bindgen_ty_9 = 18;\npub const SNDRV_CHMAP_FCH: _bindgen_ty_9 = 19;\npub const SNDRV_CHMAP_FRH: _bindgen_ty_9 = 20;\npub const SNDRV_CHMAP_TC: _bindgen_ty_9 = 21;\npub const SNDRV_CHMAP_TFL: _bindgen_ty_9 = 22;\npub const SNDRV_CHMAP_TFR: _bindgen_ty_9 = 23;\npub const SNDRV_CHMAP_TFC: _bindgen_ty_9 = 24;\npub const SNDRV_CHMAP_TRL: _bindgen_ty_9 = 25;\npub const SNDRV_CHMAP_TRR: _bindgen_ty_9 = 26;\npub const SNDRV_CHMAP_TRC: _bindgen_ty_9 = 27;\npub const SNDRV_CHMAP_TFLC: _bindgen_ty_9 = 28;\npub const SNDRV_CHMAP_TFRC: _bindgen_ty_9 = 29;\npub const SNDRV_CHMAP_TSL: _bindgen_ty_9 = 30;\npub const SNDRV_CHMAP_TSR: _bindgen_ty_9 = 31;\npub const SNDRV_CHMAP_LLFE: _bindgen_ty_9 = 32;\npub const SNDRV_CHMAP_RLFE: _bindgen_ty_9 = 33;\npub const SNDRV_CHMAP_BC: _bindgen_ty_9 = 34;\npub const SNDRV_CHMAP_BLC: _bindgen_ty_9 = 35;\npub const SNDRV_CHMAP_BRC: _bindgen_ty_9 = 36;\npub const SNDRV_CHMAP_LAST: _bindgen_ty_9 = 36;\npub type _bindgen_ty_9 = u32;\npub const SNDRV_RAWMIDI_STREAM_OUTPUT: _bindgen_ty_10 = 0;\npub const SNDRV_RAWMIDI_STREAM_INPUT: _bindgen_ty_10 = 1;\npub const SNDRV_RAWMIDI_STREAM_LAST: _bindgen_ty_10 = 1;\npub type _bindgen_ty_10 = u32;\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct snd_rawmidi_info {\n    pub device: ::core::ffi::c_uint,\n    pub subdevice: ::core::ffi::c_uint,\n    pub stream: ::core::ffi::c_int,\n    pub card: ::core::ffi::c_int,\n    pub flags: ::core::ffi::c_uint,\n    pub id: [::core::ffi::c_uchar; 64usize],\n    pub name: [::core::ffi::c_uchar; 80usize],\n    pub subname: [::core::ffi::c_uchar; 32usize],\n    pub subdevices_count: ::core::ffi::c_uint,\n    pub subdevices_avail: ::core::ffi::c_uint,\n    pub reserved: [::core::ffi::c_uchar; 64usize],\n}\n#[test]\nfn bindgen_test_layout_snd_rawmidi_info() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_rawmidi_info>(),\n        268usize,\n        concat!(\"Size of: \", stringify!(snd_rawmidi_info))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_rawmidi_info>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(snd_rawmidi_info))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_rawmidi_info>())).device as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_rawmidi_info),\n            \"::\",\n            stringify!(device)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_rawmidi_info>())).subdevice as *const _ as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_rawmidi_info),\n            \"::\",\n            stringify!(subdevice)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_rawmidi_info>())).stream as *const _ as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_rawmidi_info),\n            \"::\",\n            stringify!(stream)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_rawmidi_info>())).card as *const _ as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_rawmidi_info),\n            \"::\",\n            stringify!(card)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_rawmidi_info>())).flags as *const _ as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_rawmidi_info),\n            \"::\",\n            stringify!(flags)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_rawmidi_info>())).id as *const _ as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_rawmidi_info),\n            \"::\",\n            stringify!(id)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_rawmidi_info>())).name as *const _ as usize },\n        84usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_rawmidi_info),\n            \"::\",\n            stringify!(name)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_rawmidi_info>())).subname as *const _ as usize },\n        164usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_rawmidi_info),\n            \"::\",\n            stringify!(subname)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_rawmidi_info>())).subdevices_count as *const _ as usize\n        },\n        196usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_rawmidi_info),\n            \"::\",\n            stringify!(subdevices_count)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_rawmidi_info>())).subdevices_avail as *const _ as usize\n        },\n        200usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_rawmidi_info),\n            \"::\",\n            stringify!(subdevices_avail)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_rawmidi_info>())).reserved as *const _ as usize },\n        204usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_rawmidi_info),\n            \"::\",\n            stringify!(reserved)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct snd_rawmidi_params {\n    pub stream: ::core::ffi::c_int,\n    pub buffer_size: usize,\n    pub avail_min: usize,\n    pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize], u8>,\n    pub reserved: [::core::ffi::c_uchar; 16usize],\n}\n#[test]\nfn bindgen_test_layout_snd_rawmidi_params() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_rawmidi_params>(),\n        48usize,\n        concat!(\"Size of: \", stringify!(snd_rawmidi_params))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_rawmidi_params>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(snd_rawmidi_params))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_rawmidi_params>())).stream as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_rawmidi_params),\n            \"::\",\n            stringify!(stream)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_rawmidi_params>())).buffer_size as *const _ as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_rawmidi_params),\n            \"::\",\n            stringify!(buffer_size)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_rawmidi_params>())).avail_min as *const _ as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_rawmidi_params),\n            \"::\",\n            stringify!(avail_min)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_rawmidi_params>())).reserved as *const _ as usize },\n        25usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_rawmidi_params),\n            \"::\",\n            stringify!(reserved)\n        )\n    );\n}\nimpl snd_rawmidi_params {\n    #[inline]\n    pub fn no_active_sensing(&self) -> ::core::ffi::c_uint {\n        unsafe { ::core::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) }\n    }\n    #[inline]\n    pub fn set_no_active_sensing(&mut self, val: ::core::ffi::c_uint) {\n        unsafe {\n            let val: u32 = ::core::mem::transmute(val);\n            self._bitfield_1.set(0usize, 1u8, val as u64)\n        }\n    }\n    #[inline]\n    pub fn new_bitfield_1(\n        no_active_sensing: ::core::ffi::c_uint,\n    ) -> __BindgenBitfieldUnit<[u8; 1usize], u8> {\n        let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize], u8> =\n            Default::default();\n        __bindgen_bitfield_unit.set(0usize, 1u8, {\n            let no_active_sensing: u32 = unsafe { ::core::mem::transmute(no_active_sensing) };\n            no_active_sensing as u64\n        });\n        __bindgen_bitfield_unit\n    }\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct snd_rawmidi_status {\n    pub stream: ::core::ffi::c_int,\n    pub tstamp: timespec,\n    pub avail: usize,\n    pub xruns: usize,\n    pub reserved: [::core::ffi::c_uchar; 16usize],\n}\n#[test]\nfn bindgen_test_layout_snd_rawmidi_status() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_rawmidi_status>(),\n        56usize,\n        concat!(\"Size of: \", stringify!(snd_rawmidi_status))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_rawmidi_status>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(snd_rawmidi_status))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_rawmidi_status>())).stream as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_rawmidi_status),\n            \"::\",\n            stringify!(stream)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_rawmidi_status>())).tstamp as *const _ as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_rawmidi_status),\n            \"::\",\n            stringify!(tstamp)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_rawmidi_status>())).avail as *const _ as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_rawmidi_status),\n            \"::\",\n            stringify!(avail)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_rawmidi_status>())).xruns as *const _ as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_rawmidi_status),\n            \"::\",\n            stringify!(xruns)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_rawmidi_status>())).reserved as *const _ as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_rawmidi_status),\n            \"::\",\n            stringify!(reserved)\n        )\n    );\n}\npub const SNDRV_TIMER_CLASS_NONE: _bindgen_ty_11 = -1;\npub const SNDRV_TIMER_CLASS_SLAVE: _bindgen_ty_11 = 0;\npub const SNDRV_TIMER_CLASS_GLOBAL: _bindgen_ty_11 = 1;\npub const SNDRV_TIMER_CLASS_CARD: _bindgen_ty_11 = 2;\npub const SNDRV_TIMER_CLASS_PCM: _bindgen_ty_11 = 3;\npub const SNDRV_TIMER_CLASS_LAST: _bindgen_ty_11 = 3;\npub type _bindgen_ty_11 = i32;\npub const SNDRV_TIMER_SCLASS_NONE: _bindgen_ty_12 = 0;\npub const SNDRV_TIMER_SCLASS_APPLICATION: _bindgen_ty_12 = 1;\npub const SNDRV_TIMER_SCLASS_SEQUENCER: _bindgen_ty_12 = 2;\npub const SNDRV_TIMER_SCLASS_OSS_SEQUENCER: _bindgen_ty_12 = 3;\npub const SNDRV_TIMER_SCLASS_LAST: _bindgen_ty_12 = 3;\npub type _bindgen_ty_12 = u32;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct snd_timer_id {\n    pub dev_class: ::core::ffi::c_int,\n    pub dev_sclass: ::core::ffi::c_int,\n    pub card: ::core::ffi::c_int,\n    pub device: ::core::ffi::c_int,\n    pub subdevice: ::core::ffi::c_int,\n}\n#[test]\nfn bindgen_test_layout_snd_timer_id() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_timer_id>(),\n        20usize,\n        concat!(\"Size of: \", stringify!(snd_timer_id))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_timer_id>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(snd_timer_id))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_id>())).dev_class as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_id),\n            \"::\",\n            stringify!(dev_class)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_id>())).dev_sclass as *const _ as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_id),\n            \"::\",\n            stringify!(dev_sclass)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_id>())).card as *const _ as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_id),\n            \"::\",\n            stringify!(card)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_id>())).device as *const _ as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_id),\n            \"::\",\n            stringify!(device)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_id>())).subdevice as *const _ as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_id),\n            \"::\",\n            stringify!(subdevice)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct snd_timer_ginfo {\n    pub tid: snd_timer_id,\n    pub flags: ::core::ffi::c_uint,\n    pub card: ::core::ffi::c_int,\n    pub id: [::core::ffi::c_uchar; 64usize],\n    pub name: [::core::ffi::c_uchar; 80usize],\n    pub reserved0: ::core::ffi::c_ulong,\n    pub resolution: ::core::ffi::c_ulong,\n    pub resolution_min: ::core::ffi::c_ulong,\n    pub resolution_max: ::core::ffi::c_ulong,\n    pub clients: ::core::ffi::c_uint,\n    pub reserved: [::core::ffi::c_uchar; 32usize],\n}\n#[test]\nfn bindgen_test_layout_snd_timer_ginfo() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_timer_ginfo>(),\n        248usize,\n        concat!(\"Size of: \", stringify!(snd_timer_ginfo))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_timer_ginfo>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(snd_timer_ginfo))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_ginfo>())).tid as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_ginfo),\n            \"::\",\n            stringify!(tid)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_ginfo>())).flags as *const _ as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_ginfo),\n            \"::\",\n            stringify!(flags)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_ginfo>())).card as *const _ as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_ginfo),\n            \"::\",\n            stringify!(card)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_ginfo>())).id as *const _ as usize },\n        28usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_ginfo),\n            \"::\",\n            stringify!(id)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_ginfo>())).name as *const _ as usize },\n        92usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_ginfo),\n            \"::\",\n            stringify!(name)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_ginfo>())).reserved0 as *const _ as usize },\n        176usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_ginfo),\n            \"::\",\n            stringify!(reserved0)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_ginfo>())).resolution as *const _ as usize },\n        184usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_ginfo),\n            \"::\",\n            stringify!(resolution)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_ginfo>())).resolution_min as *const _ as usize },\n        192usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_ginfo),\n            \"::\",\n            stringify!(resolution_min)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_ginfo>())).resolution_max as *const _ as usize },\n        200usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_ginfo),\n            \"::\",\n            stringify!(resolution_max)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_ginfo>())).clients as *const _ as usize },\n        208usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_ginfo),\n            \"::\",\n            stringify!(clients)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_ginfo>())).reserved as *const _ as usize },\n        212usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_ginfo),\n            \"::\",\n            stringify!(reserved)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct snd_timer_gparams {\n    pub tid: snd_timer_id,\n    pub period_num: ::core::ffi::c_ulong,\n    pub period_den: ::core::ffi::c_ulong,\n    pub reserved: [::core::ffi::c_uchar; 32usize],\n}\n#[test]\nfn bindgen_test_layout_snd_timer_gparams() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_timer_gparams>(),\n        72usize,\n        concat!(\"Size of: \", stringify!(snd_timer_gparams))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_timer_gparams>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(snd_timer_gparams))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_gparams>())).tid as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_gparams),\n            \"::\",\n            stringify!(tid)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_gparams>())).period_num as *const _ as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_gparams),\n            \"::\",\n            stringify!(period_num)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_gparams>())).period_den as *const _ as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_gparams),\n            \"::\",\n            stringify!(period_den)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_gparams>())).reserved as *const _ as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_gparams),\n            \"::\",\n            stringify!(reserved)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct snd_timer_gstatus {\n    pub tid: snd_timer_id,\n    pub resolution: ::core::ffi::c_ulong,\n    pub resolution_num: ::core::ffi::c_ulong,\n    pub resolution_den: ::core::ffi::c_ulong,\n    pub reserved: [::core::ffi::c_uchar; 32usize],\n}\n#[test]\nfn bindgen_test_layout_snd_timer_gstatus() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_timer_gstatus>(),\n        80usize,\n        concat!(\"Size of: \", stringify!(snd_timer_gstatus))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_timer_gstatus>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(snd_timer_gstatus))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_gstatus>())).tid as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_gstatus),\n            \"::\",\n            stringify!(tid)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_gstatus>())).resolution as *const _ as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_gstatus),\n            \"::\",\n            stringify!(resolution)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_timer_gstatus>())).resolution_num as *const _ as usize\n        },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_gstatus),\n            \"::\",\n            stringify!(resolution_num)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_timer_gstatus>())).resolution_den as *const _ as usize\n        },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_gstatus),\n            \"::\",\n            stringify!(resolution_den)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_gstatus>())).reserved as *const _ as usize },\n        48usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_gstatus),\n            \"::\",\n            stringify!(reserved)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct snd_timer_select {\n    pub id: snd_timer_id,\n    pub reserved: [::core::ffi::c_uchar; 32usize],\n}\n#[test]\nfn bindgen_test_layout_snd_timer_select() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_timer_select>(),\n        52usize,\n        concat!(\"Size of: \", stringify!(snd_timer_select))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_timer_select>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(snd_timer_select))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_select>())).id as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_select),\n            \"::\",\n            stringify!(id)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_select>())).reserved as *const _ as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_select),\n            \"::\",\n            stringify!(reserved)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct snd_timer_info {\n    pub flags: ::core::ffi::c_uint,\n    pub card: ::core::ffi::c_int,\n    pub id: [::core::ffi::c_uchar; 64usize],\n    pub name: [::core::ffi::c_uchar; 80usize],\n    pub reserved0: ::core::ffi::c_ulong,\n    pub resolution: ::core::ffi::c_ulong,\n    pub reserved: [::core::ffi::c_uchar; 64usize],\n}\n#[test]\nfn bindgen_test_layout_snd_timer_info() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_timer_info>(),\n        232usize,\n        concat!(\"Size of: \", stringify!(snd_timer_info))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_timer_info>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(snd_timer_info))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_info>())).flags as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_info),\n            \"::\",\n            stringify!(flags)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_info>())).card as *const _ as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_info),\n            \"::\",\n            stringify!(card)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_info>())).id as *const _ as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_info),\n            \"::\",\n            stringify!(id)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_info>())).name as *const _ as usize },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_info),\n            \"::\",\n            stringify!(name)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_info>())).reserved0 as *const _ as usize },\n        152usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_info),\n            \"::\",\n            stringify!(reserved0)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_info>())).resolution as *const _ as usize },\n        160usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_info),\n            \"::\",\n            stringify!(resolution)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_info>())).reserved as *const _ as usize },\n        168usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_info),\n            \"::\",\n            stringify!(reserved)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct snd_timer_params {\n    pub flags: ::core::ffi::c_uint,\n    pub ticks: ::core::ffi::c_uint,\n    pub queue_size: ::core::ffi::c_uint,\n    pub reserved0: ::core::ffi::c_uint,\n    pub filter: ::core::ffi::c_uint,\n    pub reserved: [::core::ffi::c_uchar; 60usize],\n}\n#[test]\nfn bindgen_test_layout_snd_timer_params() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_timer_params>(),\n        80usize,\n        concat!(\"Size of: \", stringify!(snd_timer_params))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_timer_params>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(snd_timer_params))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_params>())).flags as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_params),\n            \"::\",\n            stringify!(flags)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_params>())).ticks as *const _ as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_params),\n            \"::\",\n            stringify!(ticks)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_params>())).queue_size as *const _ as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_params),\n            \"::\",\n            stringify!(queue_size)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_params>())).reserved0 as *const _ as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_params),\n            \"::\",\n            stringify!(reserved0)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_params>())).filter as *const _ as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_params),\n            \"::\",\n            stringify!(filter)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_params>())).reserved as *const _ as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_params),\n            \"::\",\n            stringify!(reserved)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct snd_timer_status {\n    pub tstamp: timespec,\n    pub resolution: ::core::ffi::c_uint,\n    pub lost: ::core::ffi::c_uint,\n    pub overrun: ::core::ffi::c_uint,\n    pub queue: ::core::ffi::c_uint,\n    pub reserved: [::core::ffi::c_uchar; 64usize],\n}\n#[test]\nfn bindgen_test_layout_snd_timer_status() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_timer_status>(),\n        96usize,\n        concat!(\"Size of: \", stringify!(snd_timer_status))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_timer_status>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(snd_timer_status))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_status>())).tstamp as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_status),\n            \"::\",\n            stringify!(tstamp)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_status>())).resolution as *const _ as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_status),\n            \"::\",\n            stringify!(resolution)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_status>())).lost as *const _ as usize },\n        20usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_status),\n            \"::\",\n            stringify!(lost)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_status>())).overrun as *const _ as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_status),\n            \"::\",\n            stringify!(overrun)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_status>())).queue as *const _ as usize },\n        28usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_status),\n            \"::\",\n            stringify!(queue)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_status>())).reserved as *const _ as usize },\n        32usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_status),\n            \"::\",\n            stringify!(reserved)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct snd_timer_read {\n    pub resolution: ::core::ffi::c_uint,\n    pub ticks: ::core::ffi::c_uint,\n}\n#[test]\nfn bindgen_test_layout_snd_timer_read() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_timer_read>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(snd_timer_read))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_timer_read>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(snd_timer_read))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_read>())).resolution as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_read),\n            \"::\",\n            stringify!(resolution)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_read>())).ticks as *const _ as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_read),\n            \"::\",\n            stringify!(ticks)\n        )\n    );\n}\npub const SNDRV_TIMER_EVENT_RESOLUTION: _bindgen_ty_13 = 0;\npub const SNDRV_TIMER_EVENT_TICK: _bindgen_ty_13 = 1;\npub const SNDRV_TIMER_EVENT_START: _bindgen_ty_13 = 2;\npub const SNDRV_TIMER_EVENT_STOP: _bindgen_ty_13 = 3;\npub const SNDRV_TIMER_EVENT_CONTINUE: _bindgen_ty_13 = 4;\npub const SNDRV_TIMER_EVENT_PAUSE: _bindgen_ty_13 = 5;\npub const SNDRV_TIMER_EVENT_EARLY: _bindgen_ty_13 = 6;\npub const SNDRV_TIMER_EVENT_SUSPEND: _bindgen_ty_13 = 7;\npub const SNDRV_TIMER_EVENT_RESUME: _bindgen_ty_13 = 8;\npub const SNDRV_TIMER_EVENT_MSTART: _bindgen_ty_13 = 12;\npub const SNDRV_TIMER_EVENT_MSTOP: _bindgen_ty_13 = 13;\npub const SNDRV_TIMER_EVENT_MCONTINUE: _bindgen_ty_13 = 14;\npub const SNDRV_TIMER_EVENT_MPAUSE: _bindgen_ty_13 = 15;\npub const SNDRV_TIMER_EVENT_MSUSPEND: _bindgen_ty_13 = 17;\npub const SNDRV_TIMER_EVENT_MRESUME: _bindgen_ty_13 = 18;\npub type _bindgen_ty_13 = u32;\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct snd_timer_tread {\n    pub event: ::core::ffi::c_int,\n    pub tstamp: timespec,\n    pub val: ::core::ffi::c_uint,\n}\n#[test]\nfn bindgen_test_layout_snd_timer_tread() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_timer_tread>(),\n        32usize,\n        concat!(\"Size of: \", stringify!(snd_timer_tread))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_timer_tread>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(snd_timer_tread))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_tread>())).event as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_tread),\n            \"::\",\n            stringify!(event)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_tread>())).tstamp as *const _ as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_tread),\n            \"::\",\n            stringify!(tstamp)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_timer_tread>())).val as *const _ as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_timer_tread),\n            \"::\",\n            stringify!(val)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct snd_ctl_card_info {\n    pub card: ::core::ffi::c_int,\n    pub pad: ::core::ffi::c_int,\n    pub id: [::core::ffi::c_uchar; 16usize],\n    pub driver: [::core::ffi::c_uchar; 16usize],\n    pub name: [::core::ffi::c_uchar; 32usize],\n    pub longname: [::core::ffi::c_uchar; 80usize],\n    pub reserved_: [::core::ffi::c_uchar; 16usize],\n    pub mixername: [::core::ffi::c_uchar; 80usize],\n    pub components: [::core::ffi::c_uchar; 128usize],\n}\n#[test]\nfn bindgen_test_layout_snd_ctl_card_info() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_ctl_card_info>(),\n        376usize,\n        concat!(\"Size of: \", stringify!(snd_ctl_card_info))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_ctl_card_info>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(snd_ctl_card_info))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_card_info>())).card as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_card_info),\n            \"::\",\n            stringify!(card)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_card_info>())).pad as *const _ as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_card_info),\n            \"::\",\n            stringify!(pad)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_card_info>())).id as *const _ as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_card_info),\n            \"::\",\n            stringify!(id)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_card_info>())).driver as *const _ as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_card_info),\n            \"::\",\n            stringify!(driver)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_card_info>())).name as *const _ as usize },\n        40usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_card_info),\n            \"::\",\n            stringify!(name)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_card_info>())).longname as *const _ as usize },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_card_info),\n            \"::\",\n            stringify!(longname)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_card_info>())).reserved_ as *const _ as usize },\n        152usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_card_info),\n            \"::\",\n            stringify!(reserved_)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_card_info>())).mixername as *const _ as usize },\n        168usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_card_info),\n            \"::\",\n            stringify!(mixername)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_card_info>())).components as *const _ as usize },\n        248usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_card_info),\n            \"::\",\n            stringify!(components)\n        )\n    );\n}\npub type snd_ctl_elem_type_t = ::core::ffi::c_int;\npub type snd_ctl_elem_iface_t = ::core::ffi::c_int;\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct snd_ctl_elem_id {\n    pub numid: ::core::ffi::c_uint,\n    pub iface: snd_ctl_elem_iface_t,\n    pub device: ::core::ffi::c_uint,\n    pub subdevice: ::core::ffi::c_uint,\n    pub name: [::core::ffi::c_uchar; 44usize],\n    pub index: ::core::ffi::c_uint,\n}\n#[test]\nfn bindgen_test_layout_snd_ctl_elem_id() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_ctl_elem_id>(),\n        64usize,\n        concat!(\"Size of: \", stringify!(snd_ctl_elem_id))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_ctl_elem_id>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(snd_ctl_elem_id))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_elem_id>())).numid as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_id),\n            \"::\",\n            stringify!(numid)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_elem_id>())).iface as *const _ as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_id),\n            \"::\",\n            stringify!(iface)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_elem_id>())).device as *const _ as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_id),\n            \"::\",\n            stringify!(device)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_elem_id>())).subdevice as *const _ as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_id),\n            \"::\",\n            stringify!(subdevice)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_elem_id>())).name as *const _ as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_id),\n            \"::\",\n            stringify!(name)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_elem_id>())).index as *const _ as usize },\n        60usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_id),\n            \"::\",\n            stringify!(index)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct snd_ctl_elem_list {\n    pub offset: ::core::ffi::c_uint,\n    pub space: ::core::ffi::c_uint,\n    pub used: ::core::ffi::c_uint,\n    pub count: ::core::ffi::c_uint,\n    pub pids: *mut snd_ctl_elem_id,\n    pub reserved: [::core::ffi::c_uchar; 50usize],\n}\n#[test]\nfn bindgen_test_layout_snd_ctl_elem_list() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_ctl_elem_list>(),\n        80usize,\n        concat!(\"Size of: \", stringify!(snd_ctl_elem_list))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_ctl_elem_list>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(snd_ctl_elem_list))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_elem_list>())).offset as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_list),\n            \"::\",\n            stringify!(offset)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_elem_list>())).space as *const _ as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_list),\n            \"::\",\n            stringify!(space)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_elem_list>())).used as *const _ as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_list),\n            \"::\",\n            stringify!(used)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_elem_list>())).count as *const _ as usize },\n        12usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_list),\n            \"::\",\n            stringify!(count)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_elem_list>())).pids as *const _ as usize },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_list),\n            \"::\",\n            stringify!(pids)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_elem_list>())).reserved as *const _ as usize },\n        24usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_list),\n            \"::\",\n            stringify!(reserved)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct snd_ctl_elem_info {\n    pub id: snd_ctl_elem_id,\n    pub type_: snd_ctl_elem_type_t,\n    pub access: ::core::ffi::c_uint,\n    pub count: ::core::ffi::c_uint,\n    pub owner: __kernel_pid_t,\n    pub value: snd_ctl_elem_info__bindgen_ty_1,\n    pub dimen: snd_ctl_elem_info__bindgen_ty_2,\n    pub reserved: [::core::ffi::c_uchar; 56usize],\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union snd_ctl_elem_info__bindgen_ty_1 {\n    pub integer: snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_1,\n    pub integer64: snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_2,\n    pub enumerated: snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_3,\n    pub reserved: [::core::ffi::c_uchar; 128usize],\n    _bindgen_union_align: [u64; 16usize],\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_1 {\n    pub min: ::core::ffi::c_long,\n    pub max: ::core::ffi::c_long,\n    pub step: ::core::ffi::c_long,\n}\n#[test]\nfn bindgen_test_layout_snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_1() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_1>(),\n        24usize,\n        concat!(\n            \"Size of: \",\n            stringify!(snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_1)\n        )\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_1>(),\n        8usize,\n        concat!(\n            \"Alignment of \",\n            stringify!(snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_1)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_1>())).min\n                as *const _ as usize\n        },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(min)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_1>())).max\n                as *const _ as usize\n        },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(max)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_1>())).step\n                as *const _ as usize\n        },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(step)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_2 {\n    pub min: ::core::ffi::c_longlong,\n    pub max: ::core::ffi::c_longlong,\n    pub step: ::core::ffi::c_longlong,\n}\n#[test]\nfn bindgen_test_layout_snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_2() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_2>(),\n        24usize,\n        concat!(\n            \"Size of: \",\n            stringify!(snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_2)\n        )\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_2>(),\n        8usize,\n        concat!(\n            \"Alignment of \",\n            stringify!(snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_2)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_2>())).min\n                as *const _ as usize\n        },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_2),\n            \"::\",\n            stringify!(min)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_2>())).max\n                as *const _ as usize\n        },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_2),\n            \"::\",\n            stringify!(max)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_2>())).step\n                as *const _ as usize\n        },\n        16usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_2),\n            \"::\",\n            stringify!(step)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_3 {\n    pub items: ::core::ffi::c_uint,\n    pub item: ::core::ffi::c_uint,\n    pub name: [::core::ffi::c_char; 64usize],\n    pub names_ptr: __u64,\n    pub names_length: ::core::ffi::c_uint,\n}\n#[test]\nfn bindgen_test_layout_snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_3() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_3>(),\n        88usize,\n        concat!(\n            \"Size of: \",\n            stringify!(snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_3)\n        )\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_3>(),\n        8usize,\n        concat!(\n            \"Alignment of \",\n            stringify!(snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_3)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_3>())).items\n                as *const _ as usize\n        },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_3),\n            \"::\",\n            stringify!(items)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_3>())).item\n                as *const _ as usize\n        },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_3),\n            \"::\",\n            stringify!(item)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_3>())).name\n                as *const _ as usize\n        },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_3),\n            \"::\",\n            stringify!(name)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_3>())).names_ptr\n                as *const _ as usize\n        },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_3),\n            \"::\",\n            stringify!(names_ptr)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_3>())).names_length\n                as *const _ as usize\n        },\n        80usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_info__bindgen_ty_1__bindgen_ty_3),\n            \"::\",\n            stringify!(names_length)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_snd_ctl_elem_info__bindgen_ty_1() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_ctl_elem_info__bindgen_ty_1>(),\n        128usize,\n        concat!(\"Size of: \", stringify!(snd_ctl_elem_info__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_ctl_elem_info__bindgen_ty_1>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(snd_ctl_elem_info__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_ctl_elem_info__bindgen_ty_1>())).integer as *const _ as usize\n        },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_info__bindgen_ty_1),\n            \"::\",\n            stringify!(integer)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_ctl_elem_info__bindgen_ty_1>())).integer64 as *const _\n                as usize\n        },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_info__bindgen_ty_1),\n            \"::\",\n            stringify!(integer64)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_ctl_elem_info__bindgen_ty_1>())).enumerated as *const _\n                as usize\n        },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_info__bindgen_ty_1),\n            \"::\",\n            stringify!(enumerated)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_ctl_elem_info__bindgen_ty_1>())).reserved as *const _\n                as usize\n        },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_info__bindgen_ty_1),\n            \"::\",\n            stringify!(reserved)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union snd_ctl_elem_info__bindgen_ty_2 {\n    pub d: [::core::ffi::c_ushort; 4usize],\n    pub d_ptr: *mut ::core::ffi::c_ushort,\n    _bindgen_union_align: u64,\n}\n#[test]\nfn bindgen_test_layout_snd_ctl_elem_info__bindgen_ty_2() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_ctl_elem_info__bindgen_ty_2>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(snd_ctl_elem_info__bindgen_ty_2))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_ctl_elem_info__bindgen_ty_2>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(snd_ctl_elem_info__bindgen_ty_2))\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_ctl_elem_info__bindgen_ty_2>())).d as *const _ as usize\n        },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_info__bindgen_ty_2),\n            \"::\",\n            stringify!(d)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_ctl_elem_info__bindgen_ty_2>())).d_ptr as *const _ as usize\n        },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_info__bindgen_ty_2),\n            \"::\",\n            stringify!(d_ptr)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_snd_ctl_elem_info() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_ctl_elem_info>(),\n        272usize,\n        concat!(\"Size of: \", stringify!(snd_ctl_elem_info))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_ctl_elem_info>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(snd_ctl_elem_info))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_elem_info>())).id as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_info),\n            \"::\",\n            stringify!(id)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_elem_info>())).type_ as *const _ as usize },\n        64usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_info),\n            \"::\",\n            stringify!(type_)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_elem_info>())).access as *const _ as usize },\n        68usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_info),\n            \"::\",\n            stringify!(access)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_elem_info>())).count as *const _ as usize },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_info),\n            \"::\",\n            stringify!(count)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_elem_info>())).owner as *const _ as usize },\n        76usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_info),\n            \"::\",\n            stringify!(owner)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_elem_info>())).value as *const _ as usize },\n        80usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_info),\n            \"::\",\n            stringify!(value)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_elem_info>())).dimen as *const _ as usize },\n        208usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_info),\n            \"::\",\n            stringify!(dimen)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_elem_info>())).reserved as *const _ as usize },\n        216usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_info),\n            \"::\",\n            stringify!(reserved)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct snd_ctl_elem_value {\n    pub id: snd_ctl_elem_id,\n    pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize], u8>,\n    pub value: snd_ctl_elem_value__bindgen_ty_1,\n    pub tstamp: timespec,\n    pub reserved: [::core::ffi::c_uchar; 112usize],\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union snd_ctl_elem_value__bindgen_ty_1 {\n    pub integer: snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_1,\n    pub integer64: snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_2,\n    pub enumerated: snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_3,\n    pub bytes: snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_4,\n    pub iec958: snd_aes_iec958,\n    _bindgen_union_align: [u64; 128usize],\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_1 {\n    pub value: [::core::ffi::c_long; 128usize],\n    pub value_ptr: *mut ::core::ffi::c_long,\n    _bindgen_union_align: [u64; 128usize],\n}\n#[test]\nfn bindgen_test_layout_snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_1() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_1>(),\n        1024usize,\n        concat!(\n            \"Size of: \",\n            stringify!(snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_1)\n        )\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_1>(),\n        8usize,\n        concat!(\n            \"Alignment of \",\n            stringify!(snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_1)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_1>())).value\n                as *const _ as usize\n        },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(value)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_1>())).value_ptr\n                as *const _ as usize\n        },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(value_ptr)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_2 {\n    pub value: [::core::ffi::c_longlong; 64usize],\n    pub value_ptr: *mut ::core::ffi::c_longlong,\n    _bindgen_union_align: [u64; 64usize],\n}\n#[test]\nfn bindgen_test_layout_snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_2() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_2>(),\n        512usize,\n        concat!(\n            \"Size of: \",\n            stringify!(snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_2)\n        )\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_2>(),\n        8usize,\n        concat!(\n            \"Alignment of \",\n            stringify!(snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_2)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_2>())).value\n                as *const _ as usize\n        },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_2),\n            \"::\",\n            stringify!(value)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_2>())).value_ptr\n                as *const _ as usize\n        },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_2),\n            \"::\",\n            stringify!(value_ptr)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_3 {\n    pub item: [::core::ffi::c_uint; 128usize],\n    pub item_ptr: *mut ::core::ffi::c_uint,\n    _bindgen_union_align: [u64; 64usize],\n}\n#[test]\nfn bindgen_test_layout_snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_3() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_3>(),\n        512usize,\n        concat!(\n            \"Size of: \",\n            stringify!(snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_3)\n        )\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_3>(),\n        8usize,\n        concat!(\n            \"Alignment of \",\n            stringify!(snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_3)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_3>())).item\n                as *const _ as usize\n        },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_3),\n            \"::\",\n            stringify!(item)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_3>())).item_ptr\n                as *const _ as usize\n        },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_3),\n            \"::\",\n            stringify!(item_ptr)\n        )\n    );\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_4 {\n    pub data: [::core::ffi::c_uchar; 512usize],\n    pub data_ptr: *mut ::core::ffi::c_uchar,\n    _bindgen_union_align: [u64; 64usize],\n}\n#[test]\nfn bindgen_test_layout_snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_4() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_4>(),\n        512usize,\n        concat!(\n            \"Size of: \",\n            stringify!(snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_4)\n        )\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_4>(),\n        8usize,\n        concat!(\n            \"Alignment of \",\n            stringify!(snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_4)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_4>())).data\n                as *const _ as usize\n        },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_4),\n            \"::\",\n            stringify!(data)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_4>())).data_ptr\n                as *const _ as usize\n        },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_value__bindgen_ty_1__bindgen_ty_4),\n            \"::\",\n            stringify!(data_ptr)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_snd_ctl_elem_value__bindgen_ty_1() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_ctl_elem_value__bindgen_ty_1>(),\n        1024usize,\n        concat!(\"Size of: \", stringify!(snd_ctl_elem_value__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_ctl_elem_value__bindgen_ty_1>(),\n        8usize,\n        concat!(\n            \"Alignment of \",\n            stringify!(snd_ctl_elem_value__bindgen_ty_1)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_ctl_elem_value__bindgen_ty_1>())).integer as *const _\n                as usize\n        },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_value__bindgen_ty_1),\n            \"::\",\n            stringify!(integer)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_ctl_elem_value__bindgen_ty_1>())).integer64 as *const _\n                as usize\n        },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_value__bindgen_ty_1),\n            \"::\",\n            stringify!(integer64)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_ctl_elem_value__bindgen_ty_1>())).enumerated as *const _\n                as usize\n        },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_value__bindgen_ty_1),\n            \"::\",\n            stringify!(enumerated)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_ctl_elem_value__bindgen_ty_1>())).bytes as *const _ as usize\n        },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_value__bindgen_ty_1),\n            \"::\",\n            stringify!(bytes)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_ctl_elem_value__bindgen_ty_1>())).iec958 as *const _ as usize\n        },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_value__bindgen_ty_1),\n            \"::\",\n            stringify!(iec958)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_snd_ctl_elem_value() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_ctl_elem_value>(),\n        1224usize,\n        concat!(\"Size of: \", stringify!(snd_ctl_elem_value))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_ctl_elem_value>(),\n        8usize,\n        concat!(\"Alignment of \", stringify!(snd_ctl_elem_value))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_elem_value>())).id as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_value),\n            \"::\",\n            stringify!(id)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_elem_value>())).value as *const _ as usize },\n        72usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_value),\n            \"::\",\n            stringify!(value)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_elem_value>())).tstamp as *const _ as usize },\n        1096usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_value),\n            \"::\",\n            stringify!(tstamp)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_elem_value>())).reserved as *const _ as usize },\n        1112usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_elem_value),\n            \"::\",\n            stringify!(reserved)\n        )\n    );\n}\nimpl snd_ctl_elem_value {\n    #[inline]\n    pub fn indirect(&self) -> ::core::ffi::c_uint {\n        unsafe { ::core::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) }\n    }\n    #[inline]\n    pub fn set_indirect(&mut self, val: ::core::ffi::c_uint) {\n        unsafe {\n            let val: u32 = ::core::mem::transmute(val);\n            self._bitfield_1.set(0usize, 1u8, val as u64)\n        }\n    }\n    #[inline]\n    pub fn new_bitfield_1(\n        indirect: ::core::ffi::c_uint,\n    ) -> __BindgenBitfieldUnit<[u8; 1usize], u8> {\n        let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize], u8> =\n            Default::default();\n        __bindgen_bitfield_unit.set(0usize, 1u8, {\n            let indirect: u32 = unsafe { ::core::mem::transmute(indirect) };\n            indirect as u64\n        });\n        __bindgen_bitfield_unit\n    }\n}\n#[repr(C)]\n#[derive(Debug)]\npub struct snd_ctl_tlv {\n    pub numid: ::core::ffi::c_uint,\n    pub length: ::core::ffi::c_uint,\n    pub tlv: __IncompleteArrayField<::core::ffi::c_uint>,\n}\n#[test]\nfn bindgen_test_layout_snd_ctl_tlv() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_ctl_tlv>(),\n        8usize,\n        concat!(\"Size of: \", stringify!(snd_ctl_tlv))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_ctl_tlv>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(snd_ctl_tlv))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_tlv>())).numid as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_tlv),\n            \"::\",\n            stringify!(numid)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_tlv>())).length as *const _ as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_tlv),\n            \"::\",\n            stringify!(length)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_tlv>())).tlv as *const _ as usize },\n        8usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_tlv),\n            \"::\",\n            stringify!(tlv)\n        )\n    );\n}\npub const sndrv_ctl_event_type_SNDRV_CTL_EVENT_ELEM: sndrv_ctl_event_type = 0;\npub const sndrv_ctl_event_type_SNDRV_CTL_EVENT_LAST: sndrv_ctl_event_type = 0;\npub type sndrv_ctl_event_type = u32;\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct snd_ctl_event {\n    pub type_: ::core::ffi::c_int,\n    pub data: snd_ctl_event__bindgen_ty_1,\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union snd_ctl_event__bindgen_ty_1 {\n    pub elem: snd_ctl_event__bindgen_ty_1__bindgen_ty_1,\n    pub data8: [::core::ffi::c_uchar; 60usize],\n    _bindgen_union_align: [u32; 17usize],\n}\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct snd_ctl_event__bindgen_ty_1__bindgen_ty_1 {\n    pub mask: ::core::ffi::c_uint,\n    pub id: snd_ctl_elem_id,\n}\n#[test]\nfn bindgen_test_layout_snd_ctl_event__bindgen_ty_1__bindgen_ty_1() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_ctl_event__bindgen_ty_1__bindgen_ty_1>(),\n        68usize,\n        concat!(\n            \"Size of: \",\n            stringify!(snd_ctl_event__bindgen_ty_1__bindgen_ty_1)\n        )\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_ctl_event__bindgen_ty_1__bindgen_ty_1>(),\n        4usize,\n        concat!(\n            \"Alignment of \",\n            stringify!(snd_ctl_event__bindgen_ty_1__bindgen_ty_1)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_ctl_event__bindgen_ty_1__bindgen_ty_1>())).mask as *const _\n                as usize\n        },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_event__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(mask)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_ctl_event__bindgen_ty_1__bindgen_ty_1>())).id as *const _\n                as usize\n        },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_event__bindgen_ty_1__bindgen_ty_1),\n            \"::\",\n            stringify!(id)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_snd_ctl_event__bindgen_ty_1() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_ctl_event__bindgen_ty_1>(),\n        68usize,\n        concat!(\"Size of: \", stringify!(snd_ctl_event__bindgen_ty_1))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_ctl_event__bindgen_ty_1>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(snd_ctl_event__bindgen_ty_1))\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_ctl_event__bindgen_ty_1>())).elem as *const _ as usize\n        },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_event__bindgen_ty_1),\n            \"::\",\n            stringify!(elem)\n        )\n    );\n    assert_eq!(\n        unsafe {\n            &(*(::core::ptr::null::<snd_ctl_event__bindgen_ty_1>())).data8 as *const _ as usize\n        },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_event__bindgen_ty_1),\n            \"::\",\n            stringify!(data8)\n        )\n    );\n}\n#[test]\nfn bindgen_test_layout_snd_ctl_event() {\n    assert_eq!(\n        ::core::mem::size_of::<snd_ctl_event>(),\n        72usize,\n        concat!(\"Size of: \", stringify!(snd_ctl_event))\n    );\n    assert_eq!(\n        ::core::mem::align_of::<snd_ctl_event>(),\n        4usize,\n        concat!(\"Alignment of \", stringify!(snd_ctl_event))\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_event>())).type_ as *const _ as usize },\n        0usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_event),\n            \"::\",\n            stringify!(type_)\n        )\n    );\n    assert_eq!(\n        unsafe { &(*(::core::ptr::null::<snd_ctl_event>())).data as *const _ as usize },\n        4usize,\n        concat!(\n            \"Offset of field: \",\n            stringify!(snd_ctl_event),\n            \"::\",\n            stringify!(data)\n        )\n    );\n}\n"
  },
  {
    "path": "src/direct/ffi.rs",
    "content": "//! Some definitions from the kernel headers\n\n#![allow(non_camel_case_types)]\n\nuse cfg_if::cfg_if;\n\n// const SNDRV_PCM_MMAP_OFFSET_DATA: c_uint = 0x00000000;\npub const SNDRV_PCM_MMAP_OFFSET_STATUS: libc::c_uint = 0x80000000;\npub const SNDRV_PCM_MMAP_OFFSET_CONTROL: libc::c_uint = 0x81000000;\n\npub const SNDRV_PCM_SYNC_PTR_HWSYNC: libc::c_uint = 1;\npub const SNDRV_PCM_SYNC_PTR_APPL: libc::c_uint = 2;\npub const SNDRV_PCM_SYNC_PTR_AVAIL_MIN: libc::c_uint = 4;\n\n// #[repr(C)]\n#[allow(non_camel_case_types)]\npub type snd_pcm_state_t = libc::c_int;\n\n// #[repr(C)]\n#[allow(non_camel_case_types)]\npub type snd_pcm_uframes_t = libc::c_ulong;\n\n// I think?! Not sure how this will work with X32 ABI?!\n#[allow(non_camel_case_types)]\npub type __kernel_off_t = libc::c_long;\n\n#[repr(C)]\n#[derive(Copy, Clone, Debug)]\npub struct snd_pcm_mmap_status {\n    pub state: snd_pcm_state_t,    /* RO: state - SNDRV_PCM_STATE_XXXX */\n    pub pad1: libc::c_int,         /* Needed for 64 bit alignment */\n    pub hw_ptr: snd_pcm_uframes_t, /* RO: hw ptr (0...boundary-1) */\n    pub tstamp: libc::timespec,    /* Timestamp */\n    pub suspended_state: snd_pcm_state_t, /* RO: suspended stream state */\n    pub audio_tstamp: libc::timespec, /* from sample counter or wall clock */\n}\n\n#[repr(C)]\n#[derive(Debug, Copy, Clone)]\npub struct snd_pcm_mmap_control {\n    pub appl_ptr: snd_pcm_uframes_t,  /* RW: appl ptr (0...boundary-1) */\n    pub avail_min: snd_pcm_uframes_t, /* RW: min available frames for wakeup */\n}\n\n#[repr(C)]\n#[derive(Debug)]\npub struct snd_pcm_channel_info {\n    pub channel: libc::c_uint,\n    pub offset: __kernel_off_t, /* mmap offset */\n    pub first: libc::c_uint,    /* offset to first sample in bits */\n    pub step: libc::c_uint,     /* samples distance in bits */\n}\n\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union snd_pcm_mmap_status_r {\n    pub status: snd_pcm_mmap_status,\n    pub reserved: [libc::c_uchar; 64],\n}\n\n#[repr(C)]\n#[derive(Copy, Clone)]\npub union snd_pcm_mmap_control_r {\n    pub control: snd_pcm_mmap_control,\n    pub reserved: [libc::c_uchar; 64],\n}\n\n#[repr(C)]\n#[derive(Copy, Clone)]\npub struct snd_pcm_sync_ptr {\n    pub flags: libc::c_uint,\n    pub s: snd_pcm_mmap_status_r,\n    pub c: snd_pcm_mmap_control_r,\n}\n\ncfg_if! {\n    if #[cfg(any(target_os = \"linux\", target_os = \"android\"))] {\n        // See <https://github.com/nix-rust/nix/blob/197f55b3ccbce3273bf6ce119d1a8541b5df5d66/src/sys/ioctl/linux.rs>\n\n        cfg_if! {\n            if #[cfg(any(target_os = \"android\", target_env = \"musl\"))] {\n                pub(super) type ioctl_num_type = libc::c_int;\n            } else {\n                pub(super) type ioctl_num_type = libc::c_ulong;\n            }\n        }\n\n        // The READ dir is consistent across arches\n        pub(super) const READ: ioctl_num_type = 2;\n\n        // But WRITE is not, as well as having a different number of bits for the SIZEBITS\n        cfg_if!{\n            if #[cfg(any(\n                target_arch = \"mips\",\n                target_arch = \"mips32r6\",\n                target_arch = \"mips64\",\n                target_arch = \"mips64r6\",\n                target_arch = \"powerpc\",\n                target_arch = \"powerpc64\",\n                target_arch = \"sparc64\"\n            ))] {\n                pub(super) const WRITE: ioctl_num_type = 4;\n                const SIZEBITS: ioctl_num_type = 13;\n            } else {\n                pub(super) const WRITE: ioctl_num_type = 1;\n                const SIZEBITS: ioctl_num_type = 14;\n            }\n        }\n\n        const NRSHIFT: ioctl_num_type = 0;\n        const NRBITS: ioctl_num_type = 8;\n        const TYPEBITS: ioctl_num_type = 8;\n        const TYPESHIFT: ioctl_num_type = NRSHIFT + NRBITS;\n        const SIZESHIFT: ioctl_num_type = TYPESHIFT + TYPEBITS;\n        const DIRSHIFT: ioctl_num_type = SIZESHIFT + SIZEBITS;\n\n        /// Replication of the [`nix::ioc!`](https://github.com/nix-rust/nix/blob/197f55b3ccbce3273bf6ce119d1a8541b5df5d66/src/sys/ioctl/linux.rs#L78-L96)\n        pub(super) const fn make_request(\n            dir: ioctl_num_type,\n            typ: u8,\n            nr: u8,\n            size: usize,\n        ) -> ioctl_num_type {\n            dir << DIRSHIFT\n                | (typ as ioctl_num_type) << TYPESHIFT\n                | (nr as ioctl_num_type) << NRSHIFT\n                | (size as ioctl_num_type) << SIZESHIFT\n        }\n    } else if #[cfg(any(\n        target_os = \"dragonfly\",\n        target_os = \"freebsd\",\n        target_os = \"netbsd\",\n        target_os = \"openbsd\",\n        target_os = \"solaris\",\n        target_os = \"illumos\"\n    ))] {\n        // See <https://github.com/nix-rust/nix/blob/197f55b3ccbce3273bf6ce119d1a8541b5df5d66/src/sys/ioctl/bsd.rs>\n\n        cfg_if! {\n            if #[cfg(not(any(target_os = \"illumos\", target_os = \"solaris\")))] {\n                pub(super) type ioctl_num_type = libc::c_ulong;\n            } else {\n                pub(super) type ioctl_num_type = libc::c_int;\n            }\n        }\n\n        #[allow(overflowing_literals)]\n        pub(super) const READ: ioctl_num_type = 0x4000_0000;\n        #[allow(overflowing_literals)]\n        pub(super) const WRITE: ioctl_num_type = 0x8000_0000;\n\n        const IOCPARM_MASK: ioctl_num_type = 0x1fff;\n\n        /// Replication of [`nix::ioc!`](https://github.com/nix-rust/nix/blob/197f55b3ccbce3273bf6ce119d1a8541b5df5d66/src/sys/ioctl/bsd.rs#L31-L42)\n        pub(super) const fn make_request(\n            dir: ioctl_num_type,\n            typ: u8,\n            nr: u8,\n            size: usize,\n        ) -> ioctl_num_type {\n            dir | ((size as ioctl_num_type) & IOCPARM_MASK) << 16\n                | (typ as ioctl_num_type) << 8\n                | nr as ioctl_num_type\n        }\n    } else {\n        compile_error!(\"unknown target platform\");\n    }\n}\n\npub(crate) unsafe fn sndrv_pcm_ioctl_channel_info(\n    fd: libc::c_int,\n    data: *mut snd_pcm_channel_info,\n) -> Result<(), crate::Error> {\n    const REQUEST: ioctl_num_type = make_request(\n        READ,\n        b'A',\n        0x32,\n        core::mem::size_of::<snd_pcm_channel_info>(),\n    );\n\n    unsafe {\n        if libc::ioctl(fd, REQUEST, data) == -1 {\n            Err(crate::Error::last(\"SNDRV_PCM_IOCTL_CHANNEL_INFO\"))\n        } else {\n            Ok(())\n        }\n    }\n}\n\npub(crate) unsafe fn sndrv_pcm_ioctl_sync_ptr(\n    fd: libc::c_int,\n    data: *mut snd_pcm_sync_ptr,\n) -> Result<(), crate::Error> {\n    const REQUEST: ioctl_num_type = make_request(\n        READ | WRITE,\n        b'A',\n        0x23,\n        core::mem::size_of::<snd_pcm_sync_ptr>(),\n    );\n\n    unsafe {\n        if libc::ioctl(fd, REQUEST, data) == -1 {\n            Err(crate::Error::last(\"SNDRV_PCM_IOCTL_SYNC_PTR\"))\n        } else {\n            Ok(())\n        }\n    }\n}\n\npub fn pagesize() -> usize {\n    unsafe { libc::sysconf(libc::_SC_PAGESIZE) as usize }\n}\n"
  },
  {
    "path": "src/direct/pcm.rs",
    "content": "/*!\nThis module bypasses alsa-lib and directly read and write into memory mapped kernel memory.\nIn case of the sample memory, this is in many cases the DMA buffers that is transferred to the sound card.\n\nThe reasons for doing this are:\n\n * Minimum overhead where it matters most: let alsa-lib do the code heavy setup -\n   then steal its file descriptor and deal with sample streaming from Rust.\n * RT-safety to the maximum extent possible. Creating/dropping any of these structs causes syscalls,\n   but function calls on these are just read and write from memory. No syscalls, no memory allocations,\n   not even loops (with the exception of `MmapPlayback::write` that loops over samples to write).\n * Possibility to allow Send + Sync for structs\n * It's a fun experiment and an interesting deep dive into how alsa-lib does things.\n\nNote: Not all sound card drivers support this direct method of communication; although almost all\nmodern/common ones do. It only works with hardware devices though (such as \"hw:xxx\" device strings),\ndon't expect it to work with, e g, the PulseAudio plugin or so.\n\nFor an example of how to use this mode, look in the \"synth-example\" directory.\n*/\n\nuse libc;\nuse core::{mem, ptr, fmt, cmp};\nuse crate::error::{Error, Result};\nuse crate::{pcm, PollDescriptors, Direction};\nuse crate::pcm::Frames;\nuse core::marker::PhantomData;\n\nuse super::ffi::*;\n\n#[cfg(feature = \"std\")]\ntype RawFd = std::os::unix::io::RawFd;\n\n#[cfg(not(feature = \"std\"))]\ntype RawFd = core::ffi::c_int;\n\n/// Read PCM status via a simple kernel syscall, bypassing alsa-lib.\n///\n/// If Status is not available on your architecture, this is the second best option.\n#[derive(Debug)]\npub struct SyncPtrStatus(snd_pcm_mmap_status);\n\nimpl SyncPtrStatus {\n    /// Executes sync_ptr syscall.\n    ///\n    /// Unsafe because\n    ///  - setting appl_ptr and avail_min might make alsa-lib confused\n    ///  - no check that the fd is really a PCM\n    pub unsafe fn sync_ptr(fd: RawFd, hwsync: bool, appl_ptr: Option<pcm::Frames>, avail_min: Option<pcm::Frames>) -> Result<Self> {\n        let mut data = snd_pcm_sync_ptr {\n\t\t\tflags: (if hwsync { SNDRV_PCM_SYNC_PTR_HWSYNC } else { 0 }) +\n\t\t\t\t(if appl_ptr.is_some() { SNDRV_PCM_SYNC_PTR_APPL } else { 0 }) +\n\t\t\t\t(if avail_min.is_some() { SNDRV_PCM_SYNC_PTR_AVAIL_MIN } else { 0 }),\n\t\t\tc: snd_pcm_mmap_control_r {\n\t\t\t\tcontrol: snd_pcm_mmap_control {\n\t\t\t\t\tappl_ptr: appl_ptr.unwrap_or(0) as snd_pcm_uframes_t,\n\t\t\t\t\tavail_min: avail_min.unwrap_or(0) as snd_pcm_uframes_t,\n\t\t\t\t}\n\t\t\t},\n\t\t\ts: mem::zeroed()\n\t\t};\n\n        sndrv_pcm_ioctl_sync_ptr(fd, &mut data)?;\n\n        let i = data.s.status.state;\n        if (i >= (pcm::State::Open as snd_pcm_state_t)) && (i <= (pcm::State::Disconnected as snd_pcm_state_t)) {\n            Ok(SyncPtrStatus(data.s.status))\n        } else {\n            Err(Error::unsupported(\"SNDRV_PCM_IOCTL_SYNC_PTR returned broken state\"))\n        }\n    }\n\n    pub fn hw_ptr(&self) -> pcm::Frames { self.0.hw_ptr as pcm::Frames }\n    pub fn state(&self) -> pcm::State { unsafe { mem::transmute(self.0.state as u8) } /* valid range checked in sync_ptr */ }\n    pub fn htstamp(&self) -> libc::timespec { self.0.tstamp }\n}\n\n\n\n/// Read PCM status directly from memory, bypassing alsa-lib.\n///\n/// This means that it's\n/// 1) less overhead for reading status (no syscall, no allocations, no virtual dispatch, just a read from memory)\n/// 2) Send + Sync, and\n/// 3) will only work for \"hw\" / \"plughw\" devices (not e g PulseAudio plugins), and not\n/// all of those are supported, although all common ones are (as of 2017, and a kernel from the same decade).\n/// Kernel supported archs are: x86, PowerPC, Alpha. Use \"SyncPtrStatus\" for other archs.\n///\n/// The values are updated every now and then by the kernel. Many functions will force an update to happen,\n/// e g `PCM::avail()` and `PCM::delay()`.\n///\n/// Note: Even if you close the original PCM device, ALSA will not actually close the device until all\n/// Status structs are dropped too.\n///\n#[derive(Debug)]\npub struct Status(DriverMemory<snd_pcm_mmap_status>);\n\nfn pcm_to_fd(p: &pcm::PCM) -> Result<RawFd> {\n    let mut fds: [libc::pollfd; 1] = unsafe { mem::zeroed() };\n    let c = PollDescriptors::fill(p, &mut fds)?;\n    if c != 1 {\n        return Err(Error::unsupported(\"snd_pcm_poll_descriptors returned wrong number of fds\"))\n    }\n    Ok(fds[0].fd)\n}\n\nimpl Status {\n    pub fn new(p: &pcm::PCM) -> Result<Self> { Status::from_fd(pcm_to_fd(p)?) }\n\n    pub fn from_fd(fd: RawFd) -> Result<Self> {\n        DriverMemory::new(fd, 1, SNDRV_PCM_MMAP_OFFSET_STATUS as libc::off_t, false).map(Status)\n    }\n\n    /// Current PCM state.\n    pub fn state(&self) -> pcm::State {\n        unsafe {\n            let i = ptr::read_volatile(&(*self.0.ptr).state);\n            assert!((i >= (pcm::State::Open as snd_pcm_state_t)) && (i <= (pcm::State::Disconnected as snd_pcm_state_t)));\n            mem::transmute(i as u8)\n        }\n    }\n\n    /// Number of frames hardware has read or written\n    ///\n    /// This number is updated every now and then by the kernel.\n    /// Calling most functions on the PCM will update it, so will usually a period interrupt.\n    /// No guarantees given.\n    ///\n    /// This value wraps at \"boundary\" (a large value you can read from SwParams).\n    pub fn hw_ptr(&self) -> pcm::Frames {\n        unsafe {\n            ptr::read_volatile(&(*self.0.ptr).hw_ptr) as pcm::Frames\n        }\n    }\n\n    /// Timestamp - fast version of alsa-lib's Status::get_htstamp\n    ///\n    /// Note: This just reads the actual value in memory.\n    /// Unfortunately, the timespec is too big to be read atomically on most archs.\n    /// Therefore, this function can potentially give bogus result at times, at least in theory...?\n    pub fn htstamp(&self) -> libc::timespec {\n        unsafe {\n            ptr::read_volatile(&(*self.0.ptr).tstamp)\n        }\n    }\n\n    /// Audio timestamp - fast version of alsa-lib's Status::get_audio_htstamp\n    ///\n    /// Note: This just reads the actual value in memory.\n    /// Unfortunately, the timespec is too big to be read atomically on most archs.\n    /// Therefore, this function can potentially give bogus result at times, at least in theory...?\n    pub fn audio_htstamp(&self) -> libc::timespec {\n        unsafe {\n            ptr::read_volatile(&(*self.0.ptr).audio_tstamp)\n        }\n    }\n}\n\n/// Write PCM appl ptr directly, bypassing alsa-lib.\n///\n/// Provides direct access to appl ptr and avail min, without the overhead of\n/// alsa-lib or a syscall. Caveats that apply to Status applies to this struct too.\n#[derive(Debug)]\npub struct Control(DriverMemory<snd_pcm_mmap_control>);\n\nimpl Control {\n    pub fn new(p: &pcm::PCM) -> Result<Self> { Self::from_fd(pcm_to_fd(p)?) }\n\n    pub fn from_fd(fd: RawFd) -> Result<Self> {\n        DriverMemory::new(fd, 1, SNDRV_PCM_MMAP_OFFSET_CONTROL as libc::off_t, true).map(Control)\n    }\n\n    /// Read number of frames application has read or written\n    ///\n    /// This value wraps at \"boundary\" (a large value you can read from SwParams).\n    pub fn appl_ptr(&self) -> pcm::Frames {\n        unsafe {\n            ptr::read_volatile(&(*self.0.ptr).appl_ptr) as pcm::Frames\n        }\n    }\n\n    /// Set number of frames application has read or written\n    ///\n    /// When the kernel wakes up due to a period interrupt, this value will\n    /// be checked by the kernel. An XRUN will happen in case the application\n    /// has not read or written enough data.\n    pub fn set_appl_ptr(&self, value: pcm::Frames) {\n        unsafe {\n            ptr::write_volatile(&mut (*self.0.ptr).appl_ptr, value as snd_pcm_uframes_t)\n        }\n    }\n\n    /// Read minimum number of frames in buffer in order to wakeup process\n    pub fn avail_min(&self) -> pcm::Frames {\n        unsafe {\n            ptr::read_volatile(&(*self.0.ptr).avail_min) as pcm::Frames\n        }\n    }\n\n    /// Write minimum number of frames in buffer in order to wakeup process\n    pub fn set_avail_min(&self, value: pcm::Frames) {\n        unsafe {\n            ptr::write_volatile(&mut (*self.0.ptr).avail_min, value as snd_pcm_uframes_t)\n        }\n    }\n}\n\nstruct DriverMemory<S> {\n   ptr: *mut S,\n   size: libc::size_t,\n}\n\nimpl<S> fmt::Debug for DriverMemory<S> {\n   fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, \"DriverMemory({:?})\", self.ptr) }\n}\n\nimpl<S> DriverMemory<S> {\n    fn new(fd: RawFd, count: usize, offs: libc::off_t, writable: bool) -> Result<Self> {\n        let mut total = count * mem::size_of::<S>();\n        let ps = pagesize();\n        assert!(total > 0);\n        if total % ps != 0 { total += ps - total % ps };\n        let flags = if writable { libc::PROT_WRITE | libc::PROT_READ } else { libc::PROT_READ };\n        let p = unsafe { libc::mmap(ptr::null_mut(), total, flags, libc::MAP_FILE | libc::MAP_SHARED, fd, offs) };\n        if p.is_null() || p == libc::MAP_FAILED {\n            Err(Error::last(\"mmap (of driver memory)\"))\n        } else {\n            Ok(DriverMemory { ptr: p as *mut S, size: total })\n        }\n    }\n}\n\nunsafe impl<S> Send for DriverMemory<S> {}\nunsafe impl<S> Sync for DriverMemory<S> {}\n\nimpl<S> Drop for DriverMemory<S> {\n    fn drop(&mut self) {\n        unsafe {{ libc::munmap(self.ptr as *mut libc::c_void, self.size); } }\n    }\n}\n\n#[derive(Debug)]\nstruct SampleData<S> {\n    mem: DriverMemory<S>,\n    frames: pcm::Frames,\n    channels: u32,\n}\n\nimpl<S> SampleData<S> {\n    pub fn new(p: &pcm::PCM) -> Result<Self> {\n        let params = p.hw_params_current()?;\n        let bufsize = params.get_buffer_size()?;\n        let channels = params.get_channels()?;\n        if params.get_access()? != pcm::Access::MMapInterleaved {\n            return Err(Error::unsupported(\"Not MMAP interleaved data\"))\n        }\n\n        let fd = pcm_to_fd(p)?;\n        let info = unsafe {\n            let mut info: snd_pcm_channel_info = mem::zeroed();\n            sndrv_pcm_ioctl_channel_info(fd, &mut info)?;\n            info\n        };\n        // println!(\"{:?}\", info);\n        if (info.step != channels * mem::size_of::<S>() as u32 * 8) || (info.first != 0) {\n            return Err(Error::unsupported(\"MMAP data size mismatch\"))\n        }\n        Ok(SampleData {\n            mem: DriverMemory::new(fd, (bufsize as usize) * (channels as usize), info.offset as libc::off_t, true)?,\n            frames: bufsize,\n            channels,\n        })\n    }\n}\n\n\n/// Dummy trait for better generics\npub trait MmapDir: fmt::Debug {\n    const DIR: Direction;\n    fn avail(hwptr: Frames, applptr: Frames, buffersize: Frames, boundary: Frames) -> Frames;\n}\n\n/// Dummy struct for better generics\n#[derive(Copy, Clone, Debug)]\npub struct Playback;\n\nimpl MmapDir for Playback {\n    const DIR: Direction = Direction::Playback;\n    #[inline]\n    fn avail(hwptr: Frames, applptr: Frames, buffersize: Frames, boundary: Frames) -> Frames {\n\tlet r = hwptr.wrapping_add(buffersize).wrapping_sub(applptr);\n\tlet r = if r < 0 { r.wrapping_add(boundary) } else { r };\n        if r as usize >= boundary as usize { r.wrapping_sub(boundary) } else { r }\n    }\n}\n\n/// Dummy struct for better generics\n#[derive(Copy, Clone, Debug)]\npub struct Capture;\n\nimpl MmapDir for Capture {\n    const DIR: Direction = Direction::Capture;\n    #[inline]\n    fn avail(hwptr: Frames, applptr: Frames, _buffersize: Frames, boundary: Frames) -> Frames {\n\tlet r = hwptr.wrapping_sub(applptr);\n\tif r < 0 { r.wrapping_add(boundary) } else { r }\n    }\n}\n\npub type MmapPlayback<S> = MmapIO<S, Playback>;\n\npub type MmapCapture<S> = MmapIO<S, Capture>;\n\n#[derive(Debug)]\n/// Struct containing direct I/O functions shared between playback and capture.\npub struct MmapIO<S, D> {\n    data: SampleData<S>,\n    c: Control,\n    ss: Status,\n    bound: Frames,\n    dir: PhantomData<*const D>,\n}\n\n#[derive(Debug, Clone, Copy)]\n/// A raw pointer to samples, and the amount of samples readable or writable.\npub struct RawSamples<S> {\n    pub ptr: *mut S,\n    pub frames: Frames,\n    pub channels: u32,\n}\n\nimpl<S> RawSamples<S> {\n    #[inline]\n    /// Returns `frames` * `channels`, i e the amount of samples (of type `S`) that can be read/written.\n    pub fn samples(&self) -> isize { self.frames as isize * (self.channels as isize) }\n\n    /// Writes samples from an iterator.\n    ///\n    /// Returns true if iterator was depleted, and the number of samples written.\n    /// This is just raw read/write of memory.\n    pub unsafe fn write_samples<I: Iterator<Item=S>>(&self, i: &mut I) -> (bool, isize) {\n        let mut z = 0;\n        let max_samples = self.samples();\n        while z < max_samples {\n            let b = if let Some(b) = i.next() { b } else { return (true, z) };\n            ptr::write_volatile(self.ptr.offset(z), b);\n            z += 1;\n        };\n        (false, z)\n    }\n\n}\n\nimpl<S, D: MmapDir> MmapIO<S, D> {\n    fn new(p: &pcm::PCM) -> Result<Self> {\n        if p.info()?.get_stream() != D::DIR {\n            return Err(Error::unsupported(\"Wrong direction\"));\n        }\n        let boundary = p.sw_params_current()?.get_boundary()?;\n        Ok(MmapIO {\n            data: SampleData::new(p)?,\n            c: Control::new(p)?,\n            ss: Status::new(p)?,\n            bound: boundary,\n            dir: PhantomData,\n        })\n    }\n}\n\npub (crate) fn new_mmap<S, D: MmapDir>(p: &pcm::PCM) -> Result<MmapIO<S, D>> { MmapIO::new(p) }\n\nimpl<S, D: MmapDir> MmapIO<S, D> {\n    /// Read current status\n    pub fn status(&self) -> &Status { &self.ss }\n\n    /// Read current number of frames committed by application\n    ///\n    /// This number wraps at 'boundary'.\n    #[inline]\n    pub fn appl_ptr(&self) -> Frames { self.c.appl_ptr() }\n\n    /// Read current number of frames read / written by hardware\n    ///\n    /// This number wraps at 'boundary'.\n    #[inline]\n    pub fn hw_ptr(&self) -> Frames { self.ss.hw_ptr() }\n\n    /// The number at which hw_ptr and appl_ptr wraps.\n    #[inline]\n    pub fn boundary(&self) -> Frames { self.bound }\n\n    /// Total number of frames in hardware buffer\n    #[inline]\n    pub fn buffer_size(&self) -> Frames { self.data.frames }\n\n    /// Number of channels in stream\n    #[inline]\n    pub fn channels(&self) -> u32 { self.data.channels }\n\n    /// Notifies the kernel that frames have now been read / written by the application\n    ///\n    /// This will allow the kernel to write new data into this part of the buffer.\n    pub fn commit(&self, v: Frames) {\n        let mut z = self.appl_ptr() + v;\n        if z + v >= self.boundary() { z -= self.boundary() };\n        self.c.set_appl_ptr(z)\n    }\n\n    /// Number of frames available to read / write.\n    ///\n    /// In case of an underrun, this value might be bigger than the buffer size.\n    pub fn avail(&self) -> Frames { D::avail(self.hw_ptr(), self.appl_ptr(), self.buffer_size(), self.boundary()) }\n\n    /// Returns raw pointers to data to read / write.\n    ///\n    /// Use this if you want to read/write data yourself (instead of using iterators). If you do,\n    /// using `write_volatile` or `read_volatile` is recommended, since it's DMA memory and can\n    /// change at any time.\n    ///\n    /// Since this is a ring buffer, there might be more data to read/write in the beginning\n    /// of the buffer as well. If so this is returned as the second return value.\n    pub fn data_ptr(&self) -> (RawSamples<S>, Option<RawSamples<S>>) {\n        let (hwptr, applptr) = (self.hw_ptr(), self.appl_ptr());\n        let c = self.channels();\n        let bufsize = self.buffer_size();\n\n        // These formulas mostly mimic the behaviour of\n        // snd_pcm_mmap_begin (in alsa-lib/src/pcm/pcm.c).\n        let offs = applptr % bufsize;\n        let mut a = D::avail(hwptr, applptr, bufsize, self.boundary());\n        a = cmp::min(a, bufsize);\n        let b = bufsize - offs;\n        let more_data = if b < a {\n            let z = a - b;\n            a = b;\n            Some( RawSamples { ptr: self.data.mem.ptr, frames: z, channels: c })\n        } else { None };\n\n        let p = unsafe { self.data.mem.ptr.offset(offs as isize * self.data.channels as isize) };\n        (RawSamples { ptr: p, frames: a, channels: c }, more_data)\n    }\n}\n\nimpl<S> MmapPlayback<S> {\n    /// Write samples to the kernel ringbuffer.\n    pub fn write<I: Iterator<Item=S>>(&mut self, i: &mut I) -> Frames {\n        let (data, more_data) = self.data_ptr();\n        let (iter_end, samples) = unsafe { data.write_samples(i) };\n        let mut z = samples / data.channels as isize;\n        if !iter_end {\n            if let Some(data2) = more_data {\n                let (_, samples2) = unsafe {  data2.write_samples(i) };\n                z += samples2 / data2.channels as isize;\n            }\n        }\n        let z = z as Frames;\n        self.commit(z);\n        z\n    }\n}\n\nimpl<S> MmapCapture<S> {\n    /// Read samples from the kernel ringbuffer.\n    ///\n    /// When the iterator is dropped or depleted, the read samples will be committed, i e,\n    /// the kernel can then write data to the location again. So do this ASAP.\n    pub fn iter(&mut self) -> CaptureIter<'_, S> {\n        let (data, more_data) = self.data_ptr();\n        CaptureIter {\n            m: self,\n            samples: data,\n            p_offs: 0,\n            read_samples: 0,\n            next_p: more_data,\n        }\n    }\n}\n\n/// Iterator over captured samples\n#[derive(Debug)]\npub struct CaptureIter<'a, S: 'static> {\n    m: &'a MmapCapture<S>,\n    samples: RawSamples<S>,\n    p_offs: isize,\n    read_samples: isize,\n    next_p: Option<RawSamples<S>>,\n}\n\nimpl<'a, S: 'static + Copy> CaptureIter<'a, S> {\n    fn handle_max(&mut self) {\n        self.p_offs = 0;\n        if let Some(p2) = self.next_p.take() {\n            self.samples = p2;\n        } else {\n            self.m.commit((self.read_samples / self.samples.channels as isize) as Frames);\n            self.read_samples = 0;\n            self.samples.frames = 0; // Shortcut to \"None\" in case anyone calls us again\n        }\n    }\n}\n\nimpl<'a, S: 'static + Copy> Iterator for CaptureIter<'a, S> {\n    type Item = S;\n\n    #[inline]\n    fn next(&mut self) -> Option<Self::Item> {\n        if self.p_offs >= self.samples.samples() {\n            self.handle_max();\n            if self.samples.frames <= 0 { return None; }\n        }\n        let s = unsafe { ptr::read_volatile(self.samples.ptr.offset(self.p_offs)) };\n        self.p_offs += 1;\n        self.read_samples += 1;\n        Some(s)\n    }\n}\n\nimpl<'a, S: 'static> Drop for CaptureIter<'a, S> {\n    fn drop(&mut self) {\n        self.m.commit((self.read_samples / self.m.data.channels as isize) as Frames);\n    }\n}\n\n\n#[test]\n#[ignore] // Not everyone has a recording device on plughw:1. So let's ignore this test by default.\nfn record_from_plughw_rw() {\n    extern crate std;\n    use crate::pcm::*;\n    use crate::{ValueOr, Direction};\n    use ::alloc::ffi::CString;\n    let pcm = PCM::open(&*CString::new(\"plughw:1\").unwrap(), Direction::Capture, false).unwrap();\n    let ss = self::Status::new(&pcm).unwrap();\n    let c = self::Control::new(&pcm).unwrap();\n    let hwp = HwParams::any(&pcm).unwrap();\n    hwp.set_channels(2).unwrap();\n    hwp.set_rate(44100, ValueOr::Nearest).unwrap();\n    hwp.set_format(Format::s16()).unwrap();\n    hwp.set_access(Access::RWInterleaved).unwrap();\n    pcm.hw_params(&hwp).unwrap();\n\n    {\n        let swp = pcm.sw_params_current().unwrap();\n        swp.set_tstamp_mode(true).unwrap();\n        pcm.sw_params(&swp).unwrap();\n    }\n    assert_eq!(ss.state(), State::Prepared);\n    pcm.start().unwrap();\n    assert_eq!(c.appl_ptr(), 0);\n    std::println!(\"{:?}, {:?}\", ss, c);\n    let mut buf = [0i16; 512*2];\n    assert_eq!(pcm.io_i16().unwrap().readi(&mut buf).unwrap(), 512);\n    assert_eq!(c.appl_ptr(), 512);\n\n    assert_eq!(ss.state(), State::Running);\n    assert!(ss.hw_ptr() >= 512);\n    let t2 = ss.htstamp();\n    assert!(t2.tv_sec > 0 || t2.tv_nsec > 0);\n}\n\n\n#[test]\n#[ignore] // Not everyone has a record device on plughw:1. So let's ignore this test by default.\nfn record_from_plughw_mmap() {\n    extern crate std;\n    use crate::pcm::*;\n    use crate::{ValueOr, Direction};\n    use ::alloc::ffi::CString;\n    use ::alloc::vec::Vec;\n    use std::{thread, time, println};\n\n    let pcm = PCM::open(&*CString::new(\"plughw:1\").unwrap(), Direction::Capture, false).unwrap();\n    let hwp = HwParams::any(&pcm).unwrap();\n    hwp.set_channels(2).unwrap();\n    hwp.set_rate(44100, ValueOr::Nearest).unwrap();\n    hwp.set_format(Format::s16()).unwrap();\n    hwp.set_access(Access::MMapInterleaved).unwrap();\n    pcm.hw_params(&hwp).unwrap();\n\n    let ss = unsafe { SyncPtrStatus::sync_ptr(pcm_to_fd(&pcm).unwrap(), false, None, None).unwrap() };\n    assert_eq!(ss.state(), State::Prepared);\n\n    let mut m = pcm.direct_mmap_capture::<i16>().unwrap();\n\n    assert_eq!(m.status().state(), State::Prepared);\n    assert_eq!(m.appl_ptr(), 0);\n    assert_eq!(m.hw_ptr(), 0);\n\n\n    println!(\"{:?}\", m);\n\n    let now = time::Instant::now();\n    pcm.start().unwrap();\n    while m.avail() < 256 { thread::sleep(time::Duration::from_millis(1)) };\n    assert!(now.elapsed() >= time::Duration::from_millis(256 * 1000 / 44100));\n    let (ptr1, md) = m.data_ptr();\n    assert_eq!(ptr1.channels, 2);\n    assert!(ptr1.frames >= 256);\n    assert!(md.is_none());\n    println!(\"Has {:?} frames at {:?} in {:?}\", m.avail(), ptr1.ptr, now.elapsed());\n    let samples: Vec<i16> = m.iter().collect();\n    assert!(samples.len() >= ptr1.frames as usize * 2);\n    println!(\"Collected {} samples\", samples.len());\n    let (ptr2, _md) = m.data_ptr();\n    assert!(unsafe { ptr1.ptr.offset(256 * 2) } <= ptr2.ptr);\n}\n\n#[test]\n#[ignore]\nfn playback_to_plughw_mmap() {\n    extern crate std;\n    use crate::pcm::*;\n    use crate::{ValueOr, Direction};\n    use ::alloc::ffi::CString;\n\n    let pcm = PCM::open(&*CString::new(\"plughw:1\").unwrap(), Direction::Playback, false).unwrap();\n    let hwp = HwParams::any(&pcm).unwrap();\n    hwp.set_channels(2).unwrap();\n    hwp.set_rate(44100, ValueOr::Nearest).unwrap();\n    hwp.set_format(Format::s16()).unwrap();\n    hwp.set_access(Access::MMapInterleaved).unwrap();\n    pcm.hw_params(&hwp).unwrap();\n    let mut m = pcm.direct_mmap_playback::<i16>().unwrap();\n\n    assert_eq!(m.status().state(), State::Prepared);\n    assert_eq!(m.appl_ptr(), 0);\n    assert_eq!(m.hw_ptr(), 0);\n\n    std::println!(\"{:?}\", m);\n    let mut i = (0..(m.buffer_size() * 2)).map(|i|\n        (((i / 2) as f32 * 2.0 * std::f32::consts::PI / 128.0).sin() * 8192.0) as i16);\n    m.write(&mut i);\n    assert_eq!(m.appl_ptr(), m.buffer_size());\n\n    pcm.start().unwrap();\n    pcm.drain().unwrap();\n    assert_eq!(m.appl_ptr(), m.buffer_size());\n    assert!(m.hw_ptr() >= m.buffer_size());\n}\n"
  },
  {
    "path": "src/direct.rs",
    "content": "//! Functions that bypass alsa-lib and talk directly to the kernel.\n\npub mod pcm;\n\nmod ffi;\n"
  },
  {
    "path": "src/error.rs",
    "content": "#![macro_use]\n\nuse libc::{c_char, c_int, c_void, free};\nuse core::error::Error as StdError;\nuse core::ffi::CStr;\nuse core::{fmt, str};\nuse ::alloc::string::{String, ToString};\n\n/// ALSA error\n///\n/// Most ALSA functions can return a negative error code.\n/// If so, then that error code is wrapped into this `Error` struct.\n/// An Error is also returned in case ALSA returns a string that\n/// cannot be translated into Rust's UTF-8 strings.\n#[derive(Clone, PartialEq, Copy)]\npub struct Error(&'static str, c_int);\n\npub type Result<T> = ::core::result::Result<T, Error>;\n\n#[cfg(not(feature = \"std\"))]\nextern \"C\" {\n    pub(crate) static errno: c_int;\n}\n\nmacro_rules! acheck {\n    ($f: ident ( $($x: expr),* ) ) => {{\n        let r = unsafe { alsa::$f( $($x),* ) };\n        if r < 0 { Err(Error::new(stringify!($f), -r as ::libc::c_int)) }\n        else { Ok(r) }\n    }}\n}\n\npub fn from_const<'a>(func: &'static str, s: *const c_char) -> Result<&'a str> {\n    if s.is_null() {\n        return Err(invalid_str(func));\n    };\n    let cc = unsafe { CStr::from_ptr(s) };\n    str::from_utf8(cc.to_bytes()).map_err(|_| invalid_str(func))\n}\n\npub fn from_alloc(func: &'static str, s: *mut c_char) -> Result<String> {\n    if s.is_null() {\n        return Err(invalid_str(func));\n    };\n    let c = unsafe { CStr::from_ptr(s) };\n    let ss = str::from_utf8(c.to_bytes())\n        .map_err(|_| {\n            unsafe {\n                free(s as *mut c_void);\n            }\n            invalid_str(func)\n        })?\n        .to_string();\n    unsafe {\n        free(s as *mut c_void);\n    }\n    Ok(ss)\n}\n\npub fn from_code(func: &'static str, r: c_int) -> Result<c_int> {\n    if r < 0 {\n        Err(Error::new(func, r))\n    } else {\n        Ok(r)\n    }\n}\n\nimpl Error {\n    pub fn new(func: &'static str, res: c_int) -> Error {\n        Self(func, res)\n    }\n\n    pub fn last(func: &'static str) -> Error {\n        #[cfg(feature = \"std\")] {\n            Self(\n                func,\n                std::io::Error::last_os_error().raw_os_error().unwrap_or_default(),\n            )\n        }\n        #[cfg(not(feature = \"std\"))] {\n            Self(\n                func,\n                unsafe {errno},\n            )\n        }\n    }\n\n    pub fn unsupported(func: &'static str) -> Error {\n        Error(func, libc::ENOTSUP)\n    }\n\n    /// The function which failed.\n    pub fn func(&self) -> &'static str {\n        self.0\n    }\n\n    /// Underlying error\n    ///\n    /// Match this against the re-export of `nix::Error` in this crate, not against a specific version\n    /// of the nix crate. The nix crate version might be updated with minor updates of this library.\n    pub fn errno(&self) -> i32 {\n        self.1\n    }\n}\n\npub fn invalid_str(func: &'static str) -> Error {\n    Error(func, libc::EILSEQ)\n}\n\nimpl StdError for Error {\n    fn description(&self) -> &str {\n        \"ALSA error\"\n    }\n}\n\nimpl fmt::Debug for Error {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        write!(f, \"{}\", self)\n    }\n}\n\nimpl fmt::Display for Error {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        write!(\n            f,\n            \"ALSA function '{}' failed with error '{} ({})'\",\n            self.0,\n            desc(self.1),\n            self.1,\n        )\n    }\n}\n\n/// See <https://github.com/nix-rust/nix/blob/197f55b3ccbce3273bf6ce119d1a8541b5df5d66/src/errno.rs#L198>\n///\n/// Note this doesn't include the total set of possible errno variants, but they\n/// can easily be added in the future for better error messages\nfn desc(err: i32) -> &'static str {\n    match err {\n        libc::EPERM => \"Operation not permitted\",\n        libc::ENOENT => \"No such file or directory\",\n        libc::ESRCH => \"No such process\",\n        libc::EINTR => \"Interrupted system call\",\n        libc::EIO => \"I/O error\",\n        libc::ENXIO => \"No such device or address\",\n        libc::E2BIG => \"Argument list too long\",\n        libc::ENOEXEC => \"Exec format error\",\n        libc::EBADF => \"Bad file number\",\n        libc::ECHILD => \"No child processes\",\n        libc::EAGAIN => \"Try again\",\n        libc::ENOMEM => \"Out of memory\",\n        libc::EACCES => \"Permission denied\",\n        libc::EFAULT => \"Bad address\",\n        libc::ENOTBLK => \"Block device required\",\n        libc::EBUSY => \"Device or resource busy\",\n        libc::EEXIST => \"File exists\",\n        libc::EXDEV => \"Cross-device link\",\n        libc::ENODEV => \"No such device\",\n        libc::ENOTDIR => \"Not a directory\",\n        libc::EISDIR => \"Is a directory\",\n        libc::EINVAL => \"Invalid argument\",\n        libc::ENFILE => \"File table overflow\",\n        libc::EMFILE => \"Too many open files\",\n        libc::ENOTTY => \"Not a typewriter\",\n        libc::ETXTBSY => \"Text file busy\",\n        libc::EFBIG => \"File too large\",\n        libc::ENOSPC => \"No space left on device\",\n        libc::ESPIPE => \"Illegal seek\",\n        libc::EROFS => \"Read-only file system\",\n        libc::EMLINK => \"Too many links\",\n        libc::EPIPE => \"Broken pipe\",\n        libc::EDOM => \"Math argument out of domain of func\",\n        libc::ERANGE => \"Math result not representable\",\n        libc::EDEADLK => \"Resource deadlock would occur\",\n        libc::ENAMETOOLONG => \"File name too long\",\n        libc::ENOLCK => \"No record locks available\",\n        libc::ENOSYS => \"Function not implemented\",\n        libc::ENOTEMPTY => \"Directory not empty\",\n        libc::ELOOP => \"Too many symbolic links encountered\",\n        libc::ENOMSG => \"No message of desired type\",\n        libc::EIDRM => \"Identifier removed\",\n        libc::EINPROGRESS => \"Operation now in progress\",\n        libc::EALREADY => \"Operation already in progress\",\n        libc::ENOTSOCK => \"Socket operation on non-socket\",\n        libc::EDESTADDRREQ => \"Destination address required\",\n        libc::EMSGSIZE => \"Message too long\",\n        libc::EPROTOTYPE => \"Protocol wrong type for socket\",\n        libc::ENOPROTOOPT => \"Protocol not available\",\n        libc::EPROTONOSUPPORT => \"Protocol not supported\",\n        libc::ESOCKTNOSUPPORT => \"Socket type not supported\",\n        libc::EPFNOSUPPORT => \"Protocol family not supported\",\n        libc::EAFNOSUPPORT => \"Address family not supported by protocol\",\n        libc::EADDRINUSE => \"Address already in use\",\n        libc::EADDRNOTAVAIL => \"Cannot assign requested address\",\n        libc::ENETDOWN => \"Network is down\",\n        libc::ENETUNREACH => \"Network is unreachable\",\n        libc::ENETRESET => \"Network dropped connection because of reset\",\n        libc::ECONNABORTED => \"Software caused connection abort\",\n        libc::ECONNRESET => \"Connection reset by peer\",\n        libc::ENOBUFS => \"No buffer space available\",\n        libc::EISCONN => \"Transport endpoint is already connected\",\n        libc::ENOTCONN => \"Transport endpoint is not connected\",\n        libc::ESHUTDOWN => \"Cannot send after transport endpoint shutdown\",\n        libc::ETOOMANYREFS => \"Too many references: cannot splice\",\n        libc::ETIMEDOUT => \"Connection timed out\",\n        libc::ECONNREFUSED => \"Connection refused\",\n        libc::EHOSTDOWN => \"Host is down\",\n        libc::EHOSTUNREACH => \"No route to host\",\n        libc::ENOTSUP => \"Operation not supported\",\n        _ => \"Unknown errno\",\n    }\n}\n\nimpl From<Error> for fmt::Error {\n    fn from(_: Error) -> fmt::Error {\n        fmt::Error\n    }\n}\n\n#[test]\nfn broken_pcm_name() {\n    use ::alloc::ffi::CString;\n    let e = crate::PCM::open(\n        &*CString::new(\"this_PCM_does_not_exist\").unwrap(),\n        crate::Direction::Playback,\n        false,\n    )\n    .err()\n    .unwrap();\n    assert_eq!(e.func(), \"snd_pcm_open\");\n    assert_eq!(e.errno(), libc::ENOENT);\n}\n"
  },
  {
    "path": "src/hctl.rs",
    "content": "//! HCtl API - for mixer control and jack detection\n//!\n//! # Example\n//! Print all jacks and their status\n//!\n//! ```\n//! for a in ::alsa::card::Iter::new().map(|x| x.unwrap()) {\n//!     use std::ffi::CString;\n//!     use alsa::hctl::HCtl;\n//!     let h = HCtl::open(&CString::new(format!(\"hw:{}\", a.get_index())).unwrap(), false).unwrap();\n//!     h.load().unwrap();\n//!     for b in h.elem_iter() {\n//!         use alsa::ctl::ElemIface;\n//!         let id = b.get_id().unwrap();\n//!         if id.get_interface() != ElemIface::Card { continue; }\n//!         let name = id.get_name().unwrap();\n//!         if !name.ends_with(\" Jack\") { continue; }\n//!         if name.ends_with(\" Phantom Jack\") {\n//!             println!(\"{} is always present\", &name[..name.len()-13])\n//!         }\n//!         else { println!(\"{} is {}\", &name[..name.len()-5],\n//!             if b.read().unwrap().get_boolean(0).unwrap() { \"plugged in\" } else { \"unplugged\" })\n//!         }\n//!     }\n//! }\n//! ```\n\n#![allow(dead_code)]\n/* There is a \"field is never read\" warning for the ElemIter struct. We still need to hold on\n   to the HCtl pointer somehow; to guarantee that the HCtl does not go out of scope while we use\n   ElemIter, which would make the snd_hctl_elem_t pointer invalid. Hence the decision to allow dead code here.\n   I suppose there is a better solution for this but I'm not sure how.\n*/\n\n\nuse crate::{alsa, Card};\nuse core::ffi::CStr;\nuse ::alloc::ffi::CString;\nuse super::error::*;\nuse core::ptr;\nuse super::{ctl_int, poll};\nuse libc::{c_short, c_uint, c_int, pollfd};\n\n\n/// [snd_hctl_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___h_control.html) wrapper\n#[derive(Debug)]\npub struct HCtl(*mut alsa::snd_hctl_t);\n\nunsafe impl Send for HCtl {}\n\nimpl Drop for HCtl {\n    fn drop(&mut self) { unsafe { alsa::snd_hctl_close(self.0) }; }\n}\n\nimpl HCtl {\n    /// Wrapper around open that takes a &str instead of a &CStr\n    pub fn new(c: &str, nonblock: bool) -> Result<HCtl> {\n        Self::open(&CString::new(c).unwrap(), nonblock)\n    }\n\n    /// Open does not support async mode (it's not very Rustic anyway)\n    /// Note: You probably want to call `load` afterwards.\n    pub fn open(c: &CStr, nonblock: bool) -> Result<HCtl> {\n        let mut r = ptr::null_mut();\n        let flags = if nonblock { 1 } else { 0 }; // FIXME: alsa::SND_CTL_NONBLOCK does not exist in alsa-sys\n        acheck!(snd_hctl_open(&mut r, c.as_ptr(), flags))\n            .map(|_| HCtl(r))\n    }\n\n    /// Wrapper around open. You probably want to call `load` afterwards.\n    pub fn from_card(c: &Card, nonblock: bool) -> Result<HCtl> {\n        let s = ::alloc::format!(\"hw:{}\", c.get_index());\n        HCtl::new(&s, nonblock)\n    }\n\n    pub fn load(&self) -> Result<()> { acheck!(snd_hctl_load(self.0)).map(|_| ()) }\n\n    pub fn elem_iter(&self) -> ElemIter<'_> { ElemIter(self, ptr::null_mut()) }\n\n    pub fn find_elem(&self, id: &ctl_int::ElemId) -> Option<Elem<'_>> {\n        let p = unsafe { alsa::snd_hctl_find_elem(self.0, ctl_int::elem_id_ptr(id)) };\n        if p.is_null() { None } else { Some(Elem(self, p)) }\n    }\n\n    pub fn handle_events(&self) -> Result<u32> {\n        acheck!(snd_hctl_handle_events(self.0)).map(|x| x as u32)\n    }\n\n    pub fn wait(&self, timeout_ms: Option<u32>) -> Result<bool> {\n        acheck!(snd_hctl_wait(self.0, timeout_ms.map(|x| x as c_int).unwrap_or(-1))).map(|i| i == 1) }\n}\n\nimpl poll::Descriptors for HCtl {\n    fn count(&self) -> usize {\n        unsafe { alsa::snd_hctl_poll_descriptors_count(self.0) as usize }\n    }\n    fn fill(&self, p: &mut [pollfd]) -> Result<usize> {\n        let z = unsafe { alsa::snd_hctl_poll_descriptors(self.0, p.as_mut_ptr(), p.len() as c_uint) };\n        from_code(\"snd_hctl_poll_descriptors\", z).map(|_| z as usize)\n    }\n    fn revents(&self, p: &[pollfd]) -> Result<poll::Flags> {\n        let mut r = 0;\n        let z = unsafe { alsa::snd_hctl_poll_descriptors_revents(self.0, p.as_ptr() as *mut pollfd, p.len() as c_uint, &mut r) };\n        from_code(\"snd_hctl_poll_descriptors_revents\", z).map(|_| poll::Flags::from_bits_truncate(r as c_short))\n    }\n}\n\n/// Iterates over elements for a `HCtl`\n#[derive(Debug)]\npub struct ElemIter<'a>(&'a HCtl, *mut alsa::snd_hctl_elem_t);\n\nimpl<'a> Iterator for ElemIter<'a> {\n    type Item = Elem<'a>;\n    fn next(&mut self) -> Option<Elem<'a>> {\n        self.1 = if self.1.is_null() { unsafe { alsa::snd_hctl_first_elem((self.0).0) }}\n            else { unsafe { alsa::snd_hctl_elem_next(self.1) }};\n        if self.1.is_null() { None }\n        else { Some(Elem(self.0, self.1)) }\n    }\n}\n\n\n/// [snd_hctl_elem_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___h_control.html) wrapper\n#[derive(Debug)]\npub struct Elem<'a>(&'a HCtl, *mut alsa::snd_hctl_elem_t);\n\nimpl<'a> Elem<'a> {\n    pub fn get_id(&self) -> Result<ctl_int::ElemId> {\n        let v = ctl_int::elem_id_new()?;\n        unsafe { alsa::snd_hctl_elem_get_id(self.1, ctl_int::elem_id_ptr(&v)) };\n        Ok(v)\n    }\n    pub fn info(&self) -> Result<ctl_int::ElemInfo> {\n        let v = ctl_int::elem_info_new()?;\n        acheck!(snd_hctl_elem_info(self.1, ctl_int::elem_info_ptr(&v))).map(|_| v)\n    }\n    pub fn read(&self) -> Result<ctl_int::ElemValue> {\n        let i = self.info()?;\n        let v = ctl_int::elem_value_new(i.get_type(), i.get_count())?;\n        acheck!(snd_hctl_elem_read(self.1, ctl_int::elem_value_ptr(&v))).map(|_| v)\n    }\n\n    pub fn write(&self, v: &ctl_int::ElemValue) -> Result<bool> {\n        acheck!(snd_hctl_elem_write(self.1, ctl_int::elem_value_ptr(v))).map(|e| e > 0)\n    }\n}\n\n#[test]\nfn print_hctls() {\n    extern crate std;\n    for a in super::card::Iter::new().map(|x| x.unwrap()) {\n        use ::alloc::ffi::CString;\n        let h = HCtl::open(&CString::new(::alloc::format!(\"hw:{}\", a.get_index())).unwrap(), false).unwrap();\n        h.load().unwrap();\n        std::println!(\"Card {}:\", a.get_name().unwrap());\n        for b in h.elem_iter() {\n            std::println!(\"  {:?} - {:?}\", b.get_id().unwrap(), b.read().unwrap());\n        }\n    }\n}\n\n#[test]\nfn print_jacks() {\n    extern crate std;\n    for a in super::card::Iter::new().map(|x| x.unwrap()) {\n        use ::alloc::ffi::CString;\n        let h = HCtl::open(&CString::new(::alloc::format!(\"hw:{}\", a.get_index())).unwrap(), false).unwrap();\n        h.load().unwrap();\n        for b in h.elem_iter() {\n            let id = b.get_id().unwrap();\n            if id.get_interface() != super::ctl_int::ElemIface::Card { continue; }\n            let name = id.get_name().unwrap();\n            if !name.ends_with(\" Jack\") { continue; }\n            if name.ends_with(\" Phantom Jack\") {\n                std::println!(\"{} is always present\", &name[..name.len()-13])\n            }\n            else { std::println!(\"{} is {}\", &name[..name.len()-5],\n                if b.read().unwrap().get_boolean(0).unwrap() { \"plugged in\" } else { \"unplugged\" })\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/io.rs",
    "content": "use crate::alsa;\nuse super::error::*;\nuse core::{slice, ptr, fmt};\nuse core::cell::RefCell;\nuse ::alloc::rc::Rc;\nuse libc::{c_char, c_int};\n\n/// [snd_output_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___output.html) wrapper\npub struct Output(*mut alsa::snd_output_t);\n\nunsafe impl Send for Output {}\n\n#[cfg(feature = \"std\")]\nstd::thread_local! {\n    static ERROR_OUTPUT: RefCell<Option<Rc<RefCell<Output>>>> = RefCell::new(None);\n}\n\nimpl Drop for Output {\n    fn drop(&mut self) { unsafe { alsa::snd_output_close(self.0) }; }\n}\n\nimpl Output {\n\n    pub fn buffer_open() -> Result<Output> {\n        let mut q = ptr::null_mut();\n        acheck!(snd_output_buffer_open(&mut q)).map(|_| Output(q))\n    }\n\n    pub fn buffer_string<T, F: FnOnce(&[u8]) -> T>(&self, f: F) -> T {\n        let b = unsafe {\n            let mut q = ptr::null_mut();\n            let s = alsa::snd_output_buffer_string(self.0, &mut q);\n            if s == 0 { &[] } else { slice::from_raw_parts(q as *const u8, s as usize) }\n        };\n        f(b)\n    }\n\n\n    /// Installs a thread local error handler.\n    ///\n    /// Sometimes alsa-lib writes to stderr, but if you prefer, you can write it here instead.\n    /// Should you wish to empty the buffer; just call local_error_handler again and drop the old instance.\n    ///\n    /// This is not available in `no-std` environments, because we use thread_local variables.\n    #[cfg(feature = \"std\")]\n    pub fn local_error_handler() -> Result<Rc<RefCell<Output>>> {\n        let output = Output::buffer_open()?;\n        let r = Rc::new(RefCell::new(output));\n        ERROR_OUTPUT.with_borrow_mut(|e| *e = Some(r.clone()));\n        unsafe { alsa::snd_lib_error_set_local(Some(our_error_handler)); }\n        Ok(r)\n    }\n}\n\nimpl fmt::Debug for Output {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        write!(f, \"Output(\")?;\n        fmt::Display::fmt(self, f)?;\n        write!(f, \")\")\n        /* self.buffer_string(|b| f.write_str(try!(str::from_utf8(b).map_err(|_| fmt::Error)))) */\n    }\n}\n\nimpl fmt::Display for Output {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        self.buffer_string(|b| {\n            let s = ::alloc::string::String::from_utf8_lossy(b);\n            f.write_str(&*s)\n        })\n    }\n}\n\npub fn output_handle(o: &Output) -> *mut alsa::snd_output_t { o.0 }\n\n#[cfg(feature = \"std\")]\nunsafe extern \"C\" fn our_error_handler(_file: *const c_char,\n    _line: c_int,\n    func: *const c_char,\n    _err: c_int,\n    fmt: *const c_char,\n    arg: *mut alsa::__va_list_tag,\n) {\n    ERROR_OUTPUT.with_borrow(|e| {\n        let b = e.as_ref().expect(\"ERROR_OUTPUT not set\").borrow_mut();\n        alsa::snd_output_puts(b.0, func);\n        alsa::snd_output_puts(b.0, c\": \".as_ptr());\n        alsa::snd_output_vprintf(b.0, fmt, arg);\n        alsa::snd_output_putc(b.0, '\\n' as i32);\n    })\n}\n"
  },
  {
    "path": "src/lib.rs",
    "content": "//! Thin but safe wrappers for [ALSA](https://alsa-project.org).\n//!\n//! [GitHub repo](https://github.com/diwic/alsa-rs)\n//!\n//! [Crates.io](https://crates.io/crates/alsa)\n//!\n//! This ALSA API wrapper/binding is WIP - the ALSA API is huge, and new\n//! functions and structs might be added as requested.\n//!\n//! Most functions map 1-to-1 to alsa-lib functions, e g, `ctl::CardInfo::get_id()` is a wrapper around\n//! `snd_ctl_card_info_get_id` and the [alsa-lib documentation](https://www.alsa-project.org/alsa-doc/alsa-lib/)\n//! can be consulted for additional information.\n//!\n//! Enjoy!\n\n#![allow(clippy::all)]\n#![warn(clippy::correctness, clippy::suspicious, clippy::perf)]\n#![no_std]\n\n#[cfg(feature = \"std\")]\nextern crate std;\n\nextern crate alsa_sys as alsa;\nextern crate alloc;\nextern crate libc;\n#[macro_use]\nextern crate bitflags;\n\nmacro_rules! alsa_enum {\n ($(#[$attr:meta])+ $name:ident, $static_name:ident [$count:expr], $( $a:ident = $b:ident),* ,) =>\n{\n#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]\n$(#[$attr])*\npub enum $name {\n$(\n    $a = alsa::$b as isize,\n)*\n}\n\nstatic $static_name: [$name; $count] =\n  [ $( $name::$a, )* ];\n\nimpl $name {\n    /// Returns a slice of all possible values; useful for iteration\n    pub fn all() -> &'static [$name] { &$static_name[..] }\n\n    #[allow(dead_code)]\n    fn from_c_int(c: ::libc::c_int, s: &'static str) -> Result<$name> {\n        Self::all().iter().find(|&&x| c == x as ::libc::c_int).map(|&x| x)\n            .ok_or_else(|| Error::unsupported(s))\n    }\n\n    #[allow(dead_code)]\n    fn to_c_int(&self) -> ::libc::c_int {\n        return *self as ::libc::c_int;\n    }\n}\n\n}\n}\n\n/// Replaces constants ending with PLAYBACK/CAPTURE as well as\n/// INPUT/OUTPUT\n#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]\npub enum Direction {\n    Playback,\n    Capture\n}\nimpl Direction {\n    #[inline]\n    pub fn input() -> Direction { Direction::Capture }\n    #[inline]\n    pub fn output() -> Direction { Direction::Playback }\n}\n\n/// Used to restrict hw parameters. In case the submitted\n/// value is unavailable, in which direction should one search\n/// for available values?\n#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]\npub enum ValueOr {\n    /// The value set is the submitted value, or less\n    Less = -1,\n    /// The value set is the submitted value, or the nearest\n    Nearest = 0,\n    /// The value set is the submitted value, or greater\n    Greater = 1,\n}\n\n/// Rounding mode (used in some mixer related calls)\n#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]\npub enum Round {\n    /// Round down (towards negative infinity)\n    Floor = 0,\n    /// Round up (towards positive infinity)\n    Ceil = 1,\n}\n\nmod error;\npub use crate::error::{Error, Result};\n\npub mod card;\npub use crate::card::Card as Card;\n\nmod ctl_int;\npub mod ctl {\n    //! Control device API\n    pub use super::ctl_int::{Ctl, CardInfo, DeviceIter, ElemIface, ElemId, ElemList, ElemType, ElemValue, ElemInfo};\n}\n\npub use crate::ctl::Ctl as Ctl;\n\npub mod hctl;\npub use crate::hctl::HCtl as HCtl;\n\npub mod pcm;\npub use crate::pcm::PCM as PCM;\n\npub mod config;\n\npub mod rawmidi;\npub use crate::rawmidi::Rawmidi as Rawmidi;\n\npub mod device_name;\n\npub mod poll;\npub use crate::poll::Descriptors as PollDescriptors;\n\npub mod mixer;\npub use crate::mixer::Mixer as Mixer;\n\npub mod seq;\npub use crate::seq::Seq as Seq;\n\nmod io;\npub use crate::io::Output;\n\n// Reexported inside PCM module\nmod chmap;\n\npub mod direct;\n"
  },
  {
    "path": "src/mixer.rs",
    "content": "//! Mixer API - Simple Mixer API for mixer control\n//!\nuse core::ffi::CStr;\nuse ::alloc::ffi::CString;\nuse ::alloc::string::String;\nuse core::{ptr, mem, fmt, ops};\nuse libc::{c_long, c_int, c_uint, c_short, pollfd};\nuse crate::poll;\n\nuse crate::alsa;\nuse super::Round;\nuse super::error::*;\n\nconst SELEM_ID_SIZE: usize = 64;\n\n/// wraps [snd_mixer_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___mixer.html)\n#[derive(Debug)]\npub struct Mixer(*mut alsa::snd_mixer_t);\n\nunsafe impl Send for Mixer {}\n\nimpl Mixer {\n    /// Opens a mixer and attaches it to a card identified by its name (like hw:0) and loads the\n    /// mixer after registering a Selem.\n    pub fn new(name: &str, nonblock: bool) -> Result<Mixer> {\n        let mut mixer = Mixer::open(nonblock)?;\n        mixer.attach(&CString::new(name).unwrap())?;\n        Selem::register(&mut mixer)?;\n        mixer.load()?;\n        Ok(mixer)\n    }\n\n    /// Creates a Selem by looking for a specific selem by name given a mixer (of a card)\n    pub fn find_selem(&self, id: &SelemId) -> Option<Selem<'_>> {\n        let selem = unsafe { alsa::snd_mixer_find_selem(self.0, id.as_ptr()) };\n\n        if selem.is_null() { None }\n        else { Some(Selem(Elem {handle: selem, _mixer: self})) }\n    }\n\n    pub fn open(nonblock: bool) -> Result<Mixer> {\n        let mut r = ptr::null_mut();\n        let flags = if nonblock { 1 } else { 0 }; // FIXME: alsa::SND_CTL_NONBLOCK does not exist in alsa-sys\n        acheck!(snd_mixer_open(&mut r, flags)).map(|_| Mixer(r))\n    }\n\n    pub fn attach(&mut self, name: &CStr) -> Result<()> {\n        acheck!(snd_mixer_attach(self.0, name.as_ptr())).map(|_| ())\n    }\n\n    pub fn load(&mut self) -> Result<()> {\n        acheck!(snd_mixer_load(self.0)).map(|_| ())\n    }\n\n    pub fn iter(&self) -> Iter<'_> {\n        Iter {\n            last_handle: ptr::null_mut(),\n            mixer: self\n        }\n    }\n\n    pub fn handle_events(&self) -> Result<u32> {\n        acheck!(snd_mixer_handle_events(self.0)).map(|x| x as u32)\n    }\n\n    pub fn wait(&self, timeout_ms: Option<u32>) -> Result<()> {\n        acheck!(snd_mixer_wait(self.0, timeout_ms.map(|x| x as c_int).unwrap_or(-1))).map(|_| ()) }\n}\n\n/// Closes mixer and frees used resources\nimpl Drop for Mixer {\n    fn drop(&mut self) {\n        unsafe { alsa::snd_mixer_close(self.0) };\n    }\n}\n\n\nimpl poll::Descriptors for Mixer {\n    fn count(&self) -> usize {\n        unsafe { alsa::snd_mixer_poll_descriptors_count(self.0) as usize }\n    }\n    fn fill(&self, p: &mut [pollfd]) -> Result<usize> {\n        let z = unsafe { alsa::snd_mixer_poll_descriptors(self.0, p.as_mut_ptr(), p.len() as c_uint) };\n        from_code(\"snd_mixer_poll_descriptors\", z).map(|_| z as usize)\n    }\n    fn revents(&self, p: &[pollfd]) -> Result<poll::Flags> {\n        let mut r = 0;\n        let z = unsafe { alsa::snd_mixer_poll_descriptors_revents(self.0, p.as_ptr() as *mut pollfd, p.len() as c_uint, &mut r) };\n        from_code(\"snd_mixer_poll_descriptors_revents\", z).map(|_| poll::Flags::from_bits_truncate(r as c_short))\n    }\n}\n\n\n/// Wrapper for a mB (millibel) value.\n///\n/// Despite some ALSA functions named \"dB\", they actually take mB values instead.\n/// This is a wrapper type to help with those calculations. Its interior is the\n/// actual mB value.\n#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]\npub struct MilliBel(pub i64);\n\nimpl MilliBel {\n    pub fn to_db(self) -> f32 { (self.0 as f32) / 100.0 }\n    pub fn from_db(db: f32) -> Self { MilliBel((db * 100.0) as i64) }\n}\n\nimpl ops::Deref for MilliBel {\n    type Target = i64;\n    fn deref(&self) -> &i64 { &self.0 }\n}\n\nimpl ops::Add for MilliBel {\n    type Output = MilliBel;\n    fn add(self, rhs: Self) -> Self { MilliBel(self.0 + rhs.0) }\n}\n\nimpl ops::AddAssign for MilliBel {\n    fn add_assign(&mut self, rhs: Self) { self.0 += rhs.0 }\n}\n\nimpl ops::Sub for MilliBel {\n    type Output = MilliBel;\n    fn sub(self, rhs: Self) -> Self { MilliBel(self.0 - rhs.0) }\n}\n\nimpl ops::SubAssign for MilliBel {\n    fn sub_assign(&mut self, rhs: Self) { self.0 -= rhs.0 }\n}\n\n/// Wraps [snd_mixer_elem_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___mixer.html)\n#[derive(Copy, Clone, Debug)]\npub struct Elem<'a>{\n    handle: *mut alsa::snd_mixer_elem_t,\n    _mixer: &'a Mixer\n}\n\n/// Iterator for all elements of mixer\n#[derive(Copy, Clone, Debug)]\npub struct Iter<'a>{\n    last_handle: *mut alsa::snd_mixer_elem_t,\n    mixer: &'a Mixer\n}\n\nimpl<'a> Iterator for Iter<'a> {\n    type Item = Elem<'a>;\n\n    fn next(&mut self) -> Option<Elem<'a>> {\n        let elem = if self.last_handle.is_null() {\n            unsafe { alsa::snd_mixer_first_elem(self.mixer.0) }\n        } else {\n            unsafe { alsa::snd_mixer_elem_next(self.last_handle) }\n        };\n\n        if elem.is_null() {\n            None\n        } else {\n            self.last_handle = elem;\n            Some(Elem { handle: elem, _mixer: self.mixer})\n        }\n    }\n\n}\n\n/// Wrapper for [snd_mixer_selem_id_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___simple_mixer.html)\n/// No allocation (uses fixed array)\n// #[derive(Copy, Clone)]\n#[derive(Debug)]\npub struct SelemId([u8; SELEM_ID_SIZE]);\n\nimpl SelemId {\n\n    pub fn new(name: &str, index: u32) -> SelemId {\n        let mut s = SelemId::empty();\n        s.set_name(&CString::new(name).unwrap());\n        s.set_index(index);\n        s\n    }\n\n    /// Returns an empty (zeroed) SelemId. This id is not a usable id and need to be initialized\n    /// like `SelemId::new()` does\n    pub fn empty() -> SelemId {\n        assert!(unsafe { alsa::snd_mixer_selem_id_sizeof() } as usize <= SELEM_ID_SIZE);\n        // Create empty selem_id and fill from mixer\n        SelemId(unsafe { mem::zeroed() })\n    }\n\n    /// Convert SelemId into ``*mut snd_mixer_selem_id_t` that the alsa call needs.\n    /// See [snd_mixer_selem_id_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___simple_mixer.html)\n    #[inline]\n    fn as_ptr(&self) -> *mut alsa::snd_mixer_selem_id_t {\n        self.0.as_ptr() as *const _ as *mut alsa::snd_mixer_selem_id_t\n    }\n\n    pub fn get_name(&self) -> Result<&str> {\n        let c = unsafe { alsa::snd_mixer_selem_id_get_name(self.as_ptr()) };\n        from_const(\"snd_mixer_selem_id_get_name\", c)\n    }\n\n    pub fn get_index(&self) -> u32 {\n        unsafe { alsa::snd_mixer_selem_id_get_index(self.as_ptr()) }\n    }\n\n    pub fn set_name(&mut self, name: &CStr) {\n        unsafe { alsa::snd_mixer_selem_id_set_name(self.as_ptr(), name.as_ptr()) };\n    }\n\n    pub fn set_index(&mut self, index: u32) {\n        unsafe { alsa::snd_mixer_selem_id_set_index(self.as_ptr(), index) };\n    }\n\n}\n\n/// Wraps an Elem as a Selem\n// #[derive(Copy, Clone)]\n#[derive(Debug)]\npub struct Selem<'a>(Elem<'a>);\n\nimpl<'a> Selem<'a> {\n    /// Creates a Selem by wrapping `elem`.\n    pub fn new(elem: Elem<'a>) -> Option<Selem<'a>> {\n        if unsafe { alsa::snd_mixer_elem_get_type(elem.handle) } == alsa::SND_MIXER_ELEM_SIMPLE\n           { Some(Selem(elem)) } else { None }\n    }\n\n    /// TODO: This function might change to support regopt and to return the mixer class\n    pub fn register(mixer: &mut Mixer) -> Result<()> {\n        acheck!(snd_mixer_selem_register(mixer.0, ptr::null_mut(), ptr::null_mut())).map(|_| ())\n    }\n\n    pub fn get_id(&self) -> SelemId {\n        let id = SelemId::empty();\n        unsafe { alsa::snd_mixer_selem_get_id(self.handle, id.as_ptr()) };\n        id\n    }\n\n    pub fn has_capture_volume(&self) -> bool {\n        unsafe { alsa::snd_mixer_selem_has_capture_volume(self.handle) > 0 }\n    }\n\n    pub fn has_capture_switch(&self) -> bool {\n        unsafe { alsa::snd_mixer_selem_has_capture_switch(self.handle) > 0 }\n    }\n\n    pub fn has_playback_volume(&self) -> bool {\n        unsafe { alsa::snd_mixer_selem_has_playback_volume(self.handle) > 0 }\n    }\n\n    pub fn has_playback_switch(&self) -> bool {\n        unsafe { alsa::snd_mixer_selem_has_playback_switch(self.handle) > 0 }\n    }\n\n    pub fn can_capture(&self) -> bool {\n        self.has_capture_volume() || self.has_capture_switch()\n    }\n\n    pub fn can_playback(&self) -> bool {\n        self.has_playback_volume() || self.has_playback_switch()\n    }\n\n    pub fn has_volume(&self) -> bool {\n        self.has_capture_volume() || self.has_playback_volume()\n    }\n\n    /// returns range for capture volume as (min, max) values\n    pub fn get_capture_volume_range(&self) -> (i64, i64) {\n        let mut min: c_long = 0;\n        let mut max: c_long = 0;\n        unsafe { alsa::snd_mixer_selem_get_capture_volume_range(self.handle, &mut min, &mut max) };\n        (min as i64, max as i64)\n    }\n\n    /// returns (min, max) values.\n    pub fn get_capture_db_range(&self) -> (MilliBel, MilliBel) {\n        let mut min: c_long = 0;\n        let mut max: c_long = 0;\n        unsafe { alsa::snd_mixer_selem_get_capture_dB_range(self.handle, &mut min, &mut max) };\n        (MilliBel(min as i64), MilliBel(max as i64))\n    }\n\n    /// returns (min, max) values.\n    pub fn get_playback_volume_range(&self) -> (i64, i64) {\n        let mut min: c_long = 0;\n        let mut max: c_long = 0;\n        unsafe { alsa::snd_mixer_selem_get_playback_volume_range(self.handle, &mut min, &mut max) };\n        (min as i64, max as i64)\n    }\n\n    /// returns (min, max) values.\n    pub fn get_playback_db_range(&self) -> (MilliBel, MilliBel) {\n        let mut min: c_long = 0;\n        let mut max: c_long = 0;\n        unsafe { alsa::snd_mixer_selem_get_playback_dB_range(self.handle, &mut min, &mut max) };\n        (MilliBel(min as i64), MilliBel(max as i64))\n    }\n\n    pub fn is_capture_mono(&self) -> bool {\n        unsafe { alsa::snd_mixer_selem_is_capture_mono(self.handle) == 1 }\n    }\n\n    pub fn is_playback_mono(&self) -> bool {\n        unsafe { alsa::snd_mixer_selem_is_playback_mono(self.handle) == 1 }\n    }\n\n    pub fn has_capture_channel(&self, channel: SelemChannelId) -> bool {\n        unsafe { alsa::snd_mixer_selem_has_capture_channel(self.handle, channel as i32) > 0 }\n    }\n\n    pub fn has_playback_channel(&self, channel: SelemChannelId) -> bool {\n        unsafe { alsa::snd_mixer_selem_has_playback_channel(self.handle, channel as i32) > 0 }\n    }\n\n    /// Gets name from snd_mixer_selem_channel_name\n    pub fn channel_name(channel: SelemChannelId) -> Result<&'static str> {\n        let c = unsafe { alsa::snd_mixer_selem_channel_name(channel as i32) };\n        from_const(\"snd_mixer_selem_channel_name\", c)\n    }\n\n    pub fn get_playback_volume(&self, channel: SelemChannelId) -> Result<i64> {\n        let mut value: c_long = 0;\n        acheck!(snd_mixer_selem_get_playback_volume(self.handle, channel as i32, &mut value)).and_then(|_| Ok(value as i64))\n    }\n\n    /// returns volume in millibels.\n    pub fn get_playback_vol_db(&self, channel: SelemChannelId) -> Result<MilliBel> {\n        self.get_playback_volume(channel)\n            .and_then(|volume| self.ask_playback_vol_db(volume))\n    }\n\n    /// Asks alsa to convert playback volume to millibels.\n    pub fn ask_playback_vol_db(&self, volume: i64) -> Result<MilliBel> {\n        let mut decibel_value: c_long = 0;\n        acheck!(snd_mixer_selem_ask_playback_vol_dB(self.handle, volume as c_long, &mut decibel_value))\n            .map(|_| MilliBel(decibel_value as i64))\n    }\n\n    // Asks alsa to convert millibels to playback volume.\n    pub fn ask_playback_db_vol(&self, db: MilliBel, dir: Round) -> Result<i64> {\n        let mut raw_volume: c_long = 0;\n        acheck!(snd_mixer_selem_ask_playback_dB_vol(self.handle, db.0 as c_long, dir as c_int, &mut raw_volume))\n            .map(|_| raw_volume as i64)\n    }\n\n    pub fn get_capture_volume(&self, channel: SelemChannelId) -> Result<i64> {\n        let mut value: c_long = 0;\n        acheck!(snd_mixer_selem_get_capture_volume(self.handle, channel as i32, &mut value)).map(|_| value as i64)\n    }\n\n    /// returns volume in millibels.\n    pub fn get_capture_vol_db(&self, channel: SelemChannelId) -> Result<MilliBel> {\n        self.get_capture_volume(channel)\n            .and_then(|volume| self.ask_capture_vol_db(volume))\n    }\n\n    /// Asks alsa to convert capture volume to millibels\n    pub fn ask_capture_vol_db(&self, volume: i64) -> Result<MilliBel> {\n        let mut decibel_value: c_long = 0;\n        acheck!(snd_mixer_selem_ask_capture_vol_dB (self.handle, volume as c_long, &mut decibel_value))\n            .map(|_| MilliBel(decibel_value as i64))\n    }\n\n    // Asks alsa to convert millibels to capture volume.\n    pub fn ask_capture_db_vol(&self, db: MilliBel, dir: Round) -> Result<i64> {\n        let mut raw_volume: c_long = 0;\n        acheck!(snd_mixer_selem_ask_capture_dB_vol(self.handle, db.0 as c_long, dir as c_int, &mut raw_volume))\n            .map(|_| raw_volume as i64)\n    }\n\n    pub fn set_playback_volume(&self, channel: SelemChannelId, value: i64) -> Result<()> {\n        acheck!(snd_mixer_selem_set_playback_volume(self.handle, channel as i32, value as c_long)).map(|_| ())\n    }\n\n    pub fn set_playback_volume_range(&self, min: i64, max: i64) -> Result<()> {\n        acheck!(snd_mixer_selem_set_playback_volume_range(self.handle, min as c_long, max as c_long)).map(|_| ())\n    }\n\n    pub fn set_playback_volume_all(&self, value: i64) -> Result<()> {\n        acheck!(snd_mixer_selem_set_playback_volume_all(self.handle, value as c_long)).map(|_| ())\n    }\n\n    pub fn set_playback_db(&self, channel: SelemChannelId, value: MilliBel, dir: Round) -> Result<()> {\n        acheck!(snd_mixer_selem_set_playback_dB(self.handle, channel as i32, *value as c_long, dir as c_int)).map(|_| ())\n    }\n\n    pub fn set_capture_db(&self, channel: SelemChannelId, value: MilliBel, dir: Round) -> Result<()> {\n        acheck!(snd_mixer_selem_set_capture_dB(self.handle, channel as i32, *value as c_long, dir as c_int)).map(|_| ())\n    }\n\n    pub fn set_playback_db_all(&self, value: MilliBel, dir: Round) -> Result<()> {\n        acheck!(snd_mixer_selem_set_playback_dB_all(self.handle, *value as c_long, dir as c_int)).map(|_| ())\n    }\n\n    pub fn set_capture_db_all(&self, value: MilliBel, dir: Round) -> Result<()> {\n        acheck!(snd_mixer_selem_set_capture_dB_all(self.handle, *value as c_long, dir as c_int)).map(|_| ())\n    }\n\n    pub fn set_capture_volume(&self, channel: SelemChannelId, value: i64) -> Result<()> {\n        acheck!(snd_mixer_selem_set_capture_volume(self.handle, channel as i32, value as c_long)).map(|_| ())\n    }\n\n    pub fn set_capture_volume_range(&self, min: i64, max: i64) -> Result<()> {\n        acheck!(snd_mixer_selem_set_capture_volume_range(self.handle, min as c_long, max as c_long)).map(|_| ())\n    }\n\n    pub fn set_capture_volume_all(&self, value: i64) -> Result<()> {\n        acheck!(snd_mixer_selem_set_capture_volume_all(self.handle, value as c_long)).map(|_| ())\n    }\n\n    pub fn set_playback_switch(&self, channel: SelemChannelId, value: i32) -> Result<()> {\n        acheck!(snd_mixer_selem_set_playback_switch(self.handle, channel as i32, value)).map(|_| ())\n    }\n\n    pub fn set_playback_switch_all(&self, value: i32) -> Result<()> {\n        acheck!(snd_mixer_selem_set_playback_switch_all(self.handle, value)).map(|_| ())\n    }\n\n    pub fn set_capture_switch(&self, channel: SelemChannelId, value: i32) -> Result<()> {\n        acheck!(snd_mixer_selem_set_capture_switch(self.handle, channel as i32, value)).map(|_| ())\n    }\n\n    pub fn set_capture_switch_all(&self, value: i32) -> Result<()> {\n        acheck!(snd_mixer_selem_set_capture_switch_all(self.handle, value)).map(|_| ())\n    }\n\n    pub fn get_playback_switch(&self, channel: SelemChannelId) -> Result<i32> {\n        let mut value: i32 = 0;\n        acheck!(snd_mixer_selem_get_playback_switch(self.handle, channel as i32, &mut value)).map(|_| value)\n    }\n\n    pub fn get_capture_switch(&self, channel: SelemChannelId) -> Result<i32> {\n        let mut value: i32 = 0;\n        acheck!(snd_mixer_selem_get_capture_switch(self.handle, channel as i32, &mut value)).map(|_| value)\n    }\n\n    pub fn is_enumerated(&self) -> bool {\n        unsafe { alsa::snd_mixer_selem_is_enumerated(self.handle) == 1 }\n    }\n\n    pub fn is_enum_playback(&self) -> bool {\n        unsafe { alsa::snd_mixer_selem_is_enum_playback(self.handle) == 1 }\n    }\n\n    pub fn is_enum_capture(&self) -> bool {\n        unsafe { alsa::snd_mixer_selem_is_enum_capture(self.handle) == 1 }\n    }\n\n    pub fn get_enum_items(&self) -> Result<u32> {\n        acheck!(snd_mixer_selem_get_enum_items(self.handle)).map(|v| v as u32)\n    }\n\n    pub fn get_enum_item_name(&self, idx: u32) -> Result<String> {\n        let mut temp = [0 as ::libc::c_char; 128];\n        acheck!(snd_mixer_selem_get_enum_item_name(self.handle, idx, temp.len()-1, temp.as_mut_ptr()))\n            .and_then(|_| from_const(\"snd_mixer_selem_get_enum_item_name\", temp.as_ptr()))\n            .map(|v| v.into())\n    }\n\n    /// Enumerates over valid Enum values\n    pub fn iter_enum(&self) -> Result<IterEnum<'_>> {\n        Ok(IterEnum(self, 0, self.get_enum_items()?))\n    }\n\n    pub fn get_enum_item(&self, channel: SelemChannelId) -> Result<u32> {\n        let mut temp = 0;\n        acheck!(snd_mixer_selem_get_enum_item(self.handle, channel as i32, &mut temp))\n            .map(|_| temp)\n    }\n\n    pub fn set_enum_item(&self, channel: SelemChannelId, idx: u32) -> Result<()> {\n        acheck!(snd_mixer_selem_set_enum_item(self.handle, channel as i32, idx))\n            .map(|_| ())\n    }\n}\n\nimpl<'a> ops::Deref for Selem<'a> {\n    type Target = Elem<'a>;\n\n    /// returns the elem of this selem\n    fn deref(&self) -> &Elem<'a> {\n        &self.0\n    }\n}\n\n#[derive(Debug)]\npub struct IterEnum<'a>(&'a Selem<'a>, u32, u32);\n\nimpl<'a> Iterator for IterEnum<'a> {\n    type Item = Result<String>;\n    fn next(&mut self) -> Option<Self::Item> {\n        if self.1 >= self.2 { None }\n        else { self.1 += 1; Some(self.0.get_enum_item_name(self.1-1)) }\n    }\n}\n\nalsa_enum!(\n    /// Wrapper for [SND_MIXER_SCHN_*](http://www.alsa-project.org/alsa-doc/alsa-lib/group___simple_mixer.html) constants\n    SelemChannelId, ALL_SELEM_CHANNEL_ID[11],\n\n    Unknown     = SND_MIXER_SCHN_UNKNOWN,\n    FrontLeft   = SND_MIXER_SCHN_FRONT_LEFT,\n    FrontRight  = SND_MIXER_SCHN_FRONT_RIGHT,\n    RearLeft    = SND_MIXER_SCHN_REAR_LEFT,\n    RearRight   = SND_MIXER_SCHN_REAR_RIGHT,\n    FrontCenter = SND_MIXER_SCHN_FRONT_CENTER,\n    Woofer      = SND_MIXER_SCHN_WOOFER,\n    SideLeft    = SND_MIXER_SCHN_SIDE_LEFT,\n    SideRight   = SND_MIXER_SCHN_SIDE_RIGHT,\n    RearCenter  = SND_MIXER_SCHN_REAR_CENTER,\n    Last        = SND_MIXER_SCHN_LAST,\n);\n\nimpl SelemChannelId {\n    pub fn mono() -> SelemChannelId { SelemChannelId::FrontLeft }\n}\n\nimpl fmt::Display for SelemChannelId {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        write!(f, \"{}\", Selem::channel_name(*self).unwrap())\n    }\n}\n\n#[test]\nfn print_mixer_of_cards() {\n    extern crate std;\n    use std::{println, print};\n    use ::alloc::format;\n    use ::alloc::string::ToString;\n    use super::card;\n\n    for card in card::Iter::new().map(|c| c.unwrap()) {\n        println!(\"Card #{}: {} ({})\", card.get_index(), card.get_name().unwrap(), card.get_longname().unwrap());\n\n        let mixer = Mixer::new(&format!(\"hw:{}\", card.get_index()), false).unwrap();\n        for selem in mixer.iter().filter_map(|e| Selem::new(e)) {\n\n            let sid = selem.get_id();\n            println!(\"\\tMixer element {},{}:\", sid.get_name().unwrap(), sid.get_index());\n\n            if selem.has_volume() {\n                print!(\"\\t  Volume limits: \");\n                if selem.has_capture_volume() {\n                    let (vmin, vmax) = selem.get_capture_volume_range();\n                    let (mbmin, mbmax) = selem.get_capture_db_range();\n                    print!(\"Capture = {} - {}\", vmin, vmax);\n                    print!(\" ({} dB - {} dB)\", mbmin.to_db(), mbmax.to_db());\n                }\n                if selem.has_playback_volume() {\n                    let (vmin, vmax) = selem.get_playback_volume_range();\n                    let (mbmin, mbmax) = selem.get_playback_db_range();\n                    print!(\"Playback = {} - {}\", vmin, vmax);\n                    print!(\" ({} dB - {} dB)\", mbmin.to_db(), mbmax.to_db());\n                }\n                println!();\n            }\n\n            if selem.is_enumerated() {\n                print!(\"\\t  Valid values: \");\n                for v in selem.iter_enum().unwrap() { print!(\"{}, \", v.unwrap()) };\n                print!(\"\\n\\t  Current values: \");\n                for v in SelemChannelId::all().iter().filter_map(|&v| selem.get_enum_item(v).ok()) {\n                    print!(\"{}, \", selem.get_enum_item_name(v).unwrap());\n                }\n                println!();\n            }\n\n            if selem.can_capture() {\n                print!(\"\\t  Capture channels: \");\n                if selem.is_capture_mono() {\n                    print!(\"Mono\");\n                } else {\n                    for channel in SelemChannelId::all() {\n                        if selem.has_capture_channel(*channel) { print!(\"{}, \", channel) };\n                    }\n                }\n                println!();\n                print!(\"\\t  Capture volumes: \");\n                for channel in SelemChannelId::all() {\n                    if selem.has_capture_channel(*channel) { print!(\"{}: {} ({} dB), \", channel,\n                        match selem.get_capture_volume(*channel) {Ok(v) => format!(\"{}\", v), Err(_) => \"n/a\".to_string()},\n                        match selem.get_capture_vol_db(*channel) {Ok(v) => format!(\"{}\", v.to_db()), Err(_) => \"n/a\".to_string()}\n                    );}\n                }\n                println!();\n            }\n\n            if selem.can_playback() {\n                print!(\"\\t  Playback channels: \");\n                if selem.is_playback_mono() {\n                    print!(\"Mono\");\n                } else {\n                    for channel in SelemChannelId::all() {\n                        if selem.has_playback_channel(*channel) { print!(\"{}, \", channel) };\n                    }\n                }\n                println!();\n                if selem.has_playback_volume() {\n                    print!(\"\\t  Playback volumes: \");\n                    for channel in SelemChannelId::all() {\n                        if selem.has_playback_channel(*channel) { print!(\"{}: {} / {}dB, \",\n                            channel,\n                            match selem.get_playback_volume(*channel) {Ok(v) => format!(\"{}\", v), Err(_) => \"n/a\".to_string()},\n                            match selem.get_playback_vol_db(*channel) {Ok(v) => format!(\"{}\", v.to_db()), Err(_) => \"n/a\".to_string()}\n                        );}\n                    }\n                    println!();\n                }\n            }\n        }\n    }\n}\n\n#[test]\n#[ignore]\nfn get_and_set_playback_volume() {\n    extern crate std;\n\n    let mixer = Mixer::new(\"hw:1\", false).unwrap();\n    let selem = mixer.find_selem(&SelemId::new(\"Master\", 0)).unwrap();\n\n    let (rmin, rmax) = selem.get_playback_volume_range();\n    let mut channel = SelemChannelId::mono();\n    for c in SelemChannelId::all().iter() {\n        if selem.has_playback_channel(*c) { channel = *c; break }\n    }\n    std::println!(\"Testing on {} with limits {}-{} on channel {}\", selem.get_id().get_name().unwrap(), rmin, rmax, channel);\n\n    let old: i64 = selem.get_playback_volume(channel).unwrap();\n    let new: i64 = rmax / 2;\n    assert_ne!(new, old);\n\n    std::println!(\"Changing volume of {} from {} to {}\", channel, old, new);\n    selem.set_playback_volume(channel, new).unwrap();\n    let mut result: i64 = selem.get_playback_volume(channel).unwrap();\n    assert_eq!(new, result);\n\n    // return volume to old value\n    selem.set_playback_volume(channel, old).unwrap();\n    result = selem.get_playback_volume(channel).unwrap();\n    assert_eq!(old, result);\n}\n\n#[test]\n#[ignore]\nfn get_and_set_capture_volume() {\n    extern crate std;\n\n    let mixer = Mixer::new(\"hw:1\", false).unwrap();\n    let selem = mixer.find_selem(&SelemId::new(\"Capture\", 0)).unwrap();\n\n    let (rmin, rmax) = selem.get_capture_volume_range();\n    let mut channel = SelemChannelId::mono();\n    for c in SelemChannelId::all().iter() {\n        if selem.has_playback_channel(*c) { channel = *c; break }\n    }\n    std::println!(\"Testing on {} with limits {}-{} on channel {}\", selem.get_id().get_name().unwrap(), rmin, rmax, channel);\n\n    let old: i64 = selem.get_capture_volume(channel).unwrap();\n    let new: i64 = rmax / 2;\n    assert_ne!(new, old);\n\n    std::println!(\"Changing volume of {} from {} to {}\", channel, old, new);\n    selem.set_capture_volume(channel, new).unwrap();\n    let mut result: i64 = selem.get_capture_volume(channel).unwrap();\n    assert_eq!(new, result);\n\n    // return volume to old value\n    selem.set_capture_volume(channel, old).unwrap();\n    result = selem.get_capture_volume(channel).unwrap();\n    assert_eq!(old, result);\n}\n\n\n#[test]\nfn print_sizeof() {\n    extern crate std;\n    let selemid = unsafe { alsa::snd_mixer_selem_id_sizeof() } as usize;\n\n    assert!(selemid <= SELEM_ID_SIZE);\n    std::println!(\"Selem id: {}\", selemid);\n}\n"
  },
  {
    "path": "src/pcm.rs",
    "content": "//! Audio playback and capture\n//!\n//! # Example\n//! Playback a sine wave through the \"default\" device.\n//!\n//! ```\n//! use alsa::{Direction, ValueOr};\n//! use alsa::pcm::{PCM, HwParams, Format, Access, State};\n//!\n//! // Open default playback device\n//! let pcm = PCM::new(\"default\", Direction::Playback, false).unwrap();\n//!\n//! // Set hardware parameters: 44100 Hz / Mono / 16 bit\n//! let hwp = HwParams::any(&pcm).unwrap();\n//! hwp.set_channels(1).unwrap();\n//! hwp.set_rate(44100, ValueOr::Nearest).unwrap();\n//! hwp.set_format(Format::s16()).unwrap();\n//! hwp.set_access(Access::RWInterleaved).unwrap();\n//! pcm.hw_params(&hwp).unwrap();\n//! let io = pcm.io_i16().unwrap();\n//!\n//! // Make sure we don't start the stream too early\n//! let hwp = pcm.hw_params_current().unwrap();\n//! let swp = pcm.sw_params_current().unwrap();\n//! swp.set_start_threshold(hwp.get_buffer_size().unwrap()).unwrap();\n//! pcm.sw_params(&swp).unwrap();\n//!\n//! // Make a sine wave\n//! let mut buf = [0i16; 1024];\n//! for (i, a) in buf.iter_mut().enumerate() {\n//!     *a = ((i as f32 * 2.0 * ::core::f32::consts::PI / 128.0).sin() * 8192.0) as i16\n//! }\n//!\n//! // Play it back for 2 seconds.\n//! for _ in 0..2*44100/1024 {\n//!     assert_eq!(io.writei(&buf[..]).unwrap(), 1024);\n//! }\n//!\n//! // In case the buffer was larger than 2 seconds, start the stream manually.\n//! if pcm.state() != State::Running { pcm.start().unwrap() };\n//! // Wait for the stream to finish playback.\n//! pcm.drain().unwrap();\n//! ```\n\n\nuse libc::{c_int, c_uint, c_void, ssize_t, c_short, timespec, pollfd};\nuse crate::alsa;\nuse core::convert::Infallible;\nuse core::marker::PhantomData;\nuse core::mem::{size_of, zeroed};\nuse core::ffi::CStr;\nuse core::str::FromStr;\nuse ::alloc::ffi::CString;\nuse ::alloc::format;\nuse core::{fmt, ptr, cell};\nuse super::error::*;\nuse super::{Direction, Output, poll, ValueOr, chmap};\n\npub use super::chmap::{Chmap, ChmapPosition, ChmapType, ChmapsQuery};\n\n/// [snd_pcm_sframes_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html)\npub type Frames = alsa::snd_pcm_sframes_t;\n\n/// [snd_pcm_info_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html) wrapper - PCM generic info container\n#[derive(Debug)]\npub struct Info(pub(crate) *mut alsa::snd_pcm_info_t);\n\nimpl Info {\n    pub fn new() -> Result<Info> {\n        let mut p = ptr::null_mut();\n        acheck!(snd_pcm_info_malloc(&mut p)).map(|_| Info(p))\n    }\n\n    pub fn get_card(&self) -> i32 {\n        unsafe { alsa::snd_pcm_info_get_card(self.0) }\n    }\n\n    pub fn get_device(&self) -> u32 {\n        unsafe { alsa::snd_pcm_info_get_device(self.0) }\n    }\n\n    pub fn get_subdevice(&self) -> u32 {\n        unsafe { alsa::snd_pcm_info_get_subdevice(self.0) }\n    }\n\n    pub fn get_id(&self) -> Result<&str> {\n        let c = unsafe { alsa::snd_pcm_info_get_id(self.0) };\n        from_const(\"snd_pcm_info_get_id\", c)\n    }\n\n    pub fn get_name(&self) -> Result<&str> {\n        let c = unsafe { alsa::snd_pcm_info_get_name(self.0) };\n        from_const(\"snd_pcm_info_get_name\", c)\n    }\n\n    pub fn get_subdevice_name(&self) -> Result<&str> {\n        let c = unsafe { alsa::snd_pcm_info_get_subdevice_name(self.0) };\n        from_const(\"snd_pcm_info_get_subdevice_name\", c)\n    }\n\n    pub fn get_stream(&self) -> Direction {\n        match unsafe { alsa::snd_pcm_info_get_stream(self.0) } {\n            alsa::SND_PCM_STREAM_CAPTURE => Direction::Capture,\n            alsa::SND_PCM_STREAM_PLAYBACK => Direction::Playback,\n            n @ _ => panic!(\"snd_pcm_info_get_stream invalid direction '{}'\", n),\n        }\n    }\n\n    pub fn get_subdevices_count(&self) -> u32 {\n        unsafe { alsa::snd_pcm_info_get_subdevices_count(self.0) }\n    }\n\n    pub fn get_subdevices_avail(&self) -> u32 {\n        unsafe { alsa::snd_pcm_info_get_subdevices_avail(self.0) }\n    }\n\n    pub(crate) fn set_device(&mut self, device: u32) {\n        unsafe { alsa::snd_pcm_info_set_device(self.0, device) }\n    }\n\n    pub(crate) fn set_stream(&mut self, direction: Direction) {\n        let stream = match direction {\n            Direction::Capture => alsa::SND_PCM_STREAM_CAPTURE,\n            Direction::Playback => alsa::SND_PCM_STREAM_PLAYBACK,\n        };\n        unsafe { alsa::snd_pcm_info_set_stream(self.0, stream) }\n    }\n\n    pub(crate) fn set_subdevice(&mut self, subdevice: u32) {\n        unsafe { alsa::snd_pcm_info_set_subdevice(self.0, subdevice) }\n    }\n}\n\nimpl Drop for Info {\n    fn drop(&mut self) { unsafe { alsa::snd_pcm_info_free(self.0) }; }\n}\n\n/// [snd_pcm_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html) wrapper - start here for audio playback and recording\n#[derive(Debug)]\npub struct PCM(*mut alsa::snd_pcm_t, cell::Cell<bool>);\n\nunsafe impl Send for PCM {}\n\nimpl PCM {\n    fn check_has_io(&self) {\n        if self.1.get() { panic!(\"No hw_params call or additional IO objects allowed\") }\n    }\n\n    /// Wrapper around open that takes a &str instead of a &CStr\n    pub fn new(name: &str, dir: Direction, nonblock: bool) -> Result<PCM> {\n        Self::open(&CString::new(name).unwrap(), dir, nonblock)\n    }\n\n    // Does not offer async mode (it's not very Rustic anyway)\n    pub fn open(name: &CStr, dir: Direction, nonblock: bool) -> Result<PCM> {\n        let mut r = ptr::null_mut();\n        let stream = match dir {\n            Direction::Capture => alsa::SND_PCM_STREAM_CAPTURE,\n            Direction::Playback => alsa::SND_PCM_STREAM_PLAYBACK\n        };\n        let flags = if nonblock { alsa::SND_PCM_NONBLOCK } else { 0 };\n        acheck!(snd_pcm_open(&mut r, name.as_ptr(), stream, flags)).map(|_| PCM(r, cell::Cell::new(false)))\n    }\n\n    pub fn start(&self) -> Result<()> { acheck!(snd_pcm_start(self.0)).map(|_| ()) }\n    pub fn drop(&self) -> Result<()> { acheck!(snd_pcm_drop(self.0)).map(|_| ()) }\n    pub fn pause(&self, pause: bool) -> Result<()> {\n        acheck!(snd_pcm_pause(self.0, if pause { 1 } else { 0 })).map(|_| ()) }\n    pub fn resume(&self) -> Result<()> { acheck!(snd_pcm_resume(self.0)).map(|_| ()) }\n    pub fn drain(&self) -> Result<()> { acheck!(snd_pcm_drain(self.0)).map(|_| ()) }\n    pub fn prepare(&self) -> Result<()> { acheck!(snd_pcm_prepare(self.0)).map(|_| ()) }\n    pub fn reset(&self) -> Result<()> { acheck!(snd_pcm_reset(self.0)).map(|_| ()) }\n    pub fn recover(&self, err: c_int, silent: bool) -> Result<()> {\n        acheck!(snd_pcm_recover(self.0, err, if silent { 1 } else { 0 })).map(|_| ()) }\n\n    /// Wrapper around snd_pcm_recover.\n    ///\n    /// Returns Ok if the error was successfully recovered from, or the original\n    /// error if the error was unhandled.\n    pub fn try_recover(&self, err: Error, silent: bool) -> Result<()> {\n        self.recover(err.errno() as c_int, silent)\n    }\n\n    pub fn wait(&self, timeout_ms: Option<u32>) -> Result<bool> {\n        acheck!(snd_pcm_wait(self.0, timeout_ms.map(|x| x as c_int).unwrap_or(-1))).map(|i| i == 1) }\n\n    pub fn state(&self) -> State {\n        let rawstate = self.state_raw();\n        if let Ok(state) = State::from_c_int(rawstate, \"snd_pcm_state\") {\n            state\n        }\n        else {\n            panic!(\"snd_pcm_state returned an invalid value of {}\", rawstate);\n        }\n    }\n\n    /// Only used internally, and for debugging the alsa library. Please use the \"state\" function instead.\n    pub fn state_raw(&self) -> c_int { unsafe { alsa::snd_pcm_state(self.0) as c_int } }\n\n    pub fn bytes_to_frames(&self, i: isize) -> Frames { unsafe { alsa::snd_pcm_bytes_to_frames(self.0, i as ssize_t) }}\n    pub fn frames_to_bytes(&self, i: Frames) -> isize { unsafe { alsa::snd_pcm_frames_to_bytes(self.0, i) as isize }}\n\n    pub fn avail_update(&self) -> Result<Frames> { acheck!(snd_pcm_avail_update(self.0)) }\n    pub fn avail(&self) -> Result<Frames> { acheck!(snd_pcm_avail(self.0)) }\n\n    pub fn avail_delay(&self) -> Result<(Frames, Frames)> {\n        let (mut a, mut d) = (0, 0);\n        acheck!(snd_pcm_avail_delay(self.0, &mut a, &mut d)).map(|_| (a, d))\n    }\n    pub fn delay(&self) -> Result<Frames> {\n        let mut d = 0;\n        acheck!(snd_pcm_delay(self.0, &mut d)).map(|_| d)\n    }\n\n    pub fn status(&self) -> Result<Status> {\n        StatusBuilder::new().build(self)\n    }\n\n    fn verify_format(&self, f: Format) -> Result<()> {\n        let ff = self.hw_params_current().and_then(|h| h.get_format())?;\n        if ff == f { Ok(()) }\n        else {\n            // let s = format!(\"Invalid sample format ({:?}, expected {:?})\", ff, f);\n            Err(Error::unsupported(\"io_xx\"))\n        }\n    }\n\n    pub fn io_i8(&self) -> Result<IO<'_, i8>> { self.io_checked() }\n    pub fn io_u8(&self) -> Result<IO<'_, u8>> { self.io_checked() }\n    pub fn io_i16(&self) -> Result<IO<'_, i16>> { self.io_checked() }\n    pub fn io_u16(&self) -> Result<IO<'_, u16>> { self.io_checked() }\n    pub fn io_i32(&self) -> Result<IO<'_, i32>> { self.io_checked() }\n    pub fn io_u32(&self) -> Result<IO<'_, u32>> { self.io_checked() }\n    pub fn io_f32(&self) -> Result<IO<'_, f32>> { self.io_checked() }\n    pub fn io_f64(&self) -> Result<IO<'_, f64>> { self.io_checked() }\n\n    /// For the `s24` format, represented by i32\n    pub fn io_i32_s24(&self) -> Result<IO<'_, i32>> { self.verify_format(Format::s24()).map(|_| IO::new(self)) }\n    /// For the `u24` format, represented by u32\n    pub fn io_u32_u24(&self) -> Result<IO<'_, u32>> { self.verify_format(Format::u24()).map(|_| IO::new(self)) }\n\n    pub fn io_checked<S: IoFormat>(&self) -> Result<IO<'_, S>> {\n        self.verify_format(S::FORMAT).map(|_| IO::new(self))\n    }\n\n    /// Creates IO without checking `S` is valid type.\n    ///\n    /// SAFETY: Caller must guarantee `S` is valid type for this PCM stream\n    /// and that no other IO objects exist at the same time for the same stream\n    /// (or in some other way guarantee mmap safety)\n    pub unsafe fn io_unchecked<S: IoFormat>(&self) -> IO<'_, S> {\n        IO::new_unchecked(self)\n    }\n\n    #[deprecated(note = \"renamed to io_bytes\")]\n    pub fn io(&self) -> IO<'_, u8> { IO::new(self) }\n\n    /// Call this if you have an unusual format, not supported by the regular access methods\n    /// (io_i16 etc). It will succeed regardless of the sample format, but conversion to and from\n    /// bytes to your format is up to you.\n    pub fn io_bytes(&self) -> IO<'_, u8> { IO::new(self) }\n\n    /// Read buffers by talking to the kernel directly, bypassing alsa-lib.\n    pub fn direct_mmap_capture<S>(&self) -> Result<crate::direct::pcm::MmapCapture<S>> {\n        self.check_has_io();\n        crate::direct::pcm::new_mmap(self)\n    }\n\n    /// Write buffers by talking to the kernel directly, bypassing alsa-lib.\n    pub fn direct_mmap_playback<S>(&self) -> Result<crate::direct::pcm::MmapPlayback<S>> {\n        self.check_has_io();\n        crate::direct::pcm::new_mmap(self)\n    }\n\n    /// Remove PCM hardware configuration and free associated resources.\n    pub fn hw_free(&self) -> Result<()> {\n        self.check_has_io();\n        acheck!(snd_pcm_hw_free(self.0)).map(|_| ())\n    }\n\n    /// Sets hw parameters. Note: No IO object can exist for this PCM\n    /// when hw parameters are set.\n    pub fn hw_params(&self, h: &HwParams) -> Result<()> {\n        self.check_has_io();\n        acheck!(snd_pcm_hw_params(self.0, h.0)).map(|_| ())\n    }\n\n    /// Retreive current PCM hardware configuration.\n    pub fn hw_params_current(&self) -> Result<HwParams<'_>> {\n        HwParams::new(self).and_then(|h|\n            acheck!(snd_pcm_hw_params_current(self.0, h.0)).map(|_| h))\n    }\n\n    pub fn sw_params(&self, h: &SwParams) -> Result<()> {\n        acheck!(snd_pcm_sw_params(self.0, h.0)).map(|_| ())\n    }\n\n    pub fn sw_params_current(&self) -> Result<SwParams<'_>> {\n        SwParams::new(self).and_then(|h|\n            acheck!(snd_pcm_sw_params_current(self.0, h.0)).map(|_| h))\n    }\n\n    /// Wraps `snd_pcm_get_params`, returns `(buffer_size, period_size)`.\n    pub fn get_params(&self) -> Result<(u64, u64)> {\n        let mut buffer_size = 0;\n        let mut period_size = 0;\n        acheck!(snd_pcm_get_params(self.0, &mut buffer_size, &mut period_size))\n            .map(|_| (buffer_size as u64, period_size as u64))\n\n    }\n\n    pub fn info(&self) -> Result<Info> {\n        Info::new().and_then(|info|\n            acheck!(snd_pcm_info(self.0, info.0)).map(|_| info ))\n    }\n\n    pub fn dump(&self, o: &mut Output) -> Result<()> {\n        acheck!(snd_pcm_dump(self.0, super::io::output_handle(o))).map(|_| ())\n    }\n\n    pub fn dump_hw_setup(&self, o: &mut Output) -> Result<()> {\n        acheck!(snd_pcm_dump_hw_setup(self.0, super::io::output_handle(o))).map(|_| ())\n    }\n\n    pub fn dump_sw_setup(&self, o: &mut Output) -> Result<()> {\n        acheck!(snd_pcm_dump_sw_setup(self.0, super::io::output_handle(o))).map(|_| ())\n    }\n\n    pub fn query_chmaps(&self) -> ChmapsQuery {\n        chmap::chmaps_query_new(unsafe { alsa::snd_pcm_query_chmaps(self.0) })\n    }\n\n    pub fn set_chmap(&self, c: &Chmap) -> Result<()> {\n        acheck!(snd_pcm_set_chmap(self.0, chmap::chmap_handle(c))).map(|_| ())\n    }\n\n    pub fn get_chmap(&self) -> Result<Chmap> {\n        let p = unsafe { alsa::snd_pcm_get_chmap(self.0) };\n        if p.is_null() { Err(Error::unsupported(\"snd_pcm_get_chmap\")) }\n        else { Ok(chmap::chmap_new(p)) }\n    }\n\n    pub fn link(&self, other: &PCM) -> Result<()> {\n        acheck!(snd_pcm_link(self.0, other.0)).map(|_| ())\n    }\n\n    pub fn unlink(&self) -> Result<()> {\n        acheck!(snd_pcm_unlink(self.0)).map(|_| ())\n    }\n}\n\nimpl Drop for PCM {\n    fn drop(&mut self) { unsafe { alsa::snd_pcm_close(self.0) }; }\n}\n\n\nimpl poll::Descriptors for PCM {\n    fn count(&self) -> usize {\n        unsafe { alsa::snd_pcm_poll_descriptors_count(self.0) as usize }\n    }\n    fn fill(&self, p: &mut [pollfd]) -> Result<usize> {\n        let z = unsafe { alsa::snd_pcm_poll_descriptors(self.0, p.as_mut_ptr(), p.len() as c_uint) };\n        from_code(\"snd_pcm_poll_descriptors\", z).map(|_| z as usize)\n    }\n    fn revents(&self, p: &[pollfd]) -> Result<poll::Flags> {\n        let mut r = 0;\n        let z = unsafe { alsa::snd_pcm_poll_descriptors_revents(self.0, p.as_ptr() as *mut pollfd, p.len() as c_uint, &mut r) };\n        from_code(\"snd_pcm_poll_descriptors_revents\", z).map(|_| poll::Flags::from_bits_truncate(r as c_short))\n    }\n}\n\n/// Sample format dependent struct for reading from and writing data to a `PCM`.\n/// Also implements `std::io::Read` and `std::io::Write`.\n///\n/// Note: Only one IO object is allowed in scope at a time (for mmap safety).\n#[derive(Debug)]\npub struct IO<'a, S: Copy>(&'a PCM, PhantomData<S>);\n\nimpl<'a, S: Copy> Drop for IO<'a, S> {\n    fn drop(&mut self) { (self.0).1.set(false) }\n}\n\nimpl<'a, S: Copy> IO<'a, S> {\n\n    fn new(a: &'a PCM) -> IO<'a, S> {\n        a.check_has_io();\n        a.1.set(true);\n        IO(a, PhantomData)\n    }\n\n    unsafe fn new_unchecked(a: &'a PCM) -> IO<'a, S> {\n        a.1.set(true);\n        IO(a, PhantomData)\n    }\n\n    fn to_frames(&self, b: usize) -> alsa::snd_pcm_uframes_t {\n        // TODO: Do we need to check for overflow here?\n        self.0.bytes_to_frames((b * size_of::<S>()) as isize) as alsa::snd_pcm_uframes_t\n    }\n\n    fn from_frames(&self, b: alsa::snd_pcm_uframes_t) -> usize {\n        // TODO: Do we need to check for overflow here?\n        (self.0.frames_to_bytes(b as Frames) as usize) / size_of::<S>()\n    }\n\n    /// On success, returns number of *frames* written.\n    /// (Multiply with number of channels to get number of items in buf successfully written.)\n    pub fn writei(&self, buf: &[S]) -> Result<usize> {\n        acheck!(snd_pcm_writei((self.0).0, buf.as_ptr() as *const c_void, self.to_frames(buf.len()))).map(|r| r as usize)\n    }\n\n    /// On success, returns number of *frames* read.\n    /// (Multiply with number of channels to get number of items in buf successfully read.)\n    pub fn readi(&self, buf: &mut [S]) -> Result<usize> {\n        acheck!(snd_pcm_readi((self.0).0, buf.as_mut_ptr() as *mut c_void, self.to_frames(buf.len()))).map(|r| r as usize)\n    }\n\n    /// Write non-interleaved frames to pcm. On success, returns number of frames written.\n    ///\n    /// # Safety\n    ///\n    /// Caller must ensure that the length of `bufs` is at least the number of\n    /// channels, and that each element of bufs is a valid pointer to an array\n    /// of at least `frames` length.\n    pub unsafe fn writen(&self, bufs: &[*const S], frames: usize) -> Result<usize> {\n        let frames = frames as alsa::snd_pcm_uframes_t;\n        acheck!(snd_pcm_writen((self.0).0, bufs.as_ptr() as *mut *mut c_void, frames)).map(|r| r as usize)\n    }\n\n    /// Read non-interleaved frames to pcm. On success, returns number of frames read.\n    ///\n    /// # Safety\n    ///\n    /// Caller must ensure that the length of `bufs` is at least the number of\n    /// channels, and that each element of bufs is a valid pointer to an array\n    /// of at least `frames` length.\n    pub unsafe fn readn(&self, bufs: &mut [*mut S], frames: usize) -> Result<usize> {\n        let frames = frames as alsa::snd_pcm_uframes_t;\n        acheck!(snd_pcm_readn((self.0).0, bufs.as_mut_ptr() as *mut *mut c_void, frames)).map(|r| r as usize)\n    }\n\n    /// Wrapper around snd_pcm_mmap_begin and snd_pcm_mmap_commit.\n    ///\n    /// You can read/write into the sound card's buffer during the call to the closure.\n    /// According to alsa-lib docs, you should call avail_update before calling this function.\n    ///\n    /// All calculations are in *frames*, i e, the closure should return number of frames processed.\n    /// Also, there might not be as many frames to read/write as requested, and there can even be\n    /// an empty buffer supplied to the closure.\n    ///\n    /// Note: This function works only with interleaved access mode.\n    pub fn mmap<F: FnOnce(&mut [S]) -> usize>(&self, frames: usize, func: F) -> Result<usize> {\n        let mut f = frames as alsa::snd_pcm_uframes_t;\n        let mut offs: alsa::snd_pcm_uframes_t = 0;\n        let mut areas = ptr::null();\n        acheck!(snd_pcm_mmap_begin((self.0).0, &mut areas, &mut offs, &mut f))?;\n\n        let (first, step) = unsafe { ((*areas).first, (*areas).step) };\n        if first != 0 || step as isize != self.0.frames_to_bytes(1) * 8 {\n            unsafe { alsa::snd_pcm_mmap_commit((self.0).0, offs, 0) };\n            // let s = format!(\"Can only mmap a single interleaved buffer (first = {:?}, step = {:?})\", first, step);\n            return Err(Error::unsupported(\"snd_pcm_mmap_begin\"));\n        }\n\n        let buf = unsafe {\n            let p = ((*areas).addr as *mut S).add(self.from_frames(offs));\n            ::core::slice::from_raw_parts_mut(p, self.from_frames(f))\n        };\n        let fres = func(buf);\n        debug_assert!(fres <= f as usize);\n        acheck!(snd_pcm_mmap_commit((self.0).0, offs, fres as alsa::snd_pcm_uframes_t)).map(|r| r as usize)\n    }\n}\n\n#[cfg(feature = \"std\")]\nimpl<'a, S: Copy> std::io::Read for IO<'a, S> {\n    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {\n        let size = self.0.bytes_to_frames(buf.len() as isize) as alsa::snd_pcm_uframes_t; // TODO: Do we need to check for overflow here?\n        let r = unsafe { alsa::snd_pcm_readi((self.0).0, buf.as_mut_ptr() as *mut c_void, size) };\n        if r < 0 { Err(std::io::Error::from_raw_os_error(-r as i32)) }\n        else { Ok(self.0.frames_to_bytes(r) as usize) }\n    }\n}\n\n#[cfg(feature = \"std\")]\nimpl<'a, S: Copy> std::io::Write for IO<'a, S> {\n    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {\n        let size = self.0.bytes_to_frames(buf.len() as isize) as alsa::snd_pcm_uframes_t; // TODO: Do we need to check for overflow here?\n        let r = unsafe { alsa::snd_pcm_writei((self.0).0, buf.as_ptr() as *const c_void, size) };\n        if r < 0 { Err(std::io::Error::from_raw_os_error(r as i32)) }\n        else { Ok(self.0.frames_to_bytes(r) as usize) }\n    }\n    fn flush(&mut self) -> std::io::Result<()> { Ok(()) }\n}\n\n\nalsa_enum!(\n    /// [SND_PCM_STATE_xxx](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html) constants\n    State, ALL_STATES[9],\n\n    Open = SND_PCM_STATE_OPEN,\n    Setup = SND_PCM_STATE_SETUP,\n    Prepared = SND_PCM_STATE_PREPARED,\n    Running = SND_PCM_STATE_RUNNING,\n    XRun = SND_PCM_STATE_XRUN,\n    Draining = SND_PCM_STATE_DRAINING,\n    Paused = SND_PCM_STATE_PAUSED,\n    Suspended = SND_PCM_STATE_SUSPENDED,\n    Disconnected = SND_PCM_STATE_DISCONNECTED,\n);\n\nalsa_enum!(\n    #[non_exhaustive]\n    /// [SND_PCM_FORMAT_xxx](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html) constants\n    Format, ALL_FORMATS[52],\n\n    Unknown = SND_PCM_FORMAT_UNKNOWN,\n    S8 = SND_PCM_FORMAT_S8,\n    U8 = SND_PCM_FORMAT_U8,\n    S16LE = SND_PCM_FORMAT_S16_LE,\n    S16BE = SND_PCM_FORMAT_S16_BE,\n    U16LE = SND_PCM_FORMAT_U16_LE,\n    U16BE = SND_PCM_FORMAT_U16_BE,\n    S24LE = SND_PCM_FORMAT_S24_LE,\n    S24BE = SND_PCM_FORMAT_S24_BE,\n    U24LE = SND_PCM_FORMAT_U24_LE,\n    U24BE = SND_PCM_FORMAT_U24_BE,\n    S32LE = SND_PCM_FORMAT_S32_LE,\n    S32BE = SND_PCM_FORMAT_S32_BE,\n    U32LE = SND_PCM_FORMAT_U32_LE,\n    U32BE = SND_PCM_FORMAT_U32_BE,\n    FloatLE = SND_PCM_FORMAT_FLOAT_LE,\n    FloatBE = SND_PCM_FORMAT_FLOAT_BE,\n    Float64LE = SND_PCM_FORMAT_FLOAT64_LE,\n    Float64BE = SND_PCM_FORMAT_FLOAT64_BE,\n    IEC958SubframeLE = SND_PCM_FORMAT_IEC958_SUBFRAME_LE,\n    IEC958SubframeBE = SND_PCM_FORMAT_IEC958_SUBFRAME_BE,\n    MuLaw = SND_PCM_FORMAT_MU_LAW,\n    ALaw = SND_PCM_FORMAT_A_LAW,\n    ImaAdPCM = SND_PCM_FORMAT_IMA_ADPCM,\n    MPEG = SND_PCM_FORMAT_MPEG,\n    GSM = SND_PCM_FORMAT_GSM,\n    S20LE = SND_PCM_FORMAT_S20_LE,\n    S20BE = SND_PCM_FORMAT_S20_BE,\n    U20LE = SND_PCM_FORMAT_U20_LE,\n    U20BE = SND_PCM_FORMAT_U20_BE,\n    Special = SND_PCM_FORMAT_SPECIAL,\n    S243LE = SND_PCM_FORMAT_S24_3LE,\n    S243BE = SND_PCM_FORMAT_S24_3BE,\n    U243LE = SND_PCM_FORMAT_U24_3LE,\n    U243BE = SND_PCM_FORMAT_U24_3BE,\n    S203LE = SND_PCM_FORMAT_S20_3LE,\n    S203BE = SND_PCM_FORMAT_S20_3BE,\n    U203LE = SND_PCM_FORMAT_U20_3LE,\n    U203BE = SND_PCM_FORMAT_U20_3BE,\n    S183LE = SND_PCM_FORMAT_S18_3LE,\n    S183BE = SND_PCM_FORMAT_S18_3BE,\n    U183LE = SND_PCM_FORMAT_U18_3LE,\n    U183BE = SND_PCM_FORMAT_U18_3BE,\n    G72324 = SND_PCM_FORMAT_G723_24,\n    G723241B = SND_PCM_FORMAT_G723_24_1B,\n    G72340 = SND_PCM_FORMAT_G723_40,\n    G723401B = SND_PCM_FORMAT_G723_40_1B,\n    DSDU8 = SND_PCM_FORMAT_DSD_U8,\n    DSDU16LE = SND_PCM_FORMAT_DSD_U16_LE,\n    DSDU32LE = SND_PCM_FORMAT_DSD_U32_LE,\n    DSDU16BE = SND_PCM_FORMAT_DSD_U16_BE,\n    DSDU32BE = SND_PCM_FORMAT_DSD_U32_BE,\n);\n\nimpl fmt::Display for Format {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        use Format::*;\n        match *self {\n            S8 => write!(f, \"S8\"),\n            U8 => write!(f, \"U8\"),\n            S16LE => write!(f, \"S16_LE\"),\n            S16BE => write!(f, \"S16_BE\"),\n            U16LE => write!(f, \"U16_LE\"),\n            U16BE => write!(f, \"U16_BE\"),\n            S24LE => write!(f, \"S24_LE\"),\n            S24BE => write!(f, \"S24_BE\"),\n            U24LE => write!(f, \"U24_LE\"),\n            U24BE => write!(f, \"U24_BE\"),\n            S32LE => write!(f, \"S32_LE\"),\n            S32BE => write!(f, \"S32_BE\"),\n            U32LE => write!(f, \"U32_LE\"),\n            U32BE => write!(f, \"U32_BE\"),\n            FloatLE => write!(f, \"FLOAT_LE\"),\n            FloatBE => write!(f, \"FLOAT_BE\"),\n            Float64LE => write!(f, \"FLOAT64_LE\"),\n            Float64BE => write!(f, \"FLOAT64_BE\"),\n            IEC958SubframeLE => write!(f, \"IEC958_SUBFRAME_LE\"),\n            IEC958SubframeBE => write!(f, \"IEC958_SUBFRAME_BE\"),\n            MuLaw => write!(f, \"MU_LAW\"),\n            ALaw => write!(f, \"A_LAW\"),\n            ImaAdPCM => write!(f, \"IMA_ADPCM\"),\n            MPEG => write!(f, \"MPEG\"),\n            GSM => write!(f, \"GSM\"),\n            S20LE => write!(f, \"S20_LE\"),\n            S20BE => write!(f, \"S20_BE\"),\n            U20LE => write!(f, \"U20_LE\"),\n            U20BE => write!(f, \"U20_BE\"),\n            Special => write!(f, \"SPECIAL\"),\n            S243LE => write!(f, \"S24_3LE\"),\n            S243BE => write!(f, \"S24_3BE\"),\n            U243LE => write!(f, \"U24_3LE\"),\n            U243BE => write!(f, \"U24_3BE\"),\n            S203LE => write!(f, \"S20_3LE\"),\n            S203BE => write!(f, \"S20_3BE\"),\n            U203LE => write!(f, \"U20_3LE\"),\n            U203BE => write!(f, \"U20_3BE\"),\n            S183LE => write!(f, \"S18_3LE\"),\n            S183BE => write!(f, \"S18_3BE\"),\n            U183LE => write!(f, \"U18_3LE\"),\n            U183BE => write!(f, \"U18_3BE\"),\n            G72324 => write!(f, \"G723_24\"),\n            G723241B => write!(f, \"G723_24_1B\"),\n            G72340 => write!(f, \"G723_40\"),\n            G723401B => write!(f, \"G723_40_1B\"),\n            DSDU8 => write!(f, \"DSD_U8\"),\n            DSDU16LE => write!(f, \"DSD_U16_LE\"),\n            DSDU32LE => write!(f, \"DSD_U32_LE\"),\n            DSDU16BE => write!(f, \"DSD_U16_BE\"),\n            DSDU32BE => write!(f, \"DSD_U32_BE\"),\n            _ => write!(f, \"UNKNOWN\"),\n        }\n    }\n}\n\nimpl FromStr for Format {\n    type Err = Infallible;\n\n    fn from_str(s: &str) -> core::result::Result<Self, Self::Err> {\n        use Format::*;\n        Ok(match s.to_ascii_uppercase().as_str() {\n            \"S8\" => S8,\n            \"U8\" => U8,\n            \"S16_LE\" => S16LE,\n            \"S16_BE\" => S16BE,\n            \"U16_LE\" => U16LE,\n            \"U16_BE\" => U16BE,\n            \"S24_LE\" => S24LE,\n            \"S24_BE\" => S24BE,\n            \"U24_LE\" => U24LE,\n            \"U24_BE\" => U24BE,\n            \"S32_LE\" => S32LE,\n            \"S32_BE\" => S32BE,\n            \"U32_LE\" => U32LE,\n            \"U32_BE\" => U32BE,\n            \"FLOAT_LE\" => FloatLE,\n            \"FLOAT_BE\" => FloatBE,\n            \"FLOAT64_LE\" => Float64LE,\n            \"FLOAT64_BE\" => Float64BE,\n            \"IEC958_SUBFRAME_LE\" => IEC958SubframeLE,\n            \"IEC958_SUBFRAME_BE\" => IEC958SubframeBE,\n            \"MU_LAW\" => MuLaw,\n            \"A_LAW\" => ALaw,\n            \"IMA_ADPCM\" => ImaAdPCM,\n            \"MPEG\" => MPEG,\n            \"GSM\" => GSM,\n            \"S20_LE\" => S20LE,\n            \"S20_BE\" => S20BE,\n            \"U20_LE\" => U20LE,\n            \"U20_BE\" => U20BE,\n            \"SPECIAL\" => Special,\n            \"S24_3LE\" => S243LE,\n            \"S24_3BE\" => S243BE,\n            \"U24_3LE\" => U243LE,\n            \"U24_3BE\" => U243BE,\n            \"S20_3LE\" => S203LE,\n            \"S20_3BE\" => S203BE,\n            \"U20_3LE\" => U203LE,\n            \"U20_3BE\" => U203BE,\n            \"S18_3LE\" => S183LE,\n            \"S18_3BE\" => S183BE,\n            \"U18_3LE\" => U183LE,\n            \"U18_3BE\" => U183BE,\n            \"G723_24\" => G72324,\n            \"G723_24_1B\" => G723241B,\n            \"G723_40\" => G72340,\n            \"G723_40_1B\" => G723401B,\n            \"DSD_U8\" => DSDU8,\n            \"DSD_U16_LE\" => DSDU16LE,\n            \"DSD_U32_LE\" => DSDU32LE,\n            \"DSD_U16_BE\" => DSDU16BE,\n            \"DSD_U32_BE\" => DSDU32BE,\n            _ => Unknown,\n        })\n    }\n}\n\nimpl Format {\n    pub const fn s16() -> Format { <i16 as IoFormat>::FORMAT }\n    pub const fn u16() -> Format { <u16 as IoFormat>::FORMAT }\n    pub const fn s32() -> Format { <i32 as IoFormat>::FORMAT }\n    pub const fn u32() -> Format { <u32 as IoFormat>::FORMAT }\n    pub const fn float() -> Format { <f32 as IoFormat>::FORMAT }\n    pub const fn float64() -> Format { <f64 as IoFormat>::FORMAT }\n\n    #[cfg(target_endian = \"little\")] pub const fn s24() -> Format { Format::S24LE }\n    #[cfg(target_endian = \"big\")] pub const fn s24() -> Format { Format::S24BE }\n\n    #[cfg(target_endian = \"little\")] pub const fn s24_3() -> Format { Format::S243LE }\n    #[cfg(target_endian = \"big\")] pub const fn s24_3() -> Format { Format::S243BE }\n\n    #[cfg(target_endian = \"little\")] pub const fn u24() -> Format { Format::U24LE }\n    #[cfg(target_endian = \"big\")] pub const fn u24() -> Format { Format::U24BE }\n\n    #[cfg(target_endian = \"little\")] pub const fn u24_3() -> Format { Format::U243LE }\n    #[cfg(target_endian = \"big\")] pub const fn u24_3() -> Format { Format::U243BE }\n\n    #[cfg(target_endian = \"little\")] pub const fn s20() -> Format { Format::S20LE }\n    #[cfg(target_endian = \"big\")] pub const fn s20() -> Format { Format::S20BE }\n\n    #[cfg(target_endian = \"little\")] pub const fn s20_3() -> Format { Format::S203LE }\n    #[cfg(target_endian = \"big\")] pub const fn s20_3() -> Format { Format::S203BE }\n\n    #[cfg(target_endian = \"little\")] pub const fn u20() -> Format { Format::U20LE }\n    #[cfg(target_endian = \"big\")] pub const fn u20() -> Format { Format::U20BE }\n\n    #[cfg(target_endian = \"little\")] pub const fn u20_3() -> Format { Format::U203LE }\n    #[cfg(target_endian = \"big\")] pub const fn u20_3() -> Format { Format::U203BE }\n\n    #[cfg(target_endian = \"little\")] pub const fn s18_3() -> Format { Format::S183LE }\n    #[cfg(target_endian = \"big\")] pub const fn s18_3() -> Format { Format::S183BE }\n\n    #[cfg(target_endian = \"little\")] pub const fn u18_3() -> Format { Format::U183LE }\n    #[cfg(target_endian = \"big\")] pub const fn u18_3() -> Format { Format::U183BE }\n\n    #[cfg(target_endian = \"little\")] pub const fn dsd_u16() -> Format { Format::DSDU16LE }\n    #[cfg(target_endian = \"big\")] pub const fn dsd_u16() -> Format { Format::DSDU16BE }\n\n    #[cfg(target_endian = \"little\")] pub const fn dsd_u32() -> Format { Format::DSDU32LE }\n    #[cfg(target_endian = \"big\")] pub const fn dsd_u32() -> Format { Format::DSDU32BE }\n\n    #[cfg(target_endian = \"little\")] pub const fn iec958_subframe() -> Format { Format::IEC958SubframeLE }\n    #[cfg(target_endian = \"big\")] pub const fn iec958_subframe() -> Format { Format::IEC958SubframeBE }\n\n    pub fn physical_width(&self) -> Result<i32> {\n        acheck!(snd_pcm_format_physical_width(self.to_c_int()))\n    }\n\n    pub fn width(&self) -> Result<i32> {\n        acheck!(snd_pcm_format_width(self.to_c_int()))\n    }\n\n    pub fn silence_16(&self) -> u16 {\n        unsafe { alsa::snd_pcm_format_silence_16(self.to_c_int()) }\n    }\n\n    pub fn little_endian(&self) -> Result<bool> {\n        acheck!(snd_pcm_format_little_endian(self.to_c_int())).map(|v| v != 0)\n    }\n}\n\n\npub trait IoFormat: Copy {\n    const FORMAT: Format;\n}\n\nimpl IoFormat for i8 { const FORMAT: Format = Format::S8; }\nimpl IoFormat for u8 { const FORMAT: Format = Format::U8; }\n\nimpl IoFormat for i16 {\n    #[cfg(target_endian = \"little\")]\n    const FORMAT: Format = Format::S16LE;\n    #[cfg(target_endian = \"big\")]\n    const FORMAT: Format = Format::S16BE;\n}\nimpl IoFormat for u16 {\n    #[cfg(target_endian = \"little\")]\n    const FORMAT: Format = Format::U16LE;\n    #[cfg(target_endian = \"big\")]\n    const FORMAT: Format = Format::U16BE;\n}\nimpl IoFormat for i32 {\n    #[cfg(target_endian = \"little\")]\n    const FORMAT: Format = Format::S32LE;\n    #[cfg(target_endian = \"big\")]\n    const FORMAT: Format = Format::S32BE;\n}\nimpl IoFormat for u32 {\n    #[cfg(target_endian = \"little\")]\n    const FORMAT: Format = Format::U32LE;\n    #[cfg(target_endian = \"big\")]\n    const FORMAT: Format = Format::U32BE;\n}\nimpl IoFormat for f32 {\n    #[cfg(target_endian = \"little\")]\n    const FORMAT: Format = Format::FloatLE;\n    #[cfg(target_endian = \"big\")]\n    const FORMAT: Format = Format::FloatBE;\n}\nimpl IoFormat for f64 {\n    #[cfg(target_endian = \"little\")]\n    const FORMAT: Format = Format::Float64LE;\n    #[cfg(target_endian = \"big\")]\n    const FORMAT: Format = Format::Float64BE;\n}\n\n\nalsa_enum!(\n    /// [SND_PCM_ACCESS_xxx](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html) constants\n    Access, ALL_ACCESSES[5],\n\n    MMapInterleaved = SND_PCM_ACCESS_MMAP_INTERLEAVED,\n    MMapNonInterleaved = SND_PCM_ACCESS_MMAP_NONINTERLEAVED,\n    MMapComplex = SND_PCM_ACCESS_MMAP_COMPLEX,\n    RWInterleaved = SND_PCM_ACCESS_RW_INTERLEAVED,\n    RWNonInterleaved = SND_PCM_ACCESS_RW_NONINTERLEAVED,\n);\n\nalsa_enum!(\n    /// [SND_PCM_TSTAMP_TYPE_xxx](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html) constants\n    TstampType, ALL_TSTAMP_TYPES[3],\n\n    Gettimeofday = SND_PCM_TSTAMP_TYPE_GETTIMEOFDAY,\n    Monotonic = SND_PCM_TSTAMP_TYPE_MONOTONIC,\n    MonotonicRaw = SND_PCM_TSTAMP_TYPE_MONOTONIC_RAW,\n);\n\n/// [snd_pcm_hw_params_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m___h_w___params.html) wrapper\npub struct HwParams<'a>(*mut alsa::snd_pcm_hw_params_t, &'a PCM);\n\nimpl<'a> Drop for HwParams<'a> {\n    fn drop(&mut self) { unsafe { alsa::snd_pcm_hw_params_free(self.0) }; }\n}\n\nimpl<'a> HwParams<'a> {\n    fn new(a: &'a PCM) -> Result<HwParams<'a>> {\n        let mut p = ptr::null_mut();\n        acheck!(snd_pcm_hw_params_malloc(&mut p)).map(|_| HwParams(p, a))\n    }\n\n    pub fn any(a: &'a PCM) -> Result<HwParams<'a>> { HwParams::new(a).and_then(|p|\n        acheck!(snd_pcm_hw_params_any(a.0, p.0)).map(|_| p)\n    )}\n\n    pub fn get_rate_resample(&self) -> Result<bool> {\n        let mut v = 0;\n        acheck!(snd_pcm_hw_params_get_rate_resample((self.1).0, self.0, &mut v)).map(|_| v != 0)\n    }\n\n    pub fn set_rate_resample(&self, resample: bool) -> Result<()> {\n        acheck!(snd_pcm_hw_params_set_rate_resample((self.1).0, self.0, if resample {1} else {0})).map(|_| ())\n    }\n\n    pub fn set_channels_near(&self, v: u32) -> Result<u32> {\n        let mut r = v as c_uint;\n        acheck!(snd_pcm_hw_params_set_channels_near((self.1).0, self.0, &mut r)).map(|_| r)\n    }\n\n    pub fn set_channels(&self, v: u32) -> Result<()> {\n        acheck!(snd_pcm_hw_params_set_channels((self.1).0, self.0, v as c_uint)).map(|_| ())\n    }\n\n    pub fn get_channels(&self) -> Result<u32> {\n        let mut v = 0;\n        acheck!(snd_pcm_hw_params_get_channels(self.0, &mut v)).map(|_| v as u32)\n    }\n\n    pub fn get_channels_max(&self) -> Result<u32> {\n        let mut v = 0;\n        acheck!(snd_pcm_hw_params_get_channels_max(self.0, &mut v)).map(|_| v as u32)\n    }\n\n    pub fn get_channels_min(&self) -> Result<u32> {\n        let mut v = 0;\n        acheck!(snd_pcm_hw_params_get_channels_min(self.0, &mut v)).map(|_| v as u32)\n    }\n\n    pub fn test_channels(&self, v: u32) -> Result<()> {\n        acheck!(snd_pcm_hw_params_test_channels((self.1).0, self.0, v as c_uint)).map(|_| ())\n    }\n\n    pub fn set_rate_near(&self, v: u32, dir: ValueOr) -> Result<u32> {\n        let mut d = dir as c_int;\n        let mut r = v as c_uint;\n        acheck!(snd_pcm_hw_params_set_rate_near((self.1).0, self.0, &mut r, &mut d)).map(|_| r)\n    }\n\n    pub fn set_rate(&self, v: u32, dir: ValueOr) -> Result<()> {\n        acheck!(snd_pcm_hw_params_set_rate((self.1).0, self.0, v as c_uint, dir as c_int)).map(|_| ())\n    }\n\n    pub fn get_rate(&self) -> Result<u32> {\n        let (mut v, mut d) = (0,0);\n        acheck!(snd_pcm_hw_params_get_rate(self.0, &mut v, &mut d)).map(|_| v as u32)\n    }\n\n    pub fn get_rate_max(&self) -> Result<u32> {\n        let mut v = 0;\n        // Note on the null ptr: if this ptr is not null, then the value behind it is replaced with\n        // -1 if the suprenum is not in the set (i.e. it's an open range), 0 otherwise. This could\n        // be returned along with the value, but it's safe to pass a null ptr in, in which case the\n        // pointer is not dereferenced.\n        acheck!(snd_pcm_hw_params_get_rate_max(self.0, &mut v, ptr::null_mut())).map(|_| v as u32)\n    }\n\n    pub fn get_rate_min(&self) -> Result<u32> {\n        let mut v = 0;\n        // Note on the null ptr: see get_rate_max but read +1 and infinum instead of -1 and\n        // suprenum.\n        acheck!(snd_pcm_hw_params_get_rate_min(self.0, &mut v, ptr::null_mut())).map(|_| v as u32)\n    }\n\n    pub fn test_rate(&self, rate: u32) -> Result<()> {\n        acheck!(snd_pcm_hw_params_test_rate((self.1).0, self.0, rate as c_uint, 0)).map(|_| ())\n    }\n\n    pub fn set_format(&self, v: Format) -> Result<()> {\n        acheck!(snd_pcm_hw_params_set_format((self.1).0, self.0, v as c_int)).map(|_| ())\n    }\n\n    pub fn get_format(&self) -> Result<Format> {\n        let mut v = 0;\n        acheck!(snd_pcm_hw_params_get_format(self.0, &mut v))\n            .and_then(|_| Format::from_c_int(v, \"snd_pcm_hw_params_get_format\"))\n    }\n\n    pub fn test_format(&self, v: Format) -> Result<()> {\n        acheck!(snd_pcm_hw_params_test_format((self.1).0, self.0, v as c_int)).map(|_| ())\n    }\n\n    pub fn test_access(&self, v: Access) -> Result<()> {\n        acheck!(snd_pcm_hw_params_test_access((self.1).0, self.0, v as c_uint)).map(|_| ())\n    }\n\n    pub fn set_access(&self, v: Access) -> Result<()> {\n        acheck!(snd_pcm_hw_params_set_access((self.1).0, self.0, v as c_uint)).map(|_| ())\n    }\n\n    pub fn get_access(&self) -> Result<Access> {\n        let mut v = 0;\n        acheck!(snd_pcm_hw_params_get_access(self.0, &mut v))\n            .and_then(|_| Access::from_c_int(v as c_int, \"snd_pcm_hw_params_get_access\"))\n    }\n\n    pub fn set_period_size_near(&self, v: Frames, dir: ValueOr) -> Result<Frames> {\n        let mut d = dir as c_int;\n        let mut r = v as alsa::snd_pcm_uframes_t;\n        acheck!(snd_pcm_hw_params_set_period_size_near((self.1).0, self.0, &mut r, &mut d)).map(|_| r as Frames)\n    }\n\n    pub fn set_period_size(&self, v: Frames, dir: ValueOr) -> Result<()> {\n        acheck!(snd_pcm_hw_params_set_period_size((self.1).0, self.0, v as alsa::snd_pcm_uframes_t, dir as c_int)).map(|_| ())\n    }\n\n    pub fn set_period_time_near(&self, v: u32, dir: ValueOr) -> Result<u32> {\n        let mut d = dir as c_int;\n        let mut r = v as c_uint;\n        acheck!(snd_pcm_hw_params_set_period_time_near((self.1).0, self.0, &mut r, &mut d)).map(|_| r as u32)\n    }\n\n    pub fn set_period_size_min(&self, v: Frames, dir: ValueOr) -> Result<Frames> {\n        let mut d = dir as c_int;\n        let mut r = v as alsa::snd_pcm_uframes_t;\n        acheck!(snd_pcm_hw_params_set_period_size_min((self.1).0, self.0, &mut r, &mut d)).map(|_| r as Frames)\n    }\n\n    pub fn set_period_size_max(&self, v: Frames, dir: ValueOr) -> Result<Frames> {\n        let mut d = dir as c_int;\n        let mut r = v as alsa::snd_pcm_uframes_t;\n        acheck!(snd_pcm_hw_params_set_period_size_max((self.1).0, self.0, &mut r, &mut d)).map(|_| r as Frames)\n    }\n\n    pub fn set_period_time(&self, v: u32, dir: ValueOr) -> Result<()> {\n        acheck!(snd_pcm_hw_params_set_period_time((self.1).0, self.0, v as c_uint, dir as c_int)).map(|_| ())\n    }\n\n    pub fn set_period_time_min(&self, v: u32, dir: ValueOr) -> Result<u32> {\n        let mut d = dir as c_int;\n        let mut r = v as c_uint;\n        acheck!(snd_pcm_hw_params_set_period_time_min((self.1).0, self.0, &mut r, &mut d)).map(|_| r as u32)\n    }\n\n    pub fn set_period_time_max(&self, v: u32, dir: ValueOr) -> Result<u32> {\n        let mut d = dir as c_int;\n        let mut r = v as c_uint;\n        acheck!(snd_pcm_hw_params_set_period_time_max((self.1).0, self.0, &mut r, &mut d)).map(|_| r as u32)\n    }\n\n    pub fn get_period_time(&self) -> Result<u32> {\n        let (mut v, mut d) = (0,0);\n        acheck!(snd_pcm_hw_params_get_period_time(self.0, &mut v, &mut d)).map(|_| v as u32)\n    }\n\n    pub fn get_period_time_min(&self) -> Result<u32> {\n        let (mut v, mut d) = (0,0);\n        acheck!(snd_pcm_hw_params_get_period_time_min(self.0, &mut v, &mut d)).map(|_| v as u32)\n    }\n\n    pub fn get_period_time_max(&self) -> Result<u32> {\n        let (mut v, mut d) = (0,0);\n        acheck!(snd_pcm_hw_params_get_period_time_max(self.0, &mut v, &mut d)).map(|_| v as u32)\n    }\n\n    pub fn get_period_size(&self) -> Result<Frames> {\n        let (mut v, mut d) = (0,0);\n        acheck!(snd_pcm_hw_params_get_period_size(self.0, &mut v, &mut d)).map(|_| v as Frames)\n    }\n\n    pub fn get_period_size_min(&self) -> Result<Frames> {\n        let (mut v, mut d) = (0,0);\n        acheck!(snd_pcm_hw_params_get_period_size_min(self.0, &mut v, &mut d)).map(|_| v as Frames)\n    }\n\n    pub fn get_period_size_max(&self) -> Result<Frames> {\n        let (mut v, mut d) = (0,0);\n        acheck!(snd_pcm_hw_params_get_period_size_max(self.0, &mut v, &mut d)).map(|_| v as Frames)\n    }\n\n    pub fn set_periods_near(&self, v: u32, dir: ValueOr) -> Result<u32> {\n        let mut d = dir as c_int;\n        let mut r = v as c_uint;\n        acheck!(snd_pcm_hw_params_set_periods_near((self.1).0, self.0, &mut r, &mut d)).map(|_| r as u32)\n    }\n\n    pub fn set_periods(&self, v: u32, dir: ValueOr) -> Result<()> {\n        acheck!(snd_pcm_hw_params_set_periods((self.1).0, self.0, v as c_uint, dir as c_int)).map(|_| ())\n    }\n\n    pub fn set_periods_min(&self, v: u32, dir: ValueOr) -> Result<u32> {\n        let mut d = dir as c_int;\n        let mut r = v as c_uint;\n        acheck!(snd_pcm_hw_params_set_periods_min((self.1).0, self.0, &mut r, &mut d)).map(|_| r as u32)\n    }\n\n    pub fn set_periods_max(&self, v: u32, dir: ValueOr) -> Result<u32> {\n        let mut d = dir as c_int;\n        let mut r = v as c_uint;\n        acheck!(snd_pcm_hw_params_set_periods_max((self.1).0, self.0, &mut r, &mut d)).map(|_| r as u32)\n    }\n\n    pub fn get_periods(&self) -> Result<u32> {\n        let (mut v, mut d) = (0,0);\n        acheck!(snd_pcm_hw_params_get_periods(self.0, &mut v, &mut d)).map(|_| v as u32)\n    }\n\n    pub fn get_periods_min(&self) -> Result<u32> {\n        let (mut v, mut d) = (0,0);\n        acheck!(snd_pcm_hw_params_get_periods_min(self.0, &mut v, &mut d)).map(|_| v as u32)\n    }\n\n    pub fn get_periods_max(&self) -> Result<u32> {\n        let (mut v, mut d) = (0,0);\n        acheck!(snd_pcm_hw_params_get_periods_max(self.0, &mut v, &mut d)).map(|_| v as u32)\n    }\n\n    pub fn set_buffer_size_near(&self, v: Frames) -> Result<Frames> {\n        let mut r = v as alsa::snd_pcm_uframes_t;\n        acheck!(snd_pcm_hw_params_set_buffer_size_near((self.1).0, self.0, &mut r)).map(|_| r as Frames)\n    }\n\n    pub fn set_buffer_size_max(&self, v: Frames) -> Result<Frames> {\n        let mut r = v as alsa::snd_pcm_uframes_t;\n        acheck!(snd_pcm_hw_params_set_buffer_size_max((self.1).0, self.0, &mut r)).map(|_| r as Frames)\n    }\n\n    pub fn set_buffer_size_min(&self, v: Frames) -> Result<Frames> {\n        let mut r = v as alsa::snd_pcm_uframes_t;\n        acheck!(snd_pcm_hw_params_set_buffer_size_min((self.1).0, self.0, &mut r)).map(|_| r as Frames)\n    }\n\n    pub fn set_buffer_size(&self, v: Frames) -> Result<()> {\n        acheck!(snd_pcm_hw_params_set_buffer_size((self.1).0, self.0, v as alsa::snd_pcm_uframes_t)).map(|_| ())\n    }\n\n    pub fn set_buffer_time_near(&self, v: u32, dir: ValueOr) -> Result<u32> {\n        let mut d = dir as c_int;\n        let mut r = v as c_uint;\n        acheck!(snd_pcm_hw_params_set_buffer_time_near((self.1).0, self.0, &mut r, &mut d)).map(|_| r as u32)\n    }\n\n    pub fn set_buffer_time(&self, v: u32, dir: ValueOr) -> Result<()> {\n        acheck!(snd_pcm_hw_params_set_buffer_time((self.1).0, self.0, v as c_uint, dir as c_int)).map(|_| ())\n    }\n\n    pub fn set_buffer_time_min(&self, v: u32, dir: ValueOr) -> Result<u32> {\n        let mut d = dir as c_int;\n        let mut r = v as c_uint;\n        acheck!(snd_pcm_hw_params_set_buffer_time_min((self.1).0, self.0, &mut r, &mut d)).map(|_| r as u32)\n    }\n\n    pub fn set_buffer_time_max(&self, v: u32, dir: ValueOr) -> Result<u32> {\n        let mut d = dir as c_int;\n        let mut r = v as c_uint;\n        acheck!(snd_pcm_hw_params_set_buffer_time_max((self.1).0, self.0, &mut r, &mut d)).map(|_| r as u32)\n    }\n\n    pub fn get_buffer_size(&self) -> Result<Frames> {\n        let mut v = 0;\n        acheck!(snd_pcm_hw_params_get_buffer_size(self.0, &mut v)).map(|_| v as Frames)\n    }\n\n    pub fn get_buffer_size_min(&self) -> Result<Frames> {\n        let mut v = 0;\n        acheck!(snd_pcm_hw_params_get_buffer_size_min(self.0, &mut v)).map(|_| v as Frames)\n    }\n\n    pub fn get_buffer_size_max(&self) -> Result<Frames> {\n        let mut v = 0;\n        acheck!(snd_pcm_hw_params_get_buffer_size_max(self.0, &mut v)).map(|_| v as Frames)\n    }\n\n    pub fn get_buffer_time(&self) -> Result<u32> {\n        let (mut v, mut d) = (0,0);\n        acheck!(snd_pcm_hw_params_get_buffer_time(self.0, &mut v, &mut d)).map(|_| v as u32)\n    }\n\n    pub fn get_buffer_time_min(&self) -> Result<u32> {\n        let (mut v, mut d) = (0,0);\n        acheck!(snd_pcm_hw_params_get_buffer_time_min(self.0, &mut v, &mut d)).map(|_| v as u32)\n    }\n\n    pub fn get_buffer_time_max(&self) -> Result<u32> {\n        let (mut v, mut d) = (0,0);\n        acheck!(snd_pcm_hw_params_get_buffer_time_max(self.0, &mut v, &mut d)).map(|_| v as u32)\n    }\n\n    /// Returns true if the alsa stream can be paused, false if not.\n    ///\n    /// This function should only be called when the configuration space contains a single\n    /// configuration. Call `PCM::hw_params` to choose a single configuration from the\n    /// configuration space.\n    pub fn can_pause(&self) -> bool {\n        unsafe { alsa::snd_pcm_hw_params_can_pause(self.0) != 0 }\n    }\n\n    /// Returns true if the alsa stream can be resumed, false if not.\n    ///\n    /// This function should only be called when the configuration space contains a single\n    /// configuration. Call `PCM::hw_params` to choose a single configuration from the\n    /// configuration space.\n    pub fn can_resume(&self) -> bool {\n        unsafe { alsa::snd_pcm_hw_params_can_resume(self.0) != 0 }\n    }\n\n    /// Returns true if the alsa stream supports the provided `AudioTstampType`, false if not.\n    ///\n    /// This function should only be called when the configuration space contains a single\n    /// configuration. Call `PCM::hw_params` to choose a single configuration from the\n    /// configuration space.\n    pub fn supports_audio_ts_type(&self, type_: AudioTstampType) -> bool {\n        unsafe { alsa::snd_pcm_hw_params_supports_audio_ts_type(self.0, type_ as libc::c_int) != 0 }\n    }\n\n    pub fn dump(&self, o: &mut Output) -> Result<()> {\n        acheck!(snd_pcm_hw_params_dump(self.0, super::io::output_handle(o))).map(|_| ())\n    }\n\n    pub fn copy_from(&mut self, other: &HwParams<'a>) {\n        self.1 = other.1;\n        unsafe { alsa::snd_pcm_hw_params_copy(self.0, other.0) };\n    }\n}\n\nimpl<'a> Clone for HwParams<'a> {\n    fn clone(&self) -> HwParams<'a> {\n        let mut r = HwParams::new(self.1).unwrap();\n        r.copy_from(self);\n        r\n    }\n}\n\nimpl<'a> fmt::Debug for HwParams<'a> {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        f.debug_struct(\"HwParams\")\n            .field(\"channels\", &self.get_channels())\n            .field(\"rate\", &format!(\"{:?} Hz\", self.get_rate()))\n            .field(\"format\", &self.get_format())\n            .field(\"access\", &self.get_access())\n            .field(\"period_size\", &format!(\"{:?} frames\", self.get_period_size()))\n            .field(\"buffer_size\", &format!(\"{:?} frames\", self.get_buffer_size()))\n            .finish()\n    }\n}\n\n/// [snd_pcm_sw_params_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m___s_w___params.html) wrapper\npub struct SwParams<'a>(*mut alsa::snd_pcm_sw_params_t, &'a PCM);\n\nimpl<'a> Drop for SwParams<'a> {\n    fn drop(&mut self) { unsafe { alsa::snd_pcm_sw_params_free(self.0) }; }\n}\n\nimpl<'a> SwParams<'a> {\n\n    fn new(a: &'a PCM) -> Result<SwParams<'a>> {\n        let mut p = ptr::null_mut();\n        acheck!(snd_pcm_sw_params_malloc(&mut p)).map(|_| SwParams(p, a))\n    }\n\n    pub fn set_avail_min(&self, v: Frames) -> Result<()> {\n        acheck!(snd_pcm_sw_params_set_avail_min((self.1).0, self.0, v as alsa::snd_pcm_uframes_t)).map(|_| ())\n    }\n\n    pub fn get_avail_min(&self) -> Result<Frames> {\n        let mut v = 0;\n        acheck!(snd_pcm_sw_params_get_avail_min(self.0, &mut v)).map(|_| v as Frames)\n    }\n\n    pub fn get_boundary(&self) -> Result<Frames> {\n        let mut v = 0;\n        acheck!(snd_pcm_sw_params_get_boundary(self.0, &mut v)).map(|_| v as Frames)\n    }\n\n    pub fn set_start_threshold(&self, v: Frames) -> Result<()> {\n        acheck!(snd_pcm_sw_params_set_start_threshold((self.1).0, self.0, v as alsa::snd_pcm_uframes_t)).map(|_| ())\n    }\n\n    pub fn get_start_threshold(&self) -> Result<Frames> {\n        let mut v = 0;\n        acheck!(snd_pcm_sw_params_get_start_threshold(self.0, &mut v)).map(|_| v as Frames)\n    }\n\n    pub fn set_stop_threshold(&self, v: Frames) -> Result<()> {\n        acheck!(snd_pcm_sw_params_set_stop_threshold((self.1).0, self.0, v as alsa::snd_pcm_uframes_t)).map(|_| ())\n    }\n\n    pub fn get_stop_threshold(&self) -> Result<Frames> {\n        let mut v = 0;\n        acheck!(snd_pcm_sw_params_get_stop_threshold(self.0, &mut v)).map(|_| v as Frames)\n    }\n\n    pub fn set_tstamp_mode(&self, v: bool) -> Result<()> {\n        let z = if v { alsa::SND_PCM_TSTAMP_ENABLE } else { alsa::SND_PCM_TSTAMP_NONE };\n        acheck!(snd_pcm_sw_params_set_tstamp_mode((self.1).0, self.0, z)).map(|_| ())\n    }\n\n    pub fn get_tstamp_mode(&self) -> Result<bool> {\n        let mut v = 0;\n        acheck!(snd_pcm_sw_params_get_tstamp_mode(self.0, &mut v)).map(|_| v != 0)\n    }\n\n    pub fn set_tstamp_type(&self, v: TstampType) -> Result<()> {\n        acheck!(snd_pcm_sw_params_set_tstamp_type((self.1).0, self.0, v as u32)).map(|_| ())\n    }\n\n    pub fn get_tstamp_type(&self) -> Result<TstampType> {\n        let mut v = 0;\n        acheck!(snd_pcm_sw_params_get_tstamp_type(self.0, &mut v))?;\n        TstampType::from_c_int(v as c_int, \"snd_pcm_sw_params_get_tstamp_type\")\n    }\n\n    pub fn dump(&self, o: &mut Output) -> Result<()> {\n        acheck!(snd_pcm_sw_params_dump(self.0, super::io::output_handle(o))).map(|_| ())\n    }\n}\n\nimpl<'a> fmt::Debug for SwParams<'a> {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        write!(f,\n           \"SwParams(avail_min: {:?} frames, start_threshold: {:?} frames, stop_threshold: {:?} frames)\",\n           self.get_avail_min(), self.get_start_threshold(), self.get_stop_threshold())\n    }\n}\n\nconst STATUS_SIZE: usize = 152;\n\n/// [snd_pcm_status_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m___status.html) wrapper\n#[derive(Debug)]\npub struct Status([u64; (STATUS_SIZE+7)/8]);\n\nimpl Status {\n    fn new() -> Status {\n        assert!(unsafe { alsa::snd_pcm_status_sizeof() } as usize <= STATUS_SIZE);\n        Status([0; (STATUS_SIZE+7)/8])\n    }\n\n    fn ptr(&self) -> *mut alsa::snd_pcm_status_t { self.0.as_ptr() as *const _ as *mut alsa::snd_pcm_status_t }\n\n    pub fn get_htstamp(&self) -> timespec {\n        let mut h: timespec = unsafe { zeroed() };\n        unsafe { alsa::snd_pcm_status_get_htstamp(self.ptr(), &mut h) };\n        h\n    }\n\n    pub fn get_trigger_htstamp(&self) -> timespec {\n        let mut h: timespec = unsafe { zeroed() };\n        unsafe { alsa::snd_pcm_status_get_trigger_htstamp(self.ptr(), &mut h) };\n        h\n    }\n\n    pub fn get_audio_htstamp(&self) -> timespec {\n        let mut h: timespec = unsafe { zeroed() };\n        unsafe { alsa::snd_pcm_status_get_audio_htstamp(self.ptr(), &mut h) };\n        h\n    }\n\n    pub fn get_state(&self) -> State { State::from_c_int(\n        unsafe { alsa::snd_pcm_status_get_state(self.ptr()) } as c_int, \"snd_pcm_status_get_state\").unwrap() }\n\n    pub fn get_avail(&self) -> Frames { unsafe { alsa::snd_pcm_status_get_avail(self.ptr()) as Frames }}\n    pub fn get_delay(&self) -> Frames { unsafe { alsa::snd_pcm_status_get_delay(self.ptr()) }}\n    pub fn get_avail_max(&self) -> Frames { unsafe { alsa::snd_pcm_status_get_avail_max(self.ptr()) as Frames }}\n    pub fn get_overrange(&self) -> Frames { unsafe { alsa::snd_pcm_status_get_overrange(self.ptr()) as Frames }}\n\n    pub fn dump(&self, o: &mut Output) -> Result<()> {\n        acheck!(snd_pcm_status_dump(self.ptr(), super::io::output_handle(o))).map(|_| ())\n    }\n}\n\n/// Builder for [`Status`].\n///\n/// Allows setting the audio timestamp configuration before retrieving the\n/// status from the stream.\n#[derive(Debug)]\npub struct StatusBuilder(Status);\n\nimpl StatusBuilder {\n    pub fn new() -> Self {\n        StatusBuilder(Status::new())\n    }\n\n    pub fn audio_htstamp_config(\n        self,\n        type_requested: AudioTstampType,\n        report_delay: bool,\n    ) -> Self {\n        let mut cfg: alsa::snd_pcm_audio_tstamp_config_t = unsafe { core::mem::zeroed() };\n        cfg.set_type_requested(type_requested as _);\n        cfg.set_report_delay(report_delay as _);\n        unsafe { alsa::snd_pcm_status_set_audio_htstamp_config(self.0.ptr(), &mut cfg) };\n        self\n    }\n\n    pub fn build(mut self, pcm: &PCM) -> Result<Status> {\n        let p = self.0.0.as_mut_ptr() as *mut alsa::snd_pcm_status_t;\n        acheck!(snd_pcm_status(pcm.0, p)).map(|_| self.0)\n    }\n}\n\nalsa_enum!(\n    #[non_exhaustive]\n    /// [SND_PCM_AUDIO_TSTAMP_TYPE_xxx](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html) constants\n    AudioTstampType, ALL_AUDIO_TSTAMP_TYPES[6],\n\n    Compat = SND_PCM_AUDIO_TSTAMP_TYPE_COMPAT,\n    Default = SND_PCM_AUDIO_TSTAMP_TYPE_DEFAULT,\n    Link = SND_PCM_AUDIO_TSTAMP_TYPE_LINK,\n    LinkAbsolute = SND_PCM_AUDIO_TSTAMP_TYPE_LINK_ABSOLUTE,\n    LinkEstimated = SND_PCM_AUDIO_TSTAMP_TYPE_LINK_ESTIMATED,\n    LinkSynchronized = SND_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED,\n);\n\n#[test]\nfn info_from_default() {\n    extern crate std;\n    use ::alloc::ffi::CString;\n    let pcm = PCM::open(&*CString::new(\"default\").unwrap(), Direction::Capture, false).unwrap();\n    let info = pcm.info().unwrap();\n    std::println!(\"PCM Info:\");\n    std::println!(\"\\tCard: {}\", info.get_card());\n    std::println!(\"\\tDevice: {}\", info.get_device());\n    std::println!(\"\\tSubdevice: {}\", info.get_subdevice());\n    std::println!(\"\\tId: {}\", info.get_id().unwrap());\n    std::println!(\"\\tName: {}\", info.get_name().unwrap());\n    std::println!(\"\\tSubdevice Name: {}\", info.get_subdevice_name().unwrap());\n}\n\n#[test]\nfn drop() {\n    use ::alloc::ffi::CString;\n    let pcm = PCM::open(&*CString::new(\"default\").unwrap(), Direction::Capture, false).unwrap();\n    // Verify that this does not cause a naming conflict (issue #14)\n    let _ = pcm.drop();\n}\n\n#[test]\nfn record_from_default() {\n    use ::alloc::ffi::CString;\n    let pcm = PCM::open(&*CString::new(\"default\").unwrap(), Direction::Capture, false).unwrap();\n    let hwp = HwParams::any(&pcm).unwrap();\n    hwp.set_channels(2).unwrap();\n    hwp.set_rate(44100, ValueOr::Nearest).unwrap();\n    hwp.set_format(Format::s16()).unwrap();\n    hwp.set_access(Access::RWInterleaved).unwrap();\n    pcm.hw_params(&hwp).unwrap();\n    pcm.start().unwrap();\n    let mut buf = [0i16; 1024];\n    assert_eq!(pcm.io_i16().unwrap().readi(&mut buf).unwrap(), 1024/2);\n}\n\n#[test]\nfn open_s24() {\n    let pcm = PCM::open(c\"default\", Direction::Playback, false).unwrap();\n    let hwp = HwParams::any(&pcm).unwrap();\n    hwp.set_channels(1).unwrap();\n    hwp.set_rate(44100, ValueOr::Nearest).unwrap();\n    hwp.set_format(Format::s24()).unwrap();\n    hwp.set_access(Access::RWInterleaved).unwrap();\n    pcm.hw_params(&hwp).unwrap();\n    assert_eq!(Format::s24().physical_width(), Ok(32));\n    let _io = pcm.io_i32_s24().unwrap();\n}\n\n#[test]\nfn playback_to_default() {\n    extern crate std;\n\n    use ::alloc::ffi::CString;\n    let pcm = PCM::open(&*CString::new(\"default\").unwrap(), Direction::Playback, false).unwrap();\n    let hwp = HwParams::any(&pcm).unwrap();\n    hwp.set_channels(1).unwrap();\n    hwp.set_rate(44100, ValueOr::Nearest).unwrap();\n    hwp.set_format(Format::s16()).unwrap();\n    hwp.set_access(Access::RWInterleaved).unwrap();\n    pcm.hw_params(&hwp).unwrap();\n\n    let hwp = pcm.hw_params_current().unwrap();\n    let swp = pcm.sw_params_current().unwrap();\n    swp.set_start_threshold(hwp.get_buffer_size().unwrap()).unwrap();\n    pcm.sw_params(&swp).unwrap();\n\n    std::println!(\"PCM status: {:?}, {:?}\", pcm.state(), pcm.hw_params_current().unwrap());\n    let mut outp = Output::buffer_open().unwrap();\n    pcm.dump(&mut outp).unwrap();\n    std::println!(\"== PCM dump ==\\n{}\", outp);\n\n    let mut buf = [0i16; 1024];\n    for (i, a) in buf.iter_mut().enumerate() {\n        *a = ((i as f32 * 2.0 * ::core::f32::consts::PI / 128.0).sin() * 8192.0) as i16\n    }\n    let io = pcm.io_i16().unwrap();\n    for _ in 0..2*44100/1024 { // 2 seconds of playback\n        std::println!(\"PCM state: {:?}\", pcm.state());\n        assert_eq!(io.writei(&buf[..]).unwrap(), 1024);\n    }\n    if pcm.state() != State::Running { pcm.start().unwrap() };\n\n    let mut outp2 = Output::buffer_open().unwrap();\n    pcm.status().unwrap().dump(&mut outp2).unwrap();\n    std::println!(\"== PCM status dump ==\\n{}\", outp2);\n\n    pcm.drain().unwrap();\n}\n\n#[test]\nfn print_sizeof() {\n    extern crate std;\n\n    let s = unsafe { alsa::snd_pcm_status_sizeof() } as usize;\n    std::println!(\"Status size: {}\", s);\n\n    assert!(s <= STATUS_SIZE);\n}\n\n#[test]\nfn format_display_from_str() {\n    use ::alloc::string::ToString;\n\n    for format in ALL_FORMATS {\n        assert_eq!(format, format.to_string().parse().unwrap());\n    }\n}\n"
  },
  {
    "path": "src/poll.rs",
    "content": "//! Tiny poll ffi\n//!\n//! A tiny wrapper around libc's poll system call.\n\nuse libc;\nuse super::error::*;\npub use libc::pollfd;\nuse ::alloc::vec;\nuse ::alloc::vec::Vec;\n\nbitflags! {\n    #[repr(transparent)]\n    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]\n    pub struct Flags: ::libc::c_short {\n        const IN  = ::libc::POLLIN;\n        const PRI = ::libc::POLLPRI;\n        const OUT = ::libc::POLLOUT;\n        const ERR = ::libc::POLLERR;\n        const HUP = ::libc::POLLHUP;\n        const NVAL = ::libc::POLLNVAL;\n    }\n}\n\npub trait Descriptors {\n    fn count(&self) -> usize;\n    fn fill(&self, _: &mut [pollfd]) -> Result<usize>;\n    fn revents(&self, _: &[pollfd]) -> Result<Flags>;\n\n    /// Wrapper around count and fill - returns an array of pollfds\n    fn get(&self) -> Result<Vec<pollfd>> {\n        let mut v = vec![pollfd { fd: 0, events: 0, revents: 0 }; self.count()];\n        if self.fill(&mut v)? != v.len() { Err(Error::unsupported(\"did not fill the poll descriptors array\")) }\n        else { Ok(v) }\n    }\n}\n\nimpl Descriptors for pollfd {\n    fn count(&self) -> usize { 1 }\n    fn fill(&self, a: &mut [pollfd]) -> Result<usize> { a[0] = *self; Ok(1) }\n    fn revents(&self, a: &[pollfd]) -> Result<Flags> { Ok(Flags::from_bits_truncate(a[0].revents)) }\n}\n\n/// Wrapper around the libc poll call.\npub fn poll(fds: &mut[pollfd], timeout: i32) -> Result<usize> {\n    let r = unsafe { libc::poll(fds.as_mut_ptr(), fds.len() as libc::nfds_t, timeout as libc::c_int) };\n    if r >= 0 { Ok(r as usize) } else {\n        #[cfg(feature = \"std\")]\n        { from_code(\n            \"poll\",\n            -std::io::Error::last_os_error().raw_os_error().unwrap_or_default()).map(|_| unreachable!())\n        }\n        #[cfg(not(feature = \"std\"))]\n        { from_code(\"poll\", -unsafe {super::error::errno}).map(|_| unreachable!()) }\n        \n    }\n}\n\n/// Builds a pollfd array, polls it, and returns the poll descriptors which have non-zero revents.\npub fn poll_all<'a>(desc: &[&'a dyn Descriptors], timeout: i32) -> Result<Vec<(&'a dyn Descriptors, Flags)>> {\n\n    let mut pollfds: Vec<pollfd> = vec!();\n    let mut indices = vec!();\n    for v2 in desc.iter().map(|q| q.get()) {\n        let v = v2?;\n        indices.push(pollfds.len() .. pollfds.len()+v.len());\n        pollfds.extend(v);\n    };\n\n    poll(&mut pollfds, timeout)?;\n\n    let mut res = vec!();\n    for (i, r) in indices.into_iter().enumerate() {\n        let z = desc[i].revents(&pollfds[r])?;\n        if !z.is_empty() { res.push((desc[i], z)); }\n    }\n    Ok(res)\n}\n"
  },
  {
    "path": "src/rawmidi.rs",
    "content": "//! MIDI devices I/O and enumeration\n\nuse libc::{c_int, c_uint, c_void, size_t, c_short, pollfd};\nuse super::ctl_int::{ctl_ptr, Ctl};\nuse super::{Direction, poll};\nuse super::error::*;\nuse crate::alsa;\nuse ::alloc::ffi::CString;\nuse ::alloc::string::{String, ToString};\nuse core::ptr;\nuse core::ffi::CStr;\n\n/// Iterator over [Rawmidi](http://www.alsa-project.org/alsa-doc/alsa-lib/group___raw_midi.html) devices and subdevices\n#[derive(Debug)]\npub struct Iter<'a> {\n    ctl: &'a Ctl,\n    device: c_int,\n    in_count: i32,\n    out_count: i32,\n    current: i32,\n}\n\n/// [snd_rawmidi_info_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___raw_midi.html) wrapper\n#[derive(Debug)]\npub struct Info(*mut alsa::snd_rawmidi_info_t);\n\nimpl Drop for Info {\n    fn drop(&mut self) { unsafe { alsa::snd_rawmidi_info_free(self.0) }; }\n}\n\nimpl Info {\n    fn new() -> Result<Info> {\n        let mut p = ptr::null_mut();\n        acheck!(snd_rawmidi_info_malloc(&mut p)).map(|_| Info(p))\n    }\n\n    fn from_iter(c: &Ctl, device: i32, sub: i32, dir: Direction) -> Result<Info> {\n        let r = Info::new()?;\n        unsafe { alsa::snd_rawmidi_info_set_device(r.0, device as c_uint) };\n        let d = match dir {\n            Direction::Playback => alsa::SND_RAWMIDI_STREAM_OUTPUT,\n            Direction::Capture => alsa::SND_RAWMIDI_STREAM_INPUT,\n        };\n        unsafe { alsa::snd_rawmidi_info_set_stream(r.0, d) };\n        unsafe { alsa::snd_rawmidi_info_set_subdevice(r.0, sub as c_uint) };\n        acheck!(snd_ctl_rawmidi_info(ctl_ptr(c), r.0)).map(|_| r)\n    }\n\n    fn subdev_count(c: &Ctl, device: c_int) -> Result<(i32, i32)> {\n        let i = Info::from_iter(c, device, 0, Direction::Capture)?;\n        let o = Info::from_iter(c, device, 0, Direction::Playback)?;\n        Ok((unsafe { alsa::snd_rawmidi_info_get_subdevices_count(o.0) as i32 },\n            unsafe { alsa::snd_rawmidi_info_get_subdevices_count(i.0) as i32 }))\n    }\n\n    pub fn get_device(&self) -> i32 { unsafe { alsa::snd_rawmidi_info_get_device(self.0) as i32 }}\n    pub fn get_subdevice(&self) -> i32 { unsafe { alsa::snd_rawmidi_info_get_subdevice(self.0) as i32 }}\n    pub fn get_stream(&self) -> super::Direction {\n        if unsafe { alsa::snd_rawmidi_info_get_stream(self.0) } == alsa::SND_RAWMIDI_STREAM_OUTPUT { super::Direction::Playback }\n        else { super::Direction::Capture }\n    }\n\n    pub fn get_subdevice_name(&self) -> Result<String> {\n        let c = unsafe { alsa::snd_rawmidi_info_get_subdevice_name(self.0) };\n        from_const(\"snd_rawmidi_info_get_subdevice_name\", c).map(|s| s.to_string())\n    }\n    pub fn get_id(&self) -> Result<String> {\n        let c = unsafe { alsa::snd_rawmidi_info_get_id(self.0) };\n        from_const(\"snd_rawmidi_info_get_id\", c).map(|s| s.to_string())\n    }\n}\n\n/// [snd_rawmidi_info_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___raw_midi.html) wrapper\n#[derive(Debug)]\npub struct Status(*mut alsa::snd_rawmidi_status_t);\n\nimpl Status {\n    fn new() -> Result<Self> {\n        let mut p = ptr::null_mut();\n        acheck!(snd_rawmidi_status_malloc(&mut p)).map(|_| Status(p))\n    }\n}\n\nimpl Status {\n    pub fn get_avail(&self) -> usize { unsafe { alsa::snd_rawmidi_status_get_avail(self.0 as *const _) } }\n    pub fn get_xruns(&self) -> usize { unsafe { alsa::snd_rawmidi_status_get_xruns(self.0 as *const _) } }\n}\n\nimpl Drop for Status {\n    fn drop(&mut self) { unsafe { alsa::snd_rawmidi_status_free(self.0) }; }\n}\n\n\nimpl<'a> Iter<'a> {\n    pub fn new(c: &'a Ctl) -> Iter<'a> { Iter { ctl: c, device: -1, in_count: 0, out_count: 0, current: 0 }}\n}\n\nimpl<'a> Iterator for Iter<'a> {\n    type Item = Result<Info>;\n    fn next(&mut self) -> Option<Result<Info>> {\n        if self.current < self.in_count {\n            self.current += 1;\n            return Some(Info::from_iter(self.ctl, self.device, self.current-1, Direction::Capture));\n        }\n        if self.current - self.in_count < self.out_count {\n            self.current += 1;\n            return Some(Info::from_iter(self.ctl, self.device, self.current-1-self.in_count, Direction::Playback));\n        }\n\n        let r = acheck!(snd_ctl_rawmidi_next_device(ctl_ptr(self.ctl), &mut self.device));\n        match r {\n            Err(e) if e.errno() == libc::ENOTTY => return None,\n            Err(e) => return Some(Err(e)),\n            Ok(_) if self.device == -1 => return None,\n            _ => {},\n        }\n        self.current = 0;\n        match Info::subdev_count(self.ctl, self.device) {\n            Err(e) => Some(Err(e)),\n            Ok((oo, ii)) => {\n                self.in_count = ii;\n                self.out_count = oo;\n                self.next()\n            }\n        }\n    }\n}\n\n/// [snd_rawmidi_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___raw_midi.html) wrapper\n#[derive(Debug)]\npub struct Rawmidi(*mut alsa::snd_rawmidi_t);\n\nunsafe impl Send for Rawmidi {}\n\nimpl Drop for Rawmidi {\n    fn drop(&mut self) { unsafe { alsa::snd_rawmidi_close(self.0) }; }\n}\n\nimpl Rawmidi {\n\n    /// Wrapper around open that takes a &str instead of a &CStr\n    pub fn new(name: &str, dir: Direction, nonblock: bool) -> Result<Self> {\n        Self::open(&CString::new(name).unwrap(), dir, nonblock)\n    }\n\n    pub fn open(name: &CStr, dir: Direction, nonblock: bool) -> Result<Rawmidi> {\n        let mut h = ptr::null_mut();\n        let flags = if nonblock { 2 } else { 0 }; // FIXME: alsa::SND_RAWMIDI_NONBLOCK does not exist in alsa-sys\n        acheck!(snd_rawmidi_open(\n            if dir == Direction::Capture { &mut h } else { ptr::null_mut() },\n            if dir == Direction::Playback { &mut h } else { ptr::null_mut() },\n            name.as_ptr(), flags))\n            .map(|_| Rawmidi(h))\n    }\n\n    pub fn info(&self) -> Result<Info> {\n        Info::new().and_then(|i| acheck!(snd_rawmidi_info(self.0, i.0)).map(|_| i))\n    }\n\n    pub fn status(&self) -> Result<Status> {\n        Status::new().and_then(|i| acheck!(snd_rawmidi_status(self.0, i.0)).map(|_| i))\n    }\n\n    pub fn drop(&self) -> Result<()> { acheck!(snd_rawmidi_drop(self.0)).map(|_| ()) }\n    pub fn drain(&self) -> Result<()> { acheck!(snd_rawmidi_drain(self.0)).map(|_| ()) }\n    pub fn name(&self) -> Result<String> {\n        let c = unsafe { alsa::snd_rawmidi_name(self.0) };\n        from_const(\"snd_rawmidi_name\", c).map(|s| s.to_string())\n    }\n\n    pub fn io(&self) -> IO<'_> { IO(self) }\n}\n\nimpl poll::Descriptors for Rawmidi {\n    fn count(&self) -> usize {\n        unsafe { alsa::snd_rawmidi_poll_descriptors_count(self.0) as usize }\n    }\n    fn fill(&self, p: &mut [pollfd]) -> Result<usize> {\n        let z = unsafe { alsa::snd_rawmidi_poll_descriptors(self.0, p.as_mut_ptr(), p.len() as c_uint) };\n        from_code(\"snd_rawmidi_poll_descriptors\", z).map(|_| z as usize)\n    }\n    fn revents(&self, p: &[pollfd]) -> Result<poll::Flags> {\n        let mut r = 0;\n        let z = unsafe { alsa::snd_rawmidi_poll_descriptors_revents(self.0, p.as_ptr() as *mut pollfd, p.len() as c_uint, &mut r) };\n        from_code(\"snd_rawmidi_poll_descriptors_revents\", z).map(|_| poll::Flags::from_bits_truncate(r as c_short))\n    }\n}\n\n/// Implements `std::io::Read` and `std::io::Write` for `Rawmidi`\n#[derive(Debug)]\npub struct IO<'a>(&'a Rawmidi);\n\n#[cfg(feature = \"std\")]\nimpl<'a> std::io::Read for IO<'a> {\n    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {\n        let r = unsafe { alsa::snd_rawmidi_read((self.0).0, buf.as_mut_ptr() as *mut c_void, buf.len() as size_t) };\n        if r < 0 { Err(std::io::Error::from_raw_os_error(r as i32)) }\n        else { Ok(r as usize) }\n    }\n}\n\n#[cfg(feature = \"std\")]\nimpl<'a> std::io::Write for IO<'a> {\n    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {\n        let r = unsafe { alsa::snd_rawmidi_write((self.0).0, buf.as_ptr() as *const c_void, buf.len() as size_t) };\n        if r < 0 { Err(std::io::Error::from_raw_os_error(r as i32)) }\n        else { Ok(r as usize) }\n    }\n    fn flush(&mut self) -> std::io::Result<()> { Ok(()) }\n}\n\n\n#[test]\nfn print_rawmidis() {\n    extern crate std;\n\n    for a in super::card::Iter::new().map(|a| a.unwrap()) {\n        for b in Iter::new(&Ctl::from_card(&a, false).unwrap()).map(|b| b.unwrap()) {\n            std::println!(\"Rawmidi {:?} (hw:{},{},{}) {} - {}\", b.get_stream(), a.get_index(), b.get_device(), b.get_subdevice(),\n                 a.get_name().unwrap(), b.get_subdevice_name().unwrap())\n        }\n    }\n}\n"
  },
  {
    "path": "src/seq.rs",
    "content": "//! MIDI sequencer I/O and enumeration\n\nuse libc::{c_uint, c_int, c_short, c_uchar, c_void, c_long, size_t, pollfd};\nuse super::error::*;\nuse crate::alsa;\nuse super::{Direction, poll};\nuse core::{ptr, fmt, mem, slice, time, cell};\nuse core::str::{FromStr, Split};\nuse core::ffi::CStr;\nuse ::alloc::borrow::Cow;\nuse ::alloc::boxed::Box;\n\n// Workaround for improper alignment of snd_seq_ev_ext_t in alsa-sys\n#[repr(packed)]\nstruct EvExtPacked {\n    len: c_uint,\n    ptr: *mut c_void,\n}\n\n/// [snd_seq_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___sequencer.html) wrapper\n///\n/// To access the functions `event_input`, `event_input_pending` and `set_input_buffer_size`,\n/// you first have to obtain an instance of `Input` by calling `input()`. Only one instance of\n/// `Input` may exist at any time for a given `Seq`.\n#[derive(Debug)]\npub struct Seq(*mut alsa::snd_seq_t, cell::Cell<bool>);\n\nunsafe impl Send for Seq {}\n\nimpl Drop for Seq {\n    fn drop(&mut self) { unsafe { alsa::snd_seq_close(self.0) }; }\n}\n\nimpl Seq {\n    fn check_has_input(&self) {\n        if self.1.get() { panic!(\"No additional Input object allowed\")}\n    }\n\n    /// Opens the sequencer.\n    ///\n    /// If name is None, \"default\" will be used. That's almost always what you usually want to use anyway.\n    pub fn open(name: Option<&CStr>, dir: Option<Direction>, nonblock: bool) -> Result<Seq> {\n        let n2 = name.unwrap_or(unsafe { CStr::from_bytes_with_nul_unchecked(b\"default\\0\") });\n        let mut h = ptr::null_mut();\n        let mode = if nonblock { alsa::SND_SEQ_NONBLOCK } else { 0 };\n        let streams = match dir {\n            None => alsa::SND_SEQ_OPEN_DUPLEX,\n            Some(Direction::Playback) => alsa::SND_SEQ_OPEN_OUTPUT,\n            Some(Direction::Capture) => alsa::SND_SEQ_OPEN_INPUT,\n        };\n        acheck!(snd_seq_open(&mut h, n2.as_ptr(), streams, mode))\n            .map(|_| Seq(h, cell::Cell::new(false)))\n    }\n\n    pub fn set_client_name(&self, name: &CStr) -> Result<()> {\n        acheck!(snd_seq_set_client_name(self.0, name.as_ptr())).map(|_| ())\n    }\n\n    pub fn set_client_event_filter(&self, event_type: i32) -> Result<()> {\n        acheck!(snd_seq_set_client_event_filter(self.0, event_type as c_int)).map(|_| ())\n    }\n\n    pub fn set_client_pool_output(&self, size: u32) -> Result<()> {\n        acheck!(snd_seq_set_client_pool_output(self.0, size as size_t)).map(|_| ())\n    }\n\n    pub fn set_client_pool_input(&self, size: u32) -> Result<()> {\n        acheck!(snd_seq_set_client_pool_input(self.0, size as size_t)).map(|_| ())\n    }\n\n    pub fn set_client_pool_output_room(&self, size: u32) -> Result<()> {\n        acheck!(snd_seq_set_client_pool_output_room(self.0, size as size_t)).map(|_| ())\n    }\n\n    pub fn client_id(&self) -> Result<i32> {\n        acheck!(snd_seq_client_id(self.0)).map(|q| q as i32)\n    }\n\n    pub fn drain_output(&self) -> Result<i32> {\n        acheck!(snd_seq_drain_output(self.0)).map(|q| q as i32)\n    }\n\n    pub fn get_any_client_info(&self, client: i32) -> Result<ClientInfo> {\n        let c = ClientInfo::new()?;\n        acheck!(snd_seq_get_any_client_info(self.0, client, c.0)).map(|_| c)\n    }\n\n    pub fn get_any_port_info(&self, a: Addr) -> Result<PortInfo> {\n        let c = PortInfo::new()?;\n        acheck!(snd_seq_get_any_port_info(self.0, a.client as c_int, a.port as c_int, c.0)).map(|_| c)\n    }\n\n    pub fn create_port(&self, port: &PortInfo) -> Result<()> {\n        acheck!(snd_seq_create_port(self.0, port.0)).map(|_| ())\n    }\n\n    pub fn create_simple_port(&self, name: &CStr, caps: PortCap, t: PortType) -> Result<i32> {\n        acheck!(snd_seq_create_simple_port(self.0, name.as_ptr(), caps.bits() as c_uint, t.bits() as c_uint)).map(|q| q as i32)\n    }\n\n    pub fn set_port_info(&self, port: i32, info: &mut PortInfo) -> Result<()> {\n        acheck!(snd_seq_set_port_info(self.0, port, info.0)).map(|_| ())\n    }\n\n    pub fn delete_port(&self, port: i32) -> Result<()> {\n        acheck!(snd_seq_delete_port(self.0, port as c_int)).map(|_| ())\n    }\n\n    pub fn subscribe_port(&self, info: &PortSubscribe) -> Result<()> {\n        acheck!(snd_seq_subscribe_port(self.0, info.0)).map(|_| ())\n    }\n\n    pub fn unsubscribe_port(&self, sender: Addr, dest: Addr) -> Result<()> {\n        let z = PortSubscribe::new()?;\n        z.set_sender(sender);\n        z.set_dest(dest);\n        acheck!(snd_seq_unsubscribe_port(self.0, z.0)).map(|_| ())\n    }\n\n    pub fn control_queue(&self, q: i32, t: EventType, value: i32, e: Option<&mut Event>) -> Result<()> {\n        assert!(EvQueueControl::<()>::has_data(t) || EvQueueControl::<i32>::has_data(t) || EvQueueControl::<u32>::has_data(t));\n        let p = e.map(|e| &mut e.0 as *mut _).unwrap_or(ptr::null_mut());\n        acheck!(snd_seq_control_queue(self.0, q as c_int, t as c_int, value as c_int, p)).map(|_| ())\n    }\n\n    pub fn event_output(&self, e: &mut Event) -> Result<u32> {\n        e.ensure_buf();\n        acheck!(snd_seq_event_output(self.0, &mut e.0)).map(|q| q as u32)\n    }\n\n    pub fn event_output_buffer(&self, e: &mut Event) -> Result<u32> {\n        e.ensure_buf();\n        acheck!(snd_seq_event_output_buffer(self.0, &mut e.0)).map(|q| q as u32)\n    }\n\n    pub fn event_output_direct(&self, e: &mut Event) -> Result<u32> {\n        e.ensure_buf();\n        acheck!(snd_seq_event_output_direct(self.0, &mut e.0)).map(|q| q as u32)\n    }\n\n    pub fn get_queue_tempo(&self, q: i32) -> Result<QueueTempo> {\n        let value = QueueTempo::new()?;\n        acheck!(snd_seq_get_queue_tempo(self.0, q as c_int, value.0)).map(|_| value)\n    }\n\n    pub fn set_queue_tempo(&self, q: i32, value: &QueueTempo) -> Result<()> {\n        acheck!(snd_seq_set_queue_tempo(self.0, q as c_int, value.0)).map(|_| ())\n    }\n\n    pub fn get_queue_status(&self, q: i32) -> Result<QueueStatus> {\n        let value = QueueStatus::new()?;\n        acheck!(snd_seq_get_queue_status(self.0, q as c_int, value.0)).map(|_| value)\n    }\n\n    pub fn free_queue(&self, q: i32) -> Result<()> { acheck!(snd_seq_free_queue(self.0, q)).map(|_| ()) }\n    pub fn alloc_queue(&self) -> Result<i32> { acheck!(snd_seq_alloc_queue(self.0)).map(|q| q as i32) }\n    pub fn alloc_named_queue(&self, n: &CStr) -> Result<i32> {\n        acheck!(snd_seq_alloc_named_queue(self.0, n.as_ptr())).map(|q| q as i32)\n    }\n\n    pub fn sync_output_queue(&self) -> Result<()> {\n        acheck!(snd_seq_sync_output_queue(self.0)).map(|_| ())\n    }\n\n    pub fn drop_output(&self) -> Result<()> {\n        acheck!(snd_seq_drop_output(self.0)).map(|_| ())\n    }\n\n    /// Call this function to obtain an instance of `Input` to access the functions `event_input`,\n    /// `event_input_pending` and `set_input_buffer_size`. See the documentation of `Input` for details.\n    pub fn input(&self) -> Input<'_> {\n        Input::new(self)\n    }\n\n    pub fn remove_events(&self, condition: RemoveEvents) -> Result<()> {\n        acheck!(snd_seq_remove_events(self.0, condition.0)).map(|_| ())\n    }\n}\n\n/// Struct for receiving input events from a sequencer. The methods offered by this\n/// object may modify the internal input buffer of the sequencer, which must not happen\n/// while an `Event` is alive that has been obtained from a call to `event_input` (which\n/// takes `Input` by mutable reference for this reason). This is because the event might\n/// directly reference the sequencer's input buffer for variable-length messages (e.g. Sysex).\n///\n/// Note: Only one `Input` object is allowed in scope at a time.\n#[derive(Debug)]\npub struct Input<'a>(&'a Seq);\n\nimpl<'a> Drop for Input<'a> {\n    fn drop(&mut self) { (self.0).1.set(false) }\n}\n\nimpl<'a> Input<'a> {\n    fn new(s: &'a Seq) -> Input<'a> {\n        s.check_has_input();\n        s.1.set(true);\n        Input(s)\n    }\n\n    pub fn event_input(&mut self) -> Result<Event<'_>> {\n        // The returned event might reference the input buffer of the `Seq`.\n        // Therefore we mutably borrow the `Input` structure, preventing any\n        // other function call that might change the input buffer while the\n        // event is alive.\n        let mut z = ptr::null_mut();\n        acheck!(snd_seq_event_input((self.0).0, &mut z))?;\n        unsafe { Event::extract (&mut *z, \"snd_seq_event_input\") }\n    }\n\n    pub fn event_input_pending(&self, fetch_sequencer: bool) -> Result<u32> {\n        acheck!(snd_seq_event_input_pending((self.0).0, if fetch_sequencer {1} else {0})).map(|q| q as u32)\n    }\n\n    pub fn set_input_buffer_size(&self, size: u32)  -> Result<()> {\n        acheck!(snd_seq_set_input_buffer_size((self.0).0, size as size_t)).map(|_| ())\n    }\n\n    pub fn drop_input(&self) -> Result<()> {\n        acheck!(snd_seq_drop_input((self.0).0)).map(|_| ())\n    }\n}\n\nfn polldir(o: Option<Direction>) -> c_short {\n    match o {\n        None => poll::Flags::IN | poll::Flags::OUT,\n        Some(Direction::Playback) => poll::Flags::OUT,\n        Some(Direction::Capture) => poll::Flags::IN,\n    }.bits()\n}\n\nimpl<'a> poll::Descriptors for (&'a Seq, Option<Direction>) {\n\n    fn count(&self) -> usize {\n        unsafe { alsa::snd_seq_poll_descriptors_count((self.0).0, polldir(self.1)) as usize }\n    }\n\n    fn fill(&self, p: &mut [pollfd]) -> Result<usize> {\n        let z = unsafe { alsa::snd_seq_poll_descriptors((self.0).0, p.as_mut_ptr(), p.len() as c_uint, polldir(self.1)) };\n        from_code(\"snd_seq_poll_descriptors\", z).map(|_| z as usize)\n    }\n\n    fn revents(&self, p: &[pollfd]) -> Result<poll::Flags> {\n        let mut r = 0;\n        let z = unsafe { alsa::snd_seq_poll_descriptors_revents((self.0).0, p.as_ptr() as *mut pollfd, p.len() as c_uint, &mut r) };\n        from_code(\"snd_seq_poll_descriptors_revents\", z).map(|_| poll::Flags::from_bits_truncate(r as c_short))\n    }\n}\n\n/// [snd_seq_client_info_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_client.html) wrapper\npub struct ClientInfo(*mut alsa::snd_seq_client_info_t);\n\nunsafe impl Send for ClientInfo {}\n\nimpl Drop for ClientInfo {\n    fn drop(&mut self) {\n        unsafe { alsa::snd_seq_client_info_free(self.0) };\n    }\n}\n\nimpl ClientInfo {\n    fn new() -> Result<Self> {\n        let mut p = ptr::null_mut();\n        acheck!(snd_seq_client_info_malloc(&mut p)).map(|_| ClientInfo(p))\n    }\n\n    // Not sure if it's useful for this one to be public.\n    fn set_client(&self, client: i32) {\n        unsafe { alsa::snd_seq_client_info_set_client(self.0, client as c_int) };\n    }\n\n    pub fn get_client(&self) -> i32 {\n        unsafe { alsa::snd_seq_client_info_get_client(self.0) as i32 }\n    }\n\n    pub fn get_name(&self) -> Result<&str> {\n        let c = unsafe { alsa::snd_seq_client_info_get_name(self.0) };\n        from_const(\"snd_seq_client_info_get_name\", c)\n    }\n\n    pub fn get_card(&self) -> Result<i32> {\n        acheck!(snd_seq_client_info_get_card(self.0))\n    }\n}\n\nimpl fmt::Debug for ClientInfo {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        write!(f, \"ClientInfo({},{:?})\", self.get_client(), self.get_name())\n    }\n}\n\n#[derive(Copy, Clone, Debug)]\n/// Iterates over clients connected to the seq API (both kernel and userspace clients).\npub struct ClientIter<'a>(&'a Seq, i32);\n\nimpl<'a> ClientIter<'a> {\n    pub fn new(seq: &'a Seq) -> Self { ClientIter(seq, -1) }\n}\n\nimpl<'a> Iterator for ClientIter<'a> {\n    type Item = ClientInfo;\n    fn next(&mut self) -> Option<Self::Item> {\n        let z = ClientInfo::new().unwrap();\n        z.set_client(self.1);\n        let r = unsafe { alsa::snd_seq_query_next_client((self.0).0, z.0) };\n        if r < 0 { self.1 = -1; return None };\n        self.1 = z.get_client();\n        Some(z)\n    }\n}\n\n/// [snd_seq_port_info_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_port.html) wrapper\npub struct PortInfo(*mut alsa::snd_seq_port_info_t);\n\nunsafe impl Send for PortInfo {}\n\nimpl Drop for PortInfo {\n    fn drop(&mut self) {\n        unsafe { alsa::snd_seq_port_info_free(self.0) };\n    }\n}\n\nimpl PortInfo {\n    fn new() -> Result<Self> {\n        let mut p = ptr::null_mut();\n        acheck!(snd_seq_port_info_malloc(&mut p)).map(|_| PortInfo(p))\n    }\n\n    /// Creates a new PortInfo with all fields set to zero.\n    pub fn empty() -> Result<Self> {\n        let z = Self::new()?;\n        unsafe { ptr::write_bytes(z.0 as *mut u8, 0, alsa::snd_seq_port_info_sizeof()) };\n        Ok(z)\n    }\n\n    pub fn get_client(&self) -> i32 {\n        unsafe { alsa::snd_seq_port_info_get_client(self.0) as i32 }\n    }\n\n    pub fn get_port(&self) -> i32 {\n        unsafe { alsa::snd_seq_port_info_get_port(self.0) as i32 }\n    }\n\n    // Not sure if it's useful for this one to be public.\n    fn set_client(&self, client: i32) {\n        unsafe { alsa::snd_seq_port_info_set_client(self.0, client as c_int) };\n    }\n\n    // Not sure if it's useful for this one to be public.\n    fn set_port(&self, port: i32) {\n        unsafe { alsa::snd_seq_port_info_set_port(self.0, port as c_int) };\n    }\n\n    pub fn get_name(&self) -> Result<&str> {\n        let c = unsafe { alsa::snd_seq_port_info_get_name(self.0) };\n        from_const(\"snd_seq_port_info_get_name\", c)\n    }\n\n    pub fn set_name(&mut self, name: &CStr) {\n        // Note: get_name returns an interior reference, so this one must take &mut self\n        unsafe { alsa::snd_seq_port_info_set_name(self.0, name.as_ptr()) };\n    }\n\n    pub fn get_capability(&self) -> PortCap {\n        PortCap::from_bits_truncate(unsafe { alsa::snd_seq_port_info_get_capability(self.0) as u32 })\n    }\n\n    pub fn get_type(&self) -> PortType {\n        PortType::from_bits_truncate(unsafe { alsa::snd_seq_port_info_get_type(self.0) as u32 })\n    }\n\n    pub fn set_capability(&self, c: PortCap) {\n        unsafe { alsa::snd_seq_port_info_set_capability(self.0, c.bits() as c_uint) }\n    }\n\n    pub fn set_type(&self, c: PortType) {\n        unsafe { alsa::snd_seq_port_info_set_type(self.0, c.bits() as c_uint) }\n    }\n\n    /// Returns an Addr containing this PortInfo's client and port id.\n    pub fn addr(&self) -> Addr {\n        Addr {\n            client: self.get_client(),\n            port: self.get_port(),\n        }\n    }\n\n    pub fn get_midi_channels(&self) -> i32 { unsafe { alsa::snd_seq_port_info_get_midi_channels(self.0) as i32 } }\n    pub fn get_midi_voices(&self) -> i32 { unsafe { alsa::snd_seq_port_info_get_midi_voices(self.0) as i32 } }\n    pub fn get_synth_voices(&self) -> i32 { unsafe { alsa::snd_seq_port_info_get_synth_voices(self.0) as i32 } }\n    pub fn get_read_use(&self) -> i32 { unsafe { alsa::snd_seq_port_info_get_read_use(self.0) as i32 } }\n    pub fn get_write_use(&self) -> i32 { unsafe { alsa::snd_seq_port_info_get_write_use(self.0) as i32 } }\n    pub fn get_port_specified(&self) -> bool { unsafe { alsa::snd_seq_port_info_get_port_specified(self.0) == 1 } }\n    pub fn get_timestamping(&self) -> bool { unsafe { alsa::snd_seq_port_info_get_timestamping(self.0) == 1 } }\n    pub fn get_timestamp_real(&self) -> bool { unsafe { alsa::snd_seq_port_info_get_timestamp_real(self.0) == 1 } }\n    pub fn get_timestamp_queue(&self) -> i32 { unsafe { alsa::snd_seq_port_info_get_timestamp_queue(self.0) as i32 } }\n\n    pub fn set_midi_channels(&self, value: i32) { unsafe { alsa::snd_seq_port_info_set_midi_channels(self.0, value as c_int) } }\n    pub fn set_midi_voices(&self, value: i32) { unsafe { alsa::snd_seq_port_info_set_midi_voices(self.0, value as c_int) } }\n    pub fn set_synth_voices(&self, value: i32) { unsafe { alsa::snd_seq_port_info_set_synth_voices(self.0, value as c_int) } }\n    pub fn set_port_specified(&self, value: bool) { unsafe { alsa::snd_seq_port_info_set_port_specified(self.0, if value { 1 } else { 0 } ) } }\n    pub fn set_timestamping(&self, value: bool) { unsafe { alsa::snd_seq_port_info_set_timestamping(self.0, if value { 1 } else { 0 } ) } }\n    pub fn set_timestamp_real(&self, value: bool) { unsafe { alsa::snd_seq_port_info_set_timestamp_real(self.0, if value { 1 } else { 0 } ) } }\n    pub fn set_timestamp_queue(&self, value: i32) { unsafe { alsa::snd_seq_port_info_set_timestamp_queue(self.0, value as c_int) } }\n}\n\nimpl fmt::Debug for PortInfo {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        write!(f, \"PortInfo({}:{},{:?})\", self.get_client(), self.get_port(), self.get_name())\n    }\n}\n\n#[derive(Copy, Clone, Debug)]\n/// Iterates over clients connected to the seq API (both kernel and userspace clients).\npub struct PortIter<'a>(&'a Seq, i32, i32);\n\nimpl<'a> PortIter<'a> {\n    pub fn new(seq: &'a Seq, client: i32) -> Self { PortIter(seq, client, -1) }\n}\n\nimpl<'a> Iterator for PortIter<'a> {\n    type Item = PortInfo;\n    fn next(&mut self) -> Option<Self::Item> {\n        let z = PortInfo::new().unwrap();\n        z.set_client(self.1);\n        z.set_port(self.2);\n        let r = unsafe { alsa::snd_seq_query_next_port((self.0).0, z.0) };\n        if r < 0 { self.2 = -1; return None };\n        self.2 = z.get_port();\n        Some(z)\n    }\n}\n\nbitflags! {\n    #[repr(transparent)]\n    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]\n    /// [SND_SEQ_PORT_CAP_xxx](http://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_port.html) constants\n    pub struct PortCap: u32 {\n        const READ = 1<<0;\n        const WRITE = 1<<1;\n        const SYNC_READ = 1<<2;\n        const SYNC_WRITE = 1<<3;\n        const DUPLEX = 1<<4;\n        const SUBS_READ = 1<<5;\n        const SUBS_WRITE = 1<<6;\n        const NO_EXPORT = 1<<7;\n   }\n}\n\nbitflags! {\n    #[repr(transparent)]\n    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]\n    /// [SND_SEQ_PORT_TYPE_xxx](http://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_port.html) constants\n    pub struct PortType: u32 {\n        const SPECIFIC = (1<<0);\n        const MIDI_GENERIC = (1<<1);\n        const MIDI_GM = (1<<2);\n        const MIDI_GS = (1<<3);\n        const MIDI_XG = (1<<4);\n        const MIDI_MT32 = (1<<5);\n        const MIDI_GM2 = (1<<6);\n        const SYNTH = (1<<10);\n        const DIRECT_SAMPLE = (1<<11);\n        const SAMPLE = (1<<12);\n        const HARDWARE = (1<<16);\n        const SOFTWARE = (1<<17);\n        const SYNTHESIZER = (1<<18);\n        const PORT = (1<<19);\n        const APPLICATION = (1<<20);\n    }\n}\n\nbitflags! {\n    #[repr(transparent)]\n    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]\n    /// [SND_SEQ_REMOVE_xxx](https://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_event.html) constants\n    pub struct Remove: u32 {\n        const INPUT = (1<<0);\n        const OUTPUT = (1<<1);\n        const DEST = (1<<2);\n        const DEST_CHANNEL = (1<<3);\n        const TIME_BEFORE = (1<<4);\n        const TIME_AFTER = (1<<5);\n        const TIME_TICK = (1<<6);\n        const EVENT_TYPE = (1<<7);\n        const IGNORE_OFF = (1<<8);\n        const TAG_MATCH = (1<<9);\n    }\n}\n\n\n/// [snd_seq_addr_t](http://www.alsa-project.org/alsa-doc/alsa-lib/structsnd__seq__addr__t.html) wrapper\n#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Default)]\npub struct Addr {\n    pub client: i32,\n    pub port: i32,\n}\n\nimpl FromStr for Addr {\n    type Err = Box<dyn core::error::Error>;\n\n    fn from_str(s: &str) -> core::result::Result<Self, Self::Err> {\n        let mut split: Split<'_, char> = s.trim().split(':');\n        let client = split.next()\n                          .ok_or(\"no client provided\")?\n                          .parse::<i32>()?;\n        let port = split.next()\n                        .ok_or(\"no port provided\")?\n                        .parse::<i32>()?;\n        match split.next() {\n            Some(_) => {\n                Err(\"too many arguments\".into())\n            },\n            None => {\n                Ok(Addr { client, port })\n            }\n        }\n    }\n}\n\nimpl Addr {\n    pub fn system_timer() -> Addr { Addr { client: alsa::SND_SEQ_CLIENT_SYSTEM as i32, port: alsa::SND_SEQ_PORT_SYSTEM_TIMER as i32 } }\n    pub fn system_announce() -> Addr { Addr { client: alsa::SND_SEQ_CLIENT_SYSTEM as i32, port: alsa::SND_SEQ_PORT_SYSTEM_ANNOUNCE as i32 } }\n    pub fn broadcast() -> Addr { Addr { client: alsa::SND_SEQ_ADDRESS_BROADCAST as i32, port: alsa::SND_SEQ_ADDRESS_BROADCAST as i32 } }\n}\n\n/// [snd_seq_port_subscribe_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_subscribe.html) wrapper\n#[derive(Debug)]\npub struct PortSubscribe(*mut alsa::snd_seq_port_subscribe_t);\n\nunsafe impl Send for PortSubscribe {}\n\nimpl Drop for PortSubscribe {\n    fn drop(&mut self) { unsafe { alsa::snd_seq_port_subscribe_free(self.0) }; }\n}\n\nimpl PortSubscribe {\n    fn new() -> Result<Self> {\n        let mut p = ptr::null_mut();\n        acheck!(snd_seq_port_subscribe_malloc(&mut p)).map(|_| PortSubscribe(p))\n    }\n\n    /// Creates a new PortSubscribe with all fields set to zero.\n    pub fn empty() -> Result<Self> {\n        let z = Self::new()?;\n        unsafe { ptr::write_bytes(z.0 as *mut u8, 0, alsa::snd_seq_port_subscribe_sizeof()) };\n        Ok(z)\n    }\n\n    pub fn get_sender(&self) -> Addr { unsafe {\n        let z = alsa::snd_seq_port_subscribe_get_sender(self.0);\n        Addr { client: (*z).client as i32, port: (*z).port as i32 }\n    } }\n\n    pub fn get_dest(&self) -> Addr { unsafe {\n        let z = alsa::snd_seq_port_subscribe_get_dest(self.0);\n        Addr { client: (*z).client as i32, port: (*z).port as i32 }\n    } }\n\n    pub fn get_queue(&self) -> i32 { unsafe { alsa::snd_seq_port_subscribe_get_queue(self.0) as i32 } }\n    pub fn get_exclusive(&self) -> bool { unsafe { alsa::snd_seq_port_subscribe_get_exclusive(self.0) == 1 } }\n    pub fn get_time_update(&self) -> bool { unsafe { alsa::snd_seq_port_subscribe_get_time_update(self.0) == 1 } }\n    pub fn get_time_real(&self) -> bool { unsafe { alsa::snd_seq_port_subscribe_get_time_real(self.0) == 1 } }\n\n    pub fn set_sender(&self, value: Addr) {\n        let z = alsa::snd_seq_addr_t { client: value.client as c_uchar, port: value.port as c_uchar };\n        unsafe { alsa::snd_seq_port_subscribe_set_sender(self.0, &z) };\n    }\n\n    pub fn set_dest(&self, value: Addr) {\n        let z = alsa::snd_seq_addr_t { client: value.client as c_uchar, port: value.port as c_uchar };\n        unsafe { alsa::snd_seq_port_subscribe_set_dest(self.0, &z) };\n    }\n\n    pub fn set_queue(&self, value: i32) { unsafe { alsa::snd_seq_port_subscribe_set_queue(self.0, value as c_int) } }\n    pub fn set_exclusive(&self, value: bool) { unsafe { alsa::snd_seq_port_subscribe_set_exclusive(self.0, if value { 1 } else { 0 } ) } }\n    pub fn set_time_update(&self, value: bool) { unsafe { alsa::snd_seq_port_subscribe_set_time_update(self.0, if value { 1 } else { 0 } ) } }\n    pub fn set_time_real(&self, value: bool) { unsafe { alsa::snd_seq_port_subscribe_set_time_real(self.0, if value { 1 } else { 0 } ) } }\n\n}\n\n/// [snd_seq_query_subs_type_t](https://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_subscribe.html) wrapper\n#[derive(Copy, Clone, Debug)]\npub enum QuerySubsType {\n    READ = alsa::SND_SEQ_QUERY_SUBS_READ as isize,\n    WRITE = alsa::SND_SEQ_QUERY_SUBS_WRITE as isize,\n}\n\n/// [snd_seq_query_subscribe_t](https://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_subscribe.html) wrapper\n//(kept private, functionality exposed by PortSubscribeIter)\nstruct QuerySubscribe(*mut alsa::snd_seq_query_subscribe_t);\n\nunsafe impl Send for QuerySubscribe {}\n\nimpl Drop for QuerySubscribe {\n    fn drop(&mut self) { unsafe { alsa::snd_seq_query_subscribe_free(self.0) } }\n}\n\nimpl QuerySubscribe {\n    pub fn new() -> Result<Self> {\n        let mut q = ptr::null_mut();\n        acheck!(snd_seq_query_subscribe_malloc(&mut q)).map(|_| QuerySubscribe(q))\n    }\n\n    pub fn get_index(&self) -> i32 { unsafe { alsa::snd_seq_query_subscribe_get_index(self.0) as i32 } }\n    pub fn get_addr(&self) -> Addr { unsafe {\n        let a = &(*alsa::snd_seq_query_subscribe_get_addr(self.0));\n        Addr { client: a.client as i32, port: a.port as i32 }\n    } }\n    pub fn get_queue(&self) -> i32 { unsafe { alsa::snd_seq_query_subscribe_get_queue(self.0) as i32 } }\n    pub fn get_exclusive(&self) -> bool { unsafe { alsa::snd_seq_query_subscribe_get_exclusive(self.0) == 1 } }\n    pub fn get_time_update(&self) -> bool { unsafe { alsa::snd_seq_query_subscribe_get_time_update(self.0) == 1 } }\n    pub fn get_time_real(&self) -> bool { unsafe { alsa::snd_seq_query_subscribe_get_time_real(self.0) == 1 } }\n\n    pub fn set_root(&self, value: Addr) { unsafe {\n        let a = alsa::snd_seq_addr_t { client: value.client as c_uchar, port: value.port as c_uchar};\n        alsa::snd_seq_query_subscribe_set_root(self.0, &a);\n    } }\n    pub fn set_type(&self, value: QuerySubsType) { unsafe {\n        alsa::snd_seq_query_subscribe_set_type(self.0, value as alsa::snd_seq_query_subs_type_t)\n    } }\n    pub fn set_index(&self, value: i32) { unsafe { alsa::snd_seq_query_subscribe_set_index(self.0, value as c_int) } }\n}\n\n#[derive(Copy, Clone, Debug)]\n/// Iterates over port subscriptions for a given client:port/type.\npub struct PortSubscribeIter<'a> {\n    seq: &'a Seq,\n    addr: Addr,\n    query_subs_type: QuerySubsType,\n    index: i32\n}\n\nimpl<'a> PortSubscribeIter<'a> {\n    pub fn new(seq: &'a Seq, addr: Addr, query_subs_type: QuerySubsType) -> Self {\n        PortSubscribeIter {seq, addr, query_subs_type, index: 0 }\n    }\n}\n\nimpl<'a> Iterator for PortSubscribeIter<'a> {\n    type Item = PortSubscribe;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        let query = QuerySubscribe::new().unwrap();\n\n        query.set_root(self.addr);\n        query.set_type(self.query_subs_type);\n        query.set_index(self.index);\n\n        let r = unsafe { alsa::snd_seq_query_port_subscribers((self.seq).0, query.0) };\n        if r < 0 {\n            self.index = 0;\n            return None;\n        }\n\n        self.index = query.get_index() + 1;\n        let vtr = PortSubscribe::new().unwrap();\n        match self.query_subs_type {\n            QuerySubsType::READ => {\n                vtr.set_sender(self.addr);\n                vtr.set_dest(query.get_addr());\n            },\n            QuerySubsType:: WRITE => {\n                vtr.set_sender(query.get_addr());\n                vtr.set_dest(self.addr);\n            }\n        };\n        vtr.set_queue(query.get_queue());\n        vtr.set_exclusive(query.get_exclusive());\n        vtr.set_time_update(query.get_time_update());\n        vtr.set_time_real(query.get_time_real());\n\n        Some(vtr)\n    }\n}\n\n/// [snd_seq_event_t](http://www.alsa-project.org/alsa-doc/alsa-lib/structsnd__seq__event__t.html) wrapper\n///\n/// Fields of the event is not directly exposed. Instead call `Event::new` to set data (which can be, e g, an EvNote).\n/// Use `get_type` and `get_data` to retrieve data.\n///\n/// The lifetime parameter refers to the lifetime of an associated external buffer that might be used for\n/// variable-length messages (e.g. SysEx).\npub struct Event<'a>(alsa::snd_seq_event_t, EventType, Option<Cow<'a, [u8]>>);\n\nunsafe impl<'a> Send for Event<'a> {}\n\nimpl<'a> Event<'a> {\n    /// Creates a new event. For events that carry variable-length data (e.g. Sysex), `new_ext` has to be used instead.\n    pub fn new<D: EventData>(t: EventType, data: &D) -> Event<'static> {\n        assert!(!Event::has_ext_data(t), \"event type must not carry variable-length data\");\n        let mut z = Event(unsafe { mem::zeroed() }, t, None);\n        (z.0).type_ = t as c_uchar;\n        (z.0).flags |= Event::get_length_flag(t);\n        debug_assert!(D::has_data(t));\n        data.set_data(&mut z);\n        z\n    }\n\n    /// Creates a new event carrying variable-length data. This is required for event types `Sysex`, `Bounce`, and the `UsrVar` types.\n    pub fn new_ext<D: Into<Cow<'a, [u8]>>>(t: EventType, data: D) -> Event<'a> {\n        assert!(Event::has_ext_data(t), \"event type must carry variable-length data\");\n        let mut z = Event(unsafe { mem::zeroed() }, t, Some(data.into()));\n        (z.0).type_ = t as c_uchar;\n        (z.0).flags |= Event::get_length_flag(t);\n        z\n    }\n\n    /// Consumes this event and returns an (otherwise unchanged) event where the externally referenced\n    /// buffer for variable length messages (e.g. SysEx) has been copied into the event.\n    /// The returned event has a static lifetime, i e, it's decoupled from the original buffer.\n    pub fn into_owned(self) -> Event<'static> {\n        Event(self.0, self.1, self.2.map(|cow| Cow::Owned(cow.into_owned())))\n    }\n\n    fn get_length_flag(t: EventType) -> u8 {\n        match t {\n            EventType::Sysex => alsa::SND_SEQ_EVENT_LENGTH_VARIABLE,\n            EventType::Bounce => alsa::SND_SEQ_EVENT_LENGTH_VARIABLE, // not clear whether this should be VARIABLE or VARUSR\n            EventType::UsrVar0 => alsa::SND_SEQ_EVENT_LENGTH_VARUSR,\n            EventType::UsrVar1 => alsa::SND_SEQ_EVENT_LENGTH_VARUSR,\n            EventType::UsrVar2 => alsa::SND_SEQ_EVENT_LENGTH_VARUSR,\n            EventType::UsrVar3 => alsa::SND_SEQ_EVENT_LENGTH_VARUSR,\n            EventType::UsrVar4 => alsa::SND_SEQ_EVENT_LENGTH_VARUSR,\n            _ => alsa::SND_SEQ_EVENT_LENGTH_FIXED\n        }\n    }\n\n    fn has_ext_data(t: EventType) -> bool {\n        Event::get_length_flag(t) != alsa::SND_SEQ_EVENT_LENGTH_FIXED\n    }\n\n    /// Extracts event type and data. Produces a result with an arbitrary lifetime, hence the unsafety.\n    unsafe fn extract<'any>(z: &mut alsa::snd_seq_event_t, func: &'static str) -> Result<Event<'any>> {\n        let t = EventType::from_c_int((*z).type_ as c_int, func)?;\n        let ext_data = if Event::has_ext_data(t) {\n            assert_ne!((*z).flags & alsa::SND_SEQ_EVENT_LENGTH_MASK, alsa::SND_SEQ_EVENT_LENGTH_FIXED);\n            Some(Cow::Borrowed({\n                let zz: &EvExtPacked = &*(&(*z).data as *const alsa::snd_seq_event_data as *const _);\n                slice::from_raw_parts((*zz).ptr as *mut u8, (*zz).len as usize)\n            }))\n        } else {\n            None\n        };\n        Ok(Event(ptr::read(z), t, ext_data))\n    }\n\n    /// Ensures that the ev.ext union element points to the correct resize_buffer for events\n    /// with variable length content\n    fn ensure_buf(&mut self) {\n        if !Event::has_ext_data(self.1) { return; }\n        let slice: &[u8] = match self.2 {\n            Some(Cow::Owned(ref mut vec)) => &vec[..],\n            Some(Cow::Borrowed(buf)) => buf,\n            // The following case is always a logic error in the program, thus panicking is okay.\n            None => panic!(\"event type requires variable-length data, but none was provided\")\n        };\n        let z: &mut EvExtPacked = unsafe { &mut *(&mut self.0.data as *mut alsa::snd_seq_event_data as *mut _) };\n        z.len = slice.len() as c_uint;\n        z.ptr = slice.as_ptr() as *mut c_void;\n    }\n\n    #[inline]\n    pub fn get_type(&self) -> EventType { self.1 }\n\n    /// Extract the event data from an event.\n    /// Use `get_ext` instead for events carrying variable-length data.\n    pub fn get_data<D: EventData>(&self) -> Option<D> { if D::has_data(self.1) { Some(D::get_data(self)) } else { None } }\n\n    /// Extract the variable-length data carried by events of type `Sysex`, `Bounce`, or the `UsrVar` types.\n    pub fn get_ext(&self) -> Option<&[u8]> {\n        if Event::has_ext_data(self.1) {\n            match self.2 {\n                Some(Cow::Owned(ref vec)) => Some(&vec[..]),\n                Some(Cow::Borrowed(buf)) => Some(buf),\n                // The following case is always a logic error in the program, thus panicking is okay.\n                None => panic!(\"event type requires variable-length data, but none was found\")\n            }\n        } else {\n            None\n        }\n    }\n\n    pub fn set_subs(&mut self) {\n        self.0.dest.client = alsa::SND_SEQ_ADDRESS_SUBSCRIBERS;\n        self.0.dest.port = alsa::SND_SEQ_ADDRESS_UNKNOWN;\n    }\n\n    pub fn set_source(&mut self, p: i32) { self.0.source.port = p as u8 }\n    pub fn set_dest(&mut self, d: Addr) { self.0.dest.client = d.client as c_uchar; self.0.dest.port = d.port as c_uchar; }\n    pub fn set_tag(&mut self, t: u8) { self.0.tag = t as c_uchar;  }\n    pub fn set_queue(&mut self, q: i32) { self.0.queue = q as c_uchar;  }\n\n    pub fn get_source(&self) -> Addr { Addr { client: self.0.source.client as i32, port: self.0.source.port as i32 } }\n    pub fn get_dest(&self) -> Addr { Addr { client: self.0.dest.client as i32, port: self.0.dest.port as i32 } }\n    pub fn get_tag(&self) -> u8 { self.0.tag as u8  }\n    pub fn get_queue(&self) -> i32 { self.0.queue as i32 }\n\n    pub fn schedule_real(&mut self, queue: i32, relative: bool, rtime: time::Duration) {\n        self.0.flags &= !(alsa::SND_SEQ_TIME_STAMP_MASK | alsa::SND_SEQ_TIME_MODE_MASK);\n        self.0.flags |= alsa::SND_SEQ_TIME_STAMP_REAL | (if relative { alsa::SND_SEQ_TIME_MODE_REL } else { alsa::SND_SEQ_TIME_MODE_ABS });\n        self.0.queue = queue as u8;\n        let t = unsafe { &mut self.0.time.time };\n        t.tv_sec = rtime.as_secs() as c_uint;\n        t.tv_nsec = rtime.subsec_nanos() as c_uint;\n    }\n\n    pub fn schedule_tick(&mut self, queue: i32, relative: bool, ttime: u32) {\n        self.0.flags &= !(alsa::SND_SEQ_TIME_STAMP_MASK | alsa::SND_SEQ_TIME_MODE_MASK);\n        self.0.flags |= alsa::SND_SEQ_TIME_STAMP_TICK | (if relative { alsa::SND_SEQ_TIME_MODE_REL } else { alsa::SND_SEQ_TIME_MODE_ABS });\n        self.0.queue = queue as u8;\n        let t = unsafe { &mut self.0.time.tick };\n        *t = ttime as c_uint;\n    }\n\n    pub fn set_direct(&mut self) { self.0.queue = alsa::SND_SEQ_QUEUE_DIRECT }\n\n    pub fn get_relative(&self) -> bool { (self.0.flags & alsa::SND_SEQ_TIME_MODE_REL) != 0 }\n\n    pub fn get_time(&self) -> Option<time::Duration> {\n        if (self.0.flags & alsa::SND_SEQ_TIME_STAMP_REAL) != 0 {\n            let d = self.0.time;\n            let t = unsafe { &d.time };\n            Some(time::Duration::new(t.tv_sec as u64, t.tv_nsec as u32))\n        } else { None }\n    }\n\n    pub fn get_tick(&self) -> Option<u32> {\n        if (self.0.flags & alsa::SND_SEQ_TIME_STAMP_REAL) == 0 {\n            let d = self.0.time;\n            let t = unsafe { &d.tick };\n            Some(*t)\n        } else { None }\n    }\n\n    /// Returns true if the message is high priority.\n    pub fn get_priority(&self) -> bool { (self.0.flags & alsa::SND_SEQ_PRIORITY_HIGH) != 0 }\n\n    pub fn set_priority(&mut self, is_high_prio: bool) {\n        if is_high_prio { self.0.flags |= alsa::SND_SEQ_PRIORITY_HIGH; }\n        else { self.0.flags &= !alsa::SND_SEQ_PRIORITY_HIGH; }\n    }\n}\n\nimpl<'a> Clone for Event<'a> {\n    fn clone(&self) -> Self { Event(unsafe { ptr::read(&self.0) }, self.1, self.2.clone()) }\n}\n\nimpl<'a> fmt::Debug for Event<'a> {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        let mut x = f.debug_tuple(\"Event\");\n        x.field(&self.1);\n        if let Some(z) = self.get_data::<EvNote>() { x.field(&z); }\n        if let Some(z) = self.get_data::<EvCtrl>() { x.field(&z); }\n        if let Some(z) = self.get_data::<Addr>() { x.field(&z); }\n        if let Some(z) = self.get_data::<Connect>() { x.field(&z); }\n        if let Some(z) = self.get_data::<EvQueueControl<()>>() { x.field(&z); }\n        if let Some(z) = self.get_data::<EvQueueControl<i32>>() { x.field(&z); }\n        if let Some(z) = self.get_data::<EvQueueControl<u32>>() { x.field(&z); }\n        if let Some(z) = self.get_data::<EvQueueControl<time::Duration>>() { x.field(&z); }\n        if let Some(z) = self.get_data::<EvResult>() { x.field(&z); }\n        if let Some(z) = self.get_data::<[u8; 12]>() { x.field(&z); }\n        if let Some(z) = self.get_ext() { x.field(&z); }\n        x.finish()\n    }\n}\n\n/// Internal trait implemented for different event type structs (`EvNote`, `EvCtrl`, etc).\n///\n/// Use it through `Event::get_data` and `Event::new`.\npub trait EventData {\n    #[doc(hidden)]\n    fn get_data(ev: &Event) -> Self;\n    #[doc(hidden)]\n    fn has_data(e: EventType) -> bool;\n    #[doc(hidden)]\n    fn set_data(&self, ev: &mut Event);\n}\n\nimpl EventData for () {\n    fn get_data(_: &Event) -> Self {}\n    fn has_data(e: EventType) -> bool {\n         matches!(e,\n             EventType::TuneRequest |\n             EventType::Reset |\n             EventType::Sensing |\n             EventType::None)\n    }\n    fn set_data(&self, _: &mut Event) {}\n}\n\nimpl EventData for [u8; 12] {\n    fn get_data(ev: &Event) -> Self {\n         let d = unsafe { ptr::read(&ev.0.data) };\n         let z = unsafe { &d.raw8 };\n         z.d\n    }\n    fn has_data(e: EventType) -> bool {\n         matches!(e,\n             EventType::Echo |\n             EventType::Oss |\n             EventType::Usr0 |\n             EventType::Usr1 |\n             EventType::Usr2 |\n             EventType::Usr3 |\n             EventType::Usr4 |\n             EventType::Usr5 |\n             EventType::Usr6 |\n             EventType::Usr7 |\n             EventType::Usr8 |\n             EventType::Usr9)\n    }\n    fn set_data(&self, ev: &mut Event) {\n         let z = unsafe { &mut ev.0.data.raw8 };\n         z.d = *self;\n    }\n}\n\n\n#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash, Default)]\npub struct EvNote {\n    pub channel: u8,\n    pub note: u8,\n    pub velocity: u8,\n    pub off_velocity: u8,\n    pub duration: u32,\n}\n\nimpl EventData for EvNote {\n    fn get_data(ev: &Event) -> Self {\n         let z: &alsa::snd_seq_ev_note_t = unsafe { &*(&ev.0.data as *const alsa::snd_seq_event_data as *const _) };\n         EvNote { channel: z.channel as u8, note: z.note as u8, velocity: z.velocity as u8, off_velocity: z.off_velocity as u8, duration: z.duration as u32 }\n    }\n    fn has_data(e: EventType) -> bool {\n         matches!(e,\n             EventType::Note |\n             EventType::Noteon |\n             EventType::Noteoff |\n             EventType::Keypress)\n    }\n    fn set_data(&self, ev: &mut Event) {\n         let z: &mut alsa::snd_seq_ev_note_t = unsafe { &mut *(&mut ev.0.data as *mut alsa::snd_seq_event_data as *mut _) };\n         z.channel = self.channel as c_uchar;\n         z.note = self.note as c_uchar;\n         z.velocity = self.velocity as c_uchar;\n         z.off_velocity = self.off_velocity as c_uchar;\n         z.duration = self.duration as c_uint;\n    }\n}\n\n#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash, Default)]\npub struct EvCtrl {\n    pub channel: u8,\n    pub param: u32,\n    pub value: i32,\n}\n\nimpl EventData for EvCtrl {\n    fn get_data(ev: &Event) -> Self {\n         let z: &alsa::snd_seq_ev_ctrl_t = unsafe { &*(&ev.0.data as *const alsa::snd_seq_event_data as *const _) };\n         EvCtrl { channel: z.channel as u8, param: z.param as u32, value: z.value as i32 }\n    }\n    fn has_data(e: EventType) -> bool {\n         matches!(e,\n             EventType::Controller |\n             EventType::Pgmchange |\n             EventType::Chanpress |\n             EventType::Pitchbend |\n             EventType::Control14 |\n             EventType::Nonregparam |\n             EventType::Regparam |\n             EventType::Songpos |\n             EventType::Songsel |\n             EventType::Qframe |\n             EventType::Timesign |\n             EventType::Keysign)\n    }\n    fn set_data(&self, ev: &mut Event) {\n         let z: &mut alsa::snd_seq_ev_ctrl_t = unsafe { &mut *(&mut ev.0.data as *mut alsa::snd_seq_event_data as *mut _) };\n         z.channel = self.channel as c_uchar;\n         z.param = self.param as c_uint;\n         z.value = self.value as c_int;\n    }\n}\n\nimpl EventData for Addr {\n    fn get_data(ev: &Event) -> Self {\n         let z: &alsa::snd_seq_addr_t = unsafe { &*(&ev.0.data as *const alsa::snd_seq_event_data as *const _) };\n         Addr { client: z.client as i32, port: z.port as i32 }\n    }\n    fn has_data(e: EventType) -> bool {\n         matches!(e,\n             EventType::ClientStart |\n             EventType::ClientExit |\n             EventType::ClientChange |\n             EventType::PortStart |\n             EventType::PortExit |\n             EventType::PortChange)\n    }\n    fn set_data(&self, ev: &mut Event) {\n         let z: &mut alsa::snd_seq_addr_t = unsafe { &mut *(&mut ev.0.data as *mut alsa::snd_seq_event_data as *mut _) };\n         z.client = self.client as c_uchar;\n         z.port = self.port as c_uchar;\n    }\n}\n\n#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash, Default)]\n/// [snd_seq_connect_t](http://www.alsa-project.org/alsa-doc/alsa-lib/structsnd__seq__connect__t.html) wrapper\npub struct Connect {\n    pub sender: Addr,\n    pub dest: Addr,\n}\n\nimpl EventData for Connect {\n    fn get_data(ev: &Event) -> Self {\n         let d = unsafe { ptr::read(&ev.0.data) };\n         let z = unsafe { &d.connect };\n         Connect {\n             sender: Addr { client: z.sender.client as i32, port: z.sender.port as i32 },\n             dest: Addr { client: z.dest.client as i32, port: z.dest.port as i32 }\n         }\n    }\n    fn has_data(e: EventType) -> bool {\n         matches!(e,\n             EventType::PortSubscribed |\n             EventType::PortUnsubscribed)\n    }\n    fn set_data(&self, ev: &mut Event) {\n         let z = unsafe { &mut ev.0.data.connect };\n         z.sender.client = self.sender.client as c_uchar;\n         z.sender.port = self.sender.port as c_uchar;\n         z.dest.client = self.dest.client as c_uchar;\n         z.dest.port = self.dest.port as c_uchar;\n    }\n}\n\n#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash, Default)]\n/// [snd_seq_ev_queue_control_t](http://www.alsa-project.org/alsa-doc/alsa-lib/structsnd__seq__ev__queue__control__t.html) wrapper\n///\n/// Note: This struct is generic, but what types of T are required for the different EvQueueControl messages is\n/// not very well documented in alsa-lib. Right now, Tempo is i32, Tick, SetposTick and SyncPos are u32, SetposTime is time::Duration,\n/// and the rest is (). If I guessed wrong, let me know.\npub struct EvQueueControl<T> {\n    pub queue: i32,\n    pub value: T,\n}\n\nimpl EventData for EvQueueControl<()> {\n    fn get_data(ev: &Event) -> Self {\n         let d = unsafe { ptr::read(&ev.0.data) };\n         let z = unsafe { &d.queue };\n         EvQueueControl { queue: z.queue as i32, value: () }\n    }\n    fn has_data(e: EventType) -> bool {\n         matches!(e,\n             EventType::Start |\n             EventType::Continue |\n             EventType::Stop |\n             EventType::Clock |\n             EventType::QueueSkew)\n    }\n    fn set_data(&self, ev: &mut Event) {\n         let z = unsafe { &mut ev.0.data.queue };\n         z.queue = self.queue as c_uchar;\n    }\n}\n\nimpl EventData for EvQueueControl<i32> {\n    fn get_data(ev: &Event) -> Self { unsafe {\n         let mut d = ptr::read(&ev.0.data);\n         let z = &mut d.queue;\n         EvQueueControl { queue: z.queue as i32, value: z.param.value as i32 }\n    } }\n    fn has_data(e: EventType) -> bool {\n         matches!(e,\n             EventType::Tempo)\n    }\n    fn set_data(&self, ev: &mut Event) { unsafe {\n         let z = &mut ev.0.data.queue;\n         z.queue = self.queue as c_uchar;\n         z.param.value = self.value as c_int;\n    } }\n}\n\nimpl EventData for EvQueueControl<u32> {\n    fn get_data(ev: &Event) -> Self { unsafe {\n         let mut d = ptr::read(&ev.0.data);\n         let z = &mut d.queue;\n         EvQueueControl { queue: z.queue as i32, value: z.param.position as u32 }\n    } }\n    fn has_data(e: EventType) -> bool {\n         matches!(e,\n             EventType::SyncPos |\n             EventType::Tick |\n             EventType::SetposTick)\n    }\n    fn set_data(&self, ev: &mut Event) { unsafe {\n         let z = &mut ev.0.data.queue;\n         z.queue = self.queue as c_uchar;\n         z.param.position = self.value as c_uint;\n    } }\n}\n\nimpl EventData for EvQueueControl<time::Duration> {\n    fn get_data(ev: &Event) -> Self { unsafe {\n         let mut d = ptr::read(&ev.0.data);\n         let z = &mut d.queue;\n         let t = &mut z.param.time.time;\n         EvQueueControl { queue: z.queue as i32, value: time::Duration::new(t.tv_sec as u64, t.tv_nsec as u32) }\n    } }\n    fn has_data(e: EventType) -> bool {\n         matches!(e,\n             EventType::SetposTime)\n    }\n    fn set_data(&self, ev: &mut Event) { unsafe {\n         let z = &mut ev.0.data.queue;\n         z.queue = self.queue as c_uchar;\n         let t = &mut z.param.time.time;\n         t.tv_sec = self.value.as_secs() as c_uint;\n         t.tv_nsec = self.value.subsec_nanos() as c_uint;\n    } }\n}\n\n#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash, Default)]\n/// [snd_seq_result_t](http://www.alsa-project.org/alsa-doc/alsa-lib/structsnd__seq__result__t.html) wrapper\n///\n/// It's called EvResult instead of Result, in order to not be confused with Rust's Result type.\npub struct EvResult {\n    pub event: i32,\n    pub result: i32,\n}\n\nimpl EventData for EvResult {\n    fn get_data(ev: &Event) -> Self {\n         let d = unsafe { ptr::read(&ev.0.data) };\n         let z = unsafe { &d.result };\n         EvResult { event: z.event as i32, result: z.result as i32 }\n    }\n    fn has_data(e: EventType) -> bool {\n         matches!(e,\n             EventType::System |\n             EventType::Result)\n    }\n    fn set_data(&self, ev: &mut Event) {\n         let z = unsafe { &mut ev.0.data.result };\n         z.event = self.event as c_int;\n         z.result = self.result as c_int;\n    }\n}\n\n\n\nalsa_enum!(\n    /// [SND_SEQ_EVENT_xxx](http://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_events.html) constants\n\n    EventType, ALL_EVENT_TYPES[59],\n\n    Bounce = SND_SEQ_EVENT_BOUNCE,\n    Chanpress = SND_SEQ_EVENT_CHANPRESS,\n    ClientChange = SND_SEQ_EVENT_CLIENT_CHANGE,\n    ClientExit = SND_SEQ_EVENT_CLIENT_EXIT,\n    ClientStart = SND_SEQ_EVENT_CLIENT_START,\n    Clock = SND_SEQ_EVENT_CLOCK,\n    Continue = SND_SEQ_EVENT_CONTINUE,\n    Control14 = SND_SEQ_EVENT_CONTROL14,\n    Controller = SND_SEQ_EVENT_CONTROLLER,\n    Echo = SND_SEQ_EVENT_ECHO,\n    Keypress = SND_SEQ_EVENT_KEYPRESS,\n    Keysign = SND_SEQ_EVENT_KEYSIGN,\n    None = SND_SEQ_EVENT_NONE,\n    Nonregparam = SND_SEQ_EVENT_NONREGPARAM,\n    Note = SND_SEQ_EVENT_NOTE,\n    Noteoff = SND_SEQ_EVENT_NOTEOFF,\n    Noteon = SND_SEQ_EVENT_NOTEON,\n    Oss = SND_SEQ_EVENT_OSS,\n    Pgmchange = SND_SEQ_EVENT_PGMCHANGE,\n    Pitchbend = SND_SEQ_EVENT_PITCHBEND,\n    PortChange = SND_SEQ_EVENT_PORT_CHANGE,\n    PortExit = SND_SEQ_EVENT_PORT_EXIT,\n    PortStart = SND_SEQ_EVENT_PORT_START,\n    PortSubscribed = SND_SEQ_EVENT_PORT_SUBSCRIBED,\n    PortUnsubscribed = SND_SEQ_EVENT_PORT_UNSUBSCRIBED,\n    Qframe = SND_SEQ_EVENT_QFRAME,\n    QueueSkew = SND_SEQ_EVENT_QUEUE_SKEW,\n    Regparam = SND_SEQ_EVENT_REGPARAM,\n    Reset = SND_SEQ_EVENT_RESET,\n    Result = SND_SEQ_EVENT_RESULT,\n    Sensing = SND_SEQ_EVENT_SENSING,\n    SetposTick = SND_SEQ_EVENT_SETPOS_TICK,\n    SetposTime = SND_SEQ_EVENT_SETPOS_TIME,\n    Songpos = SND_SEQ_EVENT_SONGPOS,\n    Songsel = SND_SEQ_EVENT_SONGSEL,\n    Start = SND_SEQ_EVENT_START,\n    Stop = SND_SEQ_EVENT_STOP,\n    SyncPos = SND_SEQ_EVENT_SYNC_POS,\n    Sysex = SND_SEQ_EVENT_SYSEX,\n    System = SND_SEQ_EVENT_SYSTEM,\n    Tempo = SND_SEQ_EVENT_TEMPO,\n    Tick = SND_SEQ_EVENT_TICK,\n    Timesign = SND_SEQ_EVENT_TIMESIGN,\n    TuneRequest = SND_SEQ_EVENT_TUNE_REQUEST,\n    Usr0 = SND_SEQ_EVENT_USR0,\n    Usr1 = SND_SEQ_EVENT_USR1,\n    Usr2 = SND_SEQ_EVENT_USR2,\n    Usr3 = SND_SEQ_EVENT_USR3,\n    Usr4 = SND_SEQ_EVENT_USR4,\n    Usr5 = SND_SEQ_EVENT_USR5,\n    Usr6 = SND_SEQ_EVENT_USR6,\n    Usr7 = SND_SEQ_EVENT_USR7,\n    Usr8 = SND_SEQ_EVENT_USR8,\n    Usr9 = SND_SEQ_EVENT_USR9,\n    UsrVar0 = SND_SEQ_EVENT_USR_VAR0,\n    UsrVar1 = SND_SEQ_EVENT_USR_VAR1,\n    UsrVar2 = SND_SEQ_EVENT_USR_VAR2,\n    UsrVar3 = SND_SEQ_EVENT_USR_VAR3,\n    UsrVar4 = SND_SEQ_EVENT_USR_VAR4,\n);\n\n/// [snd_seq_queue_tempo_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_queue.html) wrapper\n#[derive(Debug)]\npub struct QueueTempo(*mut alsa::snd_seq_queue_tempo_t);\n\nunsafe impl Send for QueueTempo {}\n\nimpl Drop for QueueTempo {\n    fn drop(&mut self) { unsafe { alsa::snd_seq_queue_tempo_free(self.0) } }\n}\n\nimpl QueueTempo {\n    fn new() -> Result<Self> {\n        let mut q = ptr::null_mut();\n        acheck!(snd_seq_queue_tempo_malloc(&mut q)).map(|_| QueueTempo(q))\n    }\n\n    /// Creates a new QueueTempo with all fields set to zero.\n    pub fn empty() -> Result<Self> {\n        let q = QueueTempo::new()?;\n        unsafe { ptr::write_bytes(q.0 as *mut u8, 0, alsa::snd_seq_queue_tempo_sizeof()) };\n        Ok(q)\n    }\n\n    pub fn get_queue(&self) -> i32 { unsafe { alsa::snd_seq_queue_tempo_get_queue(self.0) as i32 } }\n    pub fn get_tempo(&self) -> u32 { unsafe { alsa::snd_seq_queue_tempo_get_tempo(self.0) as u32 } }\n    pub fn get_ppq(&self) -> i32 { unsafe { alsa::snd_seq_queue_tempo_get_ppq(self.0) as i32 } }\n    pub fn get_skew(&self) -> u32 { unsafe { alsa::snd_seq_queue_tempo_get_skew(self.0) as u32 } }\n    pub fn get_skew_base(&self) -> u32 { unsafe { alsa::snd_seq_queue_tempo_get_skew_base(self.0) as u32 } }\n\n//    pub fn set_queue(&self, value: i32) { unsafe { alsa::snd_seq_queue_tempo_set_queue(self.0, value as c_int) } }\n    pub fn set_tempo(&self, value: u32) { unsafe { alsa::snd_seq_queue_tempo_set_tempo(self.0, value as c_uint) } }\n    pub fn set_ppq(&self, value: i32) { unsafe { alsa::snd_seq_queue_tempo_set_ppq(self.0, value as c_int) } }\n    pub fn set_skew(&self, value: u32) { unsafe { alsa::snd_seq_queue_tempo_set_skew(self.0, value as c_uint) } }\n    pub fn set_skew_base(&self, value: u32) { unsafe { alsa::snd_seq_queue_tempo_set_skew_base(self.0, value as c_uint) } }\n}\n\n/// [snd_seq_queue_status_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_queue.html) wrapper\n#[derive(Debug)]\npub struct QueueStatus(*mut alsa::snd_seq_queue_status_t);\n\nunsafe impl Send for QueueStatus {}\n\nimpl Drop for QueueStatus {\n    fn drop(&mut self) { unsafe { alsa::snd_seq_queue_status_free(self.0) } }\n}\n\nimpl QueueStatus {\n    fn new() -> Result<Self> {\n        let mut q = ptr::null_mut();\n        acheck!(snd_seq_queue_status_malloc(&mut q)).map(|_| QueueStatus(q))\n    }\n\n    /// Creates a new QueueStatus with all fields set to zero.\n    pub fn empty() -> Result<Self> {\n        let q = QueueStatus::new()?;\n        unsafe { ptr::write_bytes(q.0 as *mut u8, 0, alsa::snd_seq_queue_status_sizeof()) };\n        Ok(q)\n    }\n\n    pub fn get_queue(&self) -> i32 { unsafe { alsa::snd_seq_queue_status_get_queue(self.0) as i32 } }\n    pub fn get_events(&self) -> i32 { unsafe { alsa::snd_seq_queue_status_get_events(self.0) as i32 } }\n    pub fn get_tick_time(&self) -> u32 { unsafe {alsa::snd_seq_queue_status_get_tick_time(self.0) as u32 } }\n    pub fn get_real_time(&self) -> time::Duration { unsafe {\n        let t = &(*alsa::snd_seq_queue_status_get_real_time(self.0));\n        time::Duration::new(t.tv_sec as u64, t.tv_nsec as u32)\n    } }\n    pub fn get_status(&self) -> u32 { unsafe { alsa::snd_seq_queue_status_get_status(self.0) as u32 } }\n}\n\n/// [snd_seq_remove_events_t](https://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_event.html) wrapper\n#[derive(Debug)]\npub struct RemoveEvents(*mut alsa::snd_seq_remove_events_t);\n\nunsafe impl Send for RemoveEvents {}\n\nimpl Drop for RemoveEvents {\n    fn drop(&mut self) { unsafe { alsa::snd_seq_remove_events_free(self.0) } }\n}\n\nimpl RemoveEvents {\n    pub fn new() -> Result<Self> {\n        let mut q = ptr::null_mut();\n        acheck!(snd_seq_remove_events_malloc(&mut q)).map(|_| RemoveEvents(q))\n    }\n\n    pub fn get_condition(&self) -> Remove { unsafe {\n        Remove::from_bits_truncate(alsa::snd_seq_remove_events_get_condition(self.0) as u32)\n    } }\n    pub fn get_queue(&self) -> i32 { unsafe { alsa::snd_seq_remove_events_get_queue(self.0) as i32 } }\n    pub fn get_time(&self) -> time::Duration { unsafe {\n        let d = ptr::read(alsa::snd_seq_remove_events_get_time(self.0));\n        let t = &d.time;\n\n        time::Duration::new(t.tv_sec as u64, t.tv_nsec as u32)\n    } }\n    pub fn get_dest(&self) -> Addr { unsafe {\n        let a = &(*alsa::snd_seq_remove_events_get_dest(self.0));\n\n        Addr { client: a.client as i32, port: a.port as i32 }\n    } }\n    pub fn get_channel(&self) -> i32 { unsafe { alsa::snd_seq_remove_events_get_channel(self.0) as i32 } }\n    pub fn get_event_type(&self) -> Result<EventType> { unsafe {\n        EventType::from_c_int(alsa::snd_seq_remove_events_get_event_type(self.0), \"snd_seq_remove_events_get_event_type\")\n    } }\n    pub fn get_tag(&self) -> u8 { unsafe { alsa::snd_seq_remove_events_get_tag(self.0) as u8 } }\n\n\n    pub fn set_condition(&self, value: Remove) { unsafe {\n        alsa::snd_seq_remove_events_set_condition(self.0, value.bits() as c_uint);\n    } }\n    pub fn set_queue(&self, value: i32) { unsafe { alsa::snd_seq_remove_events_set_queue(self.0, value as c_int) } }\n    pub fn set_time(&self, value: time::Duration) { unsafe {\n        let mut d: alsa::snd_seq_timestamp_t = mem::zeroed();\n        let t = &mut d.time;\n\n        t.tv_sec = value.as_secs() as c_uint;\n        t.tv_nsec = value.subsec_nanos() as c_uint;\n\n        alsa::snd_seq_remove_events_set_time(self.0, &d);\n    } }\n    pub fn set_dest(&self, value: Addr) { unsafe {\n        let a = alsa::snd_seq_addr_t { client: value.client as c_uchar, port: value.port as c_uchar};\n\n        alsa::snd_seq_remove_events_set_dest(self.0, &a);\n    } }\n    pub fn set_channel(&self, value: i32) { unsafe { alsa::snd_seq_remove_events_set_channel(self.0, value as c_int) } }\n    pub fn set_event_type(&self, value: EventType) { unsafe { alsa::snd_seq_remove_events_set_event_type(self.0, value as i32); } }\n    pub fn set_tag(&self, value: u8) { unsafe { alsa::snd_seq_remove_events_set_tag(self.0, value as c_int) } }\n}\n\n/// [snd_midi_event_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___m_i_d_i___event.html) Wrapper\n///\n/// Sequencer event <-> MIDI byte stream coder\n#[derive(Debug)]\npub struct MidiEvent(*mut alsa::snd_midi_event_t);\n\nimpl Drop for MidiEvent {\n    fn drop(&mut self) { unsafe { alsa::snd_midi_event_free(self.0) } }\n}\n\nimpl MidiEvent {\n    pub fn new(bufsize: u32) -> Result<MidiEvent> {\n        let mut q = ptr::null_mut();\n        acheck!(snd_midi_event_new(bufsize as size_t, &mut q)).map(|_| MidiEvent(q))\n    }\n\n    pub fn resize_buffer(&self, bufsize: u32) -> Result<()> { acheck!(snd_midi_event_resize_buffer(self.0, bufsize as size_t)).map(|_| ()) }\n\n    /// Note: this corresponds to snd_midi_event_no_status, but on and off are switched.\n    ///\n    /// Alsa-lib is a bit confusing here. Anyhow, set \"enable\" to true to enable running status.\n    pub fn enable_running_status(&self, enable: bool) { unsafe { alsa::snd_midi_event_no_status(self.0, if enable {0} else {1}) } }\n\n    /// Resets both encoder and decoder\n    pub fn init(&self) { unsafe { alsa::snd_midi_event_init(self.0) } }\n\n    pub fn reset_encode(&self) { unsafe { alsa::snd_midi_event_reset_encode(self.0) } }\n\n    pub fn reset_decode(&self) { unsafe { alsa::snd_midi_event_reset_decode(self.0) } }\n\n    pub fn decode(&self, buf: &mut [u8], ev: &mut Event) -> Result<usize> {\n        ev.ensure_buf();\n        acheck!(snd_midi_event_decode(self.0, buf.as_mut_ptr() as *mut c_uchar, buf.len() as c_long, &ev.0)).map(|r| r as usize)\n    }\n\n    /// In case of success, returns a tuple of (bytes consumed from buf, found Event).\n    pub fn encode<'a>(&'a mut self, buf: &[u8]) -> Result<(usize, Option<Event<'a>>)> {\n        // The ALSA documentation clearly states that the event will be valid as long as the Encoder\n        // is not messed with (because the data pointer for sysex events may point into the Encoder's\n        // buffer). We make this safe by taking self by unique reference and coupling it to\n        // the event's lifetime.\n        let mut ev = unsafe { mem::zeroed() };\n        let r = acheck!(snd_midi_event_encode(self.0, buf.as_ptr() as *const c_uchar, buf.len() as c_long, &mut ev))?;\n        let e = if ev.type_ == alsa::SND_SEQ_EVENT_NONE as u8 {\n                None\n            } else {\n                Some(unsafe { Event::extract(&mut ev, \"snd_midi_event_encode\") }?)\n            };\n        Ok((r as usize, e))\n    }\n}\n\n#[test]\nfn print_seqs() {\n    extern crate std;\n    use ::alloc::ffi::CString;\n    use ::alloc::vec::Vec;\n    let s = super::Seq::open(None, None, false).unwrap();\n    s.set_client_name(&CString::new(\"rust_test_print_seqs\").unwrap()).unwrap();\n    let clients: Vec<_> = ClientIter::new(&s).collect();\n    for a in &clients {\n        let ports: Vec<_> = PortIter::new(&s, a.get_client()).collect();\n        std::println!(\"{:?}: {:?}\", a, ports);\n    }\n}\n\n#[test]\nfn seq_subscribe() {\n    use ::alloc::ffi::CString;\n    let s = super::Seq::open(None, None, false).unwrap();\n    s.set_client_name(&CString::new(\"rust_test_seq_subscribe\").unwrap()).unwrap();\n    let timer_info = s.get_any_port_info(Addr { client: 0, port: 0 }).unwrap();\n    assert_eq!(timer_info.get_name().unwrap(), \"Timer\");\n    let info = PortInfo::empty().unwrap();\n    let _port = s.create_port(&info);\n    let subs = PortSubscribe::empty().unwrap();\n    subs.set_sender(Addr { client: 0, port: 0 });\n    subs.set_dest(Addr { client: s.client_id().unwrap(), port: info.get_port() });\n    s.subscribe_port(&subs).unwrap();\n}\n\n#[test]\nfn seq_loopback() {\n    extern crate std;\n    use ::alloc::ffi::CString;\n    let s = super::Seq::open(Some(&CString::new(\"default\").unwrap()), None, false).unwrap();\n    s.set_client_name(&CString::new(\"rust_test_seq_loopback\").unwrap()).unwrap();\n\n    // Create ports\n    let sinfo = PortInfo::empty().unwrap();\n    sinfo.set_capability(PortCap::READ | PortCap::SUBS_READ);\n    sinfo.set_type(PortType::MIDI_GENERIC | PortType::APPLICATION);\n    s.create_port(&sinfo).unwrap();\n    let sport = sinfo.get_port();\n    let dinfo = PortInfo::empty().unwrap();\n    dinfo.set_capability(PortCap::WRITE | PortCap::SUBS_WRITE);\n    dinfo.set_type(PortType::MIDI_GENERIC | PortType::APPLICATION);\n    s.create_port(&dinfo).unwrap();\n    let dport = dinfo.get_port();\n\n    // Connect them\n    let subs = PortSubscribe::empty().unwrap();\n    subs.set_sender(Addr { client: s.client_id().unwrap(), port: sport });\n    subs.set_dest(Addr { client: s.client_id().unwrap(), port: dport });\n    s.subscribe_port(&subs).unwrap();\n    std::println!(\"Connected {:?} to {:?}\", subs.get_sender(), subs.get_dest());\n\n    // Send a note!\n    let note = EvNote { channel: 0, note: 64, duration: 100, velocity: 100, off_velocity: 64 };\n    let mut e = Event::new(EventType::Noteon, &note);\n    e.set_subs();\n    e.set_direct();\n    e.set_source(sport);\n    std::println!(\"Sending {:?}\", e);\n    s.event_output(&mut e).unwrap();\n    s.drain_output().unwrap();\n\n    // Receive the note!\n    let mut input = s.input();\n    let e2 = input.event_input().unwrap();\n    std::println!(\"Receiving {:?}\", e2);\n    assert_eq!(e2.get_type(), EventType::Noteon);\n    assert_eq!(e2.get_data(), Some(note));\n}\n\n#[test]\nfn seq_encode_sysex() {\n    let mut me = MidiEvent::new(16).unwrap();\n    let sysex = &[0xf0, 1, 2, 3, 4, 5, 6, 7, 0xf7];\n    let (s, ev) = me.encode(sysex).unwrap();\n    assert_eq!(s, 9);\n    let ev = ev.unwrap();\n    let v = ev.get_ext().unwrap();\n    assert_eq!(&*v, sysex);\n}\n\n#[test]\nfn seq_decode_sysex() {\n    let sysex = [0xf0, 1, 2, 3, 4, 5, 6, 7, 0xf7];\n    let mut ev = Event::new_ext(EventType::Sysex, &sysex[..]);\n    let me = MidiEvent::new(0).unwrap();\n    let mut buffer = ::alloc::vec![0; sysex.len()];\n    assert_eq!(me.decode(&mut buffer[..], &mut ev).unwrap(), sysex.len());\n    assert_eq!(buffer, sysex);\n}\n\n#[test]\n#[should_panic]\nfn seq_get_input_twice() {\n    use ::alloc::ffi::CString;\n    let s = super::Seq::open(None, None, false).unwrap();\n    s.set_client_name(&CString::new(\"rust_test_seq_get_input_twice\").unwrap()).unwrap();\n    let input1 = s.input();\n    let input2 = s.input(); // this should panic\n    let _ = (input1, input2);\n}\n\n#[test]\nfn seq_has_data() {\n    for v in EventType::all() {\n        let v = *v;\n        let mut i = 0;\n        if <() as EventData>::has_data(v) { i += 1; }\n        if <[u8; 12] as EventData>::has_data(v) { i += 1; }\n        if Event::has_ext_data(v) { i += 1; }\n        if EvNote::has_data(v) { i += 1; }\n        if EvCtrl::has_data(v) { i += 1; }\n        if Addr::has_data(v) { i += 1; }\n        if Connect::has_data(v) { i += 1; }\n        if EvResult::has_data(v) { i += 1; }\n        if EvQueueControl::<()>::has_data(v) { i += 1; }\n        if EvQueueControl::<u32>::has_data(v) { i += 1; }\n        if EvQueueControl::<i32>::has_data(v) { i += 1; }\n        if EvQueueControl::<time::Duration>::has_data(v) { i += 1; }\n        if i != 1 { panic!(\"{:?}: {} has_data\", v, i) }\n    }\n}\n\n#[test]\nfn seq_remove_events() -> core::result::Result<(), Box<dyn core::error::Error>> {\n    let info = RemoveEvents::new()?;\n\n\n    info.set_condition(Remove::INPUT | Remove::DEST | Remove::TIME_BEFORE | Remove::TAG_MATCH);\n    info.set_queue(123);\n    info.set_time(time::Duration::new(456, 789));\n    info.set_dest(Addr { client: 212, port: 121 });\n    info.set_channel(15);\n    info.set_event_type(EventType::Noteon);\n    info.set_tag(213);\n\n    assert_eq!(info.get_condition(), Remove::INPUT | Remove::DEST | Remove::TIME_BEFORE | Remove::TAG_MATCH);\n    assert_eq!(info.get_queue(), 123);\n    assert_eq!(info.get_time(), time::Duration::new(456, 789));\n    assert_eq!(info.get_dest(), Addr { client: 212, port: 121 });\n    assert_eq!(info.get_channel(), 15);\n    assert_eq!(info.get_event_type()?, EventType::Noteon);\n    assert_eq!(info.get_tag(), 213);\n\n    Ok(())\n}\n\n#[test]\nfn seq_portsubscribeiter() {\n    use ::alloc::vec::Vec;\n\n    let s = super::Seq::open(None, None, false).unwrap();\n\n    // Create ports\n    let sinfo = PortInfo::empty().unwrap();\n    sinfo.set_capability(PortCap::READ | PortCap::SUBS_READ);\n    sinfo.set_type(PortType::MIDI_GENERIC | PortType::APPLICATION);\n    s.create_port(&sinfo).unwrap();\n    let sport = sinfo.get_port();\n    let dinfo = PortInfo::empty().unwrap();\n    dinfo.set_capability(PortCap::WRITE | PortCap::SUBS_WRITE);\n    dinfo.set_type(PortType::MIDI_GENERIC | PortType::APPLICATION);\n    s.create_port(&dinfo).unwrap();\n    let dport = dinfo.get_port();\n\n    // Connect them\n    let subs = PortSubscribe::empty().unwrap();\n    subs.set_sender(Addr { client: s.client_id().unwrap(), port: sport });\n    subs.set_dest(Addr { client: s.client_id().unwrap(), port: dport });\n    s.subscribe_port(&subs).unwrap();\n\n    // Query READ subs from sport's point of view\n    let read_subs: Vec<PortSubscribe> = PortSubscribeIter::new(&s,\n                        Addr {client: s.client_id().unwrap(), port: sport },\n                        QuerySubsType::READ).collect();\n    assert_eq!(read_subs.len(), 1);\n    assert_eq!(read_subs[0].get_sender(), subs.get_sender());\n    assert_eq!(read_subs[0].get_dest(), subs.get_dest());\n\n    let write_subs: Vec<PortSubscribe> = PortSubscribeIter::new(&s,\n                        Addr {client: s.client_id().unwrap(), port: sport },\n                        QuerySubsType::WRITE).collect();\n    assert_eq!(write_subs.len(), 0);\n\n    // Now query WRITE subs from dport's point of view\n    let write_subs: Vec<PortSubscribe> = PortSubscribeIter::new(&s,\n                        Addr {client: s.client_id().unwrap(), port: dport },\n                        QuerySubsType::WRITE).collect();\n    assert_eq!(write_subs.len(), 1);\n    assert_eq!(write_subs[0].get_sender(), subs.get_sender());\n    assert_eq!(write_subs[0].get_dest(), subs.get_dest());\n}\n"
  },
  {
    "path": "synth-example/Cargo.toml",
    "content": "[package]\nname = \"synth-example\"\nversion = \"0.1.0\"\nauthors = [\"David Henningsson <coding@diwic.se>\"]\nedition = \"2021\"\n\n[dependencies]\ndasp = { version = \"0.11\", features = [\"signal\"] }\nalsa = { path = \"..\", version = \"0.11\" }\n"
  },
  {
    "path": "synth-example/src/main.rs",
    "content": "// A quickly made Hammond organ.\n\nuse std::{iter, error};\nuse alsa::{seq, pcm};\nuse std::ffi::CString;\nuse dasp::signal;\n\ntype Res<T> = Result<T, Box<dyn error::Error>>;\n\nfn connect_midi_source_ports(s: &alsa::Seq, our_port: i32) -> Res<()> {\n    // Iterate over clients and clients' ports\n    let our_id = s.client_id()?;\n    let ci = seq::ClientIter::new(&s);\n    for client in ci {\n        if client.get_client() == our_id { continue; } // Skip ourselves\n        let pi = seq::PortIter::new(&s, client.get_client());\n        for port in pi {\n            let caps = port.get_capability();\n\n            // Check that it's a normal input port\n            if !caps.contains(seq::PortCap::READ) || !caps.contains(seq::PortCap::SUBS_READ) { continue; }\n            if !port.get_type().contains(seq::PortType::MIDI_GENERIC) { continue; }\n\n            // Connect source and dest ports\n            let subs = seq::PortSubscribe::empty()?;\n            subs.set_sender(seq::Addr { client: port.get_client(), port: port.get_port() });\n            subs.set_dest(seq::Addr { client: our_id, port: our_port });\n            println!(\"Reading from midi input {:?}\", port);\n            s.subscribe_port(&subs)?;\n        }\n    }\n\n    Ok(())\n}\n\nfn open_midi_dev() -> Res<alsa::Seq> {\n    // Open the sequencer.\n    let s = alsa::Seq::open(None, Some(alsa::Direction::Capture), true)?;\n    let cstr = CString::new(\"rust_synth_example\").unwrap();\n    s.set_client_name(&cstr)?;\n\n    // Create a destination port we can read from\n    let mut dinfo = seq::PortInfo::empty().unwrap();\n    dinfo.set_capability(seq::PortCap::WRITE | seq::PortCap::SUBS_WRITE);\n    dinfo.set_type(seq::PortType::MIDI_GENERIC | seq::PortType::APPLICATION);\n    dinfo.set_name(&cstr);\n    s.create_port(&dinfo).unwrap();\n    let dport = dinfo.get_port();\n\n    // source ports should ideally be configurable, but right now we're just reading them all.\n    connect_midi_source_ports(&s, dport)?;\n\n    Ok(s)\n}\n\nfn open_audio_dev() -> Res<(alsa::PCM, u32)> {\n    let args: Vec<_> = std::env::args().collect();\n    if args.len() < 2 {\n        println!(\"Usage: 'cargo run --release CARD_NAME SAMPLE_RATE BUF_SIZE'\");\n        Err(\"No card name specified\")?\n    }\n    let req_devname = format!(\"hw:{}\", args[1]);\n    let req_samplerate = args.get(2).map(|x| x.parse()).unwrap_or(Ok(48000))?;\n    let req_bufsize = args.get(3).map(|x| x.parse()).unwrap_or(Ok(256))?; // A few ms latency by default, that should be nice\n\n    // Open the device\n    let p = alsa::PCM::new(&req_devname, alsa::Direction::Playback, false)?;\n\n    // Set hardware parameters\n    {\n        let hwp = pcm::HwParams::any(&p)?;\n        hwp.set_channels(2)?;\n        hwp.set_rate(req_samplerate, alsa::ValueOr::Nearest)?;\n        hwp.set_format(pcm::Format::s16())?;\n        hwp.set_access(pcm::Access::MMapInterleaved)?;\n        hwp.set_buffer_size(req_bufsize)?;\n        hwp.set_period_size(req_bufsize / 4, alsa::ValueOr::Nearest)?;\n        p.hw_params(&hwp)?;\n    }\n\n    // Set software parameters\n    let rate = {\n        let hwp = p.hw_params_current()?;\n        let swp = p.sw_params_current()?;\n        let (bufsize, periodsize) = (hwp.get_buffer_size()?, hwp.get_period_size()?);\n        swp.set_start_threshold(bufsize - periodsize)?;\n        swp.set_avail_min(periodsize)?;\n        p.sw_params(&swp)?;\n        println!(\"Opened audio output {:?} with parameters: {:?}, {:?}\", req_devname, hwp, swp);\n        hwp.get_rate()?\n    };\n\n    Ok((p, rate))\n}\n\n// Sample format\ntype SF = i16;\n\ntype SigGen = signal::Sine<signal::ConstHz>;\n\n// Standard Hammond drawbar.\nconst BAR_FREQS: [f64; 9] = [16., 5.+1./3., 8., 4., 2.+2./3., 2., 1.+3./5., 1.+1./3., 1.];\n\n#[derive(Clone)]\nstruct Sig {\n    note: u8,\n    sig: SigGen,\n    targetvol: f64,\n    curvol: f64,\n    baridx: usize,\n}\n\n\nstruct Synth {\n    sigs: Vec<Option<Sig>>,\n    sample_rate: signal::Rate,\n    stored_sample: Option<SF>,\n    bar_values: [f64; 9],\n}\n\nimpl Synth {\n    fn add_note(&mut self, note: u8, vol: f64) {\n        let hz = 440. * 2_f64.powf((note as f64 - 69.)/12.);\n\n        for (baridx, barfreq) in BAR_FREQS.iter().enumerate() {\n            let idx = self.sigs.iter().position(|s| s.is_none());\n            let idx = if let Some(idx) = idx { idx } else {\n                println!(\"Voice overflow!\"); return;\n            };\n            let hz = self.sample_rate.const_hz(hz * 8. / barfreq);\n            let s = Sig { sig: hz.sine(), note, targetvol: vol, curvol: 0., baridx };\n            self.sigs[idx] = Some(s);\n        }\n    }\n    fn remove_note(&mut self, note: u8) {\n        for i in self.sigs.iter_mut() {\n            if let &mut Some(ref mut i) = i {\n                if i.note == note { i.targetvol = 0. }\n            }\n        }\n    }\n    fn cc(&mut self, ctrl: u32, value: i32) {\n        let idx = match ctrl {\n            // Standard knobs on UMA25S, modify to your liking\n            1 => 0,\n            74 => 1,\n            71 => 2,\n            73 => 3,\n            75 => 4,\n            72 => 5,\n            91 => 6,\n            93 => 7,\n            10 => 8,\n            _ => return,\n        };\n        self.bar_values[idx] = f64::from(value) / 255.;\n    }\n}\n\nimpl Iterator for Synth {\n    type Item = SF;\n    fn next(&mut self) -> Option<Self::Item> {\n        use dasp::{signal::Signal, Sample};\n\n        // Mono -> Stereo\n        if let Some(s) = self.stored_sample.take() { return Some(s) };\n\n        let mut z = 0f64;\n        for sig in &mut self.sigs {\n            let mut remove = false;\n            if let &mut Some(ref mut i) = sig {\n                let barvalue = self.bar_values[i.baridx];\n                if barvalue > 0.0 {\n                    let s = i.sig.next();\n                    z += s.mul_amp(i.curvol * barvalue);\n                }\n\n                // Quick and dirty volume envelope to avoid clicks.\n                if i.curvol != i.targetvol {\n                    if i.targetvol == 0. {\n                        i.curvol -= 0.002;\n                        if i.curvol <= 0. { remove = true; }\n                    } else {\n                        i.curvol += 0.002;\n                        if i.curvol >= i.targetvol { i.curvol = i.targetvol; }\n                    }\n                }\n            }\n            if remove { *sig = None };\n        }\n        let z = z.min(0.999).max(-0.999);\n        let z: Option<SF> = Some(SF::from_sample(z));\n        self.stored_sample = z;\n        z\n    }\n}\n\nfn write_samples_direct(p: &alsa::PCM, mmap: &mut alsa::direct::pcm::MmapPlayback<SF>, synth: &mut Synth)\n    -> Res<bool> {\n\n    if mmap.avail() > 0 {\n        // Write samples to DMA area from iterator\n        mmap.write(synth);\n    }\n    use alsa::pcm::State;\n    match mmap.status().state() {\n        State::Running => { return Ok(false); }, // All fine\n        State::Prepared => { println!(\"Starting audio output stream\"); p.start()? },\n        State::XRun => { println!(\"Underrun in audio output stream!\"); p.prepare()? },\n        State::Suspended => { println!(\"Resuming audio output stream\"); p.resume()? },\n        n @ _ => Err(format!(\"Unexpected pcm state {:?}\", n))?,\n    }\n    Ok(true) // Call us again, please, there might be more data to write\n}\n\nfn write_samples_io(p: &alsa::PCM, io: &mut alsa::pcm::IO<SF>, synth: &mut Synth) -> Res<bool> {\n    let avail = match p.avail_update() {\n        Ok(n) => n,\n        Err(e) => {\n            println!(\"Recovering from {}\", e);\n            p.recover(e.errno() as std::os::raw::c_int, true)?;\n            p.avail_update()?\n        }\n    } as usize;\n\n    if avail > 0 {\n        io.mmap(avail, |buf| {\n            for sample in buf.iter_mut() {\n                *sample = synth.next().unwrap()\n            };\n            buf.len() / 2\n        })?;\n    }\n    use alsa::pcm::State;\n    match p.state() {\n        State::Running => Ok(false), // All fine\n        State::Prepared => { println!(\"Starting audio output stream\"); p.start()?; Ok(true) },\n        State::Suspended | State::XRun => Ok(true), // Recover from this in next round\n        n @ _ => Err(format!(\"Unexpected pcm state {:?}\", n))?,\n    }\n}\n\nfn read_midi_event(input: &mut seq::Input, synth: &mut Synth) -> Res<bool> {\n    if input.event_input_pending(true)? == 0 { return Ok(false); }\n    let ev = input.event_input()?;\n    // println!(\"Received: {:?}\", ev);\n    match ev.get_type() {\n        seq::EventType::Noteon => {\n            let data: seq::EvNote = ev.get_data().unwrap();\n            if data.velocity == 0 {\n                synth.remove_note(data.note);\n            } else {\n                synth.add_note(data.note, f64::from(data.velocity + 64) / 2048.);\n            }\n        },\n        seq::EventType::Noteoff => {\n            let data: seq::EvNote = ev.get_data().unwrap();\n            synth.remove_note(data.note);\n        },\n        seq::EventType::Controller => {\n            let data: seq::EvCtrl = ev.get_data().unwrap();\n            synth.cc(data.param, data.value);\n        }\n        _ => {},\n    }\n    Ok(true)\n}\n\n\nfn run() -> Res<()> {\n    let (audio_dev, rate) = open_audio_dev()?;\n    let midi_dev = open_midi_dev()?;\n\n    let mut midi_input = midi_dev.input();\n\n    // 256 Voices synth\n    let mut synth = Synth {\n        sigs: iter::repeat(None).take(256).collect(),\n        sample_rate: signal::rate(f64::from(rate)),\n        stored_sample: None,\n        bar_values: [1., 0.75, 1., 0.75, 0., 0., 0., 0., 0.75], // Some Gospel-ish default.\n    };\n\n    // Create an array of fds to poll.\n    use alsa::PollDescriptors;\n    let mut fds = audio_dev.get()?;\n    fds.append(&mut (&midi_dev, Some(alsa::Direction::Capture)).get()?);\n\n    // Let's use the fancy new \"direct mode\" for minimum overhead!\n    let mut mmap = audio_dev.direct_mmap_playback::<SF>();\n\n    // Direct mode unavailable, use alsa-lib's mmap emulation instead\n    let mut io = if mmap.is_err() {\n        Some(audio_dev.io_i16()?)\n    } else { None };\n\n    loop {\n        if let Ok(ref mut mmap) = mmap {\n            if write_samples_direct(&audio_dev, mmap, &mut synth)? { continue; }\n        } else if let Some(ref mut io) = io {\n            if write_samples_io(&audio_dev, io, &mut synth)? { continue; }\n        }\n        if read_midi_event(&mut midi_input, &mut synth)? { continue; }\n        // Nothing to do, let's sleep until woken up by the kernel.\n        alsa::poll::poll(&mut fds, 100)?;\n    }\n}\n\nfn main() {\n    if let Err(e) = run() { println!(\"Error: {}\", e); }\n}\n"
  }
]