Adding Music Playback
This commit is contained in:
parent
7b325244c5
commit
231b30b2cb
12 changed files with 1840 additions and 149 deletions
|
|
@ -1,12 +1,22 @@
|
||||||
|
|
||||||
#include "Allocators.hpp"
|
#include "Allocators.hpp"
|
||||||
|
#include "HeapAllocatorGlobal.hpp"
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
static bool init(const tp::ModuleManifest* self) {
|
||||||
|
tp::HeapAllocGlobal::stopIgnore();
|
||||||
|
if (tp::HeapAllocGlobal::getNAllocations()) {
|
||||||
|
printf("Warning : Operator new was called outside module initialization!!\n\n");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static void deinit(const tp::ModuleManifest* self) { tp::HeapAllocGlobal::checkLeaks(); }
|
static void deinit(const tp::ModuleManifest* self) { tp::HeapAllocGlobal::checkLeaks(); }
|
||||||
|
|
||||||
static tp::ModuleManifest* sModuleDependencies[] = { &tp::gModuleUtils, nullptr };
|
static tp::ModuleManifest* sModuleDependencies[] = { &tp::gModuleUtils, nullptr };
|
||||||
tp::ModuleManifest tp::gModuleAllocators = ModuleManifest("Allocators", nullptr, deinit, sModuleDependencies);
|
tp::ModuleManifest tp::gModuleAllocators = ModuleManifest("Allocators", init, deinit, sModuleDependencies);
|
||||||
|
|
||||||
void* operator new(size_t aSize) { return tp::HeapAllocGlobal::allocate(aSize); }
|
void* operator new(size_t aSize) { return tp::HeapAllocGlobal::allocate(aSize); }
|
||||||
void* operator new[](size_t aSize) { return tp::HeapAllocGlobal::allocate(aSize); }
|
void* operator new[](size_t aSize) { return tp::HeapAllocGlobal::allocate(aSize); }
|
||||||
|
|
|
||||||
|
|
@ -21,13 +21,14 @@ HeapAllocGlobal::~HeapAllocGlobal() = default;
|
||||||
bool HeapAllocGlobal::checkLeaks() { return false; }
|
bool HeapAllocGlobal::checkLeaks() { return false; }
|
||||||
void HeapAllocGlobal::startIgnore() {}
|
void HeapAllocGlobal::startIgnore() {}
|
||||||
void HeapAllocGlobal::stopIgnore() {}
|
void HeapAllocGlobal::stopIgnore() {}
|
||||||
|
ualni HeapAllocGlobal::getNAllocations() { return 0; }
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
tp::MemHead* tp::HeapAllocGlobal::mEntry = nullptr;
|
tp::MemHead* tp::HeapAllocGlobal::mEntry = nullptr;
|
||||||
tp::ualni tp::HeapAllocGlobal::mNumAllocations = 0;
|
tp::ualni tp::HeapAllocGlobal::mNumAllocations = 0;
|
||||||
tp::Mutex tp::HeapAllocGlobal::mMutex;
|
tp::Mutex tp::HeapAllocGlobal::mMutex;
|
||||||
bool tp::HeapAllocGlobal::mIgnore;
|
bool tp::HeapAllocGlobal::mIgnore = true;
|
||||||
|
|
||||||
// ----------------------- Debug Implementation ---------------------------- //
|
// ----------------------- Debug Implementation ---------------------------- //
|
||||||
// |----------------|
|
// |----------------|
|
||||||
|
|
@ -100,7 +101,9 @@ ALLOCATE:
|
||||||
|
|
||||||
// 3) Trace the stack
|
// 3) Trace the stack
|
||||||
#ifdef MEM_STACK_TRACE
|
#ifdef MEM_STACK_TRACE
|
||||||
head->mCallStack = gCSCapture->getSnapshot();
|
// check if somewhat decides to call new within static variable initialization
|
||||||
|
if (gCSCapture) head->mCallStack = gCSCapture->getSnapshot();
|
||||||
|
else head->mCallStack = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mMutex.unlock();
|
mMutex.unlock();
|
||||||
|
|
@ -194,6 +197,10 @@ void HeapAllocGlobal::stopIgnore() {
|
||||||
mMutex.unlock();
|
mMutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ualni HeapAllocGlobal::getNAllocations() {
|
||||||
|
return mNumAllocations;
|
||||||
|
}
|
||||||
|
|
||||||
HeapAllocGlobal::~HeapAllocGlobal() = default;
|
HeapAllocGlobal::~HeapAllocGlobal() = default;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ namespace tp {
|
||||||
static bool checkLeaks();
|
static bool checkLeaks();
|
||||||
static void startIgnore();
|
static void startIgnore();
|
||||||
static void stopIgnore();
|
static void stopIgnore();
|
||||||
|
static ualni getNAllocations();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
[[nodiscard]] bool checkWrap() const { return false; }
|
[[nodiscard]] bool checkWrap() const { return false; }
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ set(CMAKE_CXX_STANDARD 20)
|
||||||
|
|
||||||
# set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_SOURCE_DIR}/./tmp/install)
|
# set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_SOURCE_DIR}/./tmp/install)
|
||||||
# set(CMAKE_CXX_FLAGS "-fuse-ld=lld-15 ${CMAKE_CXX_FLAGS} -gdwarf-4 ")
|
# set(CMAKE_CXX_FLAGS "-fuse-ld=lld-15 ${CMAKE_CXX_FLAGS} -gdwarf-4 ")
|
||||||
# add_compile_definitions(MEM_DEBUG)
|
add_compile_definitions(MEM_DEBUG)
|
||||||
|
|
||||||
project(ModulesRoot)
|
project(ModulesRoot)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
project(LibraryViewer)
|
project(LibraryViewer)
|
||||||
|
|
||||||
find_package(ALSA REQUIRED)
|
find_package(ALSA REQUIRED)
|
||||||
|
# find_package(PortAudio REQUIRED)
|
||||||
|
|
||||||
### ---------------------- Externals --------------------- ###
|
### ---------------------- Externals --------------------- ###
|
||||||
set(BINDINGS_INCLUDE ../Externals/glfw/include ../Externals/glew/include)
|
set(BINDINGS_INCLUDE ../Externals/glfw/include ../Externals/glew/include)
|
||||||
set(BINDINGS_LIBS glfw glew_s Imgui Nanovg)
|
set(BINDINGS_LIBS glfw glew_s Imgui Nanovg portaudio)
|
||||||
|
|
||||||
### ---------------------- Static Library --------------------- ###
|
### ---------------------- Static Library --------------------- ###
|
||||||
file(GLOB SOURCES "./private/*.cpp" "./private/*/*.cpp")
|
file(GLOB SOURCES "./private/*.cpp" "./private/*/*.cpp")
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
// #include "NewPlacement.hpp"
|
#include "NewPlacement.hpp"
|
||||||
#include "WavPlayer.hpp"
|
#include "WavPlayer.hpp"
|
||||||
#include "LibraryGui.hpp"
|
#include "LibraryGui.hpp"
|
||||||
|
|
||||||
|
|
@ -8,6 +8,11 @@
|
||||||
|
|
||||||
void runApp() {
|
void runApp() {
|
||||||
|
|
||||||
|
TrackPlayer player;
|
||||||
|
|
||||||
|
player.startStreamTrack(0);
|
||||||
|
player.playSong();
|
||||||
|
|
||||||
Library library;
|
Library library;
|
||||||
library.loadJson("library/Library.json");
|
library.loadJson("library/Library.json");
|
||||||
|
|
||||||
|
|
@ -32,7 +37,6 @@ void runApp() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
// example();
|
|
||||||
|
|
||||||
tp::ModuleManifest* deps[] = { &tp::gModuleLibraryViewer, nullptr };
|
tp::ModuleManifest* deps[] = { &tp::gModuleLibraryViewer, nullptr };
|
||||||
tp::ModuleManifest binModule("LibViewEntry", nullptr, nullptr, deps);
|
tp::ModuleManifest binModule("LibViewEntry", nullptr, nullptr, deps);
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -1,138 +1,217 @@
|
||||||
|
|
||||||
#include "WavPlayer.hpp"
|
#include "WavPlayer.hpp"
|
||||||
#include <chrono>
|
|
||||||
#include <fstream>
|
|
||||||
#include <iostream>
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
WavPlayer::WavPlayer() :
|
#include "portaudio.h"
|
||||||
handle(nullptr),
|
#include "Buffer.hpp"
|
||||||
playbackThread(nullptr),
|
|
||||||
isPlaying(false),
|
|
||||||
progress(0.0f) {
|
|
||||||
if (snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0) < 0) {
|
|
||||||
std::cerr << "Error: Couldn't open ALSA PCM device." << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
WavPlayer::~WavPlayer() {
|
typedef u_int8_t uint8_t;
|
||||||
stopSong();
|
typedef u_int16_t uint16_t;
|
||||||
if (handle) {
|
typedef u_int32_t uint32_t;
|
||||||
snd_pcm_close(handle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WavPlayer::loadSong(const char* filePath) {
|
#include "wav_file_reader.h"
|
||||||
stopSong();
|
|
||||||
|
|
||||||
if (snd_pcm_prepare(handle) < 0) {
|
class Sine {
|
||||||
std::cerr << "Error: Couldn't prepare PCM." << std::endl;
|
public:
|
||||||
return;
|
Sine() {}
|
||||||
|
|
||||||
|
void setSampleRate(int aSampleRate) {
|
||||||
|
sampleRate = aSampleRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Load and parse the WAV file
|
tp::Buffer<float>* geLeftBuffer() { return &leftBuffer; }
|
||||||
// For simplicity, assume a 16-bit, mono WAV file with a 44.1 kHz sample rate
|
tp::Buffer<float>* geRightBuffer() { return &rightBuffer; }
|
||||||
// You need to handle loading and parsing of the WAV file here
|
|
||||||
|
|
||||||
// Example:
|
bool open(PaDeviceIndex index) {
|
||||||
// std::ifstream file(filePath, std::ios::binary);
|
PaStreamParameters outputParameters;
|
||||||
// if (!file) {
|
|
||||||
// std::cerr << "Error: Could not open WAV file." << std::endl;
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// ... (load and parse WAV file)
|
|
||||||
|
|
||||||
snd_pcm_set_params(handle, SND_PCM_FORMAT_S16_LE, SND_PCM_ACCESS_RW_INTERLEAVED, 1, 44100, 1, 500000);
|
outputParameters.device = index;
|
||||||
}
|
if (outputParameters.device == paNoDevice) {
|
||||||
|
return false;
|
||||||
void WavPlayer::playSong() {
|
|
||||||
if (!isPlaying) {
|
|
||||||
isPlaying = true;
|
|
||||||
playbackThread = new std::thread(&WavPlayer::playbackThreadFunction, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WavPlayer::stopSong() {
|
|
||||||
if (isPlaying) {
|
|
||||||
isPlaying = false;
|
|
||||||
if (playbackThread && playbackThread->joinable()) {
|
|
||||||
playbackThread->join();
|
|
||||||
}
|
|
||||||
delete playbackThread;
|
|
||||||
playbackThread = nullptr;
|
|
||||||
snd_pcm_drop(handle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WavPlayer::setVolume(float volume) {
|
|
||||||
// TODO: Adjust volume using ALSA API
|
|
||||||
// You might need to use functions like snd_pcm_volume() or other ALSA functions
|
|
||||||
}
|
|
||||||
|
|
||||||
float WavPlayer::getProgress() const { return progress; }
|
|
||||||
|
|
||||||
float WavPlayer::getDurationSec() const {
|
|
||||||
// TODO: Return the duration of the loaded song
|
|
||||||
// You need information from the loaded WAV file for this
|
|
||||||
return 0.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WavPlayer::setProgress(float newProgress) {
|
|
||||||
if (newProgress >= 0.0f && newProgress <= 1.0f) {
|
|
||||||
progress = newProgress;
|
|
||||||
|
|
||||||
// TODO: Adjust playback position based on the progress using ALSA API
|
|
||||||
// You might need to use functions like snd_pcm_writei() or other ALSA functions
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WavPlayer::playbackThreadFunction() {
|
|
||||||
const int buffer_size = 1024; // Adjust the buffer size according to your requirements
|
|
||||||
short buffer[buffer_size];
|
|
||||||
|
|
||||||
while (isPlaying) {
|
|
||||||
// TODO: Implement actual playback logic using ALSA API
|
|
||||||
// You might need to use functions like snd_pcm_writei() or other ALSA functions
|
|
||||||
|
|
||||||
// For simplicity, we'll fill the buffer with dummy data
|
|
||||||
for (int i = 0; i < buffer_size; ++i) {
|
|
||||||
buffer[i] = static_cast<short>(32767 * std::sin(2.0 * M_PI * 440.0 * progress));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the buffer to the PCM device
|
const PaDeviceInfo* pInfo = Pa_GetDeviceInfo(index);
|
||||||
int err = snd_pcm_writei(handle, buffer, buffer_size);
|
if (pInfo != 0) {
|
||||||
if (err < 0) {
|
printf("Output device name: '%s'\r", pInfo->name);
|
||||||
std::cerr << "Error writing to PCM device: " << snd_strerror(err) << std::endl;
|
|
||||||
stopSong();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update progress
|
outputParameters.channelCount = 2;
|
||||||
progress += 0.1f;
|
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
|
||||||
if (progress >= 1.0f) {
|
outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
|
||||||
stopSong();
|
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||||
|
|
||||||
|
PaError err = Pa_OpenStream(&stream, NULL, &outputParameters, sampleRate, paFramesPerBufferUnspecified, paClipOff, &Sine::paCallback, this);
|
||||||
|
|
||||||
|
/* Failed to open stream to device !!! */
|
||||||
|
if (err != paNoError) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sleep for a short duration (adjust as needed)
|
err = Pa_SetStreamFinishedCallback(stream, &Sine::paStreamFinished);
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void example() {
|
if (err != paNoError) {
|
||||||
WavPlayer player;
|
Pa_CloseStream(stream);
|
||||||
|
stream = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Load a WAV file
|
return true;
|
||||||
player.loadSong("path/to/your/file.wav");
|
|
||||||
|
|
||||||
// Start playing the song asynchronously
|
|
||||||
player.playSong();
|
|
||||||
|
|
||||||
// Simulate a main application loop (replace this with your actual application logic)
|
|
||||||
for (int i = 0; i < 30; ++i) {
|
|
||||||
std::cout << "Progress: " << player.getProgress() << std::endl;
|
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop the song playback
|
bool close() {
|
||||||
player.stopSong();
|
if (stream == 0) return false;
|
||||||
|
PaError err = Pa_CloseStream(stream);
|
||||||
|
stream = 0;
|
||||||
|
return (err == paNoError);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool start() {
|
||||||
|
if (stream == 0) return false;
|
||||||
|
PaError err = Pa_StartStream(stream);
|
||||||
|
return (err == paNoError);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool stop() {
|
||||||
|
if (stream == 0) return false;
|
||||||
|
PaError err = Pa_StopStream(stream);
|
||||||
|
return (err == paNoError);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int paCallbackMethod(const void* inputBuffer, void* outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags) {
|
||||||
|
float* out = (float*) outputBuffer;
|
||||||
|
|
||||||
|
for (unsigned long i = 0; i < framesPerBuffer; i++) {
|
||||||
|
*out++ = leftBuffer[leftSampleIdx];
|
||||||
|
*out++ = rightBuffer[rightSampleIdx];
|
||||||
|
|
||||||
|
leftSampleIdx += 1;
|
||||||
|
rightSampleIdx += 1;
|
||||||
|
|
||||||
|
if (leftSampleIdx >= leftBuffer.size())
|
||||||
|
leftSampleIdx -= 1;
|
||||||
|
if (rightSampleIdx >= rightBuffer.size())
|
||||||
|
rightSampleIdx -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return paContinue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void paStreamFinishedMethod() { printf("Stream Completed\n"); }
|
||||||
|
|
||||||
|
static int paCallback(const void* inputBuffer, void* outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void* userData) {
|
||||||
|
return ((Sine*) userData)->paCallbackMethod(inputBuffer, outputBuffer, framesPerBuffer, timeInfo, statusFlags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void paStreamFinished(void* userData) { return ((Sine*) userData)->paStreamFinishedMethod(); }
|
||||||
|
|
||||||
|
PaStream* stream = 0;
|
||||||
|
|
||||||
|
tp::Buffer<float> leftBuffer;
|
||||||
|
tp::Buffer<float> rightBuffer;
|
||||||
|
|
||||||
|
int leftSampleIdx = 0;
|
||||||
|
int rightSampleIdx = 0;
|
||||||
|
|
||||||
|
int sampleRate = 44100;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MusicPlayerContext {
|
||||||
|
public:
|
||||||
|
MusicPlayerContext() {
|
||||||
|
initStatus = Pa_Initialize();
|
||||||
|
if (initStatus != paNoError) {
|
||||||
|
fprintf(stderr, "An error occurred while using the portaudio stream\n");
|
||||||
|
fprintf(stderr, "Error number: %d\n", initStatus);
|
||||||
|
fprintf(stderr, "Error message: %s\n", Pa_GetErrorText(initStatus));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void load() {
|
||||||
|
if (connected) {
|
||||||
|
stop();
|
||||||
|
sine.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
exampleLoad();
|
||||||
|
connected = sine.open(Pa_GetDefaultOutputDevice());
|
||||||
|
}
|
||||||
|
|
||||||
|
void stop() {
|
||||||
|
if (!connected) return;
|
||||||
|
sine.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void start() {
|
||||||
|
if (!connected) return;
|
||||||
|
sine.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
~MusicPlayerContext() {
|
||||||
|
if (connected) {
|
||||||
|
stop();
|
||||||
|
sine.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (initStatus == paNoError) {
|
||||||
|
Pa_Terminate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void exampleLoad() {
|
||||||
|
AudioFile<double> audioFile;
|
||||||
|
audioFile.load("library/Example.wav");
|
||||||
|
|
||||||
|
audioFile.printSummary();
|
||||||
|
|
||||||
|
sine.setSampleRate(audioFile.getSampleRate());
|
||||||
|
|
||||||
|
int numSamples = audioFile.getNumSamplesPerChannel();
|
||||||
|
|
||||||
|
auto left = sine.geLeftBuffer();
|
||||||
|
auto right = sine.geRightBuffer();
|
||||||
|
|
||||||
|
left->reserve(numSamples);
|
||||||
|
right->reserve(numSamples);
|
||||||
|
|
||||||
|
int channel = 0;
|
||||||
|
for (int i = 0; i < numSamples; i++) {
|
||||||
|
left->getBuff()[i] = audioFile.samples[0][i];
|
||||||
|
right->getBuff()[i] = audioFile.samples[1][i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Sine sine;
|
||||||
|
PaError initStatus;
|
||||||
|
bool connected = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
TrackPlayer::TrackPlayer() {
|
||||||
|
mContext = new MusicPlayerContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TrackPlayer::~TrackPlayer() {
|
||||||
|
delete mContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrackPlayer::startStreamTrack(SongId id) {
|
||||||
|
mContext->load();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrackPlayer::playSong() {
|
||||||
|
mContext->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrackPlayer::stopSong() {
|
||||||
|
mContext->stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrackPlayer::setVolume(float volume) {}
|
||||||
|
|
||||||
|
float TrackPlayer::getProgress() const { return 0; }
|
||||||
|
|
||||||
|
float TrackPlayer::getDurationSec() const { return 0; }
|
||||||
|
|
||||||
|
void TrackPlayer::setProgress(float newProgress) {}
|
||||||
|
|
@ -1,29 +1,29 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <iostream>
|
#include "Common.hpp"
|
||||||
#include <thread>
|
|
||||||
#include <alsa/asoundlib.h>
|
|
||||||
|
|
||||||
class WavPlayer {
|
class MusicPlayerContext;
|
||||||
|
typedef tp::ualni SongId;
|
||||||
|
|
||||||
|
class TrackPlayer {
|
||||||
public:
|
public:
|
||||||
WavPlayer();
|
TrackPlayer();
|
||||||
~WavPlayer();
|
~TrackPlayer();
|
||||||
|
|
||||||
void loadSong(const char* filePath);
|
void startStreamTrack(SongId id);
|
||||||
void playSong();
|
|
||||||
void stopSong();
|
void playSong();
|
||||||
void setVolume(float volume);
|
|
||||||
float getProgress() const;
|
void stopSong();
|
||||||
float getDurationSec() const;
|
|
||||||
void setProgress(float newProgress);
|
void setVolume(float volume);
|
||||||
|
|
||||||
|
float getProgress() const;
|
||||||
|
|
||||||
|
float getDurationSec() const;
|
||||||
|
|
||||||
|
void setProgress(float newProgress);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void playbackThreadFunction();
|
MusicPlayerContext* mContext;
|
||||||
|
|
||||||
snd_pcm_t* handle;
|
|
||||||
std::thread* playbackThread;
|
|
||||||
bool isPlaying;
|
|
||||||
float progress;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void example();
|
|
||||||
1587
LibraryViewer/public/wav_file_reader.h
Normal file
1587
LibraryViewer/public/wav_file_reader.h
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -208,9 +208,11 @@ void CallStackCapture::platformWriteDebugSymbols(FramePointer frame, DebugSymbol
|
||||||
|
|
||||||
void CallStackCapture::printSnapshot(const CallStack* snapshot) {
|
void CallStackCapture::printSnapshot(const CallStack* snapshot) {
|
||||||
printf("CallStack: \n");
|
printf("CallStack: \n");
|
||||||
for (auto frame : *snapshot) {
|
if (snapshot) {
|
||||||
auto symbols = gCSCapture->getSymbols(frame.getFrame());
|
for (auto frame : *snapshot) {
|
||||||
printf(" %s ----- %s:%llu\n", symbols->getFunc(), symbols->getFile(), symbols->getLine());
|
auto symbols = gCSCapture->getSymbols(frame.getFrame());
|
||||||
|
printf(" %s ----- %s:%llu\n", symbols->getFunc(), symbols->getFile(), symbols->getLine());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ namespace tp {
|
||||||
ModuleManifest gModuleUtils = ModuleManifest("Utils", initialize, deinitialize, sModuleUtilsDeps);
|
ModuleManifest gModuleUtils = ModuleManifest("Utils", initialize, deinitialize, sModuleUtilsDeps);
|
||||||
|
|
||||||
void memSetVal(void* p, uhalni byteSize, uint1 val) {
|
void memSetVal(void* p, uhalni byteSize, uint1 val) {
|
||||||
MODULE_SANITY_CHECK(gModuleBase)
|
// MODULE_SANITY_CHECK(gModuleBase)
|
||||||
|
|
||||||
alni alignedVal = val;
|
alni alignedVal = val;
|
||||||
alignedVal = (alignedVal << 8) | alignedVal;
|
alignedVal = (alignedVal << 8) | alignedVal;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue