Skip to content

Instantly share code, notes, and snippets.

@zapu
Created October 7, 2012 20:47
Show Gist options
  • Save zapu/3849544 to your computer and use it in GitHub Desktop.
Save zapu/3849544 to your computer and use it in GitHub Desktop.
portaudio stuff
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <portaudio.h>
#include <assert.h>
#include <stdio.h>
#include <math.h>
#define NUM_CHANNELS 2
#define PA_SAMPLE_TYPE paInt16
typedef short SAMPLE;
#define SAMPLE_SILENCE (0)
#define PRINTF_S_FORMAT "%d"
#define SAMPLE_RATE 44100
#define FRAMES_PER_BUFFER 512
unsigned char getUInt8Sample() {
const char melody_notes[] = "IQNNNN!!]]!Q!IWJWQNN??!!W]WQNNN?";
const double bass_notes[4] = { 3.0, 3.0, 4.75, 2.0 };
static double a, d, m, b, drum, melody, bass, sample;
static unsigned int t, w, v, p;
static unsigned int tt = 0;
t = tt * 100 / 551;
w = t >> 9;
v = w >> 7;
p = (w >> 5) & 0x03;
a = 1.0 - fmod(t / 2048.0, 1.0);
b = bass_notes[p] * t / 4.0;
d = a * fmod((14 * t * t) ^ t, 2048.0);
m = (melody_notes[((w >> 1) & 0x0F) | ((p / 3) << 4)] / 33.0 * t) - t;
bass = fmod(b * 0.98, 80.0) + fmod(b, 80.0);
drum = (((unsigned int)(fmod(5.0 * t, 2048.0) * a) & 128) * ((0x53232323 >> (w / 4)) & 1)) + (((unsigned int)d & 127) * ((0xA444C444 >> (w / 4)) & 1)) + ((unsigned int)(d * w) & 1);
melody = (fmod(m, 32.0) + fmod(m * 1.99, 32.0) + fmod(m * 0.49, 32.0) + fmod(m * 0.97, 32.0) - 64.0) * (4.0 - a - a - a);
sample = bass + (a * ((v ? drum : 0.0) + (v > 1 ? melody : 0.0)));
sample = (sample >= 0.0) ? sample : 0.0;
tt++;
return (((unsigned int)(sample * sample) >> 14) ? 127 : (int)sample);
}
SAMPLE getSample() {
return getUInt8Sample() * 100;
}
static int recordCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
const SAMPLE* buf = (const SAMPLE*)inputBuffer;
SAMPLE max = SAMPLE_SILENCE;
if(buf != NULL) {
for(int i = 0; i < framesPerBuffer; i++) {
SAMPLE s = *buf++;
if(s > max)
max = s;
}
}
printf("Mic level: " PRINTF_S_FORMAT " \r", max);
return paContinue;
}
static int playCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
SAMPLE* buf = (SAMPLE*)outputBuffer;
for(int i = 0; i < framesPerBuffer; i++) {
SAMPLE sample = getSample();
*(buf++) = sample;
*(buf++) = sample;
}
return paContinue;
}
int main()
{
PaError err = Pa_Initialize();
assert(err == paNoError);
for(int i = 0; i < Pa_GetDeviceCount(); i++) {
const PaDeviceInfo* info = Pa_GetDeviceInfo(i);
printf("device %d: %s\n", i, info->name);
}
PaStreamParameters outputParameters;
outputParameters.device = Pa_GetDefaultOutputDevice();
outputParameters.channelCount = NUM_CHANNELS;
outputParameters.sampleFormat = PA_SAMPLE_TYPE;
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
PaStreamParameters inputParameters;
inputParameters.device = Pa_GetDefaultInputDevice();
inputParameters.channelCount = 1;
inputParameters.sampleFormat = PA_SAMPLE_TYPE;
inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowOutputLatency;
inputParameters.hostApiSpecificStreamInfo = NULL;
PaStream* outputStream;
err = Pa_OpenStream(
&outputStream,
NULL,
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff,
playCallback,
NULL);
assert(err == paNoError);
PaStream* inputStream;
err = Pa_OpenStream(
&inputStream,
&inputParameters,
NULL,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff,
recordCallback,
NULL);
assert(err == paNoError);
Pa_StartStream(inputStream);
Pa_StartStream(outputStream);
printf("Streams started...\n");
getchar();
Pa_CloseStream(inputStream);
Pa_CloseStream(outputStream);
printf("Streams closed...\n");
Pa_Terminate();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment