From owner-svn-soc-all@freebsd.org Sat Jun 25 18:28:24 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 30C7EB81D55 for ; Sat, 25 Jun 2016 18:28:24 +0000 (UTC) (envelope-from iateaca@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 1615326A9 for ; Sat, 25 Jun 2016 18:28:24 +0000 (UTC) (envelope-from iateaca@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u5PISNhQ080044 for ; Sat, 25 Jun 2016 18:28:23 GMT (envelope-from iateaca@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u5PISNh7080033 for svn-soc-all@FreeBSD.org; Sat, 25 Jun 2016 18:28:23 GMT (envelope-from iateaca@FreeBSD.org) Date: Sat, 25 Jun 2016 18:28:23 GMT Message-Id: <201606251828.u5PISNh7080033@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to iateaca@FreeBSD.org using -f From: iateaca@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r305547 - soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 25 Jun 2016 18:28:24 -0000 Author: iateaca Date: Sat Jun 25 18:28:22 2016 New Revision: 305547 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=305547 Log: implement the Audio Player used to play samples to the sound device (/dev/dsp) the public interface provides 3 functions: audio_init, audio_set_params and audio_playback A audio.c A audio.h Added: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/audio.c soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/audio.h Added: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/audio.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/audio.c Sat Jun 25 18:28:22 2016 (r305547) @@ -0,0 +1,163 @@ + +#include +#include +#include +#include +#include +#include +#include + +#include "audio.h" +#include "pci_hda.h" + +/* + * Audio Player internal data structures + */ + +struct audio { + int fd; + uint8_t dir; + char dev_name[64]; +}; + +/* + * Audio Player module function definitions + */ + +/* + * audio_init - initialize an instance of audio player + * @dev_name - the backend sound device used to play / capture + * @dir - dir = 1 for write mode, dir = 0 for read mode + */ +struct audio *audio_init(const char *dev_name, uint8_t dir) +{ + struct audio *aud = NULL; + + assert(dev_name); + + aud = calloc(1, sizeof(*aud)); + if (!aud) + return NULL; + + if (strlen(dev_name) < sizeof(aud->dev_name)) + memcpy(aud->dev_name, dev_name, strlen(dev_name) + 1); + else { + DPRINTF("dev_name too big\n"); + free(aud); + return NULL; + } + + aud->fd = -1; + aud->dir = dir; + + return aud; +} + +/* + * audio_set_params - reset the sound device and set the audio params + * @aud - the audio player to be configured + * @params - the audio parameters to be set + */ +int audio_set_params(struct audio *aud, struct audio_params *params) +{ + int audio_fd = -1; + int format, channels, rate; + int err; + + assert(aud); + assert(params); + + /* Close the device if was opened before */ + if (aud->fd != -1) { + err = close(aud->fd); + if (err == -1) { + DPRINTF("Fail to close fd: %d, errno: %d\n", aud->fd, errno); + return -1; + } + } + + audio_fd = open(aud->dev_name, aud->dir ? O_WRONLY : O_RDONLY, 0); + if (audio_fd == -1) { + DPRINTF("Fail to open dev: %s, errno: %d\n", aud->dev_name, errno); + return -1; + } + + aud->fd = audio_fd; + + /* Set the Format (Bits per Sample) */ + format = params->format; + err = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format); + if (err == -1) { + DPRINTF("Fail to set fmt: 0x%x errno: %d\n", params->format, errno); + return -1; + } + + /* The device does not support the requested audio format */ + if (format != params->format) { + DPRINTF("Mismatch format: 0x%x params->format: 0x%x\n", format, params->format); + return -1; + } + + /* Set the Number of Channels */ + channels = params->channels; + err = ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &channels); + if (err == -1) { + DPRINTF("Fail to set channels: %d errno: %d\n", params->channels, errno); + return -1; + } + + /* The device does not support the requested no. of channels */ + if (channels != params->channels) { + DPRINTF("Mismatch channels: %d params->channels: %d\n", channels, params->channels); + return -1; + } + + /* Set the Sample Rate / Speed */ + rate = params->rate; + err = ioctl(audio_fd, SNDCTL_DSP_SPEED, &rate); + if (err == -1) { + DPRINTF("Fail to set speed: %d errno: %d\n", params->rate, errno); + return -1; + } + + /* The device does not support the requested rate / speed */ + if (rate != params->rate) { + DPRINTF("Mismatch rate: %d params->rate: %d\n", rate, params->rate); + return -1; + } + + return 0; +} + +/* + * audio_playback - plays samples to the sound device using blocking operations + * @aud - the audio player used to play the samples + * @buf - the buffer containing the samples + * @count - the number of bytes in buffer + */ +ssize_t audio_playback(struct audio *aud, const void *buf, size_t count) +{ + int audio_fd = -1; + ssize_t len = 0, total = 0; + + assert(aud); + assert(aud->dir); + assert(buf); + + audio_fd = aud->fd; + assert(audio_fd != -1); + + total = 0; + while (total < count) { + len = write(audio_fd, buf + total, count - total); + if (len == -1) { + DPRINTF("Fail to write to fd: %d, errno: %d\n", audio_fd, errno); + return -1; + } + + total += len; + } + + return 0; +} + Added: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/audio.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/audio.h Sat Jun 25 18:28:22 2016 (r305547) @@ -0,0 +1,46 @@ + +#ifndef _AUDIO_EMUL_H_ +#define _AUDIO_EMUL_H_ + +#include +#include + +/* + * Audio Player data structures + */ + +struct audio; + +struct audio_params { + int format; + int channels; + int rate; +}; + +/* + * Audio Player API + */ + +/* + * audio_init - initialize an instance of audio player + * @dev_name - the backend sound device used to play / capture + * @dir - dir = 1 for write mode, dir = 0 for read mode + */ +struct audio *audio_init(const char *dev_name, uint8_t dir); + +/* + * audio_set_params - reset the sound device and set the audio params + * @aud - the audio player to be configured + * @params - the audio parameters to be set + */ +int audio_set_params(struct audio *aud, struct audio_params *params); + +/* + * audio_playback - plays samples to the sound device using blocking operations + * @aud - the audio player used to play the samples + * @buf - the buffer containing the samples + * @count - the number of bytes in buffer + */ +ssize_t audio_playback(struct audio *aud, const void *buf, size_t count); + +#endif /* _AUDIO_EMUL_H_ */