/[svn]/linuxsampler/trunk/src/audioio.cpp
ViewVC logotype

Annotation of /linuxsampler/trunk/src/audioio.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9 - (hide annotations) (download)
Wed Nov 5 14:47:10 2003 UTC (20 years, 4 months ago) by schoenebeck
File size: 7237 byte(s)
* transition from plain Makefile to autotools, source files moved to src/
* configure.in: added test for x86 architecture
* src/voice.h: x86 specific asm optimization for double to int casts only
  if compiling for x86 architecture

1 schoenebeck 9 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5     * Copyright (C) 2003 by Benno Senoner and Christian Schoenebeck *
6     * *
7     * This program is free software; you can redistribute it and/or modify *
8     * it under the terms of the GNU General Public License as published by *
9     * the Free Software Foundation; either version 2 of the License, or *
10     * (at your option) any later version. *
11     * *
12     * This program is distributed in the hope that it will be useful, *
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15     * GNU General Public License for more details. *
16     * *
17     * You should have received a copy of the GNU General Public License *
18     * along with this program; if not, write to the Free Software *
19     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
20     * MA 02111-1307 USA *
21     ***************************************************************************/
22    
23     #include "audioio.h"
24    
25     AudioIO::AudioIO() {
26     pcm_handle = NULL;
27     pOutputBuffer = NULL;
28     }
29    
30     AudioIO::~AudioIO() {
31     Close();
32     }
33    
34     int AudioIO::Initialize(uint channels, uint samplerate, uint numfragments, uint fragmentsize) {
35     this->Channels = channels;
36     this->Samplerate = samplerate;
37     this->Fragments = numfragments;
38     this->FragmentSize = fragmentsize;
39    
40     /* Playback stream */
41     snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK;
42    
43     /* This structure contains information about */
44     /* the hardware and can be used to specify the */
45     /* configuration to be used for the PCM stream. */
46     snd_pcm_hw_params_t* hwparams;
47    
48     snd_pcm_sw_params_t* swparams;
49    
50     /* Name of the PCM device, like plughw:0,0 */
51     /* The first number is the number of the soundcard, */
52     /* the second number is the number of the device. */
53     char* pcm_name;
54    
55     /* Init pcm_name. Of course, later you */
56    
57     int err;
58    
59     pcm_name = strdup("hw:0,0");
60    
61     /* Allocate the snd_pcm_hw_params_t structure on the stack. */
62     snd_pcm_hw_params_alloca(&hwparams);
63    
64     /* Open PCM. The last parameter of this function is the mode. */
65     /* If this is set to 0, the standard mode is used. Possible */
66     /* other values are SND_PCM_NONBLOCK and SND_PCM_ASYNC. */
67     /* If SND_PCM_NONBLOCK is used, read / write access to the */
68     /* PCM device will return immediately. If SND_PCM_ASYNC is */
69     /* specified, SIGIO will be emitted whenever a period has */
70     /* been completely processed by the soundcard. */
71     if ((err = snd_pcm_open(&pcm_handle, pcm_name, stream, 0)) < 0) {
72     fprintf(stderr, "Error opening PCM device %s: %s\n", pcm_name, snd_strerror(err));
73     return EXIT_FAILURE;
74     }
75    
76     if ((err = snd_pcm_hw_params_any(pcm_handle, hwparams)) < 0) {
77     fprintf(stderr, "Error, cannot initialize hardware parameter structure: %s.\n", snd_strerror(err));
78     return EXIT_FAILURE;
79     }
80    
81     /* Set access type. This can be either */
82     /* SND_PCM_ACCESS_RW_INTERLEAVED or */
83     /* SND_PCM_ACCESS_RW_NONINTERLEAVED. */
84     if ((err = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
85     fprintf(stderr, "Error snd_pcm_hw_params_set_access: %s.\n", snd_strerror(err));
86     return EXIT_FAILURE;
87     }
88    
89     /* Set sample format */
90     if ((err = snd_pcm_hw_params_set_format(pcm_handle, hwparams, SND_PCM_FORMAT_S16_LE)) < 0) {
91     fprintf(stderr, "Error setting sample format. : %s\n", snd_strerror(err));
92     return EXIT_FAILURE;
93     }
94    
95     /* Set sample rate. If the exact rate is not supported */
96     /* by the hardware, use nearest possible rate. */
97     if((err = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, samplerate, 0)) < 0) {
98     fprintf(stderr, "Error setting sample rate. : %s\n", snd_strerror(err));
99     return EXIT_FAILURE;
100     }
101    
102     if ((err = snd_pcm_hw_params_set_channels(pcm_handle, hwparams, channels)) < 0) {
103     fprintf(stderr, "Error setting number of channels. : %s\n", snd_strerror(err));
104     return EXIT_FAILURE;
105     }
106    
107     /* Set number of periods. Periods used to be called fragments. */
108     if ((err = snd_pcm_hw_params_set_periods(pcm_handle, hwparams, numfragments, 0)) < 0) {
109     fprintf(stderr, "Error setting number of periods. : %s\n", snd_strerror(err));
110     return EXIT_FAILURE;
111     }
112    
113     /* Set buffer size (in frames). The resulting latency is given by */
114     /* latency = periodsize * periods / (rate * bytes_per_frame) */
115     if ((err = snd_pcm_hw_params_set_buffer_size(pcm_handle, hwparams, (fragmentsize * numfragments))) < 0) {
116     fprintf(stderr, "Error setting buffersize. : %s\n", snd_strerror(err));
117     return EXIT_FAILURE;
118     }
119    
120     /* Apply HW parameter settings to */
121     /* PCM device and prepare device */
122     if ((err = snd_pcm_hw_params(pcm_handle, hwparams)) < 0) {
123     fprintf(stderr, "Error setting HW params. : %s\n", snd_strerror(err));
124     return EXIT_FAILURE;
125     }
126    
127     if (snd_pcm_sw_params_malloc(&swparams) != 0) {
128     fprintf(stderr, "Error in snd_pcm_sw_params_malloc. : %s\n", snd_strerror(err));
129     return EXIT_FAILURE;
130     }
131    
132     if (snd_pcm_sw_params_current(pcm_handle, swparams) != 0) {
133     fprintf(stderr, "Error in snd_pcm_sw_params_current. : %s\n", snd_strerror(err));
134     return EXIT_FAILURE;
135     }
136    
137     if (snd_pcm_sw_params_set_stop_threshold(pcm_handle, swparams, 0xffffffff) != 0) {
138     fprintf(stderr, "Error in snd_pcm_sw_params_set_stop_threshold. : %s\n", snd_strerror(err));
139     return EXIT_FAILURE;
140     }
141    
142     if (snd_pcm_sw_params(pcm_handle, swparams) != 0) {
143     fprintf(stderr, "Error in snd_pcm_sw_params. : %s\n", snd_strerror(err));
144     return EXIT_FAILURE;
145     }
146    
147     if ((err = snd_pcm_prepare(pcm_handle)) < 0) {
148     fprintf(stderr, "Error snd_pcm_prepare : %s\n", snd_strerror(err));
149     return EXIT_FAILURE;
150     }
151    
152     // allocate the audio output buffer
153     pOutputBuffer = new int16_t[channels * fragmentsize];
154    
155     return EXIT_SUCCESS;
156     }
157    
158     int AudioIO::Output() {
159     int err = snd_pcm_writei(pcm_handle, pOutputBuffer, FragmentSize);
160     if (err < 0) {
161     fprintf(stderr, "Error snd_pcm_writei failed. : %s\n", snd_strerror(err));
162     return EXIT_FAILURE;
163     }
164     return EXIT_SUCCESS;
165     }
166    
167     void AudioIO::Close(void) {
168     if (pcm_handle) {
169     snd_pcm_close(pcm_handle);
170     pcm_handle = NULL;
171     }
172     if (pOutputBuffer) {
173     delete[] pOutputBuffer;
174     pOutputBuffer = NULL;
175     }
176     }

  ViewVC Help
Powered by ViewVC