8899d5f033
- Add missing gl depends - Fix build with clang 6 - Regenerate patches
222 lines
5.9 KiB
C++
222 lines
5.9 KiB
C++
--- src-common/soundenginealsa.cxx.orig 2008-06-18 01:36:34 UTC
|
|
+++ src-common/soundenginealsa.cxx
|
|
@@ -38,219 +38,46 @@ SoundEngineAlsa::SoundEngineAlsa(int lag
|
|
complexfeed(0),
|
|
enginefeed(0),
|
|
activefeed(0),
|
|
- handle(0),
|
|
- periodsz(0),
|
|
batchsize(0),
|
|
framelag(lag),
|
|
lpfilter(0.0)
|
|
{
|
|
- // test endiness
|
|
- unsigned int scratch=0;
|
|
- unsigned char *p = (unsigned char*) &scratch;
|
|
- *p = 1;
|
|
- assert(scratch == 1 || scratch == 16777216);
|
|
- SoundClip::bigendian = (scratch == 16777216);
|
|
- //fprintf(stderr,"soundenginealsa.cxx: %s endian\n", (SoundClip::bigendian)?"big":"little");
|
|
-
|
|
- /* Open PCM device for playback. */
|
|
- int rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0);
|
|
- if (rc < 0)
|
|
- {
|
|
- fprintf(stderr, "unable to open pcm device: %s\n", snd_strerror(rc));
|
|
- return;
|
|
- }
|
|
- snd_pcm_hw_params_t *params=0;
|
|
-
|
|
- /* Allocate a hardware parameters object. */
|
|
- snd_pcm_hw_params_alloca(¶ms);
|
|
- /* Fill it in with default values. */
|
|
- snd_pcm_hw_params_any(handle, params);
|
|
- /* Set the desired hardware parameters. */
|
|
- /* Interleaved mode */
|
|
- snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
|
|
- /* Signed 16-bit little-endian format */
|
|
- snd_pcm_hw_params_set_format(handle, params, (SoundClip::bigendian)?SND_PCM_FORMAT_S16_BE:SND_PCM_FORMAT_S16_LE);
|
|
- /* Two channels (stereo) */
|
|
- snd_pcm_hw_params_set_channels(handle, params, 2);
|
|
- /* 44100 bits/second sampling rate (CD quality) */
|
|
- const unsigned int cd_rate = 44100;
|
|
- unsigned int playback_sampling_rate = cd_rate;
|
|
- int dir=-1; // round down actual rate, please.
|
|
- snd_pcm_hw_params_set_rate_near(handle, params, &playback_sampling_rate, &dir);
|
|
- if (playback_sampling_rate != cd_rate)
|
|
- {
|
|
- fprintf
|
|
- (
|
|
- stderr,
|
|
- "Asked for %dHz playback rate, but got %dHz\n",
|
|
- cd_rate,
|
|
- playback_sampling_rate
|
|
- );
|
|
- }
|
|
-
|
|
- snd_pcm_uframes_t frames_in_buffer = framelag;
|
|
- snd_pcm_uframes_t frames_in_period = framelag/8;
|
|
-
|
|
- snd_pcm_hw_params_set_buffer_size_near(handle, params, &frames_in_buffer);
|
|
- snd_pcm_hw_params_set_period_size_near(handle, params, &frames_in_period, &dir);
|
|
-
|
|
- /* Write the parameters to the driver */
|
|
- rc = snd_pcm_hw_params(handle, params);
|
|
- if (rc < 0)
|
|
- {
|
|
- fprintf(stderr, "unable to set hw parameters: %s\n", snd_strerror(rc));
|
|
- return;
|
|
- }
|
|
- snd_pcm_hw_params_get_period_size(params, &periodsz, &dir);
|
|
- snd_pcm_hw_params_get_buffer_size(params, &buffersz);
|
|
-
|
|
- fprintf(stderr,"soundenginealsa.cxx: period size SOLL-WERT %d, IST-WERT %d\n", framelag/8, (int) periodsz);
|
|
- fprintf(stderr,"soundenginealsa.cxx: buffer size SOLL-WERT %d, IST-WERT %d\n", framelag, (int) buffersz);
|
|
-
|
|
- if (buffersz % periodsz)
|
|
- fprintf(stderr,"soundenginealsa.cxx: WARNING - buffersz is not a multiple of periodsz\n");
|
|
-
|
|
- simplefeed = new SoundFeedSimple(periodsz);
|
|
- complexfeed = new SoundFeedComplex(periodsz);
|
|
- modulatedfeed = new SoundFeedModulated(periodsz);
|
|
- enginefeed = new SoundFeedEngine(periodsz);
|
|
- activefeed = simplefeed;
|
|
- opened = true;
|
|
}
|
|
|
|
|
|
SoundEngineAlsa::~SoundEngineAlsa()
|
|
{
|
|
- if (opened)
|
|
- {
|
|
- fprintf(stderr,"Closing down SoundEngineAlsa\n");
|
|
- snd_pcm_drain(handle);
|
|
- snd_pcm_close(handle);
|
|
- }
|
|
}
|
|
|
|
|
|
void SoundEngineAlsa::Play(const std::string &fname, int delay, bool looping)
|
|
{
|
|
- activefeed->Paste(fname, delay, looping);
|
|
}
|
|
|
|
|
|
void SoundEngineAlsa::StopPlay(void)
|
|
{
|
|
- puts("NOT YET IMPLEMENTED");
|
|
}
|
|
|
|
|
|
void SoundEngineAlsa::SetMode(const std::string &modename)
|
|
{
|
|
- if (modename=="complex")
|
|
- {
|
|
- activefeed = complexfeed;
|
|
- return;
|
|
- }
|
|
- if (modename=="simple")
|
|
- {
|
|
- activefeed = simplefeed;
|
|
- return;
|
|
- }
|
|
- if (modename=="modulated")
|
|
- {
|
|
- activefeed = modulatedfeed;
|
|
- return;
|
|
- }
|
|
- if (modename=="engine")
|
|
- {
|
|
- activefeed = enginefeed;
|
|
- return;
|
|
- }
|
|
- if (modename=="none")
|
|
- {
|
|
- activefeed = 0;
|
|
- return;
|
|
- }
|
|
- assert(0);
|
|
}
|
|
|
|
|
|
void SoundEngineAlsa::SetModulation(float freq, float ampl)
|
|
{
|
|
- modulatedfeed->SetModulation(freq, ampl);
|
|
- complexfeed->SetModulation(freq, ampl);
|
|
- enginefeed->SetModulation(freq, ampl);
|
|
}
|
|
|
|
|
|
void SoundEngineAlsa::SetLowPass(float f)
|
|
{
|
|
- lpfilter = f;
|
|
}
|
|
|
|
|
|
|
|
float SoundEngineAlsa::Sustain(void)
|
|
{
|
|
- if (!activefeed)
|
|
- return 0.0;
|
|
- snd_pcm_sframes_t delay;
|
|
- int avail = snd_pcm_avail_update(handle);
|
|
- int rc = snd_pcm_delay(handle, &delay);
|
|
- if (rc<0)
|
|
- snd_strerror(rc);
|
|
- if (rc==-EPIPE)
|
|
- fprintf(stderr,"soundenginealsa.cxx: EPIPE\n");
|
|
- else
|
|
- assert(!rc);
|
|
-
|
|
- // We can only trust pcm_delay if the state is running.
|
|
- snd_pcm_state_t pcm_state = snd_pcm_state(handle);
|
|
- if (pcm_state != SND_PCM_STATE_RUNNING || delay<0)
|
|
- {
|
|
- delay=0;
|
|
- if (pcm_state == SND_PCM_STATE_XRUN)
|
|
- snd_pcm_prepare(handle);
|
|
- }
|
|
-
|
|
-#if 0
|
|
- if (delay<0)
|
|
- fprintf(stderr,"delay=%d, avail=%d, periodsz=%d\n", (int) delay, (int) avail, (int) periodsz);
|
|
-#else
|
|
- (void) avail;
|
|
-#endif
|
|
-
|
|
- float fractiondone = activefeed->FractionDone(delay);
|
|
-
|
|
- if (delay < (int) buffersz)
|
|
- {
|
|
- int todo = buffersz - delay;
|
|
-#if 1
|
|
- int cnt = (todo + periodsz-1) / periodsz; // Use this with pulse audio (fedora)
|
|
-#else
|
|
- int cnt = todo / periodsz; // Use this with all other alsa implementations
|
|
-#endif
|
|
- short *data = activefeed->Get(cnt);
|
|
- if (cnt)
|
|
- {
|
|
- assert(data);
|
|
- if (lpfilter>0.01)
|
|
- low_pass_filter(data, cnt*periodsz, lpfilter);
|
|
- rc = snd_pcm_writei(handle, data, cnt*periodsz);
|
|
- assert(rc == -EPIPE || rc >= 0);
|
|
- if (rc == -EPIPE)
|
|
- {
|
|
- snd_pcm_prepare(handle);
|
|
- fprintf(stderr,"Underrrun!\n");
|
|
- }
|
|
- else
|
|
- if (rc != (int) (cnt*periodsz))
|
|
- fprintf(stderr, "short write, wrote %d frames instead of %d\n", rc, (int) periodsz);
|
|
-#if 0
|
|
- else
|
|
- fprintf(stderr, "wrote %d sound frames\n", rc);
|
|
-#endif
|
|
- }
|
|
- }
|
|
- return fractiondone;
|
|
}
|
|
|
|
clipmap_t SoundClip::clips;
|