Comments (62)
Hi everyone, I've merged the code in the master branch.
Expect a new signed release soon, in the meantime I'm closing this issue.
Thanks to all the testers for making this possible.
from scream.
Good! Because I have something for you :)
Before you get all excited, no, I haven't finished it yet, but I have started working on it and I have a small benchmark to test on as much machines as possible.
HOWTO INSTALL
- Add a new IVSHMEM device like this. Size should be 1M.
<shmem name='looking-glass'>
<model type='ivshmem-plain'/>
<size unit='M'>64</size>
<address type='pci' domain='0x0000' bus='0x00' slot='0x10' function='0x0'/>
</shmem>
<shmem name='scream-ivshmem'>
<model type='ivshmem-plain'/>
<size unit='M'>1</size>
<address type='pci' domain='0x0000' bus='0x00' slot='0x11' function='0x0'/>
</shmem>
It is REALLY important that the new device is enumerated after the one used by looking glass.
Currently there isn't a mechanism to differentiate between a device and another.
While I'll make sure to include some check, looking glass doesn't bother to do so. It use the 1st available shared memory.
If you swap the order you'll send audio to looking glass and video to scream. It may be a nice psychedelic show, but it's best to avoid it.
-
Start your VM.
You should see in/dev/shm/
that a new device namedscream-ivshmem
was created.
Ensure you have read permission. -
In windows ensure you see 2 IVSHMEM devices in device manager, like this.
-
Download the test program from here
-
Run the benchmark, let it run for at least 10 seconds, then post a screenshot like this
The reason for this test is to ensure that the transfer speed is high and consistent among different KVM configurations. That's why I need as much tests as possible in different environments.
- Not needed, but if you are curious you can hexdump
/dev/shm/scream-ivshmem
. You should see a 16 byte header follower by a debug string. If you keep looking you should find a sequence of blocks of 1280 bytes each, the 1st filled with 0x01, the 2nd with 0x02 and so on.
Those blocks are the chunks that will contain the scream packets. They are memory aligned for faster memory copy.
Roadmap
The scream-ivshmem-pulse receiver is almost done. It's the easiest part of the project.
What I'll do next is to modify the test program I posted here to send audible chunks instead of garbage, to test the system. It's working!!! :D it takes a raw pcm file and it send it to scream-ivshmem-pulse. I have to clean a few things, then I'll release it for testing.
For last, when the code is stable, I'll move it from the test program to the scream driver. And that's it I think.
I'll take the time to patch all the linux receivers of course.
Unfortunately I will not have much time this week so don't expect anything ready soon, but maybe I'll send other test programs.
from scream.
@gnif You are right, this is a hack, I'm well aware of that. Why do this instead of a fully fledged VirtIO sound card?
A few simple reasons: lack of experience and lack of time on my side, I've been clear on this from the start.
I evaluated both solutions and this seemed to be simpler and faster for me to implement. It's an approach that better match my background and that allowed me to deliver something rapidly.
Usually I have a daily job that's very time consuming, I don't have much free time, but given that we are around Easter and that in Italy we have a lot of holidays between April the 25th and May the 1st I decided to take a route that will allow me to deliver a functional product in this timeframe, before my job will take over again.
In the future I will love to remake this into an independent VirtIO sound card, no doubt about that, but at the moment I simply don't have the knowledge to do so. But I'm studying, and I learn fast.
Two weeks ago when all of this started I had zero experience with windows driver development, no experience with IVSHMEM or VirtIO and no experience with Scream or anything related to this project. But I worked hard night and day to learn what I had to learn and to deliver multichannel support first and then this.
This allowed me to wet my feet in this world, to start working with windows driver, to gain a bit of experience with WinDBG and other useful tools, to see if the ideas I have in my mind are viable or are a waste of time. So far I'm happy with the results and the knowledge I acquired doing this, but I know I can do much much better.
I will learn everything I'll have to learn about VirtIO, Qemu, and whatever, but in the meantime this is what I can do with the resources at my disposal. I hope you'll understand.
The road to a VirtIO driver is long, I'll have to have my code upstreamed by Qemu, and my windows driver signed and distributed. Will Qemu accept my code? Will RedHat / Fedora distribute the driver? MS-PL license allows me to do so? I don't know.
Anyway, my reasons are not important.
Quoting @paul70078 from here, the thing is allowing more than one IVSHMEM device to be in place without conflicts.
What I did here is to loop through the IVSHMEM devices and use the 1st device that have a size defined by the user in a registry key.
If I'll make a patch for looking glass host program to accept an optional command line parameter where the user can specify the size of the IVSHMEM device to use, will you be willing to accept the pull request?
from scream.
I think it's time for an Easter present to all of you guys. Scream-IVSHMEM-RC1
See the README.md inside the zip for instructions.
from scream.
You bet I'll test (and ultimately use) this too!
from scream.
Was about to run your test program but it seems like it's a debug build?
This would require me to install visual studio to get some missing dlls.
Mind doing a release build for it? Would save me a lot of trouble 😅
from scream.
Oops, you are right, my bad. I'm at work now, I'll build a release version this evening.
In the meantime I've implemented a lot more, I'll give you access to scream-ivshmem-pulse that is already working.
The build version I'll send will require you to pass a raw pcm file as an argument. At the moment it's only 44100Hz, 16bit, 2 channels, but only for my convenience. Full multichannel support is only few lines ahead.
To make a raw pcm file you can take any audio (or video) file as input and use ffmpeg like this:
ffmpeg -i <input-file> -f s16le -acodec pcm_s16le test.raw
Please make sure that test.raw is 44100Hz with 2 channels. You can see this in the output of ffmpeg.
Then in windows you can run
scream-ivshmem-test.exe test.raw
And in linux
scream-ivshmem-pulse
You should hear your test sample playing flawlessy. As a test you can kill and restart the windows binary as many times as you want while keeping the linux one running. If everything is ok it should restart playing the audio sample without crashing.
Same with the linux receiver, you should be able to kill and restart it at any moment without having to restart the windows binary. At least that's the idea.
If it crash or it produce strange behaviours let me know.
from scream.
Hi @tadly , you can download both scream-ivshmem-text.exe in release mode and scream-ivshmem-pulse source code here
Follow the instructions on my previous message. If you encounter any problem let me know.
While you are listening to some audio can you check windows task manager to measure the process usage? CPU usage should be near 0%, while memory is dependent on the file you are streaming (it's loaded in ram at the start).
Please send me the output of both windows and linux program, thank you.
from scream.
Hi everyone, figured it might not hurt posting my findings. The demo works great, I have less than 2% CPU usage, most of the time its about 0.5%.
I am a bit surprised about the rather low TX speed after the initialization, but had no dropouts. Using QEMU v4.0.0-rc3, without libvirt.
Outstanding work @martinellimarco! I will definitely use this when its ready!
from scream.
Hi @alegru , thank you for testing this!
If you use the first exe, the benchmark, you'll see unconstrained speed (100+Mbps in most cases) since it's sending random data without waiting for the receiver to pick them up.
The second one is a fully functional transmitter. It will fill the audio buffer as fast as possible (the initial spike you see). Then it will wait for the receiver to free some space in the buffer before writing anything else.
The speed you see is a constant. 44100Hz, 16bit, 2 channels = 44100*16*2/1024/1024
= 1,34 Mbps.
It will not be any faster, it doesn't have to. Instead the thread will sleep for a bit, keeping the CPU utilization low.
The fastest it will have to be is at 192kHz, 32bit, 8 channels. That's around 50Mbps, but it can handle it.
from scream.
Thank you for explaining the details! Throttling on purpose makes sense, guess I was a bit distracted because of your first screenshot with unthrottled random data.
If you need something else to test I will gladly post feedback.
from scream.
I will probably make another release of the transmitter with more command line parameters to specify the sample rate, sample size, number of channels and speaker configuration, to test the performance of the system with any kind of configuration and the stability switching from a configuration to another.
It's not too much work, really a few lines of code, but I don't have much time this week, I can work on this only at night. I expect to release this update this evening or tomorrow morning (Italian time).
This will require different raw pcm files, with matching parameters for each test. I'll take the time to document how to make those files with ffmpeg.
from scream.
Was trying to get it tested but am struggling a bit.
I'm getting Unable to enumerate the device, is it attached? 259
but my configuration seems to be fine from what I can tell.
I even removed the looking-glass shmem (including libvirtd restarts) to make sure there are no conflicts etc.
<shmem name='scream-ivshmem'>
<model type='ivshmem-plain'/>
<size unit='M'>1</size>
<address type='pci' domain='0x0000' bus='0x0b' slot='0x01' function='0x0'/>
</shmem>
-rw-rw---- 1 tadly kvm 1048576 Apr 16 10:48 /dev/shm/scream-ivshmem
from scream.
Don't ask me why but now it's working (Re-added looking-glass, did some more reboots)
Anyways, here be your stats fine sir :)
CPU initially climbed by ~1% for a few seconds (could be something else) and settled back to 7% after.
from scream.
7% ? it's a lot :( I was expecting it to stay way lower, I'll have to work more on this.
Anyway, glad it's working. There is a second parameter I've not mentioned right after the file name, it's the device index. It default to 1 but you can change it. The assumption is that the 0 is looking glass and the next one is scream, but if you remove looking glass you can pass 0 and it should work.
I'm studying a robust way to scan IVSHMEM devices and detect what is the one assigned to scream, but it's not that easy.
As a fallback I'm thinking of having a registry key to specify the device path that windows see. This way the user will always be able to override the autodetected device. I have not done any work in this regard yet.
Anyway, thanks for the test, it's good to see positive feedbacks :)
from scream.
No no no you misunderstood :)
7% is my VM at idle (for whatever reason) and running your tool does not increase this, so all is good ;)
I assume the windows path is quite an ugly one (unlike it is on linux).
I do think we should talk to the guys over at looking-glass as well for them to not assume the device.
Given how devices can't be named or anything, specifying an index is probably the nicest solution while both projects should simply default to 0.
Sure, logic could be added to e.g. check its size and determine if it's sensible to use it but that's still kind of hacky.
What I meanis, looking-glass could say: that thing's only 1M big, I can't use that
while you could say: that things >=32M, that's probably not right
Personally I've always favored explicitly doing stuff and as we're working on something that's not for the dumb consumer it doesn't have to be plug&play anyways so device-index or device-path (if documented) is IMO just fine :)
from scream.
I just noticed on the host, the CPU usage of pulseaudio and scream-ivshmem-pulse is close to 0% while the guest is transmitting audio, but 100% for scream when the transmit has not started / is finished. If the host scream process is not started, the guest uses about 20% CPU while waiting for the host to initialize the shared memory. Might need some synchronization mechanism in the driver later.
Regarding the index, I think a registry entry with the shared memory index 0-n, defaulting to 0 would be the simplest. Like if you customize unicast / port for network Scream.
from scream.
Thanks for reporting this. The reason is that at the moment I'm doing "busy waiting" for the transmitter to send. This will absolutely change in the final version and you'll always see cpu utilization at a minimum.
from scream.
Hi, @martinellimarco I'm yestaes from reddit. I'm glad to see that you are working on this project.
I came here to show my results as the other here.
https://i.imgur.com/VYfGa2z.png
https://i.imgur.com/ogIRxs2.png
I noticed the same issue as well as alegru told you.
Regards
from scream.
Hi guys, another day, another release
@1985a Hi yestaes, it's nice to see you here. Thank you for testing this, I really appreciate it.
In the new release there is:
- a fix for the high cpu usage of the client while waiting for the transmitter.
- improved transmitter cpu utilization
- improved transmitter memory usage
- full support for all the sample rates, sample sizes, number of channels and channel mapping configurations :)
At 192kHz, 32bit, 8 channels this is the kind of performance you should see for the transmitter. CPU ~1%, RAM < 1MB, average speed ~50Mbps. And, best of all, no crackling at all. :)
To create a test file for this configuration run ffmpeg like this
ffmpeg -i <input-file> -ac 8 -ar 192000 -f s32le -acodec pcm_s32le test.raw
The source can be any audio or video file, even if the number of channel, sample rate or sample size are lower. Beware that even few minutes of audio will produce a file of a few GiB.
The file I was testing for the screenshot above was 1.5GiB
To test it you'll have to pass the appropriate parameters to the transmitter.
scream-ivshmem-test.exe test.raw 192000 32 8 255
Where 192000 is the sample rate, 32 is the sample size, 8 is the number of channels and 255 is the channel map.
To test the same file you tested with the old version run this
scream-ivshmem-test.exe test.raw 44100 16 2 3
Now, if you have any problem with channels mapped in the wrong position you can replace 255 with 3. This will default to stereo and pulseaudio will mix the 8 channels to 2. It's not ideal but it works.
Not needed, but maybe you want to play around
If you want to map the channels differently you can calculate the right number for your raw pcm file summing together the numbers from this table.
Channel | Value |
---|---|
FRONT_LEFT | 1 |
FRONT_RIGHT | 2 |
FRONT_CENTER | 4 |
LOW_FREQUENCY | 8 |
BACK_LEFT | 16 |
BACK_RIGHT | 32 |
FRONT_LEFT_OF_CENTER | 64 |
FRONT_RIGHT_OF_CENTER | 128 |
BACK_CENTER | 256 |
SIDE_LEFT | 512 |
SIDE_RIGHT | 1024 |
In the example it's assumed that in the pcm file the channels are from 1 to 8 in this exact order. Summing the numbers from the 1st to the 8th you get 255.
If for any reason the channels in the raw pcm appear in an order that is not as above (eg, LOW_FREQUENCY before FRONT_CENTER) then you can't make a correct channel map.
This is not a limitation for the final product, windows will always output its stream in that order.
NOTE
There is a known bug if you use an odd number of channels (eg 6.1 surround). Don't test them now, the receiver will just crash.
This bug also affect the 3.0 release of scream, I'll patch it soon.
Enjoy! :)
from scream.
Hey everyone, time for feedback. As far as I can test, everything works as expected, but since I have a stereo only setup someone else should probably comment on the multi-channel side of things. So far, CPU utilization is much lower, always close to 0%. Only pulseaudio was working hard downsampling the 7.1 stream, which was expected. There were no audio dropouts noticable.
Like in my last comment, if the scream-ivshmem-pulse is not running and the transmitter already started, we have a CPU usage of about 20% on windows. This is actually not really problematic, since best practice would suggest the host process should already be running, waiting for the windows driver to start, not the other way around. But I am sure this is easy to fix.
Is it normal for the ivshmem address to change? I did not reboot between the two tests; is the windows process mapping the ivshmem in its process space? Will certainly study the source code when you publish it :)
As always, thank your very much for your hard work. I am sure this will supersede other virtualized audio solutions.
from scream.
Hi @alegru , thank you for your test.
Yes, it's normal that the IVSHMEM address change, for the exact reason you guessed.
It's good to know that there is no crackling on your system as well.
The high CPU utilization you see now if there is not an active receiver will completely disappear in the final product.
The thing is that at the moment the transmitter keep waiting in a loop for the other process to pickup. Once this will be converted into a proper audio driver windows will notify it once there is a "packet" to send and the driver will do absolutely nothing for the rest of the time.
If there will not be a receiver on the other side the audio will be lost, just like it happen now with the network version.
What matters is the cpu / memory usage during the actual transmission, that's the only part of the code that will end up as is in the final product.
from scream.
@martinellimarco Hi, I'm glad to see you that you are making progress on this project.
I'd like to test this, but today I have to work, so tomorrow I'm going to test this progress.
from scream.
I tried to run the test program on a Windows 7 Guest but it did not run.
from scream.
Hi there. I don't know what is the problem here today
https://imgur.com/a/DbqkT53
My user has read permission to the dev file. On the other hand, the receiver is waiting for scream server and this just it does not start.
Regards
edit: looking at my pictures I realized that the size of IVHSMEM is 64M, I don't know why is it pick up the looking glass instead.
Maybe that is the reason the receiver never start.
from scream.
@1985a that's definitively the issue, the transmitter is picking up looking glass.
Can you post here the XML part where you define the 2 IVSHMEM devices ? I need to see both looking glass and scream.
Have you changed something in the VM or was it working then after a reboot it stopped ?
Anyway, there is another parameter you can add after the last one, it's the device index. By default it takes 1, it's assumed that looking glass is the 0.
If for some reason you have them swapped you can try to add a 0 as last parameter.
@Vaporeon Thank you for taking the time to test this. Can I ask you to add more details please? What was not working exactly?
If you can please post:
- XML of your VM where you have defined the IVSHMEM device
- a screenshot of windows device manager where you can see that device
- the output of
ls -la /dev/shm/
- a screenshot of the receiver on linux
- a screenshot of the transmitter on windows
- any other info that you think may help
from scream.
@martinellimarco hi there.
I don't change anything in the VM. I'm going to test it now. Thnks.
Here is the part of the IVSHMEM devices.
<shmem name='looking-glass'>
<model type='ivshmem-plain'/>
<size unit='M'>64</size>
<address type='pci' domain='0x0000' bus='0x02' slot='0x02' function='0x0'/>
</shmem>
<shmem name='scream-ivshmem'>
<model type='ivshmem-plain'/>
<size unit='M'>1</size>
<address type='pci' domain='0x0000' bus='0x02' slot='0x03' function='0x0'/>
</shmem>
EDIT: by putting 0 at the end of the command, it works
there is the picture
https://i.imgur.com/Zn5YvmH.png
from scream.
@1985a Thank you. I was hoping for a mistake in the XML, instead it's what I was fearing.
You see, in your XML you have set two devices on the same bus, one in slot 2, one in slot 3. That's perfect.
So far in every test I did Windows respected that order. I didn't know if that was always the case, I have not looked into it in deepth.
I was hoping the order in windows was always predictable.
The user would have had to set the device index once and then enjoy his new setup forever.
In practice your report proved that it's not predictable and that windows can reorder the devices even if the user doesn't touch the configurations.
I'm curious. Does looking glass still work even if the devices are swapped? I was under the impresion that looking glass always used the first IVSHMEM device available, but maybe it skips the 1MiB one because it's too small.. I'll have to take another look at their source code. This is critical because I don't want this to interfere with looking glass in any way.
Anyway, I have a couple of ideas for autoselecting the right IVSHMEM device. If looking glass can't do this for any reason maybe I can contribute a patch to their code too.
from scream.
@martinellimarco Haven't had time to test your new stuff yet (I'm really sorry) but can at least answer your question in regards to looking glass...
Looking glass will just fail if the device it picks is to small. Don't remember the exact issue but for me, it never worked with both ivshmem configured.
This is also why I previously mentioned that we should open a issue over at looking-glass so they can harden their implementation as well. I'm referring to my comment here
Browsing through the the registry it at least seems like windows isn't recreating them with new ids.
So we could either:
- require the user to specify the Device Path/Hardware ID
More work for the user but less likely to cause issues - Check how big the memory device is and decide whether or not it's feasible to use.
Less/no work for the user but more likely to go south if other memory devices exist
looking-glass would have to do the same.
from scream.
@martinellimarco On windows 7 Scream-IVSHMEM-test.exe
Crashes on run with the arguments test.raw 192000 32 8 255 0
, using a ~1.6GB test file.
I have only one IVSHMEM Device and am not using looking glass, I also only run Qemu from the command line.
The relevant arguments are:
-device ivshmem-plain,memdev=ivshmem
-object memory-backend-file,id=ivshmem,share=on,mem-path=/dev/shm/scream,size=1M
The host side pulse application reports it is waiting for scream to initialize the shared memory.
Also, I'm using the IVSHMEM device driver found here:
virtio-win/kvm-guest-drivers-windows#217
from scream.
Regarding device order, I just tested scream and looking together. It works fine if specified like this on the command line:
OPTS+=" -device ivshmem-plain,memdev=ivshmem-looking-glass"
OPTS+=" -object memory-backend-file,size=32M,id=ivshmem-looking-glass,share=on,mem-path=/dev/shm/looking-glass"
OPTS+=" -device ivshmem-plain,memdev=ivshmem-scream"
OPTS+=" -object memory-backend-file,size=1M,id=ivshmem-scream,share=on,mem-path=/dev/shm/scream"
As soon as I switched the order, Windows also enumerated them with scream first and looking glass second. Of course, since looking glass is hard coded to use the first device, it crashes silently; but scream works if I specify device 0 on the command line.
Maybe I am lucky, but on my setup Windows orders the devices just as specified on the qemu command line...
from scream.
@alegru and @tadly , thank you for confirming that looking glass fails if the devices are in the wrong order. I will get in contact with them to find a solution.
@alegru In all my tests windows always respected the order of the devices and thanks to that looking glass never failed, but the report of @1985a showed that this is not always the case, so yes, I think both of us are lucky.
I remember a similar situation in linux where devices (usually hard disks or network cards) showed up in different orders depending on the time the controller took to initialize the device. Maybe this is something similar, while most of the time the devices are initialized in the same order sometime they end up reversed. I'm really speculating here, I'll have to dig a bit deeper in the details.
@tadly the hardware IDs are the same for both IVSHMEM devices. There are other differences like the "Device BIOS Name" or the "Physical Device Name", but I don't know if when the device are detected in a different order those IDs change. Sorry, I don't have the names in english, I'm translating them and the actual names may be differents.
I can think of a few solutions (ignoring for a moment looking glass)
Option 1
as @tadly said, the driver will check for the memory size and will select the device with less memory.
Pros: very easy
Cons: not future proof. Now we are dealing with only 2 devices, but what if some day someone else invent a new something that requires IVSHMEM?
Option 2
- the receiver write a magic number at the beginning of the shared memory
- the transmitter / driver loop trought the IVSHMEM devices and it peeks the first bytes in search of the magic number
- if no such number is found then the transmitter will retry at a later point in time, otherwhise from that point onward that device will be the chosen one
Pros: easy, future proof, it doesn't require any configurationa from the user
Cons: I don't know if this can interfere with looking glass. I have to read their source code in details.
Option 3
- investigate if IVSHMEM IOCTLs provide a way to identify the devices
@Vaporeon thank you, I'll make sure to test on win7, but I don't have one at hand now, it will require some days. In the meanime can you test with stereo? (44100 16 8 3 0)
from scream.
@Vaporeon is it possible that IVSHMEM is not working in Win 7 ? See this
from scream.
Good morning everyone here.
@martinellimarco you have to excuse me. Today while I was brushing my teeth it came to my brain an image. That day I was making a tutorial for my personal blog, so I installed a new USB device, a network card then uninstalled it.
BTW, this is my blog. It is in spanish, but I drop the things I consider very important to save.
from scream.
@1985a oh! Ok, so maybe that's the reason.. I'm investigating what's the supposed behaviour. At the moment I'm setting up different VMs with different configurations and multiple IVSHMEM devices each to test the edge cases. We'll see.
off topic: I tried to visit your blog but it's not working, it redirect me to https://nautilus.tcp4.me/wordpress/?p=1047 and then I get an ERR_CONNECTION_RESET
from scream.
Just saw (and tried) this and its awesome 👍
Have you already tried integrating it in scream? Or can you share the windows application? I'd like to use it as my audio device for my (new) looking glass system :)
from scream.
I know I'll make myself unpopular by saying this but it really grinds my gear when people don't even spend the necessary 10 seconds to read the original post to see what this issues intent is.
Obviously @martinellimarco is trying to integrate it into scream (hence why this issue exists) and if he would have working prototype he would have posted so already.
I'm not trying to be a dick (even though I sound like one right now) but please, just spend the few minutes to go through the issue (in general, not just this one) FIRST before posting irrelevant stuff notifying everyone involved etc.
Sorry for the (also kinda irrelevant) rant.
from scream.
@tadly sorry for my previous post. I didn't managed to say what I meant with it. And your rant is absolutely correct because I sound like a dick.
I've read most of this thread and really like it. What i wanted to know is if @martinellimarco already started at the implementation in scream or if he would share his sample application (i don't know it this application uses scream or code from it in some way) so it would be possible to start implementing it in scream while he works on the device detection. I do programming in C/C++ myself and would like to help :)
from scream.
@paul70078 I'll share it when it's ready to test. At the moment you'll get a BSOD so... not yet.
I was hoping to release something this weekend, but there is a bug I'm facing with the kernel memory manager, due to my lack of experience in windows driver development I guess. I know I will fix it, but I don't know how long it will take. If you have experience with this any help is well accepted.
Aside from this, here's a checklist of what I've done and what's left to do.
Task | Status |
---|---|
Userspace tests to see if this is viable | Done, it's the program I've already published here |
Have Scream detect a registry key to enable IVSHMEM instead of network | Done |
Have Scream switch from network to IVSHMEM | Done, original Scream have CSaveData, the new one have CSaveData and CIVSHMEMSaveData |
Enumerate IVSHMEM devices from kernel space | Done, I can enumerate all the IVSHMEM devices (so far tested with 10 devices) |
Do IOCTLs to enumerated devices | Done, I can talk to IVSHMEM devices from kernel space! :D |
Detect the right IVSHMEM device based on device size and order | Done, I can detect the size of all IVSHMEM devices. At the moment the rule is "select the 1st one that have size = 1MB". The size will be configurable. |
Have access to the shared memory (PCI BAR2 of IVSHMEM) | Done, I can read and write, linux can see this in /dev/shm/ |
Pass configurations such sample rate, sample size, channels, channel mapping and status from Scream to the receiver | (Almost) done. The configurations are passed correctly, the receiver detect them and setup the correct Pulseaudio parameters, but I think I'll have to review a few things here. |
Write the PCM samples from windows internal buffer to the shared memory. | BSOD :( I'm studying how to fix this at the moment, but it takes ages. Windos crash, reboot a few times, go in recovery mode, uninstall the driver, reboot, try another one, BSOD and repeat. I'm debugging with WinDBG, if someone have experience with it any tip to speedup this process is appreciated. |
Performance check | WIP |
Test on multiple setups and environments | ToDo, here I'll ask your help guys |
Review it all and clean the code | ToDo |
Request a PR | ToDo |
from scream.
Regarding the BSOD, I can take a look at the code if you like. Is it checked into your clone repo?
from scream.
Not yet, the code is a bit messy, I want to clean it up first.
I think I have just figured out the root cause, I'll try to explain so maybe you can tell me if I'm on the right track, or if you know how to deal with it.
At the moment I do an IOCTL to IVSHMEM to request a pointer to the shared memory.
This work, I can read and write from the function that called this and other functions called in the same context.
I then save this pointer for later use. When WriteData is invoked (suppose we are talking about savedata.cpp, I strarted from there) I try to read / write from that same pointer and it crash (but not 100% of the time).
Looking at IVSHMEM source code here I see that they call MmMapLockedPagesSpecifyCache with the UserMode so the address that they return to me is not always valid.
Do you know if there is a way to "convert" this to KernelMode so I access to it in any context?
I'm reading about MDLs but I admin that's a concept I have yet to grasp.
I think a solution would be to send a PR for IVSHMEM to have a parameter in the IOCTL to select UserMode or KernelMode but I fear this will take ages to be merged and distributed.
from scream.
I think you should not use pointers to foreign driver mem in the interrupt hot path. Did you try keeping the internal ring buffer, and copying the data further in a worker (like the networked version does with CSaveData::SendData?
from scream.
Yeah, I totally agree with you and that's how I'm doing it, but it's the same thing, the worker doesn't have access to that memory address too.
The code is organized the same way as CSaveData, with WriteData that fill a ring buffer and launch a worker that when invoked execute SendData.
In SendData it crashed 100% of the time, so to better understand the problem I've started testing where it was working and where it wasn't, going backward (SendData -> SendDataWorkerCallback -> WriteData).
Finally in WriteData I had some success, it crashed most of the times, but once in a while I could see the audio chunks being copied in the shm from linux, that's why I mentioned it.
from scream.
I see. What bugcheck code do you get when writing in SendData?
from scream.
Bugcheck 7E, exception code 0xc0000005, attempt to read from address 0x000001bede7f004.
That's the address returned by the IVSHMEM IOCTL during initialization.
As a test, I'm thinking of calling again the REQUEST_MMAP and RELEASE_MMAP IOCTLs in SendData to see if it works. I have to go out an hour, then I'll test this if you don't have another idea.
from scream.
OK then I guess your assumption here is correct:
Looking at IVSHMEM source code here I see that they call MmMapLockedPagesSpecifyCache with the UserMode so the address that they return to me is not always valid.
That is probably meant as a userspace API.
from scream.
Calling REQUEST_MMAP and RELEASE_MMAP in the worker does seem to work. I'll have to test the performance of this but at the moment it doesn't seem to be noticeable.
from scream.
Teaser trailer :)
It's 2:50 in the morning here, but I wanted to share it with you guys. It's working!! :)
It's not ready to be released yet, I need to clanup the code a lot, tune a few things and test it more but if it's not tomorrow then Monday.
So far I listened to half an hour of music at 192kHz, 32bit, 8 channels (downmixed to 2 channels by pulseaudio) and I couldn't hear a single crack in the sound, so it's promising, but the system was not doing much in the background, I'll need to stress test it.
from scream.
Congrats, and happy Easter :)
from scream.
Why use IVSHMEM for this? It's a huge hack. QEMU is open source, why not write a virtual PCI device to Qemu specifically for this purpose? As in a VirtIO sound card.
from scream.
One option would be to specify the IVSHMEM device used by the PCI location triple (bus, address, function). These values are configureable with libvirt and can be read via the Windows API. The Windows application could have default values to look for (bus, address) and the option to configure these values as the user (e.g. commandline parameters)
from scream.
If I'll make a patch for looking glass host program to accept an optional command line parameter where the user can specify the size of the IVSHMEM device to use, will you be willing to accept the pull request?
I have already started on this and @tadly opened at issue over at Looking Glass.
from scream.
@paul70078 yes, I quoted you from that issue in my reply. It didn't occur to me that you already started working on a patch. I'll leave it to you then, thank you :)
from scream.
Wow, what can I say - the driver works as expected 👍
As soon as I remembered that you need Windows test mode for unsigned drivers, I got it installed.
Just run BCDEDIT –Set TESTSIGNING ON
in a privileged console, reboot.
The host application updates its configuration for pulseaudio immediately while playing around in the sound driver settings. As promised, CPU usage is near 0%, with no noticeable latency (at least for me). Great job! I will continue testing tomorrow, at different workloads and such.
Happy Easter :)
from scream.
Thank you @alegru , it's good to know that it's working well on other systems :)
You are right about the test mode for unsigned drivers, I forgot to mention that in the readme.
from scream.
Hi, I'm testing this new RC. TL;DR lol, it works perfectly. As alegru said that the CPU usage is near to 0%, if you are using 48000Hz 16Bits 6C. Congratulations @martinellimarco and the other people who made this possible.
from scream.
Thank you @1985a :) Off topic: I was able to see your blog using a proxy (it doesn't work directly), nice job!
from scream.
Hi there, @martinellimarco off topic, Thanks you. Now that you told me you were able to see through a proxy, I realized that a long time ago, when I configure the server, I put in some countries in the ban list. Italy is one of them.
This was made by using ipset through iptables rules.
https://i.imgur.com/n31puxg.png
from scream.
For those of you that are interested I've just released the ivshmem-alsa receiver. You can get the source code here
from scream.
"Scream-IVSHMEM-RC1" working great here (Arch, QEMU 4.0, Win10 Guest), 1 MiB seems to be enough even for the highest selectable quality (using 2 channels). No noticeable CPU usage at all 👍 (0% idle, 1% playing, but that's just VLC) Thank you very much!
from scream.
@PiMaker Thank you for your feedback! :)
Out of curiosity, have you tested the pulseaudio receiver or the alsa one?
from scream.
@martinellimarco I tested the pulseaudio one. Didn't test the alsa one, and I since had to revert back to the network-based driver since yours is unsigned (which interfers with anti-cheat software, sadly).
from scream.
Related Issues (20)
- Please extend support to >8 channels (e.g. Atmos is 7.1.4 (12ch)) HOT 4
- Updating drivers for *Scream from `\Scream\Install\driver\x64\Scream.inf` HOT 11
- Uninstall driver
- can ScreamReader windows support for unicast? can ffmpeg's ffplay.exe recieve pcm stream?
- IPv6 multicast and unicast support
- Install fail in 22H2, new workaround found HOT 7
- asio4all support
- PipeWire support HOT 1
- glitchy sound after sleep+wake on windows
- Streaming stopped working on Windows 11 after Nov update, driver reports no issues HOT 1
- Blue screen while install driver on windows 7 HOT 1
- Certificate from Tom is not valid anymore HOT 5
- Rocksmith 2014 no audio output detected
- Installation fails on Windows 11 HOT 3
- Scream stream mixer+router, python receiver HOT 4
- Why is the 24-bit configuration doubled? HOT 1
- Loud static pulse after media paused
- Linux Audio Host Can't playback input from two different scream audio machines. (only 1) HOT 6
- 'Scream' Name
- Front/Back channels randomly switch. HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from scream.