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:
Bluetooth codecs (ACC, SBC, AptX, LDAC) - Audiophonics Blogwww.audiophonics.frWer 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:
Code
Display More< ACL data: handle 256 flags 0x00 dlen 20 L2CAP(d): cid 0x0043 len 16 [psm 25] AVDTP(p): Set config cmd: transaction 8 nsp 0x00 ACP SEID 1 - INT SEID 9 Media Transport Media Codec - SBC 48kHz JointStereo 16 Blocks 8 Subbands Loudness Bitpool Range 2-52 Delay ReportingMaximum 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):
Code165 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/libsbcContribute to google/libsbc development by creating an account on GitHub.github.comIch 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 recordingI 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´sLABHeute 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, PDFALC1200 Datasheet. Part #: ALC12. Datasheet: 5MbKb/66P. Manufacturer: Kemet Corporation. Description: Aluminum Electrolytic Capacitors. 2 Results. Datasheet:…www.alldatasheet.netBillig 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 0RFA - 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 = 8Recommended 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 fragmentedSBC 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:
- sie nimmt eine Symmetrierung des Signals vor und,
- für uns vielleicht am Wichtigsten, sie sorgt für eine galvanische Trennung der Kabel.
- 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.comDeswegen 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 ID Tag Name Writable Values / Notes 'IHDR' ImageHeader - --> PNG ImageHeader Tags 'PLTE' Palette no 'acTL' AnimationControl - --> PNG AnimationControl Tags 'bKGD' BackgroundColor no 'cHRM' PrimaryChromaticities - --> PNG PrimaryChromaticities Tags 'cICP' CICodePoints - --> PNG CICodePoints Tags 'caBX' JUMBF - --> Jpeg2000 Tags 'cpIp' OLEInfo - --> FlashPix Tags 'dSIG' DigitalSignature no 'eXIf' eXIf - --> EXIF Tags
(this is where ExifTool will create new EXIF)'fRAc' FractalParameters no 'gAMA' Gamma yes! (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' GIFGraphicControlExtension no 'gIFt' GIFPlainTextExtension no 'gIFx' GIFApplicationExtension no 'gdAT' GainMapImage no 'hIST' PaletteHistogram no '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' ProfileName yes (not a real tag ID, this tag represents the iCCP profile name, and may only be written when the ICC_Profile is written) 'iDOT' AppleDataOffsets no 'iTXt' InternationalText - --> PNG TextualData Tags 'meTa' MeTa - --> XMP XML Tags 'oFFs' ImageOffset no 'pCAL' PixelCalibration no 'pHYs' PhysicalPixel - --> PNG PhysicalPixel Tags 'sBIT' SignificantBits no 'sCAL' SubjectScale - --> PNG SubjectScale Tags 'sPLT' SuggestedPalette no 'sRGB' SRGBRendering yes! (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' ModifyDate yes 'tRNS' Transparency no '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
QuoteIndex1 Tag Name Writable Values / Notes 0 ImageWidth no 4 ImageHeight no 8 BitDepth no 9 ColorType no 0 = Grayscale
2 = RGB
3 = Palette
4 = Grayscale with Alpha
6 = RGB with Alpha10 Compression no 0 = Deflate/Inflate 11 Filter no 0 = Adaptive 12 Interlace no 0 = Noninterlaced
1 = Adam7 InterlacePNG AnimationControl Tags
Tags found in the Animation Control chunk. See https://wiki.mozilla.org/APNG_Specification for details.
QuoteIndex4 Tag Name Writable Values / Notes 0 AnimationFrames no 1 AnimationPlays no PNG PrimaryChromaticities Tags
QuoteIndex4 Tag Name Writable Values / Notes 0 WhitePointX no 1 WhitePointY no 2 RedX no 3 RedY no 4 GreenX no 5 GreenY no 6 BlueX no 7 BlueY no PNG CICodePoints Tags
These tags are found in the PNG cICP chunk and belong to the PNG-cICP family 1 group.
QuoteDisplay MoreIndex1 Tag Name Writable Values / Notes 0 ColorPrimaries no 1 = BT.709
2 = Unspecified
4 = BT.470 System M (historical)
5 = BT.470 System B, G (historical)
6 = BT.601
7 = SMPTE 240
8 = Generic film (color filters using illuminant C)
9 = BT.2020, BT.2100
10 = SMPTE 428 (CIE 1921 XYZ)
11 = SMPTE RP 431-2
12 = SMPTE EG 432-1
22 = EBU Tech. 3213-E1 TransferCharacteristics no 0 = For future use (0)
1 = BT.709
2 = Unspecified
3 = For future use (3)
4 = BT.470 System M (historical)
5 = BT.470 System B, G (historical)
6 = BT.601
7 = SMPTE 240 M
8 = Linear
9 = Logarithmic (100 : 1 range)
10 = Logarithmic (100 * Sqrt(10) : 1 range)
11 = IEC 61966-2-4
12 = BT.1361
13 = sRGB or sYCC
14 = BT.2020 10-bit systems
15 = BT.2020 12-bit systems
16 = SMPTE ST 2084, ITU BT.2100 PQ
17 = SMPTE ST 428
18 = BT.2100 HLG, ARIB STD-B672 MatrixCoefficients no 0 = Identity matrix
1 = BT.709
2 = Unspecified
3 = For future use (3)
4 = US FCC 73.628
5 = BT.470 System B, G (historical)
6 = BT.601
7 = SMPTE 240 M
8 = YCgCo
9 = BT.2020 non-constant luminance, BT.2100 YCbCr
10 = BT.2020 constant luminance
11 = SMPTE ST 2085 YDzDx
12 = Chromaticity-derived non-constant luminance
13 = Chromaticity-derived constant luminance
14 = BT.2100 ICtCp3 VideoFullRangeFlag no 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.
QuoteDisplay MoreTag ID Tag Name Writable Values / Notes 'Artist' Artist string (unregistered) 'Author' Author string 'Collection' Collection string 'Comment' Comment string 'Copyright' Copyright string 'Creation Time' CreationTime string (stored in RFC-1123 format and converted to/from EXIF format by ExifTool) 'Description' Description string 'Disclaimer' Disclaimer string 'Document' Document string (unregistered) 'Label' Label string (unregistered) 'Make' Make string (unregistered) 'Model' Model string (unregistered) 'Raw profile type 8bim' Photoshop_Profile - --> Photoshop Tags
(unregistered)'Raw profile type APP1' APP1_Profile - --> EXIF Tags
--> XMP Tags
(unregistered)'Raw profile type exif' EXIF_Profile - --> EXIF Tags
(unregistered)'Raw profile type icc' ICC_Profile - --> ICC_Profile Tags
(unregistered)'Raw profile type icm' ICC_Profile - --> ICC_Profile Tags
(unregistered)'Raw profile type iptc' IPTC_Profile - --> Photoshop Tags
(unregistered. May be either IPTC IIM or Photoshop IRB format. This is where ExifTool will add new IPTC, inside a Photoshop IRB container)'Raw profile type xmp' XMP_Profile - --> XMP Tags
(unregistered)'Software' Software string 'Source' Source string 'TimeStamp' TimeStamp string (unregistered) 'Title' Title string 'URL' URL string (unregistered) 'Warning' PNGWarning string 'XML:com.adobe.xmp' XMP - --> XMP Tags
(unregistered, but this is the location according to the June 2002 or later XMP specification, and is where ExifTool will add a new XMP chunk if the image didn't already contain XMP)'aesthetic_score' AestheticScore string (unregistered) 'create-date' CreateDate string (unregistered) 'modify-date' ModDate string (unregistered) 'parameters' Parameters string (unregistered) 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.
QuoteIndex1 Tag Name Writable Values / Notes 0 PixelsPerUnitX int32u (default 2834) 4 PixelsPerUnitY int32u (default 2834) 8 PixelUnits int8u (default meters)
0 = Unknown
1 = metersPNG SubjectScale Tags
QuoteIndex1 Tag Name Writable Values / Notes 0 SubjectUnits no 1 = meters
2 = radians1 SubjectPixelWidth no 2 SubjectPixelHeight no PNG StereoImage Tags
QuoteIndex1 Tag Name Writable Values / Notes 0 StereoMode no 0 = Cross-fuse Layout
1 = Diverging-fuse LayoutPNG VirtualPage Tags
QuoteIndex4 Tag Name Writable Values / Notes 0 VirtualImageWidth no 1 VirtualImageHeight no 2 VirtualPageUnits no Hier mal der PNG-Header:
Code00000000 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:
Code
Display Moreimport os import binascii import struct misc = open("misc4.png","rb").read() for i in range(1024): data = misc[12:16] + struct.pack('>i',i)+ misc[20:29] crc32 = binascii.crc32(data) & 0xffffffff if crc32 == 0x932f8a6b: print(i)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:
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:
Install Dependencies: Ensure you have Python installed. Install the required Python libraries using pip:
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.
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.
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:
Choose 1 and follow the instructions.
To convert a matrix file back to an image:
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
Code0100 0003 0000 0001 0064 0000 | | | | tag --+ | | | short int -+ | | one value ------+ | value of 100 -------------+Und hier mal die TIFF-Matrix in Hexbinär
Code
Display More4d4d 002a 0000 ea68 ffff ff00 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 .... .... black 0's deleted .... .... 0000 0000 00ff ffff 000e 0100 0003 0000 0001 0064 0000 0101 0003 0000 0001 00c8 0000 0102 0003 0000 0003 0000 eb16 0103 0003 0000 0001 0001 0000 0106 0003 0000 0001 0002 0000 0111 0004 0000 0001 0000 0008 0112 0003 0000 0001 0001 0000 0115 0003 0000 0001 0003 0000 0116 0003 0000 0001 00c8 0000 0117 0004 0000 0001 0000 ea60 0118 0003 0000 0003 0000 eb1c 0119 0003 0000 0003 0000 eb22 011c 0003 0000 0001 0001 0000 0153 0003 0000 0003 0000 eb28 0000 0000 0008 0008 0008 0000 0000 0000 00ff 00ff 00ff 0001 0001 0001Noch 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 formatWer 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).
Code
Display More/* Write the header */ WriteHexString(fptr,"4d4d002a"); /* Big endian & TIFF identifier */ offset = nx * ny * 3 + 8; putc((offset & 0xff000000) / 16777216,fptr); putc((offset & 0x00ff0000) / 65536,fptr); putc((offset & 0x0000ff00) / 256,fptr); putc((offset & 0x000000ff),fptr); /* Write the binary data */ for (j=0;j<ny;j++) { for (i=0;i<nx;i++) { ... calculate the RGB value between 0 and 255 ... fputc(red,fptr); fputc(green,fptr); fputc(blue,fptr); } } /* Write the footer */ WriteHexString(fptr,"000e"); /* The number of directory entries (14) */ /* Width tag, short int */ WriteHexString(fptr,"0100000300000001"); fputc((nx & 0xff00) / 256,fptr); /* Image width */ fputc((nx & 0x00ff),fptr); WriteHexString(fptr,"0000"); /* Height tag, short int */ WriteHexString(fptr,"0101000300000001"); fputc((ny & 0xff00) / 256,fptr); /* Image height */ fputc((ny & 0x00ff),fptr); WriteHexString(fptr,"0000"); /* Bits per sample tag, short int */ WriteHexString(fptr,"0102000300000003"); offset = nx * ny * 3 + 182; putc((offset & 0xff000000) / 16777216,fptr); putc((offset & 0x00ff0000) / 65536,fptr); putc((offset & 0x0000ff00) / 256,fptr); putc((offset & 0x000000ff),fptr); /* Compression flag, short int */ WriteHexString(fptr,"010300030000000100010000"); /* Photometric interpolation tag, short int */ WriteHexString(fptr,"010600030000000100020000"); /* Strip offset tag, long int */ WriteHexString(fptr,"011100040000000100000008"); /* Orientation flag, short int */ WriteHexString(fptr,"011200030000000100010000"); /* Sample per pixel tag, short int */ WriteHexString(fptr,"011500030000000100030000"); /* Rows per strip tag, short int */ WriteHexString(fptr,"0116000300000001"); fputc((ny & 0xff00) / 256,fptr); fputc((ny & 0x00ff),fptr); WriteHexString(fptr,"0000"); /* Strip byte count flag, long int */ WriteHexString(fptr,"0117000400000001"); offset = nx * ny * 3; putc((offset & 0xff000000) / 16777216,fptr); putc((offset & 0x00ff0000) / 65536,fptr); putc((offset & 0x0000ff00) / 256,fptr); putc((offset & 0x000000ff),fptr); /* Minimum sample value flag, short int */ WriteHexString(fptr,"0118000300000003"); offset = nx * ny * 3 + 188; putc((offset & 0xff000000) / 16777216,fptr); putc((offset & 0x00ff0000) / 65536,fptr); putc((offset & 0x0000ff00) / 256,fptr); putc((offset & 0x000000ff),fptr); /* Maximum sample value tag, short int */ WriteHexString(fptr,"0119000300000003"); offset = nx * ny * 3 + 194; putc((offset & 0xff000000) / 16777216,fptr); putc((offset & 0x00ff0000) / 65536,fptr); putc((offset & 0x0000ff00) / 256,fptr); putc((offset & 0x000000ff),fptr); /* Planar configuration tag, short int */ WriteHexString(fptr,"011c00030000000100010000"); /* Sample format tag, short int */ WriteHexString(fptr,"0153000300000003"); offset = nx * ny * 3 + 200; putc((offset & 0xff000000) / 16777216,fptr); putc((offset & 0x00ff0000) / 65536,fptr); putc((offset & 0x0000ff00) / 256,fptr); putc((offset & 0x000000ff),fptr); /* End of the directory entry */ WriteHexString(fptr,"00000000"); /* Bits for each colour channel */ WriteHexString(fptr,"000800080008"); /* Minimum value for each component */ WriteHexString(fptr,"000000000000"); /* Maximum value per channel */ WriteHexString(fptr,"00ff00ff00ff"); /* Samples per pixel for each channel */ WriteHexString(fptr,"000100010001");The WriteHexString() function is given below.
Code
Display Morevoid BM_WriteHexString(FILE *fptr,char *s) { unsigned int i,c; char hex[3]; for (i=0;i<strlen(s);i+=2) { hex[0] = s[i]; hex[1] = s[i+1]; hex[2] = '\0'; sscanf(hex,"%X",&c); putc(c,fptr); } }
Die benötigte lib heißt libtiff -> ibtiffWhile 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:
C
Display More#include <stdio.h> #include <stdlib.h> #include "tiffio.h" main(int argc,char **argv) { TIFF* tif = TIFFOpen(argv[1],"r"); if (tif) { uint32 w, h; size_t npixels; uint32* raster; TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h); TIFFClose(tif); } exit(0); }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 
Dateiendung: .tiff, .tif MIME-Type: image/tiff, image/tiff-fx Entwickelt von: Aldus Corporation Aktuelle Version 6.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 ->
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.beContent 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 👍🏼😎.
-
Display More
Moin Schatten-Nacht
Natürlich gibt es solche Kits aber meinst du nicht es ist ein Unterschied ob sowas offenliegt und von jedem eingesehen werden kann oder erarbeitet werden muss.
Nichts in dieser Welt ist unknackbar, es ist halt nur die Frage wie einfach es einem gemacht wird.
Du hast dich ja sehr eingebracht in das Thema.Finde ich Klasse, jede technische Diskussion ist es Wert weiter geführt zu werden. 👍 👏
Nur nutzt das wirklich jemandem?
Jeder der sich ein bisschen Auskennt und Gedanken dazu macht wird einen Weg finden, behaupte ich einfach mal.
Bis dann
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)"
QuoteFinal 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 🖐🏼
-
Display More
Wenn die AMSI offen liegen würde.
Ich rede jetzt speziell von Windows.
Wo läge der nutzen ?
edit:Antimalware Scan Interfaceedit2: https://learn.microsoft.com/de-de/windows/…nterface-portal <- ganz grusselig
edit:3 https://de.wikipedia.org/wiki/Antimalware_Scan_Interface <- ich bekomme würgereitz
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 🖐🏼
- Native