C++ Microphone Input As A Random Seed - c++

I am currently playing around with some cryptography (RSA Public Key, in this case) and in order to generate a random key I need a random input. I figured the microphone would be a good source for relatively unreplicatable data. Is there any way to read the raw data out of a microphone in a way that can be used as to seed srand? Is there a better way to get a purely random seed and if so how would I do it?
I am running Windows 8 on a laptop with a built in mic and I am using the g++ compiler.

Do not try to get seed from hardware yourself. The OS knows a lot more than you about how to get quality randomness.
On Linux, the correct way is to read /dev/urandom (not /dev/random; it is actually worthless)
On Windows, Google indicates that you should use the CryptGenRandom function.

Related

real time audio processing in C++

I want to produce software that reads raw audio from an external audio interface (Focusrite Scarlett 2i2) and processes it in C++ before returning it to the interface for playback. I currently run Windows 8 and was wondering how to do this with minimum latency?
I've spent a while looking into (boost) ASIO but the documentation seems fairly poor. I've also been considering OpenCL but I've been told it would most likely have higher latency. Ideally I'd like to be able to just access the Focusrite driver directly.
I'm sorry that this is such an open question but I've been having some trouble finding educational materiel on Audio Programming, other than just manipulating the audio when provided by a third party plug in design suite such as RackAFX. I'd also be grateful if anyone could recommend some reading on low level stuff like this.
You can get very low latency by communicating directly with the Focuswrite ASIO driver (this is totally different than boost ASIO). To work with this you'll need to register and download the ASIO SDK from Steinberg. Within the API download there is a Visual C++ sample project called hostsample which is a good starting point and there is pretty good documentation about the buffering process that is used by ASIO.
ASIO uses double buffering. Your application is able to choose a buffer size within the limits of the driver. For each input channel and each output channel, 2 buffers of that size are created. While the driver is playing from and recording to one set of buffers your program is reading from and writing to the other set. If your program was performing a simple loopback then it would have access to the input 1 buffer period after it was recorded, would write directly to the output buffer which would be played out on the next period so there would be 2 buffer periods of latency. You'll need to experiment to find the smallest buffer size you can tolerate without glitches and this will give you the lowest latency. And of course the signal processing code will need to be optimized well enough to keep up. A 64 sample (1.3 ms # 48kHz) is not unheard of.

WMI giving me incomplete hardware info (PhysicalMemory)

I have read an almost exact same question regarding this issue already (WMI hardware, get RAM info), and here I'm hoping for more information on this topic.
I need to get various hardware information such as RAM serial number, hard drive SN, CPU SN, etc. I am using Visual C++ 2010 and using WMI to query for the information, but it's not giving me what I want. For example, I started trying to get RAM SN, and after querying for it (I used Win32_PhysicalMemory then I get the property "SerialNumber"), I get
SerialNumber
SerNum0
SerNum1
which is obviously not it. I also went to the command line for it (wmic memorychip get serialnumber), but I get the same thing. But I know the serial number is there; when I use a 3rd party program CPU-Z, it retrieves the RAM serial numbers flawlessly.
Am I querying the wrong class? Is there anything I'm missing? I have tried the executable I made on multiple other computers, with mixed results of success and failure--but CPU-Z never fails.
I am developing in Visual Studio C++ 2010 on Windows 7 64 bit computer. Thanks.
The WMI get the data using the WMI providers, unfortunately some manufacturers doesn't expose such data to these providers so you are out luck here. If you want a reliable method to obtain some memory info like serial numbers, manufacturer and so on, you can use the Serial presence detect (SPD) like CPU-Z does. You can get all the documentation related to SPD from the jedec site.

How to create sound from an array of double and play it on speaker

I have an array of double (size more than 60k entries), I have the frequency value. Now I want to create a sound from it using C/C++ which I can play on speaker. My OS is linux.
Thanks. I hope I am clear enough.
http://www.linuxjournal.com/article/6735
This is a link to an article in Linux Journal about programming with the ALSA (Advance Linux Sound Architecture). It contains some example code.
The following information comes from a command-line program called beep, available in Debian. The source code is available through the repositories, and also available here.
There's an ioctl() call with a KIOCSOUND request to the console device that you can use to play sounds through the PC speaker. The snippet is:
ioctl(fd, KIOCSOUND, CLOCK_TICK_RATE/(int)frequency);
to play a sound with frequency frequency, and:
ioctl(fd, KIOCSOUND, 0);
to stop the beep. fd is a file descriptor with write permission to /dev/console, and frequency is the sound frequency, given in hertz. The constant CLOCK_TICK_RATE is related to a timer chip used to create the beep, and in the beep source code has the value 1193180 (hertz). Although this might be different for your system, if my mind is correct, I do remember have seen this same constant on old DOS programs that used the PC speaker.
The Qt library may be overkill for what you want to do and there may be an easier option but it's an option :)
You should be able to use the QAudioOutput class to do what you want.
Two other api's to look at would be SDL and SFML.

Uniquely identify PC based on software/hardware

For a requirement to generate per-PC license keys, I need some code which will return a stable and (near) unique key on any PC. It doesn't have to be guaranteed unique, but close. It does need to be reasonably stable though, so that a given PC always generates the same result unless the hardware is substantially changed.
This is for a Windows application, using wxWidgets but a Win32 or other option is fine.
I was thinking about MAC address but what about laptops which can routinely disable the network card in power-saving mode? I came across GetCurrentHwProfile but it doesn't quite look like what I want?
One idea I had a while back for this is to use CryptProtectData as a way to identify a machine. Behind-the-scenes in that API, Microsoft has done what you're looking for. I never tested it though and I'm curious if it's actually viable.
Basically you would encode a constant magic value with CryptProtectData with CRYPTPROTECT_LOCAL_MACHINE, and the result is your machine ID.
I would just go with the MAC address method; when the wireless / LAN cards are turned off they still show up in Network Connections. You should therefore still be able to get the MAC.
Consider this: Any time you'd be able to contact your webserver or whatever you're cataloging these IDs with, the user is going to have to have some form of network card available.
Oh, and you might be able to use CPU serial number of the customer's computer supports it.
I think there no really easy and unique method so far discovered here.
GetVolumeInformation retrieves not even close to unique ID.....
To use any hardware serial is problematic because manufactures are not committed to supported it always and especially to keep it globally unique
GetCurrentHwProfile retrieves GUID but it's value affected by minor! hardware changes...
Using Product Key ... will bring U to deal with the stolen software - there lot of pirate installations over the globe.
Creation of own GUID and preserving it under registry (in any place) will not prevent duplication by cloning of image ....
etc...
From my perspective of view the best way is combine:
Volume ID + MAC's list + Machine SID + Machine Name. And obviously manage license policy on the server side ;0)
Regards
Mickel.
If you want something a bit harder to spoof than whatever the machine itself can tell you, you'll probably need to provide a USB dongle dedicated for this purpose (not just a flash drive).
For a pretty brain dead test I am using the ProductID code of the OS and the computer name - both extracted from the registry. Not really secure, but its all pretend security anyway.
edit
To answer John's question about what keys I am reading:
SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProductID
SYSTEM\CurrentControlset\Control\ComputerName\ComputerName\ComputerName
How about using the serial number of the harddisk where windows is installed?
The function GetVolumeInformation() will give you such serial number.
To access the ID assigned by the harddisk vendor instead of the ID assigned by Windows, you can use the Win32_PhysicalMedia Class.
To determine the drive where windows is installed, you could expand the variable %windir" by using the function ExpandEnvironmentStrings()
Another option, if your architecture allows, is to use UuidCreate() to generate a random GUID at installation time and save it permanently in the registry. This GUID can then be used as the ID as long as the registry remains. A new registry database is generally considered as a new installation.
A third option is to have a well-known server assigning the IDs. Upon starting up, the software could look up for the ID in the registry and if not found, would contact the server and supply it with its MAC address, hostname, harddisk serial number, Machine SID and any number of indentifyable information (keys).
The server then determines if the client is already registered or not based on the information given. The server could have a relaxed policy and for example only require most of the keys for a match, so that the mechanism would work even in the event of a complete wipe out of the registry and if part (but not all) of the hardware was replaced.
How about using the serial number of a CPU. I remember Microsoft used to provide an api for this that would run the necessary assembler code and give you back all sorts of info about the CPU including serial number. Not sure if it'd work with AMD chips or not, I think it was intel specific.
Surely CPU Id is secure and static enough!!

Linux, C++ audio capturing (just microphone) library

I'm developing a musical game, it's like a singstar but instead of singing, you have to play the recorder. It's called oFlute, and it's still in early development stage.
In the game, I capture the microphone input, then run a simple FFT analysis and compare the results to typical recorder's frequencies, thus getting the played note.
At the beginning, the audio library I was using was RtAudio, but I don't remember why I switched to PortAudio, which is what I'm currently using. The problem is that, from time to time, either it crashes randomly or stops capturing, like if there were no sound coming from the microphone.
My question is, what's the best option to capture microphone input on Linux? I just need to open, read, and close a flow of bytes from the microphone.
I've been reading this guide, and (un)surprisingly it says:
I don't think that PortAudio is very good API for Unix-like operating systems.
So, what do you recommend me?
PortAudio is a strange choice given the other options.
I would personally abstract away from everything and use GStreamer. Audio can be a horrible mess on Linux (speaking as a long term sufferer). Letting Gstreamer deal with that lets you forget about it, move along and not have to think about it again.
OpenAL is probably the most popular for game dev though and it should support most systems (although you will have "fun" getting it playing nice with PulseAudio).
I'd certainly make sure you're developing for the most popular setup (which is PulseAudio at the moment, I reckon) so you don't end up in a situation where you release and you're plunged into a pool of people moaning about the sound not working.
And don't listen to the nonsense about PulseAudio - it might be new and it might take up a few more resources than a barebones ALSA system but it's certainly not mired with latency issues. Asking people to remove it isn't an option with modern desktop distros as it's so tightly integrated (and useful too).