from desktop pc
This commit is contained in:
parent
828d1b3360
commit
6850c9646e
|
@ -1,7 +1,10 @@
|
|||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"platformio.platformio-ide"
|
||||
]
|
||||
}
|
||||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"platformio.platformio-ide"
|
||||
],
|
||||
"unwantedRecommendations": [
|
||||
"ms-vscode.cpptools-extension-pack"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
**/*.mp3
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
musicmouse.FCStd
BIN
musicmouse.FCStd
Binary file not shown.
|
@ -1,6 +0,0 @@
|
|||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
project("pyaudioplayeralsa")
|
||||
|
||||
add_executable(play main.cpp src/WavFile.cpp)
|
||||
target_link_libraries(play -lasound -pthread)
|
|
@ -1,177 +0,0 @@
|
|||
/*
|
||||
* Simple sound playback using ALSA API and libasound.
|
||||
*
|
||||
* Compile:
|
||||
* $ cc -o play sound_playback.c -lasound
|
||||
*
|
||||
* Usage:
|
||||
* $ ./play <sample_rate> <channels> <seconds> < <file>
|
||||
*
|
||||
* Examples:
|
||||
* $ ./play 44100 2 5 < /dev/urandom
|
||||
* $ ./play 22050 1 8 < /path/to/file.wav
|
||||
*
|
||||
* Copyright (C) 2009 Alessandro Ghedini <al3xbio@gmail.com>
|
||||
* --------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* Alessandro Ghedini wrote this file. As long as you retain this
|
||||
* notice you can do whatever you want with this stuff. If we
|
||||
* meet some day, and you think this stuff is worth it, you can
|
||||
* buy me a beer in return.
|
||||
* --------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <alsa/asoundlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "src/WavFile.h"
|
||||
|
||||
#include <future>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include <queue>
|
||||
|
||||
#define PCM_DEVICE "default"
|
||||
|
||||
std::deque<std::string> queue;
|
||||
std::mutex queueMutex;
|
||||
|
||||
static std::string getInput()
|
||||
{
|
||||
|
||||
std::cout << "starting input thread" << std::endl;
|
||||
while (true)
|
||||
{
|
||||
std::string result;
|
||||
std::getline(std::cin, result);
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(queueMutex);
|
||||
std::cout << "adding to queue" << std::endl;
|
||||
queue.push_back(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
std::ifstream wavFileStream("test.wav", std::ios::binary);
|
||||
WavFile wav(wavFileStream);
|
||||
wavFileStream.close();
|
||||
std::cout << "Wav samples " << wav.size() << std::endl;
|
||||
|
||||
unsigned int pcm, tmp, dir;
|
||||
snd_pcm_t *pcm_handle;
|
||||
snd_pcm_hw_params_t *params;
|
||||
snd_pcm_uframes_t frames;
|
||||
char *buff;
|
||||
int buff_size, loops;
|
||||
|
||||
/* Open the PCM device in playback mode */
|
||||
if (pcm = snd_pcm_open(&pcm_handle, PCM_DEVICE,
|
||||
SND_PCM_STREAM_PLAYBACK, 0) < 0)
|
||||
printf("ERROR: Can't open \"%s\" PCM device. %s\n",
|
||||
PCM_DEVICE, snd_strerror(pcm));
|
||||
|
||||
/* Allocate parameters object and fill it with default values*/
|
||||
snd_pcm_hw_params_alloca(¶ms);
|
||||
|
||||
snd_pcm_hw_params_any(pcm_handle, params);
|
||||
|
||||
/* Set parameters */
|
||||
if (pcm = snd_pcm_hw_params_set_access(pcm_handle, params,
|
||||
SND_PCM_ACCESS_RW_INTERLEAVED) < 0)
|
||||
printf("ERROR: Can't set interleaved mode. %s\n", snd_strerror(pcm));
|
||||
|
||||
if (pcm = snd_pcm_hw_params_set_format(pcm_handle, params,
|
||||
SND_PCM_FORMAT_S16_LE) < 0)
|
||||
printf("ERROR: Can't set format. %s\n", snd_strerror(pcm));
|
||||
|
||||
if (pcm = snd_pcm_hw_params_set_channels(pcm_handle, params, wav.channels()) < 0)
|
||||
printf("ERROR: Can't set channels number. %s\n", snd_strerror(pcm));
|
||||
|
||||
snd_pcm_hw_params_set_buffer_size(pcm_handle, params, 2 * 2048);
|
||||
|
||||
unsigned int rate = wav.sampleRate();
|
||||
if (pcm = snd_pcm_hw_params_set_rate_near(pcm_handle, params, &rate, 0) < 0)
|
||||
printf("ERROR: Can't set rate. %s\n", snd_strerror(pcm));
|
||||
|
||||
/* Write parameters */
|
||||
if (pcm = snd_pcm_hw_params(pcm_handle, params) < 0)
|
||||
printf("ERROR: Can't set harware parameters. %s\n", snd_strerror(pcm));
|
||||
|
||||
/* Resume information */
|
||||
printf("PCM name: '%s'\n", snd_pcm_name(pcm_handle));
|
||||
|
||||
printf("PCM state: %s\n", snd_pcm_state_name(snd_pcm_state(pcm_handle)));
|
||||
|
||||
snd_pcm_hw_params_get_channels(params, &tmp);
|
||||
|
||||
printf("channels: %i ", tmp);
|
||||
|
||||
if (tmp == 1)
|
||||
printf("(mono)\n");
|
||||
else if (tmp == 2)
|
||||
printf("(stereo)\n");
|
||||
|
||||
snd_pcm_hw_params_get_rate(params, &tmp, 0);
|
||||
printf("rate: %d bps\n", tmp);
|
||||
|
||||
/* Allocate buffer to hold single period */
|
||||
snd_pcm_hw_params_get_period_size(params, &frames, 0);
|
||||
|
||||
buff_size = frames * wav.channels() * 2 /* 2 -> sample size */;
|
||||
buff = (char *)malloc(buff_size);
|
||||
std::cout << "Buffer size " << buff_size << " frames " << frames << std::endl;
|
||||
|
||||
snd_pcm_hw_params_get_period_time(params, &tmp, NULL);
|
||||
|
||||
std::thread inputThread(getInput);
|
||||
bool playing = true;
|
||||
|
||||
size_t wavFilePosition = 0;
|
||||
while (wavFilePosition < wav.size())
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(queueMutex);
|
||||
if (queue.size() > 0)
|
||||
{
|
||||
queue.pop_back();
|
||||
std::cout << "Toggling" << std::endl;
|
||||
//snd_pcm_drain(pcm_handle);
|
||||
std::cout << "Done" << std::endl;
|
||||
playing = !playing;
|
||||
if (playing)
|
||||
{
|
||||
std::cout << "continuing at " << wavFilePosition << std::endl;
|
||||
snd_pcm_pause(pcm_handle, 0);
|
||||
//snd_pcm_prepare(pcm_handle);
|
||||
}
|
||||
else
|
||||
snd_pcm_pause(pcm_handle, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!playing)
|
||||
continue;
|
||||
size_t dataToWrite = std::min(size_t(buff_size), wav.size() - wavFilePosition);
|
||||
int framesToWrite = dataToWrite / wav.channels() / 2;
|
||||
if (pcm = snd_pcm_writei(pcm_handle, wav[wavFilePosition], framesToWrite) == -EPIPE)
|
||||
{
|
||||
std::cout << "XRUN at wav position " << wavFilePosition << std::endl;
|
||||
snd_pcm_prepare(pcm_handle);
|
||||
}
|
||||
else if (pcm < 0)
|
||||
printf("ERROR. Can't write to PCM device. %s\n", snd_strerror(pcm));
|
||||
|
||||
wavFilePosition += dataToWrite;
|
||||
}
|
||||
|
||||
std::cout << "done filling buffer" << std::endl;
|
||||
snd_pcm_drain(pcm_handle);
|
||||
snd_pcm_close(pcm_handle);
|
||||
free(buff);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
- play wav file [ok]
|
||||
- read & parse wav file [ok]
|
||||
- stop wave file in the middle, wait 2 secs and continue
|
||||
- fade in/out
|
||||
- mix second wave file on top (some effect)
|
|
@ -1,61 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
template <size_t len>
|
||||
std::string readStr(std::istream &str)
|
||||
{
|
||||
char buff[len];
|
||||
str.read(buff, len);
|
||||
return std::string(buff, len);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T read(std::istream &str)
|
||||
{
|
||||
T res;
|
||||
str.read((char *)&res, sizeof(res));
|
||||
return res;
|
||||
}
|
||||
|
||||
class WavFile
|
||||
{
|
||||
public:
|
||||
WavFile(std::istream &str)
|
||||
{
|
||||
auto chunkId = readStr<4>(str);
|
||||
auto chunkSize = read<uint32_t>(str);
|
||||
auto format = readStr<4>(str);
|
||||
|
||||
auto subchunk1Id = readStr<4>(str);
|
||||
auto subchunk1Size = read<uint32_t>(str);
|
||||
|
||||
auto audioFormat = read<uint16_t>(str);
|
||||
numChannels_ = read<uint16_t>(str);
|
||||
sampleRate_ = read<uint32_t>(str);
|
||||
auto byteRate = read<uint32_t>(str);
|
||||
|
||||
auto blockAlign = read<uint16_t>(str);
|
||||
bitsPerSample_ = read<uint16_t>(str);
|
||||
|
||||
auto subchunk2Id = readStr<4>(str);
|
||||
dataSize_ = read<uint32_t>(str);
|
||||
|
||||
data_ = std::unique_ptr<char>(new char[dataSize_]);
|
||||
str.read(data_.get(), dataSize_);
|
||||
}
|
||||
|
||||
uint32_t sampleRate() const { return sampleRate_; }
|
||||
uint16_t channels() const { return numChannels_; }
|
||||
uint32_t size() const { return dataSize_; }
|
||||
|
||||
const char *operator[](int offset) const { return &data_.get()[offset]; }
|
||||
|
||||
private:
|
||||
std::unique_ptr<char> data_;
|
||||
uint32_t sampleRate_;
|
||||
uint16_t bitsPerSample_;
|
||||
uint32_t dataSize_;
|
||||
uint16_t numChannels_;
|
||||
};
|
Loading…
Reference in New Issue