17153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson/* tinycap.c 27153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson** 37153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson** Copyright 2011, The Android Open Source Project 47153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson** 57153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson** Redistribution and use in source and binary forms, with or without 67153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson** modification, are permitted provided that the following conditions are met: 77153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson** * Redistributions of source code must retain the above copyright 87153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson** notice, this list of conditions and the following disclaimer. 97153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson** * Redistributions in binary form must reproduce the above copyright 107153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson** notice, this list of conditions and the following disclaimer in the 117153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson** documentation and/or other materials provided with the distribution. 127153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson** * Neither the name of The Android Open Source Project nor the names of 137153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson** its contributors may be used to endorse or promote products derived 147153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson** from this software without specific prior written permission. 157153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson** 167153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson** THIS SOFTWARE IS PROVIDED BY The Android Open Source Project ``AS IS'' AND 177153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 187153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 197153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson** ARE DISCLAIMED. IN NO EVENT SHALL The Android Open Source Project BE LIABLE 207153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 217153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 227153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 237153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 247153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 257153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 267153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson** DAMAGE. 277153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson*/ 287153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson 297153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson#include <tinyalsa/asoundlib.h> 307153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson#include <stdio.h> 317153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson#include <stdlib.h> 327153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson#include <stdint.h> 337153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson#include <signal.h> 34da39e0b09eb0a1b559a96e2108160d1d8dccf314Simon Wilson#include <string.h> 357153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson 367153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson#define ID_RIFF 0x46464952 377153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson#define ID_WAVE 0x45564157 387153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson#define ID_FMT 0x20746d66 397153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson#define ID_DATA 0x61746164 407153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson 417153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson#define FORMAT_PCM 1 427153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson 437153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilsonstruct wav_header { 447153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson uint32_t riff_id; 457153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson uint32_t riff_sz; 467153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson uint32_t riff_fmt; 477153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson uint32_t fmt_id; 487153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson uint32_t fmt_sz; 497153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson uint16_t audio_format; 507153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson uint16_t num_channels; 517153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson uint32_t sample_rate; 527153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson uint32_t byte_rate; 537153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson uint16_t block_align; 547153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson uint16_t bits_per_sample; 557153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson uint32_t data_id; 567153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson uint32_t data_sz; 577153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson}; 587153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson 597153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilsonint capturing = 1; 607153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson 61daa83291944318d8face12c780dfb69ae96b0723Simon Wilsonunsigned int capture_sample(FILE *file, unsigned int card, unsigned int device, 627153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson unsigned int channels, unsigned int rate, 6336ea2d824e5d8af550c139da9da20e73f82a9ae1Simon Wilson enum pcm_format format, unsigned int period_size, 64daa83291944318d8face12c780dfb69ae96b0723Simon Wilson unsigned int period_count); 657153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson 667153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilsonvoid sigint_handler(int sig) 677153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson{ 687153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson capturing = 0; 697153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson} 707153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson 717153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilsonint main(int argc, char **argv) 727153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson{ 737153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson FILE *file; 747153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson struct wav_header header; 75daa83291944318d8face12c780dfb69ae96b0723Simon Wilson unsigned int card = 0; 767153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson unsigned int device = 0; 777153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson unsigned int channels = 2; 787153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson unsigned int rate = 44100; 797153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson unsigned int bits = 16; 807153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson unsigned int frames; 81daa83291944318d8face12c780dfb69ae96b0723Simon Wilson unsigned int period_size = 1024; 82daa83291944318d8face12c780dfb69ae96b0723Simon Wilson unsigned int period_count = 4; 8336ea2d824e5d8af550c139da9da20e73f82a9ae1Simon Wilson enum pcm_format format; 847153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson 857153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson if (argc < 2) { 86daa83291944318d8face12c780dfb69ae96b0723Simon Wilson fprintf(stderr, "Usage: %s file.wav [-D card] [-d device] [-c channels] " 87e44e30a90293ffebe604efea37842aff9d5da874Simon Wilson "[-r rate] [-b bits] [-p period_size] [-n n_periods]\n", argv[0]); 887153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson return 1; 897153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson } 907153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson 917153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson file = fopen(argv[1], "wb"); 927153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson if (!file) { 937153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson fprintf(stderr, "Unable to create file '%s'\n", argv[1]); 947153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson return 1; 957153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson } 967153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson 977153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson /* parse command line arguments */ 987153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson argv += 2; 997153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson while (*argv) { 100dd88f13d9b398c132e3358c62137ff2e23f321abSimon Wilson if (strcmp(*argv, "-d") == 0) { 1017153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson argv++; 102daa83291944318d8face12c780dfb69ae96b0723Simon Wilson if (*argv) 103daa83291944318d8face12c780dfb69ae96b0723Simon Wilson device = atoi(*argv); 104dd88f13d9b398c132e3358c62137ff2e23f321abSimon Wilson } else if (strcmp(*argv, "-c") == 0) { 1057153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson argv++; 106daa83291944318d8face12c780dfb69ae96b0723Simon Wilson if (*argv) 107daa83291944318d8face12c780dfb69ae96b0723Simon Wilson channels = atoi(*argv); 108dd88f13d9b398c132e3358c62137ff2e23f321abSimon Wilson } else if (strcmp(*argv, "-r") == 0) { 1097153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson argv++; 110daa83291944318d8face12c780dfb69ae96b0723Simon Wilson if (*argv) 111daa83291944318d8face12c780dfb69ae96b0723Simon Wilson rate = atoi(*argv); 112dd88f13d9b398c132e3358c62137ff2e23f321abSimon Wilson } else if (strcmp(*argv, "-b") == 0) { 1137153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson argv++; 114daa83291944318d8face12c780dfb69ae96b0723Simon Wilson if (*argv) 115daa83291944318d8face12c780dfb69ae96b0723Simon Wilson bits = atoi(*argv); 116daa83291944318d8face12c780dfb69ae96b0723Simon Wilson } else if (strcmp(*argv, "-D") == 0) { 117daa83291944318d8face12c780dfb69ae96b0723Simon Wilson argv++; 118daa83291944318d8face12c780dfb69ae96b0723Simon Wilson if (*argv) 119daa83291944318d8face12c780dfb69ae96b0723Simon Wilson card = atoi(*argv); 120daa83291944318d8face12c780dfb69ae96b0723Simon Wilson } else if (strcmp(*argv, "-p") == 0) { 121daa83291944318d8face12c780dfb69ae96b0723Simon Wilson argv++; 122daa83291944318d8face12c780dfb69ae96b0723Simon Wilson if (*argv) 123daa83291944318d8face12c780dfb69ae96b0723Simon Wilson period_size = atoi(*argv); 124daa83291944318d8face12c780dfb69ae96b0723Simon Wilson } else if (strcmp(*argv, "-n") == 0) { 125daa83291944318d8face12c780dfb69ae96b0723Simon Wilson argv++; 126daa83291944318d8face12c780dfb69ae96b0723Simon Wilson if (*argv) 127daa83291944318d8face12c780dfb69ae96b0723Simon Wilson period_count = atoi(*argv); 1287153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson } 129daa83291944318d8face12c780dfb69ae96b0723Simon Wilson if (*argv) 130daa83291944318d8face12c780dfb69ae96b0723Simon Wilson argv++; 1317153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson } 1327153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson 1337153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson header.riff_id = ID_RIFF; 1347153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson header.riff_sz = 0; 1357153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson header.riff_fmt = ID_WAVE; 1367153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson header.fmt_id = ID_FMT; 1377153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson header.fmt_sz = 16; 1387153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson header.audio_format = FORMAT_PCM; 1397153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson header.num_channels = channels; 1407153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson header.sample_rate = rate; 14136ea2d824e5d8af550c139da9da20e73f82a9ae1Simon Wilson 14236ea2d824e5d8af550c139da9da20e73f82a9ae1Simon Wilson switch (bits) { 14336ea2d824e5d8af550c139da9da20e73f82a9ae1Simon Wilson case 32: 14436ea2d824e5d8af550c139da9da20e73f82a9ae1Simon Wilson format = PCM_FORMAT_S32_LE; 14536ea2d824e5d8af550c139da9da20e73f82a9ae1Simon Wilson break; 14636ea2d824e5d8af550c139da9da20e73f82a9ae1Simon Wilson case 24: 14736ea2d824e5d8af550c139da9da20e73f82a9ae1Simon Wilson format = PCM_FORMAT_S24_LE; 14836ea2d824e5d8af550c139da9da20e73f82a9ae1Simon Wilson break; 14936ea2d824e5d8af550c139da9da20e73f82a9ae1Simon Wilson case 16: 15036ea2d824e5d8af550c139da9da20e73f82a9ae1Simon Wilson format = PCM_FORMAT_S16_LE; 15136ea2d824e5d8af550c139da9da20e73f82a9ae1Simon Wilson break; 15236ea2d824e5d8af550c139da9da20e73f82a9ae1Simon Wilson default: 15336ea2d824e5d8af550c139da9da20e73f82a9ae1Simon Wilson fprintf(stderr, "%d bits is not supported.\n", bits); 15436ea2d824e5d8af550c139da9da20e73f82a9ae1Simon Wilson return 1; 15536ea2d824e5d8af550c139da9da20e73f82a9ae1Simon Wilson } 15636ea2d824e5d8af550c139da9da20e73f82a9ae1Simon Wilson 15736ea2d824e5d8af550c139da9da20e73f82a9ae1Simon Wilson header.bits_per_sample = pcm_format_to_bits(format); 1587153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson header.byte_rate = (header.bits_per_sample / 8) * channels * rate; 1597153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson header.block_align = channels * (header.bits_per_sample / 8); 1607153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson header.data_id = ID_DATA; 1617153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson 1627153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson /* leave enough room for header */ 1637153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson fseek(file, sizeof(struct wav_header), SEEK_SET); 1647153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson 1657153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson /* install signal handler and begin capturing */ 1667153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson signal(SIGINT, sigint_handler); 167daa83291944318d8face12c780dfb69ae96b0723Simon Wilson frames = capture_sample(file, card, device, header.num_channels, 16836ea2d824e5d8af550c139da9da20e73f82a9ae1Simon Wilson header.sample_rate, format, 169daa83291944318d8face12c780dfb69ae96b0723Simon Wilson period_size, period_count); 1707153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson printf("Captured %d frames\n", frames); 1717153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson 1727153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson /* write header now all information is known */ 1737153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson header.data_sz = frames * header.block_align; 174da39e0b09eb0a1b559a96e2108160d1d8dccf314Simon Wilson header.riff_sz = header.data_sz + sizeof(header) - 8; 1757153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson fseek(file, 0, SEEK_SET); 1767153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson fwrite(&header, sizeof(struct wav_header), 1, file); 1777153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson 1787153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson fclose(file); 1797153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson 1807153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson return 0; 1817153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson} 1827153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson 183daa83291944318d8face12c780dfb69ae96b0723Simon Wilsonunsigned int capture_sample(FILE *file, unsigned int card, unsigned int device, 1847153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson unsigned int channels, unsigned int rate, 18536ea2d824e5d8af550c139da9da20e73f82a9ae1Simon Wilson enum pcm_format format, unsigned int period_size, 186daa83291944318d8face12c780dfb69ae96b0723Simon Wilson unsigned int period_count) 1877153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson{ 1887153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson struct pcm_config config; 1897153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson struct pcm *pcm; 1907153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson char *buffer; 1917153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson unsigned int size; 1927153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson unsigned int bytes_read = 0; 1937153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson 1947153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson config.channels = channels; 1957153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson config.rate = rate; 196daa83291944318d8face12c780dfb69ae96b0723Simon Wilson config.period_size = period_size; 197daa83291944318d8face12c780dfb69ae96b0723Simon Wilson config.period_count = period_count; 19836ea2d824e5d8af550c139da9da20e73f82a9ae1Simon Wilson config.format = format; 199621047309242d04a6186230e7a337de8642ec754Simon Wilson config.start_threshold = 0; 200621047309242d04a6186230e7a337de8642ec754Simon Wilson config.stop_threshold = 0; 201621047309242d04a6186230e7a337de8642ec754Simon Wilson config.silence_threshold = 0; 2027153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson 203daa83291944318d8face12c780dfb69ae96b0723Simon Wilson pcm = pcm_open(card, device, PCM_IN, &config); 2047153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson if (!pcm || !pcm_is_ready(pcm)) { 2057153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson fprintf(stderr, "Unable to open PCM device (%s)\n", 2067153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson pcm_get_error(pcm)); 2077153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson return 0; 2087153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson } 2097153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson 2109673f5717d824137d64320d0bc98a6461a9383a8Simon Wilson size = pcm_frames_to_bytes(pcm, pcm_get_buffer_size(pcm)); 2117153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson buffer = malloc(size); 2127153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson if (!buffer) { 2137153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson fprintf(stderr, "Unable to allocate %d bytes\n", size); 2147153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson free(buffer); 2157153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson pcm_close(pcm); 2167153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson return 0; 2177153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson } 2187153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson 21936ea2d824e5d8af550c139da9da20e73f82a9ae1Simon Wilson printf("Capturing sample: %u ch, %u hz, %u bit\n", channels, rate, 22036ea2d824e5d8af550c139da9da20e73f82a9ae1Simon Wilson pcm_format_to_bits(format)); 2217153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson 2227153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson while (capturing && !pcm_read(pcm, buffer, size)) { 2237153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson if (fwrite(buffer, 1, size, file) != size) { 2247153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson fprintf(stderr,"Error capturing sample\n"); 2257153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson break; 2267153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson } 2277153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson bytes_read += size; 2287153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson } 2297153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson 2307153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson free(buffer); 2317153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson pcm_close(pcm); 23236ea2d824e5d8af550c139da9da20e73f82a9ae1Simon Wilson return pcm_bytes_to_frames(pcm, bytes_read); 2337153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson} 2347153bffb805359a82f7857889e82bdcc5ff0afd8Simon Wilson 235