Nothing has happend
Signed-off-by: Nikolai Rodionov <allanger@badhouseplants.net>
This commit is contained in:
@@ -20,6 +20,7 @@ class daw_projectConan(ConanFile):
|
||||
self.requires("conan-test-lib/0.0.2")
|
||||
self.requires("qt/6.10.1")
|
||||
self.requires("libsndfile/1.2.2")
|
||||
self.requires("gtest/1.17.0")
|
||||
|
||||
def layout(self):
|
||||
self.folders.build = "build"
|
||||
|
||||
113
coreaudio.cpp
Normal file
113
coreaudio.cpp
Normal file
@@ -0,0 +1,113 @@
|
||||
|
||||
|
||||
|
||||
#include <AudioUnit/AudioUnit.h>
|
||||
#include <AudioToolbox/AudioToolbox.h>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
|
||||
constexpr double SAMPLE_RATE = 44100.0;
|
||||
constexpr double FREQUENCY = 440.0; // A4
|
||||
constexpr double AMPLITUDE = 0.25;
|
||||
|
||||
struct SineState {
|
||||
double phase = 0.0;
|
||||
};
|
||||
|
||||
OSStatus renderCallback(
|
||||
void* inRefCon,
|
||||
AudioUnitRenderActionFlags* ioActionFlags,
|
||||
const AudioTimeStamp* inTimeStamp,
|
||||
UInt32 inBusNumber,
|
||||
UInt32 inNumberFrames,
|
||||
AudioBufferList* ioData)
|
||||
{
|
||||
auto* state = static_cast<SineState*>(inRefCon);
|
||||
double phase = state->phase;
|
||||
double phaseIncrement = 2.0 * M_PI * FREQUENCY / SAMPLE_RATE;
|
||||
|
||||
for (UInt32 frame = 0; frame < inNumberFrames; ++frame) {
|
||||
float sample = static_cast<float>(std::sin(phase) * AMPLITUDE);
|
||||
phase += phaseIncrement;
|
||||
if (phase >= 2.0 * M_PI)
|
||||
phase -= 2.0 * M_PI;
|
||||
|
||||
// Write same sample to all channels
|
||||
for (UInt32 buffer = 0; buffer < ioData->mNumberBuffers; ++buffer) {
|
||||
float* data = static_cast<float*>(ioData->mBuffers[buffer].mData);
|
||||
data[frame] = sample;
|
||||
}
|
||||
}
|
||||
|
||||
state->phase = phase;
|
||||
return noErr;
|
||||
}
|
||||
|
||||
int main() {
|
||||
AudioUnit audioUnit;
|
||||
SineState state;
|
||||
|
||||
// Describe output unit
|
||||
AudioComponentDescription desc{};
|
||||
desc.componentType = kAudioUnitType_Output;
|
||||
desc.componentSubType = kAudioUnitSubType_DefaultOutput;
|
||||
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
|
||||
|
||||
AudioComponent comp = AudioComponentFindNext(nullptr, &desc);
|
||||
if (!comp) {
|
||||
std::cerr << "Failed to find audio component\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
AudioComponentInstanceNew(comp, &audioUnit);
|
||||
|
||||
// Set stream format
|
||||
AudioStreamBasicDescription format{};
|
||||
format.mSampleRate = SAMPLE_RATE;
|
||||
format.mFormatID = kAudioFormatLinearPCM;
|
||||
format.mFormatFlags = kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked;
|
||||
format.mBitsPerChannel = 32;
|
||||
format.mChannelsPerFrame = 2;
|
||||
format.mBytesPerFrame = sizeof(float) * format.mChannelsPerFrame;
|
||||
format.mFramesPerPacket = 1;
|
||||
format.mBytesPerPacket = format.mBytesPerFrame;
|
||||
|
||||
AudioUnitSetProperty(
|
||||
audioUnit,
|
||||
kAudioUnitProperty_StreamFormat,
|
||||
kAudioUnitScope_Input,
|
||||
0,
|
||||
&format,
|
||||
sizeof(format)
|
||||
);
|
||||
|
||||
// Set render callback
|
||||
AURenderCallbackStruct callback{};
|
||||
callback.inputProc = renderCallback;
|
||||
callback.inputProcRefCon = &state;
|
||||
|
||||
AudioUnitSetProperty(
|
||||
audioUnit,
|
||||
kAudioUnitProperty_SetRenderCallback,
|
||||
kAudioUnitScope_Input,
|
||||
0,
|
||||
&callback,
|
||||
sizeof(callback)
|
||||
);
|
||||
|
||||
AudioUnitInitialize(audioUnit);
|
||||
AudioOutputUnitStart(audioUnit);
|
||||
|
||||
std::cout << "Playing sine wave (Ctrl+C to quit)...\n";
|
||||
while (true) {
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
AudioOutputUnitStop(audioUnit);
|
||||
AudioUnitUninitialize(audioUnit);
|
||||
AudioComponentInstanceDispose(audioUnit);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
7
src/gui/editor.cpp
Normal file
7
src/gui/editor.cpp
Normal file
@@ -0,0 +1,7 @@
|
||||
#include <QPushButton>
|
||||
|
||||
QPushButton renderButton()
|
||||
{
|
||||
QPushButton button ("Hello world !");
|
||||
return button;
|
||||
}
|
||||
116
src/main.cpp
116
src/main.cpp
@@ -1,110 +1,20 @@
|
||||
#include <AudioUnit/AudioUnit.h>
|
||||
#include <AudioToolbox/AudioToolbox.h>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
#include <QApplication>
|
||||
#include <QPushButton>
|
||||
#include <QWidget>
|
||||
|
||||
constexpr double SAMPLE_RATE = 44100.0;
|
||||
constexpr double FREQUENCY = 440.0; // A4
|
||||
constexpr double AMPLITUDE = 0.25;
|
||||
|
||||
struct SineState {
|
||||
double phase = 0.0;
|
||||
};
|
||||
|
||||
OSStatus renderCallback(
|
||||
void* inRefCon,
|
||||
AudioUnitRenderActionFlags* ioActionFlags,
|
||||
const AudioTimeStamp* inTimeStamp,
|
||||
UInt32 inBusNumber,
|
||||
UInt32 inNumberFrames,
|
||||
AudioBufferList* ioData)
|
||||
{
|
||||
auto* state = static_cast<SineState*>(inRefCon);
|
||||
double phase = state->phase;
|
||||
double phaseIncrement = 2.0 * M_PI * FREQUENCY / SAMPLE_RATE;
|
||||
|
||||
for (UInt32 frame = 0; frame < inNumberFrames; ++frame) {
|
||||
float sample = static_cast<float>(std::sin(phase) * AMPLITUDE);
|
||||
phase += phaseIncrement;
|
||||
if (phase >= 2.0 * M_PI)
|
||||
phase -= 2.0 * M_PI;
|
||||
|
||||
// Write same sample to all channels
|
||||
for (UInt32 buffer = 0; buffer < ioData->mNumberBuffers; ++buffer) {
|
||||
float* data = static_cast<float*>(ioData->mBuffers[buffer].mData);
|
||||
data[frame] = sample;
|
||||
}
|
||||
}
|
||||
|
||||
state->phase = phase;
|
||||
return noErr;
|
||||
void renderButton(QWidget *parent) {
|
||||
QPushButton *button = new QPushButton("Hello world!", parent);
|
||||
button->show();
|
||||
}
|
||||
|
||||
int main() {
|
||||
AudioUnit audioUnit;
|
||||
SineState state;
|
||||
int main(int argc, char **argv) {
|
||||
QApplication app (argc, argv);
|
||||
|
||||
// Describe output unit
|
||||
AudioComponentDescription desc{};
|
||||
desc.componentType = kAudioUnitType_Output;
|
||||
desc.componentSubType = kAudioUnitSubType_DefaultOutput;
|
||||
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
|
||||
QWidget window;
|
||||
window.resize(300, 200);
|
||||
window.show();
|
||||
|
||||
AudioComponent comp = AudioComponentFindNext(nullptr, &desc);
|
||||
if (!comp) {
|
||||
std::cerr << "Failed to find audio component\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
AudioComponentInstanceNew(comp, &audioUnit);
|
||||
|
||||
// Set stream format
|
||||
AudioStreamBasicDescription format{};
|
||||
format.mSampleRate = SAMPLE_RATE;
|
||||
format.mFormatID = kAudioFormatLinearPCM;
|
||||
format.mFormatFlags = kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked;
|
||||
format.mBitsPerChannel = 32;
|
||||
format.mChannelsPerFrame = 2;
|
||||
format.mBytesPerFrame = sizeof(float) * format.mChannelsPerFrame;
|
||||
format.mFramesPerPacket = 1;
|
||||
format.mBytesPerPacket = format.mBytesPerFrame;
|
||||
|
||||
AudioUnitSetProperty(
|
||||
audioUnit,
|
||||
kAudioUnitProperty_StreamFormat,
|
||||
kAudioUnitScope_Input,
|
||||
0,
|
||||
&format,
|
||||
sizeof(format)
|
||||
);
|
||||
|
||||
// Set render callback
|
||||
AURenderCallbackStruct callback{};
|
||||
callback.inputProc = renderCallback;
|
||||
callback.inputProcRefCon = &state;
|
||||
|
||||
AudioUnitSetProperty(
|
||||
audioUnit,
|
||||
kAudioUnitProperty_SetRenderCallback,
|
||||
kAudioUnitScope_Input,
|
||||
0,
|
||||
&callback,
|
||||
sizeof(callback)
|
||||
);
|
||||
|
||||
AudioUnitInitialize(audioUnit);
|
||||
AudioOutputUnitStart(audioUnit);
|
||||
|
||||
std::cout << "Playing sine wave (Ctrl+C to quit)...\n";
|
||||
while (true) {
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
AudioOutputUnitStop(audioUnit);
|
||||
AudioUnitUninitialize(audioUnit);
|
||||
AudioComponentInstanceDispose(audioUnit);
|
||||
|
||||
return 0;
|
||||
renderButton(&window);
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user