You could do this with OpenAL.
You would need to generate an array containing PCM encoded data that represents your desired output, then call alBufferData() on your array with the desired sampling frequency and format. See page 21 of the OpenAL Programmers Guide for the format required by the alBufferData() function.
For example, the following code plays a 100hz tone.
#include <iostream>
#include <cmath>
#include <al.h>
#include <alc.h>
#include <AL/alut.h>
#pragma comment(lib, "OpenAL32.lib")
#pragma comment(lib, "alut.lib")
int main(int argc, char** argv)
{
alutInit(&argc, argv);
alGetError();
ALuint buffer;
alGenBuffers(1, &buffer);
{
// Creating a buffer that hold about 1.5 seconds of audio data.
char data[32 * 1024];
for (int i = 0; i < 32 * 1024; ++i)
{
// get a value in the interval [0, 1) over the length of a second
float intervalPerSecond = static_cast<float>(i % 22050) / 22050.0f;
// increase the frequency to 100hz
float intervalPerHundreth = fmod(intervalPerSecond * 100.0f, 1.0f);
// translate to the interval [0, 2PI)
float x = intervalPerHundreth * 2 * 3.14159f;
// and then convert back to the interval [0, 255] for our amplitude data.
data[i] = static_cast<char>((sin(x) + 1.0f) / 2.0f * 255.0f);
}
alBufferData(buffer, AL_FORMAT_MONO8, data, 32 * 1024, 22050);
}
ALuint source;
alGenSources(1, &source);
alSourcei(source, AL_BUFFER, buffer);
alSourcePlay(source);
system("pause");
alSourceStop(source);
alDeleteSources(1, &source);
alDeleteBuffers(1, &buffer);
alutExit();
return 0;
}