Skip to content

Instantly share code, notes, and snippets.

@johnroper100
Last active May 26, 2020 16:58
Show Gist options
  • Save johnroper100/b87641f5609dbb49bc3c1121b1f4daf1 to your computer and use it in GitHub Desktop.
Save johnroper100/b87641f5609dbb49bc3c1121b1f4daf1 to your computer and use it in GitHub Desktop.
Test code
#include <stdio.h>
#include <vector>
#include <iostream>
#include <string>
#include "portaudio.h"
#include <sndfile.hh>
#include <cstring>
#include <thread>
#include <chrono>
using namespace std::chrono;
#define NUMCHANNELS (2)
#define SAMPLE_RATE (48000)
#define FRAMES_PER_BUFFER (512)
class Sound
{
public:
std::string fname;
int midnote, channel, rate, loop, nframes;
float *data;
void init(std::string filename, bool release, int midinote);
};
void Sound::init(std::string filename, bool release, int midinote)
{
SNDFILE *wf;
SF_INFO inFileInfo;
channel = 0;
wf = sf_open(filename.c_str(), SFM_READ, &inFileInfo);
SF_INSTRUMENT inst;
sf_command(wf, SFC_GET_INSTRUMENT, &inst, sizeof(inst));
if (release == false && inst.loop_count > 0)
{
loop = inst.loops[0].start;
nframes = inst.loops[0].end;
}
else
{
loop = -1;
nframes = inFileInfo.frames;
}
data = (float *)malloc((nframes * 2) * sizeof(float));
sf_read_float(wf, data, nframes * 2);
rate = inFileInfo.samplerate;
sf_close(wf);
};
class PlayingSound
{
public:
Sound sound;
int pos, fadeoutpos, fadeinpos, note;
bool isfadeout, isfadein;
double volMult, pitchMult;
void init(Sound s, int midinote);
void fadeout();
void fadein();
};
void PlayingSound::init(Sound s, int midinote)
{
sound = s;
pos = 0;
fadeoutpos = 0;
fadeinpos = 0;
isfadein = false;
isfadeout = false;
note = midinote;
volMult = 1.0;
pitchMult = 1.0;
};
void PlayingSound::fadeout()
{
isfadeout = true;
};
void PlayingSound::fadein()
{
isfadein = true;
};
static int patestCallback(const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo *timeInfo,
PaStreamCallbackFlags statusFlags, void *userData)
{
//auto start = high_resolution_clock::now();
(void)timeInfo; /* Prevent unused variable warnings. */
(void)statusFlags;
(void)inputBuffer;
float *out = (float *)outputBuffer;
memset(out, 0, sizeof(float) * framesPerBuffer * NUMCHANNELS);
std::vector<PlayingSound>* playingsounds = (std::vector<PlayingSound> *)userData;
int sizeLength = playingsounds->size();
int kk;
int ii;
int pos;
int k;
int nframes, loop, channel;
float *data;
for (int jj = 0; jj < sizeLength; jj++)
{
PlayingSound &snd = playingsounds[0][jj];
kk = 0;
ii = 0;
pos = snd.pos;
nframes = snd.sound.nframes;
loop = snd.sound.loop;
channel = snd.sound.channel;
data = snd.sound.data;
for (int i = 0; i < framesPerBuffer; i++)
{
k = pos + ii;
ii += 1;
if (k > nframes - 2)
{
pos = loop + 1;
snd.pos = pos;
ii = 0;
k = pos;
};
out[NUMCHANNELS * i + channel] += data[2 * k];
out[NUMCHANNELS * i + channel + 1] += data[2 * k + 1];
};
snd.pos += ii;
};
//auto stop = high_resolution_clock::now();
//auto duration = duration_cast<microseconds>(stop-start);
//std::cout << duration.count() << std::endl;
return paContinue;
}
void foo(void *userData)
{
std::vector<PlayingSound> *playingSounds = (std::vector<PlayingSound> *)userData;
Sound test;
test.init("test.wav", false, 36);
PlayingSound test1;
test1.init(test, 36);
playingSounds->push_back(test1);
Sound test2;
test2.init("test2.wav", false, 36);
for (int i = 0; i < 10000; i++)
{
PlayingSound test3;
test3.init(test2, 36);
playingSounds->push_back(test3);
};
}
int main(void);
int main(void)
{
PaStreamParameters outputParameters;
PaStream *stream;
PaError err;
std::vector<PlayingSound> playingSounds;
std::thread thread_obj(foo, &playingSounds);
thread_obj.join();
err = Pa_Initialize();
if (err != paNoError)
goto error;
outputParameters.device = Pa_GetDefaultOutputDevice();
if (outputParameters.device == paNoDevice)
{
fprintf(stderr, "Error: No default output device.\n");
goto error;
}
outputParameters.channelCount = NUMCHANNELS;
outputParameters.sampleFormat = paFloat32;
outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
err = Pa_OpenStream(
&stream,
NULL,
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff,
patestCallback,
&playingSounds);
if (err != paNoError)
goto error;
err = Pa_StartStream(stream);
if (err != paNoError)
goto error;
while (1)
{
Pa_Sleep(1000);
}
err = Pa_StopStream(stream);
if (err != paNoError)
goto error;
err = Pa_CloseStream(stream);
if (err != paNoError)
goto error;
Pa_Terminate();
return err;
error:
Pa_Terminate();
fprintf(stderr, "An error occured while using the portaudio stream\n");
fprintf(stderr, "Error number: %d\n", err);
fprintf(stderr, "Error message: %s\n", Pa_GetErrorText(err));
return err;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment