/[svn]/linuxsampler/tags/start/audioio.cpp
ViewVC logotype

Contents of /linuxsampler/tags/start/audioio.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6 - (show annotations) (download)
Sat Oct 25 20:24:32 2003 UTC (20 years, 5 months ago) by (unknown author)
File size: 7237 byte(s)
This commit was manufactured by cvs2svn to create tag 'start'.
1 /***************************************************************************
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