~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/widget/src/gtk/nsSound.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 
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/
 
7
 * 
 
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.
 
12
 * 
 
13
 * The Original Code is mozilla.org code.
 
14
 * 
 
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.
 
19
 * 
 
20
 * Contributor(s):
 
21
 *   Stuart Parmenter <pavlov@netscape.com>
 
22
 */
 
23
 
 
24
#include "nscore.h"
 
25
#include "plstr.h"
 
26
#include "prlink.h"
 
27
 
 
28
#include "nsSound.h"
 
29
 
 
30
#include "nsIURL.h"
 
31
#include "nsIFileURL.h"
 
32
#include "nsNetUtil.h"
 
33
#include "nsCOMPtr.h"
 
34
 
 
35
#include <stdio.h>
 
36
#include <unistd.h>
 
37
 
 
38
#include <gtk/gtk.h>
 
39
/* used with esd_open_sound */
 
40
static int esdref = -1;
 
41
static PRLibrary *elib = nsnull;
 
42
 
 
43
// the following from esd.h
 
44
 
 
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)
 
51
 
 
52
typedef int (PR_CALLBACK *EsdOpenSoundType)(const char *host);
 
53
typedef int (PR_CALLBACK *EsdCloseType)(int);
 
54
 
 
55
/* used to play the sounds from the find symbol call */
 
56
typedef int (PR_CALLBACK *EsdPlayStreamFallbackType)(int, int, const char *, const char *);
 
57
 
 
58
NS_IMPL_ISUPPORTS2(nsSound, nsISound, nsIStreamLoaderObserver)
 
59
 
 
60
////////////////////////////////////////////////////////////////////////
 
61
nsSound::nsSound()
 
62
{
 
63
  mInited = PR_FALSE;
 
64
}
 
65
 
 
66
nsSound::~nsSound()
 
67
{
 
68
  /* see above comment */
 
69
 
 
70
  if (esdref != -1) {
 
71
    EsdCloseType EsdClose = (EsdCloseType) PR_FindSymbol(elib, "esd_close");
 
72
    (*EsdClose)(esdref);
 
73
    esdref = -1;
 
74
  }
 
75
}
 
76
 
 
77
NS_IMETHODIMP
 
78
nsSound::Init()
 
79
{
 
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
 
82
  */
 
83
  if (mInited) return NS_OK;
 
84
  if (elib) return NS_OK;
 
85
  
 
86
 
 
87
  EsdOpenSoundType EsdOpenSound;
 
88
 
 
89
  elib = PR_LoadLibrary("libesd.so.0");
 
90
  if (!elib) return NS_ERROR_FAILURE;
 
91
 
 
92
  EsdOpenSound = (EsdOpenSoundType) PR_FindSymbol(elib, "esd_open_sound");
 
93
 
 
94
  if (!EsdOpenSound)
 
95
    return NS_ERROR_FAILURE;
 
96
 
 
97
  esdref = (*EsdOpenSound)("localhost");
 
98
 
 
99
  if (!esdref)
 
100
    return NS_ERROR_FAILURE;
 
101
 
 
102
  mInited = PR_TRUE;
 
103
 
 
104
  return NS_OK;
 
105
}
 
106
 
 
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]
 
109
 
 
110
NS_IMETHODIMP nsSound::OnStreamComplete(nsIStreamLoader *aLoader,
 
111
                                        nsISupports *context,
 
112
                                        nsresult aStatus,
 
113
                                        PRUint32 stringLen,
 
114
                                        const char *string)
 
115
{
 
116
 
 
117
#ifdef DEBUG
 
118
  // print a load error on bad status
 
119
  if (NS_FAILED(aStatus)) {
 
120
    if (aLoader) {
 
121
      nsCOMPtr<nsIRequest> request;
 
122
      aLoader->GetRequest(getter_AddRefs(request));
 
123
      if (request) {
 
124
        nsCOMPtr<nsIURI> uri;
 
125
        nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
 
126
        if (channel) {
 
127
            channel->GetURI(getter_AddRefs(uri));
 
128
            if (uri) {
 
129
                nsCAutoString uriSpec;
 
130
                uri->GetSpec(uriSpec);
 
131
                printf("Failed to load %s\n", uriSpec.get());
 
132
            }
 
133
        }
 
134
      }
 
135
    }
 
136
  }
 
137
#endif
 
138
 
 
139
  int fd, mask = 0;
 
140
 
 
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;
 
144
 
 
145
 
 
146
  if (PL_strncmp(string, "RIFF", 4)) {
 
147
#ifdef DEBUG
 
148
    printf("We only support WAV files currently.\n");
 
149
#endif
 
150
    return NS_ERROR_FAILURE;
 
151
  }
 
152
 
 
153
  PRUint32 i;
 
154
  for (i= 0; i < stringLen; i++) {
 
155
 
 
156
    if (i+3 <= stringLen) 
 
157
      if ((string[i] == 'f') &&
 
158
          (string[i+1] == 'm') &&
 
159
          (string[i+2] == 't') &&
 
160
          (string[i+3] == ' ')) {
 
161
        i += 4;
 
162
 
 
163
        /* length of the rest of this subblock (should be 16 for PCM data */
 
164
        //        long len = GET_DWORD(string, i);
 
165
        i+=4;
 
166
 
 
167
        format = GET_WORD(string, i);
 
168
        i+=2;
 
169
 
 
170
        channels = GET_WORD(string, i);
 
171
        i+=2;
 
172
 
 
173
        samples_per_sec = GET_DWORD(string, i);
 
174
        i+=4;
 
175
 
 
176
        avg_bytes_per_sec = GET_DWORD(string, i);
 
177
        i+=4;
 
178
 
 
179
        block_align = GET_WORD(string, i);
 
180
        i+=2;
 
181
 
 
182
        bits_per_sample = GET_WORD(string, i);
 
183
        i+=2;
 
184
 
 
185
        rate = samples_per_sec;
 
186
 
 
187
        break;
 
188
      }
 
189
  }
 
190
 
 
191
#ifdef DEBUG
 
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);
 
194
#endif
 
195
 
 
196
  /* open up conneciton to esd */  
 
197
  EsdPlayStreamFallbackType EsdPlayStreamFallback = (EsdPlayStreamFallbackType) PR_FindSymbol(elib, "esd_play_stream_fallback");
 
198
  
 
199
  mask = ESD_PLAY | ESD_STREAM;
 
200
 
 
201
  if (bits_per_sample == 8)
 
202
    mask |= ESD_BITS8;
 
203
  else 
 
204
    mask |= ESD_BITS16;
 
205
 
 
206
  if (channels == 1)
 
207
    mask |= ESD_MONO;
 
208
  else 
 
209
    mask |= ESD_STEREO;
 
210
 
 
211
  fd = (*EsdPlayStreamFallback)(mask, rate, NULL, "mozillaSound"); 
 
212
  
 
213
  if (fd < 0) {
 
214
    return NS_ERROR_FAILURE;
 
215
  }
 
216
 
 
217
  /* write data out */
 
218
  write(fd, string, stringLen);
 
219
  
 
220
  close(fd);
 
221
 
 
222
  return NS_OK;
 
223
}
 
224
 
 
225
NS_METHOD nsSound::Beep()
 
226
{
 
227
  ::gdk_beep();
 
228
 
 
229
  return NS_OK;
 
230
}
 
231
 
 
232
NS_METHOD nsSound::Play(nsIURL *aURL)
 
233
{
 
234
  nsresult rv;
 
235
 
 
236
  if (!mInited)
 
237
    Init();
 
238
 
 
239
  if (!elib) return NS_ERROR_FAILURE;
 
240
 
 
241
  nsCOMPtr<nsIStreamLoader> loader;
 
242
  rv = NS_NewStreamLoader(getter_AddRefs(loader), aURL, this);
 
243
 
 
244
  return rv;
 
245
}
 
246
 
 
247
NS_IMETHODIMP nsSound::PlaySystemSound(const char *aSoundAlias)
 
248
{
 
249
  if (!aSoundAlias) return NS_ERROR_FAILURE;
 
250
  if (strcmp(aSoundAlias, "_moz_mailbeep") == 0)
 
251
  {
 
252
    return Beep();
 
253
  }
 
254
  nsresult rv;
 
255
  nsCOMPtr <nsIURI> fileURI;
 
256
 
 
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);
 
262
 
 
263
  rv = NS_NewFileURI(getter_AddRefs(fileURI), soundFile);
 
264
  NS_ENSURE_SUCCESS(rv,rv);
 
265
 
 
266
  nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(fileURI,&rv);
 
267
  NS_ENSURE_SUCCESS(rv,rv);
 
268
  rv = Play(fileURL);
 
269
  return rv;
 
270
}