Sooooooo.
Das mit der globalen Variable habe ich nicht weg bekommen. Bleibt also erst einmal so. Aber jetzt schön in einer Header-Datei verwurstet. Hier ist der Code:
Code:
#include <alsa/asoundlib.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
using namespace std;
typedef struct _FILE_head
{
unsigned char ID[4];
unsigned int Length;
unsigned char Type[4];
} FILE_head;
typedef struct _FORMAT
{
short wFormatTag;
unsigned short wChannels;
unsigned int dwSamplesPerSec;
unsigned int dwAvgBytesPerSec;
unsigned short wBlockAlign;
unsigned short wBitsPerSample;
} FORMAT;
typedef struct _CHUNK_head
{
unsigned char ID[4];
unsigned int Length;
} CHUNK_head;
snd_pcm_t *soundKarte;
bool Init(string name, unsigned int channels, unsigned int actualRate, unsigned short WaveBits)
{
int err;
snd_pcm_format_t bits;
unsigned int resample = 1;
switch(WaveBits)
{
case 8:
bits = SND_PCM_FORMAT_U8;
break;
case 16:
bits = SND_PCM_FORMAT_S16;
break;
case 24:
bits = SND_PCM_FORMAT_S24;
break;
case 32:
bits = SND_PCM_FORMAT_S32;
break;
}
snd_pcm_hw_params_t *hw_params;
if(name.length() == 0)
{
err = snd_pcm_open(&soundKarte, "plughw:1,0", SND_PCM_STREAM_PLAYBACK, 0);
}
else
{
err = snd_pcm_open(&soundKarte, name.c_str(), SND_PCM_STREAM_PLAYBACK, 0);
}
if(err < 0)
{
cout << "Init: Kann die Soundkarte nicht öffnen! " << name << " (" << snd_strerror (err) << ")" << endl;
return false;
}
if((err = snd_pcm_hw_params_malloc(&hw_params)) < 0)
{
cout << "Init: Parameter können nicht initialisiert werden (" << snd_strerror (err) << ")" << endl;
return false;
}
if((err = snd_pcm_hw_params_any(soundKarte, hw_params)) < 0)
{
cout << "Init: Parameter können nicht ermittelt werden (" << snd_strerror (err) << ")" << endl;
return false;
}
err = snd_pcm_hw_params_set_rate_resample(soundKarte, hw_params, resample);
if(err < 0)
{
cout << "Init: Resampling kann nicht eingeschaltet werden " << snd_strerror(err) << endl;
return err;
}
if((err = snd_pcm_hw_params_set_access(soundKarte, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0)
{
cout << "Init: Zugriffstyp kann nicht gesetzt werden (" << snd_strerror (err) << ")" << endl;
return false;
}
if((err = snd_pcm_hw_params_set_format(soundKarte, hw_params, bits)) < 0)
{
cout << "Init: Sample-Format kann nicht gesetzt werden (" << snd_strerror (err) << ")" << endl;
return false;
}
if((err = snd_pcm_hw_params_set_channels(soundKarte, hw_params, channels)) < 0)
{
cout << "Init: Anzahl der Kanäle kann nicht gesetzt werden (" << snd_strerror (err) << ")" << endl;
return false;
}
if((err = snd_pcm_hw_params_set_rate_near(soundKarte, hw_params, &actualRate, 0)) < 0)
{
cout << "Init: Sample-Rate kann nicht auf " << actualRate << " gesetzt werden (" << snd_strerror (err) << ")" << endl;
return false;
}
if((err = snd_pcm_hw_params (soundKarte, hw_params)) < 0)
{
cout << "Init: Üarameters können nicht gesetzt werden(" << snd_strerror (err) << ")" << endl;
return false;
}
// snd_pcm_hw_params_get_buffer_size(hw_params, &bufferSize);
snd_pcm_hw_params_free(hw_params);
if((err = snd_pcm_prepare(soundKarte)) < 0)
{
cout << "Init: Audio kann nicht zur Nutzung vorbereitet werden (" << snd_strerror (err) << ")" << endl;
return false;
}
return true;
}
bool UnInit()
{
snd_pcm_close(soundKarte);
return true;
}
int playwave(string waveDatei, string name)
{
FORMAT format;
FILE_head head;
CHUNK_head chead;
char *wave;
register snd_pcm_uframes_t count, frames;
int datei;
unsigned int WaveSize;
datei = open(waveDatei.c_str(), 00);
read(datei, &head, sizeof(FILE_head));
read(datei, &chead, sizeof(CHUNK_head));
read(datei, &format, sizeof(FORMAT));
wave = (char *) malloc(head.Length);
read(datei, wave, head.Length);
WaveSize = head.Length * 8 / ((unsigned int)format.wBitsPerSample * (unsigned int)format.wChannels);
close(datei);
Init(name, format.wChannels, format.dwSamplesPerSec, format.wBitsPerSample);
count = 0;
do
{
frames = snd_pcm_writei(soundKarte, wave + count, WaveSize - count);
if (frames < 0) frames = snd_pcm_recover(soundKarte, frames, 0);
if (frames < 0)
{
printf("Kann wav nicht abspielen: %s\n", snd_strerror(frames));
break;
}
count += frames;
} while (count < WaveSize);
if (count == WaveSize) snd_pcm_drain(soundKarte);
free(wave);
UnInit();
return 0;
}
Jetzt kannst du mit
Code:
playwave(Dateiname, Soundkarte);
zB:
playwave("/home/pi/Music/cantalow.wav", "plughw:1,0");
Ganz locker eine Wave abspielen.
Lesezeichen