Posts by Schatten-Nacht

    Zu meinem Smartphone Setup ich nutze liebend gerne mein Oldskool Smartphone ein SAMSUNG Galaxy S7.


    Zu den einzelnen Audio-Codecs mit Bluetooth:

    "aptX Lossless, CD-quality wireless connection

    The latest member of Qualcomm's codec family, it is specifically designed for audiophile use, with a bandwidth of 1mbps sufficient to guarantee the transmission of CD-quality files, i.e. 1411Kpbs with a very low level of compression. However, very few devices on the market today are compatible with this codec."

    Ich bezweifle stark das ein 1 Dollar Audio-Codec SAC (Signal Audio Codec) so eine Streaming-Qualität hinbekommt das wäre ja schon eine SACD (Super Audio-CD (4,7GB) was die Abtastraten angeht von 1411kbit/s !

    Direct Stream Digital

    SACD audio is stored in Direct Stream Digital (DSD) format using pulse-density modulation (PDM), where audio amplitude is determined by the varying proportion of 1s and 0s. This contrasts with compact disc and conventional computer audio systems using pulse-code modulation (PCM,) where audio amplitude is determined by numbers encoded in the bit stream. Both modulations require neighboring samples to reconstruct the original waveform; the more neighboring samples, the lower the frequency that can be encoded.

    DSD is 1-bit, has a sampling rate of 2.8224 MHz, and makes use of noise shaping quantization techniques in order to push 1-bit quantization noise up to inaudible ultrasonic frequencies. This gives the format a greater dynamic range and wider frequency response than the CD. The SACD format is capable of delivering a dynamic range of 120 dB from 20 Hz to 20 kHz and an extended frequency response up to 100 kHz, although most available players list an upper limit of 70–90 kHz and practical limits reduce this to 50 kHz.

    Because of the nature of sigma-delta converters, DSD and PCM cannot be directly compared. DSD's frequency response can be as high as 100 kHz, but frequencies that high compete with high levels of ultrasonic quantization noise.[18] With appropriate low-pass filtering, a frequency response of 20 kHz can be achieved along with a dynamic range of nearly 120 dB, which is about the same dynamic range as PCM audio with a resolution of 20 bits.

    Direct Stream Transfer

    To reduce the space and bandwidth requirements of DSD, a lossless data compression method called Direct Stream Transfer (DST) is used. DST compression is compulsory for multi-channel regions and optional for stereo regions. It typically compresses by a factor of between two and three, allowing a disc to contain 80 minutes of both 2-channel and 5.1-channel sound.

    Direct Stream Transfer compression was standardized as an amendment to the MPEG-4 Audio standard, ISO/IEC 14496-3:2001/Amd 6:2005 (Lossless coding of oversampled audio), in 2005.

    It contains the DSD and DST definitions as described in the Super Audio CD Specification.The MPEG-4 DST provides lossless coding of oversampled audio signals. Target applications of DST are archiving and storage of 1-bit oversampled audio signals and SA-CD.

    Zu den Bluetooth-Audio-Codec:


    Wer etwas mehr mit den A2DP -APIs herumspielen will der kann sich ja mal diese Webseite ansehen:

    https://wiki.debian.org/BluetoothUser/a2dp 👍🏼

    SBC codec

    The SBC codec mandatory for A2DP is often described as having poor quality. Actually it allows wide range of parameters* and with recommended High Quality settings (e.g. Joint Stereo with 48 kHz sampling rate and 51 bitpool value has 345 kb/s bit rate) should not be significantly worse than other codecs. Some devices have significantly lower limit for bitbool value that causes degraded quality. In the case of unreliable connection (weak signal, interference with other Bluetooth, WiFi, and USB devices) communicating devices may negotiate to to lower bitpool value. Another reason for perceptible difference with other codecs might be different equalizer presets.

    Unfortunately PipeWire and PulseAudio do not expose supported and actually used codec settings. There are no diagnostic tools that may query a device. The only way is to capture Bluetooth traffic and to find packets with codec settings. Either hcidump or wireshark/tshark (dumpcap -i bluetooth0) may be used. An example of hcidump capture:

    Maximum bitbool value allows SBC HQ settings.

    SBC-XQ* is a kind of trick to overcome maximum bitbool limit imposed by devices. It uses Dual Channel instead of Joint Stereo mode, so bitpool value should be doubled. An example of packet decoded by tshark (wrapped):

    Code
    165   5.296488 localhost () → <Vendor_aa:bb:cc> (<HeadPhones Model>) AVDTP 25 Sent Command - SetConfiguration
     - ACP SEID [1 - Audio Sink] - INT SEID [11 - unknown unknown]
     - Audio SBC (48000 | DualChannel | block: 16 | subbands: 8 | allocation: Loudness
       | bitpool: 2..39)


    Und wer sich etwas mit SBC (Subband Codec) zu Bluetooth A2DP beschäftigen will ist hier richtig:

    GitHub - google/libsbc
    Contribute to google/libsbc development by creating an account on GitHub.
    github.com

    Ich hänge das Subband Wiki zu Bluetooth mit allen Siganl-Bits als PDF-Link noch mit dran.

    Das nennt sich "Hands Free Profile

    https://www.bluetooth.org/DocMan/handlers/DownloadDoc.ashx?doc_id=489628


    LG von Schatten-Nacht 🖐🏼

    Noch ein kleiner Nachtrag zu deiner Aussage am 13. März 2025  algl

    "Nahezu jeder RTL*-Audiochip, der heute auf Mainboards verbaut wird, ist seit gut 10 Jahren über Zweifel, die ein PC-Audio-Genießer haben könnte, erhaben.

    Übertragungsverluste, die ich meine, entstehen aufgrund von alten, leistungsschwachen BT-Protokollen wie HFP, HSP oder SBC über A2DP. Die BT-Hardware sollte für eine gute Qualität heute wenigstens AAC, aptX und aptX-HD bieten (auf beiden Seiten)."


    Diese Antwort verstehe ich gar nicht wieso sollte ein 0,15 Dollar Cent RealTek-Audio-Chip erhaben sein in seiner Funktion?


    Question - RealTek chipsets for music recording
    I am looking to get a new Windows PC for DIY home music recording and I am wondering what the good, the bad, and the ugly of RealTek chipsets are. In my…
    forums.tomshardware.com

    "28. Mai 2025The Realtek DACs (codecs) on the motherboard are OK for general purpose work, but they're not quite up to serious studio work. A huge amount depends on how demanding you are about audio quality!"


    Hier mal ein kurzer Auszug von "IgorsLab" zu RTL-Audio Chips

    Realtek ALC1200 entmystifiziert - was den Einsteiger-Sound-Chip vom größeren ALC1220 wirklich unterscheidet und was beim ALC4080 passiert | Update | igor´sLAB
    Heute möchte ich um Update auf ein Detail eingehen, das in der Praxis oft übersehen wird, obwohl es entscheidend für die richtige Einordnung von Messwerten und…
    www.igorslab.de

    "Realtek ALC1200 entmystifiziert – was den Einsteiger-Sound-Chip vom größeren ALC1220 wirklich unterscheidet und was beim ALC4080 passiert | Update"

    Heute möchte ich um Update auf ein Detail eingehen, das in der Praxis oft übersehen wird, obwohl es entscheidend für die richtige Einordnung von Messwerten und Herstellerangaben ist. Gemeint ist die Unterscheidung zwischen Front-Header und Front-Audio. Während der Front-Header den internen Pfostenstecker auf dem Mainboard bezeichnet, über den das Kabel des Gehäuses angeschlossen wird, versteht man unter Front-Audio die tatsächlich erreichbaren Buchsen am Gehäuse selbst. Erst durch diese Verbindung gelangt das vom Codec bereitgestellte Signal – meist Port-D beim Realtek ALC1200 oder ALC1220 – vom Mainboard nach außen. Genau dieser Unterschied ist wichtig, wenn das Marketing der Hersteller den „Front-Kopfhörerverstärker“ hervorheben, denn in Wahrheit handelt es sich um den internen Port-D, der über den Header zum Gehäuse geführt wird. Oder manchmal leider auch nicht. Aber das lest Ihr gleich.

    Originalartikel vom 20.08.2020

    Man findet den Realtek ALC1200 sehr oft auf Einsteiger- und Mittelklasse-Motherboards und es ist, wenn man einmal googelt oder die Schwarmintelligenz der einschlägigen Foren interpretiert, auch eine erschreckende Menge Halb- und Unwissen im Umlauf. Die einen schreiben von einem hochgelabelten ALC887, die anderen von einem nur leicht abgespeckten ALC1220. Und das einzig Richtige ist: beides ist schon einmal komplett falsch. Der größere und hochwertigere ALC1220 (2017) ist sogar älter, der ALC1200 kam nämlich erst ein Jahr später (2018) und ein komplett anderer Chip.

    Mit einem alten ALC887 kann man jedoch auch den ALC1200 nicht vergleichen, das wäre arg unfair. Das Package des ALC1220 ist übrigens nicht zufällig größer, denn die Funktionalität ist es auch. Trotzdem ist der ALC1200 kein Schund. Ich habe mir auf dem kleinen Dienstweg von einem Boardhersteller auch die Datenblätter besorgen können, die Realtek leider noch unter Verschluss hält. Ich hoffe zumindest, mit dem heutigen Artikel mal die eine oder andere Urban Legend zerstören zu können.


    RTL ALC1200 Blockdiagramm und Verschaltung des ICs.


    Wenn ich mir da den PCM und deren PCM-Gate ansehe auf dem Blockdiagramm da grusselt es mich 192Khz was Resampling angeht und das noch 24 Bit Floating-Point <- wobei Point genau der Knackpunkt ist bei so einer hohen Sampling-Rate fängt das Rauschen erst richtig an.

    ALC1200 Datasheet, PDF
    ALC1200 Datasheet. Part #: ALC12. Datasheet: 5MbKb/66P. Manufacturer: Kemet Corporation. Description: Aluminum Electrolytic Capacitors. 2 Results. Datasheet:…
    www.alldatasheet.net

    REALTEK - ALC1200


    Billig bleibt nun mal billig gerade auf Mainboards was Audio Zirpern wie RealTek angeht!

    Audio Roundup - Audio Chipsets im Vergleich Realtek ALC883, ALC888


    Jetzt zum der Thematik zu Bluetooth Protokolle A2DP,SAC und deiner Aussage zu den Übertragungsverlusten das verstehe ich auch nicht was du mit "Übertragungsverlusten damit meinst Bitte um "Erklärung" von Übertragungsverlusten <- das Wort ist zu allgemein weil alle hat Verluste nicht nur Signal die via Funkwellen was Bluetooth angeht sonder auch Kupfer, Silber, Silizium usw.


    BLUETOOTH SPECIFICATION

    Advanced Audio Distribution Profile (A2DP)

    Figure 4.3 shows the media payload header format and Bits of SBC.
    [7 6 5 4 3 2 1 0]
    F S L RFA Number of frames Octet0
    Figure 4.3: Header format of media payload for SBC
    - F bit – Set to 1 if the SBC Bit-frame is fragmented, otherwise set to 0.
    - S bit – Set to 1 for the starting packet of a fragmented SBC Bit-frame, otherwise set to 0 <- Zero Bit.
    - L bit – Set to 1 for the last packet of a fragmented SBC frame, otherwise set to 0

    RFA - Number of frames (4 bits) – If the F bit is set to 0, this field indicates the number of
    frames contained in this packet. If the F bit is set to 1, this field indicates the number
    of remaining fragments, including the current fragment. Thus the last counter value
    shall be one. For example, if there are three fragments then the counter has value 3,
    2 and 1 for subsequent fragments. This field is expressed by 4 bit UiMsbf.


    BLUETOOTH SPECIFICATION
    Advanced Audio Distribution Profile (A2DP)

    For the encoder of the SRC, it is required to support at least one possible bitpool value.
    However, it is recommended for the encoder to support the following settings.


    ------------------------------------SBC encoder settings------------------------------------------------------------------------------------
    |-------------------Middle Quality---------------------High Quality-----------------|

    -----------------------------------------|------ Mono----- |-------Stereo------ |--Joint Stereo-- |--- Joint Mono-- ------------
    Sampling frequency (kHz)|44.1, 48, 86, 96 |44.1, 48, 86, 96 |44.1, 48, 86, 96|44.1, 48, 86, 96 |

    ----------------------------------------------Bitpool value 19 18 35 33 31 29 53 51------------------------------------------------

    -----------------------------------------------------green is an header-Bit length by bytes----------------------------------------
    ----------------------------------Resulting frame length (bytes) 46 44 83 79 70 66 119 115--------------------------------
    ----------------------------------Resulting bit rate (kb/s) 127 132 229 237 193 198 328 345-------------------------------

    -------------------------------------------------red is an resolution frame per byte------------------------------------------------
    Other settings: Block length = 16, Allocation method = Loudness, Subbands = 8

    Recommended sets of SBC parameters in the SRC device
    Note again that the frame length shown in this table is variable according to the bitpool
    value. For the most efficient use of the transport in L2CAP, the frame length may be
    adjusted when media payload is constructed. For creation of media payload format
    using SBC frames.

    Media Packet Header Requirements and Timestamp (TS)
    The clock frequency necessary to create TS shall be set to the sample rate of the
    encoded audio data. If a media payload consists of multiple SBC frames, the TS of the media packet header represent the TS of the first SBC frame. The TS of the following SBC frames shall be
    calculated using the sample rate and the number of samples per frame per channel.
    When a SBC frame is fragmented into multiple media packets, all packets that make up
    a fragmented SBC frame shall use the same TS.

    Payload Type (PT)
    A payload type in the dynamic range shall be chosen.

    Marker (M) bit and Extension (X) bit
    Set to zero.

    Not used, set to zero.

    Media Payload Format
    The media payload for SBC consists of SBC specific header and
    SBC frame(s) defined in the SBC specification.
    If the configured MTU size for the transport channel is greater or equal to the SBC
    frame size + the sum of [Media Payload header size, Content Protection header size (if
    Content Protection is selected), Media Packet header size], then a media payload shall
    contain an integral number of complete SBC frames (a).


    BLUETOOTH SPECIFICATION

    Advanced Audio Distribution Profile (A2DP)

    If this is not the case, and provided that the multiplexing service of AVDTP is not
    selected, the SBC frame shall be fragmented across several media payloads (b). All
    fragmented packets, except the last one, shall have the same total data packet size. A
    media payload always starts with an 8-bit header, which is placed before the SBC data.
    If the multiplexing service of AVDTP is selected, then it is recommended not to fragment
    the SBC frame across several media payloads, because AVDTP shall fragment the
    media payloads across several L2CAP packets if necessary.

    (a) When the media payload contains an integral number of SBC frames

    --------------------------------------------------------------------------------------------------------------------------------------------------------

    SBC frameHeader | First fragment of SBC frame Header |

    Resulting bit rate (kb/s) | 127 132 229 237 193 198 328 345 |

    --------------------------------------------------------------------------------------------------------------------------------------------------------
    (b) When the SBC frame is fragmented

    SBC frame Header Resulting frame length (bytes) 46 44 83 79 70 66 119 115

    Und ja der IC (Chip und der Signal-Prozessor) sind was die Übertragung und deren Signallänge also Meter per (a) Smartphone to (b) Reciever Bluetooth-Anlage oder Bluetooth Soundbar entscheiden auf beiden Wegen einmal der MUX also Muxer (Mischer innerhalb der Soundbar oder der Bluetooth-Anlage was diesen IC also Bluetooth-chip angeht deswegen gibt es trotzdem nicht gleich wenn man nur 5 Meter vor der Bluetooth-Anlage steht kein CRC-Header SRC Frame Bit Verlust das stimmt so einfach nicht zu deiner Aussage algl die Verluste entstehen wenn die Räume stark viel Stahlbeton aufweisen dann können SRC-Frame Bits verloren gehen und der CRC-Header muss dann dem Signal Bit Keyframe mitteilen das das Audio_material weiter heruntergrechnet werden soll damit die Bluetooth Verbindung also die SSID-Adresse in der Bluetooth Zelle nicht verworfen wird dann wäre die Verbindung nicht mehr möglich zum Reciever also der Bluetooth-Anlage oder der Soundbar.


    LG von Schatten-Nacht 🖐🏼

    "Kabel & Verschaltungen" Teil 2


    Im Bereich Lautsprecherkabel gibt es ein paar Versionen mehr dank der Kombinationen aus Klinkenstecker, XLR- und Speakon-Stecker. Hier solltet Ihr ein zweiadriges Lautsprecherkabel mit einigermaßen großem Querschnitt (2 x 2,5 mm ist ganz ok) nehmen und schauen, dass Ihr „sauber schaffet“… sonst (bei nem „kurzen“) ist die Endstufe bzw. der Verstärker schnell beleidigt.


    Lautsprecher | XLR-Mono – Speakon-Mono


    Lautsprecher | Klinke-Mono <–> Speakon-Mono


    Lautsprecher XLR-Mono <–> XLR-Mono


    Lautsprecher XLR-Mono – Klinke Mono


    Lautsprecher Speakon-Mono <–> Speakon-Mono


    Und bei Audiokabel allgemein gibt es ja auch genug Variationen. Bei einem Audiokabel benötigt Ihr für „mono“ ein einadriges geschirmtes Kabel – für “ Stereo“ die Geschichte in doppelter Ausführung (sogenannte Zwillingskabel). Die Stecker (Cinch (RCA), Mono-Klinke, Stereo-Klinke etc.) dann halt je nach Anwendung wählen… aber vom Prinzip ist es immer das gleiche: entweder Mono-Ausführungen oder Stereo-Ausführungen.


    Audio Klinke-Mono <–> Klink-Mono


    Audio Klinke-Stereo <–> Klinke-Stereo


    Zu deiner Aussage algl am 11.April 2025 zu Monitoren (Lautsprechern)

    "Ähm, also.

    Aktive Consumer-Boxen, die man analog (z.B. per 3,5mm-Klinke) an den Line Out des Mainboards anschließt - ja, zu großen Teilen ist da die Soundqualität von den verbauten Chips abhängig.

    Aktive Studiomonitore, die deinem Qualitätsanspruch ja eher gerecht sein dürften, sind hauptsächlich mit symmetrischen (balanced) Eingängen ausgestattet, meistens in 6,3mm-Klinke oder XLR, was zwar für kurze Kabel und heimische Anwendungen unnötig ist, aber nice to have - bedeutet jedoch, wenn man das nutzen will, daß ein extra Audio Interface her muß, welches symmetrische Ausgänge bietet. Das ist dann sowas wie ne externe Soundkarte, die wiederum am PC via USB angeschlossen wird (meist erhält sie darüber auch ihren Betriebsstrom). Auf diese Weise wärst du vom Mainboard-Soundchip unabhängig. Außerdem bietet das Extra-Gerät meistens noch einen deutlich besseren Kopfhörerverstärker und natürlich Downstream für angeschlossene Musikinstrumente (daher ist das Gerät eigentlich keine reine Soundkarte, sondern ein Arbeitsgerät für Gesangs-/Musikaufnahmen und das (gleichzeitige) Abhören per KH, Lautsprecherausgänge sind sozusagen mit dabei.

    Und wie gesagt gibt's ein paar Boxen, die ein Audio Interface / Soundkarte schon eingebaut haben und so z.B. direkt per USB am PC betrieben werden können. Und das gilt für immer mehr Studio-Boxen ebenso wie für Consumer-Geräte. Extra Netzanschluß haben die natürlich dennoch."


    Das stimmt so auch nicht da ich kein Lautsprecher kenne der mit drei Adern 2,1 ,3 Pins Stereo Spricht Lautsprecher sind immer nur Mono also im Aufbau Unsymmetrisch was das Terminal angeht.

    Das gleiche gilt natürlich auch für passive sowie aktive Monitore (Lautsprecher)

    Wie die Yamaha HS5 Monitore


    Hier kann ich auch am Input-Terminal des Yamaha HS5 sowohl ein DIN-Stecker Mono in den Input (Eingang) stecken also auch, ein 6,3mm Mono-Klinke (XLR) da es dem Lautsprecher Wurscht ist ob es 2, 1, 3 Pins (Signal-Adern im Kabel vorhanden sind oder eben nur 2, 1 Pins (zwei Adern) im Kabel vorhanden sind da wären wir wieder bei Asymmetrisch und Klirrfaktor.


    Das Audio-Interface von Steinberg besitze ich.


    Und Bitte gebe mir mal Feedback algl damit ich das auch als Analoge-Audio-Freak der ich bin besser verstehen kann deine Aussagen die nicht immer schlüssig sind gerade wenn sich Audiophobe-Freunde für Hardware Tool and Gears interessieren wo deine Aussagen mehr Lücken lassen als sie zu beantworten Danke.


    LG von Schatten-Nacht 🖐🏼


    PS: Ich hoffe meine kleine Erläuterung zu Asymmetrischen und Symmetrischen Standards bei Kabeln und Terninal-Anschlüssen ist jetzt für den ein oder anderen der sich auch mit dieser Thematik auseinandersetzen möchte jetzt besser zu verstehen.


    Un zur Aussage "Wandeln" also Mono-Siganle egal ob Midi via DIN-Stecker oder Mono-Klinke XLR bleibt trotzdem immer ein Mono-Signal das kann nur ein MUX oder DI-Plexer in einem DSP-Mischer oder eben klassisch zwei Mono-Signale rein und danach als Stereo-Signal wieder raus aus dem Mischer aber das macht keine DI-Box ein Mono-Signal in ein Stereo-Signal zu Wandeln <- allen der Begriff "Wandeln" stell mir schon Haare zu Berge.

    Guten Abend und Hallo algl 🖐🏼,

    zu deine Aussagen zu Asymmetrisch und Symmetrisch zu Kabeln und Terminal-Anschlüssen diese nicht nicht korrekt im Bezug auf Klinke da auch es auch DIN-Stecker gibt die schon seit 1978 existieren bei Midi diese sind immer asymmetrisch also unbalcend weil Mono-Signal.


    Auf der oberen Grafik die zwei ersten Mono-Klinke zu XLR sind wegen des einadringen Kabels immer asymmetrisch.

    Die beiden unteren Mono als auch Stereo Klinke zu XLR sind wegen der Adern 3 sind wieder symmetrisch (balanced). Was natürlich nicht heißt das der Signalweg auch ausbalanciert ist, da es auch immer auf Güte des Kupfers CFG-Anteil und die Aderverseilung drauf ankommt der zweite Part ist die Abschirmung innen wie außen was das Kabel schlussendlich ausmacht. Und ja güstigere Kabel habe weniger Kupfer-Anteil und eventuell auch eine Schlechtere Abschirmung das kann man leider auch da nicht so verallgemeinern das kommt auch auf den Anspruch drauf an was hat man mit dem Kabel vor wie Lang sollte das Kabel sein was für einen Preis hat man im Kopf usw das sind auch noch Faktoren die da mit hereinspielen.

    Genau, aber so weit, daß man das mit Wandlerkabeln machen kann, und daß man durchaus unsymmetrische Ausgänge mit symmetrischen Eingängen verbinden kann, und daß man sich Brummschleifen einhandeln kann, wofür man dann DI-Boxen, am besten mit Groud Lift, einsetzen kann, wollte ich im ersten Wurf nicht gehen... "


    Da gehe ich nicht so konträr bei Thoman steht zwar zu den Di-Boxen folgendes "Die DI-Box vereint meistens direkt zwei Mechanismen zur Reduzierung von Störungen:

    1. sie nimmt eine Symmetrierung des Signals vor und,
    2. für uns vielleicht am Wichtigsten, sie sorgt für eine galvanische Trennung der Kabel.
    3. Das geschieht wie folgt: damit eine Antenne tatsächlich eine Antenne ist, muss es unbedingt eine geschlossene Leiterschleife sein. Eine DI-Box trennt diese geschlossene Leiterschleife in zwei Stücke, indem das Nutzsignal für einen kurzen Weg nicht als Strom/Spannung transportiert wird, sondern als Magnetfeld. Außerdem haben eigentlich alle DI-Boxen einen Ground-Lift Schalter, so dass die Masse im Eingang der DI-Box von der Masse im Ausgang getrennt werden kann. Die Folge: keine Masseschleife mehr vorhanden. In diesem Sinne ist ein wichtiger Bestandteil der DI-Box der s.g. Übertrager, ein kleiner Transformator, der speziell für Töne und deren Anforderungen optimiert ist.

    Hier die Quelle dazu -> https://www.thomann.de/de/onlineexper…die_di_box.html


    Selbst mein 50 Jahre alter Röhrentrafo mit Übertrager ist was die Kupferwinklungen angeht Galvanisch Getrennt das hat nicht mit Trennung von Tonsignalen zu tun da geht es nur um die Streuung von Eleketromagnetischenfelder diesen nutze ich hauptsächlich für meine Zinklampen.


    DI-Boxen aktiv als auch passiv "Vor- und Nachteile der beiden Varianten" Mit aktiven DI-Boxen lassen sich prinzipiell beliebig hohe Eingangsimpedanzen und beliebig kleine Ausgangsimpedanzen realisieren, während die Eingangsimpedanzen passiver DI-Boxen höchstens in der Größenordnung von 500 kΩ liegen. Ein weiterer Vorteil aktiver DI-Boxen ist, dass man durch eine aktive Symmetrierung die Nachteile von Übertragern umgeht. Übertrager sind in hoher Qualität recht teuer, je nach Ausführung empfindlich gegen magnetische Einstreuungen und können (insbesondere bei tiefen Frequenzen und höheren Pegeln) einen nicht zu vernachlässigenden Klirrfaktor haben. Auch bieten sie im Vergleich mit aktiver Symmetrierung eine eingeschränkte Bandbreite. Allerdings ermöglichen Übertrager eine echte Potentialtrennung, weswegen es hochwertige, aktive DI-Boxen mit Übertragersymmetrierung gibt.

    Die Vorteile passiver DI-Boxen liegen darin, dass sie keine Versorgungsspannung benötigen und durch den Übertrager bedingt das Signal galvanisch trennen. Übertrager sind in hoher Qualität recht teuer, je nach Ausführung empfindlich gegen magnetische Einstreuungen und können (insbesondere bei tiefen Frequenzen und höheren Pegeln) einen nicht zu vernachlässigenden Klirrfaktor haben. Auch bieten sie im Vergleich mit aktiver Symmetrierung eine eingeschränkte Bandbreite. Einige Hersteller wie Palmer bieten daher aktive und passive DI-Boxen an und erläutern die Unterschiede in der Anwendung detailliert.

    Sie lassen sich außerdem auch grundsätzlich umgekehrt, also zur Wandlung eines symmetrischen in ein unsymmetrisches Signal, verwenden. Eine Anwendung, bei der eine DI-Box umgekehrt benutzt wird, nennt man Re-Amping. Hier wird eine bereits aufgenommene Gitarren- oder Bassspur nachträglich über einen Gitarren- bzw. Bassverstärker wiedergegeben und erneut aufgenommen.

    In der Praxis verwendet man daher bei Signalquellen mit hoher Ausgangsimpedanz und kleinem Pegel (zum Beispiel Piezo-Tonabnehmer) wegen ihrer hohen Eingangsimpedanz aktive DI-Boxen. Hinter einem Instrument mit Line-Ausgangspegel genügt dagegen eine hochwertige passive DI-Box.

    Das hier ist der wichtigste Part bei den Nachteilen einer DI-Box die Siganlverfärbung und der Klirrfaktor was das Rausch-Signal bei Analogen Instrumenten wie E-Gitarre oder Elektro-Schlagzeug noch verstärkt was den Subton angeht das Signal wird schlechter und das Grundrauschen wird höher und hörbarer.

    "Spezielle Varianten"

    Normalerweise sollte eine DI-Box keinerlei Klangverfärbungen verursachen, sondern das Signal möglichst unverfälscht übertragen. Eine Sonderstellung nehmen jedoch spezielle DI-Boxen mit Klangfilter für E-Gitarren ein. Diese enthalten einen Klangfilter, der den charakteristischen Frequenzgang von Gitarrenlautsprechern nachahmen soll. Hintergrund ist, dass Gitarrenlautsprecher wesentlich zum Klang einer Gitarre beitragen. Dieser Beitrag fehlt aber, wenn das Signal nicht mit einem Mikrofon vor dem Lautsprecher abgenommen wird. In der Regel werden solche DI-Boxen entweder zwischen den Verstärker und Lautsprecher, oder in den Effektweg eingeschleift.

    Diese Lösung hat Vor- und Nachteile und ist deshalb umstritten. So lässt sich der Klang der E-Gitarre durch Auswahl und Position des Mikrofons beeinflussen. Auch ist die Nachbildung des Lautsprecherklangs nicht immer zufriedenstellend, insbesondere bei sehr hohen Wiedergabelautstärken. Verzichtet man andererseits auf Mikrofone, so lassen sich die Probleme mit Übersprechen und Rückkopplung auf der Bühne verringern.

    Verzerrungen

    Alle Übertragungsmedien dämpfen das darauf übertragene Signal ab. Die Dämpfung beschreibt die Abnahme der Spannungs-, Strom- und Leistungswerte während der Übertragung.
    Die Ursache der Dämpfung ist z. B. der Leitungswiderstand. Eine weitere Ursache ist das Einkoppeln von Fremdsignalen in die Signalamplitude. Das führt dann zu Rauschen. Eine weitere Ursache für die Veränderung von Signalen ist die Verzerrung.


    Lineare Verzerrungen

    Lineare Verzerrungen entstehen durch frequenzabhängige Verstärker und kapazitive und induktive Spannungsteiler.


    Bei der linearen Verzerrung wird die ursprüngliche Kurvenform nicht verändert. Es entstehen deshalb keine neuen Oberwellen.
    Es findet nur eine Veränderung der Amplitude statt. Man spricht vom Abfallen der Tiefen und der Höhen bei der Verstärkung (Audio).

    Nichtlineare Verzerrungen

    Nichtlineare Verzerrungen entstehen durch Spiegelungen an Kennlinien von passiven bzw. aktiven Halbleiterbauelementen.


    Die Kennlinien einer Verstärkerschaltung sind nichtlinear. Dadurch wird eine Sinuskurve am Eingang eines Verstärkers in der Kurvenform verändert.
    Bei der Übersteuerung wird der positive und der negative Amplitudenbereich abgeschnitten. Das dabei entstehende Signal enthält Oberwellen, die das Signal härter, höher und lauter klingen lassen (Akustik).
    Nichtlineare Verzerrungen führen zu Frequenzen, die im Originalsignal nicht vorhanden sind. Abhilfe schafft Gegenkopplung.

    Die Nichtlinearität ist ein Verhalten, die sich nicht durch Gleichungen ersten Grades bestimmen lassen.

    Klirrfaktor k

    Der Klirrfaktor k ist das Maß für die nichtlinearen Verzerrungen durch/in einen Vierpol (z. B. Verstärker, Mikrofon, Tonbandgerät).
    Der Klirrfaktor ist frequenzabhängig und gibt den Oberwellenanteil in % eines Signals an.
    Je kleiner der Klirrfaktor ist, desto besser entspricht das Signal dem Original.

    Formel zur Berechnung des Klirrfaktors


    Richtwerte für den Klirrfaktor:

    • FM-Rundfunksender < 1%
    • Hifi-Verstärker < 1%
    • AM-Rundfunksender < 4%

    Ein Klirrfaktor von 1% ist für geschulte Ohren gerade noch hörbar.

    Als Buchtipp kann ich dir nur mal so ohne Schleichwerbung zu machen die Elektrofiebel von Patrick Schrabel empfehlen da geht es auch bei Schaltdiagrammen um Übertrager.


    Nichtlineare Verzerrungen werden als Dämpfungsmaß (Klirrdämpfung oder Klirrabstand) ak in dB oder als Dämpfungsfaktor (Klirrfaktor) k in Prozent angegeben. Die gesamte harmonische Verzerrung (THD) wird als das Verhältnis der Effektiv-Spannung (RMS) der Harmonischen zu der Grundkomponente bestimmt. Dieses wird unter Verwendung eines Spektrumanalysators erreicht, um den Pegel der einzelnen Harmonischen zu erhalten. Dann wird eine Effektivwert-Summierung durchgeführt. Der Pegel wird durch die Grundschwingung geteilt und als die gesamte harmonische Verzerrung (in Prozent) angegeben. Auch der englische Ausdruck THD = Total Harmonic Distortion ist für die Verzerrungsgröße Klirrdämpfung oder besser Klirrdämpfungsmaß üblich.
    Das ist der Pegelunterschied zwischen Klirranteil (unerwünschte Obertöne) und dem gesamten Signal in dB; vgl. Klirrfaktor. Der Klirrfaktor eines Audiogeräts gibt an, in welchem Maße einem sinusförmigen Eingangssignal (Messton- Amplitude) durch nichtlineare Verzerrungen unerwünschte Obertöne bzw. Harmonische zugefügt werden. Er ist also ein Maß für die auftretenden harmonischen Verzerrungen. Die Angabe erfolgt in Prozent, bezogen auf das Gesamtsignal.
    Harmonische Verzerrungen findet man mit einem Minuszeichen vor dem dB- Wert, die Klirrdämpfung wird auch mit einem positiven Vorzeichen angegeben.
    Es gibt Größen, die keine Maßeinheit besitzen. Dazu gehören Verhältnisse, die gern mit der uneigentlichen Maßeinheit Prozent (%) oder Dezibel (dB) versehen werden.


    Wie gesagt auch eine tolle Webseite zur Berechnung von Klirrfaktoren und Verzerrungen im Signalgang bei Kabeln oder Übertragern die Webseite kann beides mit Rechner zu THD und Dämpfungs-Filter als db Wert. -> https://sengpielaudio.com/Rechner-klirr.htm 👍🏼

    "Kabel & Verschaltungen" Teil 1

    Also mich hat das immer geärgert, als ich meine Verschaltungen für Micro-, Instrumenten-, Lautsprecher- und sonstige Audiokabel grad nicht zur Hand hatte. So bin ich mal her gegangen und hab die für mich wichtigsten auf meine kleine Homepage gestellt.

    Ich hoff Ihr habt somit ein kleines Nachschlagewerk…

    Los geht es mit einem unsymmetrischen Mikrofonkabel!
    Dazu benötigt Ihr eine XLR-Kupplung, einen Mono-Klinkenstecker bzw. zwei Mono-Klinkenstecker und einadriges geschirmtes Kabel.


    Mikrofon | XLR – Klinke (Mono)


    Mikrofon | XLR – Klinke (Mono)


    Bei einem symmetrisches Mikrofonkabel sieht es ähnlich aus:
    Für dieses benötigt Ihr eine XLR-Kupplung, einen XLR-Stecker bzw. Stereo-Klinkenstecker und n zweiadriges geschirmtes Kabel.


    Mikrofon | XLR – XLR


    Mikrofon | XLR – Klinke (Stereo)


    LG von Schatten-Nacht 🖐🏼

    Hallo und Guten Abend bernhard es ist schade das du bei "Teufel" was Qualität und Funktion betrifft enttäuscht wurden bist. Das große Problem in unserer West-Europäischen Hemisphäre ist das sich niemand die Arbeit und die Mühe macht wenn es um den Kauf von Geräte geht sich im Vorfeld Datenblätter und eventuelle Reviews sich mal, durchließt und ja an Baupläne und Schaltung zu kommen ist nicht so einfach um sich noch mehr Details über die Verbauten Chips, das PGA Platinen-Layout und das Mainboard an sich einzuholen das steht außer Frage.


    Und ja es ist dann hinterher traurig, wenn man ein Gerät bei einem Hersteller einschickt der das Gerät was einen Defekt hat der nicht mal beheben kann das zeigt auf das "Teufel" kein Direkter Hersteller ist was das Assembling von und das Lithografieren von PGA-Bauelementen angeht da "Teufel" nur ein Auftragsfertiger ist ähnlich wie Nvidia und kein OEM-Hersteller deswegen war ich etwas verwirrt als ich im (Impressum) gelesen hatte "Lautsprecher Teufel GmbH / Bikini Berlin"


    Und, ja es ist heute besonders schwiering heraus zubekommen wer für "Teufel" oder andere Hersteller im Lautsprecherbau Zulieferer und OEM-Fertiger ist.

    "The key differences between contract manufacturing and traditional manufacturing models lie in ownership, control, and focus. In traditional manufacturing, a company owns and operates its production facilities, controls the entire manufacturing process, and bears all the risks associated with production. Conversely, in contract manufacturing, the client company outsources production to a contractor, shifting the focus from manufacturing to other aspects of the business such as product development, marketing, and sales. This model reduces capital investment and operational risks for the client but requires careful selection of manufacturing partners and robust quality control mechanisms to ensure product standards are met. Contract manufacturing represents a strategic choice for companies aiming to stay competitive by focusing on their strengths while leveraging global manufacturing capabilities.

    Types of Contract Manufacturing

    Contract manufacturing is a versatile and strategic approach that allows companies to outsource various aspects of their production processes. It encompasses a range of services, tailored to meet the diverse needs of businesses across industries. The types of contract manufacturing can generally be categorized based on the nature of the work involved, including:

    1. OEM (Original Equipment Manufacturing)

    OEM involves manufacturing components or products that are designed and specified by the hiring company. The contract manufacturer produces these items under the hiring company's brand name. This type of contract manufacturing is prevalent in industries such as electronics, automotive, and appliances, where complex components are required.

    2. ODM (Original Design Manufacturing)

    In ODM, the contract manufacturer not only produces but also designs the products based on the hiring company's specifications. This arrangement allows companies without extensive design capabilities to bring products to market. ODM is common in consumer electronics, clothing, and furniture industries.

    3. Electronics Manufacturing Services (EMS)

    EMS providers offer a comprehensive range of services for companies in the electronics industry, covering the production of components, assembly of electronic devices, and sometimes additional services like design and after-sales support. EMS is crucial for businesses looking to outsource their electronics production efficiently."

    What is difference between OEM, CM, CEM, ECM, EMS, ODM, JDM, design house contract electronic firms?
    The design and manufacture of electronic hardware equipment products is divided into two primary camps: OEM brand companies and contract …
    ventureoutsource.com


    Deswegen verstehe ich auch zu gut wenn so eine Anschaffung dann schon mal in die Hose gehen kann und man seine "Erwartungen" an das Produkt und man dann enttäuscht wurde wegen schlechter Implementierung von PGA-Bauelementen was MUX Encoder und Di-Plexer angeht im Bezug auf Bluetooth-Chips.


    LG von Schatten-Nacht 🖐🏼

    Hallo, 🖐🏼 und Guten Abend Freedstorm schade 🤔 ich hätte dir gerne bei deinem Hobby-Projekt geholfen da ich was Coding angeht auch noch immer wieder dazu lerne möchte du kannst / könntest ja deine .src source code als gepackten Anhang hier im Forum an pinnen und ich schaue mal in den Code.


    Mein Vorschlag an dich ich würde gar kein Skin weder als GTK noch als Qt-Quck in deine Anwendung Einbauen sie kann doch eine CLI-Anwendung seien das ist doch nicht schlimm wenn die Schalter und deren Funktion und die Pattern bei der Datananalyse gut strukturiert sind ist das doch ne feine Sache.


    LG von Schatten-Nacht 🖐🏼

    Hallo und Guten Morgen MaxC 🖐🏼,


    du könntest ja auch den Audio-Player namens "Audacius" mal als.Appimage Variante dir herunterladen sollten deine LM-Repos nicht gut in deiner LinuxMint Distro zu Adacius funktionieren.


    Das behebt zwar keine Soundkarten Treiberprobleme aber es läuft Isoliert ohne sich in dein Linux-System reinzuschreiben nur der /tmp/ <- Ordner wird angefasst.


    Hier mal die Quelle wo du dir Audacius als Appimage downloaden kannst -> https://github.com/ivan-hc/Audacious-appimage/releases

    Nimm auf GitHub die erste Quelle bei Release zu den Appimages für dein 64Bit LinuxMint System:


    LG von Schatten-Nacht 🖐🏼 und dir noch ein Gesundes neues Jahr 2026.

    Hallo Freedstorm ich habe noch was vergessen im Bezug auf Baue deine eigne Distro hier meine Code-Biblothek von meinem Compositor.


    #include "compositor.h"

    #include "config-kwin.h"

    #include "core/backendoutput.h"
    #include "core/brightnessdevice.h"
    #include "core/drmdevice.h"
    #include "core/graphicsbufferview.h"
    #include "core/outputbackend.h"
    #include "core/outputlayer.h"
    #include "core/renderbackend.h"
    #include "core/renderloop.h"
    #include "cursor.h"
    #include "cursorsource.h"
    #include "dbusinterface.h"
    #include "effect/effecthandler.h"
    #include "ftrace.h"
    #include "opengl/eglbackend.h"
    #include "opengl/glplatform.h"
    #include "qpainter/qpainterbackend.h"
    #include "renderloopdrivenqanimationdriver.h"
    #include "scene/cursoritem.h"
    #include "scene/itemrenderer_opengl.h"
    #include "scene/itemrenderer_qpainter.h"
    #include "scene/surfaceitem.h"
    #include "scene/surfaceitem_wayland.h"
    #include "scene/workspacescene.h"
    #include "utils/common.h"
    #include "utils/envvar.h"
    #include "wayland/surface.h"
    #include "wayland_server.h"
    #include "window.h"
    #include "workspace.h"

    #include "utils/drm_format_helper.h"

    #include <KCrash>
    #if KWIN_BUILD_NOTIFICATIONS
    #include <KLocalizedString>
    #include <KNotification>
    #endif

    #include <QQuickWindow>
    #include <optional>
    #include <ranges>

    namespace KWin
    {

    Compositor *Compositor::create(QObject *parent)
    {
       Q_ASSERT(!s_compositor);
       auto *compositor = new Compositor(parent);
       s_compositor = compositor;
       return compositor;
    }

    Compositor *Compositor::s_compositor = nullptr;
    Compositor *Compositor::self()
    {
       return s_compositor;
    }

    Compositor::Compositor(QObject *workspace)
       : QObject(workspace)
       , m_allowOverlaysEnv(environmentVariableBoolValue("KWIN_USE_OVERLAYS"))
       , m_renderLoopDrivenAnimationDriver(new RenderLoopDrivenQAnimationDriver(this))
    {
       // register DBus
       new CompositorDBusInterface(this);

       m_renderLoopDrivenAnimationDriver->install();
       connect(m_renderLoopDrivenAnimationDriver, &RenderLoopDrivenQAnimationDriver::started, this, [this]() {
           // foreach output, schedule repaint on render loop
           for (const auto &it : m_primaryViews) {
               RenderLoop *loop = it.first;
               loop->scheduleRepaint();
           }
       });

       FTraceLogger::create();
    }

    Compositor::~Compositor()
    {
       Q_EMIT aboutToDestroy();
       stop(); // this can't be called in the destructor of Compositor
       s_compositor = nullptr;
    }

    BackendOutput *Compositor::findOutput(RenderLoop *loop) const
    {
       const auto outputs = kwinApp()->outputBackend()->outputs();
       for (BackendOutput *output : outputs) {
           if (output->renderLoop() == loop) {
               return output;
           }
       }
       return nullptr;
    }

    void Compositor::reinitialize()
    {
       // Restart compositing
       stop();
       start();
    }

    void Compositor::handleFrameRequested(RenderLoop *renderLoop)
    {
       composite(renderLoop);
    }

    bool Compositor::isActive()
    {
       return m_state == State::On;
    }

    static QVariantHash collectCrashInformation(const EglBackend *backend)
    {
       const GLPlatform *glPlatform = backend->openglContext()->glPlatform();

       QVariantHash gpuInformation;
       gpuInformation[QStringLiteral("api_type")] = QStringLiteral("OpenGL");
       gpuInformation[QStringLiteral("name")] = QString::fromUtf8(glPlatform->glRendererString());
       if (const auto pciInfo = backend->drmDevice()->pciDeviceInfo()) {
           gpuInformation[QStringLiteral("id")] = QString::number(pciInfo->device_id, 16);
           gpuInformation[QStringLiteral("vendor_id")] = QString::number(pciInfo->vendor_id, 16);
       }
       if (glPlatform->driverVersion().isValid()) {
           gpuInformation[QStringLiteral("version")] = glPlatform->driverVersion().toString();
       }

       return gpuInformation;
    }

    bool Compositor::attemptOpenGLCompositing()
    {
       std::unique_ptr<EglBackend> backend = kwinApp()->outputBackend()->createOpenGLBackend();
       if (!backend) {
           return false;
       }
       if (!backend->isFailed()) {
           backend->init();
       }
       if (backend->isFailed()) {
           return false;
       }

       KCrash::setGPUData(collectCrashInformation(backend.get()));

       const QByteArray forceEnv = qgetenv("KWIN_COMPOSE");
       if (!forceEnv.isEmpty()) {
           if (qstrcmp(forceEnv, "O2") == 0 || qstrcmp(forceEnv, "O2ES") == 0) {
               qCDebug(KWIN_CORE) << "OpenGL 2 compositing enforced by environment variable";
           } else {
               // OpenGL 2 disabled by environment variable
               return false;
           }
       } else {
           if (backend->openglContext()->glPlatform()->recommendedCompositor() < OpenGLCompositing) {
               qCDebug(KWIN_CORE) << "Driver does not recommend OpenGL compositing";
               return false;
           }
       }

       // We only support the OpenGL 2+ shader API, not GL_ARB_shader_objects
       if (!backend->openglContext()->hasVersion(Version(2, 0))) {
           qCDebug(KWIN_CORE) << "OpenGL 2.0 is not supported";
           return false;
       }
       m_backend = std::move(backend);
       qCDebug(KWIN_CORE) << "OpenGL compositing has been successfully initialized";
       return true;
    }

    bool Compositor::attemptQPainterCompositing()
    {
       std::unique_ptr<QPainterBackend> backend(kwinApp()->outputBackend()->createQPainterBackend());
       if (!backend || backend->isFailed()) {
           return false;
       }
       m_backend = std::move(backend);
       qCDebug(KWIN_CORE) << "QPainter compositing has been successfully initialized";
       return true;
    }

    void Compositor::createRenderer()
    {
       // If compositing has been restarted, try to use the last used compositing type.
       const QList<CompositingType> availableCompositors = kwinApp()->outputBackend()->supportedCompositors();
       QList<CompositingType> candidateCompositors;

       if (m_selectedCompositor != NoCompositing) {
           candidateCompositors.append(m_selectedCompositor);
       } else {
           candidateCompositors = availableCompositors;

           const auto userConfigIt = std::find(candidateCompositors.begin(), candidateCompositors.end(), options->compositingMode());
           if (userConfigIt != candidateCompositors.end()) {
               candidateCompositors.erase(userConfigIt);
               candidateCompositors.prepend(options->compositingMode());
           } else {
               qCWarning(KWIN_CORE) << "Configured compositor not supported by Platform. Falling back to defaults";
           }
       }

       for (auto type : std::as_const(candidateCompositors)) {
           bool stop = false;
           switch (type) {
           case OpenGLCompositing:
               qCDebug(KWIN_CORE) << "Attempting to load the OpenGL scene";
               stop = attemptOpenGLCompositing();
               break;
           case QPainterCompositing:
               qCDebug(KWIN_CORE) << "Attempting to load the QPainter scene";
               stop = attemptQPainterCompositing();
               break;
           case NoCompositing:
               qCDebug(KWIN_CORE) << "Starting without compositing...";
               stop = true;
               break;
           }

           if (stop) {
               break;
           } else if (qEnvironmentVariableIsSet("KWIN_COMPOSE")) {
               qCCritical(KWIN_CORE) << "Could not fulfill the requested compositing mode in KWIN_COMPOSE:" << type << ". Exiting.";
               qApp->quit();
           }
       }
    }

    void Compositor::createScene()
    {
       if (const auto eglBackend = qobject_cast<EglBackend *>(m_backend.get())) {
           m_scene = std::make_unique<WorkspaceScene>(std::make_unique<ItemRendererOpenGL>(eglBackend->eglDisplayObject()));
       } else {
           m_scene = std::make_unique<WorkspaceScene>(std::make_unique<ItemRendererQPainter>());
       }
       Q_EMIT sceneCreated();
    }

    void Compositor::start()
    {
       if (kwinApp()->isTerminating()) {
           return;
       }
       if (m_state != State::Off) {
           return;
       }

       Q_EMIT aboutToToggleCompositing();
       m_state = State::Starting;

       if (!m_backend) {
           createRenderer();
       }

       if (!m_backend) {
           m_state = State::Off;

           qCCritical(KWIN_CORE) << "The used windowing system requires compositing";
           qCCritical(KWIN_CORE) << "We are going to quit KWin now as it is broken";
           qApp->quit();
           return;
       }

       if (m_selectedCompositor == NoCompositing) {
           m_selectedCompositor = m_backend->compositingType();

           switch (m_selectedCompositor) {
           case NoCompositing:
               break;
           case OpenGLCompositing:
               QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL);
               break;
           case QPainterCompositing:
               QQuickWindow::setGraphicsApi(QSGRendererInterface::Software);
               break;
           }
       }

       createScene();

       handleOutputsChanged();
       connect(workspace(), &Workspace::outputsChanged, this, &Compositor::handleOutputsChanged);
       connect(kwinApp()->outputBackend(), &OutputBackend::outputRemoved, this, &Compositor::removeOutput);

       m_state = State::On;

       const auto windows = workspace()->windows();
       for (Window *window : windows) {
           window->setupCompositing();
       }

       // Sets also the 'effects' pointer.
       new EffectsHandler(this, m_scene.get());

       Q_EMIT compositingToggled(true);
    }

    void Compositor::stop()
    {
       if (m_state == State::Off || m_state == State::Stopping) {
           return;
       }
       m_state = State::Stopping;
       Q_EMIT aboutToToggleCompositing();

       // Some effects might need access to effect windows when they are about to
       // be destroyed, for example to unreference deleted windows, so we have to
       // make sure that effect windows outlive effects.
       delete effects;
       effects = nullptr;

       if (Workspace::self()) {
           const auto windows = workspace()->windows();
           for (Window *window : windows) {
               window->finishCompositing();
           }
           disconnect(workspace(), &Workspace::outputsChanged, this, &Compositor::handleOutputsChanged);
           disconnect(kwinApp()->outputBackend(), &OutputBackend::outputRemoved, this, &Compositor::removeOutput);
       }

       if (m_backend->compositingType() == OpenGLCompositing) {
           // some layers need a context current for destruction
           static_cast<EglBackend *>(m_backend.get())->openglContext()->makeCurrent();
       }

       const auto loops = m_primaryViews | std::views::transform([](const auto &pair) {
           return pair.first;
       }) | std::ranges::to<QList>();
       for (RenderLoop *loop : loops) {
           removeOutput(findOutput(loop));
       }

       m_scene.reset();
       m_backend.reset();

       m_state = State::Off;
       Q_EMIT compositingToggled(false);
    }

    static bool isTearingRequested(const Item *item)
    {
       if (item->presentationHint() == PresentationModeHint::Async) {
           return true;
       }

       const auto childItems = item->childItems();
       return std::ranges::any_of(childItems, [](const Item *childItem) {
           return isTearingRequested(childItem);
       });
    }

    static Rect mapGlobalLogicalToOutputDeviceCoordinates(const RectF &logicalGeometry, LogicalOutput *logicalOutput, BackendOutput *backendOutput)
    {
       const Rect localDevice = logicalGeometry.translated(-logicalOutput->geometryF().topLeft()).scaled(backendOutput->scale()).rounded();
       return backendOutput->transform().map(localDevice.translated(backendOutput->deviceOffset()), backendOutput->pixelSize());
    }

    static bool prepareDirectScanout(RenderView *view, LogicalOutput *logicalOutput, BackendOutput *backendOutput, const std::shared_ptr<OutputFrame> &frame)
    {
       if (!view->isVisible()) {
           return false;
       }
       const auto layer = view->layer();
       const auto scanoutCandidates = view->scanoutCandidates(1);
       if (scanoutCandidates.isEmpty()) {
           layer->setScanoutCandidate(nullptr);
           return false;
       }
       SurfaceItem *candidate = scanoutCandidates.front();
       SurfaceItemWayland *wayland = qobject_cast<SurfaceItemWayland *>(candidate);
       if (!wayland || !wayland->surface()) {
           return false;
       }
       const auto buffer = wayland->surface()->buffer();
       if (!buffer) {
           return false;
       }
       const auto attrs = buffer->dmabufAttributes();
       if (!attrs) {
           return false;
       }
       const bool tearing = frame->presentationMode() == PresentationMode::Async || frame->presentationMode() == PresentationMode::AdaptiveAsync;
       const auto formats = tearing ? layer->supportedAsyncDrmFormats() : layer->supportedDrmFormats();
       if (auto it = formats.find(attrs->format); it == formats.end() || !it->contains(attrs->modifier)) {
           layer->setScanoutCandidate(candidate);
           candidate->setScanoutHint(layer->scanoutDevice(), formats);
           return false;
       }
       const auto geometry = candidate->mapToScene(RectF(QPointF(0, 0), candidate->size()));
       layer->setTargetRect(mapGlobalLogicalToOutputDeviceCoordinates(geometry, logicalOutput, backendOutput));
       layer->setEnabled(true);
       layer->setSourceRect(candidate->bufferSourceBox());
       layer->setBufferTransform(candidate->bufferTransform());
       layer->setOffloadTransform(candidate->bufferTransform().combine(backendOutput->transform().inverted()));
       layer->setColor(candidate->colorDescription(), candidate->renderingIntent(), ColorPipeline::create(candidate->colorDescription(), backendOutput->layerBlendingColor(), candidate->renderingIntent()));
       const bool ret = layer->importScanoutBuffer(candidate->buffer(), frame);
       if (ret) {
           candidate->resetDamage();
           // ensure the pixmap is updated when direct scanout ends
           candidate->destroyTexture();
       }
       return ret;
    }

    static bool prepareRendering(RenderView *view, LogicalOutput *logicalOutput, BackendOutput *backendOutput, uint32_t requiredAlphaBits)
    {
       if (!view->isVisible()) {
           return false;
       }
       auto nativeRect = mapGlobalLogicalToOutputDeviceCoordinates(view->viewport(), logicalOutput, backendOutput);
       // we need to render black bars for mirroring,
       // so add the relevant area to the source and target rect
       const QSize renderOffset = backendOutput->transform().map(QSize(view->renderOffset().x(), view->renderOffset().y()));
       nativeRect.adjust(-renderOffset.width(), -renderOffset.height(), renderOffset.width(), renderOffset.height());
       if ((nativeRect & Rect(QPoint(), backendOutput->modeSize())).isEmpty()) {
           return false;
       }

       const auto layer = view->layer();
       const double reference = backendOutput->colorDescription()->referenceLuminance();
       const double maxOutputLuminance = backendOutput->colorDescription()->maxHdrLuminance().value_or(reference);
       const double usedMaxLuminance = std::min(view->desiredHdrHeadroom() * reference, maxOutputLuminance);
       layer->setSourceRect(Rect(QPoint(0, 0), nativeRect.size()));
       layer->setTargetRect(nativeRect);
       layer->setHotspot(backendOutput->transform().map(view->hotspot() * view->scale(), nativeRect.size()));
       layer->setEnabled(true);
       layer->setOffloadTransform(OutputTransform::Normal);
       layer->setBufferTransform(backendOutput->transform());
       layer->setColor(backendOutput->layerBlendingColor()->withHdrMetadata(reference, usedMaxLuminance), RenderingIntent::AbsoluteColorimetricNoAdaptation, ColorPipeline{});
       layer->setRequiredAlphaBits(requiredAlphaBits);
       return layer->preparePresentationTest();
    }

    static bool renderLayer(RenderView *view, LogicalOutput *logicalOutput, BackendOutput *backendOutput, const std::shared_ptr<OutputFrame> &frame, const Region &surfaceDamage)
    {
       auto beginInfo = view->layer()->beginFrame();
       if (!beginInfo) {
           return false;
       }
       auto &[renderTarget, repaint] = beginInfo.value();
       const Region bufferDamage = surfaceDamage.united(repaint).intersected(renderTarget.transformedRect());
       view->paint(renderTarget, view->renderOffset(), bufferDamage);
       return view->layer()->endFrame(bufferDamage, surfaceDamage, frame.get());
    }

    static OutputLayer *findLayer(std::span<OutputLayer *const> layers, OutputLayerType type, std::optional<int> minZPos)
    {
       const auto it = std::ranges::find_if(layers, [type, minZPos](OutputLayer *layer) {
           if (minZPos.has_value() && layer->maxZpos() < *minZPos) {
               return false;
           }
           return layer->type() == type;
       });
       return it == layers.end() ? nullptr : *it;
    }

    /**
    * items and layers need to be sorted top to bottom
    */
    static std::unordered_map<Item *, OutputLayer *> assignOverlays(RenderView *sceneView, std::span<Item *const> underlays, std::span<Item *const> overlays, std::span<OutputLayer *const> layers)
    {
       if (layers.empty() || (underlays.empty() && overlays.empty())) {
           return {};
       }
       // TODO also allow assigning the primary view to a different plane
       const int primaryZpos = sceneView->layer()->zpos();
       auto layerIt = layers.begin();
       int zpos = (*layerIt)->maxZpos();
       std::unordered_map<Item *, OutputLayer *> ret;
       auto overlaysIt = overlays.begin();
       for (; overlaysIt != overlays.end();) {
           Item *item = *overlaysIt;
           const RectF sceneRect = item->mapToView(item->rect(), sceneView);
           if (sceneRect.contains(sceneView->viewport())) {
               // leave fullscreen direct scanout to the primary plane
               overlaysIt++;
               continue;
           }
           if (layerIt == layers.end()) {
               return {};
           }
           OutputLayer *layer = *layerIt;
           const int nextZpos = std::min(zpos, layer->maxZpos());
           if (layer->minZpos() > nextZpos) {
               layerIt++;
               continue;
           }
           if (nextZpos < primaryZpos) {
               // can't use this
               return {};
           }
           if (layer->type() == OutputLayerType::CursorOnly && qobject_cast<CursorItem *>(item) == nullptr) {
               layerIt++;
               continue;
           }
           const auto recommendedSizes = layer->recommendedSizes();
           if (!recommendedSizes.isEmpty()) {
               // it's likely that sizes other than the recommended ones won't work
               const bool compositingAllowed = qobject_cast<CursorItem *>(item) != nullptr;
               const Rect deviceRect = sceneRect.translated(-sceneView->viewport().topLeft()).scaled(sceneView->scale()).rounded();
               const bool hasFittingSize = std::ranges::any_of(recommendedSizes, [compositingAllowed, deviceRect](const QSize &size) {
                   if (compositingAllowed) {
                       return deviceRect.size().width() <= size.width()
                           && deviceRect.size().height() <= size.height();
                   } else {
                       return deviceRect.size() == size;
                   }
               });
               if (!hasFittingSize) {
                   layerIt++;
                   continue;
               }
           }
           layer->setZpos(nextZpos);
           ret[item] = layer;
           overlaysIt++;
           layerIt++;
           zpos = nextZpos - 1;
       }
       if (overlaysIt != overlays.end()) {
           // not all items were assigned, we need to composite
           return {};
       }
       if (layerIt == layers.end()) {
           if (underlays.empty()) {
               return ret;
           } else {
               return {};
           }
       }
       zpos = std::min(primaryZpos - 1, (*layerIt)->maxZpos());
       auto underlaysIt = underlays.begin();
       for (; underlaysIt != underlays.end();) {
           Item *item = *underlaysIt;
           const RectF sceneRect = item->mapToView(item->rect(), sceneView);
           if (sceneRect.contains(sceneView->viewport())) {
               // leave fullscreen direct scanout to the primary plane
               underlaysIt++;
               continue;
           }
           if (layerIt == layers.end()) {
               return {};
           }
           OutputLayer *layer = *layerIt;
           const int nextZpos = std::min(zpos, layer->maxZpos());
           if (layer->minZpos() > nextZpos) {
               layerIt++;
               continue;
           }
           if (layer->type() == OutputLayerType::CursorOnly && qobject_cast<CursorItem *>(item) == nullptr) {
               layerIt++;
               continue;
           }
           const auto recommendedSizes = layer->recommendedSizes();
           if (!recommendedSizes.isEmpty()) {
               // it's likely that sizes other than the recommended ones won't work
               const bool compositingAllowed = qobject_cast<CursorItem *>(item) != nullptr;
               const Rect deviceRect = sceneRect.translated(-sceneView->viewport().topLeft()).scaled(sceneView->scale()).rounded();
               const bool hasFittingSize = std::ranges::any_of(recommendedSizes, [compositingAllowed, deviceRect](const QSize &size) {
                   if (compositingAllowed) {
                       return deviceRect.size().width() <= size.width()
                           && deviceRect.size().height() <= size.height();
                   } else {
                       return deviceRect.size() == size;
                   }
               });
               if (!hasFittingSize) {
                   layerIt++;
                   continue;
               }
           }
           layer->setZpos(nextZpos);
           ret[item] = layer;
           underlaysIt++;
           layerIt++;
           zpos = nextZpos - 1;
       }
       if (underlaysIt != underlays.end()) {
           // not all items were assigned, we need to composite
           return {};
       }
       return ret;
    }

    void Compositor::composite(RenderLoop *renderLoop)
    {
       if (m_backend->checkGraphicsReset()) {
           qCDebug(KWIN_CORE) << "Graphics reset occurred";
    #if KWIN_BUILD_NOTIFICATIONS
           KNotification::event(QStringLiteral("graphicsreset"), i18n("Desktop effects were restarted due to a graphics reset"));
    #endif
           reinitialize();
           return;
       }
       if (m_renderLoopDrivenAnimationDriver->isRunning()) {
           m_renderLoopDrivenAnimationDriver->advanceToNextFrame(renderLoop->nextPresentationTimestamp());
       }

       BackendOutput *output = findOutput(renderLoop);
       LogicalOutput *logicalOutput = workspace()->findOutput(output);
       const auto primaryView = m_primaryViews[renderLoop].get();
       fTraceDuration("Paint (", output->name(), ")");

       QList<OutputLayer *> toUpdate;

       renderLoop->prepareNewFrame();
       auto totalTimeQuery = std::make_unique<CpuRenderTimeQuery>();
       auto frame = std::make_shared<OutputFrame>(renderLoop, std::chrono::nanoseconds(1'000'000'000'000 / output->refreshRate()));
       std::optional<double> desiredArtificalHdrHeadroom;

       // brightness animations should be skipped when
       // - the output is new, and we didn't have the output configuration applied yet
       // - there's not enough steps to do a smooth animation
       // - the brightness device is external, most of them do an animation on their own
       if (!output->currentBrightness().has_value()
           || (!output->highDynamicRange() && output->brightnessDevice() && !output->isInternal())
           || (!output->highDynamicRange() && output->brightnessDevice() && output->brightnessDevice()->brightnessSteps() < 5)) {
           frame->setBrightness(output->brightnessSetting() * output->dimming());
       } else {
           // animate much slower for automatic brightness
           double changePerSecond = 3;
           if (output->lastBrightnessAdjustmentReason() == BackendOutput::BrightnessReason::AutomaticBrightness) {
               if (output->brightnessSetting() < output->currentBrightness()) {
                   // brightness should be reduced slowly, or it'll be annoying
                   changePerSecond = 0.1;
               } else {
                   // but increased more quickly, so that you can still read your screen
                   changePerSecond = 0.5;
               }
           }
           const double maxChangePerFrame = changePerSecond * 1'000.0 / renderLoop->refreshRate();
           // brightness perception is non-linear, gamma 2.2 encoding *roughly* represents that
           const double current = std::pow(*output->currentBrightness(), 1.0 / 2.2);
           frame->setBrightness(std::pow(std::clamp(std::pow(output->brightnessSetting() * output->dimming(), 1.0 / 2.2), current - maxChangePerFrame, current + maxChangePerFrame), 2.2));
       }

       Window *const activeWindow = workspace()->activeWindow();
       SurfaceItem *const activeFullscreenItem = activeWindow && activeWindow->isFullScreen() && activeWindow->frameGeometry().intersects(primaryView->viewport()) ? activeWindow->surfaceItem() : nullptr;
       frame->setContentType(activeWindow && activeFullscreenItem ? activeFullscreenItem->contentType() : ContentType::None);

       const bool wantsAdaptiveSync = activeWindow && activeWindow->frameGeometry().intersects(primaryView->viewport()) && activeWindow->wantsAdaptiveSync();
       const bool vrr = (output->capabilities() & BackendOutput::Capability::Vrr) && (output->vrrPolicy() == VrrPolicy::Always || (output->vrrPolicy() == VrrPolicy::Automatic && wantsAdaptiveSync));
       const bool tearing = (output->capabilities() & BackendOutput::Capability::Tearing) && options->allowTearing() && activeFullscreenItem && activeWindow->wantsTearing(isTearingRequested(activeFullscreenItem));
       if (vrr) {
           frame->setPresentationMode(tearing ? PresentationMode::AdaptiveAsync : PresentationMode::AdaptiveSync);
       } else {
           frame->setPresentationMode(tearing ? PresentationMode::Async : PresentationMode::VSync);
       }

       // collect all the layers we may use
       struct LayerData
       {
           RenderView *view;
           bool directScanout = false;
           bool directScanoutOnly = false;
           bool highPriority = false;
           Region surfaceDamage;
           uint32_t requiredAlphaBits;
       };
       QList<LayerData> layers;

       primaryView->prePaint();
       layers.push_back(LayerData{
           .view = primaryView,
           .directScanout = false,
           .directScanoutOnly = false,
           .highPriority = false,
           .surfaceDamage = Region{},
           .requiredAlphaBits = 0,
       });

       // slowly adjust the artificial HDR headroom for the next frame. Note that
       // - this has to happen (right) after prePaint, so that the scene's stacking order is valid
       // - this is only done for internal displays, because external displays usually apply slow animations to brightness changes
       if (!output->highDynamicRange() && output->brightnessDevice() && output->currentBrightness() && output->isInternal()) {
           const auto desiredHdrHeadroom = output->edrPolicy() == BackendOutput::EdrPolicy::Always ? primaryView->desiredHdrHeadroom() : 1.0;
           // just a rough estimate from the Framework 13 laptop. The less accurate this is, the more the screen will flicker during backlight changes
           constexpr double relativeLuminanceAtZeroBrightness = 0.04;
           // the higher this is, the more likely the user is to notice the change in backlight brightness
           // at the same time, if it's too low, it takes ages until the user sees the HDR effect
           constexpr double changePerSecond = 0.5;
           // to restrict HDR videos from using all the battery and burning your eyes
           // TODO make it a setting, and/or dependent on the power management state?
           constexpr double maxHdrHeadroom = 3.0;
           // = the headroom at 100% backlight
           const double maxPossibleHeadroom = (1 + relativeLuminanceAtZeroBrightness) / (relativeLuminanceAtZeroBrightness + *output->currentBrightness());
           desiredArtificalHdrHeadroom = std::clamp(desiredHdrHeadroom, 1.0, std::min(maxPossibleHeadroom, maxHdrHeadroom));
           const double changePerFrame = changePerSecond * double(frame->refreshDuration().count()) / 1'000'000'000;
           const double newHeadroom = std::clamp(*desiredArtificalHdrHeadroom, output->artificialHdrHeadroom() - changePerFrame, output->artificialHdrHeadroom() + changePerFrame);
           frame->setArtificialHdrHeadroom(newHeadroom);
       } else {
           frame->setArtificialHdrHeadroom(1);
       }

       QList<OutputLayer *> unusedOutputLayers = m_backend->compatibleOutputLayers(output);
       // the primary output layer is currently always used for the main content
       unusedOutputLayers.removeOne(primaryView->layer());

       const bool overlaysAllowed = m_allowOverlaysEnv.value_or(!output->overlayLayersLikelyBroken() && PROJECT_VERSION_PATCH >= 80);
       QList<OutputLayer *> specialLayers = unusedOutputLayers | std::views::filter([this, renderLoop, overlaysAllowed](OutputLayer *layer) {
           return layer->type() != OutputLayerType::Primary
               && (!m_brokenCursors.contains(renderLoop) || layer->type() != OutputLayerType::CursorOnly)
               && (overlaysAllowed || layer->type() != OutputLayerType::GenericLayer);
       }) | std::ranges::to<QList>();
       std::ranges::sort(specialLayers, [](OutputLayer *left, OutputLayer *right) {
           return left->maxZpos() > right->maxZpos();
       });
       const size_t maxOverlayCount = std::ranges::count_if(specialLayers, [primaryView](OutputLayer *layer) {
           return layer->maxZpos() > primaryView->layer()->zpos();
       });
       const size_t maxUnderlayCount = std::ranges::count_if(specialLayers, [primaryView](OutputLayer *layer) {
           return layer->minZpos() < primaryView->layer()->zpos();
       });
       const auto [overlayCandidates, underlayCandidates] = m_scene->overlayCandidates(specialLayers.size(), maxOverlayCount, maxUnderlayCount);
       auto overlayAssignments = assignOverlays(primaryView, underlayCandidates, overlayCandidates, specialLayers);
       if (overlayAssignments.empty()) {
           // the cursor is important, so try again without other over/underlays
           const auto cursorOnly = overlayCandidates | std::views::filter([](Item *item) {
               return qobject_cast<CursorItem *>(item) != nullptr;
           }) | std::ranges::to<QList>();
           overlayAssignments = assignOverlays(primaryView, {}, cursorOnly, specialLayers);
       }
       for (const auto &[item, layer] : overlayAssignments) {
           const bool isCursor = qobject_cast<CursorItem *>(item) != nullptr;
           auto &view = m_overlayViews[output->renderLoop()][layer];
           if (!view || view->item() != item) {
               if (isCursor) {
                   // special handling for the cursor
                   view = std::make_unique<ItemTreeView>(primaryView, item, logicalOutput, output, layer);
                   connect(layer, &OutputLayer::repaintScheduled, view.get(), [logicalOutput, output, cursorView = view.get()]() {
                       // this just deals with moving the plane asynchronously, for improved latency.
                       // enabling, disabling and updating the cursor image still happen in composite()
                       const auto outputLayer = cursorView->layer();
                       if (!outputLayer->isEnabled()
                           || !outputLayer->deviceRepaints().isEmpty()
                           || !cursorView->isVisible()
                           || cursorView->needsRepaint()) {
                           // composite() handles this
                           return;
                       }
                       std::optional<std::chrono::nanoseconds> maxVrrCursorDelay;
                       if (output->renderLoop()->activeWindowControlsVrrRefreshRate()) {
                           const auto effectiveMinRate = output->minVrrRefreshRateHz().transform([](uint32_t value) {
                               // this is intentionally using a tiny bit higher refresh rate than the minimum
                               // so that slight differences in timing don't drop us below the minimum
                               return value + 2;
                           }).value_or(30);
                           maxVrrCursorDelay = std::chrono::nanoseconds(1'000'000'000) / std::max(effectiveMinRate, 30u);
                       }
                       outputLayer->setTargetRect(mapGlobalLogicalToOutputDeviceCoordinates(cursorView->viewport(), logicalOutput, output));
                       outputLayer->setEnabled(true);
                       if (output->presentAsync(outputLayer, maxVrrCursorDelay)) {
                           // prevent composite() from also pushing an update with the cursor layer
                           // to avoid adding cursor updates that are synchronized with primary layer updates
                           outputLayer->resetRepaints();
                       }
                   });
               } else {
                   view = std::make_unique<ItemView>(primaryView, item, logicalOutput, output, layer);
               }
           }
           view->prePaint();
           layers.push_back(LayerData{
               .view = view.get(),
               .directScanout = !isCursor,
               .directScanoutOnly = !isCursor,
               .highPriority = isCursor,
               .surfaceDamage = Region(),
               .requiredAlphaBits = isCursor ? 8u : 0u,
           });
           unusedOutputLayers.removeOne(layer);
           if (layer->zpos() < primaryView->layer()->zpos()) {
               view->setUnderlay(true);
               // require more alpha bits on the primary plane,
               // otherwise shadows from windows on top of the
               // underlay will look terrible
               // TODO also make sure we still use more than 8 color bits when possible?
               layers.front().requiredAlphaBits = 8;
           } else {
               view->setUnderlay(false);
           }
       }

       // disable entirely unused output layers
       for (OutputLayer *layer : unusedOutputLayers) {
           m_overlayViews[renderLoop].erase(layer);
           layer->setEnabled(false);
           // TODO only add the layer to `toUpdate` when necessary
           toUpdate.push_back(layer);
       }

       // update all of them for the ideal configuration
       for (auto &layer : layers) {
           if (prepareDirectScanout(layer.view, logicalOutput, output, frame)) {
               layer.directScanout = true;
           } else if (!layer.directScanoutOnly && prepareRendering(layer.view, logicalOutput, output, layer.requiredAlphaBits)) {
               layer.directScanout = false;
           } else {
               layer.view->layer()->setEnabled(false);
               layer.view->layer()->scheduleRepaint(nullptr);
           }
       }

       // test and downgrade the configuration until the test is successful
       bool result = output->testPresentation(frame);
       if (!result) {
           bool primaryFailure = false;
           auto &primary = layers.front();
           if (primary.directScanout) {
               if (prepareRendering(primary.view, logicalOutput, output, primary.requiredAlphaBits)) {
                   primary.directScanout = false;
                   result = output->testPresentation(frame);
               } else {
                   primaryFailure = true;
                   // this should be very rare, but could happen with GPU resets
                   qCWarning(KWIN_CORE, "Preparing the primary layer failed!");
               }
           }
           if (!result && !primaryFailure) {
               // disable all low priority layers, and if that isn't enough
               // the high priority layers as well
               for (bool priority : {false, true}) {
                   auto toDisable = layers | std::views::filter([priority](const LayerData &layer) {
                       return layer.view->layer()->isEnabled()
                           && layer.highPriority == priority
                           && layer.view->layer()->type() != OutputLayerType::Primary;
                   });
                   if (!toDisable.empty()) {
                       for (const auto &layer : toDisable) {
                           layer.view->layer()->setEnabled(false);
                           layer.view->layer()->scheduleRepaint(nullptr);
                       }
                       result = output->testPresentation(frame);
                       if (result) {
                           break;
                       }
                   }
               }
           }
       }

       // now actually render the layers that need rendering
       if (result) {
           // before rendering, enable and disable all the views that need it,
           // which may add repaints to other layers
           for (auto &layer : layers) {
               layer.view->setExclusive(layer.view->layer()->isEnabled());
           }

           // Note that effects may schedule repaints while rendering
           renderLoop->newFramePrepared();

           for (auto &layer : layers) {
               if (!layer.view->layer()->needsRepaint()) {
                   continue;
               }
               toUpdate.push_back(layer.view->layer());
               layer.surfaceDamage |= layer.view->collectDamage();
               layer.surfaceDamage |= layer.view->layer()->deviceRepaints();
               layer.view->layer()->resetRepaints();
               if (layer.view->layer()->isEnabled() && !layer.directScanout) {
                   result &= renderLayer(layer.view, logicalOutput, output, frame, layer.surfaceDamage);
                   if (!result) {
                       qCWarning(KWIN_CORE, "Rendering a layer failed!");
                       break;
                   }
               }
           }
       } else {
           renderLoop->newFramePrepared();
       }

       // NOTE that this does not count the time spent in BackendOutput::present,
       // but the drm backend, where that's necessary, tracks that time itself
       totalTimeQuery->end();
       frame->addRenderTimeQuery(std::move(totalTimeQuery));
       if (result && !output->present(toUpdate, frame)) {
           // legacy modesetting can't do (useful) presentation tests
           // and even with atomic modesetting, drivers are buggy and atomic tests
           // sometimes have false positives
           result = false;
           // first, remove all non-primary layers we attempted direct scanout with
           auto toDisable = layers | std::views::filter([](const LayerData &layer) {
               return layer.view->layer()->type() != OutputLayerType::Primary
                   && layer.view->layer()->isEnabled()
                   && layer.directScanout;
           });
           auto &primary = layers.front();
           if (primary.directScanout || !toDisable.empty()) {
               for (const auto &layer : toDisable) {
                   layer.view->layer()->setEnabled(false);
                   layer.view->setExclusive(false);
               }
               // re-render without direct scanout
               if (prepareRendering(primary.view, logicalOutput, output, primary.requiredAlphaBits)
                   && renderLayer(primary.view, logicalOutput, output, frame, primary.surfaceDamage)) {
                   result = output->present(toUpdate, frame);
               } else {
                   qCWarning(KWIN_CORE, "Rendering the primary layer failed!");
               }
           }

           if (!result && layers.size() == 2 && layers[1].view->layer()->isEnabled()) {
               // presentation failed even without direct scanout.
               // try again even without the cursor layer
               layers[1].view->layer()->setEnabled(false);
               layers[1].view->setExclusive(false);
               if (prepareRendering(primary.view, logicalOutput, output, primary.requiredAlphaBits)
                   && renderLayer(primary.view, logicalOutput, output, frame, Region::infinite())) {
                   result = output->present(toUpdate, frame);
                   if (result) {
                       // disabling the cursor layer helped... so disable it permanently,
                       // to prevent constantly attempting to render the hardware cursor again
                       // this should only ever happen with legacy modesetting, where
                       // presentation can't be tested
                       qCWarning(KWIN_CORE, "Disabling hardware cursor because of presentation failure");
                       m_brokenCursors.insert(renderLoop);
                   }
               } else {
                   qCWarning(KWIN_CORE, "Rendering the primary layer failed!");
               }
           }
       }

       m_scene->frame(primaryView, frame.get());
       for (auto &layer : layers) {
           layer.view->postPaint();
       }

       // the layers have to stay valid until after postPaint, so this needs to happen after it
       if (!result) {
           qCWarning(KWIN_CORE, "Failed to find a working output layer configuration! Enabled layers:");
           for (const auto &layer : layers) {
               if (!layer.view->layer()->isEnabled()) {
                   continue;
               }
               qCWarning(KWIN_CORE) << "src" << layer.view->layer()->sourceRect() << "-> dst" << layer.view->layer()->targetRect();
           }
           output->repairPresentation();
       }

       const bool forceRepaintForBrightness = (frame->brightness() && std::abs(*frame->brightness() - output->brightnessSetting() * output->dimming()) > 0.001)
           || (desiredArtificalHdrHeadroom && frame->artificialHdrHeadroom() && std::abs(*frame->artificialHdrHeadroom() - *desiredArtificalHdrHeadroom) > 0.001);

       const bool forceRepaintForOffscreenAnimations = m_renderLoopDrivenAnimationDriver->isRunning();

       if (forceRepaintForBrightness || forceRepaintForOffscreenAnimations) {
           // we're currently running an animation to change the brightness
           renderLoop->scheduleRepaint();
       }
    }

    void Compositor::handleOutputsChanged()
    {
       for (auto &[loop, layer] : m_primaryViews) {
           disconnect(loop, &RenderLoop::frameRequested, this, &Compositor::handleFrameRequested);
       }
       m_overlayViews.clear();
       m_primaryViews.clear();
       const auto outputs = kwinApp()->outputBackend()->outputs();
       for (BackendOutput *output : outputs | std::views::filter(&BackendOutput::isEnabled)) {
           addOutput(output);
       }
    }

    void Compositor::addOutput(BackendOutput *output)
    {
       if (output->isPlaceholder()) {
           return;
       }
       assignOutputLayers(output);
       connect(output->renderLoop(), &RenderLoop::frameRequested, this, &Compositor::handleFrameRequested);
       connect(output, &BackendOutput::outputLayersChanged, this, [this, output]() {
           assignOutputLayers(output);
       });
    }

    void Compositor::removeOutput(BackendOutput *output)
    {
       if (output->isPlaceholder()) {
           return;
       }
       disconnect(output->renderLoop(), &RenderLoop::frameRequested, this, &Compositor::handleFrameRequested);
       disconnect(output, &BackendOutput::outputLayersChanged, this, nullptr);
       m_overlayViews.erase(output->renderLoop());
       m_primaryViews.erase(output->renderLoop());
       m_brokenCursors.erase(output->renderLoop());
    }

    void Compositor::assignOutputLayers(BackendOutput *output)
    {
       LogicalOutput *logical = workspace()->findOutput(output);
       Q_ASSERT(logical);
       const auto layers = m_backend->compatibleOutputLayers(output);
       const auto primaryLayer = findLayer(layers, OutputLayerType::Primary, std::nullopt);
       Q_ASSERT(primaryLayer);
       auto &sceneView = m_primaryViews[output->renderLoop()];
       if (sceneView) {
           sceneView->setLayer(primaryLayer);
       } else {
           sceneView = std::make_unique<SceneView>(m_scene.get(), logical, output, primaryLayer);
           sceneView->setViewport(logical->geometryF());
           sceneView->setScale(output->scale());
           sceneView->setRenderOffset(output->deviceOffset());
           connect(logical, &LogicalOutput::geometryChanged, sceneView.get(), [view = sceneView.get(), logical]() {
               view->setViewport(logical->geometryF());
           });
           connect(output, &BackendOutput::scaleChanged, sceneView.get(), [view = sceneView.get(), output]() {
               view->setScale(output->scale());
           });
           connect(output, &BackendOutput::deviceOffsetChanged, sceneView.get(), [view = sceneView.get(), output]() {
               view->setRenderOffset(output->deviceOffset());
           });
       }
       // will be re-assigned in the next composite() pass
       m_overlayViews.erase(output->renderLoop());
    }

    } // namespace KWin

    #include "moc_compositor.cpp"

    Sorry hatte ich in der eile ganz vergessen.


    LG von Schatten-Nacht 🖐🏼

    Guten Morgen Harry und Mastertac 🖐🏼,

    ich stimme euch beiden da völlig zu was die Kompatibilität angeht in PDF-Programmen hier mal ein kleiner Deepdive zu Portable Network Graphics und deren Struckturen einer PNG-Datei.


    Tag IDTag NameWritableValues / Notes
    'IHDR'ImageHeader---> PNG ImageHeader Tags
    'PLTE'Paletteno
    'acTL'AnimationControl---> PNG AnimationControl Tags
    'bKGD'BackgroundColorno
    'cHRM'PrimaryChromaticities---> PNG PrimaryChromaticities Tags
    'cICP'CICodePoints---> PNG CICodePoints Tags
    'caBX'JUMBF---> Jpeg2000 Tags
    'cpIp'OLEInfo---> FlashPix Tags
    'dSIG'DigitalSignatureno
    'eXIf'eXIf---> EXIF Tags
    (this is where ExifTool will create new EXIF)
    'fRAc'FractalParametersno
    'gAMA'Gammayes!(ExifTool reports the gamma for decoding the image, which is consistent with the EXIF convention, but is the inverse of the stored encoding gamma)
    'gIFg'GIFGraphicControlExtensionno
    'gIFt'GIFPlainTextExtensionno
    'gIFx'GIFApplicationExtensionno
    'gdAT'GainMapImageno
    'hIST'PaletteHistogramno
    'iCCP'ICC_Profile---> ICC_Profile Tags
    (this is where ExifTool will write a new ICC_Profile. When creating a new ICC_Profile, the SRGBRendering tag should be deleted if it exists)
    'iCCP-name'ProfileNameyes(not a real tag ID, this tag represents the iCCP profile name, and may only be written when the ICC_Profile is written)
    'iDOT'AppleDataOffsetsno
    'iTXt'InternationalText---> PNG TextualData Tags
    'meTa'MeTa---> XMP XML Tags
    'oFFs'ImageOffsetno
    'pCAL'PixelCalibrationno
    'pHYs'PhysicalPixel---> PNG PhysicalPixel Tags
    'sBIT'SignificantBitsno
    'sCAL'SubjectScale---> PNG SubjectScale Tags
    'sPLT'SuggestedPaletteno
    'sRGB'SRGBRenderingyes!(this chunk should not be present if an iCCP chunk exists)
    0 = Perceptual
    1 = Relative Colorimetric
    2 = Saturation
    3 = Absolute Colorimetric
    'sTER'StereoImage---> PNG StereoImage Tags
    'seAl'SEAL---> XMP SEAL Tags
    'tEXt'TextualData---> PNG TextualData Tags
    'tIME'ModifyDateyes
    'tRNS'Transparencyno
    'tXMP'XMP---> XMP Tags
    (obsolete location specified by a September 2001 XMP draft)
    'vpAg'VirtualPage---> PNG VirtualPage Tags
    'zTXt'CompressedText---> PNG TextualData Tags
    'zxIf'zxIf---> EXIF Tags
    (a once-proposed chunk for compressed EXIF)


    PNG ImageHeader Tags

    Quote
    Index1Tag NameWritableValues / Notes
    0ImageWidthno
    4ImageHeightno
    8BitDepthno
    9ColorTypeno0 = Grayscale
    2 = RGB
    3 = Palette
    4 = Grayscale with Alpha
    6 = RGB with Alpha
    10Compressionno0 = Deflate/Inflate
    11Filterno0 = Adaptive
    12Interlaceno0 = Noninterlaced
    1 = Adam7 Interlace

    PNG AnimationControl Tags

    Tags found in the Animation Control chunk. See https://wiki.mozilla.org/APNG_Specification for details.

    Quote
    Index4Tag NameWritableValues / Notes
    0AnimationFramesno
    1AnimationPlaysno

    PNG PrimaryChromaticities Tags

    Quote
    Index4Tag NameWritableValues / Notes
    0WhitePointXno
    1WhitePointYno
    2RedXno
    3RedYno
    4GreenXno
    5GreenYno
    6BlueXno
    7BlueYno


    PNG CICodePoints Tags

    These tags are found in the PNG cICP chunk and belong to the PNG-cICP family 1 group.


    PNG TextualData Tags

    The PNG TextualData format allows arbitrary tag names to be used. The tags listed below are the only ones that can be written (unless new user-defined tags are added via the configuration file), however ExifTool will extract any other TextualData tags that are found. All TextualData tags (including tags not listed below) are removed when deleting all PNG tags.

    These tags may be stored as tEXt, zTXt or iTXt chunks in the PNG image. By default ExifTool writes new string-value tags as as uncompressed tEXt, or compressed zTXt if the Compress (-z) option is used and Compress::Zlib is available. Alternate language tags and values containing special characters (unless the Latin character set is used) are written as iTXt, and compressed if the Compress option is used and Compress::Zlib is available. Raw profile information is always created as compressed zTXt if Compress::Zlib is available, or tEXt otherwise. Standard XMP is written as uncompressed iTXt. User-defined tags may set an 'iTXt' flag in the tag definition to be written only as iTXt.

    Alternate languages are accessed by suffixing the tag name with a '-', followed by an RFC 3066 language code (eg. "PNG:Comment-fr", or "Title-en-US"). See http://www.ietf.org/rfc/rfc3066.txt for the RFC 3066 specification.

    Some of the tags below are not registered as part of the PNG specification, but are included here because they are generated by other software such as ImageMagick.

    PNG PhysicalPixel Tags

    These tags are found in the PNG pHYs chunk and belong to the PNG-pHYs family 1 group. They are all created together with default values if necessary when any of these tags is written, and may only be deleted as a group.

    Quote
    Index1Tag NameWritableValues / Notes
    0PixelsPerUnitXint32u(default 2834)
    4PixelsPerUnitYint32u(default 2834)
    8PixelUnitsint8u(default meters)
    0 = Unknown
    1 = meters

    PNG SubjectScale Tags

    Quote
    Index1Tag NameWritableValues / Notes
    0SubjectUnitsno1 = meters
    2 = radians
    1SubjectPixelWidthno
    2SubjectPixelHeightno

    PNG StereoImage Tags

    Quote
    Index1Tag NameWritableValues / Notes
    0StereoModeno0 = Cross-fuse Layout
    1 = Diverging-fuse Layout

    PNG VirtualPage Tags

    Quote
    Index4Tag NameWritableValues / Notes
    0VirtualImageWidthno
    1VirtualImageHeightno
    2VirtualPageUnitsno

    Hier mal der PNG-Header:

    Code
    00000000  80 59 4e 47 0d 0a 1a 0a  00 00 00 0d 49 48 44 52  |.YNG........IHDR|
    00000010  00 00 00 00 00 00 02 f8  08 06 00 00 00 93 2f 8a  |............../.|
    00000020  6b 00 00 00 04 67 41 4d  41 00 00 9c 40 20 0d e4  |k....gAMA...@ ..|
    00000030  cb 00 00 00 20 63 48 52  4d 00 00 87 0f 00 00 8c  |.... cHRM.......|
    00000040  0f 00 00 fd 52 00 00 81  40 00 00 7d 79 00 00 e9  |....R...@..}y...|


    Wer das ganze Header-Tree via Python bauen will hier ein Codesnippet dazu:


    Und hier mal eine tolle Webseite die sogar wo ich die Grafik entnommen habe zu den Alpha-Kanal eines PNG-Files die Werte beschreibt:

    Portable Network Graphics (PNG) Specification (Third Edition)


    Wer noch tiefer in PNG-Struckturen eintauchen will den empfehle ich diese Webseiten hier:

    The PNG Image File Format

    PNG Specification: File Structure

    https://www.crisluengo.net/archives/1132/ <- sehr gute Anleitung zur Bilder Analyse by Cris "Image Analysis Blog" 👍🏼


    Und wer Bilder Zerlegen möchte kann dies mit PixelMatrix Converter tun -> https://github.com/nomadsdev/pixe…erter/tree/main

    Installation

    • Clone the Repository:

      Code
      git clone https://github.com/nomadsdev/pixel-matrix-converter.git

    Install Dependencies: Ensure you have Python installed. Install the required Python libraries using pip:

    Code
    pip install pillow numpy


    Usage

    • Convert Image to Matrix:

      • Place the images you want to convert in the bin/images directory.
      • Run the script and choose option 1 to convert images to matrix format.
      Code
      python main.py

    Convert Matrix to Image:

    • Ensure that the matrix files are in the bin/output directory.
    • Run the script and choose option 2 to convert matrix files back to images.
    Code
    python main.py

    The restored images will be saved in the bin/restored directory.


    File Structure

    • bin/images/ - Directory to place images for conversion.
    • bin/output/ - Directory where matrix files will be saved.
    • bin/restored/ - Directory where restored images will be saved.

    Example

    To convert an image to matrix format:

    Code
    python main.py

    Choose 1 and follow the instructions.

    To convert a matrix file back to an image:

    Code
    python main.py


    Ich hoffe das Hilft besser zuverstehen das ein PNG in seiner Header Strucktur sich besser in PDF und in Photoshop basierten Programmen eignet als eine TIFF-Datei zum anderen ist eine RAW export in eine PNG-Datei bei 24Bit Auflösung und einer Größe von 3850x2456 nur ca. 8 bis 9 GB groß als wie eine TIFF bei bei 24 Bit und der Gleichen Pixel Auflösung da ist eine TIFF zwischen 16 bis 20 GB groß mit dem gleichen Farbraum und dem gleichen Transparenten Alpha-Kanal.


    LG von Schatten-Nacht 🖐🏼

    TIFF-Dateien unterstützen Transparenz: https://datei.wiki/tech/kann-tif-…tergrund-haben/


    Zur Ausgangs-Frage kann ich nix sagen. Ich mach das (transparente Unterschrift) mit Okular in KDE.


    Guten Morgen und dir ein tolles neues @JensA 🖐🏼,

    zu der Aussage das TIFF Dateien Transparenz haben das stimmt nicht so ganz das TIFF-Dateien ein IFD-Metafile Stapel-Header besitzen dadurch sind TIFF-Dateien nicht mit allen Programmen was den Alpha-Kanal angeht Kompatibel.


    Hier mal die IFD-Tables

    Code
     0100 0003 0000 0001 0064 0000
          |    |    |         |
    tag --+    |    |         |
    short int -+    |         |
    one value ------+         |
    value of 100 -------------+


    Und hier mal die TIFF-Matrix in Hexbinär

    Noch ne kurze Erläuterung zu den Hexdumps in Hexabinär zu TIFF und den IFD-Tables dazu ->

    The above example uses 14dec (000eihex) directory entries.
    0100 - Image width
    0101 - Image height
    0102 - Bits per sample (8)
    0103 - Compression method (1 = uncompressed)
    0106 - Photometric Interpretation (2 = RGB)
    0111 - Strip Offsets
    0112 - Orientation (1 = 0 top, 0 left hand side) 0115 - Samples per pixel (1)
    0116 - Rows per strip (200 = image height)
    0117 - Strip Byte Counts (60000 = 100 x 200 x 3)
    0118 - Minimum sample value (0,0,0)
    0119 - Maximum sample value (255,255,255)
    011c - Planar configuration (1 = single image plane)
    0153 - Sample format

    Wer sich selbst eine TIFF bauen will kann das mit diesen Code-Snippets tun:

    Source code example

    The following is the guts of a C program to create a TIFF file of width nx, height ny. Each pixel is made up of 3 bytes, one byte for each of Red, Green, Blue. Each colour component ranges from 0 (black) to 255 (white).

    The WriteHexString() function is given below.



    Die benötigte lib heißt libtiff -> ibtiff


    While the above creates a simple TIFF file, the ultimate source/API for dealing with TIFF is the library "libtiff". This is particularly so if you wish to read TIFF files which is a non-trivial process if you wish to cover all possibilities. For example, if one wanted to determine the width and height one would not normally search for the width and height tags but rather employ something like this (courtesy Mehmet Vahit Kapar).


    Hier der Codeblock dazu:


    Wer nochtiefer einsteigen will was die RGB-Farbraum und den Alphakanäle angeht der wird hier fündig:

    Contribution by Chris Rorden

    Notes:

    • TIFF RGB images should always have a contiguous (RGBRGBRGB ...) not planar (RRR..RGGG..GBBB..B) format. While the header allows you to specify planar, it is not well supported.

    • For 16-bit data, be aware that most TIFF viewers ignore the maximum and minimum values and assume your data is scaled from 0 to 65535 (You can test this with my example).

    • For 16-bit data, it is important that the endian is set correctly.

    • For data with only one component (e.g. grayscale or black and white) you encode min, max, bits per sample directly in the tag, for RGB data the tag provides a pointer to the address for those values.

    The following example are an adaption of the above with the following additional features.

    • Works for grayscale and RGB images.


    • The TIFF writer supports 16-bit images (normalizing values to 65535, getting the endian correct)


    • Supports de-planarize RGB images.

    Example that converts popular JPEGs (uses NanoJPEG library)

    Example that copies an arcane lossless JPEG format that is popular with medical imaging to TIFF (my own library).

    https://paulbourke.net/dataformats/tiff/jpeg2tiff_50.zip

    https://paulbourke.net/dataformats/tiff/jpeg2tiff_70.zip


    Hier was es mit den IFD-Tables zu TIFF aufsich hat ->


    "There are a couple ways IFDs can be used. As the main images of a file, an extra piece of metadata, Next IFD, is included which tells applications where it can find the next IFD to read. This sequence of IFDs is called the main-IFD chain, and they are implicitly numbered based on the ordering, starting from zero."

    Der 2. IFD Table eines TIFF-Objektes ist viel Interesannter.


    Tags

    A piece of metadata, such as Next IFD, is officially named a tag. These tags are recorded within the header of an IFD and act as a kind of key/values lookup to further describe the IFD. Official TIFF specifications define common tags which range in purpose from low-level details (such as dimensions and byte offsets) to user-facing properties (such as copyrights and descriptions). Below are some examples referenced in this post.

    • Next IFD, mentioned previously, is what links an IFD with a subsequent IFD. Without the tag, applications will generally assume the IFD is the last in a file and stop processing. The value is the byte offset for the start of the target IFD within the file.
    • Subfile Type helps classify the image with a few common markers:
      • Full-resolution - indicates the image is the fullest resolution available.
      • Reduced-resolution - indicates the image has been resized down from full-resolution (which, typically, can also be found in the file).
      • Single page of multiple - indicates the image is one of many and there are typically other sibling IFDs within the file.
      • And there are several other official and vendor-conventional values that might appear, such as Transparency mask.
    • Width and Height (technically, Length) are generic tags that should always be present and describe the dimensions of an image (in pixels).
    • Page Number may be present when there is a particular ordering to multiple pages. Although IFDs are ordered within the TIFF file, that ordering shouldn't be relied on for user-facing information.
    • Image Description may be a user-supplied description about the subject of an image. Sometimes this is short and a literal description (e.g. company picnic), but other times this is used for application-specific metadata and may not be human-readable.

    Below is a more detailed version of the multipage.tif diagram shown earlier, but with the addition of some conventional tags.


    Es gibt auch noch andere Tiff-Patters innerhalb einer TIFF-Datei das sind die SubIFDs:

    "Next [Sub]IFD

    Another approach relies on both the SubIFD and Next IFD tags. A chain is started with a standard SubIFD tag pointing to a child IFD; but, from there, the Next IFD tag is used to continue the chain. In this case, an application would read the SubIFD tag once, and then sequentially seek through child IFDs until the Next IFD tags stop (similar to how the main-IFD chain would be processed)."


    Hier die Quelle dazu die ich für die kleine Info entwendet habe -> https://dpb587.me/entries/tiff-ifd-and-subifd-20240226


    Jetzt wisst ihr und vorallem DenalB warum sich eine TIFF-Datei nicht umbedingt so Flexibel für Transparente Alpha-Kanäle eignet und warum auch Programme wie Adobe Photoshop ihre Import Probleme haben bei TIFF-Dateien mit Tranparenten Alpha-Werten wegen den Stapelvektoren inner des IFD-Tables deswegen ist mir auch immer Master PDF 4.x abgestürtzt weil Master PDF 4.x nicht klar kommt mit Alpha-RGB-Werten.


    Hier noch paar Howtos was ist TIFF und die Struckturen von einer TIFF der kann hier einen Deepdive machen -> TIFF Structure -> https://deepwiki.com/geospatial-jef…-tiff-structure


    Wer nur sehr allgemein Infos zum Regulären TIFF (Tagged Image File Format) der wird hier fündig -> https://de.wikipedia.org/wiki/Tagged_Image_File_Format da ja TIFF wie schon erwähnt sehr alt ist von 1992 in Version 6.0

    Tagged Image File Format
    120px-TIFF_wordmark_logo.svg.png
    Dateiendung:.tiff, .tif
    MIME-Type:image/tiff, image/tiff-fx
    Entwickelt von:Aldus Corporation
    Aktuelle Version6.0
    (1992-06-03)
    Art:Bitmap-Grafikformat
    Erweitert zu:Exif, sDCF, TIFF/EP, TIFF/IT, GeoTIFF
    https://web.archive.org/web/2018042420…dards/TIFF.html


    Ich habe das mal im Terminal nachgestellt mit dem CLI-Tool tiffdump:

    mit der Datei -> 'Muster Unterschrift.tiff'


    Der Alpha-Kanal befindet sich weiter unten in der Konsole zweites Bild dazu ->



    Das macht es so unflexibel eine TIFF Datei mit aktiven Alpha-Kanal in ein PDF-Programm zu Importieren.


    Wer die auch Nachstellen möchte hier der Weblink zu tiffdump ->


    tiffdump Command in Linux

    Praxis naher ist da eher PNG (Portable Network Graphics)


    LG von Schatten-Nacht 🖐🏼 😎

    In der Vergangenheit gab es immer wieder mal den einen oder anderen Bug, durch den man Root-Rechte erlangen konnte.

    Aber mal zurück zum Thema.. Die Idee sich ein eigenes Sicherheitstool zu bauen, ist gar nicht mal so schlecht. Wir haben hier im Forum einige User, die Anwendungen mit grafischer Oberfläche bauen können, sogar Entwickler ganzer Distros. Das sollte eigentlich machbar sein. Klar, die Skripte und Mechanismen darunter müssen wir natürlich ebenfalls selbst mit entwickeln. Ich denke da an Tools wie AIDE, YARA, (Script>VirusTotal), Lynis usw. ein System, das Veränderungen erkennt und prüft, was da los ist. Die Ergebnisse könnten wir dann direkt hier im Forum besprechen. :/

    Das klingt echt spannend hier mal ein Video vom ehemaligen Linuxer marcus-s der Titel des Videos ist "marcus-s baut Euch eine Distro! #8: Tests mit eigenem Grafiksystem"

    External Content youtu.be
    Content embedded from external sources will not be displayed without your consent.
    Through the activation of external content, you agree that personal data may be transferred to third party platforms. We have provided more information on this in our privacy policy.


    Hier mal wenn du vorhast dies auf X11 XOrg Server selbst zu Coden -> via picom -> https://github.com/yshui/picom

    Und hier wenn du eher Wayland als Compositor mit in deine eigene Distro Einbinden willst -> https://waypp.readthedocs.io/en/latest/readme.html


    VCiel Spass beim Coden und Bauen und einen LG von Schatten-Nacht 🖐🏼

    Ich habe vor einiger Zeit einen Malware-Scanner geschrieben, der u.a. die aktuellsten Rules und Signaturen von Neo23x0 & Yara-rules herunterlädt. Basiert auf YARA, für mich der leistungsstärkste Such-Algorithmus überhaupt. Scannt Dateien und Ordner in Sekunden und ist sehr genau.

    Um das Ganze unter Arch Linux noch komfortabler zu machen, habe ich den Scanner so automatisiert, dass er meinen Downloads-Ordner in Echtzeit überwacht. Sobald eine Datei fertig heruntergeladen wurde, springt der Scanner sofort an.

    Sobald ich die Zeit dafür hab, werde ich es unter Software-Projekte öffentlich machen.


    Hallo Freedstorm 🖐🏼 tolles Python-Programm gefällt mir 👍🏼😎.

    Hallo /su, das stimmt und ja ich habe schon vieles ausprobiert und nicht alles ist toll das ist nicht die Frage ansich dunkelklausner wolltee, nur wissen ob es Sinn macht rkhunter oder Chrootkit auf Linux-Systemen im Hintergrund als Deamon oder als Socket.Service zu Fahren auf meiner Warte macht das nur Sinn wenn es sich um einen öffentlichen Server handelt wo jeder Zugriff darauf hat dann wären diese CLI-Tool Sinnvoll und Schlüssig wie die Diagnose dann ausfällt kann ich dir leider auch nicht sagen das ist dann nicht mehr mein Umfeld.


    Und Danke 👍🏼 /su das dir meine Antwort darauf was gibt weil, Wissen ist nicht gleich Wissen sondern Erfahrung ist das Wissen an solchen Methoden nicht anders herum.


    LG von Schatten-Nacht 🖐🏼

    Ja, was für ein Aufwand. Ganz einfach geht es auch über die Fritz!Box, die kann das von Haus aus und man muss nur in der fstab einen mount schreiben, um dann alles in System zu haben.

    Hallo Helmfuss, mann sollte niemals seine Skllis auf andere Linux-Benutzer Abbilden da nicht jeder Linux-Nutzer/in so gut mit Cloud-Servicen umgehen kann wie du und was das Mounting angeht da hätte ich auch noch weitere Anleitungen dazu schreiben können wie man sowas einbindet ich wollte das aber in einem anderen Weg hier aufzeigen weil, das schöne bei sowas es gibt mehrere Wege und kein Weg ist Perfekt.


    LG von Schatten-Nacht 🖐🏼

    Guten Abend Harry 🖐🏼,

    wie es möglich ist mit Master PDF 4.x TIFF-Dateien mit Transparenten Alpha-Kanal zu Impotieren.

    Ich habe mal ein Muster PDF-Dokument schon in das Programm Master PDF 4.x geladen.


    Hier mal mein Workload in Bilder bzw meine selbsterstellen Screenshots dazu:

    Schritt 1


    Schritt 2


    Schritt 3


    Schritt 4


    Schritt 5


    Schritt 6


    Schritt 7


    Schritt 8


    Schritt 9


    Bei mir ist das Master PDF 4.x mehrmals abgestürzt!


    Master PDF 4 ist also nicht zu empfehlen wenn es um veraltete Grafiken geht wie TIFF aus dem Jahre 1992.


    Du kannst es ja mal bei dir selbst Testen ich würde mich über Feedback deinerseits freuen.


    LG von Schatten-Nacht🖐🏼😎

    Hallo und Guten Morgen @defcon42, KI bzw AI im Webbrwoser braucht kein Mensch.


    Frage was soll KI bzw AI API im Webbrowser bringen mal angenommen FF hätte ein spezielles API für AI?

    Dann, welchen nutzen oder besser mehrwert bringt eine AI API im Webbrwoser mitsich!?

    Und wie verhält sich dann der Webbrowser bei dem jeweiligen Nutzer/in bei Sürfverhalten und PDF betrachtung das würde mich mal interessieren. :)


    LG Schatten-Nacht 🖐🏼

    Hallo und Guten Abend zum zweiten :)  dunkelklausner,

    zu deiner Aussage "Das Sicherheitskonzept von Linux ist zwar gut, dem von Win zumindest hoch überlegen, aber eben auch nicht ausreichend. Das Schadprogramme sich ins System nicht einfach einnisten können, weil sie dafür sudo-Rechte brauchen, ist ja schon mal ganz gut. Aber KeyLogger...da gibt es meines Wissens kein probates Mittel dagegen. Viren selbst sind nicht mehr das Problem Nr.1 (außer bei dieser Jahreszeit ;)). Spionagetools sind es."

    Das stimmt nicht ganz es gibt Möglichkeiten wie man auch ohne Root:Root via Python das Linux-System trotzdem korrumpieren kann diese Mechaniken darf ich hier aber nicht als Forensiche Anleitung posten. Zum anderen gibt es für nicht eine Garantie aber eines hast du doch ein Linux mit allen GPL3 Lizensen ist dir und gehört dir ein Windows ist niemals dir auch wenn du für 280 US Dollar einen Pro Key oder einen Pro for Workstation Key gekauft hast weil die AGBs seints Microsoft das auch in der Software-Lizens so regulieren das ein Windows niemals dir gehört du bist in einem Windos nur Nutzer / Benutzer und kein Besitzer wie in einem Unix bzw GNU/Linux System das ist ein großer Unterscheid.


    Kleiner Nachtrag ich habe noch ein Antivirus vergessen vorzustellen dies nennt sich pyvirus damit ist es genauso möglich wie mit ClamAV sein Unix-System auf Viren, Malware und Bloatware zu Testen wie das geht und was du alles Installieren musst erfährst du hier -> https://pypi.org/project/pyvirus/ weiter unten im Abschnitt "Project 2: Combined Attack (Final Project)"

    Quote

    Final Warning:
    Running this project can cause severe damage to your system. This code calls all the functionalities of the library in a combined manner. Execute it only in isolated and controlled environments (such as virtual machines).

    findest du den kompletten Codeblock zu pyvirus viel Spass bei Coden und herum experimentieren.


    LG von Schatten-Nacht 🖐🏼


    Hallo und Guten Abend /su zu deinen zwei Weblinks schau mal hier wie einfach es ist das AMSI Tool auch wenn es in Windows 10 1709 seit 2016 Implementiert zu Bypassen dieser Weblink zu Github ist nur für Bildungzwecke gedacht Bitte keine Laie und keine Anfänger da man sich sein Windows System sonst sehr schnell selbst Korrumpieren kann. -> https://github.com/klezVirus/inceptor

    Der Inspector als Bypass ist ein sehr gutes Python Toolkit hier mal die wichtigsten Encoder-Flags zu Inspector -> At the time of writing, the public version of Inceptor has been provided with the following encoders/compressors/encryptors:

    • Native
      • Xor
      • Nop (Insertion)
    • .NET
      • Hex
      • Base64
      • Xor
      • Nop (Insertion)
      • AES
      • Zlib
      • RLE
    • PowerShell
      • Hex
      • Base64
      • Xor
      • Nop (Insertion)
      • AES

    Und ja es gibt noch viele weitere solcher Toolkits im Netz die AMSI arm aussehen lassen da faktisch jedes Python Toolkit als Wrapper oder Injector nutzbar gemacht werden kann.


    LG von Schatten-Nacht 🖐🏼