1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
3
* The contents of this file are subject to the Mozilla Public
4
* License Version 1.1 (the "License"); you may not use this file
5
* except in compliance with the License. You may obtain a copy of
6
* the License at http://www.mozilla.org/MPL/
8
* Software distributed under the License is distributed on an "AS
9
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
10
* implied. See the License for the specific language governing
11
* rights and limitations under the License.
13
* The Original Code is mozilla.org code.
15
* The Initial Developer of the Original Code is Netscape
16
* Communications Corporation. Portions created by Netscape are
17
* Copyright (C) 2000 Netscape Communications Corporation.
18
* All Rights Reserved.
21
* Stuart Parmenter <pavlov@netscape.com>
31
#include "nsIFileURL.h"
32
#include "nsNetUtil.h"
39
/* used with esd_open_sound */
40
static int esdref = -1;
41
static PRLibrary *elib = nsnull;
43
// the following from esd.h
45
#define ESD_BITS8 (0x0000)
46
#define ESD_BITS16 (0x0001)
47
#define ESD_MONO (0x0010)
48
#define ESD_STEREO (0x0020)
49
#define ESD_STREAM (0x0000)
50
#define ESD_PLAY (0x1000)
52
typedef int (PR_CALLBACK *EsdOpenSoundType)(const char *host);
53
typedef int (PR_CALLBACK *EsdCloseType)(int);
55
/* used to play the sounds from the find symbol call */
56
typedef int (PR_CALLBACK *EsdPlayStreamFallbackType)(int, int, const char *, const char *);
58
NS_IMPL_ISUPPORTS2(nsSound, nsISound, nsIStreamLoaderObserver)
60
////////////////////////////////////////////////////////////////////////
68
/* see above comment */
71
EsdCloseType EsdClose = (EsdCloseType) PR_FindSymbol(elib, "esd_close");
80
/* we don't need to do esd_open_sound if we are only going to play files
81
but we will if we want to do things like streams, etc
83
if (mInited) return NS_OK;
84
if (elib) return NS_OK;
87
EsdOpenSoundType EsdOpenSound;
89
elib = PR_LoadLibrary("libesd.so.0");
90
if (!elib) return NS_ERROR_FAILURE;
92
EsdOpenSound = (EsdOpenSoundType) PR_FindSymbol(elib, "esd_open_sound");
95
return NS_ERROR_FAILURE;
97
esdref = (*EsdOpenSound)("localhost");
100
return NS_ERROR_FAILURE;
107
#define GET_WORD(s, i) ((unsigned char)s[i+1] << 8) | (unsigned char)s[i]
108
#define GET_DWORD(s, i) ((unsigned char)s[i+3] << 24) | ((unsigned char)s[i+2] << 16) | ((unsigned char)s[i+1] << 8) | (unsigned char)s[i]
110
NS_IMETHODIMP nsSound::OnStreamComplete(nsIStreamLoader *aLoader,
111
nsISupports *context,
118
// print a load error on bad status
119
if (NS_FAILED(aStatus)) {
121
nsCOMPtr<nsIRequest> request;
122
aLoader->GetRequest(getter_AddRefs(request));
124
nsCOMPtr<nsIURI> uri;
125
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
127
channel->GetURI(getter_AddRefs(uri));
129
nsCAutoString uriSpec;
130
uri->GetSpec(uriSpec);
131
printf("Failed to load %s\n", uriSpec.get());
141
unsigned long samples_per_sec=0, avg_bytes_per_sec=0;
142
unsigned long rate=0;
143
unsigned short format, channels = 1, block_align, bits_per_sample=0;
146
if (PL_strncmp(string, "RIFF", 4)) {
148
printf("We only support WAV files currently.\n");
150
return NS_ERROR_FAILURE;
154
for (i= 0; i < stringLen; i++) {
156
if (i+3 <= stringLen)
157
if ((string[i] == 'f') &&
158
(string[i+1] == 'm') &&
159
(string[i+2] == 't') &&
160
(string[i+3] == ' ')) {
163
/* length of the rest of this subblock (should be 16 for PCM data */
164
// long len = GET_DWORD(string, i);
167
format = GET_WORD(string, i);
170
channels = GET_WORD(string, i);
173
samples_per_sec = GET_DWORD(string, i);
176
avg_bytes_per_sec = GET_DWORD(string, i);
179
block_align = GET_WORD(string, i);
182
bits_per_sample = GET_WORD(string, i);
185
rate = samples_per_sec;
192
printf("f: %d | c: %d | sps: %li | abps: %li | ba: %d | bps: %d | rate: %li\n",
193
format, channels, samples_per_sec, avg_bytes_per_sec, block_align, bits_per_sample, rate);
196
/* open up conneciton to esd */
197
EsdPlayStreamFallbackType EsdPlayStreamFallback = (EsdPlayStreamFallbackType) PR_FindSymbol(elib, "esd_play_stream_fallback");
199
mask = ESD_PLAY | ESD_STREAM;
201
if (bits_per_sample == 8)
211
fd = (*EsdPlayStreamFallback)(mask, rate, NULL, "mozillaSound");
214
return NS_ERROR_FAILURE;
218
write(fd, string, stringLen);
225
NS_METHOD nsSound::Beep()
232
NS_METHOD nsSound::Play(nsIURL *aURL)
239
if (!elib) return NS_ERROR_FAILURE;
241
nsCOMPtr<nsIStreamLoader> loader;
242
rv = NS_NewStreamLoader(getter_AddRefs(loader), aURL, this);
247
NS_IMETHODIMP nsSound::PlaySystemSound(const char *aSoundAlias)
249
if (!aSoundAlias) return NS_ERROR_FAILURE;
250
if (strcmp(aSoundAlias, "_moz_mailbeep") == 0)
255
nsCOMPtr <nsIURI> fileURI;
257
// create a nsILocalFile and then a nsIFileURL from that
258
nsCOMPtr <nsILocalFile> soundFile;
259
rv = NS_NewNativeLocalFile(nsDependentCString(aSoundAlias), PR_TRUE,
260
getter_AddRefs(soundFile));
261
NS_ENSURE_SUCCESS(rv,rv);
263
rv = NS_NewFileURI(getter_AddRefs(fileURI), soundFile);
264
NS_ENSURE_SUCCESS(rv,rv);
266
nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(fileURI,&rv);
267
NS_ENSURE_SUCCESS(rv,rv);