1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim:set ts=2 sw=2 sts=2 et cindent: */
3 : /* ***** BEGIN LICENSE BLOCK *****
4 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 : *
6 : * The contents of this file are subject to the Mozilla Public License Version
7 : * 1.1 (the "License"); you may not use this file except in compliance with
8 : * the License. You may obtain a copy of the License at
9 : * http://www.mozilla.org/MPL/
10 : *
11 : * Software distributed under the License is distributed on an "AS IS" basis,
12 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 : * for the specific language governing rights and limitations under the
14 : * License.
15 : *
16 : * The Original Code is Mozilla code.
17 : *
18 : * The Initial Developer of the Original Code is the Mozilla Foundation.
19 : * Portions created by the Initial Developer are Copyright (C) 2010
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * David Humphrey <david.humphrey@senecac.on.ca>
24 : * Yury Delendik
25 : *
26 : * Alternatively, the contents of this file may be used under the terms of
27 : * either the GNU General Public License Version 2 or later (the "GPL"), or
28 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 : * in which case the provisions of the GPL or the LGPL are applicable instead
30 : * of those above. If you wish to allow use of your version of this file only
31 : * under the terms of either the GPL or the LGPL, and not to allow others to
32 : * use your version of this file under the terms of the MPL, indicate your
33 : * decision by deleting the provisions above and replace them with the notice
34 : * and other provisions required by the GPL or the LGPL. If you do not delete
35 : * the provisions above, a recipient may use your version of this file under
36 : * the terms of any one of the MPL, the GPL or the LGPL.
37 : *
38 : * ***** END LICENSE BLOCK ***** */
39 :
40 : #include "nsDOMNotifyAudioAvailableEvent.h"
41 : #include "nsDOMClassInfoID.h" // DOMCI_DATA, NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO
42 : #include "nsContentUtils.h" // NS_DROP_JS_OBJECTS
43 : #include "jstypedarray.h"
44 :
45 0 : nsDOMNotifyAudioAvailableEvent::nsDOMNotifyAudioAvailableEvent(nsPresContext* aPresContext,
46 : nsEvent* aEvent,
47 : PRUint32 aEventType,
48 : float* aFrameBuffer,
49 : PRUint32 aFrameBufferLength,
50 : float aTime)
51 : : nsDOMEvent(aPresContext, aEvent),
52 : mFrameBuffer(aFrameBuffer),
53 : mFrameBufferLength(aFrameBufferLength),
54 : mTime(aTime),
55 : mCachedArray(nsnull),
56 0 : mAllowAudioData(false)
57 : {
58 0 : MOZ_COUNT_CTOR(nsDOMNotifyAudioAvailableEvent);
59 0 : if (mEvent) {
60 0 : mEvent->message = aEventType;
61 : }
62 0 : }
63 :
64 : DOMCI_DATA(NotifyAudioAvailableEvent, nsDOMNotifyAudioAvailableEvent)
65 :
66 1464 : NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMNotifyAudioAvailableEvent)
67 :
68 0 : NS_IMPL_ADDREF_INHERITED(nsDOMNotifyAudioAvailableEvent, nsDOMEvent)
69 0 : NS_IMPL_RELEASE_INHERITED(nsDOMNotifyAudioAvailableEvent, nsDOMEvent)
70 :
71 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMNotifyAudioAvailableEvent, nsDOMEvent)
72 0 : if (tmp->mCachedArray) {
73 0 : NS_DROP_JS_OBJECTS(tmp, nsDOMNotifyAudioAvailableEvent);
74 0 : tmp->mCachedArray = nsnull;
75 : }
76 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
77 :
78 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMNotifyAudioAvailableEvent, nsDOMEvent)
79 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
80 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
81 :
82 0 : NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsDOMNotifyAudioAvailableEvent)
83 0 : NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mCachedArray)
84 0 : NS_IMPL_CYCLE_COLLECTION_TRACE_END
85 :
86 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMNotifyAudioAvailableEvent)
87 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMNotifyAudioAvailableEvent)
88 0 : NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(NotifyAudioAvailableEvent)
89 0 : NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent)
90 :
91 0 : nsDOMNotifyAudioAvailableEvent::~nsDOMNotifyAudioAvailableEvent()
92 : {
93 0 : MOZ_COUNT_DTOR(nsDOMNotifyAudioAvailableEvent);
94 0 : if (mCachedArray) {
95 0 : NS_DROP_JS_OBJECTS(this, nsDOMNotifyAudioAvailableEvent);
96 0 : mCachedArray = nsnull;
97 : }
98 0 : }
99 :
100 : NS_IMETHODIMP
101 0 : nsDOMNotifyAudioAvailableEvent::GetFrameBuffer(JSContext* aCx, jsval* aResult)
102 : {
103 0 : if (!mAllowAudioData) {
104 : // Media is not same-origin, don't allow the data out.
105 0 : return NS_ERROR_DOM_SECURITY_ERR;
106 : }
107 :
108 0 : if (mCachedArray) {
109 0 : *aResult = OBJECT_TO_JSVAL(mCachedArray);
110 0 : return NS_OK;
111 : }
112 :
113 : // Cache this array so we don't recreate on next call.
114 0 : NS_HOLD_JS_OBJECTS(this, nsDOMNotifyAudioAvailableEvent);
115 :
116 0 : mCachedArray = js_CreateTypedArray(aCx, js::TypedArray::TYPE_FLOAT32, mFrameBufferLength);
117 0 : if (!mCachedArray) {
118 0 : NS_DROP_JS_OBJECTS(this, nsDOMNotifyAudioAvailableEvent);
119 0 : NS_ERROR("Failed to get audio signal!");
120 0 : return NS_ERROR_FAILURE;
121 : }
122 :
123 0 : JSObject *tdest = js::TypedArray::getTypedArray(mCachedArray);
124 0 : memcpy(JS_GetTypedArrayData(tdest), mFrameBuffer.get(), mFrameBufferLength * sizeof(float));
125 :
126 0 : *aResult = OBJECT_TO_JSVAL(mCachedArray);
127 0 : return NS_OK;
128 : }
129 :
130 : NS_IMETHODIMP
131 0 : nsDOMNotifyAudioAvailableEvent::GetTime(float *aRetVal)
132 : {
133 0 : *aRetVal = mTime;
134 0 : return NS_OK;
135 : }
136 :
137 : NS_IMETHODIMP
138 0 : nsDOMNotifyAudioAvailableEvent::InitAudioAvailableEvent(const nsAString& aType,
139 : bool aCanBubble,
140 : bool aCancelable,
141 : float* aFrameBuffer,
142 : PRUint32 aFrameBufferLength,
143 : float aTime,
144 : bool aAllowAudioData)
145 : {
146 : // Auto manage the memory which stores the frame buffer. This ensures
147 : // that if we exit due to some error, the memory will be freed. Otherwise,
148 : // the framebuffer's memory will be freed when this event is destroyed.
149 0 : nsAutoArrayPtr<float> frameBuffer(aFrameBuffer);
150 0 : nsresult rv = nsDOMEvent::InitEvent(aType, aCanBubble, aCancelable);
151 0 : NS_ENSURE_SUCCESS(rv, rv);
152 :
153 0 : mFrameBuffer = frameBuffer.forget();
154 0 : mFrameBufferLength = aFrameBufferLength;
155 0 : mTime = aTime;
156 0 : mAllowAudioData = aAllowAudioData;
157 0 : return NS_OK;
158 : }
159 :
160 0 : nsresult NS_NewDOMAudioAvailableEvent(nsIDOMEvent** aInstancePtrResult,
161 : nsPresContext* aPresContext,
162 : nsEvent *aEvent,
163 : PRUint32 aEventType,
164 : float* aFrameBuffer,
165 : PRUint32 aFrameBufferLength,
166 : float aTime)
167 : {
168 : nsDOMNotifyAudioAvailableEvent* it =
169 : new nsDOMNotifyAudioAvailableEvent(aPresContext, aEvent, aEventType,
170 0 : aFrameBuffer, aFrameBufferLength, aTime);
171 0 : return CallQueryInterface(it, aInstancePtrResult);
172 4392 : }
|